[libvirt] [PATCH 2/2] storage: btrfs subvolumes for directory pools
Michal Privoznik
mprivozn at redhat.com
Wed Oct 9 15:15:16 UTC 2013
On 10.09.2013 20:59, Oskari Saarenmaa wrote:
> This commit adds support for btrfs subvolumes as directory volumes. The
> directory storage pool can be used to manage btrfs subvolumes on an existing
> btrfs filesystem. The driver can create new blank subvolumes and snapshots
> of existing subvolumes as well as delete existing subvolumes.
>
> The subvolumes created are automatically made visible on the host side
> and can be attached to domains using the <filesystem> tags as defined in
> 'format domain' documentation.
>
> Subvolumes do not implement quotas at the moment because the current
> (btrfs-progs-0.20.rc1.20130501git7854c8b-4.fc20.x86_64) support for quota
> management in btrfs-progs is lacking the necessary features, for example
> it's not possible to see the quota assigned to a certain subvolume and
> usage information is only updated on syncfs(2). Quota support will be
> implemented once the tools gain the necessary features.
>
> Signed-off-by: Oskari Saarenmaa <os at ohmu.fi>
> ---
> configure.ac | 25 ++-
> docs/schemas/storagevol.rng | 1 +
> docs/storage.html.in | 30 ++-
> libvirt.spec.in | 4 +
> src/conf/storage_conf.c | 3 +
> src/conf/storage_conf.h | 1 +
> src/storage/storage_backend.c | 15 +-
> src/storage/storage_backend_fs.c | 222 ++++++++++++++++++++--
> src/util/virstoragefile.c | 4 +-
> src/util/virstoragefile.h | 1 +
> tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml | 13 ++
> tests/storagevolxml2xmlin/vol-btrfs.xml | 9 +
> tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml | 26 +++
> tests/storagevolxml2xmlout/vol-btrfs.xml | 17 ++
> tests/storagevolxml2xmltest.c | 2 +
> 15 files changed, 343 insertions(+), 30 deletions(-)
> create mode 100644 tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml
> create mode 100644 tests/storagevolxml2xmlin/vol-btrfs.xml
> create mode 100644 tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml
> create mode 100644 tests/storagevolxml2xmlout/vol-btrfs.xml
>
> @@ -866,6 +901,23 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
> goto cleanup;
> }
>
> +#if WITH_STORAGE_BTRFS
> + /* check for subvolumes */
> + if (vol->target.format == VIR_STORAGE_FILE_DIR &&
> + fstype != NULL && STREQ(fstype, "btrfs")) {
or STREQ_NULLABLE
> + int vars[] = {2};
> + const char *regexes[] = {"^\\s*([A-Za-z ]+):\\s*(.+)\\s*$"};
> + virCommandPtr cmd = virCommandNewArgList(
> + "btrfs", "subvolume", "show", vol->target.path, NULL);
> + if (cmd == NULL)
> + goto cleanup;
> + virStorageBackendRunProgRegex(NULL, cmd, 1, regexes, vars,
> + btrfsVolInfo, vol, NULL);
> + if (vol->backingStore.format == VIR_STORAGE_FILE_VOLUME)
> + missing_subvolume_info ++;
> + }
> +#endif
> +
> +static int createVolumeDir(virConnectPtr conn ATTRIBUTE_UNUSED,
> + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
> + virStorageVolDefPtr vol,
> + virStorageVolDefPtr inputvol,
> + unsigned int flags)
> +{
> + int ret = -1;
> + char *vol_dir_name = NULL;
> + char *fstype = NULL;
> + virCommandPtr cmd = NULL;
> + struct stat st;
> +
> + virCheckFlags(0, -1);
> +
> + if (inputvol) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("cannot copy from volume to a subvolume"));
> + return -1;
> + }
> +
> + if ((vol_dir_name = mdir_name(vol->target.path)) == NULL)
> + goto cleanup;
> +
> + fstype = virFileFsType(vol_dir_name);
> + if (fstype == NULL) {
> + virReportSystemError(errno,
> + _("cannot get filesystem type for %s"),
> + vol->target.path);
> + goto cleanup;
> + }
> +#if WITH_STORAGE_BTRFS
> + else if (STREQ(fstype, "btrfs")) {
> + cmd = virCommandNew("btrfs");
> + if (!cmd)
> + goto cleanup;
> +
> + if (vol->backingStore.path == NULL) {
> + virCommandAddArgList(cmd, "subvolume", "create", vol->target.path, NULL);
> + } else {
> + int accessRetCode = -1;
> +
> + accessRetCode = access(vol->backingStore.path, R_OK | X_OK);
We need virDirIsExecutable or something like that. make syntax-check is
objecting to this line.
> + if (accessRetCode != 0) {
> + virReportSystemError(errno,
> + _("inaccessible backing store volume %s"),
> + vol->backingStore.path);
> + goto cleanup;
> + }
> +
> + virCommandAddArgList(cmd, "subvolume", "snapshot", vol->backingStore.path,
> + vol->target.path, NULL);
> + }
> + if (virCommandRun(cmd, NULL) < 0)
> + goto cleanup;
> + }
> +#endif
> + else {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("subvolumes are not supported in %s"),
> + fstype);
> + goto cleanup;
> + }
> +
> + if (stat(vol->target.path, &st) < 0) {
> + virReportSystemError(errno,
> + _("failed to create %s"), vol->target.path);
> + goto cleanup;
> + }
> + ret = 0;
> +
> +cleanup:
> + VIR_FREE(vol_dir_name);
> + VIR_FREE(fstype);
> + virCommandFree(cmd);
> + return ret;
> +}
> +
Michal
More information about the libvir-list
mailing list