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 192DA1FF2CF for ; Thu, 11 Jul 2024 13:58:54 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id DEE7D32A4C; Thu, 11 Jul 2024 13:59:15 +0200 (CEST) From: Christoph Heiss To: pve-devel@lists.proxmox.com Date: Thu, 11 Jul 2024 13:57:53 +0200 Message-ID: <20240711115804.706227-2-c.heiss@proxmox.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240711115804.706227-1-c.heiss@proxmox.com> References: <20240711115804.706227-1-c.heiss@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -1.487 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 URIBL_BLACK 3 Contains an URL listed in the URIBL blacklist [github.io] Subject: [pve-devel] [PATCH installer v3 1/4] proxmox: add zfs module for retrieving importable zpool info 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: Christoph Heiss --- Changes v2 -> v3: * no changes Changes v1 -> v2: * incorporated Aarons suggestion to use anonymous arrays instead * added documentation * renamed parsing function parse_pool_list -> zpool_import_parse_output * split out tests into separate patch Proxmox/Makefile | 1 + Proxmox/Sys/ZFS.pm | 93 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 Proxmox/Sys/ZFS.pm diff --git a/Proxmox/Makefile b/Proxmox/Makefile index 9561d9b..035626b 100644 --- a/Proxmox/Makefile +++ b/Proxmox/Makefile @@ -17,6 +17,7 @@ PERL_MODULES=\ Sys/File.pm \ Sys/Net.pm \ Sys/Udev.pm \ + Sys/ZFS.pm \ UI.pm \ UI/Base.pm \ UI/Gtk3.pm \ diff --git a/Proxmox/Sys/ZFS.pm b/Proxmox/Sys/ZFS.pm new file mode 100644 index 0000000..9232d1a --- /dev/null +++ b/Proxmox/Sys/ZFS.pm @@ -0,0 +1,93 @@ +package Proxmox::Sys::ZFS; + +use strict; +use warnings; + +use Proxmox::Sys::Command qw(run_command); + +use base qw(Exporter); +our @EXPORT_OK = qw(get_exported_pools); + +# Parses the output of running `zpool import`, which shows all importable +# ZFS pools. +# Unfortunately, `zpool` does not support JSON or any other machine-readable +# format for output, so we have to do it the hard way. +# +# Example output of `zpool import` looks like this: +# +# root@proxmox:/# zpool import +# pool: testpool +# id: 4958685680270539150 +# state: ONLINE +# action: The pool can be imported using its name or numeric identifier. +# config: +# +# testpool ONLINE +# vdc ONLINE +# vdd ONLINE +# +# pool: rpool +# id: 9412322616744093413 +# state: ONLINE +# status: The pool was last accessed by another system. +# action: The pool can be imported using its name or numeric identifier and +# the '-f' flag. +# see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-EY +# config: +# +# rpool ONLINE +# mirror-0 ONLINE +# vda3 ONLINE +# vdb3 ONLINE +# +sub zpool_import_parse_output { + my ($fh) = @_; + + my $pools = []; # all found pools + my $pool = {}; # last found pool in output + + while (my $line = <$fh>) { + # first, if we find the start of a new pool, add it to the list with + # its name + if ($line =~ /^\s+pool: (.+)$/) { + # push the previous parsed pool to the result list + push @$pools, $pool if %$pool; + $pool = { name => $1 }; + next; + } + + # ignore any (garbage) output before the actual list, just in case + next if !%$pool; + + # add any possibly-useful attribute to the last (aka. current) pool + if ($line =~ /^\s*(id|state|status|action): (.+)$/) { + chomp($pool->{$1} = $2); + next; + } + } + + # add the final parsed pool to the list + push @$pools, $pool if %$pool; + return $pools; +} + +# Returns an array of all importable ZFS pools on the system. +# Each entry is a hash of the format: +# +# { +# name => '', +# id => , +# /* see also zpool_state_to_name() in lib/libzfs/libzfs_pool.c /* +# state => 'OFFLINE' | 'REMOVED' | 'FAULTED' | 'SPLIT' | 'UNAVAIL' \ +# | 'FAULTED' | 'DEGRADED' | 'ONLINE', +# status => '', optional +# action => '', optional +# } +sub get_exported_pools { + my $raw = run_command(['zpool', 'import']); + open (my $fh, '<', \$raw) or die 'failed to open in-memory stream'; + + return zpool_import_parse_output($fh); +} + +1; -- 2.45.1 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel