Example #1
0
static int
virStorageBackendZFSDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
                              virStoragePoolObjPtr pool,
                              virStorageVolDefPtr vol,
                              unsigned int flags)
{
    int ret = -1;
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    virCommandPtr destroy_cmd = NULL;

    virCheckFlags(0, -1);

    destroy_cmd = virCommandNewArgList(ZFS, "destroy", NULL);

    virCommandAddArgFormat(destroy_cmd, "%s/%s",
                           def->source.name, vol->name);

    if (virCommandRun(destroy_cmd, NULL) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    virCommandFree(destroy_cmd);
    return ret;
}
Example #2
0
static int
virStorageBackendZFSBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED,
                              virStoragePoolObjPtr pool,
                              unsigned int flags)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    virCommandPtr cmd = NULL;
    size_t i;
    int ret = -1;

    virCheckFlags(0, -1);

    if (def->source.ndevice == 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       "%s", _("missing source devices"));
        return -1;
    }

    cmd = virCommandNewArgList(ZPOOL, "create",
                               def->source.name, NULL);

    for (i = 0; i < def->source.ndevice; i++)
        virCommandAddArg(cmd, def->source.devices[i].path);

    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virCommandFree(cmd);
    return ret;
}
static int
virStorageBackendVzIsMounted(virStoragePoolObjPtr pool)
{
    int ret = -1;
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    FILE *mtab;
    struct mntent ent;
    char buf[1024];
    VIR_AUTOFREE(char *) cluster = NULL;

    if (virAsprintf(&cluster, "vstorage://%s", def->source.name) < 0)
        return -1;

    if ((mtab = fopen(_PATH_MOUNTED, "r")) == NULL) {
        virReportSystemError(errno,
                             _("cannot read mount list '%s'"),
                             _PATH_MOUNTED);
        goto cleanup;
    }

    while ((getmntent_r(mtab, &ent, buf, sizeof(buf))) != NULL) {

        if (STREQ(ent.mnt_dir, def->target.path) &&
            STREQ(ent.mnt_fsname, cluster)) {
            ret = 1;
            goto cleanup;
        }
    }

    ret = 0;

 cleanup:
    VIR_FORCE_FCLOSE(mtab);
    return ret;
}
Example #4
0
static int
virStorageBackendZFSFindVols(virStoragePoolObjPtr pool,
                             virStorageVolDefPtr vol)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    virCommandPtr cmd = NULL;
    char *volumes_list = NULL;
    char **lines = NULL;
    size_t i;

    /**
     * $ zfs list -Hp -t volume -o name,volsize -r test
     * test/vol1       5368709120
     * test/vol3       1073741824
     * test/vol4       1572864000
     * $
     *
     * Arguments description:
     *  -t volume -- we want to see only volumes
     *  -o name,volsize -- limit output to name and volume size
     *  -r -- we want to see all the childer of our pool
     */
    cmd = virCommandNewArgList(ZFS,
                               "list", "-Hp",
                               "-t", "volume", "-r",
                               "-o", "name,volsize,refreservation",
                               def->source.name,
                               NULL);
    virCommandSetOutputBuffer(cmd, &volumes_list);
    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

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

    for (i = 0; lines[i]; i++) {
        if (STREQ(lines[i], ""))
            continue;

        if (virStorageBackendZFSParseVol(pool, vol, lines[i]) < 0)
            continue;
    }

 cleanup:
    virCommandFree(cmd);
    virStringListFree(lines);
    VIR_FREE(volumes_list);

    return 0;
}
static int
virStorageBackendVzPoolStop(virStoragePoolObjPtr pool)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    int rc;
    VIR_AUTOPTR(virCommand) cmd = NULL;

    /* Short-circuit if already unmounted */
    if ((rc = virStorageBackendVzIsMounted(pool)) != 1)
        return rc;

    cmd = virCommandNewArgList(UMOUNT, def->target.path, NULL);
    return virCommandRun(cmd, NULL);
}
Example #6
0
static int
virStorageBackendZFSCheckPool(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
                              bool *isActive)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    char *devpath;

    if (virAsprintf(&devpath, "/dev/zvol/%s",
                    def->source.name) < 0)
        return -1;
    *isActive = virFileIsDir(devpath);
    VIR_FREE(devpath);

    return 0;
}
Example #7
0
static int
virStorageBackendZFSDeletePool(virConnectPtr conn ATTRIBUTE_UNUSED,
                               virStoragePoolObjPtr pool,
                               unsigned int flags)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    virCommandPtr cmd = NULL;
    int ret = -1;

    virCheckFlags(0, -1);

    cmd = virCommandNewArgList(ZPOOL, "destroy",
                               def->source.name, NULL);

    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virCommandFree(cmd);
    return ret;
}
static int
virStorageBackendVzPoolStart(virStoragePoolObjPtr pool)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    VIR_AUTOFREE(char *) grp_name = NULL;
    VIR_AUTOFREE(char *) usr_name = NULL;
    VIR_AUTOFREE(char *) mode = NULL;
    VIR_AUTOPTR(virCommand) cmd = NULL;

    /* Check the permissions */
    if (def->target.perms.mode == (mode_t)-1)
        def->target.perms.mode = VIR_STORAGE_DEFAULT_POOL_PERM_MODE;
    if (def->target.perms.uid == (uid_t)-1)
        def->target.perms.uid = geteuid();
    if (def->target.perms.gid == (gid_t)-1)
        def->target.perms.gid = getegid();

    /* Convert ids to names because vstorage uses names */

    if (!(grp_name = virGetGroupName(def->target.perms.gid)))
        return -1;

    if (!(usr_name = virGetUserName(def->target.perms.uid)))
        return -1;

    if (virAsprintf(&mode, "%o", def->target.perms.mode) < 0)
        return -1;

    cmd = virCommandNewArgList(VSTORAGE_MOUNT,
                               "-c", def->source.name,
                               def->target.path,
                               "-m", mode,
                               "-g", grp_name, "-u", usr_name,
                               NULL);

    return virCommandRun(cmd, NULL);
}
Example #9
0
static int
virStorageBackendZFSCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED,
                              virStoragePoolObjPtr pool,
                              virStorageVolDefPtr vol)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    virCommandPtr cmd = NULL;
    int ret = -1;
    int volmode_needed = -1;

    if (vol->target.encryption != NULL) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       "%s", _("storage pool does not support encrypted "
                               "volumes"));
        return -1;
    }

    vol->type = VIR_STORAGE_VOL_BLOCK;

    VIR_FREE(vol->target.path);
    if (virAsprintf(&vol->target.path, "%s/%s",
                    def->target.path, vol->name) < 0)
        return -1;

    if (VIR_STRDUP(vol->key, vol->target.path) < 0)
        goto cleanup;

    volmode_needed = virStorageBackendZFSVolModeNeeded();
    if (volmode_needed < 0)
        goto cleanup;
    /**
     * $ zfs create -o volmode=dev -V 10240K test/volname
     * $ zfs create -o volmode=dev -s -V 10240K test/volname
     * $ zfs create -o volmode=dev -s -o refreservation=1024K -V 10240K test/volname
     *
     * -o volmode=dev -- we want to get volumes exposed as cdev
     *                   devices. If we don't specify that zfs
     *                   will lookup vfs.zfs.vol.mode sysctl value
     * -s -- create a sparse volume
     * -o refreservation -- reserve the specified amount of space
     * -V -- tells to create a volume with the specified size
     */
    cmd = virCommandNewArgList(ZFS, "create", NULL);
    if (volmode_needed)
        virCommandAddArgList(cmd, "-o", "volmode=dev", NULL);
    if (vol->target.capacity != vol->target.allocation) {
        virCommandAddArg(cmd, "-s");
        if (vol->target.allocation > 0) {
            virCommandAddArg(cmd, "-o");
            virCommandAddArgFormat(cmd, "refreservation=%lluK",
                                   VIR_DIV_UP(vol->target.allocation, 1024));
        }
        vol->target.sparse = true;
    }
    virCommandAddArg(cmd, "-V");
    virCommandAddArgFormat(cmd, "%lluK",
                           VIR_DIV_UP(vol->target.capacity, 1024));
    virCommandAddArgFormat(cmd, "%s/%s", def->source.name, vol->name);

    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    if (virStorageBackendZFSFindVols(pool, vol) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    virCommandFree(cmd);
    return ret;

}
Example #10
0
static int
virStorageBackendZFSRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
                                virStoragePoolObjPtr pool ATTRIBUTE_UNUSED)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    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",
                               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;

        virStringListFree(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"))
                def->available = value;
            else if (STREQ(prop_name, "size"))
                def->capacity = value;
            else if (STREQ(prop_name, "allocated"))
                def->allocation = value;
        }
    }

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

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

    return 0;
}
Example #11
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;
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);

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

    if (count != 3)
        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",
                        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 (virStrToLong_ull(tokens[2], NULL, 10, &volume->target.allocation) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed refreservation reported"));
        goto cleanup;
    }

    if (volume->target.allocation < volume->target.capacity)
        volume->target.sparse = true;

    if (is_new_vol && virStoragePoolObjAddVol(pool, volume) < 0)
        goto cleanup;
    volume = NULL;

    ret = 0;
 cleanup:
    virStringListFree(tokens);
    virStringListFree(name_tokens);
    if (is_new_vol)
        virStorageVolDefFree(volume);
    return ret;
}