public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Fiona Ebner <f.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH storage v5 15/51] plugin: qemu blockdev options: parse protocol paths in default implementation
Date: Wed,  2 Jul 2025 18:27:48 +0200	[thread overview]
Message-ID: <20250702162838.393696-16-f.ebner@proxmox.com> (raw)
In-Reply-To: <20250702162838.393696-1-f.ebner@proxmox.com>

for better backwards compatibility. This also means using path()
rather than filesystem_path() as the latter does not return protocol
paths.

Some protocol paths are not implemented (considered all that are
listed by grepping for '\.protocol_name' in QEMU):
- ftp(s)/http(s), which would access web servers via curl. This one
  could be added if there is enough interest.
- nvme://XXXX:XX:XX.X/X, which would access a host NVME device.
- null-{aio,co}, which are mainly useful for debugging.
- pbs, because path-based access is not used anymore for PBS,
  live-restore in qemu-server already defines a driver-based device.
- nfs and ssh, because the QEMU build script used by Proxmox VE does
  not enable them.
- blk{debug,verify}, because they are for debugging.
- the ones used by blkio, i.e. io_uring, nvme-io_uring,
  virtio-blk-vfio-pci, virtio-blk-vhost-user and
  virtio-blk-vhost-vdpa, because the QEMU build script used by Proxmox
  VE does not enable blkio.
- backup-dump and zeroinit, because they should not be used by the
  storage layer directly.
- gluster, because support is dropped in Proxmox VE 9.
- host_cdrom, because the storage layer should not access host CD-ROM
  devices.
- fat, because it hopefully isn't used by any third-party plugin here.

Co-developed-by: Alexandre Derumier <alexandre.derumier@groupe-cyllene.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

New in v5.

 src/PVE/Storage/Plugin.pm | 95 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 1 deletion(-)

diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm
index 3f2c638..c2f376b 100644
--- a/src/PVE/Storage/Plugin.pm
+++ b/src/PVE/Storage/Plugin.pm
@@ -1961,6 +1961,34 @@ sub rename_volume {
     return "${storeid}:${base}${target_vmid}/${target_volname}";
 }
 
+my sub blockdev_options_nbd_tcp {
+    my ($host, $port, $export) = @_;
+
+    die "blockdev_options_nbd_tcp: no host" if !defined($host);
+
+    my $blockdev = {};
+
+    my $server = { type => 'inet', host => "$host" };
+    # port is also a string in QAPI, not optional, default for NBD is 10809
+    $server->{port} = defined($port) ? "$port" : "10809";
+    $blockdev = { driver => 'nbd', server => $server };
+    $blockdev->{export} = "$export" if defined($export);
+
+    return $blockdev;
+}
+
+my sub blockdev_options_nbd_unix {
+    my ($socket_path, $export) = @_;
+
+    my $blockdev = {};
+
+    my $server = { type => 'unix', path => "$socket_path" };
+    $blockdev = { driver => 'nbd', server => $server };
+    $blockdev->{export} = "$export" if defined($export);
+
+    return $blockdev;
+}
+
 =pod
 
 =head3 qemu_blockdev_options
@@ -2031,7 +2059,7 @@ sub qemu_blockdev_options {
 
     my $blockdev = {};
 
-    my ($path) = $class->filesystem_path($scfg, $volname, $options->{'snapshot-name'});
+    my ($path) = $class->path($scfg, $volname, $storeid, $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
@@ -2046,6 +2074,71 @@ sub qemu_blockdev_options {
         my $st = File::stat::stat($path) or die "stat for '$path' failed - $!\n";
         my $driver = (S_ISCHR($st->mode) || S_ISBLK($st->mode)) ? 'host_device' : 'file';
         $blockdev = { driver => $driver, filename => $path };
+    } elsif ($path =~ m|^file:(\S+)|) {
+        $blockdev = { driver => 'file', filename => "$1" };
+    } elsif ($path =~ m|^host_device:(\S+)|) {
+        $blockdev = { driver => 'host_device', filename => "$1" };
+    } elsif ($path =~ m|^iscsi://(\S+)/(\S+)/(\d+)$|) {
+        $blockdev =
+            { driver => 'iscsi', portal => "$1", target => "$2", lun => "$3", transport => "tcp" };
+    } elsif ($path =~ m|^iser://(\S+)/(\S+)/(\d+)$|) {
+        $blockdev =
+            { driver => 'iscsi', portal => "$1", target => "$2", lun => "$3", transport => "iser" };
+    } elsif ($path =~ m|^nbd(?:\+tcp)?://(\S+?)(?::(\d+))?/(\S+)?$|) { # new style NBD TCP URI
+        $blockdev = blockdev_options_nbd_tcp($1, $2, $3);
+    } elsif ($path =~ m|^nbd(?:\+tcp)?:(\S+):(\d+)(?::exportname=(\S+))?$|) {
+        # old style NBD TCP URI
+        $blockdev = blockdev_options_nbd_tcp($1, $2, $3);
+    } elsif ($path =~ m|^nbd\+unix:///(\S+)?\?socket=(\S+)$|) { # new style NBD unix URI
+        $blockdev = blockdev_options_nbd_unix($2, $1); # note the order!
+    } elsif ($path =~ m|^nbd:unix:(\S+?)(?::exportname=(\S+))?$|) { # old style NBD unix URI
+        $blockdev = blockdev_options_nbd_unix($1, $2);
+    } elsif ($path =~ m/^rbd:(\S+)$/) {
+        my $rbd_options = $1;
+        $blockdev->{driver} = 'rbd';
+
+        #map options to key=value pair (if not key is provided, this is the image)
+        #options are seprated with : but we need to exclude \: used for ipv6 address
+        my $options = {
+            map {
+                s/\\:/:/g;
+                /^(.*?)=(.*)/ ? ($1 => $2) : (image => $_)
+            } $rbd_options =~ /(?:\\:|\[[^\]]*\]|[^:\\])+/g
+        };
+
+        $blockdev->{'auth-client-required'} = [$options->{'auth_supported'}]
+            if $options->{'auth_supported'};
+        $blockdev->{'conf'} = $options->{'conf'} if $options->{'conf'};
+        $blockdev->{'user'} = $options->{'id'} if $options->{'id'};
+
+        if ($options->{'mon_host'}) {
+            my $server = [];
+            my @mons = split(';', $options->{'mon_host'});
+            for my $mon (@mons) {
+                $mon =~ s/[\[\]]//g;
+                my ($host, $port) = PVE::Tools::parse_host_and_port($mon);
+                $port = '3300' if !$port;
+                push @$server, { host => $host, port => $port };
+            }
+            $blockdev->{server} = $server;
+        }
+
+        if ($options->{'image'} =~ m|^(\S+)/(\S+)$|) {
+            $blockdev->{pool} = $1;
+            $blockdev->{image} = $2;
+            if ($blockdev->{image} =~ m|^(\S+)/(\S+)$|) {
+                $blockdev->{namespace} = $1;
+                $blockdev->{image} = $2;
+            }
+        }
+
+        delete($options->@{qw(auth_supported conf id mon_host image)});
+
+        # Map rest directly. With -drive, it was possible to use arbitrary key-value-pairs. Like
+        # this, there will be warnings for those that are not allowed via blockdev.
+        for my $opt (keys $options->%*) {
+            $blockdev->{$opt} = $options->{$opt};
+        }
     } else {
         die "storage plugin doesn't implement qemu_blockdev_options() method\n";
     }
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  parent reply	other threads:[~2025-07-02 16:35 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-02 16:27 [pve-devel] [PATCH qemu/storage/qemu-server v3 00/51] let's switch to blockdev, blockdev, blockdev, part four (final) Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu v3 01/51] PVE backup: prepare for the switch to using blockdev rather than drive Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu v3 02/51] block/zeroinit: support using as blockdev driver Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu v3 03/51] block/alloc-track: " Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu v3 04/51] block/qapi: include child references in block device info Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 05/51] plugin: add method to get qemu blockdevice options for volume Fiona Ebner
2025-07-03  9:33   ` Fabian Grünbichler
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 06/51] iscsi direct plugin: implement method to get qemu blockdevice options Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 07/51] zfs iscsi plugin: implement new " Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 08/51] zfs pool plugin: implement " Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 09/51] ceph/rbd: set 'keyring' in ceph configuration for externally managed RBD storages Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 10/51] rbd plugin: implement new method to get qemu blockdevice options Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 11/51] plugin: qemu block device: add hints option and EFI disk hint Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 12/51] plugin: qemu block device: add support for snapshot option Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 13/51] plugin: add machine version to qemu_blockdev_options() interface Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 14/51] qemu blockdev options: restrict allowed drivers and options Fiona Ebner
2025-07-02 18:15   ` Fiona Ebner
2025-07-02 16:27 ` Fiona Ebner [this message]
2025-07-03  9:38   ` [pve-devel] [PATCH storage v5 15/51] plugin: qemu blockdev options: parse protocol paths in default implementation Fabian Grünbichler
2025-07-02 16:27 ` [pve-devel] [PATCH storage v5 16/51] plugin api: bump api version and age Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 17/51] mirror: code style: avoid masking earlier declaration of $op Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 18/51] test: collect mocked functions for QemuServer module Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 19/51] drive: add helper to parse drive interface Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 20/51] drive: drop invalid export of get_scsi_devicetype Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 21/51] blockdev: add and use throttle_group_id() helper Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 22/51] blockdev: introduce top_node_name() and parse_top_node_name() helpers Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 23/51] blockdev: add helpers for attaching and detaching block devices Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 24/51] blockdev: add missing include for JSON module Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 25/51] backup: use blockdev for fleecing images Fiona Ebner
2025-07-02 16:27 ` [pve-devel] [PATCH qemu-server v3 26/51] backup: use blockdev for TPM state file Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 27/51] blockdev: introduce qdev_id_to_drive_id() helper Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 28/51] blockdev: introduce and use get_block_info() helper Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 29/51] blockdev: move helper for resize into module Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 30/51] blockdev: add helper to get node below throttle node Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 31/51] blockdev: resize: query and use node name for resize operation Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 32/51] blockdev: support using zeroinit filter Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 33/51] blockdev: make some functions private Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 34/51] blockdev: add 'no-throttle' option to skip generationg throttle top node Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 35/51] block job: allow specifying a block node that should be detached upon completion Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 36/51] block job: add blockdev mirror Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 37/51] blockdev: add change_medium() helper Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 38/51] blockdev: add blockdev_change_medium() helper Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 39/51] blockdev: move helper for configuring throttle limits to module Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 40/51] clone disk: skip check for aio=default (io_uring) compatibility starting with machine version 10.0 Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 41/51] print drive device: don't reference any drive for 'none' " Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 42/51] blockdev: add support for NBD paths Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 43/51] blockdev: add helper to generate PBS block device for live restore Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 44/51] blockdev: support alloc-track driver for live-{import, restore} Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 45/51] live import: also record volid information Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 46/51] live import/restore: query which node to use for operation Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 47/51] live import/restore: use Blockdev::detach helper Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 48/51] command line: switch to blockdev starting with machine version 10.0 Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 49/51] test: migration: update running machine to 10.0 Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 50/51] partially fix #3227: ensure that target image for mirror has the same size for EFI disks Fiona Ebner
2025-07-02 16:28 ` [pve-devel] [PATCH qemu-server v3 51/51] blockdev: pass along machine version to storage layer Fiona Ebner
2025-07-03  7:17 ` [pve-devel] [PATCH qemu/storage/qemu-server v3 00/51] let's switch to blockdev, blockdev, blockdev, part four (final) DERUMIER, Alexandre via pve-devel
2025-07-03  7:35   ` Fabian Grünbichler
2025-07-03  8:03     ` DERUMIER, Alexandre via pve-devel
2025-07-03 13:01 ` [pve-devel] applied-series: " Fabian Grünbichler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250702162838.393696-16-f.ebner@proxmox.com \
    --to=f.ebner@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal