static int virStorageBackendZFSCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol) { virCommandPtr cmd = NULL; int ret = -1; vol->type = VIR_STORAGE_VOL_BLOCK; if (vol->target.path != NULL) { /* A target path passed to CreateVol has no meaning */ VIR_FREE(vol->target.path); } if (virAsprintf(&vol->target.path, "%s/%s", pool->def->target.path, vol->name) == -1) return -1; if (VIR_STRDUP(vol->key, vol->target.path) < 0) goto cleanup; /** * $ zfs create -o volmode=dev -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 * -V -- tells to create a volume with the specified size */ cmd = virCommandNewArgList(ZFS, "create", "-o", "volmode=dev", "-V", NULL); virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(vol->target.capacity, 1024)); virCommandAddArgFormat(cmd, "%s/%s", pool->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; }
static int virStorageBackendZFSCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol) { virCommandPtr cmd = NULL; int ret = -1; int volmode_needed = -1; if (vol->target.format != VIR_STORAGE_FILE_RAW) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only RAW volumes are supported by this storage pool")); return -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", pool->def->target.path, vol->name) == -1) 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 * * -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 * -V -- tells to create a volume with the specified size */ cmd = virCommandNewArgList(ZFS, "create", NULL); if (volmode_needed) virCommandAddArgList(cmd, "-o", "volmode=dev", NULL); virCommandAddArg(cmd, "-V"); virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(vol->target.capacity, 1024)); virCommandAddArgFormat(cmd, "%s/%s", pool->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; }
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; }