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 D93E76311E for ; Tue, 9 Feb 2021 11:31:42 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D75512B938 for ; Tue, 9 Feb 2021 11:31:42 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (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 id CDEA52B927 for ; Tue, 9 Feb 2021 11:31:41 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 93DAA41B49 for ; Tue, 9 Feb 2021 11:31:41 +0100 (CET) From: Hannes Laimer To: pve-devel@lists.proxmox.com Date: Tue, 9 Feb 2021 11:31:23 +0100 Message-Id: <20210209103124.1949709-2-h.laimer@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210209103124.1949709-1-h.laimer@proxmox.com> References: <20210209103124.1949709-1-h.laimer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.024 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [nodes.pm] Subject: [pve-devel] [PATCH v2 pve-manager 1/2] api2: add suspendall 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: Tue, 09 Feb 2021 10:31:42 -0000 Handels pause and hibernation, the reason for not splitting it was to mirror the behaviour of the already existing suspend endpoint for single VMs. Signed-off-by: Hannes Laimer --- Endpoint code is mostly taken from already existing ednpoints, namely stopall and startall. PVE/API2/Nodes.pm | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm index 8172231e..3e6e9fa2 100644 --- a/PVE/API2/Nodes.pm +++ b/PVE/API2/Nodes.pm @@ -1943,6 +1943,125 @@ __PACKAGE__->register_method ({ return $rpcenv->fork_worker('stopall', undef, $authuser, $code); }}); +my $create_suspend_worker = sub { + my ($nodename, $type, $vmid, $down_timeout, $todisk) = @_; + + my $upid; + if ($type eq 'qemu') { + return if !PVE::QemuServer::check_running($vmid, 1); + my $timeout = defined($down_timeout) ? int($down_timeout) : 60*3; + print STDERR "Suspending VM $vmid (timeout = $timeout seconds)\n"; + $upid = PVE::API2::Qemu->vm_suspend({node => $nodename, vmid => $vmid, todisk => $todisk}); + } else { + die "suspension is only supported on VMs, not on '$type'\n"; + } + + return $upid; +}; + +__PACKAGE__->register_method ({ + name => 'suspendall', + path => 'suspendall', + method => 'POST', + protected => 1, + permissions => { + check => ['perm', '/', [ 'VM.PowerMgmt' ]], + }, + proxyto => 'node', + description => "Suspend all VMs.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vms => { + description => "Only consider Guests with these IDs.", + type => 'string', format => 'pve-vmid-list', + optional => 1, + }, + todisk => { + type => 'boolean', + default => 0, + optional => 1, + description => 'If set, suspends the VM to disk. Will be resumed on next VM start.', + }, + }, + }, + returns => { + type => 'string', + }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + my $authuser = $rpcenv->get_user(); + + my $nodename = $param->{node}; + $nodename = PVE::INotify::nodename() if $nodename eq 'localhost'; + + my $code = sub { + + $rpcenv->{type} = 'priv'; # to start tasks in background + + my $stopList = &$get_start_stop_list($nodename, undef, $param->{vms}); + + my $cpuinfo = PVE::ProcFSTools::read_cpuinfo(); + my $datacenterconfig = cfs_read_file('datacenter.cfg'); + # if not set by user spawn max cpu count number of workers + my $maxWorkers = $datacenterconfig->{max_workers} || $cpuinfo->{cpus}; + + foreach my $order (sort {$b <=> $a} keys %$stopList) { + my $vmlist = $stopList->{$order}; + my $workers = {}; + + my $finish_worker = sub { + my $pid = shift; + my $d = $workers->{$pid}; + return if !$d; + delete $workers->{$pid}; + + syslog('info', "end task $d->{upid}"); + }; + + foreach my $vmid (sort {$b <=> $a} keys %$vmlist) { + my $d = $vmlist->{$vmid}; + my $upid; + eval { $upid = &$create_suspend_worker($nodename, $d->{type}, $vmid, $d->{down}, $param->{todisk}); }; + warn $@ if $@; + next if !$upid; + + my $res = PVE::Tools::upid_decode($upid, 1); + next if !$res; + + my $pid = $res->{pid}; + + $workers->{$pid} = { type => $d->{type}, upid => $upid, vmid => $vmid }; + while (scalar(keys %$workers) >= $maxWorkers) { + foreach my $p (keys %$workers) { + if (!PVE::ProcFSTools::check_process_running($p)) { + &$finish_worker($p); + } + } + sleep(1); + } + } + while (scalar(keys %$workers)) { + foreach my $p (keys %$workers) { + if (!PVE::ProcFSTools::check_process_running($p)) { + &$finish_worker($p); + } + } + sleep(1); + } + } + + syslog('info', "all VMs suspended"); + + return; + }; + + return $rpcenv->fork_worker('suspendall', undef, $authuser, $code); + }}); + my $create_migrate_worker = sub { my ($nodename, $type, $vmid, $target, $with_local_disks) = @_; -- 2.20.1