int virCPUDefFormatBufFull(virBufferPtr buf, virCPUDefPtr def, unsigned int flags) { if (!def) return 0; virBufferAddLit(buf, "<cpu"); if (def->type == VIR_CPU_TYPE_GUEST) { const char *tmp; if (def->mode != VIR_CPU_MODE_CUSTOM || def->model) { if (!(tmp = virCPUModeTypeToString(def->mode))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected CPU mode %d"), def->mode); return -1; } virBufferAsprintf(buf, " mode='%s'", tmp); } if (def->model && (def->mode == VIR_CPU_MODE_CUSTOM || (flags & VIR_DOMAIN_XML_UPDATE_CPU))) { if (!(tmp = virCPUMatchTypeToString(def->match))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected CPU match policy %d"), def->match); return -1; } virBufferAsprintf(buf, " match='%s'", tmp); } } virBufferAddLit(buf, ">\n"); if (def->arch) virBufferAsprintf(buf, " <arch>%s</arch>\n", virArchToString(def->arch)); virBufferAdjustIndent(buf, 2); if (virCPUDefFormatBuf(buf, def, flags) < 0) return -1; virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</cpu>\n"); return 0; }
char * virCPUDefFormat(virCPUDefPtr def, const char *indent, int flags) { virBuffer buf = VIR_BUFFER_INITIALIZER; if (virCPUDefFormatBuf(&buf, def, indent, flags) < 0) goto cleanup; if (virBufferError(&buf)) goto no_memory; return virBufferContentAndReset(&buf); no_memory: virReportOOMError(); cleanup: virBufferFreeAndReset(&buf); return NULL; }
static void virDomainCapsCPUFormat(virBufferPtr buf, virDomainCapsCPUPtr cpu) { virBufferAddLit(buf, "<cpu>\n"); virBufferAdjustIndent(buf, 2); virBufferAsprintf(buf, "<mode name='%s' supported='%s'/>\n", virCPUModeTypeToString(VIR_CPU_MODE_HOST_PASSTHROUGH), cpu->hostPassthrough ? "yes" : "no"); virBufferAsprintf(buf, "<mode name='%s' ", virCPUModeTypeToString(VIR_CPU_MODE_HOST_MODEL)); if (cpu->hostModel) { virBufferAddLit(buf, "supported='yes'>\n"); virBufferAdjustIndent(buf, 2); virCPUDefFormatBuf(buf, cpu->hostModel, false); virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</mode>\n"); } else { virBufferAddLit(buf, "supported='no'/>\n"); } virBufferAsprintf(buf, "<mode name='%s' ", virCPUModeTypeToString(VIR_CPU_MODE_CUSTOM)); if (cpu->custom && cpu->custom->nmodels) { virBufferAddLit(buf, "supported='yes'>\n"); virDomainCapsCPUCustomFormat(buf, cpu->custom); virBufferAddLit(buf, "</mode>\n"); } else { virBufferAddLit(buf, "supported='no'/>\n"); } virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</cpu>\n"); }
/** * 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); }
/** * 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); }
int virCPUDefFormatBufFull(virBufferPtr buf, virCPUDefPtr def, virDomainNumaPtr numa) { int ret = -1; virBuffer attributeBuf = VIR_BUFFER_INITIALIZER; virBuffer childrenBuf = VIR_BUFFER_INITIALIZER; if (!def) return 0; /* Format attributes for guest CPUs unless they only specify * topology or cache. */ if (def->type == VIR_CPU_TYPE_GUEST && (def->mode != VIR_CPU_MODE_CUSTOM || def->model)) { const char *tmp; if (!(tmp = virCPUModeTypeToString(def->mode))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected CPU mode %d"), def->mode); goto cleanup; } virBufferAsprintf(&attributeBuf, " mode='%s'", tmp); if (def->mode == VIR_CPU_MODE_CUSTOM) { if (!(tmp = virCPUMatchTypeToString(def->match))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected CPU match policy %d"), def->match); goto cleanup; } virBufferAsprintf(&attributeBuf, " match='%s'", tmp); } if (def->check) { virBufferAsprintf(&attributeBuf, " check='%s'", virCPUCheckTypeToString(def->check)); } } /* Format children */ virBufferSetChildIndent(&childrenBuf, buf); if (def->type == VIR_CPU_TYPE_HOST && def->arch) virBufferAsprintf(&childrenBuf, "<arch>%s</arch>\n", virArchToString(def->arch)); if (virCPUDefFormatBuf(&childrenBuf, def) < 0) goto cleanup; if (virDomainNumaDefCPUFormatXML(&childrenBuf, numa) < 0) goto cleanup; if (virBufferCheckError(&attributeBuf) < 0 || virBufferCheckError(&childrenBuf) < 0) goto cleanup; /* Put it all together */ if (virBufferUse(&attributeBuf) || virBufferUse(&childrenBuf)) { virBufferAddLit(buf, "<cpu"); if (virBufferUse(&attributeBuf)) virBufferAddBuffer(buf, &attributeBuf); if (virBufferUse(&childrenBuf)) { virBufferAddLit(buf, ">\n"); virBufferAddBuffer(buf, &childrenBuf); virBufferAddLit(buf, "</cpu>\n"); } else { virBufferAddLit(buf, "/>\n"); } } ret = 0; cleanup: virBufferFreeAndReset(&attributeBuf); virBufferFreeAndReset(&childrenBuf); return ret; }