static int lxcSetMemTune(virDomainDefPtr def, virConfPtr properties) { virConfValuePtr value; unsigned long long size = 0; if ((value = virConfGetValue(properties, "lxc.cgroup.memory.limit_in_bytes")) && value->str && STRNEQ(value->str, "-1")) { if (lxcConvertSize(value->str, &size) < 0) return -1; size = size / 1024; virDomainDefSetMemoryTotal(def, size); def->mem.hard_limit = virMemoryLimitTruncate(size); } if ((value = virConfGetValue(properties, "lxc.cgroup.memory.soft_limit_in_bytes")) && value->str && STRNEQ(value->str, "-1")) { if (lxcConvertSize(value->str, &size) < 0) return -1; def->mem.soft_limit = virMemoryLimitTruncate(size / 1024); } if ((value = virConfGetValue(properties, "lxc.cgroup.memory.memsw.limit_in_bytes")) && value->str && STRNEQ(value->str, "-1")) { if (lxcConvertSize(value->str, &size) < 0) return -1; def->mem.swap_hard_limit = virMemoryLimitTruncate(size / 1024); } return 0; }
static int lxcSetMemTune(virDomainDefPtr def, virConfPtr properties) { VIR_AUTOFREE(char *) value = NULL; unsigned long long size = 0; if (virConfGetValueString(properties, "lxc.cgroup.memory.limit_in_bytes", &value) > 0) { if (lxcConvertSize(value, &size) < 0) return -1; size = size / 1024; virDomainDefSetMemoryTotal(def, size); def->mem.hard_limit = virMemoryLimitTruncate(size); VIR_FREE(value); } if (virConfGetValueString(properties, "lxc.cgroup.memory.soft_limit_in_bytes", &value) > 0) { if (lxcConvertSize(value, &size) < 0) return -1; def->mem.soft_limit = virMemoryLimitTruncate(size / 1024); VIR_FREE(value); } if (virConfGetValueString(properties, "lxc.cgroup.memory.memsw.limit_in_bytes", &value) > 0) { if (lxcConvertSize(value, &size) < 0) return -1; def->mem.swap_hard_limit = virMemoryLimitTruncate(size / 1024); } return 0; }
static char * hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) { char *xml = NULL; hypervPrivate *priv = domain->conn->privateData; virDomainDefPtr def = NULL; char uuid_string[VIR_UUID_STRING_BUFLEN]; virBuffer query = VIR_BUFFER_INITIALIZER; Msvm_ComputerSystem *computerSystem = NULL; Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL; Msvm_ProcessorSettingData *processorSettingData = NULL; Msvm_MemorySettingData *memorySettingData = NULL; /* Flags checked by virDomainDefFormat */ if (!(def = virDomainDefNew())) goto cleanup; virUUIDFormat(domain->uuid, uuid_string); /* Get Msvm_ComputerSystem */ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) goto cleanup; /* Get Msvm_VirtualSystemSettingData */ virBufferAsprintf(&query, "associators of " "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\"," "Name=\"%s\"} " "where AssocClass = Msvm_SettingsDefineState " "ResultClass = Msvm_VirtualSystemSettingData", uuid_string); if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, &virtualSystemSettingData) < 0) { goto cleanup; } if (virtualSystemSettingData == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for domain %s"), "Msvm_VirtualSystemSettingData", computerSystem->data.common->ElementName); goto cleanup; } /* Get Msvm_ProcessorSettingData */ virBufferAsprintf(&query, "associators of " "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} " "where AssocClass = Msvm_VirtualSystemSettingDataComponent " "ResultClass = Msvm_ProcessorSettingData", virtualSystemSettingData->data.common->InstanceID); if (hypervGetMsvmProcessorSettingDataList(priv, &query, &processorSettingData) < 0) { goto cleanup; } if (processorSettingData == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for domain %s"), "Msvm_ProcessorSettingData", computerSystem->data.common->ElementName); goto cleanup; } /* Get Msvm_MemorySettingData */ virBufferAsprintf(&query, "associators of " "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} " "where AssocClass = Msvm_VirtualSystemSettingDataComponent " "ResultClass = Msvm_MemorySettingData", virtualSystemSettingData->data.common->InstanceID); if (hypervGetMsvmMemorySettingDataList(priv, &query, &memorySettingData) < 0) { goto cleanup; } if (memorySettingData == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for domain %s"), "Msvm_MemorySettingData", computerSystem->data.common->ElementName); goto cleanup; } /* Fill struct */ def->virtType = VIR_DOMAIN_VIRT_HYPERV; if (hypervIsMsvmComputerSystemActive(computerSystem, NULL)) { def->id = computerSystem->data.common->ProcessID; } else { def->id = -1; } if (virUUIDParse(computerSystem->data.common->Name, def->uuid) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not parse UUID from string '%s'"), computerSystem->data.common->Name); return NULL; } if (VIR_STRDUP(def->name, computerSystem->data.common->ElementName) < 0) goto cleanup; if (priv->wmiVersion == HYPERV_WMI_VERSION_V1) { if (VIR_STRDUP(def->description, virtualSystemSettingData->data.v1->Notes) < 0) goto cleanup; } else if (priv->wmiVersion == HYPERV_WMI_VERSION_V2 && virtualSystemSettingData->data.v2->Notes.data != NULL) { char **notes = (char **)virtualSystemSettingData->data.v2->Notes.data; virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i = 0; /* in practice Notes has 1 element */ for (i = 0; i < virtualSystemSettingData->data.v2->Notes.count; i++) { /* but if there's more than 1, separate by double new line */ if (virBufferUse(&buf) > 0) virBufferAddLit(&buf, "\n\n"); virBufferAdd(&buf, *notes, -1); notes++; } if (virBufferCheckError(&buf)) goto cleanup; def->description = virBufferContentAndReset(&buf); } virDomainDefSetMemoryTotal(def, memorySettingData->data.common->Limit * 1024); /* megabyte to kilobyte */ def->mem.cur_balloon = memorySettingData->data.common->VirtualQuantity * 1024; /* megabyte to kilobyte */ if (virDomainDefSetVcpusMax(def, processorSettingData->data.common->VirtualQuantity, NULL) < 0) goto cleanup; if (virDomainDefSetVcpus(def, processorSettingData->data.common->VirtualQuantity) < 0) goto cleanup; def->os.type = VIR_DOMAIN_OSTYPE_HVM; /* FIXME: devices section is totally missing */ xml = virDomainDefFormat(def, NULL, virDomainDefFormatConvertXMLFlags(flags)); cleanup: virDomainDefFree(def); hypervFreeObject(priv, (hypervObject *)computerSystem); hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData); hypervFreeObject(priv, (hypervObject *)processorSettingData); hypervFreeObject(priv, (hypervObject *)memorySettingData); return xml; }
virDomainDefPtr lxcParseConfigString(const char *config, virCapsPtr caps, virDomainXMLOptionPtr xmlopt) { virDomainDefPtr vmdef = NULL; virConfPtr properties = NULL; virConfValuePtr value; if (!(properties = virConfReadMem(config, 0, VIR_CONF_FLAG_LXC_FORMAT))) return NULL; if (!(vmdef = virDomainDefNew())) goto error; if (virUUIDGenerate(vmdef->uuid) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to generate uuid")); goto error; } vmdef->id = -1; virDomainDefSetMemoryTotal(vmdef, 64 * 1024); vmdef->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART; vmdef->onCrash = VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY; vmdef->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY; vmdef->virtType = VIR_DOMAIN_VIRT_LXC; /* Value not handled by the LXC driver, setting to * minimum required to make XML parsing pass */ if (virDomainDefSetVcpusMax(vmdef, 1) < 0) goto error; if (virDomainDefSetVcpus(vmdef, 1) < 0) goto error; vmdef->nfss = 0; vmdef->os.type = VIR_DOMAIN_OSTYPE_EXE; if ((value = virConfGetValue(properties, "lxc.arch")) && value->str) { virArch arch = virArchFromString(value->str); if (arch == VIR_ARCH_NONE && STREQ(value->str, "x86")) arch = VIR_ARCH_I686; else if (arch == VIR_ARCH_NONE && STREQ(value->str, "amd64")) arch = VIR_ARCH_X86_64; vmdef->os.arch = arch; } if (VIR_STRDUP(vmdef->os.init, "/sbin/init") < 0) goto error; if (!(value = virConfGetValue(properties, "lxc.utsname")) || !value->str || (VIR_STRDUP(vmdef->name, value->str) < 0)) goto error; if (!vmdef->name && (VIR_STRDUP(vmdef->name, "unnamed") < 0)) goto error; if (lxcSetRootfs(vmdef, properties) < 0) goto error; /* Look for fstab: we shouldn't have it */ if (virConfGetValue(properties, "lxc.mount")) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("lxc.mount found, use lxc.mount.entry lines instead")); goto error; } /* Loop over lxc.mount.entry to add filesystem devices for them */ if (virConfWalk(properties, lxcFstabWalkCallback, vmdef) < 0) goto error; /* Network configuration */ if (lxcConvertNetworkSettings(vmdef, properties) < 0) goto error; /* Consoles */ if (lxcCreateConsoles(vmdef, properties) < 0) goto error; /* lxc.id_map */ if (virConfWalk(properties, lxcIdmapWalkCallback, vmdef) < 0) goto error; /* lxc.cgroup.memory.* */ if (lxcSetMemTune(vmdef, properties) < 0) goto error; /* lxc.cgroup.cpu.* */ if (lxcSetCpuTune(vmdef, properties) < 0) goto error; /* lxc.cgroup.cpuset.* */ if (lxcSetCpusetTune(vmdef, properties) < 0) goto error; /* lxc.cgroup.blkio.* */ if (lxcSetBlkioTune(vmdef, properties) < 0) goto error; /* lxc.cap.drop */ lxcSetCapDrop(vmdef, properties); if (virDomainDefPostParse(vmdef, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, xmlopt) < 0) goto cleanup; goto cleanup; error: virDomainDefFree(vmdef); vmdef = NULL; cleanup: virConfFree(properties); return vmdef; }
int lxctoolsReadConfig(struct lxc_container* cont, virDomainDefPtr def) { char* item_str = NULL; virNodeInfoPtr nodeinfo = NULL; lxctoolsConffilePtr conffile = NULL; if (VIR_ALLOC(nodeinfo) < 0) { goto error; } if (virCapabilitiesGetNodeInfo(nodeinfo) < 0) { goto error; } if (VIR_ALLOC(conffile) < 0) goto error; if (lxctoolsConffileRead(conffile, cont->config_file_name(cont)) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "'%s'", _("failed to read conffile")); goto error; } if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.arch")) == NULL) { goto error; } if (item_str[0] != '\0') { if (strcmp(item_str, "x86") == 0 || strcmp(item_str, "i686") == 0) { def->os.arch = VIR_ARCH_I686; } else if (strcmp(item_str, "x86_64") == 0 || strcmp(item_str, "amd64") == 0) { def->os.arch = VIR_ARCH_X86_64; } else { virReportError(VIR_ERR_OPERATION_FAILED, "Unknown architecture '%s'.", item_str); goto error; } } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpuset.cpus")) == NULL){ goto error; } if (item_str[0] == '\0') { if (virDomainDefSetVcpusMax(def, nodeinfo->cpus, NULL) < 0) goto error; def->cpumask = virBitmapNew(nodeinfo->cpus); virBitmapSetAll(def->cpumask); } else { int cpunum; if ( (cpunum = virBitmapParse(item_str, &def->cpumask, nodeinfo->cpus) ) < 0) { goto error; } if (virDomainDefSetVcpusMax(def, cpunum, NULL) < 0) goto error; } if (virDomainDefSetVcpus(def, virDomainDefGetVcpusMax(def)) < 0) goto error; VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.shares")) == NULL) { goto error; } if (item_str[0] != '\0') { unsigned long shares; sscanf(item_str, "%lu", &shares); def->cputune.shares = shares; def->cputune.sharesSpecified = true; } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.cfs_period_us")) == NULL) { goto error; } if (item_str[0] != '\0') { unsigned long long period; sscanf(item_str, "%llu", &period); def->cputune.period = period; } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.cfs_quota_us")) == NULL) { goto error; } if (item_str[0] != '\0') { long long quota; sscanf(item_str, "%llu", "a); def->cputune.quota = quota; } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.memory.limit_in_bytes")) == NULL) { goto error; } if (item_str[0] == '\0') { virDomainDefSetMemoryTotal(def, nodeinfo->memory); } else { virDomainDefSetMemoryTotal(def, memToULL(item_str)); } def->mem.cur_balloon = virDomainDefGetMemoryTotal(def); // def->mem.max_memory = nodeinfo->memory; // def->mem.memory_slots = 1; //maybe delete max_memory alltogether VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.memory.soft_limit_in_bytes")) == NULL) { goto error; } if (item_str[0] != '\0') { def->mem.soft_limit = memToULL(item_str); } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpuset.mems")) == NULL) { goto error; } if (item_str[0] != '\0') { virBitmapPtr nodeset; if (virBitmapParse(item_str, &nodeset, nodeinfo->nodes) < 0) { goto error; } if (virDomainNumatuneSet(def->numa, true, VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT, VIR_DOMAIN_NUMATUNE_MEM_STRICT, nodeset) < 0 ) { goto error; } } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.include")) == NULL) { goto error; } //lxc.include is optional! if (item_str[0] != '\0') { def->metadata = xmlNewNode(NULL, (const xmlChar*) "metadata"); xmlNewTextChild(def->metadata, NULL, (const xmlChar*) (const xmlChar*)"lxctools:include", (const xmlChar*)item_str); } VIR_FREE(item_str); item_str = NULL; if (lxctoolsReadFSConfig(conffile, def) < 0) goto error; if (lxctoolsReadNetConfig(cont, def) < 0) goto error; return 0; error: VIR_FREE(item_str); VIR_FREE(nodeinfo); return -1; }
/* * Parse the /usr/sbin/bhyveload command line. */ static int bhyveParseBhyveLoadCommandLine(virDomainDefPtr def, int argc, char **argv) { int c; /* bhyveload called with default arguments when only -m and -d are given. * Store this in a bit field and check if only those two options are given * later */ unsigned arguments = 0; size_t memory = 0; struct _getopt_data *parser; size_t i = 0; int ret = -1; const char optstr[] = "CSc:d:e:h:l:m:"; if (!argv) goto error; if (VIR_ALLOC(parser) < 0) goto error; while ((c = _getopt_internal_r(argc, argv, optstr, NULL, NULL, 0, parser, 0)) != -1) { switch (c) { case 'd': arguments |= 1; /* Iterate over the disks of the domain trying to match up the * source */ for (i = 0; i < def->ndisks; i++) { if (STREQ(virDomainDiskGetSource(def->disks[i]), parser->optarg)) { def->disks[i]->info.bootIndex = i; break; } } break; case 'm': arguments |= 2; if (bhyveParseMemsize(parser->optarg, &memory)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse memory")); goto error; } if (def->mem.cur_balloon != 0 && def->mem.cur_balloon != memory) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse memory: size mismatch")); goto error; } def->mem.cur_balloon = memory; virDomainDefSetMemoryTotal(def, memory); break; default: arguments |= 4; } } if (arguments != 3) { /* Set os.bootloader since virDomainDefFormatInternal will only format * the bootloader arguments if os->bootloader is set. */ if (VIR_STRDUP(def->os.bootloader, argv[0]) < 0) goto error; def->os.bootloaderArgs = virStringJoin((const char**) &argv[1], " "); } if (argc != parser->optind) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse arguments for bhyveload command")); goto error; } if (def->name == NULL) { if (VIR_STRDUP(def->name, argv[argc]) < 0) goto error; } else if (STRNEQ(def->name, argv[argc])) { /* the vm name of the loader and the bhyverun command differ, throw an * error here */ virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse arguments: VM name mismatch")); goto error; } ret = 0; error: VIR_FREE(parser); return ret; }
/* * Parse the /usr/sbin/bhyve command line. */ static int bhyveParseBhyveCommandLine(virDomainDefPtr def, virDomainXMLOptionPtr xmlopt, unsigned caps, int argc, char **argv) { int c; const char optstr[] = "abehuwxACHIPSWYp:g:c:s:m:l:U:"; int vcpus = 1; size_t memory = 0; unsigned nahcidisks = 0; unsigned nvirtiodisks = 0; struct _getopt_data *parser; if (!argv) goto error; if (VIR_ALLOC(parser) < 0) goto error; while ((c = _getopt_internal_r(argc, argv, optstr, NULL, NULL, 0, parser, 0)) != -1) { switch (c) { case 'A': def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON; break; case 'c': if (virStrToLong_i(parser->optarg, NULL, 10, &vcpus) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse number of vCPUs")); goto error; } if (virDomainDefSetVcpusMax(def, vcpus, xmlopt) < 0) goto error; if (virDomainDefSetVcpus(def, vcpus) < 0) goto error; break; case 'l': if (bhyveParseBhyveLPCArg(def, caps, parser->optarg)) goto error; break; case 's': if (bhyveParseBhyvePCIArg(def, xmlopt, caps, &nahcidisks, &nvirtiodisks, parser->optarg)) goto error; break; case 'm': if (bhyveParseMemsize(parser->optarg, &memory)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse memory")); goto error; } if (def->mem.cur_balloon != 0 && def->mem.cur_balloon != memory) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse memory: size mismatch")); goto error; } def->mem.cur_balloon = memory; virDomainDefSetMemoryTotal(def, memory); break; case 'I': /* While this flag was deprecated in FreeBSD r257423, keep checking * for it for backwards compatibility. */ def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_TRISTATE_SWITCH_ON; break; case 'u': def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC; break; case 'U': if (virUUIDParse(parser->optarg, def->uuid) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Cannot parse UUID '%s'"), parser->optarg); goto error; } break; } } if (argc != parser->optind) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse arguments for bhyve command")); goto error; } if (def->name == NULL) { if (VIR_STRDUP(def->name, argv[argc]) < 0) goto error; } else if (STRNEQ(def->name, argv[argc])) { /* the vm name of the loader and the bhyverun command differ, throw an * error here */ virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Failed to parse arguments: VM name mismatch")); goto error; } VIR_FREE(parser); return 0; error: VIR_FREE(parser); return -1; }