From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 3A4681FF15C for ; Fri, 27 Jun 2025 17:58:06 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D4804181E0; Fri, 27 Jun 2025 17:57:51 +0200 (CEST) From: Fiona Ebner To: pve-devel@lists.proxmox.com Date: Fri, 27 Jun 2025 17:57:01 +0200 Message-ID: <20250627155737.162083-6-f.ebner@proxmox.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250627155737.162083-1-f.ebner@proxmox.com> References: <20250627155737.162083-1-f.ebner@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.029 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH qemu-server 05/31] blockdev: add helpers for attaching and detaching block devices X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" Signed-off-by: Fiona Ebner --- src/PVE/QemuServer/Blockdev.pm | 132 +++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/src/PVE/QemuServer/Blockdev.pm b/src/PVE/QemuServer/Blockdev.pm index 6e6b9245..26d70eee 100644 --- a/src/PVE/QemuServer/Blockdev.pm +++ b/src/PVE/QemuServer/Blockdev.pm @@ -11,6 +11,7 @@ use PVE::JSONSchema qw(json_bool); use PVE::Storage; use PVE::QemuServer::Drive qw(drive_is_cdrom); +use PVE::QemuServer::Monitor qw(mon_cmd); my sub get_node_name { my ($type, $drive_id, $volid, $snap) = @_; @@ -221,4 +222,135 @@ sub generate_drive_blockdev { }; } +my sub blockdev_add { + my ($vmid, $blockdev) = @_; + + eval { mon_cmd($vmid, 'blockdev-add', $blockdev->%*); }; + if (my $err = $@) { + my $node_name = $blockdev->{'node-name'} // 'undefined'; + die "adding blockdev '$node_name' failed : $err\n" if $@; + } + + return; +} + +=pod + +=head3 attach + + attach($storecfg, $vmid, $drive, $options); + +Attach the drive C<$drive> to the VM C<$vmid> considering the additional options C<$options>. + +Parameters: + +=over + +=item C<$storecfg> + +The storage configuration. + +=item C<$vmid> + +The ID of the virtual machine. + +=item C<$drive> + +The drive as parsed from a virtual machine configuration. + +=item C<$options> + +A hash reference with additional options. + +=over + +=item C<< $options->{'read-only'} >> + +Attach the image as read-only irrespective of the configuration in C<$drive>. + +=item C<< $options->{size} >> + +Attach the image with this virtual size. Must be smaller than the actual size of the image. The +image format must be C. + +=item C<< $options->{'snapshot-name'} >> + +Attach this snapshot of the volume C<< $drive->{file} >>, rather than the volume itself. + +=back + +=back + +=cut + +sub attach { + my ($storecfg, $vmid, $drive, $options) = @_; + + my $blockdev = generate_drive_blockdev($storecfg, $drive, $options); + + my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); + if ($blockdev->{'node-name'} eq "drive-$drive_id") { # device top nodes need a throttle group + my $throttle_group = generate_throttle_group($drive); + mon_cmd($vmid, 'object-add', $throttle_group->%*); + } + + eval { blockdev_add($vmid, $blockdev); }; + if (my $err = $@) { + eval { mon_cmd($vmid, 'object-del', id => "throttle-drive-$drive_id"); }; + warn $@ if $@; + die $err; + } + + return; +} + +=pod + +=head3 detach + + detach($vmid, $node_name); + +Detach the block device C<$node_name> from the VM C<$vmid>. Also removes associated child block +nodes. + +Parameters: + +=over + +=item C<$vmid> + +The ID of the virtual machine. + +=item C<$node_name> + +The node name identifying the block node in QEMU. + +=back + +=cut + +sub detach { + my ($vmid, $node_name) = @_; + + die "Blockdev::detach - no node name\n" if !$node_name; + + # QEMU recursively auto-removes the file children, i.e. file and format node below the top + # node and also implicit backing children referenced by a qcow2 image. + eval { mon_cmd($vmid, 'blockdev-del', 'node-name' => "$node_name"); }; + if (my $err = $@) { + return if $err =~ m/Failed to find node with node-name/; # already gone + die "deleting blockdev '$node_name' failed : $err\n"; + } + + if ($node_name =~ m/^drive-(.+)$/) { + # also remove throttle group if it was a device top node + my $drive_id = $1; + if (PVE::QemuServer::Drive::is_valid_drivename($drive_id)) { + mon_cmd($vmid, 'object-del', id => "throttle-drive-$drive_id"); + } + } + + return; +} + 1; -- 2.47.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel