Example #1
0
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);
}
Example #2
0
static int
virDomainCapsFormatInternal(virBufferPtr buf,
                            virDomainCapsPtr const caps)
{
    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);
    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);

    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);

    virBufferAdjustIndent(buf, -2);
    virBufferAddLit(buf, "</features>\n");

    virBufferAdjustIndent(buf, -2);
    virBufferAddLit(buf, "</domainCapabilities>\n");
    return 0;
}
Example #3
0
/* Functions */
virCapsPtr virLXCDriverCapsInit(virLXCDriverPtr driver)
{
    virCapsPtr caps;
    virCapsGuestPtr guest;
    virArch altArch;
    char *lxc_path = NULL;

    if ((caps = virCapabilitiesNew(virArchFromHost(),
                                   false, false)) == NULL)
        goto error;

    /* Some machines have problematic NUMA toplogy causing
     * unexpected failures. We don't want to break the lxc
     * driver in this scenario, so log errors & carry on
     */
    if (nodeCapsInitNUMA(caps) < 0) {
        virCapabilitiesFreeNUMAInfo(caps);
        VIR_WARN("Failed to query host NUMA topology, disabling NUMA capabilities");
    }

    /* Only probe for power management capabilities in the driver,
     * not in the emulator */
    if (driver && virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0)
        VIR_WARN("Failed to get host power management capabilities");

    if (virGetHostUUID(caps->host.host_uuid)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("cannot get the host uuid"));
        goto error;
    }

    if (!(lxc_path = virFileFindResource("libvirt_lxc",
                                         abs_topbuilddir "/src",
                                         LIBEXECDIR)))
        goto error;

    if ((guest = virCapabilitiesAddGuest(caps,
                                         VIR_DOMAIN_OSTYPE_EXE,
                                         caps->host.arch,
                                         lxc_path,
                                         NULL,
                                         0,
                                         NULL)) == NULL)
        goto error;

    if (virCapabilitiesAddGuestDomain(guest,
                                      VIR_DOMAIN_VIRT_LXC,
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto error;

    /* On 64-bit hosts, we can use personality() to request a 32bit process */
    if ((altArch = lxcContainerGetAlt32bitArch(caps->host.arch)) != VIR_ARCH_NONE) {
        if ((guest = virCapabilitiesAddGuest(caps,
                                             VIR_DOMAIN_OSTYPE_EXE,
                                             altArch,
                                             lxc_path,
                                             NULL,
                                             0,
                                             NULL)) == NULL)
            goto error;

        if (virCapabilitiesAddGuestDomain(guest,
                                          VIR_DOMAIN_VIRT_LXC,
                                          NULL,
                                          NULL,
                                          0,
                                          NULL) == NULL)
            goto error;
    }

    VIR_FREE(lxc_path);

    if (driver) {
        /* Security driver data */
        const char *doi, *model, *label, *type;

        doi = virSecurityManagerGetDOI(driver->securityManager);
        model = virSecurityManagerGetModel(driver->securityManager);
        label = virSecurityManagerGetBaseLabel(driver->securityManager,
                                               VIR_DOMAIN_VIRT_LXC);
        type = virDomainVirtTypeToString(VIR_DOMAIN_VIRT_LXC);
        /* Allocate the primary security driver for LXC. */
        if (VIR_ALLOC(caps->host.secModels) < 0)
            goto error;
        caps->host.nsecModels = 1;
        if (VIR_STRDUP(caps->host.secModels[0].model, model) < 0)
            goto error;
        if (VIR_STRDUP(caps->host.secModels[0].doi, doi) < 0)
            goto error;
        if (label &&
            virCapabilitiesHostSecModelAddBaseLabel(&caps->host.secModels[0],
                                                    type,
                                                    label) < 0)
            goto error;

        VIR_DEBUG("Initialized caps for security driver \"%s\" with "
                  "DOI \"%s\"", model, doi);
    } else {
        VIR_INFO("No driver, not initializing security driver");
    }

    return caps;

 error:
    VIR_FREE(lxc_path);
    virObjectUnref(caps);
    return NULL;
}
Example #4
0
virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver)
{
    size_t i, j;
    virCapsPtr caps;
    virSecurityManagerPtr *sec_managers = NULL;
    /* Security driver data */
    const char *doi, *model, *lbl, *type;
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    const int virtTypes[] = {VIR_DOMAIN_VIRT_KVM,
                             VIR_DOMAIN_VIRT_QEMU,};

    /* Basic host arch / guest machine capabilities */
    if (!(caps = virQEMUCapsInit(driver->qemuCapsCache)))
        goto error;

    if (virGetHostUUID(caps->host.host_uuid)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("cannot get the host uuid"));
        goto error;
    }

    /* access sec drivers and create a sec model for each one */
    if (!(sec_managers = virSecurityManagerGetNested(driver->securityManager)))
        goto error;

    /* calculate length */
    for (i = 0; sec_managers[i]; i++)
        ;
    caps->host.nsecModels = i;

    if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0)
        goto error;

    for (i = 0; sec_managers[i]; i++) {
        virCapsHostSecModelPtr sm = &caps->host.secModels[i];
        doi = virSecurityManagerGetDOI(sec_managers[i]);
        model = virSecurityManagerGetModel(sec_managers[i]);
        if (VIR_STRDUP(sm->model, model) < 0 ||
            VIR_STRDUP(sm->doi, doi) < 0)
            goto error;

        for (j = 0; j < ARRAY_CARDINALITY(virtTypes); j++) {
            lbl = virSecurityManagerGetBaseLabel(sec_managers[i], virtTypes[j]);
            type = virDomainVirtTypeToString(virtTypes[j]);
            if (lbl &&
                virCapabilitiesHostSecModelAddBaseLabel(sm, type, lbl) < 0)
                goto error;
        }

        VIR_DEBUG("Initialized caps for security driver \"%s\" with "
                  "DOI \"%s\"", model, doi);
    }
    VIR_FREE(sec_managers);

    virObjectUnref(cfg);
    return caps;

 error:
    VIR_FREE(sec_managers);
    virObjectUnref(caps);
    virObjectUnref(cfg);
    return NULL;
}
Example #5
0
/**
 * 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, false);

    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",
                          virDomainOSTypeToString(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'",
                virDomainVirtTypeToString(caps->guests[i]->arch.domains[j]->type));
            if (!caps->guests[i]->arch.domains[j]->info.emulator &&
                !caps->guests[i]->arch.domains[j]->info.loader &&
                !caps->guests[i]->arch.domains[j]->info.nmachines) {
                virBufferAddLit(&buf, "/>\n");
                continue;
            }
            virBufferAddLit(&buf, ">\n");
            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);
}
Example #6
0
static virCapsDomainDataPtr
virCapabilitiesDomainDataLookupInternal(virCapsPtr caps,
                                        int ostype,
                                        virArch arch,
                                        int domaintype,
                                        const char *emulator,
                                        const char *machinetype)
{
    virCapsGuestPtr foundguest = NULL;
    virCapsGuestDomainPtr founddomain = NULL;
    virCapsGuestMachinePtr foundmachine = NULL;
    virCapsDomainDataPtr ret = NULL;
    size_t i, j, k;

    for (i = 0; i < caps->nguests; i++) {
        virCapsGuestPtr guest = caps->guests[i];

        for (j = 0; j < guest->arch.ndomains; j++) {
            virCapsGuestDomainPtr domain = guest->arch.domains[j];
            virCapsGuestMachinePtr *machinelist;
            int nmachines;

            if (domain->info.nmachines) {
                nmachines = domain->info.nmachines;
                machinelist = domain->info.machines;
            } else {
                nmachines = guest->arch.defaultInfo.nmachines;
                machinelist = guest->arch.defaultInfo.machines;
            }

            for (k = 0; k < nmachines; k++) {
                virCapsGuestMachinePtr machine = machinelist[k];
                if (!virCapsDomainDataCompare(guest, domain, machine,
                                              ostype, arch, domaintype,
                                              emulator, machinetype))
                    continue;

                foundmachine = machine;
                break;
            }

            if (!foundmachine) {
                if (!virCapsDomainDataCompare(guest, domain, NULL,
                                              ostype, arch, domaintype,
                                              emulator, machinetype))
                    continue;
            }

            founddomain = domain;
            break;
        }

        if (!founddomain) {
            if (!virCapsDomainDataCompare(guest, NULL, NULL,
                                          ostype, arch, domaintype,
                                          emulator, machinetype))
                continue;
        }

        foundguest = guest;
        break;
    }

    /* XXX check default_emulator, see how it uses this */
    if (!foundguest) {
        virBuffer buf = VIR_BUFFER_INITIALIZER;
        if (ostype)
            virBufferAsprintf(&buf, "ostype=%s ",
                              virDomainOSTypeToString(ostype));
        if (arch)
            virBufferAsprintf(&buf, "arch=%s ", virArchToString(arch));
        if (domaintype != -1)
            virBufferAsprintf(&buf, "domaintype=%s ",
                              virDomainVirtTypeToString(domaintype));
        if (emulator)
            virBufferEscapeString(&buf, "emulator=%s ", emulator);
        if (machinetype)
            virBufferEscapeString(&buf, "machine=%s ", machinetype);
        if (virBufferCurrentContent(&buf) &&
            !virBufferCurrentContent(&buf)[0])
            virBufferAsprintf(&buf, "%s", _("any configuration"));
        if (virBufferCheckError(&buf) < 0) {
            virBufferFreeAndReset(&buf);
            goto error;
        }

        virReportError(VIR_ERR_INVALID_ARG,
                       _("could not find capabilities for %s"),
                       virBufferCurrentContent(&buf));
        virBufferFreeAndReset(&buf);
        goto error;
    }

    if (VIR_ALLOC(ret) < 0)
        goto error;

    ret->ostype = foundguest->ostype;
    ret->arch = foundguest->arch.id;
    if (founddomain) {
        ret->domaintype = founddomain->type;
        ret->emulator = founddomain->info.emulator;
    }
    if (!ret->emulator)
        ret->emulator = foundguest->arch.defaultInfo.emulator;
    if (foundmachine)
        ret->machinetype = foundmachine->name;

 error:
    return ret;
}