static int parseIds(const char *label, uid_t *uidPtr, gid_t *gidPtr) { int rc = -1; unsigned int theuid; unsigned int thegid; char *tmp_label = NULL; char *sep = NULL; char *owner = NULL; char *group = NULL; tmp_label = strdup(label); if (tmp_label == NULL) { virReportOOMError(); goto cleanup; } /* Split label */ sep = strchr(tmp_label, ':'); if (sep == NULL) { virReportError(VIR_ERR_INVALID_ARG, _("Missing separator ':' in DAC label \"%s\""), label); goto cleanup; } *sep = '\0'; owner = tmp_label; group = sep + 1; /* Parse owner */ if (*owner == '+') { if (virStrToLong_ui(++owner, NULL, 10, &theuid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid uid \"%s\" in DAC label \"%s\""), owner, label); goto cleanup; } } else { if (virGetUserID(owner, &theuid) < 0 && virStrToLong_ui(owner, NULL, 10, &theuid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid owner \"%s\" in DAC label \"%s\""), owner, label); goto cleanup; } } /* Parse group */ if (*group == '+') { if (virStrToLong_ui(++group, NULL, 10, &thegid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid gid \"%s\" in DAC label \"%s\""), group, label); goto cleanup; } } else { if (virGetGroupID(group, &thegid) < 0 && virStrToLong_ui(group, NULL, 10, &thegid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid group \"%s\" in DAC label \"%s\""), group, label); goto cleanup; } } if (uidPtr) *uidPtr = theuid; if (gidPtr) *gidPtr = thegid; rc = 0; cleanup: VIR_FREE(tmp_label); return rc; }
/* * sanlock plugin for the libvirt virLockManager API */ static int virLockManagerSanlockLoadConfig(const char *configFile) { virConfPtr conf; virConfValuePtr p; char *tmp; if (access(configFile, R_OK) == -1) { if (errno != ENOENT) { virReportSystemError(errno, _("Unable to access config file %s"), configFile); return -1; } return 0; } if (!(conf = virConfReadFile(configFile, 0))) return -1; #define CHECK_TYPE(name,typ) if (p && p->type != (typ)) { \ virReportError(VIR_ERR_INTERNAL_ERROR, \ "%s: %s: expected type " #typ, \ configFile, (name)); \ virConfFree(conf); \ return -1; \ } p = virConfGetValue(conf, "auto_disk_leases"); CHECK_TYPE("auto_disk_leases", VIR_CONF_LONG); if (p) driver->autoDiskLease = p->l; p = virConfGetValue(conf, "disk_lease_dir"); CHECK_TYPE("disk_lease_dir", VIR_CONF_STRING); if (p && p->str) { VIR_FREE(driver->autoDiskLeasePath); if (!(driver->autoDiskLeasePath = strdup(p->str))) { virReportOOMError(); virConfFree(conf); return -1; } } p = virConfGetValue(conf, "host_id"); CHECK_TYPE("host_id", VIR_CONF_LONG); if (p) driver->hostID = p->l; p = virConfGetValue(conf, "require_lease_for_disks"); CHECK_TYPE("require_lease_for_disks", VIR_CONF_LONG); if (p) driver->requireLeaseForDisks = p->l; else driver->requireLeaseForDisks = !driver->autoDiskLease; p = virConfGetValue(conf, "user"); CHECK_TYPE("user", VIR_CONF_STRING); if (p) { if (!(tmp = strdup(p->str))) { virReportOOMError(); virConfFree(conf); return -1; } if (virGetUserID(tmp, &driver->user) < 0) { VIR_FREE(tmp); virConfFree(conf); return -1; } VIR_FREE(tmp); } p = virConfGetValue (conf, "group"); CHECK_TYPE ("group", VIR_CONF_STRING); if (p) { if (!(tmp = strdup(p->str))) { virReportOOMError(); virConfFree(conf); return -1; } if (virGetGroupID(tmp, &driver->group) < 0) { VIR_FREE(tmp); virConfFree(conf); return -1; } VIR_FREE(tmp); } virConfFree(conf); return 0; }
int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, const char *filename) { virConfPtr conf = NULL; virConfValuePtr p; int ret = -1; size_t i; char *stdioHandler = NULL; /* 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; } if (!(conf = virConfReadFile(filename, 0))) goto cleanup; #define CHECK_TYPE(name, typ) \ if (p && p->type != (typ)) { \ virReportError(VIR_ERR_INTERNAL_ERROR, \ "%s: %s: expected type " #typ, \ filename, (name)); \ goto cleanup; \ } #define CHECK_TYPE_ALT(name, type1, type2) \ if (p && (p->type != (type1) && p->type != (type2))) { \ virReportError(VIR_ERR_INTERNAL_ERROR, \ "%s: %s: expected type " #type1, \ filename, (name)); \ goto cleanup; \ } #define GET_VALUE_LONG(NAME, VAR) \ p = virConfGetValue(conf, NAME); \ CHECK_TYPE_ALT(NAME, VIR_CONF_LONG, VIR_CONF_ULONG); \ if (p) \ VAR = p->l; #define GET_VALUE_ULONG(NAME, VAR) \ p = virConfGetValue(conf, NAME); \ CHECK_TYPE(NAME, VIR_CONF_ULONG); \ if (p) \ VAR = p->l; #define GET_VALUE_BOOL(NAME, VAR) \ p = virConfGetValue(conf, NAME); \ CHECK_TYPE(NAME, VIR_CONF_ULONG); \ if (p) \ VAR = p->l != 0; #define GET_VALUE_STR(NAME, VAR) \ p = virConfGetValue(conf, NAME); \ CHECK_TYPE(NAME, VIR_CONF_STRING); \ if (p && p->str) { \ VIR_FREE(VAR); \ if (VIR_STRDUP(VAR, p->str) < 0) \ goto cleanup; \ } GET_VALUE_BOOL("vnc_auto_unix_socket", cfg->vncAutoUnixSocket); GET_VALUE_BOOL("vnc_tls", cfg->vncTLS); GET_VALUE_BOOL("vnc_tls_x509_verify", cfg->vncTLSx509verify); GET_VALUE_STR("vnc_tls_x509_cert_dir", cfg->vncTLSx509certdir); GET_VALUE_STR("vnc_listen", cfg->vncListen); GET_VALUE_STR("vnc_password", cfg->vncPassword); GET_VALUE_BOOL("vnc_sasl", cfg->vncSASL); GET_VALUE_STR("vnc_sasl_dir", cfg->vncSASLdir); GET_VALUE_BOOL("vnc_allow_host_audio", cfg->vncAllowHostAudio); GET_VALUE_BOOL("nographics_allow_host_audio", cfg->nogfxAllowHostAudio); p = virConfGetValue(conf, "security_driver"); if (p && p->type == VIR_CONF_LIST) { size_t len, j; virConfValuePtr pp; /* Calc length and check items */ for (len = 0, pp = p->list; pp; len++, pp = pp->next) { if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("security_driver must be a list of strings")); goto cleanup; } } if (VIR_ALLOC_N(cfg->securityDriverNames, len + 1) < 0) goto cleanup; for (i = 0, pp = p->list; pp; i++, pp = pp->next) { for (j = 0; j < i; j++) { if (STREQ(pp->str, cfg->securityDriverNames[j])) { virReportError(VIR_ERR_CONF_SYNTAX, _("Duplicate security driver %s"), pp->str); goto cleanup; } } if (VIR_STRDUP(cfg->securityDriverNames[i], pp->str) < 0) goto cleanup; } cfg->securityDriverNames[len] = NULL; } else { CHECK_TYPE("security_driver", VIR_CONF_STRING); if (p && p->str) { if (VIR_ALLOC_N(cfg->securityDriverNames, 2) < 0) goto cleanup; if (VIR_STRDUP(cfg->securityDriverNames[0], p->str) < 0) goto cleanup; cfg->securityDriverNames[1] = NULL; } } GET_VALUE_BOOL("security_default_confined", cfg->securityDefaultConfined); GET_VALUE_BOOL("security_require_confined", cfg->securityRequireConfined); GET_VALUE_BOOL("spice_tls", cfg->spiceTLS); GET_VALUE_STR("spice_tls_x509_cert_dir", cfg->spiceTLSx509certdir); GET_VALUE_BOOL("spice_sasl", cfg->spiceSASL); GET_VALUE_STR("spice_sasl_dir", cfg->spiceSASLdir); GET_VALUE_STR("spice_listen", cfg->spiceListen); GET_VALUE_STR("spice_password", cfg->spicePassword); GET_VALUE_BOOL("spice_auto_unix_socket", cfg->spiceAutoUnixSocket); GET_VALUE_ULONG("remote_websocket_port_min", cfg->webSocketPortMin); if (cfg->webSocketPortMin < QEMU_WEBSOCKET_PORT_MIN) { /* if the port is too low, we can't get the display name * to tell to vnc (usually subtract 5700, e.g. localhost:1 * for port 5701) */ virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_websocket_port_min: port must be greater " "than or equal to %d"), filename, QEMU_WEBSOCKET_PORT_MIN); goto cleanup; } GET_VALUE_ULONG("remote_websocket_port_max", cfg->webSocketPortMax); if (cfg->webSocketPortMax > QEMU_WEBSOCKET_PORT_MAX || cfg->webSocketPortMax < cfg->webSocketPortMin) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_websocket_port_max: port must be between " "the minimal port and %d"), filename, QEMU_WEBSOCKET_PORT_MAX); goto cleanup; } if (cfg->webSocketPortMin > cfg->webSocketPortMax) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_websocket_port_min: min port must not be " "greater than max port"), filename); goto cleanup; } GET_VALUE_ULONG("remote_display_port_min", cfg->remotePortMin); if (cfg->remotePortMin < 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); goto cleanup; } GET_VALUE_ULONG("remote_display_port_max", cfg->remotePortMax); if (cfg->remotePortMax > QEMU_REMOTE_PORT_MAX || cfg->remotePortMax < cfg->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); goto cleanup; } if (cfg->remotePortMin > cfg->remotePortMax) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_display_port_min: min port must not be " "greater than max port"), filename); goto cleanup; } GET_VALUE_ULONG("migration_port_min", cfg->migrationPortMin); if (cfg->migrationPortMin <= 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: migration_port_min: port must be greater than 0"), filename); goto cleanup; } GET_VALUE_ULONG("migration_port_max", cfg->migrationPortMax); if (cfg->migrationPortMax > 65535 || cfg->migrationPortMax < cfg->migrationPortMin) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: migration_port_max: port must be between " "the minimal port %d and 65535"), filename, cfg->migrationPortMin); goto cleanup; } p = virConfGetValue(conf, "user"); CHECK_TYPE("user", VIR_CONF_STRING); if (p && p->str && virGetUserID(p->str, &cfg->user) < 0) goto cleanup; p = virConfGetValue(conf, "group"); CHECK_TYPE("group", VIR_CONF_STRING); if (p && p->str && virGetGroupID(p->str, &cfg->group) < 0) goto cleanup; GET_VALUE_BOOL("dynamic_ownership", cfg->dynamicOwnership); p = virConfGetValue(conf, "cgroup_controllers"); CHECK_TYPE("cgroup_controllers", VIR_CONF_LIST); if (p) { cfg->cgroupControllers = 0; virConfValuePtr pp; for (i = 0, pp = p->list; pp; ++i, pp = pp->next) { int ctl; if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("cgroup_controllers must be a " "list of strings")); goto cleanup; } if ((ctl = virCgroupControllerTypeFromString(pp->str)) < 0) { virReportError(VIR_ERR_CONF_SYNTAX, _("Unknown cgroup controller '%s'"), pp->str); goto cleanup; } cfg->cgroupControllers |= (1 << ctl); } } 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(cfg->cgroupDeviceACL, 1+len) < 0) goto cleanup; for (i = 0, pp = p->list; pp; ++i, pp = pp->next) { if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("cgroup_device_acl must be a " "list of strings")); goto cleanup; } if (VIR_STRDUP(cfg->cgroupDeviceACL[i], pp->str) < 0) goto cleanup; } cfg->cgroupDeviceACL[i] = NULL; } GET_VALUE_STR("save_image_format", cfg->saveImageFormat); GET_VALUE_STR("dump_image_format", cfg->dumpImageFormat); GET_VALUE_STR("snapshot_image_format", cfg->snapshotImageFormat); GET_VALUE_STR("auto_dump_path", cfg->autoDumpPath); GET_VALUE_BOOL("auto_dump_bypass_cache", cfg->autoDumpBypassCache); GET_VALUE_BOOL("auto_start_bypass_cache", cfg->autoStartBypassCache); /* Some crazy backcompat. Back in the old days, this was just a pure * string. We must continue supporting it. These days however, this may be * an array of strings. */ p = virConfGetValue(conf, "hugetlbfs_mount"); if (p) { /* There already might be something autodetected. Avoid leaking it. */ while (cfg->nhugetlbfs) { cfg->nhugetlbfs--; VIR_FREE(cfg->hugetlbfs[cfg->nhugetlbfs].mnt_dir); } VIR_FREE(cfg->hugetlbfs); if (p->type == VIR_CONF_LIST) { size_t len = 0; virConfValuePtr pp = p->list; /* Calc length and check items */ while (pp) { if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("hugetlbfs_mount must be a list of strings")); goto cleanup; } len++; pp = pp->next; } if (len && VIR_ALLOC_N(cfg->hugetlbfs, len) < 0) goto cleanup; cfg->nhugetlbfs = len; pp = p->list; len = 0; while (pp) { if (virQEMUDriverConfigHugeTLBFSInit(&cfg->hugetlbfs[len], pp->str, !len) < 0) goto cleanup; len++; pp = pp->next; } } else { CHECK_TYPE("hugetlbfs_mount", VIR_CONF_STRING); if (STRNEQ(p->str, "")) { if (VIR_ALLOC_N(cfg->hugetlbfs, 1) < 0) goto cleanup; cfg->nhugetlbfs = 1; if (virQEMUDriverConfigHugeTLBFSInit(&cfg->hugetlbfs[0], p->str, true) < 0) goto cleanup; } } } GET_VALUE_STR("bridge_helper", cfg->bridgeHelperName); GET_VALUE_BOOL("mac_filter", cfg->macFilter); GET_VALUE_BOOL("relaxed_acs_check", cfg->relaxedACS); GET_VALUE_BOOL("clear_emulator_capabilities", cfg->clearEmulatorCapabilities); GET_VALUE_BOOL("allow_disk_format_probing", cfg->allowDiskFormatProbing); GET_VALUE_BOOL("set_process_name", cfg->setProcessName); GET_VALUE_ULONG("max_processes", cfg->maxProcesses); GET_VALUE_ULONG("max_files", cfg->maxFiles); GET_VALUE_STR("lock_manager", cfg->lockManagerName); GET_VALUE_STR("stdio_handler", stdioHandler); if (stdioHandler) { if (STREQ(stdioHandler, "logd")) { cfg->stdioLogD = true; } else if (STREQ(stdioHandler, "file")) { cfg->stdioLogD = false; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown stdio handler %s"), stdioHandler); VIR_FREE(stdioHandler); goto cleanup; } VIR_FREE(stdioHandler); } GET_VALUE_ULONG("max_queued", cfg->maxQueuedJobs); GET_VALUE_LONG("keepalive_interval", cfg->keepAliveInterval); GET_VALUE_ULONG("keepalive_count", cfg->keepAliveCount); GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox); GET_VALUE_STR("migration_host", cfg->migrateHost); virStringStripIPv6Brackets(cfg->migrateHost); if (cfg->migrateHost && (STRPREFIX(cfg->migrateHost, "localhost") || virSocketAddrIsNumericLocalhost(cfg->migrateHost))) { virReportError(VIR_ERR_CONF_SYNTAX, _("migration_host must not be the address of" " the local machine: %s"), cfg->migrateHost); goto cleanup; } GET_VALUE_STR("migration_address", cfg->migrationAddress); virStringStripIPv6Brackets(cfg->migrationAddress); if (cfg->migrationAddress && (STRPREFIX(cfg->migrationAddress, "localhost") || virSocketAddrIsNumericLocalhost(cfg->migrationAddress))) { virReportError(VIR_ERR_CONF_SYNTAX, _("migration_address must not be the address of" " the local machine: %s"), cfg->migrationAddress); goto cleanup; } GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp); if ((p = virConfGetValue(conf, "nvram"))) { size_t len; virConfValuePtr pp; CHECK_TYPE("nvram", VIR_CONF_LIST); virFirmwareFreeList(cfg->firmwares, cfg->nfirmwares); /* Calc length and check items */ for (len = 0, pp = p->list; pp; len++, pp = pp->next) { if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("nvram must be a list of strings")); goto cleanup; } } if (len && VIR_ALLOC_N(cfg->firmwares, len) < 0) goto cleanup; cfg->nfirmwares = len; for (i = 0, pp = p->list; pp; i++, pp = pp->next) { if (VIR_ALLOC(cfg->firmwares[i]) < 0) goto cleanup; if (virFirmwareParse(pp->str, cfg->firmwares[i]) < 0) goto cleanup; } } ret = 0; cleanup: virConfFree(conf); return ret; }
static int daemonSetupNetworking(virNetServerPtr srv, struct daemonConfig *config, const char *sock_path, const char *sock_path_ro, bool ipsock, bool privileged) { virNetServerServicePtr svc = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; virNetServerServicePtr svcTLS = NULL; gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; if (config->unix_sock_group) { if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0) return -1; } if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms); goto error; } if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms); goto error; } if (!(svc = virNetServerServiceNewUNIX(sock_path, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, false, config->max_client_requests, NULL))) goto error; if (sock_path_ro && !(svcRO = virNetServerServiceNewUNIX(sock_path_ro, unix_sock_ro_mask, unix_sock_gid, config->auth_unix_ro, true, config->max_client_requests, NULL))) goto error; if (virNetServerAddService(srv, svc, config->mdns_adv && !ipsock ? "_libvirt._tcp" : NULL) < 0) goto error; if (svcRO && virNetServerAddService(srv, svcRO, NULL) < 0) goto error; if (ipsock) { if (config->listen_tcp) { if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, config->auth_tcp, false, config->max_client_requests, NULL))) goto error; if (virNetServerAddService(srv, svcTCP, config->mdns_adv ? "_libvirt._tcp" : NULL) < 0) goto error; } if (config->listen_tls) { virNetTLSContextPtr ctxt = NULL; if (config->ca_file || config->cert_file || config->key_file) { if (!(ctxt = virNetTLSContextNewServer(config->ca_file, config->crl_file, config->cert_file, config->key_file, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } else { if (!(ctxt = virNetTLSContextNewServerPath(NULL, !privileged, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } if (!(svcTLS = virNetServerServiceNewTCP(config->listen_addr, config->tls_port, config->auth_tls, false, config->max_client_requests, ctxt))) { virNetTLSContextFree(ctxt); goto error; } if (virNetServerAddService(srv, svcTLS, config->mdns_adv && !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0) goto error; virNetTLSContextFree(ctxt); } } #if HAVE_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || config->auth_tcp == REMOTE_AUTH_SASL || config->auth_tls == REMOTE_AUTH_SASL) { saslCtxt = virNetSASLContextNewServer( (const char *const*)config->sasl_allowed_username_list); if (!saslCtxt) goto error; } #endif return 0; error: virNetServerServiceFree(svcTLS); virNetServerServiceFree(svcTCP); virNetServerServiceFree(svc); virNetServerServiceFree(svcRO); return -1; }
static int daemonSetupNetworking(virNetServerPtr srv, struct daemonConfig *config, const char *sock_path, const char *sock_path_ro, bool ipsock, bool privileged) { virNetServerServicePtr svc = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; #if WITH_GNUTLS virNetServerServicePtr svcTLS = NULL; #endif gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; if (config->unix_sock_group) { if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0) return -1; } if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms); goto error; } if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms); goto error; } VIR_DEBUG("Registering unix socket %s", sock_path); if (!(svc = virNetServerServiceNewUNIX(sock_path, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests))) goto error; if (sock_path_ro) { VIR_DEBUG("Registering unix socket %s", sock_path_ro); if (!(svcRO = virNetServerServiceNewUNIX(sock_path_ro, unix_sock_ro_mask, unix_sock_gid, config->auth_unix_ro, #if WITH_GNUTLS NULL, #endif true, config->max_queued_clients, config->max_client_requests))) goto error; } if (virNetServerAddService(srv, svc, config->mdns_adv && !ipsock ? "_libvirt._tcp" : NULL) < 0) goto error; if (svcRO && virNetServerAddService(srv, svcRO, NULL) < 0) goto error; if (ipsock) { if (config->listen_tcp) { VIR_DEBUG("Registering TCP socket %s:%s", config->listen_addr, config->tcp_port); if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, config->auth_tcp, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests))) goto error; if (virNetServerAddService(srv, svcTCP, config->mdns_adv ? "_libvirt._tcp" : NULL) < 0) goto error; } #if WITH_GNUTLS if (config->listen_tls) { virNetTLSContextPtr ctxt = NULL; if (config->ca_file || config->cert_file || config->key_file) { if (!(ctxt = virNetTLSContextNewServer(config->ca_file, config->crl_file, config->cert_file, config->key_file, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } else { if (!(ctxt = virNetTLSContextNewServerPath(NULL, !privileged, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } VIR_DEBUG("Registering TLS socket %s:%s", config->listen_addr, config->tls_port); if (!(svcTLS = virNetServerServiceNewTCP(config->listen_addr, config->tls_port, config->auth_tls, ctxt, false, config->max_queued_clients, config->max_client_requests))) { virObjectUnref(ctxt); goto error; } if (virNetServerAddService(srv, svcTLS, config->mdns_adv && !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0) goto error; virObjectUnref(ctxt); } #else (void)privileged; if (config->listen_tls) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This libvirtd build does not support TLS")); goto error; } #endif } #if WITH_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || # if WITH_GNUTLS config->auth_tls == REMOTE_AUTH_SASL || # endif config->auth_tcp == REMOTE_AUTH_SASL) { saslCtxt = virNetSASLContextNewServer( (const char *const*)config->sasl_allowed_username_list); if (!saslCtxt) goto error; } #endif return 0; error: #if WITH_GNUTLS virObjectUnref(svcTLS); #endif virObjectUnref(svcTCP); virObjectUnref(svc); virObjectUnref(svcRO); return -1; }
virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged) { virQEMUDriverConfigPtr cfg; if (virQEMUConfigInitialize() < 0) return NULL; if (!(cfg = virObjectNew(virQEMUDriverConfigClass))) return NULL; 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->cacheDir, "%s/cache/libvirt/qemu", LOCALSTATEDIR) < 0) goto error; if (virAsprintf(&cfg->libDir, "%s/lib/libvirt/qemu", LOCALSTATEDIR) < 0) goto error; if (virAsprintf(&cfg->saveDir, "%s/save", cfg->libDir) < 0) goto error; if (virAsprintf(&cfg->snapshotDir, "%s/snapshot", cfg->libDir) < 0) goto error; if (virAsprintf(&cfg->autoDumpPath, "%s/dump", cfg->libDir) < 0) goto error; if (virAsprintf(&cfg->channelTargetDir, "%s/channel/target", cfg->libDir) < 0) goto error; if (virAsprintf(&cfg->nvramDir, "%s/nvram", cfg->libDir) < 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->channelTargetDir, "%s/qemu/channel/target", cfg->configBaseDir) < 0) goto error; if (virAsprintf(&cfg->nvramDir, "%s/qemu/nvram", 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; /* For privileged driver, try and find hugetlbfs mounts automatically. * Non-privileged driver requires admin to create a dir for the * user, chown it, and then let user configure it manually. */ if (privileged && virFileFindHugeTLBFS(&cfg->hugetlbfs, &cfg->nhugetlbfs) < 0) { /* This however is not implemented on all platforms. */ virErrorPtr err = virGetLastError(); if (err && err->code != VIR_ERR_NO_SUPPORT) goto error; } if (VIR_STRDUP(cfg->bridgeHelperName, QEMU_BRIDGE_HELPER) < 0) goto error; cfg->clearEmulatorCapabilities = true; cfg->securityDefaultConfined = true; cfg->securityRequireConfined = false; cfg->keepAliveInterval = 5; cfg->keepAliveCount = 5; cfg->seccompSandbox = -1; cfg->logTimestamp = true; cfg->stdioLogD = true; #ifdef DEFAULT_LOADER_NVRAM if (virFirmwareParseList(DEFAULT_LOADER_NVRAM, &cfg->firmwares, &cfg->nfirmwares) < 0) goto error; #else if (VIR_ALLOC_N(cfg->firmwares, 2) < 0) goto error; cfg->nfirmwares = 2; if (VIR_ALLOC(cfg->firmwares[0]) < 0 || VIR_ALLOC(cfg->firmwares[1]) < 0) goto error; if (VIR_STRDUP(cfg->firmwares[0]->name, VIR_QEMU_AAVMF_LOADER_PATH) < 0 || VIR_STRDUP(cfg->firmwares[0]->nvram, VIR_QEMU_AAVMF_NVRAM_PATH) < 0 || VIR_STRDUP(cfg->firmwares[1]->name, VIR_QEMU_OVMF_LOADER_PATH) < 0 || VIR_STRDUP(cfg->firmwares[1]->nvram, VIR_QEMU_OVMF_NVRAM_PATH) < 0) goto error; #endif return cfg; error: virObjectUnref(cfg); return NULL; }
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; }
int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, const char *filename) { virConfPtr conf = NULL; virConfValuePtr p; int ret = -1; size_t i; /* 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; } if (!(conf = virConfReadFile(filename, 0))) goto cleanup; #define CHECK_TYPE(name,typ) \ if (p && p->type != (typ)) { \ virReportError(VIR_ERR_INTERNAL_ERROR, \ "%s: %s: expected type " #typ, \ filename, (name)); \ goto cleanup; \ } #define GET_VALUE_LONG(NAME, VAR) \ p = virConfGetValue(conf, NAME); \ CHECK_TYPE(NAME, VIR_CONF_LONG); \ if (p) \ VAR = p->l; #define GET_VALUE_BOOL(NAME, VAR) \ p = virConfGetValue(conf, NAME); \ CHECK_TYPE(NAME, VIR_CONF_LONG); \ if (p) \ VAR = p->l != 0; #define GET_VALUE_STR(NAME, VAR) \ p = virConfGetValue(conf, NAME); \ CHECK_TYPE(NAME, VIR_CONF_STRING); \ if (p && p->str) { \ VIR_FREE(VAR); \ if (VIR_STRDUP(VAR, p->str) < 0) \ goto cleanup; \ } GET_VALUE_BOOL("vnc_auto_unix_socket", cfg->vncAutoUnixSocket); GET_VALUE_BOOL("vnc_tls", cfg->vncTLS); GET_VALUE_BOOL("vnc_tls_x509_verify", cfg->vncTLSx509verify); GET_VALUE_STR("vnc_tls_x509_cert_dir", cfg->vncTLSx509certdir); GET_VALUE_STR("vnc_listen", cfg->vncListen); GET_VALUE_STR("vnc_password", cfg->vncPassword); GET_VALUE_BOOL("vnc_sasl", cfg->vncSASL); GET_VALUE_STR("vnc_sasl_dir", cfg->vncSASLdir); GET_VALUE_BOOL("vnc_allow_host_audio", cfg->vncAllowHostAudio); GET_VALUE_BOOL("nographics_allow_host_audio", cfg->nogfxAllowHostAudio); p = virConfGetValue(conf, "security_driver"); if (p && p->type == VIR_CONF_LIST) { size_t len; virConfValuePtr pp; /* Calc length and check items */ for (len = 0, pp = p->list; pp; len++, pp = pp->next) { if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("security_driver must be a list of strings")); goto cleanup; } } if (VIR_ALLOC_N(cfg->securityDriverNames, len + 1) < 0) goto cleanup; for (i = 0, pp = p->list; pp; i++, pp = pp->next) { if (VIR_STRDUP(cfg->securityDriverNames[i], pp->str) < 0) goto cleanup; } cfg->securityDriverNames[len] = NULL; } else { CHECK_TYPE("security_driver", VIR_CONF_STRING); if (p && p->str) { if (VIR_ALLOC_N(cfg->securityDriverNames, 2) < 0) goto cleanup; if (VIR_STRDUP(cfg->securityDriverNames[0], p->str) < 0) goto cleanup; cfg->securityDriverNames[1] = NULL; } } GET_VALUE_BOOL("security_default_confined", cfg->securityDefaultConfined); GET_VALUE_BOOL("security_require_confined", cfg->securityRequireConfined); GET_VALUE_BOOL("spice_tls", cfg->spiceTLS); GET_VALUE_STR("spice_tls_x509_cert_dir", cfg->spiceTLSx509certdir); GET_VALUE_BOOL("spice_sasl", cfg->spiceSASL); GET_VALUE_STR("spice_sasl_dir", cfg->spiceSASLdir); GET_VALUE_STR("spice_listen", cfg->spiceListen); GET_VALUE_STR("spice_password", cfg->spicePassword); GET_VALUE_LONG("remote_websocket_port_min", cfg->webSocketPortMin); if (cfg->webSocketPortMin < QEMU_WEBSOCKET_PORT_MIN) { /* if the port is too low, we can't get the display name * to tell to vnc (usually subtract 5700, e.g. localhost:1 * for port 5701) */ virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_websocket_port_min: port must be greater " "than or equal to %d"), filename, QEMU_WEBSOCKET_PORT_MIN); goto cleanup; } GET_VALUE_LONG("remote_websocket_port_max", cfg->webSocketPortMax); if (cfg->webSocketPortMax > QEMU_WEBSOCKET_PORT_MAX || cfg->webSocketPortMax < cfg->webSocketPortMin) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_websocket_port_max: port must be between " "the minimal port and %d"), filename, QEMU_WEBSOCKET_PORT_MAX); goto cleanup; } if (cfg->webSocketPortMin > cfg->webSocketPortMax) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_websocket_port_min: min port must not be " "greater than max port"), filename); goto cleanup; } GET_VALUE_LONG("remote_display_port_min", cfg->remotePortMin); if (cfg->remotePortMin < 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); goto cleanup; } GET_VALUE_LONG("remote_display_port_max", cfg->remotePortMax); if (cfg->remotePortMax > QEMU_REMOTE_PORT_MAX || cfg->remotePortMax < cfg->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); goto cleanup; } if (cfg->remotePortMin > cfg->remotePortMax) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: remote_display_port_min: min port must not be " "greater than max port"), filename); goto cleanup; } GET_VALUE_LONG("migration_port_min", cfg->migrationPortMin); if (cfg->migrationPortMin <= 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: migration_port_min: port must be greater than 0"), filename); goto cleanup; } GET_VALUE_LONG("migration_port_max", cfg->migrationPortMax); if (cfg->migrationPortMax > 65535 || cfg->migrationPortMax < cfg->migrationPortMin) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: migration_port_max: port must be between " "the minimal port %d and 65535"), filename, cfg->migrationPortMin); goto cleanup; } p = virConfGetValue(conf, "user"); CHECK_TYPE("user", VIR_CONF_STRING); if (p && p->str && virGetUserID(p->str, &cfg->user) < 0) goto cleanup; p = virConfGetValue(conf, "group"); CHECK_TYPE("group", VIR_CONF_STRING); if (p && p->str && virGetGroupID(p->str, &cfg->group) < 0) goto cleanup; GET_VALUE_BOOL("dynamic_ownership", cfg->dynamicOwnership); p = virConfGetValue(conf, "cgroup_controllers"); CHECK_TYPE("cgroup_controllers", VIR_CONF_LIST); if (p) { cfg->cgroupControllers = 0; virConfValuePtr pp; for (i = 0, pp = p->list; pp; ++i, pp = pp->next) { int ctl; if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("cgroup_controllers must be a " "list of strings")); goto cleanup; } if ((ctl = virCgroupControllerTypeFromString(pp->str)) < 0) { virReportError(VIR_ERR_CONF_SYNTAX, _("Unknown cgroup controller '%s'"), pp->str); goto cleanup; } cfg->cgroupControllers |= (1 << ctl); } } 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(cfg->cgroupDeviceACL, 1+len) < 0) goto cleanup; for (i = 0, pp = p->list; pp; ++i, pp = pp->next) { if (pp->type != VIR_CONF_STRING) { virReportError(VIR_ERR_CONF_SYNTAX, "%s", _("cgroup_device_acl must be a " "list of strings")); goto cleanup; } if (VIR_STRDUP(cfg->cgroupDeviceACL[i], pp->str) < 0) goto cleanup; } cfg->cgroupDeviceACL[i] = NULL; } GET_VALUE_STR("save_image_format", cfg->saveImageFormat); GET_VALUE_STR("dump_image_format", cfg->dumpImageFormat); GET_VALUE_STR("snapshot_image_format", cfg->snapshotImageFormat); GET_VALUE_STR("auto_dump_path", cfg->autoDumpPath); GET_VALUE_BOOL("auto_dump_bypass_cache", cfg->autoDumpBypassCache); GET_VALUE_BOOL("auto_start_bypass_cache", cfg->autoStartBypassCache); GET_VALUE_STR("hugetlbfs_mount", cfg->hugetlbfsMount); GET_VALUE_STR("bridge_helper", cfg->bridgeHelperName); GET_VALUE_BOOL("mac_filter", cfg->macFilter); GET_VALUE_BOOL("relaxed_acs_check", cfg->relaxedACS); GET_VALUE_BOOL("clear_emulator_capabilities", cfg->clearEmulatorCapabilities); GET_VALUE_BOOL("allow_disk_format_probing", cfg->allowDiskFormatProbing); GET_VALUE_BOOL("set_process_name", cfg->setProcessName); GET_VALUE_LONG("max_processes", cfg->maxProcesses); GET_VALUE_LONG("max_files", cfg->maxFiles); GET_VALUE_STR("lock_manager", cfg->lockManagerName); GET_VALUE_LONG("max_queued", cfg->maxQueuedJobs); GET_VALUE_LONG("keepalive_interval", cfg->keepAliveInterval); GET_VALUE_LONG("keepalive_count", cfg->keepAliveCount); GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox); GET_VALUE_STR("migration_address", cfg->migrationAddress); ret = 0; cleanup: virConfFree(conf); return ret; }
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; }
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; }
daemonSetupNetworking(virNetServerPtr srv, virNetServerPtr srvAdm, struct daemonConfig *config, const char *sock_path, const char *sock_path_ro, const char *sock_path_adm, bool ipsock, bool privileged) { virNetServerServicePtr svc = NULL; virNetServerServicePtr svcAdm = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; #if WITH_GNUTLS virNetServerServicePtr svcTLS = NULL; #endif gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; int unix_sock_adm_mask = 0; int ret = -1; unsigned int cur_fd = STDERR_FILENO + 1; unsigned int nfds = virGetListenFDs(); if (config->unix_sock_group) { if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0) return ret; } if (nfds > (sock_path_ro ? 2 : 1)) { VIR_ERROR(_("Too many (%u) FDs passed from caller"), nfds); return ret; } if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms); goto cleanup; } if (virStrToLong_i(config->unix_sock_admin_perms, NULL, 8, &unix_sock_adm_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_admin_perms); goto cleanup; } if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms); goto cleanup; } if (!(svc = virNetServerServiceNewFDOrUNIX(sock_path, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests, nfds, &cur_fd))) goto cleanup; if (sock_path_ro) { if (!(svcRO = virNetServerServiceNewFDOrUNIX(sock_path_ro, unix_sock_ro_mask, unix_sock_gid, config->auth_unix_ro, #if WITH_GNUTLS NULL, #endif true, config->max_queued_clients, config->max_client_requests, nfds, &cur_fd))) goto cleanup; } if (virNetServerAddService(srv, svc, config->mdns_adv && !ipsock ? "_libvirt._tcp" : NULL) < 0) goto cleanup; if (svcRO && virNetServerAddService(srv, svcRO, NULL) < 0) goto cleanup; /* Temporarily disabled */ if (sock_path_adm && false) { VIR_DEBUG("Registering unix socket %s", sock_path_adm); if (!(svcAdm = virNetServerServiceNewUNIX(sock_path_adm, unix_sock_adm_mask, unix_sock_gid, REMOTE_AUTH_NONE, #if WITH_GNUTLS NULL, #endif true, config->admin_max_queued_clients, config->admin_max_client_requests))) goto cleanup; if (virNetServerAddService(srvAdm, svcAdm, NULL) < 0) goto cleanup; } if (ipsock) { if (config->listen_tcp) { VIR_DEBUG("Registering TCP socket %s:%s", config->listen_addr, config->tcp_port); if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, AF_UNSPEC, config->auth_tcp, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests))) goto cleanup; if (virNetServerAddService(srv, svcTCP, config->mdns_adv ? "_libvirt._tcp" : NULL) < 0) goto cleanup; } #if WITH_GNUTLS if (config->listen_tls) { virNetTLSContextPtr ctxt = NULL; if (config->ca_file || config->cert_file || config->key_file) { if (!(ctxt = virNetTLSContextNewServer(config->ca_file, config->crl_file, config->cert_file, config->key_file, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto cleanup; } else { if (!(ctxt = virNetTLSContextNewServerPath(NULL, !privileged, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto cleanup; } VIR_DEBUG("Registering TLS socket %s:%s", config->listen_addr, config->tls_port); if (!(svcTLS = virNetServerServiceNewTCP(config->listen_addr, config->tls_port, AF_UNSPEC, config->auth_tls, ctxt, false, config->max_queued_clients, config->max_client_requests))) { virObjectUnref(ctxt); goto cleanup; } if (virNetServerAddService(srv, svcTLS, config->mdns_adv && !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0) goto cleanup; virObjectUnref(ctxt); } #else (void)privileged; if (config->listen_tls) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This libvirtd build does not support TLS")); goto cleanup; } #endif } #if WITH_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || # if WITH_GNUTLS config->auth_tls == REMOTE_AUTH_SASL || # endif config->auth_tcp == REMOTE_AUTH_SASL) { saslCtxt = virNetSASLContextNewServer( (const char *const*)config->sasl_allowed_username_list); if (!saslCtxt) goto cleanup; } #endif ret = 0; cleanup: #if WITH_GNUTLS virObjectUnref(svcTLS); #endif virObjectUnref(svcTCP); virObjectUnref(svcRO); virObjectUnref(svcAdm); virObjectUnref(svc); return ret; }