From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 774CA79237 for ; Fri, 1 Jul 2022 16:16:45 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 7108BA694 for ; Fri, 1 Jul 2022 16:16:45 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Fri, 1 Jul 2022 16:16:44 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id C82F343DB0 for ; Fri, 1 Jul 2022 16:16:43 +0200 (CEST) From: Aaron Lauterer To: pve-devel@lists.proxmox.com Date: Fri, 1 Jul 2022 16:16:39 +0200 Message-Id: <20220701141642.2743824-3-a.lauterer@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220701141642.2743824-1-a.lauterer@proxmox.com> References: <20220701141642.2743824-1-a.lauterer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.018 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% 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 T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pve-devel] [PATCH manager 2/5] api ceph osd: add OSD details endpoint 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: , X-List-Received-Date: Fri, 01 Jul 2022 14:16:45 -0000 Adding a GET endpoint to .../ceph/osd/ that returns various metadata regarding the OSD. Such as * process id * memory usage * info about devices used (bdev/block, db, wal) * size * disks used (sdX) ... * network addresses and ports used ... Memory usage and PID are retrieved from systemd while the rest can be retrieved from the metadata provided by Ceph. Signed-off-by: Aaron Lauterer --- PVE/API2/Ceph/OSD.pm | 181 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/PVE/API2/Ceph/OSD.pm b/PVE/API2/Ceph/OSD.pm index 93433b3a..33b3fdb6 100644 --- a/PVE/API2/Ceph/OSD.pm +++ b/PVE/API2/Ceph/OSD.pm @@ -516,6 +516,187 @@ __PACKAGE__->register_method ({ return $rpcenv->fork_worker('cephcreateosd', $devs->{dev}->{name}, $authuser, $worker); }}); +my $OSD_DEV_RETURN_PROPS = { + dev_node => { + type => 'string', + description => 'Device node', + }, + devices => { + type => 'string', + description => 'Physical disks used', + }, + size => { + type => 'integer', + description => 'Size in bytes', + }, + support_discard => { + type => 'boolean', + description => 'Discard support of the physical device', + }, + type => { + type => 'string', + description => 'Type of device. For example, hdd or ssd', + }, +}; + +__PACKAGE__->register_method ({ + name => 'osddetails', + path => '{osdid}', + method => 'GET', + description => "Get OSD details", + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1], + }, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + osdid => { + description => 'OSD ID', + type => 'integer', + }, + }, + }, + returns => { + type => 'object', + properties => { + osd => { + type => 'object', + description => 'General information about the OSD', + properties => { + hostname => { + type => 'string', + description => 'Name of the host containing the OSD.', + }, + id => { + type => 'integer', + description => 'ID of the OSD.', + }, + mem_usage => { + type => 'integer', + description => 'Memory usage of the OSD service.', + }, + osd_data => { + type => 'string', + description => "Path to the OSD's data directory.", + }, + osd_objectstore => { + type => 'string', + description => 'The type of object store used.', + }, + pid => { + type => 'integer', + description => 'OSD process ID.', + }, + version => { + type => 'string', + description => 'Ceph version of the OSD service.', + }, + front_addr => { + type => 'string', + description => 'Address and port used to talk to clients and monitors.', + }, + back_addr => { + type => 'string', + description => 'Address and port used to talk to other OSDs.', + }, + hb_front_addr => { + type => 'string', + description => 'Heartbeat address and port for clients and monitors.', + }, + hb_back_addr => { + type => 'string', + description => 'Heartbeat address and port for other OSDs.', + }, + }, + }, + bdev => { + type => 'object', + description => 'Data about the OSD block device', + properties => $OSD_DEV_RETURN_PROPS, + }, + db => { + type => 'object', + description => 'Data about the DB device (optional)', + properties => $OSD_DEV_RETURN_PROPS, + optional => 1, + }, + wal => { + type => 'object', + description => 'Data about the WAL device (optional)', + properties => $OSD_DEV_RETURN_PROPS, + optional => 1, + }, + } + }, + code => sub { + my ($param) = @_; + + PVE::Ceph::Tools::check_ceph_inited(); + + my $osdid = $param->{osdid}; + my $rados = PVE::RADOS->new(); + my $metadata = $rados->mon_command({ prefix => 'osd metadata', id => int($osdid) }); + + die "OSD '${osdid}' does not exists on host '${nodename}'\n" + if $nodename ne $metadata->{hostname}; + + my $raw = ''; + my $pid; + my $memory; + my $parser = sub { $raw .= shift }; + my $cmd = [ + '/bin/systemctl', + 'show', + "ceph-osd\@${osdid}.service", + '--property=MainPID,MemoryCurrent' + ]; + eval { run_command($cmd, errmsg => 'systemctl show error', outfunc => $parser) }; + die $@ if $@; + + if ($raw =~ m/^MainPID=([0-9]*)MemoryCurrent=([0-9]*|\[not set\])$/s) { #untaint + $pid = $1; + $memory = $2 eq "[not set]" ? 0 : $2; + } else { + die "got unexpected data from systemctl: '${raw}'\n"; + } + + my $data = { + osd => { + hostname => $metadata->{hostname}, + id => $metadata->{id}, + mem_usage => int($memory), + osd_data => $metadata->{osd_data}, + osd_objectstore => $metadata->{osd_objectstore}, + pid => int($pid), + version => "$metadata->{ceph_version_short} ($metadata->{ceph_release})", + front_addr => $metadata->{front_addr}, + back_addr => $metadata->{back_addr}, + hb_front_addr => $metadata->{hb_front_addr}, + hb_back_addr => $metadata->{hb_back_addr}, + }, + }; + + my $get_data = sub { + my ($dev, $prefix) = @_; + $data->{$dev} = { + dev_node => $metadata->{"${prefix}_${dev}_dev_node"}, + devices => $metadata->{"${prefix}_${dev}_devices"}, + size => int($metadata->{"${prefix}_${dev}_size"}), + support_discard => int($metadata->{"${prefix}_${dev}_support_discard"}), + type => $metadata->{"${prefix}_${dev}_type"}, + }; + }; + + $get_data->("bdev", "bluestore"); + $get_data->("db", "bluefs") if $metadata->{bluefs_dedicated_db}; + $get_data->("wal", "bluefs") if $metadata->{bluefs_dedicated_wal}; + + return $data; + }}); + # Check if $osdid belongs to $nodename # $tree ... rados osd tree (passing the tree makes it easy to test) sub osd_belongs_to_node { -- 2.30.2