/** * virConfWriteMem: * @memory: pointer to the memory to store the config file * @len: pointer to the length in bytes of the store, on output the size * @conf: the conf * * Writes a configuration file back to a memory area. @len is an IN/OUT * parameter, it indicates the size available in bytes, and on output the * size required for the configuration file (even if the call fails due to * insufficient space). * * Returns the number of bytes written or -1 in case of error. */ int virConfWriteMem(char *memory, int *len, virConfPtr conf) { virBuffer buf = VIR_BUFFER_INITIALIZER; virConfEntryPtr cur; char *content; unsigned int use; if ((memory == NULL) || (len == NULL) || (*len <= 0) || (conf == NULL)) return -1; cur = conf->entries; while (cur != NULL) { virConfSaveEntry(&buf, cur); cur = cur->next; } if (virBufferCheckError(&buf) < 0) return -1; use = virBufferUse(&buf); content = virBufferContentAndReset(&buf); if ((int)use >= *len) { *len = (int)use; VIR_FREE(content); return -1; } memcpy(memory, content, use); VIR_FREE(content); *len = use; return use; }
static dnsmasqHostsfile * hostsfileNew(const char *name, const char *config_dir) { dnsmasqHostsfile *hostsfile; virBuffer buf = VIR_BUFFER_INITIALIZER; if (VIR_ALLOC(hostsfile) < 0) return NULL; hostsfile->hosts = NULL; hostsfile->nhosts = 0; virBufferAsprintf(&buf, "%s", config_dir); virBufferEscapeString(&buf, "/%s", name); virBufferAsprintf(&buf, ".%s", DNSMASQ_HOSTSFILE_SUFFIX); if (virBufferCheckError(&buf) < 0) goto error; if (!(hostsfile->path = virBufferContentAndReset(&buf))) goto error; return hostsfile; error: virBufferFreeAndReset(&buf); hostsfileFree(hostsfile); return NULL; }
/** * virStringReplace: * @haystack: the source string to process * @oldneedle: the substring to locate * @newneedle: the substring to insert * * Search @haystack and replace all occurrences of @oldneedle with @newneedle. * * Returns: a new string with all the replacements, or NULL on error */ char * virStringReplace(const char *haystack, const char *oldneedle, const char *newneedle) { virBuffer buf = VIR_BUFFER_INITIALIZER; const char *tmp1, *tmp2; size_t oldneedlelen = strlen(oldneedle); size_t newneedlelen = strlen(newneedle); tmp1 = haystack; tmp2 = NULL; while (tmp1) { tmp2 = strstr(tmp1, oldneedle); if (tmp2) { virBufferAdd(&buf, tmp1, (tmp2 - tmp1)); virBufferAdd(&buf, newneedle, newneedlelen); tmp2 += oldneedlelen; } else { virBufferAdd(&buf, tmp1, -1); } tmp1 = tmp2; } if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); }
char * virSecretDefFormat(const virSecretDef *def) { virBuffer buf = VIR_BUFFER_INITIALIZER; const unsigned char *uuid; char uuidstr[VIR_UUID_STRING_BUFLEN]; virBufferAsprintf(&buf, "<secret ephemeral='%s' private='%s'>\n", def->isephemeral ? "yes" : "no", def->isprivate ? "yes" : "no"); uuid = def->uuid; virUUIDFormat(uuid, uuidstr); virBufferAdjustIndent(&buf, 2); virBufferEscapeString(&buf, "<uuid>%s</uuid>\n", uuidstr); if (def->description != NULL) virBufferEscapeString(&buf, "<description>%s</description>\n", def->description); if (def->usage_type != VIR_SECRET_USAGE_TYPE_NONE && virSecretDefFormatUsage(&buf, def) < 0) goto error; virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</secret>\n"); if (virBufferCheckError(&buf) < 0) goto error; return virBufferContentAndReset(&buf); error: virBufferFreeAndReset(&buf); return NULL; }
static char * testFilterXML(char *xml) { virBuffer buf = VIR_BUFFER_INITIALIZER; char **xmlLines = NULL; char **xmlLine; char *ret = NULL; if (!(xmlLines = virStringSplit(xml, "\n", 0))) { VIR_FREE(xml); goto cleanup; } VIR_FREE(xml); for (xmlLine = xmlLines; *xmlLine; xmlLine++) { if (regexec(testSnapshotXMLVariableLineRegex, *xmlLine, 0, NULL, 0) == 0) continue; virBufferStrcat(&buf, *xmlLine, "\n", NULL); } if (virBufferCheckError(&buf) < 0) goto cleanup; ret = virBufferContentAndReset(&buf); cleanup: virBufferFreeAndReset(&buf); virStringFreeList(xmlLines); return ret; }
static char * bhyveConnectDomainXMLToNative(virConnectPtr conn, const char *format, const char *xmlData, unsigned int flags) { virBuffer buf = VIR_BUFFER_INITIALIZER; bhyveConnPtr privconn = conn->privateData; virDomainDefPtr def = NULL; virCommandPtr cmd = NULL, loadcmd = NULL; virCapsPtr caps = NULL; char *ret = NULL; virCheckFlags(0, NULL); if (virConnectDomainXMLToNativeEnsureACL(conn) < 0) goto cleanup; if (STRNEQ(format, BHYVE_CONFIG_FORMAT_ARGV)) { virReportError(VIR_ERR_INVALID_ARG, _("Unsupported config type %s"), format); goto cleanup; } if (!(caps = bhyveDriverGetCapabilities(privconn))) goto cleanup; if (!(def = virDomainDefParseString(xmlData, caps, privconn->xmlopt, 1 << VIR_DOMAIN_VIRT_BHYVE, VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto cleanup; if (bhyveDomainAssignAddresses(def, NULL) < 0) goto cleanup; if (!(loadcmd = virBhyveProcessBuildLoadCmd(conn, def, "<device.map>", NULL))) goto cleanup; if (!(cmd = virBhyveProcessBuildBhyveCmd(conn, def, true))) goto cleanup; virBufferAdd(&buf, virCommandToString(loadcmd), -1); virBufferAddChar(&buf, '\n'); virBufferAdd(&buf, virCommandToString(cmd), -1); if (virBufferCheckError(&buf) < 0) goto cleanup; ret = virBufferContentAndReset(&buf); cleanup: virCommandFree(loadcmd); virCommandFree(cmd); virDomainDefFree(def); virObjectUnref(caps); return ret; }
char * virDomainCapsFormat(virDomainCapsPtr const caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; const char *virttype_str = virDomainVirtTypeToString(caps->virttype); const char *arch_str = virArchToString(caps->arch); virBufferAddLit(&buf, "<domainCapabilities>\n"); virBufferAdjustIndent(&buf, 2); virBufferEscapeString(&buf, "<path>%s</path>\n", caps->path); virBufferAsprintf(&buf, "<domain>%s</domain>\n", virttype_str); if (caps->machine) virBufferAsprintf(&buf, "<machine>%s</machine>\n", caps->machine); virBufferAsprintf(&buf, "<arch>%s</arch>\n", arch_str); if (caps->maxvcpus) virBufferAsprintf(&buf, "<vcpu max='%d'/>\n", caps->maxvcpus); FORMAT_SINGLE("iothreads", caps->iothreads); virDomainCapsOSFormat(&buf, &caps->os); virDomainCapsCPUFormat(&buf, &caps->cpu); virBufferAddLit(&buf, "<devices>\n"); virBufferAdjustIndent(&buf, 2); virDomainCapsDeviceDiskFormat(&buf, &caps->disk); virDomainCapsDeviceGraphicsFormat(&buf, &caps->graphics); virDomainCapsDeviceVideoFormat(&buf, &caps->video); virDomainCapsDeviceHostdevFormat(&buf, &caps->hostdev); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</devices>\n"); virBufferAddLit(&buf, "<features>\n"); virBufferAdjustIndent(&buf, 2); virDomainCapsFeatureGICFormat(&buf, &caps->gic); FORMAT_SINGLE("vmcoreinfo", caps->vmcoreinfo); FORMAT_SINGLE("genid", caps->genid); virDomainCapsFeatureSEVFormat(&buf, caps->sev); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</features>\n"); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</domainCapabilities>\n"); virBufferCheckError(&buf); return virBufferContentAndReset(&buf); }
char *virSystemdMakeSliceName(const char *partition) { virBuffer buf = VIR_BUFFER_INITIALIZER; if (*partition == '/') partition++; virSystemdEscapeName(&buf, partition); virBufferAddLit(&buf, ".slice"); if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); }
static char * qemuMigrationCookieXMLFormatStr(virQEMUDriverPtr driver, qemuMigrationCookiePtr mig) { virBuffer buf = VIR_BUFFER_INITIALIZER; if (qemuMigrationCookieXMLFormat(driver, &buf, mig) < 0) { virBufferFreeAndReset(&buf); return NULL; } if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); }
char *virSystemdMakeScopeName(const char *name, const char *drivername) { virBuffer buf = VIR_BUFFER_INITIALIZER; virBufferAddLit(&buf, "machine-"); virSystemdEscapeName(&buf, drivername); virBufferAddLit(&buf, "\\x2d"); virSystemdEscapeName(&buf, name); virBufferAddLit(&buf, ".scope"); if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); }
/** * virBitmapToString: * @bitmap: Pointer to bitmap * @prefix: Whether to prepend "0x" * @trim: Whether to output only the minimum required characters * * Convert @bitmap to printable string. * * Returns pointer to the string or NULL on error. */ char * virBitmapToString(virBitmapPtr bitmap, bool prefix, bool trim) { virBuffer buf = VIR_BUFFER_INITIALIZER; size_t sz; size_t len; size_t diff; char *ret = NULL; if (prefix) virBufferAddLit(&buf, "0x"); sz = bitmap->map_len; while (sz--) { virBufferAsprintf(&buf, "%0*lx", VIR_BITMAP_BITS_PER_UNIT / 4, bitmap->map[sz]); } virBufferCheckError(&buf); ret = virBufferContentAndReset(&buf); if (!ret) return NULL; if (!trim) return ret; if (bitmap->nbits != bitmap->map_len * VIR_BITMAP_BITS_PER_UNIT) { char *tmp = ret; if (prefix) tmp += 2; len = strlen(tmp); sz = VIR_DIV_UP(bitmap->nbits, 4); diff = len - sz; if (diff) memmove(tmp, tmp + diff, sz + 1); } return ret; }
char * virCPUDefFormat(virCPUDefPtr def, virDomainNumaPtr numa) { virBuffer buf = VIR_BUFFER_INITIALIZER; if (virCPUDefFormatBufFull(&buf, def, numa) < 0) goto cleanup; if (virBufferCheckError(&buf) < 0) goto cleanup; return virBufferContentAndReset(&buf); cleanup: virBufferFreeAndReset(&buf); return NULL; }
/** * virStringListJoin: * @strings: a NULL-terminated array of strings to join * @delim: a string to insert between each of the strings * * Joins a number of strings together to form one long string, with the * @delim inserted between each of them. The returned string * should be freed with VIR_FREE(). * * Returns: a newly-allocated string containing all of the strings joined * together, with @delim between them */ char *virStringListJoin(const char **strings, const char *delim) { char *ret; virBuffer buf = VIR_BUFFER_INITIALIZER; while (*strings) { virBufferAdd(&buf, *strings, -1); if (*(strings+1)) virBufferAdd(&buf, delim, -1); strings++; } if (virBufferCheckError(&buf) < 0) return NULL; ret = virBufferContentAndReset(&buf); if (!ret) ignore_value(VIR_STRDUP(ret, "")); return ret; }
char * virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef) { virBuffer buf = VIR_BUFFER_INITIALIZER; char *ret = NULL; if (virQEMUBuildCommandLineJSON(srcdef, &buf, virQEMUBuildCommandLineJSONArrayNumbered) < 0) goto cleanup; if (virBufferCheckError(&buf) < 0) goto cleanup; ret = virBufferContentAndReset(&buf); cleanup: virBufferFreeAndReset(&buf); return ret; }
static int testCgroupDetectMounts(const void *args) { int result = -1; const char *file = args; char *mounts = NULL; char *parsed = NULL; const char *actual; virCgroupPtr group = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; if (virAsprintf(&mounts, "%s/vircgroupdata/%s.mounts", abs_srcdir, file) < 0 || virAsprintf(&parsed, "%s/vircgroupdata/%s.parsed", abs_srcdir, file) < 0 || VIR_ALLOC(group) < 0) goto cleanup; if (virCgroupDetectMountsFromFile(group, mounts, false) < 0) goto cleanup; for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { virBufferAsprintf(&buf, "%-12s %s\n", virCgroupControllerTypeToString(i), NULLSTR(group->controllers[i].mountPoint)); } if (virBufferCheckError(&buf) < 0) goto cleanup; actual = virBufferCurrentContent(&buf); if (virtTestCompareToFile(actual, parsed) < 0) goto cleanup; result = 0; cleanup: VIR_FREE(mounts); VIR_FREE(parsed); virCgroupFree(&group); virBufferFreeAndReset(&buf); return result; }
/** * virConfWriteFile: * @filename: the path to the configuration file. * @conf: the conf * * Writes a configuration file back to a file. * * Returns the number of bytes written or -1 in case of error. */ int virConfWriteFile(const char *filename, virConfPtr conf) { virBuffer buf = VIR_BUFFER_INITIALIZER; virConfEntryPtr cur; int ret; int fd; char *content; unsigned int use; if (conf == NULL) return -1; cur = conf->entries; while (cur != NULL) { virConfSaveEntry(&buf, cur); cur = cur->next; } if (virBufferCheckError(&buf) < 0) return -1; fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { virBufferFreeAndReset(&buf); virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to open file")); return -1; } use = virBufferUse(&buf); content = virBufferContentAndReset(&buf); ret = safewrite(fd, content, use); VIR_FREE(content); VIR_FORCE_CLOSE(fd); if (ret != (int)use) { virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to save content")); return -1; } return ret; }
/** * virSysinfoFormat: * @buf: buffer to append output to (may use auto-indentation) * @def: structure to convert to xml string * * Returns 0 on success, -1 on failure after generating an error message. */ int virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def) { virBuffer childrenBuf = VIR_BUFFER_INITIALIZER; const char *type = virSysinfoTypeToString(def->type); int indent = virBufferGetIndent(buf, false); int ret = -1; if (!type) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected sysinfo type model %d"), def->type); virBufferFreeAndReset(buf); goto cleanup; } virBufferAdjustIndent(&childrenBuf, indent + 2); virSysinfoBIOSFormat(&childrenBuf, def->bios); virSysinfoSystemFormat(&childrenBuf, def->system); virSysinfoBaseBoardFormat(&childrenBuf, def->baseBoard, def->nbaseBoard); virSysinfoProcessorFormat(&childrenBuf, def); virSysinfoMemoryFormat(&childrenBuf, def); virBufferAsprintf(buf, "<sysinfo type='%s'", type); if (virBufferUse(&childrenBuf)) { virBufferAddLit(buf, ">\n"); virBufferAddBuffer(buf, &childrenBuf); virBufferAddLit(buf, "</sysinfo>\n"); } else { virBufferAddLit(buf, "/>\n"); } if (virBufferCheckError(buf) < 0) goto cleanup; ret = 0; cleanup: virBufferFreeAndReset(&childrenBuf); return ret; }
/* converts bitmap to string of the form '1,2...' */ char * mapDomainPinVcpu(unsigned char *cpumap, int maplen) { virBuffer buf = VIR_BUFFER_INITIALIZER; size_t len; char *ret = NULL; size_t i, j; for (i = 0; i < maplen; i++) { for (j = 0; j < 8; j++) { if (cpumap[i] & (1 << j)) { virBufferAsprintf(&buf, "%zu,", (8*i)+j); } } } if (virBufferCheckError(&buf) < 0) return NULL; ret = virBufferContentAndReset(&buf); len = strlen(ret); if (len > 0 && ret[len - 1] == ',') ret[len - 1] = 0; return ret; }
static int testQemuDiskXMLToPropsValidateFile(const void *opaque) { struct testQemuDiskXMLToJSONData *data = (void *) opaque; virBuffer buf = VIR_BUFFER_INITIALIZER; char *jsonpath = NULL; char *actual = NULL; int ret = -1; size_t i; if (data->fail) return EXIT_AM_SKIP; if (virAsprintf(&jsonpath, "%s%s.json", testQemuDiskXMLToJSONPath, data->name) < 0) goto cleanup; for (i = 0; i < data->nprops; i++) { char *jsonstr; if (!(jsonstr = virJSONValueToString(data->props[i], true))) goto cleanup; virBufferAdd(&buf, jsonstr, -1); VIR_FREE(jsonstr); } if (virBufferCheckError(&buf) < 0) goto cleanup; actual = virBufferContentAndReset(&buf); ret = virTestCompareToFile(actual, jsonpath); cleanup: VIR_FREE(jsonpath); VIR_FREE(actual); return ret; }
char * virQEMUBuildObjectCommandlineFromJSON(const char *type, const char *alias, virJSONValuePtr props) { virBuffer buf = VIR_BUFFER_INITIALIZER; char *ret = NULL; virBufferAsprintf(&buf, "%s,id=%s,", type, alias); if (virQEMUBuildCommandLineJSON(props, &buf, virQEMUBuildCommandLineJSONArrayBitmap) < 0) goto cleanup; if (virBufferCheckError(&buf) < 0) goto cleanup; ret = virBufferContentAndReset(&buf); cleanup: virBufferFreeAndReset(&buf); return ret; }
static char * bhyveConnectGetSysinfo(virConnectPtr conn, unsigned int flags) { bhyveConnPtr privconn = conn->privateData; virBuffer buf = VIR_BUFFER_INITIALIZER; virCheckFlags(0, NULL); if (virConnectGetSysinfoEnsureACL(conn) < 0) return NULL; if (!privconn->hostsysinfo) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Host SMBIOS information is not available")); return NULL; } if (virSysinfoFormat(&buf, privconn->hostsysinfo) < 0) return NULL; if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); }
/* This function guarantees that query is freed, even on failure */ int hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root, XmlSerializerInfo *serializerInfo, const char *resourceUri, const char *className, hypervObject **list) { int result = -1; WsSerializerContextH serializerContext; client_opt_t *options = NULL; char *query_string = NULL; filter_t *filter = NULL; WsXmlDocH response = NULL; char *enumContext = NULL; hypervObject *head = NULL; hypervObject *tail = NULL; WsXmlNodeH node = NULL; XML_TYPE_PTR data = NULL; hypervObject *object; if (virBufferCheckError(query) < 0) { virBufferFreeAndReset(query); return -1; } query_string = virBufferContentAndReset(query); if (list == NULL || *list != NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); VIR_FREE(query_string); return -1; } serializerContext = wsmc_get_serialization_context(priv->client); options = wsmc_options_init(); if (options == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not initialize options")); goto cleanup; } filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string); if (filter == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create filter")); goto cleanup; } response = wsmc_action_enumerate(priv->client, root, options, filter); if (hyperyVerifyResponse(priv->client, response, "enumeration") < 0) goto cleanup; enumContext = wsmc_get_enum_context(response); ws_xml_destroy_doc(response); response = NULL; while (enumContext != NULL && *enumContext != '\0') { response = wsmc_action_pull(priv->client, resourceUri, options, filter, enumContext); if (hyperyVerifyResponse(priv->client, response, "pull") < 0) goto cleanup; node = ws_xml_get_soap_body(response); if (node == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not lookup SOAP body")); goto cleanup; } node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_PULL_RESP); if (node == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not lookup pull response")); goto cleanup; } node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ITEMS); if (node == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not lookup pull response items")); goto cleanup; } if (ws_xml_get_child(node, 0, resourceUri, className) == NULL) break; data = ws_deserialize(serializerContext, node, serializerInfo, className, resourceUri, NULL, 0, 0); if (data == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not deserialize pull response item")); goto cleanup; } if (VIR_ALLOC(object) < 0) goto cleanup; object->serializerInfo = serializerInfo; object->data = data; data = NULL; if (head == NULL) { head = object; } else { tail->next = object; } tail = object; VIR_FREE(enumContext); enumContext = wsmc_get_enum_context(response); ws_xml_destroy_doc(response); response = NULL; } *list = head; head = NULL; result = 0; cleanup: if (options != NULL) wsmc_options_destroy(options); if (filter != NULL) filter_destroy(filter); if (data != NULL) { #if WS_SERIALIZER_FREE_MEM_WORKS /* FIXME: ws_serializer_free_mem is broken in openwsman <= 2.2.6, * see hypervFreeObject for a detailed explanation. */ if (ws_serializer_free_mem(serializerContext, data, serializerInfo) < 0) { VIR_ERROR(_("Could not free deserialized data")); } #endif } VIR_FREE(query_string); ws_xml_destroy_doc(response); VIR_FREE(enumContext); hypervFreeObject(priv, head); return result; }
/** * virNetDevOpenvswitchAddPort: * @brname: the bridge name * @ifname: the network interface name * @macaddr: the mac address of the virtual interface * @vmuuid: the Domain UUID that has this interface * @ovsport: the ovs specific fields * * Add an interface to the OVS bridge * * Returns 0 in case of success or -1 in case of failure. */ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, const virMacAddr *macaddr, const unsigned char *vmuuid, virNetDevVPortProfilePtr ovsport, virNetDevVlanPtr virtVlan) { int ret = -1; size_t i = 0; virCommandPtr cmd = NULL; char macaddrstr[VIR_MAC_STRING_BUFLEN]; char ifuuidstr[VIR_UUID_STRING_BUFLEN]; char vmuuidstr[VIR_UUID_STRING_BUFLEN]; char *attachedmac_ex_id = NULL; char *ifaceid_ex_id = NULL; char *profile_ex_id = NULL; char *vmid_ex_id = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; virMacAddrFormat(macaddr, macaddrstr); virUUIDFormat(ovsport->interfaceID, ifuuidstr); virUUIDFormat(vmuuid, vmuuidstr); if (virAsprintf(&attachedmac_ex_id, "external-ids:attached-mac=\"%s\"", macaddrstr) < 0) goto cleanup; if (virAsprintf(&ifaceid_ex_id, "external-ids:iface-id=\"%s\"", ifuuidstr) < 0) goto cleanup; if (virAsprintf(&vmid_ex_id, "external-ids:vm-id=\"%s\"", vmuuidstr) < 0) goto cleanup; if (ovsport->profileID[0] != '\0') { if (virAsprintf(&profile_ex_id, "external-ids:port-profile=\"%s\"", ovsport->profileID) < 0) goto cleanup; } cmd = virCommandNew(OVSVSCTL); virCommandAddArgList(cmd, "--timeout=5", "--", "--if-exists", "del-port", ifname, "--", "add-port", brname, ifname, NULL); if (virtVlan && virtVlan->nTags > 0) { switch (virtVlan->nativeMode) { case VIR_NATIVE_VLAN_MODE_TAGGED: virCommandAddArg(cmd, "vlan_mode=native-tagged"); virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); break; case VIR_NATIVE_VLAN_MODE_UNTAGGED: virCommandAddArg(cmd, "vlan_mode=native-untagged"); virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); break; case VIR_NATIVE_VLAN_MODE_DEFAULT: default: break; } if (virtVlan->trunk) { virBufferAddLit(&buf, "trunk="); /* * Trunk ports have at least one VLAN. Do the first one * outside the "for" loop so we can put a "," at the * start of the for loop if there are more than one VLANs * on this trunk port. */ virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); for (i = 1; i < virtVlan->nTags; i++) { virBufferAddLit(&buf, ","); virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); } if (virBufferCheckError(&buf) < 0) goto cleanup; virCommandAddArg(cmd, virBufferCurrentContent(&buf)); } else if (virtVlan->nTags) { virCommandAddArgFormat(cmd, "tag=%d", virtVlan->tag[0]); } } if (ovsport->profileID[0] == '\0') { virCommandAddArgList(cmd, "--", "set", "Interface", ifname, attachedmac_ex_id, "--", "set", "Interface", ifname, ifaceid_ex_id, "--", "set", "Interface", ifname, vmid_ex_id, "--", "set", "Interface", ifname, "external-ids:iface-status=active", NULL); } else { virCommandAddArgList(cmd, "--", "set", "Interface", ifname, attachedmac_ex_id, "--", "set", "Interface", ifname, ifaceid_ex_id, "--", "set", "Interface", ifname, vmid_ex_id, "--", "set", "Interface", ifname, profile_ex_id, "--", "set", "Interface", ifname, "external-ids:iface-status=active", NULL); } if (virCommandRun(cmd, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to add port %s to OVS bridge %s"), ifname, brname); goto cleanup; } ret = 0; cleanup: virBufferFreeAndReset(&buf); VIR_FREE(attachedmac_ex_id); VIR_FREE(ifaceid_ex_id); VIR_FREE(vmid_ex_id); VIR_FREE(profile_ex_id); virCommandFree(cmd); return ret; }
static int xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk) { virBuffer buf = VIR_BUFFER_INITIALIZER; virConfValuePtr val, tmp; int format = virDomainDiskGetFormat(disk); const char *driver = virDomainDiskGetDriver(disk); char *target = NULL; /* format */ virBufferAddLit(&buf, "format="); switch (format) { case VIR_STORAGE_FILE_RAW: virBufferAddLit(&buf, "raw,"); break; case VIR_STORAGE_FILE_VHD: virBufferAddLit(&buf, "xvhd,"); break; case VIR_STORAGE_FILE_QCOW: virBufferAddLit(&buf, "qcow,"); break; case VIR_STORAGE_FILE_QCOW2: virBufferAddLit(&buf, "qcow2,"); break; /* set default */ default: virBufferAddLit(&buf, "raw,"); } /* device */ virBufferAsprintf(&buf, "vdev=%s,", disk->dst); /* access */ virBufferAddLit(&buf, "access="); if (disk->src->readonly) virBufferAddLit(&buf, "ro,"); else if (disk->src->shared) virBufferAddLit(&buf, "!,"); else virBufferAddLit(&buf, "rw,"); if (disk->transient) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("transient disks not supported yet")); goto cleanup; } /* backendtype */ if (driver) { virBufferAddLit(&buf, "backendtype="); if (STREQ(driver, "qemu") || STREQ(driver, "file")) virBufferAddLit(&buf, "qdisk,"); else if (STREQ(driver, "tap")) virBufferAddLit(&buf, "tap,"); else if (STREQ(driver, "phy")) virBufferAddLit(&buf, "phy,"); } /* devtype */ if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&buf, "devtype=cdrom,"); /* * target * From $xensrc/docs/misc/xl-disk-configuration.txt: * When this parameter is specified by name, ie with the "target=" * syntax in the configuration file, it consumes the whole rest of the * <diskspec> including trailing whitespaces. Therefore in that case * it must come last. */ if (xenFormatXLDiskSrc(disk->src, &target) < 0) goto cleanup; virBufferAsprintf(&buf, "target=%s", target); if (virBufferCheckError(&buf) < 0) goto cleanup; if (VIR_ALLOC(val) < 0) goto cleanup; val->type = VIR_CONF_STRING; val->str = virBufferContentAndReset(&buf); tmp = list->list; while (tmp && tmp->next) tmp = tmp->next; if (tmp) tmp->next = val; else list->list = val; return 0; cleanup: VIR_FREE(target); virBufferFreeAndReset(&buf); return -1; }
static char * xenFormatXLDiskSrcNet(virStorageSourcePtr src) { char *ret = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; switch ((virStorageNetProtocol) src->protocol) { case VIR_STORAGE_NET_PROTOCOL_NBD: case VIR_STORAGE_NET_PROTOCOL_HTTP: case VIR_STORAGE_NET_PROTOCOL_HTTPS: case VIR_STORAGE_NET_PROTOCOL_FTP: case VIR_STORAGE_NET_PROTOCOL_FTPS: case VIR_STORAGE_NET_PROTOCOL_TFTP: case VIR_STORAGE_NET_PROTOCOL_ISCSI: case VIR_STORAGE_NET_PROTOCOL_GLUSTER: case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: case VIR_STORAGE_NET_PROTOCOL_LAST: case VIR_STORAGE_NET_PROTOCOL_NONE: virReportError(VIR_ERR_NO_SUPPORT, _("Unsupported network block protocol '%s'"), virStorageNetProtocolTypeToString(src->protocol)); goto cleanup; case VIR_STORAGE_NET_PROTOCOL_RBD: if (strchr(src->path, ':')) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("':' not allowed in RBD source volume name '%s'"), src->path); goto cleanup; } virBufferStrcat(&buf, "rbd:", src->path, NULL); virBufferAddLit(&buf, ":auth_supported=none"); if (src->nhosts > 0) { virBufferAddLit(&buf, ":mon_host="); for (i = 0; i < src->nhosts; i++) { if (i) virBufferAddLit(&buf, "\\\\;"); /* assume host containing : is ipv6 */ if (strchr(src->hosts[i].name, ':')) virBufferEscape(&buf, '\\', ":", "[%s]", src->hosts[i].name); else virBufferAsprintf(&buf, "%s", src->hosts[i].name); if (src->hosts[i].port) virBufferAsprintf(&buf, "\\\\:%s", src->hosts[i].port); } } if (virBufferCheckError(&buf) < 0) goto cleanup; ret = virBufferContentAndReset(&buf); break; } cleanup: virBufferFreeAndReset(&buf); return ret; }
/** * virCapabilitiesFormatXML: * @caps: capabilities to format * * Convert the capabilities object into an XML representation * * Returns the XML document as a string */ char * virCapabilitiesFormatXML(virCapsPtr caps) { virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i, j, k; char host_uuid[VIR_UUID_STRING_BUFLEN]; virBufferAddLit(&buf, "<capabilities>\n\n"); virBufferAdjustIndent(&buf, 2); virBufferAddLit(&buf, "<host>\n"); virBufferAdjustIndent(&buf, 2); if (virUUIDIsValid(caps->host.host_uuid)) { virUUIDFormat(caps->host.host_uuid, host_uuid); virBufferAsprintf(&buf, "<uuid>%s</uuid>\n", host_uuid); } virBufferAddLit(&buf, "<cpu>\n"); virBufferAdjustIndent(&buf, 2); if (caps->host.arch) virBufferAsprintf(&buf, "<arch>%s</arch>\n", virArchToString(caps->host.arch)); if (caps->host.nfeatures) { virBufferAddLit(&buf, "<features>\n"); virBufferAdjustIndent(&buf, 2); for (i = 0; i < caps->host.nfeatures; i++) { virBufferAsprintf(&buf, "<%s/>\n", caps->host.features[i]); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</features>\n"); } virCPUDefFormatBuf(&buf, caps->host.cpu, 0); for (i = 0; i < caps->host.nPagesSize; i++) { virBufferAsprintf(&buf, "<pages unit='KiB' size='%u'/>\n", caps->host.pagesSize[i]); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</cpu>\n"); /* The PM query was successful. */ if (caps->host.powerMgmt) { /* The host supports some PM features. */ unsigned int pm = caps->host.powerMgmt; virBufferAddLit(&buf, "<power_management>\n"); virBufferAdjustIndent(&buf, 2); while (pm) { int bit = ffs(pm) - 1; virBufferAsprintf(&buf, "<%s/>\n", virCapsHostPMTargetTypeToString(bit)); pm &= ~(1U << bit); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</power_management>\n"); } else { /* The host does not support any PM feature. */ virBufferAddLit(&buf, "<power_management/>\n"); } if (caps->host.offlineMigrate) { virBufferAddLit(&buf, "<migration_features>\n"); virBufferAdjustIndent(&buf, 2); if (caps->host.liveMigrate) virBufferAddLit(&buf, "<live/>\n"); if (caps->host.nmigrateTrans) { virBufferAddLit(&buf, "<uri_transports>\n"); virBufferAdjustIndent(&buf, 2); for (i = 0; i < caps->host.nmigrateTrans; i++) { virBufferAsprintf(&buf, "<uri_transport>%s</uri_transport>\n", caps->host.migrateTrans[i]); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</uri_transports>\n"); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</migration_features>\n"); } if (caps->host.nnumaCell && virCapabilitiesFormatNUMATopology(&buf, caps->host.nnumaCell, caps->host.numaCell) < 0) return NULL; for (i = 0; i < caps->host.nsecModels; i++) { virBufferAddLit(&buf, "<secmodel>\n"); virBufferAdjustIndent(&buf, 2); virBufferAsprintf(&buf, "<model>%s</model>\n", caps->host.secModels[i].model); virBufferAsprintf(&buf, "<doi>%s</doi>\n", caps->host.secModels[i].doi); for (j = 0; j < caps->host.secModels[i].nlabels; j++) { virBufferAsprintf(&buf, "<baselabel type='%s'>%s</baselabel>\n", caps->host.secModels[i].labels[j].type, caps->host.secModels[i].labels[j].label); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</secmodel>\n"); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</host>\n\n"); for (i = 0; i < caps->nguests; i++) { virBufferAddLit(&buf, "<guest>\n"); virBufferAdjustIndent(&buf, 2); virBufferAsprintf(&buf, "<os_type>%s</os_type>\n", caps->guests[i]->ostype); if (caps->guests[i]->arch.id) virBufferAsprintf(&buf, "<arch name='%s'>\n", virArchToString(caps->guests[i]->arch.id)); virBufferAdjustIndent(&buf, 2); virBufferAsprintf(&buf, "<wordsize>%d</wordsize>\n", caps->guests[i]->arch.wordsize); if (caps->guests[i]->arch.defaultInfo.emulator) virBufferAsprintf(&buf, "<emulator>%s</emulator>\n", caps->guests[i]->arch.defaultInfo.emulator); if (caps->guests[i]->arch.defaultInfo.loader) virBufferAsprintf(&buf, "<loader>%s</loader>\n", caps->guests[i]->arch.defaultInfo.loader); for (j = 0; j < caps->guests[i]->arch.defaultInfo.nmachines; j++) { virCapsGuestMachinePtr machine = caps->guests[i]->arch.defaultInfo.machines[j]; virBufferAddLit(&buf, "<machine"); if (machine->canonical) virBufferAsprintf(&buf, " canonical='%s'", machine->canonical); if (machine->maxCpus > 0) virBufferAsprintf(&buf, " maxCpus='%d'", machine->maxCpus); virBufferAsprintf(&buf, ">%s</machine>\n", machine->name); } for (j = 0; j < caps->guests[i]->arch.ndomains; j++) { virBufferAsprintf(&buf, "<domain type='%s'>\n", caps->guests[i]->arch.domains[j]->type); virBufferAdjustIndent(&buf, 2); if (caps->guests[i]->arch.domains[j]->info.emulator) virBufferAsprintf(&buf, "<emulator>%s</emulator>\n", caps->guests[i]->arch.domains[j]->info.emulator); if (caps->guests[i]->arch.domains[j]->info.loader) virBufferAsprintf(&buf, "<loader>%s</loader>\n", caps->guests[i]->arch.domains[j]->info.loader); for (k = 0; k < caps->guests[i]->arch.domains[j]->info.nmachines; k++) { virCapsGuestMachinePtr machine = caps->guests[i]->arch.domains[j]->info.machines[k]; virBufferAddLit(&buf, "<machine"); if (machine->canonical) virBufferAsprintf(&buf, " canonical='%s'", machine->canonical); if (machine->maxCpus > 0) virBufferAsprintf(&buf, " maxCpus='%d'", machine->maxCpus); virBufferAsprintf(&buf, ">%s</machine>\n", machine->name); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</domain>\n"); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</arch>\n"); if (caps->guests[i]->nfeatures) { virBufferAddLit(&buf, "<features>\n"); virBufferAdjustIndent(&buf, 2); for (j = 0; j < caps->guests[i]->nfeatures; j++) { if (STREQ(caps->guests[i]->features[j]->name, "pae") || STREQ(caps->guests[i]->features[j]->name, "nonpae") || STREQ(caps->guests[i]->features[j]->name, "ia64_be") || STREQ(caps->guests[i]->features[j]->name, "cpuselection") || STREQ(caps->guests[i]->features[j]->name, "deviceboot")) { virBufferAsprintf(&buf, "<%s/>\n", caps->guests[i]->features[j]->name); } else { virBufferAsprintf(&buf, "<%s default='%s' toggle='%s'/>\n", caps->guests[i]->features[j]->name, caps->guests[i]->features[j]->defaultOn ? "on" : "off", caps->guests[i]->features[j]->toggle ? "yes" : "no"); } } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</features>\n"); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</guest>\n\n"); } virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</capabilities>\n"); if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); }
static int virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, virConnectPtr conn, virStoragePoolSourcePtr source) { int ret = -1; int r = 0; virStorageAuthDefPtr authdef = source->auth; unsigned char *secret_value = NULL; size_t secret_value_size = 0; char *rados_key = NULL; virBuffer mon_host = VIR_BUFFER_INITIALIZER; size_t i; char *mon_buff = NULL; const char *client_mount_timeout = "30"; const char *mon_op_timeout = "30"; const char *osd_op_timeout = "30"; const char *rbd_default_format = "2"; if (authdef) { VIR_DEBUG("Using cephx authorization, username: %s", authdef->username); if ((r = rados_create(&ptr->cluster, authdef->username)) < 0) { virReportSystemError(-r, "%s", _("failed to initialize RADOS")); goto cleanup; } if (!conn) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'ceph' authentication not supported " "for autostarted pools")); return -1; } if (virSecretGetSecretString(conn, &authdef->seclookupdef, VIR_SECRET_USAGE_TYPE_CEPH, &secret_value, &secret_value_size) < 0) goto cleanup; if (!(rados_key = virStringEncodeBase64(secret_value, secret_value_size))) goto cleanup; VIR_DEBUG("Found cephx key: %s", rados_key); if (rados_conf_set(ptr->cluster, "key", rados_key) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "rados_key"); goto cleanup; } if (rados_conf_set(ptr->cluster, "auth_supported", "cephx") < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "auth_supported"); goto cleanup; } } else { VIR_DEBUG("Not using cephx authorization"); if (rados_create(&ptr->cluster, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to create the RADOS cluster")); goto cleanup; } if (rados_conf_set(ptr->cluster, "auth_supported", "none") < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "auth_supported"); goto cleanup; } } VIR_DEBUG("Found %zu RADOS cluster monitors in the pool configuration", source->nhost); for (i = 0; i < source->nhost; i++) { if (source->hosts[i].name != NULL && !source->hosts[i].port) { virBufferAsprintf(&mon_host, "%s,", source->hosts[i].name); } else if (source->hosts[i].name != NULL && source->hosts[i].port) { virBufferAsprintf(&mon_host, "%s:%d,", source->hosts[i].name, source->hosts[i].port); } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("received malformed monitor, check the XML definition")); } } if (virBufferCheckError(&mon_host) < 0) goto cleanup; mon_buff = virBufferContentAndReset(&mon_host); VIR_DEBUG("RADOS mon_host has been set to: %s", mon_buff); if (rados_conf_set(ptr->cluster, "mon_host", mon_buff) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "mon_host"); goto cleanup; } /* * Set timeout options for librados. * In case the Ceph cluster is down libvirt won't block forever. * Operations in librados will return -ETIMEDOUT when the timeout is reached. */ VIR_DEBUG("Setting RADOS option client_mount_timeout to %s", client_mount_timeout); rados_conf_set(ptr->cluster, "client_mount_timeout", client_mount_timeout); VIR_DEBUG("Setting RADOS option rados_mon_op_timeout to %s", mon_op_timeout); rados_conf_set(ptr->cluster, "rados_mon_op_timeout", mon_op_timeout); VIR_DEBUG("Setting RADOS option rados_osd_op_timeout to %s", osd_op_timeout); rados_conf_set(ptr->cluster, "rados_osd_op_timeout", osd_op_timeout); /* * Librbd supports creating RBD format 2 images. We no longer have to invoke * rbd_create3(), we can tell librbd to default to format 2. * This leaves us to simply use rbd_create() and use the default behavior of librbd */ VIR_DEBUG("Setting RADOS option rbd_default_format to %s", rbd_default_format); rados_conf_set(ptr->cluster, "rbd_default_format", rbd_default_format); ptr->starttime = time(0); if ((r = rados_connect(ptr->cluster)) < 0) { virReportSystemError(-r, _("failed to connect to the RADOS monitor on: %s"), mon_buff); goto cleanup; } ret = 0; cleanup: VIR_DISPOSE_N(secret_value, secret_value_size); VIR_DISPOSE_STRING(rados_key); virBufferFreeAndReset(&mon_host); VIR_FREE(mon_buff); return ret; }
static int xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk) { virBuffer buf = VIR_BUFFER_INITIALIZER; virConfValuePtr val, tmp; const char *src = virDomainDiskGetSource(disk); int format = virDomainDiskGetFormat(disk); const char *driver = virDomainDiskGetDriver(disk); /* target */ virBufferAsprintf(&buf, "%s,", src); /* format */ switch (format) { case VIR_STORAGE_FILE_RAW: virBufferAddLit(&buf, "raw,"); break; case VIR_STORAGE_FILE_VHD: virBufferAddLit(&buf, "xvhd,"); break; case VIR_STORAGE_FILE_QCOW: virBufferAddLit(&buf, "qcow,"); break; case VIR_STORAGE_FILE_QCOW2: virBufferAddLit(&buf, "qcow2,"); break; /* set default */ default: virBufferAddLit(&buf, "raw,"); } /* device */ virBufferAdd(&buf, disk->dst, -1); virBufferAddLit(&buf, ","); if (disk->src->readonly) virBufferAddLit(&buf, "r,"); else if (disk->src->shared) virBufferAddLit(&buf, "!,"); else virBufferAddLit(&buf, "w,"); if (disk->transient) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("transient disks not supported yet")); goto cleanup; } if (STREQ_NULLABLE(driver, "qemu")) virBufferAddLit(&buf, "backendtype=qdisk"); else if (STREQ_NULLABLE(driver, "tap")) virBufferAddLit(&buf, "backendtype=tap"); else if (STREQ_NULLABLE(driver, "phy")) virBufferAddLit(&buf, "backendtype=phy"); if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&buf, ",devtype=cdrom"); if (virBufferCheckError(&buf) < 0) goto cleanup; if (VIR_ALLOC(val) < 0) goto cleanup; val->type = VIR_CONF_STRING; val->str = virBufferContentAndReset(&buf); tmp = list->list; while (tmp && tmp->next) tmp = tmp->next; if (tmp) tmp->next = val; else list->list = val; return 0; cleanup: virBufferFreeAndReset(&buf); return -1; }
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; }
static char * umlBuildCommandLineNet(virConnectPtr conn, virDomainDefPtr vm, virDomainNetDefPtr def, int idx) { virBuffer buf = VIR_BUFFER_INITIALIZER; char macaddr[VIR_MAC_STRING_BUFLEN]; /* General format: ethNN=type,options */ virBufferAsprintf(&buf, "eth%d=", idx); switch (def->type) { case VIR_DOMAIN_NET_TYPE_USER: /* ethNNN=slirp,macaddr */ virBufferAddLit(&buf, "slirp"); break; case VIR_DOMAIN_NET_TYPE_ETHERNET: /* ethNNN=tuntap,tapname,macaddr,gateway */ virBufferAddLit(&buf, "tuntap,"); if (def->ifname) virBufferAdd(&buf, def->ifname, -1); if (def->nips > 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("IP address not supported for ethernet interface")); goto error; } break; case VIR_DOMAIN_NET_TYPE_VHOSTUSER: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("vhostuser networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_SERVER: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("TCP server networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_CLIENT: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("TCP client networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_MCAST: /* ethNNN=tuntap,macaddr,ipaddr,port */ virBufferAddLit(&buf, "mcast"); break; case VIR_DOMAIN_NET_TYPE_NETWORK: { char *bridge; virNetworkPtr network = virNetworkLookupByName(conn, def->data.network.name); if (!network) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Network '%s' not found"), def->data.network.name); goto error; } bridge = virNetworkGetBridgeName(network); virObjectUnref(network); if (bridge == NULL) goto error; if (umlConnectTapDevice(vm, def, bridge) < 0) { VIR_FREE(bridge); goto error; } /* ethNNN=tuntap,tapname,macaddr,gateway */ virBufferAsprintf(&buf, "tuntap,%s", def->ifname); break; } case VIR_DOMAIN_NET_TYPE_BRIDGE: if (umlConnectTapDevice(vm, def, def->data.bridge.brname) < 0) goto error; /* ethNNN=tuntap,tapname,macaddr,gateway */ virBufferAsprintf(&buf, "tuntap,%s", def->ifname); break; case VIR_DOMAIN_NET_TYPE_INTERNAL: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("internal networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_DIRECT: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("direct networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_HOSTDEV: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("hostdev networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_LAST: break; } if (def->script) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("interface script execution not supported by this driver")); goto error; } virBufferAsprintf(&buf, ",%s", virMacAddrFormat(&def->mac, macaddr)); if (def->type == VIR_DOMAIN_NET_TYPE_MCAST) { virBufferAsprintf(&buf, ",%s,%d", def->data.socket.address, def->data.socket.port); } if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); error: virBufferFreeAndReset(&buf); return NULL; }