Exemple #1
0
/**
 * virBitmapFormat:
 * @bitmap: the bitmap
 *
 * This function is the counterpart of virBitmapParse. This function creates
 * a human-readable string representing the bits in bitmap.
 *
 * See virBitmapParse for the format of @str.
 *
 * Returns the string on success or NULL otherwise. Caller should call
 * VIR_FREE to free the string.
 */
char *virBitmapFormat(virBitmapPtr bitmap)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    bool first = true;
    int start, cur, prev;

    if (!bitmap)
        return NULL;

    cur = virBitmapNextSetBit(bitmap, -1);
    if (cur < 0)
        return strdup("");

    start = prev = cur;
    while (prev >= 0) {
        cur = virBitmapNextSetBit(bitmap, prev);

        if (cur == prev + 1) {
            prev = cur;
            continue;
        }

        /* cur < 0 or cur > prev + 1 */

        if (!first)
            virBufferAddLit(&buf, ",");
        else
            first = false;

        if (prev == start)
            virBufferAsprintf(&buf, "%d", start);
        else
            virBufferAsprintf(&buf, "%d-%d", start, prev);

        start = prev = cur;
    }

    if (virBufferError(&buf)) {
        virBufferFreeAndReset(&buf);
        return NULL;
    }

    return virBufferContentAndReset(&buf);
}
Exemple #2
0
/**
 * virBitmapFormat:
 * @bitmap: the bitmap
 *
 * This function is the counterpart of virBitmapParse. This function creates
 * a human-readable string representing the bits in bitmap.
 *
 * See virBitmapParse for the format of @str.
 *
 * If bitmap is NULL or it has no bits set, an empty string is returned.
 *
 * Returns the string on success or NULL otherwise. Caller should call
 * VIR_FREE to free the string.
 */
char *virBitmapFormat(virBitmapPtr bitmap)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    bool first = true;
    int start, cur, prev;

    if (!bitmap || (cur = virBitmapNextSetBit(bitmap, -1)) < 0) {
        char *ret;
        ignore_value(VIR_STRDUP(ret, ""));
        return ret;
    }

    start = prev = cur;
    while (prev >= 0) {
        cur = virBitmapNextSetBit(bitmap, prev);

        if (cur == prev + 1) {
            prev = cur;
            continue;
        }

        /* cur < 0 or cur > prev + 1 */

        if (!first)
            virBufferAddLit(&buf, ",");
        else
            first = false;

        if (prev == start)
            virBufferAsprintf(&buf, "%d", start);
        else
            virBufferAsprintf(&buf, "%d-%d", start, prev);

        start = prev = cur;
    }

    if (virBufferError(&buf)) {
        virBufferFreeAndReset(&buf);
        virReportOOMError();
        return NULL;
    }

    return virBufferContentAndReset(&buf);
}
Exemple #3
0
char *
virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *ret = NULL;

    if (virQEMUBuildCommandLineJSON(srcdef, &buf,
                                    virQEMUBuildCommandLineJSONArrayNumbered) < 0)
        goto cleanup;

    if (virBufferCheckError(&buf) < 0)
        goto cleanup;

    ret = virBufferContentAndReset(&buf);

 cleanup:
    virBufferFreeAndReset(&buf);
    return ret;
}
Exemple #4
0
static int
testCgroupDetectMounts(const void *args)
{
    int result = -1;
    const char *file = args;
    char *mounts = NULL;
    char *parsed = NULL;
    const char *actual;
    virCgroupPtr group = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    size_t i;

    if (virAsprintf(&mounts, "%s/vircgroupdata/%s.mounts",
                    abs_srcdir, file) < 0 ||
        virAsprintf(&parsed, "%s/vircgroupdata/%s.parsed",
                    abs_srcdir, file) < 0 ||
        VIR_ALLOC(group) < 0)
        goto cleanup;

    if (virCgroupDetectMountsFromFile(group, mounts, false) < 0)
        goto cleanup;

    for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
        virBufferAsprintf(&buf, "%-12s %s\n",
                          virCgroupControllerTypeToString(i),
                          NULLSTR(group->controllers[i].mountPoint));
    }
    if (virBufferCheckError(&buf) < 0)
        goto cleanup;

    actual = virBufferCurrentContent(&buf);
    if (virtTestCompareToFile(actual, parsed) < 0)
        goto cleanup;

    result = 0;

 cleanup:
    VIR_FREE(mounts);
    VIR_FREE(parsed);
    virCgroupFree(&group);
    virBufferFreeAndReset(&buf);
    return result;
}
Exemple #5
0
char *
virCPUDefFormat(virCPUDefPtr def,
                unsigned int flags)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (virCPUDefFormatBufFull(&buf, def, flags) < 0)
        goto cleanup;

    if (virBufferError(&buf))
        goto no_memory;

    return virBufferContentAndReset(&buf);

no_memory:
    virReportOOMError();
cleanup:
    virBufferFreeAndReset(&buf);
    return NULL;
}
Exemple #6
0
/**
 * virConfWriteFile:
 * @filename: the path to the configuration file.
 * @conf: the conf
 *
 * Writes a configuration file back to a file.
 *
 * Returns the number of bytes written or -1 in case of error.
 */
int
virConfWriteFile(const char *filename, virConfPtr conf)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    virConfEntryPtr cur;
    int ret;
    int fd;
    char *content;
    unsigned int use;

    if (conf == NULL)
        return -1;

    cur = conf->entries;
    while (cur != NULL) {
        virConfSaveEntry(&buf, cur);
        cur = cur->next;
    }

    if (virBufferCheckError(&buf) < 0)
        return -1;

    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    if (fd < 0) {
        virBufferFreeAndReset(&buf);
        virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to open file"));
        return -1;
    }

    use = virBufferUse(&buf);
    content = virBufferContentAndReset(&buf);
    ret = safewrite(fd, content, use);
    VIR_FREE(content);
    VIR_FORCE_CLOSE(fd);
    if (ret != (int)use) {
        virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to save content"));
        return -1;
    }

    return ret;
}
Exemple #7
0
/** dnsmasqDhcpHostsToString:
 *
 *   Turns a vector of dnsmasqDhcpHost into the string that is ought to be
 *   stored in the hostsfile, this functionality is split to make hostsfiles
 *   testable. Returs NULL if nhosts is 0.
 */
char *
dnsmasqDhcpHostsToString (dnsmasqDhcpHost *hosts,
                          unsigned int nhosts)
{
    int i;
    char *result = NULL;
    virBuffer hostsfilebuf = VIR_BUFFER_INITIALIZER;

    if (nhosts == 0)
       goto cleanup;

    for (i = 0; i < nhosts; i++) {
        virBufferAsprintf(&hostsfilebuf, "%s\n", hosts[i].host);
    }

    result = virBufferContentAndReset(&hostsfilebuf);

cleanup:
    virBufferFreeAndReset(&hostsfilebuf);
    return result;
}
Exemple #8
0
/**
 * virBitmapString:
 * @bitmap: Pointer to bitmap
 *
 * Convert @bitmap to printable string.
 *
 * Returns pointer to the string or NULL on error.
 */
char *virBitmapString(virBitmapPtr bitmap)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    size_t sz;

    virBufferAddLit(&buf, "0x");

    sz = bitmap->map_len;

    while (sz--) {
        virBufferAsprintf(&buf, "%0*lx",
                          VIR_BITMAP_BITS_PER_UNIT / 4,
                          bitmap->map[sz]);
    }

    if (virBufferError(&buf)) {
        virBufferFreeAndReset(&buf);
        return NULL;
    }

    return virBufferContentAndReset(&buf);
}
Exemple #9
0
static int
testSysinfo(const void *data)
{
    int result = -1;
    char *sysfsExpectData = NULL;
    const char *sysfsActualData;
    virSysinfoDefPtr ret = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const struct testSysinfoData *testdata = data;

    virSysinfoSetup(testdata->decoder, testdata->sysinfo, testdata->cpuinfo);

    if (!testdata->expected ||
        virtTestLoadFile(testdata->expected, &sysfsExpectData) < 0 ||
        !(ret = virSysinfoRead())) {
        goto cleanup;
    }

    if (virSysinfoFormat(&buf,ret) < 0)
        goto cleanup;

    if (!(sysfsActualData = virBufferCurrentContent(&buf)))
        goto cleanup;

    if (STRNEQ(sysfsActualData, sysfsExpectData)) {
        virtTestDifference(stderr, sysfsActualData, sysfsExpectData);
        goto cleanup;
    }

    result = 0;

cleanup:
    VIR_FREE(sysfsExpectData);
    virSysinfoDefFree(ret);
    virBufferFreeAndReset(&buf);

    return result;
}
Exemple #10
0
char *
virQEMUBuildObjectCommandlineFromJSON(const char *type,
                                      const char *alias,
                                      virJSONValuePtr props)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *ret = NULL;

    virBufferAsprintf(&buf, "%s,id=%s,", type, alias);

    if (virQEMUBuildCommandLineJSON(props, &buf,
                                    virQEMUBuildCommandLineJSONArrayBitmap) < 0)
        goto cleanup;

    if (virBufferCheckError(&buf) < 0)
        goto cleanup;

    ret = virBufferContentAndReset(&buf);

 cleanup:
    virBufferFreeAndReset(&buf);
    return ret;
}
Exemple #11
0
char *
qparam_get_query (const struct qparam_set *ps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    int i, amp = 0;

    for (i = 0; i < ps->n; ++i) {
        if (!ps->p[i].ignore) {
            if (amp) virBufferAddChar (&buf, '&');
            virBufferStrcat (&buf, ps->p[i].name, "=", NULL);
            virBufferURIEncodeString (&buf, ps->p[i].value);
            amp = 1;
        }
    }

    if (virBufferError(&buf)) {
        virBufferFreeAndReset(&buf);
        virReportOOMError();
        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;
}
Exemple #13
0
/*
 * 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);
}
Exemple #14
0
/**
 * 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;
}
Exemple #15
0
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 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;
}
Exemple #17
0
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 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;
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #22
0
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;
}
Exemple #23
0
static int
testFirewallRemoveRule(const void *opaque)
{
    virBuffer cmdbuf = VIR_BUFFER_INITIALIZER;
    virFirewallPtr fw = NULL;
    int ret = -1;
    const char *actual = NULL;
    const char *expected =
        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
    const struct testFirewallData *data = opaque;
    virFirewallRulePtr fwrule;

    fwDisabled = data->fwDisabled;
    if (virFirewallSetBackend(data->tryBackend) < 0)
        goto cleanup;

    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT)
        virCommandSetDryRun(&cmdbuf, NULL, NULL);
    else
        fwBuf = &cmdbuf;

    fw = virFirewallNew();

    virFirewallStartTransaction(fw, 0);

    virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
                       "-A", "INPUT",
                       "--source-host", "192.168.122.1",
                       "--jump", "ACCEPT", NULL);

    fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
                                "-A", "INPUT", NULL);
    virFirewallRuleAddArg(fw, fwrule, "--source-host");
    virFirewallRemoveRule(fw, fwrule);

    fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
                                "-A", "INPUT", NULL);
    virFirewallRuleAddArg(fw, fwrule, "--source-host");
    virFirewallRuleAddArgFormat(fw, fwrule, "%s", "!192.168.122.1");
    virFirewallRuleAddArgList(fw, fwrule, "--jump", "REJECT", NULL);

    if (virFirewallApply(fw) < 0)
        goto cleanup;

    if (virBufferError(&cmdbuf))
        goto cleanup;

    actual = virBufferCurrentContent(&cmdbuf);

    if (STRNEQ_NULLABLE(expected, actual)) {
        fprintf(stderr, "Unexected command execution\n");
        virTestDifference(stderr, expected, actual);
        goto cleanup;
    }

    ret = 0;
 cleanup:
    virBufferFreeAndReset(&cmdbuf);
    fwBuf = NULL;
    virCommandSetDryRun(NULL, NULL, NULL);
    virFirewallFree(fw);
    return ret;
}
Exemple #24
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;
}
Exemple #25
0
/**
 * virNetDevOpenvswitchAddPort:
 * @brname: the bridge name
 * @ifname: the network interface name
 * @macaddr: the mac address of the virtual interface
 * @vmuuid: the Domain UUID that has this interface
 * @ovsport: the ovs specific fields
 *
 * Add an interface to the OVS bridge
 *
 * Returns 0 in case of success or -1 in case of failure.
 */
int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname,
                                   const virMacAddr *macaddr,
                                   const unsigned char *vmuuid,
                                   virNetDevVPortProfilePtr ovsport,
                                   virNetDevVlanPtr virtVlan)
{
    int ret = -1;
    size_t i = 0;
    virCommandPtr cmd = NULL;
    char macaddrstr[VIR_MAC_STRING_BUFLEN];
    char ifuuidstr[VIR_UUID_STRING_BUFLEN];
    char vmuuidstr[VIR_UUID_STRING_BUFLEN];
    char *attachedmac_ex_id = NULL;
    char *ifaceid_ex_id = NULL;
    char *profile_ex_id = NULL;
    char *vmid_ex_id = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    virMacAddrFormat(macaddr, macaddrstr);
    virUUIDFormat(ovsport->interfaceID, ifuuidstr);
    virUUIDFormat(vmuuid, vmuuidstr);

    if (virAsprintf(&attachedmac_ex_id, "external-ids:attached-mac=\"%s\"",
                    macaddrstr) < 0)
        goto cleanup;
    if (virAsprintf(&ifaceid_ex_id, "external-ids:iface-id=\"%s\"",
                    ifuuidstr) < 0)
        goto cleanup;
    if (virAsprintf(&vmid_ex_id, "external-ids:vm-id=\"%s\"",
                    vmuuidstr) < 0)
        goto cleanup;
    if (ovsport->profileID[0] != '\0') {
        if (virAsprintf(&profile_ex_id, "external-ids:port-profile=\"%s\"",
                        ovsport->profileID) < 0)
            goto cleanup;
    }

    cmd = virCommandNew(OVSVSCTL);

    virCommandAddArgList(cmd, "--timeout=5", "--", "--if-exists", "del-port",
                         ifname, "--", "add-port", brname, ifname, NULL);

    if (virtVlan && virtVlan->nTags > 0) {

        switch (virtVlan->nativeMode) {
        case VIR_NATIVE_VLAN_MODE_TAGGED:
            virCommandAddArg(cmd, "vlan_mode=native-tagged");
            virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag);
            break;
        case VIR_NATIVE_VLAN_MODE_UNTAGGED:
            virCommandAddArg(cmd, "vlan_mode=native-untagged");
            virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag);
            break;
        case VIR_NATIVE_VLAN_MODE_DEFAULT:
        default:
            break;
        }

        if (virtVlan->trunk) {
            virBufferAddLit(&buf, "trunk=");

            /*
             * Trunk ports have at least one VLAN. Do the first one
             * outside the "for" loop so we can put a "," at the
             * start of the for loop if there are more than one VLANs
             * on this trunk port.
             */
            virBufferAsprintf(&buf, "%d", virtVlan->tag[i]);

            for (i = 1; i < virtVlan->nTags; i++) {
                virBufferAddLit(&buf, ",");
                virBufferAsprintf(&buf, "%d", virtVlan->tag[i]);
            }

            if (virBufferCheckError(&buf) < 0)
                goto cleanup;
            virCommandAddArg(cmd, virBufferCurrentContent(&buf));
        } else if (virtVlan->nTags) {
            virCommandAddArgFormat(cmd, "tag=%d", virtVlan->tag[0]);
        }
    }

    if (ovsport->profileID[0] == '\0') {
        virCommandAddArgList(cmd,
                        "--", "set", "Interface", ifname, attachedmac_ex_id,
                        "--", "set", "Interface", ifname, ifaceid_ex_id,
                        "--", "set", "Interface", ifname, vmid_ex_id,
                        "--", "set", "Interface", ifname,
                        "external-ids:iface-status=active",
                        NULL);
    } else {
        virCommandAddArgList(cmd,
                        "--", "set", "Interface", ifname, attachedmac_ex_id,
                        "--", "set", "Interface", ifname, ifaceid_ex_id,
                        "--", "set", "Interface", ifname, vmid_ex_id,
                        "--", "set", "Interface", ifname, profile_ex_id,
                        "--", "set", "Interface", ifname,
                        "external-ids:iface-status=active",
                        NULL);
    }

    if (virCommandRun(cmd, NULL) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Unable to add port %s to OVS bridge %s"),
                       ifname, brname);
        goto cleanup;
    }

    ret = 0;
 cleanup:
    virBufferFreeAndReset(&buf);
    VIR_FREE(attachedmac_ex_id);
    VIR_FREE(ifaceid_ex_id);
    VIR_FREE(vmid_ex_id);
    VIR_FREE(profile_ex_id);
    virCommandFree(cmd);
    return ret;
}
Exemple #26
0
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;
}
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;
}
/**
 * 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);
}
Exemple #29
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 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);
}
Exemple #30
0
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);
}