Example #1
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;
    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);

cleanup:
    VIR_FREE(result);
    if (host)
        cpuDataFree(host->arch, guestData);
    virCPUDefFree(host);
    virCPUDefFree(cpu);
    virCPUDefFree(guest);
    return ret;
}
Example #2
0
/**
 * virSysinfoFormat:
 * @buf: buffer to append output to (may use auto-indentation)
 * @def: structure to convert to xml string
 *
 * Returns 0 on success, -1 on failure after generating an error message.
 */
int
virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
{
    const char *type = virSysinfoTypeToString(def->type);

    if (!type) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unexpected sysinfo type model %d"),
                       def->type);
        virBufferFreeAndReset(buf);
        return -1;
    }

    virBufferAsprintf(buf, "<sysinfo type='%s'>\n", type);

    virSysinfoBIOSFormat(buf, def);
    virSysinfoSystemFormat(buf, def);
    virSysinfoProcessorFormat(buf, def);
    virSysinfoMemoryFormat(buf, def);

    virBufferAddLit(buf, "</sysinfo>\n");

    if (virBufferError(buf)) {
        virReportOOMError();
        return -1;
    }

    return 0;
}
Example #3
0
/* converts bitmap to string of the form '1,2...' */
char *
mapDomainPinVcpu(unsigned char *cpumap, int maplen)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    size_t len;
    char *ret = NULL;
    size_t i, j;
    for (i = 0; i < maplen; i++) {
        for (j = 0; j < 8; j++) {
            if (cpumap[i] & (1 << j)) {
                virBufferAsprintf(&buf, "%zu,", (8*i)+j);
            }
        }
    }
    if (virBufferError(&buf)) {
        virReportOOMError();
        virBufferFreeAndReset(&buf);
        return NULL;
    }
    ret = virBufferContentAndReset(&buf);
    len = strlen(ret);
    if (len > 0 && ret[len - 1] == ',')
        ret[len - 1] = 0;
    return ret;
}
Example #4
0
static char *
bhyveConnectGetSysinfo(virConnectPtr conn, unsigned int flags)
{
    bhyveConnPtr privconn = conn->privateData;
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    virCheckFlags(0, NULL);

    if (virConnectGetSysinfoEnsureACL(conn) < 0)
        return NULL;

    if (!privconn->hostsysinfo) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Host SMBIOS information is not available"));
        return NULL;
    }

    if (virSysinfoFormat(&buf, privconn->hostsysinfo) < 0)
        return NULL;
    if (virBufferError(&buf)) {
        virReportOOMError();
        return NULL;
    }

    return virBufferContentAndReset(&buf);
}
Example #5
0
static char *
testFilterXML(char *xml)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char **xmlLines = NULL;
    char **xmlLine;
    char *ret = NULL;

    if (!(xmlLines = virStringSplit(xml, "\n", 0))) {
        VIR_FREE(xml);
        goto cleanup;
    }
    VIR_FREE(xml);

    for (xmlLine = xmlLines; *xmlLine; xmlLine++) {
        if (regexec(testSnapshotXMLVariableLineRegex,
                    *xmlLine, 0, NULL, 0) == 0)
            continue;

        virBufferStrcat(&buf, *xmlLine, "\n", NULL);
    }

    if (virBufferError(&buf)) {
        virReportOOMError();
        goto cleanup;
    }

    ret = virBufferContentAndReset(&buf);

 cleanup:
   virBufferFreeAndReset(&buf);
   virStringFreeList(xmlLines);
   return ret;
}
Example #6
0
/* utility function to replace 'from' by 'to' in 'str' */
static char*
openvz_replace(const char* str,
               const char* from,
               const char* to) {
    const char* offset = NULL;
    const char* str_start = str;
    int to_len;
    int from_len;
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if ((!from) || (!to))
        return NULL;
    from_len = strlen(from);
    to_len = strlen(to);

    while ((offset = strstr(str_start, from)))
    {
        virBufferAdd(&buf, str_start, offset-str_start);
        virBufferAdd(&buf, to, to_len);
        str_start = offset + from_len;
    }

    virBufferAdd(&buf, str_start, -1);

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

    return virBufferContentAndReset(&buf);
}
Example #7
0
static int udevGenerateDeviceName(struct udev_device *device,
                                  virNodeDeviceDefPtr def,
                                  const char *s)
{
    int ret = 0, i = 0;
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    virBufferAsprintf(&buf, "%s_%s",
                      udev_device_get_subsystem(device),
                      udev_device_get_sysname(device));

    if (s != NULL) {
        virBufferAsprintf(&buf, "_%s", s);
    }

    if (virBufferError(&buf)) {
        virBufferFreeAndReset(&buf);
        VIR_ERROR(_("Buffer error when generating device name for device "
                    "with sysname '%s'"), udev_device_get_sysname(device));
        ret = -1;
    }

    def->name = virBufferContentAndReset(&buf);

    for (i = 0; i < strlen(def->name) ; i++) {
        if (!(c_isalnum(*(def->name + i)))) {
            *(def->name + i) = '_';
        }
    }

    return ret;
}
Example #8
0
/**
 * virStringReplace:
 * @haystack: the source string to process
 * @oldneedle: the substring to locate
 * @newneedle: the substring to insert
 *
 * Search @haystack and replace all occurrences of @oldneedle with @newneedle.
 *
 * Returns: a new string with all the replacements, or NULL on error
 */
char *
virStringReplace(const char *haystack,
                 const char *oldneedle,
                 const char *newneedle)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *tmp1, *tmp2;
    size_t oldneedlelen = strlen(oldneedle);
    size_t newneedlelen = strlen(newneedle);

    tmp1 = haystack;
    tmp2 = NULL;

    while (tmp1) {
        tmp2 = strstr(tmp1, oldneedle);

        if (tmp2) {
            virBufferAdd(&buf, tmp1, (tmp2 - tmp1));
            virBufferAdd(&buf, newneedle, newneedlelen);
            tmp2 += oldneedlelen;
        } else {
            virBufferAdd(&buf, tmp1, -1);
        }

        tmp1 = tmp2;
    }

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

    return virBufferContentAndReset(&buf);
}
Example #9
0
static char *
bhyveConnectDomainXMLToNative(virConnectPtr conn,
                              const char *format,
                              const char *xmlData,
                              unsigned int flags)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    bhyveConnPtr privconn = conn->privateData;
    virDomainDefPtr def = NULL;
    virCommandPtr cmd = NULL, loadcmd = NULL;
    virCapsPtr caps = NULL;
    char *ret = NULL;

    virCheckFlags(0, NULL);

    if (virConnectDomainXMLToNativeEnsureACL(conn) < 0)
        goto cleanup;

    if (STRNEQ(format, BHYVE_CONFIG_FORMAT_ARGV)) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("Unsupported config type %s"), format);
        goto cleanup;
    }

    if (!(caps = bhyveDriverGetCapabilities(privconn)))
        goto cleanup;

    if (!(def = virDomainDefParseString(xmlData, caps, privconn->xmlopt,
                                  1 << VIR_DOMAIN_VIRT_BHYVE,
                                  VIR_DOMAIN_XML_INACTIVE)))
        goto cleanup;

    if (bhyveDomainAssignAddresses(def, NULL) < 0)
        goto cleanup;

    if (!(loadcmd = virBhyveProcessBuildLoadCmd(privconn, def)))
        goto cleanup;

    if (!(cmd = virBhyveProcessBuildBhyveCmd(privconn, def, true)))
        goto cleanup;

    virBufferAdd(&buf, virCommandToString(loadcmd), -1);
    virBufferAddChar(&buf, '\n');
    virBufferAdd(&buf, virCommandToString(cmd), -1);

    if (virBufferError(&buf)) {
        virReportOOMError();
        goto cleanup;
    }

    ret = virBufferContentAndReset(&buf);

 cleanup:
    virCommandFree(loadcmd);
    virCommandFree(cmd);
    virDomainDefFree(def);
    virObjectUnref(caps);
    return ret;
}
Example #10
0
static int
testFirewallSingleGroup(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;

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

    virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
                       "-A", "INPUT",
                       "--source-host", "!192.168.122.1",
                       "--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;
}
Example #11
0
static int testCompareXMLToArgvFiles(const char *xml,
                                     const char *cmdline)
{
    char *actualargv = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    virNWFilterHashTablePtr vars = virNWFilterHashTableCreate(0);
    virNWFilterInst inst;
    int ret = -1;

    memset(&inst, 0, sizeof(inst));

    virCommandSetDryRun(&buf, NULL, NULL);

    if (!vars)
        goto cleanup;

    if (testSetDefaultParameters(vars) < 0)
        goto cleanup;

    if (virNWFilterDefToInst(xml,
                             vars,
                             &inst) < 0)
        goto cleanup;

    if (ebiptables_driver.applyNewRules("vnet0", inst.rules, inst.nrules) < 0)
        goto cleanup;

    if (virBufferError(&buf))
        goto cleanup;

    actualargv = virBufferContentAndReset(&buf);
    virTestClearCommandPath(actualargv);
    virCommandSetDryRun(NULL, NULL, NULL);

    testRemoveCommonRules(actualargv);

    if (virTestCompareToFile(actualargv, cmdline) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virBufferFreeAndReset(&buf);
    VIR_FREE(actualargv);
    virNWFilterInstReset(&inst);
    virNWFilterHashTableFree(vars);
    return ret;
}
Example #12
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) {
        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);
        return NULL;
    }

    return virBufferContentAndReset(&buf);
}
Example #13
0
static int
testVirNetDevBandwidthSet(const void *data)
{
    int ret = -1;
    const struct testSetStruct *info = data;
    const char *iface = info->iface;
    virNetDevBandwidthPtr band = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *actual_cmd = NULL;

    PARSE(info->band, band);

    if (!iface)
        iface = "eth0";

    virCommandSetDryRun(&buf, NULL, NULL);

    if (virNetDevBandwidthSet(iface, band, info->hierarchical_class) < 0)
        goto cleanup;

    if (!(actual_cmd = virBufferContentAndReset(&buf))) {
        int err = virBufferError(&buf);
        if (err) {
            fprintf(stderr, "buffer's in error state: %d", err);
            goto cleanup;
        }
        /* This is interesting, no command has been executed.
         * Maybe that's expected, actually. */
    }

    if (STRNEQ_NULLABLE(info->exp_cmd, actual_cmd)) {
        virTestDifference(stderr,
                          NULLSTR(info->exp_cmd),
                          NULLSTR(actual_cmd));
        goto cleanup;
    }

    ret = 0;
cleanup:
    virCommandSetDryRun(NULL, NULL, NULL);
    virNetDevBandwidthFree(band);
    virBufferFreeAndReset(&buf);
    VIR_FREE(actual_cmd);
    return ret;
}
Example #14
0
/*
 * Convert a buffer into a command line argument to the child.
 * Correctly transfers memory errors or contents from buf to cmd.
 */
void
virCommandAddArgBuffer(virCommandPtr cmd, virBufferPtr buf)
{
    if (!cmd || cmd->has_error) {
        virBufferFreeAndReset(buf);
        return;
    }

    /* Arg plus trailing NULL. */
    if (virBufferError(buf) ||
        VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) {
        cmd->has_error = ENOMEM;
        virBufferFreeAndReset(buf);
        return;
    }

    cmd->args[cmd->nargs++] = virBufferContentAndReset(buf);
}
Example #15
0
/*
 * Convert a buffer containing preformatted name=value into an
 * environment variable of the child.
 * Correctly transfers memory errors or contents from buf to cmd.
 */
void
virCommandAddEnvBuffer(virCommandPtr cmd, virBufferPtr buf)
{
    if (!cmd || cmd->has_error) {
        virBufferFreeAndReset(buf);
        return;
    }

    /* env plus trailing NULL. */
    if (virBufferError(buf) ||
        VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 1 + 1) < 0) {
        cmd->has_error = ENOMEM;
        virBufferFreeAndReset(buf);
        return;
    }

    cmd->env[cmd->nenv++] = virBufferContentAndReset(buf);
}
Example #16
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 (virBufferError(&buf)) {
        virBufferFreeAndReset(&buf);
        virReportOOMError();
        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;
}
Example #17
0
/**
 * virStringJoin:
 * @strings: a NULL-terminated array of strings to join
 * @delim: a string to insert between each of the strings
 *
 * Joins a number of strings together to form one long string, with the
 * @delim inserted between each of them. The returned string
 * should be freed with VIR_FREE().
 *
 * Returns: a newly-allocated string containing all of the strings joined
 *     together, with @delim between them
 */
char *virStringJoin(const char **strings,
                    const char *delim)
{
    char *ret;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    while (*strings) {
        virBufferAdd(&buf, *strings, -1);
        if (*(strings+1))
            virBufferAdd(&buf, delim, -1);
        strings++;
    }
    if (virBufferError(&buf)) {
        virReportOOMError();
        return NULL;
    }
    ret = virBufferContentAndReset(&buf);
    if (!ret)
        ignore_value(VIR_STRDUP(ret, ""));
    return ret;
}
Example #18
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;
}
Example #19
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);
}
Example #20
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);
}
Example #21
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);
}
Example #22
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;
}
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;
}
Example #24
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);
}
Example #25
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;
}
Example #26
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->data.ethernet.ipaddr) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("IP address not supported for ethernet interface"));
            goto error;
        }
        break;

    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);
        virNetworkFree(network);
        if (bridge == NULL) {
            goto error;
        }

        if (umlConnectTapDevice(conn, 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(conn, 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 (virBufferError(&buf)) {
        virReportOOMError();
        return NULL;
    }

    return virBufferContentAndReset(&buf);

error:
    virBufferFreeAndReset(&buf);
    return NULL;
}
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;
}
Example #28
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;
    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);
}
Example #29
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;
}
Example #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);
}