When receiving multiple socket FDs from systemd, it is critical to know
what socket address each corresponds to so we can setup the right
protocols on each.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virutil.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/util/virutil.h | 1 +
3 files changed, 47 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bc8cc1fba9..54e3b9130b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2962,6 +2962,7 @@ virGetListenFDs;
virGetSelfLastChanged;
virGetSystemPageSize;
virGetSystemPageSizeKB;
+virGetUNIXSocketPath;
virGetUnprivSGIOSysfsPath;
virGetUserCacheDirectory;
virGetUserConfigDirectory;
diff --git a/src/util/virutil.c b/src/util/virutil.c
index e9dbaf3d7a..8352e0f1f1 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -68,6 +68,10 @@
# include <shlobj.h>
#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+
#include "c-ctype.h"
#include "mgetgroups.h"
#include "virerror.h"
@@ -1978,6 +1982,47 @@ virGetListenFDs(void)
#endif /* WIN32 */
+#ifdef HAVE_SYS_UN_H
+char *virGetUNIXSocketPath(int fd)
+{
+ struct sockaddr_storage ss = { 0 };
+ struct sockaddr_un *un = (struct sockaddr_un *)&ss;
+ socklen_t len = sizeof(ss);
+ char *path;
+
+ if (getsockname(fd, (struct sockaddr *)&ss, &len) < 0) {
+ virReportSystemError(errno, _("Unable to get address of FD %d"), fd);
+ return NULL;
+ }
+
+ if (ss.ss_family != AF_UNIX) {
+ virReportSystemError(EINVAL, _("FD %d is not a UNIX socket, has
af=%d"),
+ fd, ss.ss_family);
+ return NULL;
+ }
+
+ if (un->sun_path[0] == '\0')
+ un->sun_path[0] = '@';
+
+ if (VIR_ALLOC_N(path, sizeof(un->sun_path) + 1) < 0)
+ return NULL;
+
+ memcpy(path, un->sun_path, sizeof(un->sun_path));
+ path[sizeof(un->sun_path)] = '\0';
+ return path;
+}
+
+#else /* HAVE_SYS_UN_H */
+
+char *virGetUNIXSocketPath(int fd)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("UNIX sockets not supported on this platform");
+ return NULL;
+}
+
+#endif /* HAVE_SYS_UN_H */
+
#ifndef WIN32
long virGetSystemPageSize(void)
{
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 9381ad5682..be0f6b0ea8 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -207,6 +207,7 @@ verify((int)VIR_TRISTATE_BOOL_NO == (int)VIR_TRISTATE_SWITCH_OFF);
verify((int)VIR_TRISTATE_BOOL_ABSENT == (int)VIR_TRISTATE_SWITCH_ABSENT);
unsigned int virGetListenFDs(void);
+char *virGetUNIXSocketPath(int fd);
long virGetSystemPageSize(void) ATTRIBUTE_NOINLINE;
long virGetSystemPageSizeKB(void) ATTRIBUTE_NOINLINE;
--
2.14.3