Exemplo n.º 1
0
static int testRemove(const void *args)
{
    const struct testSplitData *data = args;
    char **list = NULL;
    size_t ntokens;
    size_t i;
    int ret = -1;

    if (!(list = virStringSplitCount(data->string, data->delim,
                                     data->max_tokens, &ntokens))) {
        VIR_DEBUG("Got no tokens at all");
        return -1;
    }

    for (i = 0; data->tokens[i]; i++) {
        virStringListRemove(&list, data->tokens[i]);
        if (virStringListHasString((const char **) list, data->tokens[i])) {
            virFilePrintf(stderr, "Not removed %s", data->tokens[i]);
            goto cleanup;
        }
    }

    if (list && list[0]) {
        virFilePrintf(stderr, "Not removed all tokens: %s", list[0]);
        goto cleanup;
    }

    ret = 0;
 cleanup:
    virStringListFree(list);
    return ret;
}
Exemplo n.º 2
0
/* Parse config values of the form barrier:limit into barrier and limit */
static int
openvzParseBarrierLimit(const char* value,
                        unsigned long long *barrier,
                        unsigned long long *limit)
{
    char **tmp = NULL;
    size_t ntmp = 0;
    int ret = -1;

    if (!(tmp = virStringSplitCount(value, ":", 0, &ntmp)))
        goto error;

    if (ntmp != 2)
        goto error;

    if (barrier && virStrToLong_ull(tmp[0], NULL, 10, barrier) < 0)
        goto error;

    if (limit && virStrToLong_ull(tmp[1], NULL, 10, limit) < 0)
        goto error;

    ret = 0;
 error:
    virStringFreeListCount(tmp, ntmp);
    return ret;
}
Exemplo n.º 3
0
static int testSplit(const void *args)
{
    const struct testSplitData *data = args;
    char **got;
    size_t ntokens;
    size_t exptokens = 0;
    char **tmp1;
    const char **tmp2;
    int ret = -1;

    if (!(got = virStringSplitCount(data->string, data->delim,
                                    data->max_tokens, &ntokens))) {
        VIR_DEBUG("Got no tokens at all");
        return -1;
    }

    tmp1 = got;
    tmp2 = data->tokens;
    while (*tmp1 && *tmp2) {
        if (STRNEQ(*tmp1, *tmp2)) {
            virFilePrintf(stderr, "Mismatch '%s' vs '%s'\n", *tmp1, *tmp2);
            goto cleanup;
        }
        tmp1++;
        tmp2++;
        exptokens++;
    }
    if (*tmp1) {
        virFilePrintf(stderr, "Too many pieces returned\n");
        goto cleanup;
    }
    if (*tmp2) {
        virFilePrintf(stderr, "Too few pieces returned\n");
        goto cleanup;
    }

    if (ntokens != exptokens) {
        virFilePrintf(stderr,
                      "Returned token count (%zu) doesn't match "
                      "expected count (%zu)",
                      ntokens, exptokens);
        goto cleanup;
    }

    ret = 0;
 cleanup:
    virStringListFree(got);

    return ret;
}
Exemplo n.º 4
0
static int
virStorageBackendZFSParseVol(virStoragePoolObjPtr pool,
                             virStorageVolDefPtr vol,
                             const char *volume_string)
{
    int ret = -1;
    char **tokens;
    size_t count;
    char **name_tokens = NULL;
    char *vol_name;
    bool is_new_vol = false;
    virStorageVolDefPtr volume = NULL;

    if (!(tokens = virStringSplitCount(volume_string, "\t", 0, &count)))
        return -1;

    if (count != 2)
        goto cleanup;

    if (!(name_tokens = virStringSplit(tokens[0], "/", 2)))
        goto cleanup;

    vol_name = name_tokens[1];

    if (vol == NULL)
        volume = virStorageVolDefFindByName(pool, vol_name);
    else
        volume = vol;

    if (volume == NULL) {
        if (VIR_ALLOC(volume) < 0)
            goto cleanup;

        is_new_vol = true;
        volume->type = VIR_STORAGE_VOL_BLOCK;

        if (VIR_STRDUP(volume->name, vol_name) < 0)
            goto cleanup;
    }

    if (!volume->key && VIR_STRDUP(volume->key, tokens[0]) < 0)
        goto cleanup;

    if (volume->target.path == NULL) {
        if (virAsprintf(&volume->target.path, "%s/%s",
                        pool->def->target.path, volume->name) < 0)
            goto cleanup;
    }

    if (virStrToLong_ull(tokens[1], NULL, 10, &volume->target.capacity) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volsize reported"));
        goto cleanup;
    }

    if (is_new_vol &&
        VIR_APPEND_ELEMENT(pool->volumes.objs,
                           pool->volumes.count,
                           volume) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    virStringFreeList(tokens);
    virStringFreeList(name_tokens);
    if (is_new_vol)
        virStorageVolDefFree(volume);
    return ret;
}
Exemplo n.º 5
0
static int
virStorageBackendZFSRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
                                virStoragePoolObjPtr pool ATTRIBUTE_UNUSED)
{
    virCommandPtr cmd = NULL;
    char *zpool_props = NULL;
    char **lines = NULL;
    char **tokens = NULL;
    size_t i;

    /**
     * $ zpool get -Hp health,size,free,allocated test
     * test    health  ONLINE  -
     * test    size    199715979264    -
     * test    free    198899976704    -
     * test    allocated       816002560       -
     * $
     *
     * Here we just provide a list of properties we want to see
     */
    cmd = virCommandNewArgList(ZPOOL,
                               "get", "-Hp",
                               "health,size,free,allocated",
                               pool->def->source.name,
                               NULL);
    virCommandSetOutputBuffer(cmd, &zpool_props);
    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    if (!(lines = virStringSplit(zpool_props, "\n", 0)))
        goto cleanup;

    for (i = 0; lines[i]; i++) {
        size_t count;
        char *prop_name;

        if (STREQ(lines[i], ""))
            continue;

        virStringFreeList(tokens);
        if (!(tokens = virStringSplitCount(lines[i], "\t", 0, &count)))
            goto cleanup;

        if (count != 4)
            continue;

        prop_name = tokens[1];

        if (STREQ(prop_name, "free") || STREQ(prop_name, "size") ||
            STREQ(prop_name, "allocated")) {
            unsigned long long value;
            if (virStrToLong_ull(tokens[2], NULL, 10, &value) < 0)
                goto cleanup;

            if (STREQ(prop_name, "free"))
                pool->def->available = value;
            else if (STREQ(prop_name, "size"))
                pool->def->capacity = value;
            else if (STREQ(prop_name, "allocated"))
                pool->def->allocation = value;
        }
    }

    /* Obtain a list of volumes */
    if (virStorageBackendZFSFindVols(pool, NULL) < 0)
        goto cleanup;

 cleanup:
    virCommandFree(cmd);
    virStringFreeList(lines);
    virStringFreeList(tokens);
    VIR_FREE(zpool_props);

    return 0;
}
Exemplo n.º 6
0
static int lxctoolsReadFSConfig(lxctoolsConffilePtr conffile, virDomainDefPtr def)
{

    virDomainFSDefPtr fs = NULL;
    char* item_str = NULL;
    size_t tokencnt;
    char** splitlist = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.rootfs.path")) == NULL || item_str[0] == '\0') {
        VIR_WARN("Could not find key lxc.rootfs.path. Trying legacy key lxc.rootfs.");
        if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.rootfs")) == NULL) {
            VIR_ERROR("Could not find key lxc.rootfs");
            goto error;
        }
    }
    if (item_str[0] == '\0') {
        VIR_ERROR("Domain has no rootfs config-item.");
        goto error;
    }
    if (VIR_ALLOC(fs) < 0) {
        VIR_ERROR("Could not allocate for virDomainFSDefPtr fs.");
        goto error;
    }
    fs->type = VIR_DOMAIN_FS_TYPE_MOUNT;
    if (VIR_ALLOC(fs->src) < 0) {
        VIR_ERROR("Could not allocate for virStorageSourcePtr fs->src.");
        goto error;
    }
    splitlist = virStringSplitCount(item_str, ":", 3, &tokencnt);
    
    // Simple path
    if (tokencnt == 1) {
        fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
        if (virAsprintf(&fs->src->path, "dir:%s", splitlist[0]) < 0) {
            VIR_ERROR("Could not print string in fs->src->path.");
            goto error;
        }
    // dir
    } else if (tokencnt == 2 && strcmp(splitlist[0], "dir") == 0) {
        fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
        if (virAsprintf(&fs->src->path, "%s:%s", splitlist[0], splitlist[1]) < 0) {
            VIR_ERROR("Could not print string in fs->src->path.");
            goto error;
        }
    // overlay or overlayfs
    } else if (tokencnt == 3 && (strcmp(splitlist[0], "overlay") == 0 || strcmp(splitlist[0], "overlayfs") == 0)) {
        // We could add a new FS type like VIR_DOMAIN_FS_DRIVER_TYPE_OVERLAY, but this requires minor changes in the
        // libvirt interface and the qemu driver.
        // Also, we could either save "lowerdir:upperdir" in fs->src or create additional members to hold each seperately
        // splitlist[0] -> overlayfs/overlay
        // splitlist[1] -> lowerdir path
        // splitlist[2] -> upperdir path
        // For now, this implements overlayfs using VIR_DOMAIN_FS_DRIVER_TYPE_PATH and saving "overlayfs:lowerdir:upperdir"
        // in fs->src, which does not require lxctools external changes, but is a little bit ugly.
        fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
        if (virAsprintf(&fs->src->path, "%s:%s:%s", splitlist[0], splitlist[1], splitlist[2]) < 0) {
            VIR_ERROR("Could not print string in fs->src->path.");
            goto error;
        }
    } else {
        VIR_ERROR("Domain rootfs type is currently not supported");
        goto error;
    }
    if (VIR_STRDUP(fs->dst, "/") != 1) {
        VIR_ERROR("Could not duplicate string.");
        goto error;
    }
    if (virDomainFSInsert(def, fs) < 0) {
        VIR_ERROR("Could not insert filesystem desc into domain.");
        goto error;
    }
    fs = NULL;
    VIR_FREE(item_str);
    virStringListFree(splitlist);
    splitlist = NULL;

    if ((splitlist = lxctoolsConffileGetItemlist(conffile, "lxc.mount.entry", &tokencnt)) == NULL) {
        goto error;
    }
    if (splitlist[0] != NULL) {
        size_t param_cnt;
        char** params;
        while (tokencnt-- > 0) {
            params = virStringSplitCount(splitlist[tokencnt], " ", 6, &param_cnt);
            if (param_cnt != 6) {
                VIR_ERROR("The following entry has to few parameters: '%s'", splitlist[tokencnt]);
                goto error;
            }
            if (VIR_ALLOC(fs) < 0) {
                VIR_ERROR("Could not allocate for virDomainFSDefPtr fs.");
                goto error;
            }
            if (strcmp(params[2], "none") == 0 && strstr(params[3],"bind") != NULL) {
                fs->type = VIR_DOMAIN_FS_TYPE_MOUNT;
                fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
                if (VIR_ALLOC(fs->src) < 0) {
                    VIR_ERROR("Could not allocate for virStorageSourcePtr fs->src.");
                    goto error;
                }
                if (VIR_STRDUP(fs->src->path, params[0]) < 0) {
                    VIR_ERROR("Could not copy src string.");
                    goto error;
                }
                if (virAsprintf(&fs->dst, "/%s", params[1]) < 0) {
                    VIR_ERROR("Could not copy dst string.");
                    goto error;
                }
                if (strstr(params[3], "ro") != NULL) {
                    fs->readonly = true;
                }
                if (virDomainFSInsert(def, fs) < 0) {
                    VIR_ERROR("Could not insert filesystem desc into domain.");
                    goto error;
                }
                fs = NULL;
            }
            VIR_FREE(fs);
            virStringListFree(params);
        }
        virStringListFree(splitlist);
        splitlist = NULL;
    }
    return 0;

error:
    virStringListFree(splitlist);
    splitlist = NULL;
    VIR_FREE(item_str);
    if (fs)
        VIR_FREE(fs->src);
    VIR_FREE(fs);
    return -1;
}