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@xxxxxxx> > --- > 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list