From 912c18afa3eaa85d0679d1c2b3c188fb85ccda06 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 12 Oct 2007 16:05:44 +0000 Subject: [PATCH] Added QEMU driver config file --- ChangeLog | 6 ++++ src/qemu_conf.c | 90 +++++++++++++++++++++++++++++++++++++++++++---- src/qemu_conf.h | 6 ++++ src/qemu_driver.c | 29 ++++++++++----- 4 files changed, 117 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec241182c4..f33ca380ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Oct 12 12:05:53 EST 2007 Daniel P. Berrange + + * src/qemu_driver.c, src/qemu_conf.c, src/qemu_conf.h: Add a + /etc/libvirt/qemu.conf for storing system wide QEMU driver + default settings, such as VNC server options. + Wed Oct 10 15:44:53 EST 2007 Daniel P. Berrange * src/qemu_driver.c: Reset migration source after failed attempt diff --git a/src/qemu_conf.c b/src/qemu_conf.c index eda181cde9..f3b8f4e6cc 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -45,6 +45,7 @@ #include "qemu_conf.h" #include "uuid.h" #include "buf.h" +#include "conf.h" #define qemudLog(level, msg...) fprintf(stderr, msg) @@ -66,6 +67,68 @@ void qemudReportError(virConnectPtr conn, NULL, NULL, NULL, -1, -1, errorMessage); } +int qemudLoadDriverConfig(struct qemud_driver *driver, + const char *filename) { + virConfPtr conf; + virConfValuePtr p; + + /* Setup 2 critical defaults */ + strcpy(driver->vncListen, "127.0.0.1"); + if (!(driver->vncTLSx509certdir = strdup(SYSCONF_DIR "/pki/libvirt-vnc"))) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY, + "vncTLSx509certdir"); + return -1; + } + + /* Just check the file is readable before opening it, otherwise + * libvirt emits an error. + */ + if (access (filename, R_OK) == -1) return 0; + + conf = virConfReadFile (filename); + if (!conf) return 0; + + +#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) { \ + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, \ + "remoteReadConfigFile: %s: %s: expected type " #typ "\n", \ + filename, (name)); \ + virConfFree(conf); \ + return -1; \ + } + + p = virConfGetValue (conf, "vnc_tls"); + CHECK_TYPE ("vnc_tls", VIR_CONF_LONG); + if (p) driver->vncTLS = p->l; + + p = virConfGetValue (conf, "vnc_tls_x509_verify"); + CHECK_TYPE ("vnc_tls_x509_verify", VIR_CONF_LONG); + if (p) driver->vncTLSx509verify = p->l; + + p = virConfGetValue (conf, "vnc_tls_x509_cert_dir"); + CHECK_TYPE ("vnc_tls_x509_cert_dir", VIR_CONF_STRING); + if (p && p->str) { + free(driver->vncTLSx509certdir); + if (!(driver->vncTLSx509certdir = strdup(p->str))) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY, + "vncTLSx509certdir"); + virConfFree(conf); + return -1; + } + } + + p = virConfGetValue (conf, "vnc_listen"); + CHECK_TYPE ("vnc_listen", VIR_CONF_STRING); + if (p && p->str) { + strncpy(driver->vncListen, p->str, sizeof(driver->vncListen)); + driver->vncListen[sizeof(driver->vncListen)-1] = '\0'; + } + + virConfFree (conf); + return 0; +} + + struct qemud_vm *qemudFindVMByID(const struct qemud_driver *driver, int id) { struct qemud_vm *vm = driver->vms; @@ -1234,7 +1297,7 @@ static struct qemud_vm_def *qemudParseXML(virConnectPtr conn, if (vnclisten && *vnclisten) strncpy(def->vncListen, (char *)vnclisten, BR_INET_ADDR_MAXLEN-1); else - strcpy(def->vncListen, "127.0.0.1"); + strcpy(def->vncListen, driver->vncListen); def->vncListen[BR_INET_ADDR_MAXLEN-1] = '\0'; xmlFree(vncport); xmlFree(vnclisten); @@ -1750,15 +1813,30 @@ int qemudBuildCommandLine(virConnectPtr conn, } if (vm->def->graphicsType == QEMUD_GRAPHICS_VNC) { - char vncdisplay[BR_INET_ADDR_MAXLEN+20]; + char vncdisplay[PATH_MAX]; int ret; - if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) - ret = snprintf(vncdisplay, sizeof(vncdisplay), "%s:%d", + + if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) { + char options[PATH_MAX] = ""; + if (driver->vncTLS) { + strcat(options, ",tls"); + if (driver->vncTLSx509verify) { + strcat(options, ",x509verify="); + } else { + strcat(options, ",x509="); + } + strncat(options, driver->vncTLSx509certdir, + sizeof(options) - (strlen(driver->vncTLSx509certdir)-1)); + options[sizeof(options)-1] = '\0'; + } + ret = snprintf(vncdisplay, sizeof(vncdisplay), "%s:%d%s", vm->def->vncListen, - vm->def->vncActivePort - 5900); - else + vm->def->vncActivePort - 5900, + options); + } else { ret = snprintf(vncdisplay, sizeof(vncdisplay), "%d", vm->def->vncActivePort - 5900); + } if (ret < 0 || ret >= (int)sizeof(vncdisplay)) goto error; diff --git a/src/qemu_conf.h b/src/qemu_conf.h index 65443f38e4..e1844da05a 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -289,6 +289,10 @@ struct qemud_driver { char *networkConfigDir; char *networkAutostartDir; char logDir[PATH_MAX]; + int vncTLS : 1; + int vncTLSx509verify : 1; + char *vncTLSx509certdir; + char vncListen[BR_INET_ADDR_MAXLEN]; }; @@ -311,6 +315,8 @@ void qemudReportError(virConnectPtr conn, ATTRIBUTE_FORMAT(printf,5,6); +int qemudLoadDriverConfig(struct qemud_driver *driver, + const char *filename); struct qemud_vm *qemudFindVMByID(const struct qemud_driver *driver, int id); diff --git a/src/qemu_driver.c b/src/qemu_driver.c index bff17b0d10..c9cecc09a8 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -155,6 +155,7 @@ qemudStartup(void) { uid_t uid = geteuid(); struct passwd *pw; char *base = NULL; + char driverConf[PATH_MAX]; if (!(qemu_driver = calloc(1, sizeof(struct qemud_driver)))) { return -1; @@ -167,7 +168,7 @@ qemudStartup(void) { if (snprintf(qemu_driver->logDir, PATH_MAX, "%s/log/libvirt/qemu", LOCAL_STATE_DIR) >= PATH_MAX) goto snprintf_error; - if ((base = strdup (SYSCONF_DIR "/libvirt/qemu")) == NULL) + if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL) goto out_of_memory; } else { if (!(pw = getpwuid(uid))) { @@ -179,7 +180,7 @@ qemudStartup(void) { if (snprintf(qemu_driver->logDir, PATH_MAX, "%s/.libvirt/qemu/log", pw->pw_dir) >= PATH_MAX) goto snprintf_error; - if (asprintf (&base, "%s/.libvirt/qemu", pw->pw_dir) == -1) { + if (asprintf (&base, "%s/.libvirt", pw->pw_dir) == -1) { qemudLog (QEMUD_ERR, "out of memory in asprintf"); goto out_of_memory; } @@ -188,24 +189,36 @@ qemudStartup(void) { /* Configuration paths are either ~/.libvirt/qemu/... (session) or * /etc/libvirt/qemu/... (system). */ - if (asprintf (&qemu_driver->configDir, "%s", base) == -1) + if (snprintf (driverConf, sizeof(driverConf), "%s/qemu.conf", base) == -1) + goto out_of_memory; + driverConf[sizeof(driverConf)-1] = '\0'; + + if (asprintf (&qemu_driver->configDir, "%s/qemu", base) == -1) goto out_of_memory; - if (asprintf (&qemu_driver->autostartDir, "%s/autostart", base) == -1) + if (asprintf (&qemu_driver->autostartDir, "%s/qemu/autostart", base) == -1) goto out_of_memory; - if (asprintf (&qemu_driver->networkConfigDir, "%s/networks", base) == -1) + if (asprintf (&qemu_driver->networkConfigDir, "%s/qemu/networks", base) == -1) goto out_of_memory; - if (asprintf (&qemu_driver->networkAutostartDir, "%s/networks/autostart", + if (asprintf (&qemu_driver->networkAutostartDir, "%s/qemu/networks/autostart", base) == -1) goto out_of_memory; - if (qemudScanConfigs(qemu_driver) < 0) + free(base); + + if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) { qemudShutdown(); + return -1; + } + + if (qemudScanConfigs(qemu_driver) < 0) { + qemudShutdown(); + return -1; + } qemudAutostartConfigs(qemu_driver); - free(base); return 0; snprintf_error: