From 28a07e4c801c349061c50dbb2e3eb800c90c664a Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Tue, 20 Feb 2007 09:04:27 +0000 Subject: [PATCH] Fri Feb 20 09:03:05 IST 2007 Mark McLoughlin * qemud/qemud.c: clean up qemudInitialize() and qemudListen() so as to coalesce the two "system vs. user" code paths and fix up some problems noticed by dan. --- ChangeLog | 6 ++ qemud/qemud.c | 175 ++++++++++++++++++++++++++------------------------ 2 files changed, 97 insertions(+), 84 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0734cb07a4..9c8fcd111a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Feb 20 09:03:05 IST 2007 Mark McLoughlin + + * qemud/qemud.c: clean up qemudInitialize() and qemudListen() + so as to coalesce the two "system vs. user" code paths and + fix up some problems noticed by dan. + Fri Feb 19 16:59:18 IST 2007 Mark McLoughlin * qemud/qemud.c: don't shutdown guest and networks on diff --git a/qemud/qemud.c b/qemud/qemud.c index 9d6ed4ad5c..aeb7c1ebc2 100644 --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -350,55 +350,111 @@ static int qemudListenUnix(struct qemud_server *server, return 0; } -static int qemudListen(struct qemud_server *server, int sys) { - char sockname[PATH_MAX]; +static int +qemudEnsureDir(const char *path) +{ + struct stat st; + char parent[PATH_MAX]; + char *p; + int err; + + if (stat(path, &st) >= 0) + return 0; + + strncpy(parent, path, PATH_MAX); + parent[PATH_MAX - 1] = '\0'; + + if (!(p = strrchr(parent, '/'))) + return EINVAL; + + if (p == parent) + return EPERM; + + *p = '\0'; + + if ((err = qemudEnsureDir(parent))) + return err; + + if (mkdir(path, 0777) < 0 && errno != EEXIST) + return errno; + + return 0; +} + +static int qemudInitPaths(int sys, + char *configDir, + char *networkConfigDir, + char *sockname, + char *roSockname, + int maxlen) { + uid_t uid; + int err; + + uid = geteuid(); if (sys) { - if (snprintf(sockname, sizeof(sockname), "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= (int)sizeof(sockname)) - goto snprintf_error; - - unlink(sockname); - if (qemudListenUnix(server, sockname, 0) < 0) - return -1; - - if (snprintf(sockname, sizeof(sockname), "%s/run/libvirt/qemud-sock-ro", LOCAL_STATE_DIR) >= (int)sizeof(sockname)) - goto snprintf_error; - - unlink(sockname); - if (qemudListenUnix(server, sockname, 1) < 0) - return -1; - } else { - struct passwd *pw; - int uid; - - if ((uid = geteuid()) < 0) { + if (uid != 0) { qemudLog(QEMUD_ERR, "You must run the daemon as root to use system mode"); return -1; } + if (snprintf(configDir, maxlen, "%s/libvirt/qemu", SYSCONF_DIR) >= maxlen) + goto snprintf_error; + + if (snprintf(networkConfigDir, maxlen, "%s/libvirt/qemu/networks", SYSCONF_DIR) >= maxlen) + goto snprintf_error; + + if (snprintf(sockname, maxlen, "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= maxlen) + goto snprintf_error; + + unlink(sockname); + + if (snprintf(roSockname, maxlen, "%s/run/libvirt/qemud-sock-ro", LOCAL_STATE_DIR) >= maxlen) + goto snprintf_error; + + unlink(sockname); + } else { + struct passwd *pw; + if (!(pw = getpwuid(uid))) { - qemudLog(QEMUD_ERR, "Failed to find user record for uid '%s': %s", + qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s", uid, strerror(errno)); return -1; } - if (snprintf(sockname, sizeof(sockname), "@%s/.libvirt/qemud-sock", pw->pw_dir) >= (int)sizeof(sockname)) + if (snprintf(configDir, maxlen, "%s/.libvirt/qemu", pw->pw_dir) >= maxlen) goto snprintf_error; - if (qemudListenUnix(server, sockname, 0) < 0) - return -1; + if (snprintf(networkConfigDir, maxlen, "%s/.libvirt/qemu/networks", pw->pw_dir) >= maxlen) + goto snprintf_error; + + if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen) + goto snprintf_error; + } + + if ((err = qemudEnsureDir(configDir))) { + qemudLog(QEMUD_ERR, "Failed to create directory '%s': %s", + configDir, strerror(err)); + return -1; + } + + if ((err = qemudEnsureDir(networkConfigDir))) { + qemudLog(QEMUD_ERR, "Failed to create directory '%s': %s", + networkConfigDir, strerror(err)); + return -1; } return 0; snprintf_error: - qemudLog(QEMUD_ERR, "Resulting path to long for buffer in qemudListen()"); + qemudLog(QEMUD_ERR, "Resulting path to long for buffer in qemudInitPaths()"); return -1; } static struct qemud_server *qemudInitialize(int sys, int sigread) { struct qemud_server *server; - char libvirtConf[PATH_MAX]; + char sockname[PATH_MAX]; + char roSockname[PATH_MAX]; if (!(server = calloc(1, sizeof(struct qemud_server)))) { qemudLog(QEMUD_ERR, "Failed to allocate struct qemud_server"); @@ -411,63 +467,17 @@ static struct qemud_server *qemudInitialize(int sys, int sigread) { server->nextvmid = 1; server->sigread = sigread; - if (sys) { - if (snprintf(libvirtConf, sizeof(libvirtConf), "%s/libvirt", SYSCONF_DIR) >= (int)sizeof(libvirtConf)) { - goto snprintf_cleanup; - } - if (mkdir(libvirtConf, 0777) < 0) { - if (errno != EEXIST) { - qemudLog(QEMUD_ERR, "Failed to create directory '%s': %s", - libvirtConf, strerror(errno)); - goto cleanup; - } - } + roSockname[0] = '\0'; - if (snprintf(server->configDir, sizeof(server->configDir), "%s/libvirt/qemu", SYSCONF_DIR) >= (int)sizeof(server->configDir)) { - goto snprintf_cleanup; - } - if (snprintf(server->networkConfigDir, sizeof(server->networkConfigDir), "%s/libvirt/qemu/networks", SYSCONF_DIR) >= (int)sizeof(server->networkConfigDir)) { - goto snprintf_cleanup; - } - } else { - struct passwd *pw; - int uid; - - if ((uid = geteuid()) < 0) { - qemudLog(QEMUD_ERR, "You must run the daemon as root to use system mode"); - goto cleanup; - } - if (!(pw = getpwuid(uid))) { - qemudLog(QEMUD_ERR, "Failed to find user record for uid '%s': %s", - uid, strerror(errno)); - goto cleanup; - } - - if (snprintf(libvirtConf, sizeof(libvirtConf), "%s/.libvirt", pw->pw_dir) >= (int)sizeof(libvirtConf)) { - goto snprintf_cleanup; - } - if (mkdir(libvirtConf, 0777) < 0) { - if (errno != EEXIST) { - qemudLog(QEMUD_ERR, "Failed to create directory '%s': %s", - libvirtConf, strerror(errno)); - goto cleanup; - } - } - - - if (snprintf(server->configDir, sizeof(server->configDir), "%s/.libvirt/qemu", pw->pw_dir) >= (int)sizeof(server->configDir)) { - goto snprintf_cleanup; - } - - if (snprintf(server->networkConfigDir, sizeof(server->networkConfigDir), "%s/.libvirt/qemu/networks", pw->pw_dir) >= (int)sizeof(server->networkConfigDir)) { - goto snprintf_cleanup; - } - } - - - if (qemudListen(server, sys) < 0) { + if (qemudInitPaths(sys, server->configDir, server->networkConfigDir, + sockname, roSockname, PATH_MAX) < 0) + goto cleanup; + + if (qemudListenUnix(server, sockname, 0) < 0) + goto cleanup; + + if (roSockname[0] == '\0' && qemudListenUnix(server, roSockname, 1) < 0) goto cleanup; - } if (qemudScanConfigs(server) < 0) { goto cleanup; @@ -475,9 +485,6 @@ static struct qemud_server *qemudInitialize(int sys, int sigread) { return server; - snprintf_cleanup: - qemudLog(QEMUD_ERR, "Resulting path to long for buffer in qemudInitialize()"); - cleanup: if (server) { struct qemud_socket *sock = server->sockets;