static int testBufInfiniteLoop(const void *data) { virBuffer bufinit = VIR_BUFFER_INITIALIZER; virBufferPtr buf = &bufinit; char *addstr = NULL, *bufret = NULL; int ret = -1; const struct testInfo *info = data; virBufferAddChar(buf, 'a'); /* * Infinite loop used to trigger if: * (strlen + 1 > 1000) && (strlen == buf-size - buf-use - 1) * which was the case after the above addchar at the time of the bug. * This test is a bit fragile, since it relies on virBuffer internals. */ if (virAsprintf(&addstr, "%*s", buf->a - buf->b - 1, "a") < 0) { goto out; } if (info->doEscape) virBufferEscapeString(buf, "%s", addstr); else virBufferAsprintf(buf, "%s", addstr); ret = 0; out: bufret = virBufferContentAndReset(buf); if (!bufret) { TEST_ERROR("Buffer had error set"); ret = -1; } VIR_FREE(addstr); VIR_FREE(bufret); 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); }
static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline) { char *expectargv = NULL; char *actualargv = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; virNetworkDefPtr def = NULL; int ret = -1; virCommandSetDryRun(&buf, NULL, NULL); if (!(def = virNetworkDefParseFile(xml))) goto cleanup; if (networkAddFirewallRules(def) < 0) goto cleanup; if (virBufferError(&buf)) goto cleanup; actualargv = virBufferContentAndReset(&buf); virTestClearCommandPath(actualargv); virCommandSetDryRun(NULL, NULL, NULL); if (virTestCompareToFile(actualargv, cmdline) < 0) goto cleanup; ret = 0; cleanup: virBufferFreeAndReset(&buf); VIR_FREE(expectargv); VIR_FREE(actualargv); virNetworkDefFree(def); return ret; }
/* * Call after adding all arguments and environment settings, but before * Run/RunAsync, to return a string representation of the environment and * arguments of cmd. If virCommandRun cannot succeed (because of an * out-of-memory condition while building cmd), NULL will be returned. * Caller is responsible for freeing the resulting string. */ char * virCommandToString(virCommandPtr cmd) { size_t i; virBuffer buf = VIR_BUFFER_INITIALIZER; /* Cannot assume virCommandRun will be called; so report the error * now. If virCommandRun is called, it will report the same error. */ if (!cmd ||cmd->has_error == ENOMEM) { virReportOOMError(); return NULL; } if (cmd->has_error) { virCommandError(VIR_ERR_INTERNAL_ERROR, "%s", _("invalid use of command API")); return NULL; } for (i = 0; i < cmd->nenv; i++) { virBufferAdd(&buf, cmd->env[i], strlen(cmd->env[i])); virBufferAddChar(&buf, ' '); } virBufferAdd(&buf, cmd->args[0], strlen(cmd->args[0])); for (i = 1; i < cmd->nargs; i++) { virBufferAddChar(&buf, ' '); virBufferAdd(&buf, cmd->args[i], strlen(cmd->args[i])); } if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); virReportOOMError(); return NULL; } return virBufferContentAndReset(&buf); }
/** * virStringJoin: * @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 *virStringJoin(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 (virBufferError(&buf)) { virReportOOMError(); return NULL; } ret = virBufferContentAndReset(&buf); if (!ret) { if (!(ret = strdup(""))) { virReportOOMError(); return NULL; } } 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 (virJSONValueObjectForeachKeyValue(props, virQEMUBuildObjectCommandLineProps, &buf) < 0) goto cleanup; if (virBufferCheckError(&buf) < 0) goto cleanup; ret = virBufferContentAndReset(&buf); cleanup: virBufferFreeAndReset(&buf); return ret; }
/** * 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 (virBufferError(&buf)) { virBufferFreeAndReset(&buf); virReportOOMError(); 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 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 int openvzDomainSetNetwork(virConnectPtr conn, const char *vpsid, virDomainNetDefPtr net, virBufferPtr configBuf) { int rc = 0, narg; const char *prog[OPENVZ_MAX_ARG]; char macaddr[VIR_MAC_STRING_BUFLEN]; unsigned char host_mac[VIR_MAC_BUFLEN]; char host_macaddr[VIR_MAC_STRING_BUFLEN]; struct openvz_driver *driver = conn->privateData; char *opt = NULL; #define ADD_ARG_LIT(thisarg) \ do { \ if (narg >= OPENVZ_MAX_ARG) \ goto no_memory; \ if ((prog[narg++] = strdup(thisarg)) == NULL) \ goto no_memory; \ } while (0) if (net == NULL) return 0; if (vpsid == NULL) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Container ID is not specified")); return -1; } for (narg = 0; narg < OPENVZ_MAX_ARG; narg++) prog[narg] = NULL; narg = 0; if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE || net->type == VIR_DOMAIN_NET_TYPE_ETHERNET) { ADD_ARG_LIT(VZCTL); ADD_ARG_LIT("--quiet"); ADD_ARG_LIT("set"); ADD_ARG_LIT(vpsid); } virFormatMacAddr(net->mac, macaddr); virCapabilitiesGenerateMac(driver->caps, host_mac); virFormatMacAddr(host_mac, host_macaddr); if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE || (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET && net->data.ethernet.ipaddr == NULL)) { virBuffer buf = VIR_BUFFER_INITIALIZER; int veid = openvzGetVEID(vpsid); /* --netif_add ifname[,mac,host_ifname,host_mac] */ ADD_ARG_LIT("--netif_add") ; /* if user doesn't specify guest interface name, * then we need to generate it */ if (net->data.ethernet.dev == NULL) { net->data.ethernet.dev = openvzGenerateContainerVethName(veid); if (net->data.ethernet.dev == NULL) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not generate eth name for container")); rc = -1; goto exit; } } /* if user doesn't specified host interface name, * than we need to generate it */ if (net->ifname == NULL) { net->ifname = openvzGenerateVethName(veid, net->data.ethernet.dev); if (net->ifname == NULL) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not generate veth name")); rc = -1; goto exit; } } virBufferAdd(&buf, net->data.ethernet.dev, -1); /* Guest dev */ virBufferAsprintf(&buf, ",%s", macaddr); /* Guest dev mac */ virBufferAsprintf(&buf, ",%s", net->ifname); /* Host dev */ virBufferAsprintf(&buf, ",%s", host_macaddr); /* Host dev mac */ if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) { if (driver->version >= VZCTL_BRIDGE_MIN_VERSION) { virBufferAsprintf(&buf, ",%s", net->data.bridge.brname); /* Host bridge */ } else { virBufferAsprintf(configBuf, "ifname=%s", net->data.ethernet.dev); virBufferAsprintf(configBuf, ",mac=%s", macaddr); /* Guest dev mac */ virBufferAsprintf(configBuf, ",host_ifname=%s", net->ifname); /* Host dev */ virBufferAsprintf(configBuf, ",host_mac=%s", host_macaddr); /* Host dev mac */ virBufferAsprintf(configBuf, ",bridge=%s", net->data.bridge.brname); /* Host bridge */ } } if (!(opt = virBufferContentAndReset(&buf))) goto no_memory; ADD_ARG_LIT(opt) ; VIR_FREE(opt); } else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET && net->data.ethernet.ipaddr != NULL) { /* --ipadd ip */ ADD_ARG_LIT("--ipadd") ; ADD_ARG_LIT(net->data.ethernet.ipaddr) ; } /* TODO: processing NAT and physical device */ if (prog[0] != NULL) { ADD_ARG_LIT("--save"); if (virRun(prog, NULL) < 0) { rc = -1; goto exit; } } exit: cmdExecFree(prog); return rc; no_memory: VIR_FREE(opt); openvzError(VIR_ERR_INTERNAL_ERROR, _("Could not put argument to %s"), VZCTL); cmdExecFree(prog); return -1; #undef ADD_ARG_LIT }
static int virLockManagerSanlockRegisterKillscript(int sock, const char *vmuri, const char *uuidstr, virDomainLockFailureAction action) { virBuffer buf = VIR_BUFFER_INITIALIZER; char *path; char *args = NULL; int ret = -1; int rv; if (action > VIR_DOMAIN_LOCK_FAILURE_IGNORE) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Failure action %s is not supported by sanlock"), virDomainLockFailureTypeToString(action)); goto cleanup; } virBufferEscape(&buf, '\\', "\\ ", "%s", vmuri); virBufferAddLit(&buf, " "); virBufferEscape(&buf, '\\', "\\ ", "%s", uuidstr); virBufferAddLit(&buf, " "); virBufferEscape(&buf, '\\', "\\ ", "%s", virDomainLockFailureTypeToString(action)); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); virReportOOMError(); goto cleanup; } /* Unfortunately, sanlock_killpath() does not use const for either * path or args even though it will just copy them into its own * buffers. */ path = (char *) VIR_LOCK_MANAGER_SANLOCK_KILLPATH; args = virBufferContentAndReset(&buf); VIR_DEBUG("Register sanlock killpath: %s %s", path, args); /* sanlock_killpath() would just crop the strings */ if (strlen(path) >= SANLK_HELPER_PATH_LEN) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Sanlock helper path is longer than %d: '%s'"), SANLK_HELPER_PATH_LEN - 1, path); goto cleanup; } if (strlen(args) >= SANLK_HELPER_ARGS_LEN) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Sanlock helper arguments are longer than %d:" " '%s'"), SANLK_HELPER_ARGS_LEN - 1, args); goto cleanup; } if ((rv = sanlock_killpath(sock, 0, path, args)) < 0) { if (rv <= -200) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to register lock failure action:" " error %d"), rv); } else { virReportSystemError(-rv, "%s", _("Failed to register lock failure" " action")); } goto cleanup; } ret = 0; cleanup: VIR_FREE(args); return ret; }
static int virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr *ptr, virConnectPtr conn, virStoragePoolObjPtr pool) { int ret = -1; unsigned char *secret_value = NULL; size_t secret_value_size; char *rados_key = NULL; virBuffer mon_host = VIR_BUFFER_INITIALIZER; virSecretPtr secret = NULL; char secretUuid[VIR_UUID_STRING_BUFLEN]; int i; char *mon_buff = NULL; VIR_DEBUG("Found Cephx username: %s", pool->def->source.auth.cephx.username); if (pool->def->source.auth.cephx.username != NULL) { VIR_DEBUG("Using cephx authorization"); if (rados_create(&ptr->cluster, pool->def->source.auth.cephx.username) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to initialize RADOS")); goto cleanup; } if (pool->def->source.auth.cephx.secret.uuidUsable) { virUUIDFormat(pool->def->source.auth.cephx.secret.uuid, secretUuid); VIR_DEBUG("Looking up secret by UUID: %s", secretUuid); secret = virSecretLookupByUUIDString(conn, secretUuid); } else if (pool->def->source.auth.cephx.secret.usage != NULL) { VIR_DEBUG("Looking up secret by usage: %s", pool->def->source.auth.cephx.secret.usage); secret = virSecretLookupByUsage(conn, VIR_SECRET_USAGE_TYPE_CEPH, pool->def->source.auth.cephx.secret.usage); } if (secret == NULL) { virReportError(VIR_ERR_NO_SECRET, "%s", _("failed to find the secret")); goto cleanup; } secret_value = virSecretGetValue(secret, &secret_value_size, 0); base64_encode_alloc((char *)secret_value, secret_value_size, &rados_key); memset(secret_value, 0, secret_value_size); if (rados_key == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to decode the RADOS key")); 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; } memset(rados_key, 0, strlen(rados_key)); 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", pool->def->source.nhost); for (i = 0; i < pool->def->source.nhost; i++) { if (pool->def->source.hosts[i].name != NULL && !pool->def->source.hosts[i].port) { virBufferAsprintf(&mon_host, "%s:6789,", pool->def->source.hosts[i].name); } else if (pool->def->source.hosts[i].name != NULL && pool->def->source.hosts[i].port) { virBufferAsprintf(&mon_host, "%s:%d,", pool->def->source.hosts[i].name, pool->def->source.hosts[i].port); } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("received malformed monitor, check the XML definition")); } } if (virBufferError(&mon_host)) { virReportOOMError(); 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; } ptr->starttime = time(0); if (rados_connect(ptr->cluster) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to connect to the RADOS monitor on: %s"), mon_buff); goto cleanup; } ret = 0; cleanup: VIR_FREE(secret_value); VIR_FREE(rados_key); virSecretFree(secret); virBufferFreeAndReset(&mon_host); VIR_FREE(mon_buff); return ret; }
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; }
char *virDomainSnapshotDefFormat(const char *domain_uuid, virDomainSnapshotDefPtr def, unsigned int flags, int internal) { virBuffer buf = VIR_BUFFER_INITIALIZER; int i; virCheckFlags(VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_UPDATE_CPU, NULL); flags |= VIR_DOMAIN_XML_INACTIVE; virBufferAddLit(&buf, "<domainsnapshot>\n"); virBufferEscapeString(&buf, " <name>%s</name>\n", def->name); if (def->description) virBufferEscapeString(&buf, " <description>%s</description>\n", def->description); virBufferAsprintf(&buf, " <state>%s</state>\n", virDomainSnapshotStateTypeToString(def->state)); if (def->parent) { virBufferAddLit(&buf, " <parent>\n"); virBufferEscapeString(&buf, " <name>%s</name>\n", def->parent); virBufferAddLit(&buf, " </parent>\n"); } virBufferAsprintf(&buf, " <creationTime>%lld</creationTime>\n", def->creationTime); if (def->memory) { virBufferAsprintf(&buf, " <memory snapshot='%s'", virDomainSnapshotLocationTypeToString(def->memory)); virBufferEscapeString(&buf, " file='%s'", def->file); virBufferAddLit(&buf, "/>\n"); } if (def->ndisks) { virBufferAddLit(&buf, " <disks>\n"); for (i = 0; i < def->ndisks; i++) { virDomainSnapshotDiskDefPtr disk = &def->disks[i]; if (!disk->name) continue; virBufferEscapeString(&buf, " <disk name='%s'", disk->name); if (disk->snapshot) virBufferAsprintf(&buf, " snapshot='%s'", virDomainSnapshotLocationTypeToString(disk->snapshot)); if (disk->file || disk->format > 0) { virBufferAddLit(&buf, ">\n"); if (disk->format > 0) virBufferEscapeString(&buf, " <driver type='%s'/>\n", virStorageFileFormatTypeToString( disk->format)); if (disk->file) virBufferEscapeString(&buf, " <source file='%s'/>\n", disk->file); virBufferAddLit(&buf, " </disk>\n"); } else { virBufferAddLit(&buf, "/>\n"); } } virBufferAddLit(&buf, " </disks>\n"); } if (def->dom) { virBufferAdjustIndent(&buf, 2); if (virDomainDefFormatInternal(def->dom, flags, &buf) < 0) { virBufferFreeAndReset(&buf); return NULL; } virBufferAdjustIndent(&buf, -2); } else if (domain_uuid) { virBufferAddLit(&buf, " <domain>\n"); virBufferAsprintf(&buf, " <uuid>%s</uuid>\n", domain_uuid); virBufferAddLit(&buf, " </domain>\n"); } if (internal) virBufferAsprintf(&buf, " <active>%d</active>\n", def->current); virBufferAddLit(&buf, "</domainsnapshot>\n"); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); virReportOOMError(); return NULL; } return virBufferContentAndReset(&buf); }
/** * virBufferFreeAndReset: * @buf: the buffer to free and reset * * Frees the buffer content and resets the buffer structure. */ void virBufferFreeAndReset(virBufferPtr buf) { char *str = virBufferContentAndReset(buf); VIR_FREE(str); }
char *virNodeDeviceDefFormat(const virNodeDeviceDefPtr def) { virBuffer buf = VIR_BUFFER_INITIALIZER; virNodeDevCapsDefPtr caps; unsigned int i = 0; virBufferAddLit(&buf, "<device>\n"); virBufferEscapeString(&buf, " <name>%s</name>\n", def->name); if (def->parent) { virBufferEscapeString(&buf, " <parent>%s</parent>\n", def->parent); } if (def->driver) { virBufferAddLit(&buf, " <driver>\n"); virBufferEscapeString(&buf, " <name>%s</name>\n", def->driver); virBufferAddLit(&buf, " </driver>\n"); } for (caps = def->caps; caps; caps = caps->next) { char uuidstr[VIR_UUID_STRING_BUFLEN]; union _virNodeDevCapData *data = &caps->data; virBufferVSprintf(&buf, " <capability type='%s'>\n", virNodeDevCapTypeToString(caps->type)); switch (caps->type) { case VIR_NODE_DEV_CAP_SYSTEM: if (data->system.product_name) virBufferEscapeString(&buf, " <product>%s</product>\n", data->system.product_name); virBufferAddLit(&buf, " <hardware>\n"); if (data->system.hardware.vendor_name) virBufferEscapeString(&buf, " <vendor>%s</vendor>\n", data->system.hardware.vendor_name); if (data->system.hardware.version) virBufferEscapeString(&buf, " <version>%s</version>\n", data->system.hardware.version); if (data->system.hardware.serial) virBufferEscapeString(&buf, " <serial>%s</serial>\n", data->system.hardware.serial); virUUIDFormat(data->system.hardware.uuid, uuidstr); virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr); virBufferAddLit(&buf, " </hardware>\n"); virBufferAddLit(&buf, " <firmware>\n"); if (data->system.firmware.vendor_name) virBufferEscapeString(&buf, " <vendor>%s</vendor>\n", data->system.firmware.vendor_name); if (data->system.firmware.version) virBufferEscapeString(&buf, " <version>%s</version>\n", data->system.firmware.version); if (data->system.firmware.release_date) virBufferEscapeString(&buf, " <release_date>%s</release_date>\n", data->system.firmware.release_date); virBufferAddLit(&buf, " </firmware>\n"); break; case VIR_NODE_DEV_CAP_PCI_DEV: virBufferVSprintf(&buf, " <domain>%d</domain>\n", data->pci_dev.domain); virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->pci_dev.bus); virBufferVSprintf(&buf, " <slot>%d</slot>\n", data->pci_dev.slot); virBufferVSprintf(&buf, " <function>%d</function>\n", data->pci_dev.function); virBufferVSprintf(&buf, " <product id='0x%04x'", data->pci_dev.product); if (data->pci_dev.product_name) virBufferEscapeString(&buf, ">%s</product>\n", data->pci_dev.product_name); else virBufferAddLit(&buf, " />\n"); virBufferVSprintf(&buf, " <vendor id='0x%04x'", data->pci_dev.vendor); if (data->pci_dev.vendor_name) virBufferEscapeString(&buf, ">%s</vendor>\n", data->pci_dev.vendor_name); else virBufferAddLit(&buf, " />\n"); if (data->pci_dev.flags & VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION) { virBufferAddLit(&buf, " <capability type='phys_function'>\n"); virBufferVSprintf(&buf, " <address domain='0x%.4x' bus='0x%.2x' " "slot='0x%.2x' function='0x%.1x'/>\n", data->pci_dev.physical_function->domain, data->pci_dev.physical_function->bus, data->pci_dev.physical_function->slot, data->pci_dev.physical_function->function); virBufferAddLit(&buf, " </capability>\n"); } if (data->pci_dev.flags & VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION) { virBufferAddLit(&buf, " <capability type='virt_functions'>\n"); for (i = 0 ; i < data->pci_dev.num_virtual_functions ; i++) { virBufferVSprintf(&buf, " <address domain='0x%.4x' bus='0x%.2x' " "slot='0x%.2x' function='0x%.1x'/>\n", data->pci_dev.virtual_functions[i]->domain, data->pci_dev.virtual_functions[i]->bus, data->pci_dev.virtual_functions[i]->slot, data->pci_dev.virtual_functions[i]->function); } virBufferAddLit(&buf, " </capability>\n"); } break; case VIR_NODE_DEV_CAP_USB_DEV: virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->usb_dev.bus); virBufferVSprintf(&buf, " <device>%d</device>\n", data->usb_dev.device); virBufferVSprintf(&buf, " <product id='0x%04x'", data->usb_dev.product); if (data->usb_dev.product_name) virBufferEscapeString(&buf, ">%s</product>\n", data->usb_dev.product_name); else virBufferAddLit(&buf, " />\n"); virBufferVSprintf(&buf, " <vendor id='0x%04x'", data->usb_dev.vendor); if (data->usb_dev.vendor_name) virBufferEscapeString(&buf, ">%s</vendor>\n", data->usb_dev.vendor_name); else virBufferAddLit(&buf, " />\n"); break; case VIR_NODE_DEV_CAP_USB_INTERFACE: virBufferVSprintf(&buf, " <number>%d</number>\n", data->usb_if.number); virBufferVSprintf(&buf, " <class>%d</class>\n", data->usb_if._class); virBufferVSprintf(&buf, " <subclass>%d</subclass>\n", data->usb_if.subclass); virBufferVSprintf(&buf, " <protocol>%d</protocol>\n", data->usb_if.protocol); if (data->usb_if.description) virBufferEscapeString(&buf, " <description>%s</description>\n", data->usb_if.description); break; case VIR_NODE_DEV_CAP_NET: virBufferEscapeString(&buf, " <interface>%s</interface>\n", data->net.ifname); if (data->net.address) virBufferEscapeString(&buf, " <address>%s</address>\n", data->net.address); if (data->net.subtype != VIR_NODE_DEV_CAP_NET_LAST) { const char *subtyp = virNodeDevNetCapTypeToString(data->net.subtype); virBufferEscapeString(&buf, " <capability type='%s'/>\n", subtyp); } break; case VIR_NODE_DEV_CAP_SCSI_HOST: virBufferVSprintf(&buf, " <host>%d</host>\n", data->scsi_host.host); if (data->scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { virBufferAddLit(&buf, " <capability type='fc_host'>\n"); virBufferEscapeString(&buf, " <wwnn>%s</wwnn>\n", data->scsi_host.wwnn); virBufferEscapeString(&buf, " <wwpn>%s</wwpn>\n", data->scsi_host.wwpn); virBufferAddLit(&buf, " </capability>\n"); } if (data->scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) { virBufferAddLit(&buf, " <capability type='vport_ops' />\n"); } break; case VIR_NODE_DEV_CAP_SCSI_TARGET: virBufferEscapeString(&buf, " <target>%s</target>\n", data->scsi_target.name); break; case VIR_NODE_DEV_CAP_SCSI: virBufferVSprintf(&buf, " <host>%d</host>\n", data->scsi.host); virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->scsi.bus); virBufferVSprintf(&buf, " <target>%d</target>\n", data->scsi.target); virBufferVSprintf(&buf, " <lun>%d</lun>\n", data->scsi.lun); if (data->scsi.type) virBufferEscapeString(&buf, " <type>%s</type>\n", data->scsi.type); break; case VIR_NODE_DEV_CAP_STORAGE: virBufferEscapeString(&buf, " <block>%s</block>\n", data->storage.block); if (data->storage.bus) virBufferEscapeString(&buf, " <bus>%s</bus>\n", data->storage.bus); if (data->storage.drive_type) virBufferEscapeString(&buf, " <drive_type>%s</drive_type>\n", data->storage.drive_type); if (data->storage.model) virBufferEscapeString(&buf, " <model>%s</model>\n", data->storage.model); if (data->storage.vendor) virBufferEscapeString(&buf, " <vendor>%s</vendor>\n", data->storage.vendor); if (data->storage.serial) virBufferVSprintf(&buf, " <serial>%s</serial>\n", data->storage.serial); if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_REMOVABLE) { int avl = data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE; virBufferAddLit(&buf, " <capability type='removable'>\n"); virBufferVSprintf(&buf, " <media_available>%d" "</media_available>\n", avl ? 1 : 0); virBufferVSprintf(&buf, " <media_size>%llu</media_size>\n", data->storage.removable_media_size); if (data->storage.media_label) virBufferEscapeString(&buf, " <media_label>%s</media_label>\n", data->storage.media_label); if (data->storage.logical_block_size > 0) virBufferVSprintf(&buf, " <logical_block_size>%llu" "</logical_block_size>\n", data->storage.logical_block_size); if (data->storage.num_blocks > 0) virBufferVSprintf(&buf, " <num_blocks>%llu</num_blocks>\n", data->storage.num_blocks); virBufferAddLit(&buf, " </capability>\n"); } else { virBufferVSprintf(&buf, " <size>%llu</size>\n", data->storage.size); if (data->storage.logical_block_size > 0) virBufferVSprintf(&buf, " <logical_block_size>%llu" "</logical_block_size>\n", data->storage.logical_block_size); if (data->storage.num_blocks > 0) virBufferVSprintf(&buf, " <num_blocks>%llu</num_blocks>\n", data->storage.num_blocks); } if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE) virBufferAddLit(&buf, " <capability type='hotpluggable' />\n"); break; case VIR_NODE_DEV_CAP_LAST: /* ignore special LAST value */ break; } virBufferAddLit(&buf, " </capability>\n"); } virBufferAddLit(&buf, "</device>\n"); if (virBufferError(&buf)) goto no_memory; return virBufferContentAndReset(&buf); no_memory: virReportOOMError(); virBufferFreeAndReset(&buf); return NULL; }
static bool cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd) { virStoragePoolPtr pool; virStorageVolPtr vol; char *xml; const char *name, *capacityStr = NULL, *allocationStr = NULL, *format = NULL; const char *snapshotStrVol = NULL, *snapshotStrFormat = NULL; unsigned long long capacity, allocation = 0; virBuffer buf = VIR_BUFFER_INITIALIZER; if (!vshConnectionUsability(ctl, ctl->conn)) return false; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, VSH_BYNAME))) return false; if (vshCommandOptString(cmd, "name", &name) <= 0) goto cleanup; if (vshCommandOptString(cmd, "capacity", &capacityStr) <= 0) goto cleanup; if (vshVolSize(capacityStr, &capacity) < 0) { vshError(ctl, _("Malformed size %s"), capacityStr); goto cleanup; } if (vshCommandOptString(cmd, "allocation", &allocationStr) > 0 && vshVolSize(allocationStr, &allocation) < 0) { vshError(ctl, _("Malformed size %s"), allocationStr); goto cleanup; } if (vshCommandOptString(cmd, "format", &format) < 0 || vshCommandOptString(cmd, "backing-vol", &snapshotStrVol) < 0 || vshCommandOptString(cmd, "backing-vol-format", &snapshotStrFormat) < 0) { vshError(ctl, "%s", _("missing argument")); goto cleanup; } virBufferAddLit(&buf, "<volume>\n"); virBufferAsprintf(&buf, " <name>%s</name>\n", name); virBufferAsprintf(&buf, " <capacity>%llu</capacity>\n", capacity); if (allocationStr) virBufferAsprintf(&buf, " <allocation>%llu</allocation>\n", allocation); if (format) { virBufferAddLit(&buf, " <target>\n"); virBufferAsprintf(&buf, " <format type='%s'/>\n",format); virBufferAddLit(&buf, " </target>\n"); } /* Convert the snapshot parameters into backingStore XML */ if (snapshotStrVol) { /* Lookup snapshot backing volume. Try the backing-vol * parameter as a name */ vshDebug(ctl, VSH_ERR_DEBUG, "%s: Look up backing store volume '%s' as name\n", cmd->def->name, snapshotStrVol); virStorageVolPtr snapVol = virStorageVolLookupByName(pool, snapshotStrVol); if (snapVol) vshDebug(ctl, VSH_ERR_DEBUG, "%s: Backing store volume found using '%s' as name\n", cmd->def->name, snapshotStrVol); if (snapVol == NULL) { /* Snapshot backing volume not found by name. Try the * backing-vol parameter as a key */ vshDebug(ctl, VSH_ERR_DEBUG, "%s: Look up backing store volume '%s' as key\n", cmd->def->name, snapshotStrVol); snapVol = virStorageVolLookupByKey(ctl->conn, snapshotStrVol); if (snapVol) vshDebug(ctl, VSH_ERR_DEBUG, "%s: Backing store volume found using '%s' as key\n", cmd->def->name, snapshotStrVol); } if (snapVol == NULL) { /* Snapshot backing volume not found by key. Try the * backing-vol parameter as a path */ vshDebug(ctl, VSH_ERR_DEBUG, "%s: Look up backing store volume '%s' as path\n", cmd->def->name, snapshotStrVol); snapVol = virStorageVolLookupByPath(ctl->conn, snapshotStrVol); if (snapVol) vshDebug(ctl, VSH_ERR_DEBUG, "%s: Backing store volume found using '%s' as path\n", cmd->def->name, snapshotStrVol); } if (snapVol == NULL) { vshError(ctl, _("failed to get vol '%s'"), snapshotStrVol); goto cleanup; } char *snapshotStrVolPath; if ((snapshotStrVolPath = virStorageVolGetPath(snapVol)) == NULL) { virStorageVolFree(snapVol); goto cleanup; } /* Create XML for the backing store */ virBufferAddLit(&buf, " <backingStore>\n"); virBufferAsprintf(&buf, " <path>%s</path>\n",snapshotStrVolPath); if (snapshotStrFormat) virBufferAsprintf(&buf, " <format type='%s'/>\n",snapshotStrFormat); virBufferAddLit(&buf, " </backingStore>\n"); /* Cleanup snapshot allocations */ VIR_FREE(snapshotStrVolPath); virStorageVolFree(snapVol); } virBufferAddLit(&buf, "</volume>\n"); if (virBufferError(&buf)) { vshPrint(ctl, "%s", _("Failed to allocate XML buffer")); goto cleanup; } xml = virBufferContentAndReset(&buf); vol = virStorageVolCreateXML(pool, xml, 0); VIR_FREE(xml); virStoragePoolFree(pool); if (vol != NULL) { vshPrint(ctl, _("Vol %s created\n"), name); virStorageVolFree(vol); return true; } else { vshError(ctl, _("Failed to create vol %s"), name); return false; } cleanup: virBufferFreeAndReset(&buf); virStoragePoolFree(pool); return false; }
char *virDomainSnapshotDefFormat(const char *domain_uuid, virDomainSnapshotDefPtr def, unsigned int flags, int internal) { virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; virCheckFlags(VIR_DOMAIN_DEF_FORMAT_SECURE | VIR_DOMAIN_DEF_FORMAT_UPDATE_CPU, NULL); flags |= VIR_DOMAIN_DEF_FORMAT_INACTIVE; virBufferAddLit(&buf, "<domainsnapshot>\n"); virBufferAdjustIndent(&buf, 2); virBufferEscapeString(&buf, "<name>%s</name>\n", def->name); if (def->description) virBufferEscapeString(&buf, "<description>%s</description>\n", def->description); virBufferAsprintf(&buf, "<state>%s</state>\n", virDomainSnapshotStateTypeToString(def->state)); if (def->parent) { virBufferAddLit(&buf, "<parent>\n"); virBufferAdjustIndent(&buf, 2); virBufferEscapeString(&buf, "<name>%s</name>\n", def->parent); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</parent>\n"); } virBufferAsprintf(&buf, "<creationTime>%lld</creationTime>\n", def->creationTime); if (def->memory) { virBufferAsprintf(&buf, "<memory snapshot='%s'", virDomainSnapshotLocationTypeToString(def->memory)); virBufferEscapeString(&buf, " file='%s'", def->file); virBufferAddLit(&buf, "/>\n"); } if (def->ndisks) { virBufferAddLit(&buf, "<disks>\n"); virBufferAdjustIndent(&buf, 2); for (i = 0; i < def->ndisks; i++) virDomainSnapshotDiskDefFormat(&buf, &def->disks[i]); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</disks>\n"); } if (def->dom) { if (virDomainDefFormatInternal(def->dom, flags, &buf) < 0) { virBufferFreeAndReset(&buf); return NULL; } } else if (domain_uuid) { virBufferAddLit(&buf, "<domain>\n"); virBufferAdjustIndent(&buf, 2); virBufferAsprintf(&buf, "<uuid>%s</uuid>\n", domain_uuid); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</domain>\n"); } if (internal) virBufferAsprintf(&buf, "<active>%d</active>\n", def->current); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</domainsnapshot>\n"); if (virBufferCheckError(&buf) < 0) return NULL; return virBufferContentAndReset(&buf); }
static int testCompareStatusXMLToXMLFiles(const void *opaque) { const struct testInfo *data = opaque; virBuffer buf = VIR_BUFFER_INITIALIZER; xmlDocPtr xml = NULL; virDomainObjPtr obj = NULL; char *expect = NULL; char *actual = NULL; char *source = NULL; int ret = -1; int keepBlanksDefault = xmlKeepBlanksDefault(0); /* construct faked source status XML */ virBufferAdd(&buf, testStatusXMLPrefix, -1); virBufferAdjustIndent(&buf, 2); virBufferAddStr(&buf, data->inFile); virBufferAdjustIndent(&buf, -2); virBufferAdd(&buf, testStatusXMLSuffix, -1); if (!(source = virBufferContentAndReset(&buf))) { fprintf(stderr, "Failed to create the source XML"); goto cleanup; } /* construct the expect string */ virBufferAdd(&buf, testStatusXMLPrefix, -1); virBufferAdjustIndent(&buf, 2); virBufferAddStr(&buf, data->outActiveFile); virBufferAdjustIndent(&buf, -2); virBufferAdd(&buf, testStatusXMLSuffix, -1); if (!(expect = virBufferContentAndReset(&buf))) { fprintf(stderr, "Failed to create the expect XML"); goto cleanup; } /* parse the fake source status XML */ if (!(xml = virXMLParseString(source, "(domain_status_test_XML)")) || !(obj = virDomainObjParseNode(xml, xmlDocGetRootElement(xml), driver.caps, driver.xmlopt, VIR_DOMAIN_DEF_PARSE_STATUS | VIR_DOMAIN_DEF_PARSE_ACTUAL_NET | VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES | VIR_DOMAIN_DEF_PARSE_CLOCK_ADJUST))) { fprintf(stderr, "Failed to parse domain status XML:\n%s", source); goto cleanup; } /* format it back */ if (!(actual = virDomainObjFormat(driver.xmlopt, obj, VIR_DOMAIN_DEF_FORMAT_SECURE))) { fprintf(stderr, "Failed to format domain status XML"); goto cleanup; } if (STRNEQ(actual, expect)) { virtTestDifferenceFull(stderr, expect, data->outActiveName, actual, data->inName); goto cleanup; } ret = 0; cleanup: xmlKeepBlanksDefault(keepBlanksDefault); xmlFreeDoc(xml); virObjectUnref(obj); VIR_FREE(expect); VIR_FREE(actual); VIR_FREE(source); 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 xml = VIR_BUFFER_INITIALIZER; size_t i, j, k; char host_uuid[VIR_UUID_STRING_BUFLEN]; virBufferAddLit(&xml, "<capabilities>\n\n"); virBufferAddLit(&xml, " <host>\n"); if (virUUIDIsValid(caps->host.host_uuid)) { virUUIDFormat(caps->host.host_uuid, host_uuid); virBufferAsprintf(&xml, " <uuid>%s</uuid>\n", host_uuid); } virBufferAddLit(&xml, " <cpu>\n"); if (caps->host.arch) virBufferAsprintf(&xml, " <arch>%s</arch>\n", virArchToString(caps->host.arch)); if (caps->host.nfeatures) { virBufferAddLit(&xml, " <features>\n"); for (i = 0; i < caps->host.nfeatures; i++) { virBufferAsprintf(&xml, " <%s/>\n", caps->host.features[i]); } virBufferAddLit(&xml, " </features>\n"); } virBufferAdjustIndent(&xml, 6); virCPUDefFormatBuf(&xml, caps->host.cpu, 0); virBufferAdjustIndent(&xml, -6); virBufferAddLit(&xml, " </cpu>\n"); /* The PM query was successful. */ if (caps->host.powerMgmt) { /* The host supports some PM features. */ unsigned int pm = caps->host.powerMgmt; virBufferAddLit(&xml, " <power_management>\n"); while (pm) { int bit = ffs(pm) - 1; virBufferAsprintf(&xml, " <%s/>\n", virCapsHostPMTargetTypeToString(bit)); pm &= ~(1U << bit); } virBufferAddLit(&xml, " </power_management>\n"); } else { /* The host does not support any PM feature. */ virBufferAddLit(&xml, " <power_management/>\n"); } if (caps->host.offlineMigrate) { virBufferAddLit(&xml, " <migration_features>\n"); if (caps->host.liveMigrate) virBufferAddLit(&xml, " <live/>\n"); if (caps->host.nmigrateTrans) { virBufferAddLit(&xml, " <uri_transports>\n"); for (i = 0; i < caps->host.nmigrateTrans; i++) { virBufferAsprintf(&xml, " <uri_transport>%s</uri_transport>\n", caps->host.migrateTrans[i]); } virBufferAddLit(&xml, " </uri_transports>\n"); } virBufferAddLit(&xml, " </migration_features>\n"); } if (caps->host.nnumaCell && virCapabilitiesFormatNUMATopology(&xml, caps->host.nnumaCell, caps->host.numaCell) < 0) return NULL; for (i = 0; i < caps->host.nsecModels; i++) { virBufferAddLit(&xml, " <secmodel>\n"); virBufferAsprintf(&xml, " <model>%s</model>\n", caps->host.secModels[i].model); virBufferAsprintf(&xml, " <doi>%s</doi>\n", caps->host.secModels[i].doi); for (j = 0; j < caps->host.secModels[i].nlabels; j++) { virBufferAsprintf(&xml, " <baselabel type='%s'>%s</baselabel>\n", caps->host.secModels[i].labels[j].type, caps->host.secModels[i].labels[j].label); } virBufferAddLit(&xml, " </secmodel>\n"); } virBufferAddLit(&xml, " </host>\n\n"); for (i = 0; i < caps->nguests; i++) { virBufferAddLit(&xml, " <guest>\n"); virBufferAsprintf(&xml, " <os_type>%s</os_type>\n", caps->guests[i]->ostype); if (caps->guests[i]->arch.id) virBufferAsprintf(&xml, " <arch name='%s'>\n", virArchToString(caps->guests[i]->arch.id)); virBufferAsprintf(&xml, " <wordsize>%d</wordsize>\n", caps->guests[i]->arch.wordsize); if (caps->guests[i]->arch.defaultInfo.emulator) virBufferAsprintf(&xml, " <emulator>%s</emulator>\n", caps->guests[i]->arch.defaultInfo.emulator); if (caps->guests[i]->arch.defaultInfo.loader) virBufferAsprintf(&xml, " <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(&xml, " <machine"); if (machine->canonical) virBufferAsprintf(&xml, " canonical='%s'", machine->canonical); if (machine->maxCpus > 0) virBufferAsprintf(&xml, " maxCpus='%d'", machine->maxCpus); virBufferAsprintf(&xml, ">%s</machine>\n", machine->name); } for (j = 0; j < caps->guests[i]->arch.ndomains; j++) { virBufferAsprintf(&xml, " <domain type='%s'>\n", caps->guests[i]->arch.domains[j]->type); if (caps->guests[i]->arch.domains[j]->info.emulator) virBufferAsprintf(&xml, " <emulator>%s</emulator>\n", caps->guests[i]->arch.domains[j]->info.emulator); if (caps->guests[i]->arch.domains[j]->info.loader) virBufferAsprintf(&xml, " <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(&xml, " <machine"); if (machine->canonical) virBufferAsprintf(&xml, " canonical='%s'", machine->canonical); if (machine->maxCpus > 0) virBufferAsprintf(&xml, " maxCpus='%d'", machine->maxCpus); virBufferAsprintf(&xml, ">%s</machine>\n", machine->name); } virBufferAddLit(&xml, " </domain>\n"); } virBufferAddLit(&xml, " </arch>\n"); if (caps->guests[i]->nfeatures) { virBufferAddLit(&xml, " <features>\n"); 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(&xml, " <%s/>\n", caps->guests[i]->features[j]->name); } else { virBufferAsprintf(&xml, " <%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"); } } virBufferAddLit(&xml, " </features>\n"); } virBufferAddLit(&xml, " </guest>\n\n"); } virBufferAddLit(&xml, "</capabilities>\n"); if (virBufferError(&xml)) { virBufferFreeAndReset(&xml); return NULL; } return virBufferContentAndReset(&xml); }
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 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; }
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 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 int cpuTestGuestData(const void *arg) { const struct data *data = arg; int ret = -2; virCPUDefPtr host = NULL; virCPUDefPtr cpu = NULL; virCPUDefPtr guest = NULL; virCPUDataPtr guestData = NULL; virCPUCompareResult cmpResult; virBuffer buf = VIR_BUFFER_INITIALIZER; char *result = NULL; if (!(host = cpuTestLoadXML(data->arch, data->host)) || !(cpu = cpuTestLoadXML(data->arch, data->name))) goto cleanup; cmpResult = cpuGuestData(host, cpu, &guestData, NULL); if (cmpResult == VIR_CPU_COMPARE_ERROR || cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE) { ret = -1; goto cleanup; } if (VIR_ALLOC(guest) < 0) goto cleanup; guest->arch = host->arch; guest->type = VIR_CPU_TYPE_GUEST; guest->match = VIR_CPU_MATCH_EXACT; guest->fallback = cpu->fallback; if (cpuDecode(guest, guestData, data->models, data->nmodels, data->preferred) < 0) { ret = -1; goto cleanup; } virBufferAsprintf(&buf, "%s+%s", data->host, data->name); if (data->nmodels) virBufferAsprintf(&buf, ",%s", data->modelsName); if (data->preferred) virBufferAsprintf(&buf, ",%s", data->preferred); virBufferAddLit(&buf, "-result"); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto cleanup; } result = virBufferContentAndReset(&buf); if (cpuTestCompareXML(data->arch, guest, result, false) < 0) goto cleanup; ret = 0; cleanup: VIR_FREE(result); cpuDataFree(guestData); virCPUDefFree(host); virCPUDefFree(cpu); virCPUDefFree(guest); if (ret == data->result) { /* We got the result we expected, whether it was * a success or a failure */ virResetLastError(); ret = 0; } else { VIR_TEST_VERBOSE("\nExpected result %d, got %d\n", data->result, ret); /* Pad to line up with test name ... in virTestRun */ VIR_TEST_VERBOSE("%74s", "... "); ret = -1; } return ret; }
static int linuxCPUStatsCompareFiles(const char *cpustatfile, size_t ncpus, const char *outfile) { int ret = -1; char *actualData = NULL; char *expectData = NULL; FILE *cpustat = NULL; virNodeCPUStatsPtr params = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; int nparams = 0; if (virtTestLoadFile(outfile, &expectData) < 0) goto fail; if (!(cpustat = fopen(cpustatfile, "r"))) { virReportSystemError(errno, "failed to open '%s': ", cpustatfile); goto fail; } if (linuxNodeGetCPUStats(NULL, 0, NULL, &nparams) < 0) goto fail; if (VIR_ALLOC_N(params, nparams) < 0) goto fail; if (linuxNodeGetCPUStats(cpustat, VIR_NODE_CPU_STATS_ALL_CPUS, params, &nparams) < 0) goto fail; if (linuxCPUStatsToBuf(&buf, VIR_NODE_CPU_STATS_ALL_CPUS, params, nparams) < 0) goto fail; for (i = 0; i < ncpus; i++) { if (linuxNodeGetCPUStats(cpustat, i, params, &nparams) < 0) goto fail; if (linuxCPUStatsToBuf(&buf, i, params, nparams) < 0) goto fail; } if (!(actualData = virBufferContentAndReset(&buf))) { virReportOOMError(); goto fail; } if (STRNEQ(actualData, expectData)) { virtTestDifference(stderr, expectData, actualData); goto fail; } ret = 0; fail: virBufferFreeAndReset(&buf); VIR_FORCE_FCLOSE(cpustat); VIR_FREE(expectData); VIR_FREE(actualData); VIR_FREE(params); return ret; }
static int testBackingXMLjsonXML(const void *args) { const struct testBackingXMLjsonXMLdata *data = args; VIR_AUTOPTR(xmlDoc) xml = NULL; VIR_AUTOPTR(xmlXPathContext) ctxt = NULL; VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER; VIR_AUTOPTR(virJSONValue) backendprops = NULL; VIR_AUTOPTR(virJSONValue) wrapper = NULL; VIR_AUTOFREE(char *) propsstr = NULL; VIR_AUTOFREE(char *) protocolwrapper = NULL; VIR_AUTOFREE(char *) actualxml = NULL; VIR_AUTOUNREF(virStorageSourcePtr) xmlsrc = NULL; VIR_AUTOUNREF(virStorageSourcePtr) jsonsrc = NULL; if (!(xmlsrc = virStorageSourceNew())) return -1; xmlsrc->type = data->type; if (!(xml = virXMLParseStringCtxt(data->xml, "(test storage source XML)", &ctxt))) return -1; if (virDomainStorageSourceParse(ctxt->node, ctxt, xmlsrc, 0, NULL) < 0) { fprintf(stderr, "failed to parse disk source xml\n"); return -1; } if (!(backendprops = qemuBlockStorageSourceGetBackendProps(xmlsrc, true))) { fprintf(stderr, "failed to format disk source json\n"); return -1; } if (virJSONValueObjectCreate(&wrapper, "a:file", &backendprops, NULL) < 0) return -1; if (!(propsstr = virJSONValueToString(wrapper, false))) return -1; if (virAsprintf(&protocolwrapper, "json:%s", propsstr) < 0) return -1; if (!(jsonsrc = virStorageSourceNewFromBackingAbsolute(protocolwrapper))) { fprintf(stderr, "failed to parse disk json\n"); return -1; } if (virDomainDiskSourceFormat(&buf, jsonsrc, 0, false, 0, NULL) < 0 || !(actualxml = virBufferContentAndReset(&buf))) { fprintf(stderr, "failed to format disk source xml\n"); return -1; } if (STRNEQ(actualxml, data->xml)) { fprintf(stderr, "\n expected storage source xml:\n'%s'\n" "actual storage source xml:\n%s\n" "intermediate json:\n%s\n", data->xml, actualxml, protocolwrapper); return -1; } return 0; }
/* 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; }
static char * umlBuildCommandLineNet(virConnectPtr conn, virDomainNetDefPtr def, int idx) { virBuffer buf = VIR_BUFFER_INITIALIZER; /* 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->data.ethernet.ipaddr) { umlReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("IP address not supported for ethernet inteface")); goto error; } if (def->data.ethernet.script) { umlReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("script execution not supported for ethernet inteface")); goto error; } break; case VIR_DOMAIN_NET_TYPE_SERVER: umlReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("TCP server networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_CLIENT: umlReportError(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) { umlReportError(VIR_ERR_INTERNAL_ERROR, _("Network '%s' not found"), def->data.network.name); goto error; } bridge = virNetworkGetBridgeName(network); virNetworkFree(network); if (bridge == NULL) { goto error; } if (umlConnectTapDevice(conn, 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(conn, 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: umlReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("internal networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_DIRECT: umlReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("direct networking type not supported")); goto error; case VIR_DOMAIN_NET_TYPE_LAST: break; } virBufferAsprintf(&buf, ",%02x:%02x:%02x:%02x:%02x:%02x", def->mac[0], def->mac[1], def->mac[2], def->mac[3], def->mac[4], def->mac[5]); if (def->type == VIR_DOMAIN_NET_TYPE_MCAST) { virBufferAsprintf(&buf, ",%s,%d", def->data.socket.address, def->data.socket.port); } if (virBufferError(&buf)) { virReportOOMError(); return NULL; } return virBufferContentAndReset(&buf); error: virBufferFreeAndReset(&buf); return NULL; }
/** * 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 xml = VIR_BUFFER_INITIALIZER; int i, j, k; char host_uuid[VIR_UUID_STRING_BUFLEN]; virBufferAddLit(&xml, "<capabilities>\n\n"); virBufferAddLit(&xml, " <host>\n"); if (virUUIDIsValid(caps->host.host_uuid)) { virUUIDFormat(caps->host.host_uuid, host_uuid); virBufferAsprintf(&xml," <uuid>%s</uuid>\n", host_uuid); } virBufferAddLit(&xml, " <cpu>\n"); virBufferAsprintf(&xml, " <arch>%s</arch>\n", caps->host.arch); if (caps->host.nfeatures) { virBufferAddLit(&xml, " <features>\n"); for (i = 0 ; i < caps->host.nfeatures ; i++) { virBufferAsprintf(&xml, " <%s/>\n", caps->host.features[i]); } virBufferAddLit(&xml, " </features>\n"); } virBufferAdjustIndent(&xml, 6); virCPUDefFormatBuf(&xml, caps->host.cpu); virBufferAdjustIndent(&xml, -6); virBufferAddLit(&xml, " </cpu>\n"); if (caps->host.offlineMigrate) { virBufferAddLit(&xml, " <migration_features>\n"); if (caps->host.liveMigrate) virBufferAddLit(&xml, " <live/>\n"); if (caps->host.nmigrateTrans) { virBufferAddLit(&xml, " <uri_transports>\n"); for (i = 0 ; i < caps->host.nmigrateTrans ; i++) { virBufferAsprintf(&xml, " <uri_transport>%s</uri_transport>\n", caps->host.migrateTrans[i]); } virBufferAddLit(&xml, " </uri_transports>\n"); } virBufferAddLit(&xml, " </migration_features>\n"); } if (caps->host.nnumaCell) { virBufferAddLit(&xml, " <topology>\n"); virBufferAsprintf(&xml, " <cells num='%zu'>\n", caps->host.nnumaCell); for (i = 0 ; i < caps->host.nnumaCell ; i++) { virBufferAsprintf(&xml, " <cell id='%d'>\n", caps->host.numaCell[i]->num); virBufferAsprintf(&xml, " <cpus num='%d'>\n", caps->host.numaCell[i]->ncpus); for (j = 0 ; j < caps->host.numaCell[i]->ncpus ; j++) virBufferAsprintf(&xml, " <cpu id='%d'/>\n", caps->host.numaCell[i]->cpus[j]); virBufferAddLit(&xml, " </cpus>\n"); virBufferAddLit(&xml, " </cell>\n"); } virBufferAddLit(&xml, " </cells>\n"); virBufferAddLit(&xml, " </topology>\n"); } if (caps->host.secModel.model) { virBufferAddLit(&xml, " <secmodel>\n"); virBufferAsprintf(&xml, " <model>%s</model>\n", caps->host.secModel.model); virBufferAsprintf(&xml, " <doi>%s</doi>\n", caps->host.secModel.doi); virBufferAddLit(&xml, " </secmodel>\n"); } virBufferAddLit(&xml, " </host>\n\n"); for (i = 0 ; i < caps->nguests ; i++) { virBufferAddLit(&xml, " <guest>\n"); virBufferAsprintf(&xml, " <os_type>%s</os_type>\n", caps->guests[i]->ostype); virBufferAsprintf(&xml, " <arch name='%s'>\n", caps->guests[i]->arch.name); virBufferAsprintf(&xml, " <wordsize>%d</wordsize>\n", caps->guests[i]->arch.wordsize); if (caps->guests[i]->arch.defaultInfo.emulator) virBufferAsprintf(&xml, " <emulator>%s</emulator>\n", caps->guests[i]->arch.defaultInfo.emulator); if (caps->guests[i]->arch.defaultInfo.loader) virBufferAsprintf(&xml, " <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(&xml, " <machine"); if (machine->canonical) virBufferAsprintf(&xml, " canonical='%s'", machine->canonical); virBufferAsprintf(&xml, ">%s</machine>\n", machine->name); } for (j = 0 ; j < caps->guests[i]->arch.ndomains ; j++) { virBufferAsprintf(&xml, " <domain type='%s'>\n", caps->guests[i]->arch.domains[j]->type); if (caps->guests[i]->arch.domains[j]->info.emulator) virBufferAsprintf(&xml, " <emulator>%s</emulator>\n", caps->guests[i]->arch.domains[j]->info.emulator); if (caps->guests[i]->arch.domains[j]->info.loader) virBufferAsprintf(&xml, " <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(&xml, " <machine"); if (machine->canonical) virBufferAsprintf(&xml, " canonical='%s'", machine->canonical); virBufferAsprintf(&xml, ">%s</machine>\n", machine->name); } virBufferAddLit(&xml, " </domain>\n"); } virBufferAddLit(&xml, " </arch>\n"); if (caps->guests[i]->nfeatures) { virBufferAddLit(&xml, " <features>\n"); 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(&xml, " <%s/>\n", caps->guests[i]->features[j]->name); } else { virBufferAsprintf(&xml, " <%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"); } } virBufferAddLit(&xml, " </features>\n"); } virBufferAddLit(&xml, " </guest>\n\n"); } virBufferAddLit(&xml, "</capabilities>\n"); if (virBufferError(&xml)) { virBufferFreeAndReset(&xml); return NULL; } return virBufferContentAndReset(&xml); }
static int cpuTestGuestData(const void *arg) { const struct data *data = arg; int ret = -1; virCPUDefPtr host = NULL; virCPUDefPtr cpu = NULL; virCPUDefPtr guest = NULL; union cpuData *guestData = NULL; virCPUCompareResult cmpResult; virBuffer buf = VIR_BUFFER_INITIALIZER; char *result = NULL; if (!(host = cpuTestLoadXML(data->arch, data->host)) || !(cpu = cpuTestLoadXML(data->arch, data->name))) goto cleanup; cmpResult = cpuGuestData(host, cpu, &guestData); if (cmpResult == VIR_CPU_COMPARE_ERROR || cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE) goto cleanup; if (VIR_ALLOC(guest) < 0 || !(guest->arch = strdup(host->arch))) goto cleanup; guest->type = VIR_CPU_TYPE_GUEST; guest->match = VIR_CPU_MATCH_EXACT; guest->fallback = cpu->fallback; if (cpuDecode(guest, guestData, data->models, data->nmodels, data->preferred) < 0) { if (data->result < 0) { virResetLastError(); ret = 0; } goto cleanup; } virBufferAsprintf(&buf, "%s+%s", data->host, data->name); if (data->nmodels) virBufferAsprintf(&buf, ",%s", data->modelsName); if (data->preferred) virBufferAsprintf(&buf, ",%s", data->preferred); virBufferAddLit(&buf, "-result"); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto cleanup; } result = virBufferContentAndReset(&buf); ret = cpuTestCompareXML(data->arch, guest, result, 0); cleanup: VIR_FREE(result); if (host) cpuDataFree(host->arch, guestData); virCPUDefFree(host); virCPUDefFree(cpu); virCPUDefFree(guest); return ret; }