util: abstract parsing of passed FDs into virGetListenFDs()

Since not only systemd can do this (we'll be doing it as well few
patches later), change 'systemd' to 'caller' and fix LISTEN_FDS to
LISTEN_PID where applicable.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Martin Kletzander 2014-07-15 14:34:13 +02:00
parent 4cf1c3fab1
commit 8989597cd9
4 changed files with 69 additions and 41 deletions

View File

@ -2107,6 +2107,7 @@ virGetGroupID;
virGetGroupList; virGetGroupList;
virGetGroupName; virGetGroupName;
virGetHostname; virGetHostname;
virGetListenFDs;
virGetSelfLastChanged; virGetSelfLastChanged;
virGetUnprivSGIOSysfsPath; virGetUnprivSGIOSysfsPath;
virGetUserCacheDirectory; virGetUserCacheDirectory;

View File

@ -600,50 +600,13 @@ static int
virLockDaemonSetupNetworkingSystemD(virNetServerPtr srv) virLockDaemonSetupNetworkingSystemD(virNetServerPtr srv)
{ {
virNetServerServicePtr svc; virNetServerServicePtr svc;
const char *pidstr;
const char *fdstr;
unsigned long long procid;
unsigned int nfds; unsigned int nfds;
VIR_DEBUG("Setting up networking from systemd"); if ((nfds = virGetListenFDs()) == 0)
if (!(pidstr = virGetEnvAllowSUID("LISTEN_PID"))) {
VIR_DEBUG("No LISTEN_FDS from systemd");
return 0; return 0;
} if (nfds > 1)
VIR_DEBUG("Too many (%d) file descriptors from systemd", nfds);
if (virStrToLong_ull(pidstr, NULL, 10, &procid) < 0) {
VIR_DEBUG("Malformed LISTEN_PID from systemd %s", pidstr);
return 0;
}
if ((pid_t)procid != getpid()) {
VIR_DEBUG("LISTEN_PID %s is not for us %llu",
pidstr, (unsigned long long)getpid());
return 0;
}
if (!(fdstr = virGetEnvAllowSUID("LISTEN_FDS"))) {
VIR_DEBUG("No LISTEN_FDS from systemd");
return 0;
}
if (virStrToLong_ui(fdstr, NULL, 10, &nfds) < 0) {
VIR_DEBUG("Malformed LISTEN_FDS from systemd %s", fdstr);
return 0;
}
if (nfds > 1) {
VIR_DEBUG("Too many (%d) file descriptors from systemd",
nfds);
nfds = 1; nfds = 1;
}
unsetenv("LISTEN_PID");
unsetenv("LISTEN_FDS");
if (nfds == 0)
return 0;
/* Systemd passes FDs, starting immediately after stderr, /* Systemd passes FDs, starting immediately after stderr,
* so the first FD we'll get is '3'. */ * so the first FD we'll get is '3'. */

View File

@ -2396,3 +2396,65 @@ void virUpdateSelfLastChanged(const char *path)
selfLastChanged = sb.st_ctime; selfLastChanged = sb.st_ctime;
} }
} }
/**
* virGetListenFDs:
*
* Parse LISTEN_PID and LISTEN_FDS passed from caller.
*
* Returns number of passed FDs.
*/
unsigned int
virGetListenFDs(void)
{
const char *pidstr;
const char *fdstr;
size_t i = 0;
unsigned long long procid;
unsigned int nfds;
VIR_DEBUG("Setting up networking from caller");
if (!(pidstr = virGetEnvAllowSUID("LISTEN_PID"))) {
VIR_DEBUG("No LISTEN_PID from caller");
return 0;
}
if (virStrToLong_ull(pidstr, NULL, 10, &procid) < 0) {
VIR_DEBUG("Malformed LISTEN_PID from caller %s", pidstr);
return 0;
}
if ((pid_t)procid != getpid()) {
VIR_DEBUG("LISTEN_PID %s is not for us %llu",
pidstr, (unsigned long long)getpid());
return 0;
}
if (!(fdstr = virGetEnvAllowSUID("LISTEN_FDS"))) {
VIR_DEBUG("No LISTEN_FDS from caller");
return 0;
}
if (virStrToLong_ui(fdstr, NULL, 10, &nfds) < 0) {
VIR_DEBUG("Malformed LISTEN_FDS from caller %s", fdstr);
return 0;
}
unsetenv("LISTEN_PID");
unsetenv("LISTEN_FDS");
VIR_DEBUG("Got %u file descriptors", nfds);
for (i = 0; i < nfds; i++) {
int fd = STDERR_FILENO + i + 1;
VIR_DEBUG("Disabling inheritance of passed FD %d", fd);
if (virSetInherit(fd, false) < 0) {
VIR_WARN("Couldn't disable inheritance of passed FD %d", fd);
}
}
return nfds;
}

View File

@ -232,4 +232,6 @@ typedef enum {
VIR_ENUM_DECL(virTristateBool) VIR_ENUM_DECL(virTristateBool)
VIR_ENUM_DECL(virTristateSwitch) VIR_ENUM_DECL(virTristateSwitch)
unsigned int virGetListenFDs(void);
#endif /* __VIR_UTIL_H__ */ #endif /* __VIR_UTIL_H__ */