Пример #1
0
virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
{
    virQEMUDriverConfigPtr cfg;

    if (virQEMUConfigInitialize() < 0)
        return NULL;

    if (!(cfg = virObjectNew(virQEMUDriverConfigClass)))
        return NULL;

    cfg->privileged = privileged;
    cfg->uri = privileged ? "qemu:///system" : "qemu:///session";

    if (privileged) {
        if (virGetUserID(QEMU_USER, &cfg->user) < 0)
            goto error;
        if (virGetGroupID(QEMU_GROUP, &cfg->group) < 0)
            goto error;
    } else {
        cfg->user = (uid_t)-1;
        cfg->group = (gid_t)-1;
    }
    cfg->dynamicOwnership = privileged;

    cfg->cgroupControllers = -1; /* -1 == auto-detect */

    if (privileged) {
        if (virAsprintf(&cfg->logDir,
                        "%s/log/libvirt/qemu", LOCALSTATEDIR) < 0)
            goto error;

        if (VIR_STRDUP(cfg->configBaseDir, SYSCONFDIR "/libvirt") < 0)
            goto error;

        if (virAsprintf(&cfg->stateDir,
                      "%s/run/libvirt/qemu", LOCALSTATEDIR) < 0)
            goto error;

        if (virAsprintf(&cfg->libDir,
                      "%s/lib/libvirt/qemu", LOCALSTATEDIR) < 0)
            goto error;

        if (virAsprintf(&cfg->cacheDir,
                      "%s/cache/libvirt/qemu", LOCALSTATEDIR) < 0)
            goto error;
        if (virAsprintf(&cfg->saveDir,
                      "%s/lib/libvirt/qemu/save", LOCALSTATEDIR) < 0)
            goto error;
        if (virAsprintf(&cfg->snapshotDir,
                        "%s/lib/libvirt/qemu/snapshot", LOCALSTATEDIR) < 0)
            goto error;
        if (virAsprintf(&cfg->autoDumpPath,
                        "%s/lib/libvirt/qemu/dump", LOCALSTATEDIR) < 0)
            goto error;
    } else {
        char *rundir;
        char *cachedir;

        cachedir = virGetUserCacheDirectory();
        if (!cachedir)
            goto error;

        if (virAsprintf(&cfg->logDir,
                        "%s/qemu/log", cachedir) < 0) {
            VIR_FREE(cachedir);
            goto error;
        }
        if (virAsprintf(&cfg->cacheDir, "%s/qemu/cache", cachedir) < 0) {
            VIR_FREE(cachedir);
            goto error;
        }
        VIR_FREE(cachedir);

        rundir = virGetUserRuntimeDirectory();
        if (!rundir)
            goto error;
        if (virAsprintf(&cfg->stateDir, "%s/qemu/run", rundir) < 0) {
            VIR_FREE(rundir);
            goto error;
        }
        VIR_FREE(rundir);

        if (!(cfg->configBaseDir = virGetUserConfigDirectory()))
            goto error;

        if (virAsprintf(&cfg->libDir, "%s/qemu/lib", cfg->configBaseDir) < 0)
            goto error;
        if (virAsprintf(&cfg->saveDir, "%s/qemu/save", cfg->configBaseDir) < 0)
            goto error;
        if (virAsprintf(&cfg->snapshotDir, "%s/qemu/snapshot", cfg->configBaseDir) < 0)
            goto error;
        if (virAsprintf(&cfg->autoDumpPath, "%s/qemu/dump", cfg->configBaseDir) < 0)
            goto error;
    }

    if (virAsprintf(&cfg->configDir, "%s/qemu", cfg->configBaseDir) < 0)
        goto error;
    if (virAsprintf(&cfg->autostartDir, "%s/qemu/autostart", cfg->configBaseDir) < 0)
        goto error;


    if (VIR_STRDUP(cfg->vncListen, "127.0.0.1") < 0)
        goto error;

    if (VIR_STRDUP(cfg->vncTLSx509certdir, SYSCONFDIR "/pki/libvirt-vnc") < 0)
        goto error;

    if (VIR_STRDUP(cfg->spiceListen, "127.0.0.1") < 0)
        goto error;

    if (VIR_STRDUP(cfg->spiceTLSx509certdir,
                   SYSCONFDIR "/pki/libvirt-spice") < 0)
        goto error;

    cfg->remotePortMin = QEMU_REMOTE_PORT_MIN;
    cfg->remotePortMax = QEMU_REMOTE_PORT_MAX;

    cfg->webSocketPortMin = QEMU_WEBSOCKET_PORT_MIN;
    cfg->webSocketPortMax = QEMU_WEBSOCKET_PORT_MAX;

    cfg->migrationPortMin = QEMU_MIGRATION_PORT_MIN;
    cfg->migrationPortMax = QEMU_MIGRATION_PORT_MAX;

#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
    /* For privileged driver, try and find hugepage mount automatically.
     * Non-privileged driver requires admin to create a dir for the
     * user, chown it, and then let user configure it manually */
    if (privileged &&
        !(cfg->hugetlbfsMount = virFileFindMountPoint("hugetlbfs"))) {
        if (errno != ENOENT) {
            virReportSystemError(errno, "%s",
                                 _("unable to find hugetlbfs mountpoint"));
            goto error;
        }
    }
#endif
    if (VIR_STRDUP(cfg->bridgeHelperName, "/usr/libexec/qemu-bridge-helper") < 0)
        goto error;

    cfg->clearEmulatorCapabilities = true;

    cfg->securityDefaultConfined = true;
    cfg->securityRequireConfined = false;

    cfg->keepAliveInterval = 5;
    cfg->keepAliveCount = 5;
    cfg->seccompSandbox = -1;

    return cfg;

error:
    virObjectUnref(cfg);
    return NULL;
}
Пример #2
0
int qemudLoadDriverConfig(struct qemud_driver *driver,
                          const char *filename) {
    virConfPtr conf;
    virConfValuePtr p;
    char *user;
    char *group;
    int i;

    /* Setup critical defaults */
    driver->dynamicOwnership = 1;
    driver->clearEmulatorCapabilities = 1;

    if (!(driver->vncListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }
    if (!(driver->vncTLSx509certdir = strdup(SYSCONFDIR "/pki/libvirt-vnc"))) {
        virReportOOMError();
        return -1;
    }

    if (!(driver->spiceListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }
    if (!(driver->spiceTLSx509certdir
          = strdup(SYSCONFDIR "/pki/libvirt-spice"))) {
        virReportOOMError();
        return -1;
    }

#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
    /* For privileged driver, try and find hugepage mount automatically.
     * Non-privileged driver requires admin to create a dir for the
     * user, chown it, and then let user configure it manually */
    if (driver->privileged &&
        !(driver->hugetlbfs_mount = virFileFindMountPoint("hugetlbfs"))) {
        if (errno != ENOENT) {
            virReportSystemError(errno, "%s",
                                 _("unable to find hugetlbfs mountpoint"));
            return -1;
        }
    }
#endif


    /* Just check the file is readable before opening it, otherwise
     * libvirt emits an error.
     */
    if (access (filename, R_OK) == -1) {
        VIR_INFO("Could not read qemu config file %s", filename);
        return 0;
    }

    conf = virConfReadFile (filename, 0);
    if (!conf) {
        return -1;
    }


#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) {               \
        qemuReportError(VIR_ERR_INTERNAL_ERROR,                         \
                        "%s: %s: expected type " #typ,                  \
                        filename, (name));                              \
        virConfFree(conf);                                              \
        return -1;                                                      \
    }

    p = virConfGetValue (conf, "vnc_auto_unix_socket");
    CHECK_TYPE ("vnc_auto_unix_socket", VIR_CONF_LONG);
    if (p) driver->vncAutoUnixSocket = p->l;

    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) {
        VIR_FREE(driver->vncTLSx509certdir);
        if (!(driver->vncTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_listen");
    CHECK_TYPE ("vnc_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncListen);
        if (!(driver->vncListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_password");
    CHECK_TYPE ("vnc_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncPassword);
        if (!(driver->vncPassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "security_driver");
    CHECK_TYPE ("security_driver", VIR_CONF_STRING);
    if (p && p->str) {
        if (!(driver->securityDriverName = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_sasl");
    CHECK_TYPE ("vnc_sasl", VIR_CONF_LONG);
    if (p) driver->vncSASL = p->l;

    p = virConfGetValue (conf, "vnc_sasl_dir");
    CHECK_TYPE ("vnc_sasl_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncSASLdir);
        if (!(driver->vncSASLdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_tls");
    CHECK_TYPE ("spice_tls", VIR_CONF_LONG);
    if (p) driver->spiceTLS = p->l;

    p = virConfGetValue (conf, "spice_tls_x509_cert_dir");
    CHECK_TYPE ("spice_tls_x509_cert_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceTLSx509certdir);
        if (!(driver->spiceTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_listen");
    CHECK_TYPE ("spice_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceListen);
        if (!(driver->spiceListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_password");
    CHECK_TYPE ("spice_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spicePassword);
        if (!(driver->spicePassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "user");
    CHECK_TYPE ("user", VIR_CONF_STRING);
    if (!(user = strdup(p && p->str ? p->str : QEMU_USER))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetUserID(user, &driver->user) < 0) {
        VIR_FREE(user);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(user);


    p = virConfGetValue (conf, "group");
    CHECK_TYPE ("group", VIR_CONF_STRING);
    if (!(group = strdup(p && p->str ? p->str : QEMU_GROUP))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetGroupID(group, &driver->group) < 0) {
        VIR_FREE(group);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(group);


    p = virConfGetValue (conf, "dynamic_ownership");
    CHECK_TYPE ("dynamic_ownership", VIR_CONF_LONG);
    if (p) driver->dynamicOwnership = p->l;


    p = virConfGetValue (conf, "cgroup_controllers");
    CHECK_TYPE ("cgroup_controllers", VIR_CONF_LIST);
    if (p) {
        virConfValuePtr pp;
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            int ctl;
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR0(_("cgroup_controllers must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            ctl = virCgroupControllerTypeFromString(pp->str);
            if (ctl < 0) {
                VIR_ERROR(_("Unknown cgroup controller '%s'"), pp->str);
                virConfFree(conf);
                return -1;
            }
            driver->cgroupControllers |= (1 << ctl);
        }
    } else {
        driver->cgroupControllers =
            (1 << VIR_CGROUP_CONTROLLER_CPU) |
            (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
            (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
            (1 << VIR_CGROUP_CONTROLLER_BLKIO);
    }
    for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
        if (driver->cgroupControllers & (1 << i)) {
            VIR_INFO("Configured cgroup controller '%s'",
                     virCgroupControllerTypeToString(i));
        }
    }

    p = virConfGetValue (conf, "cgroup_device_acl");
    CHECK_TYPE ("cgroup_device_acl", VIR_CONF_LIST);
    if (p) {
        int len = 0;
        virConfValuePtr pp;
        for (pp = p->list; pp; pp = pp->next)
            len++;
        if (VIR_ALLOC_N(driver->cgroupDeviceACL, 1+len) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR0(_("cgroup_device_acl must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            driver->cgroupDeviceACL[i] = strdup (pp->str);
            if (driver->cgroupDeviceACL[i] == NULL) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }

        }
        driver->cgroupDeviceACL[i] = NULL;
    }

    p = virConfGetValue (conf, "save_image_format");
    CHECK_TYPE ("save_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->saveImageFormat);
        if (!(driver->saveImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "dump_image_format");
    CHECK_TYPE ("dump_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->dumpImageFormat);
        if (!(driver->dumpImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "auto_dump_path");
    CHECK_TYPE ("auto_dump_path", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->autoDumpPath);
        if (!(driver->autoDumpPath = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

     p = virConfGetValue (conf, "hugetlbfs_mount");
     CHECK_TYPE ("hugetlbfs_mount", VIR_CONF_STRING);
     if (p && p->str) {
         VIR_FREE(driver->hugetlbfs_mount);
         if (!(driver->hugetlbfs_mount = strdup(p->str))) {
             virReportOOMError();
             virConfFree(conf);
             return -1;
         }
     }

    p = virConfGetValue (conf, "mac_filter");
    CHECK_TYPE ("mac_filter", VIR_CONF_LONG);
    if (p && p->l) {
        driver->macFilter = p->l;
        if (!(driver->ebtables = ebtablesContextNew("qemu"))) {
            driver->macFilter = 0;
            virReportSystemError(errno,
                                 _("failed to enable mac filter in '%s'"),
                                 __FILE__);
        }

        if ((errno = networkDisableAllFrames(driver))) {
            virReportSystemError(errno,
                         _("failed to add rule to drop all frames in '%s'"),
                                 __FILE__);
        }
    }

    p = virConfGetValue (conf, "relaxed_acs_check");
    CHECK_TYPE ("relaxed_acs_check", VIR_CONF_LONG);
    if (p) driver->relaxedACS = p->l;

    p = virConfGetValue (conf, "vnc_allow_host_audio");
    CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
    if (p) driver->vncAllowHostAudio = p->l;

    p = virConfGetValue (conf, "clear_emulator_capabilities");
    CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
    if (p) driver->clearEmulatorCapabilities = p->l;

    p = virConfGetValue (conf, "allow_disk_format_probing");
    CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
    if (p) driver->allowDiskFormatProbing = p->l;

    p = virConfGetValue (conf, "set_process_name");
    CHECK_TYPE ("set_process_name", VIR_CONF_LONG);
    if (p) driver->setProcessName = p->l;

    p = virConfGetValue(conf, "max_processes");
    CHECK_TYPE("max_processes", VIR_CONF_LONG);
    if (p) driver->maxProcesses = p->l;

    virConfFree (conf);
    return 0;
}
Пример #3
0
int qemudLoadDriverConfig(struct qemud_driver *driver,
                          const char *filename) {
    virConfPtr conf;
    virConfValuePtr p;
    char *user;
    char *group;
    int i;

    /* Setup critical defaults */
    driver->securityDefaultConfined = true;
    driver->securityRequireConfined = false;
    driver->dynamicOwnership = 1;
    driver->clearEmulatorCapabilities = 1;

    if (!(driver->vncListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }

    driver->remotePortMin = QEMU_REMOTE_PORT_MIN;
    driver->remotePortMax = QEMU_REMOTE_PORT_MAX;

    if (!(driver->vncTLSx509certdir = strdup(SYSCONFDIR "/pki/libvirt-vnc"))) {
        virReportOOMError();
        return -1;
    }

    if (!(driver->spiceListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }
    if (!(driver->spiceTLSx509certdir
          = strdup(SYSCONFDIR "/pki/libvirt-spice"))) {
        virReportOOMError();
        return -1;
    }

#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
    /* For privileged driver, try and find hugepage mount automatically.
     * Non-privileged driver requires admin to create a dir for the
     * user, chown it, and then let user configure it manually */
    if (driver->privileged &&
        !(driver->hugetlbfs_mount = virFileFindMountPoint("hugetlbfs"))) {
        if (errno != ENOENT) {
            virReportSystemError(errno, "%s",
                                 _("unable to find hugetlbfs mountpoint"));
            return -1;
        }
    }
#endif

    if (!(driver->lockManager =
          virLockManagerPluginNew("nop", NULL, 0)))
        return -1;

    driver->keepAliveInterval = 5;
    driver->keepAliveCount = 5;

    /* Just check the file is readable before opening it, otherwise
     * libvirt emits an error.
     */
    if (access (filename, R_OK) == -1) {
        VIR_INFO("Could not read qemu config file %s", filename);
        return 0;
    }

    conf = virConfReadFile (filename, 0);
    if (!conf) {
        return -1;
    }


#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) {               \
        virReportError(VIR_ERR_INTERNAL_ERROR,                          \
                       "%s: %s: expected type " #typ,                   \
                       filename, (name));                               \
        virConfFree(conf);                                              \
        return -1;                                                      \
    }

    p = virConfGetValue (conf, "vnc_auto_unix_socket");
    CHECK_TYPE ("vnc_auto_unix_socket", VIR_CONF_LONG);
    if (p) driver->vncAutoUnixSocket = p->l;

    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) {
        VIR_FREE(driver->vncTLSx509certdir);
        if (!(driver->vncTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_listen");
    CHECK_TYPE ("vnc_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncListen);
        if (!(driver->vncListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_password");
    CHECK_TYPE ("vnc_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncPassword);
        if (!(driver->vncPassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "security_driver");
    if (p && p->type == VIR_CONF_LIST) {
        size_t len;
        virConfValuePtr pp;

        /* Calc lenght and check items */
        for (len = 0, pp = p->list; pp; len++, pp = pp->next) {
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR(_("security_driver be a list of strings"));
                virConfFree(conf);
                return -1;
            }
        }

        if (VIR_ALLOC_N(driver->securityDriverNames, len + 1) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }

        for (i = 0, pp = p->list; pp; i++, pp = pp->next) {
            driver->securityDriverNames[i] = strdup(pp->str);
            if (driver->securityDriverNames == NULL) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }
        }
        driver->securityDriverNames[len] = NULL;
    } else {
        CHECK_TYPE ("security_driver", VIR_CONF_STRING);
        if (p && p->str) {
            if (VIR_ALLOC_N(driver->securityDriverNames, 2) < 0 ||
                !(driver->securityDriverNames[0] = strdup(p->str))) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }
            driver->securityDriverNames[1] = NULL;
        }
    }

    p = virConfGetValue (conf, "security_default_confined");
    CHECK_TYPE ("security_default_confined", VIR_CONF_LONG);
    if (p) driver->securityDefaultConfined = p->l;

    p = virConfGetValue (conf, "security_require_confined");
    CHECK_TYPE ("security_require_confined", VIR_CONF_LONG);
    if (p) driver->securityRequireConfined = p->l;


    p = virConfGetValue (conf, "vnc_sasl");
    CHECK_TYPE ("vnc_sasl", VIR_CONF_LONG);
    if (p) driver->vncSASL = p->l;

    p = virConfGetValue (conf, "vnc_sasl_dir");
    CHECK_TYPE ("vnc_sasl_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncSASLdir);
        if (!(driver->vncSASLdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_tls");
    CHECK_TYPE ("spice_tls", VIR_CONF_LONG);
    if (p) driver->spiceTLS = p->l;

    p = virConfGetValue (conf, "spice_tls_x509_cert_dir");
    CHECK_TYPE ("spice_tls_x509_cert_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceTLSx509certdir);
        if (!(driver->spiceTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_listen");
    CHECK_TYPE ("spice_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceListen);
        if (!(driver->spiceListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_password");
    CHECK_TYPE ("spice_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spicePassword);
        if (!(driver->spicePassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "remote_display_port_min");
    CHECK_TYPE ("remote_display_port_min", VIR_CONF_LONG);
    if (p) {
        if (p->l < QEMU_REMOTE_PORT_MIN) {
            /* if the port is too low, we can't get the display name
             * to tell to vnc (usually subtract 5900, e.g. localhost:1
             * for port 5901) */
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("%s: remote_display_port_min: port must be greater than or equal to %d"),
                            filename, QEMU_REMOTE_PORT_MIN);
            virConfFree(conf);
            return -1;
        }
        driver->remotePortMin = p->l;
    }

    p = virConfGetValue (conf, "remote_display_port_max");
    CHECK_TYPE ("remote_display_port_max", VIR_CONF_LONG);
    if (p) {
        if (p->l > QEMU_REMOTE_PORT_MAX ||
            p->l < driver->remotePortMin) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("%s: remote_display_port_max: port must be between the minimal port and %d"),
                            filename, QEMU_REMOTE_PORT_MAX);
            virConfFree(conf);
            return -1;
        }
        /* increasing the value by 1 makes all the loops going through
        the bitmap (i = remotePortMin; i < remotePortMax; i++), work as
        expected. */
        driver->remotePortMax = p->l + 1;
    }

    if (driver->remotePortMin > driver->remotePortMax) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("%s: remote_display_port_min: min port must not be greater than max port"),
                        filename);
        virConfFree(conf);
        return -1;
    }

    p = virConfGetValue (conf, "user");
    CHECK_TYPE ("user", VIR_CONF_STRING);
    if (!(user = strdup(p && p->str ? p->str : QEMU_USER))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetUserID(user, &driver->user) < 0) {
        VIR_FREE(user);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(user);


    p = virConfGetValue (conf, "group");
    CHECK_TYPE ("group", VIR_CONF_STRING);
    if (!(group = strdup(p && p->str ? p->str : QEMU_GROUP))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetGroupID(group, &driver->group) < 0) {
        VIR_FREE(group);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(group);


    p = virConfGetValue (conf, "dynamic_ownership");
    CHECK_TYPE ("dynamic_ownership", VIR_CONF_LONG);
    if (p) driver->dynamicOwnership = p->l;


    p = virConfGetValue (conf, "cgroup_controllers");
    CHECK_TYPE ("cgroup_controllers", VIR_CONF_LIST);
    if (p) {
        virConfValuePtr pp;
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            int ctl;
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR(_("cgroup_controllers must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            ctl = virCgroupControllerTypeFromString(pp->str);
            if (ctl < 0) {
                VIR_ERROR(_("Unknown cgroup controller '%s'"), pp->str);
                virConfFree(conf);
                return -1;
            }
            driver->cgroupControllers |= (1 << ctl);
        }
    } else {
        driver->cgroupControllers =
            (1 << VIR_CGROUP_CONTROLLER_CPU) |
            (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
            (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
            (1 << VIR_CGROUP_CONTROLLER_BLKIO) |
            (1 << VIR_CGROUP_CONTROLLER_CPUSET) |
            (1 << VIR_CGROUP_CONTROLLER_CPUACCT);
    }
    for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
        if (driver->cgroupControllers & (1 << i)) {
            VIR_INFO("Configured cgroup controller '%s'",
                     virCgroupControllerTypeToString(i));
        }
    }

    p = virConfGetValue (conf, "cgroup_device_acl");
    CHECK_TYPE ("cgroup_device_acl", VIR_CONF_LIST);
    if (p) {
        int len = 0;
        virConfValuePtr pp;
        for (pp = p->list; pp; pp = pp->next)
            len++;
        if (VIR_ALLOC_N(driver->cgroupDeviceACL, 1+len) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR(_("cgroup_device_acl must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            driver->cgroupDeviceACL[i] = strdup (pp->str);
            if (driver->cgroupDeviceACL[i] == NULL) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }

        }
        driver->cgroupDeviceACL[i] = NULL;
    }

    p = virConfGetValue (conf, "save_image_format");
    CHECK_TYPE ("save_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->saveImageFormat);
        if (!(driver->saveImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "dump_image_format");
    CHECK_TYPE ("dump_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->dumpImageFormat);
        if (!(driver->dumpImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "auto_dump_path");
    CHECK_TYPE ("auto_dump_path", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->autoDumpPath);
        if (!(driver->autoDumpPath = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "auto_dump_bypass_cache");
    CHECK_TYPE ("auto_dump_bypass_cache", VIR_CONF_LONG);
    if (p) driver->autoDumpBypassCache = true;

    p = virConfGetValue (conf, "auto_start_bypass_cache");
    CHECK_TYPE ("auto_start_bypass_cache", VIR_CONF_LONG);
    if (p) driver->autoStartBypassCache = true;

    p = virConfGetValue (conf, "hugetlbfs_mount");
    CHECK_TYPE ("hugetlbfs_mount", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->hugetlbfs_mount);
        if (!(driver->hugetlbfs_mount = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "mac_filter");
    CHECK_TYPE ("mac_filter", VIR_CONF_LONG);
    if (p && p->l) {
        driver->macFilter = p->l;
        if (!(driver->ebtables = ebtablesContextNew("qemu"))) {
            driver->macFilter = 0;
            virReportSystemError(errno,
                                 _("failed to enable mac filter in '%s'"),
                                 __FILE__);
            virConfFree(conf);
            return -1;
        }

        if ((errno = networkDisableAllFrames(driver))) {
            virReportSystemError(errno,
                         _("failed to add rule to drop all frames in '%s'"),
                                 __FILE__);
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "relaxed_acs_check");
    CHECK_TYPE ("relaxed_acs_check", VIR_CONF_LONG);
    if (p) driver->relaxedACS = p->l;

    p = virConfGetValue (conf, "vnc_allow_host_audio");
    CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
    if (p) driver->vncAllowHostAudio = p->l;

    p = virConfGetValue (conf, "clear_emulator_capabilities");
    CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
    if (p) driver->clearEmulatorCapabilities = p->l;

    p = virConfGetValue (conf, "allow_disk_format_probing");
    CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
    if (p) driver->allowDiskFormatProbing = p->l;

    p = virConfGetValue (conf, "set_process_name");
    CHECK_TYPE ("set_process_name", VIR_CONF_LONG);
    if (p) driver->setProcessName = p->l;

    p = virConfGetValue(conf, "max_processes");
    CHECK_TYPE("max_processes", VIR_CONF_LONG);
    if (p) driver->maxProcesses = p->l;

    p = virConfGetValue(conf, "max_files");
    CHECK_TYPE("max_files", VIR_CONF_LONG);
    if (p) driver->maxFiles = p->l;

    p = virConfGetValue (conf, "lock_manager");
    CHECK_TYPE ("lock_manager", VIR_CONF_STRING);
    if (p && p->str) {
        char *lockConf;
        virLockManagerPluginUnref(driver->lockManager);
        if (virAsprintf(&lockConf, "%s/libvirt/qemu-%s.conf", SYSCONFDIR, p->str) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
        if (!(driver->lockManager =
              virLockManagerPluginNew(p->str, lockConf, 0)))
            VIR_ERROR(_("Failed to load lock manager %s"), p->str);
        VIR_FREE(lockConf);
    }

    p = virConfGetValue(conf, "max_queued");
    CHECK_TYPE("max_queued", VIR_CONF_LONG);
    if (p) driver->max_queued = p->l;

    p = virConfGetValue(conf, "keepalive_interval");
    CHECK_TYPE("keepalive_interval", VIR_CONF_LONG);
    if (p) driver->keepAliveInterval = p->l;

    p = virConfGetValue(conf, "keepalive_count");
    CHECK_TYPE("keepalive_count", VIR_CONF_LONG);
    if (p) driver->keepAliveCount = p->l;

    virConfFree (conf);
    return 0;
}