[pve-devel] [RFC v3 storage 8/9] plugin: qemu block device: add support for snapshot option

Fabian Grünbichler f.gruenbichler at proxmox.com
Mon Jun 30 13:40:46 CEST 2025


On June 26, 2025 4:40 pm, Fiona Ebner wrote:
> This is mostly in preparation for external qcow2 snapshot support.
> 
> For internal qcow2 snapshots, which currently are the only supported
> variant, it is not possible to attach the snapshot only. If access to
> that is required it will need to be handled differently, e.g. via a
> FUSE/NBD export.

just for the avoidance of doubt since it's only implied and not spelled
out explicitly - we don't do any such accesses at the moment, right?

linked clones cannot be done for running VMs, full clones of snapshots
don't happen within the running VM but via qemu-img convert, and nothing
else besides replication (which is ZFS specific) and manual `pvesm
export` calls (which are on the storage level by definition) directly
reads from a storage snapshot?

> 
> Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
> ---
> 
> No changes in v3. RFC, because it depends on the previous one.
> 
>  src/PVE/Storage/ISCSIDirectPlugin.pm |  3 +++
>  src/PVE/Storage/Plugin.pm            | 13 ++++++++++++-
>  src/PVE/Storage/RBDPlugin.pm         |  2 ++
>  src/PVE/Storage/ZFSPlugin.pm         |  3 +++
>  src/PVE/Storage/ZFSPoolPlugin.pm     |  2 ++
>  5 files changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/src/PVE/Storage/ISCSIDirectPlugin.pm b/src/PVE/Storage/ISCSIDirectPlugin.pm
> index 12b894d..e0f8a62 100644
> --- a/src/PVE/Storage/ISCSIDirectPlugin.pm
> +++ b/src/PVE/Storage/ISCSIDirectPlugin.pm
> @@ -113,6 +113,9 @@ sub path {
>  sub qemu_blockdev_options {
>      my ($class, $scfg, $storeid, $volname, $options) = @_;
>  
> +    die "volume snapshot is not possible on iscsi device\n"
> +        if $options->{'snapshot-name'};
> +
>      my $lun = ($class->parse_volname($volname))[1];
>  
>      return {
> diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm
> index 7a274a3..e6892ec 100644
> --- a/src/PVE/Storage/Plugin.pm
> +++ b/src/PVE/Storage/Plugin.pm
> @@ -2004,6 +2004,11 @@ A hash reference with additional options.
>  
>  =over
>  
> +=item C<< $options->{'snapshot-name'} >>
> +
> +(optional) The snapshot name. Set when the associated snapshot should be opened rather than the
> +volume itself.
> +
>  =item C<< $options->{hints} >>
>  
>  A hash reference with hints indicating what the volume will be used for. This can be safely ignored
> @@ -2030,9 +2035,15 @@ sub qemu_blockdev_options {
>  
>      my $blockdev = {};
>  
> -    my ($path) = $class->filesystem_path($scfg, $volname);
> +    my ($path) = $class->filesystem_path($scfg, $volname, $options->{'snapshot-name'});
>  
>      if ($path =~ m|^/|) {
> +        # For qcow2 and qed the path of a snapshot will be the same, but it's not possible to attach
> +        # the snapshot alone.
> +        my $format = ($class->parse_volname($volname))[6];
> +        die "cannot attach only the snapshot of a '$format' image\n"
> +            if $options->{'snapshot-name'} && ($format eq 'qcow2' || $format eq 'qed');
> +
>          # The 'file' driver only works for regular files. The check below is taken from
>          # block/file-posix.c:hdev_probe_device() in QEMU. Do not bother with detecting 'host_cdrom'
>          # devices here, those are not managed by the storage layer.
> diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm
> index 6b37ba3..cf3d354 100644
> --- a/src/PVE/Storage/RBDPlugin.pm
> +++ b/src/PVE/Storage/RBDPlugin.pm
> @@ -530,6 +530,7 @@ sub qemu_blockdev_options {
>      my ($name) = ($class->parse_volname($volname))[1];
>  
>      if ($scfg->{krbd}) {
> +        $name .= '@' . $options->{'snapshot-name'} if $options->{'snapshot-name'};
>          my $rbd_dev_path = get_rbd_dev_path($scfg, $storeid, $name);
>          return { driver => 'host_device', filename => $rbd_dev_path };
>      }
> @@ -540,6 +541,7 @@ sub qemu_blockdev_options {
>          image => "$name",
>      };
>      $blockdev->{namespace} = "$scfg->{namespace}" if defined($scfg->{namespace});
> +    $blockdev->{snapshot} = $options->{'snapshot-name'} if $options->{'snapshot-name'};
>  
>      $blockdev->{conf} = $cmd_option->{ceph_conf} if $cmd_option->{ceph_conf};
>  
> diff --git a/src/PVE/Storage/ZFSPlugin.pm b/src/PVE/Storage/ZFSPlugin.pm
> index 0f64898..940d4f0 100644
> --- a/src/PVE/Storage/ZFSPlugin.pm
> +++ b/src/PVE/Storage/ZFSPlugin.pm
> @@ -250,6 +250,9 @@ sub path {
>  sub qemu_blockdev_options {
>      my ($class, $scfg, $storeid, $volname, $options) = @_;
>  
> +    die "direct access to snapshots not implemented\n"
> +        if $options->{'snapshot-name'};
> +
>      my $name = ($class->parse_volname($volname))[1];
>      my $guid = $class->zfs_get_lu_name($scfg, $name);
>      my $lun = $class->zfs_get_lun_number($scfg, $guid);
> diff --git a/src/PVE/Storage/ZFSPoolPlugin.pm b/src/PVE/Storage/ZFSPoolPlugin.pm
> index 677f88c..86f83a2 100644
> --- a/src/PVE/Storage/ZFSPoolPlugin.pm
> +++ b/src/PVE/Storage/ZFSPoolPlugin.pm
> @@ -165,6 +165,8 @@ sub path {
>  sub qemu_blockdev_options {
>      my ($class, $scfg, $storeid, $volname, $options) = @_;
>  
> +    die "cannot attach only the snapshot of a zvol\n" if $options->{'snapshot-name'};
> +
>      my ($path) = $class->path($scfg, $volname, $storeid);
>  
>      my $blockdev = { driver => 'host_device', filename => $path };
> -- 
> 2.47.2
> 
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel at lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 
> 




More information about the pve-devel mailing list