From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
Aaron Lauterer <a.lauterer@proxmox.com>
Subject: Re: [pve-devel] [PATCH librados2-perl 2/6] mon_command: optionally ignore errors and return hashmap
Date: Mon, 21 Feb 2022 16:44:18 +0100 [thread overview]
Message-ID: <b7fb21fd-f991-9945-ac95-94562454b6c8@proxmox.com> (raw)
In-Reply-To: <20220218113827.1415641-3-a.lauterer@proxmox.com>
On 18.02.22 12:38, Aaron Lauterer wrote:
> In some situations, we do not want to abort if the Ceph API returns an
> error (ret != 0). We also want to be able to access all the retured
> values from the Ceph API (return code, status, data).
>
> One such situation can be the 'osd ok-to-stop' call where Ceph will
> return a non zero code if it is not okay to stop the OSD, but will also
> have useful information in the status buffer that we can use to show the
> user.
>
> For this, let's always return a hashmap with the return code, the status
> message and the returned data from RADOS.xs::mon_command. Then decide on
> the Perl side (RADOS.pm::mon_command) if we return the scalar data as we
> used to, or the contents of the hashmap in an array.
>
> The new parameter 'noerr' is used to indicate that we want to proceed on
> non-zero return values. Omitting it gives us the old behavior to die
> with the status message.
>
> The new parameter needs to be passed to the child process, which causes
> some changes there and the resulting hashmaps gets JSON encoded to be
> passed back up to the parent process.
should be avoidable, the child can always pass through the new info and
the actual perl code can do the filtering.
>
> Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
> ---
> This patch requires patch 3 of the series to not break OSD removal!
> Therefore releasing a new version of librados2-perl and pve-manager
> needs to be coordinated.
I don't like that and think it can be avoided.
>
> Please have a closer look at the C code that I wrote in RADOS.xs as I
> have never written much C and am not sure if I introduced some nasty bug
> / security issue.
>
> PVE/RADOS.pm | 37 ++++++++++++++++++++++---------------
> RADOS.xs | 26 ++++++++++++++++++++------
> 2 files changed, 42 insertions(+), 21 deletions(-)
>
> @@ -259,19 +259,26 @@ sub cluster_stat {
> # example1: { prefix => 'get_command_descriptions'})
> # example2: { prefix => 'mon dump', format => 'json' }
> sub mon_command {
> - my ($self, $cmd) = @_;
> + my ($self, $cmd, $noerr) = @_;
> +
> + $noerr = 0 if !$noerr;
>
> $cmd->{format} = 'json' if !$cmd->{format};
>
> my $json = encode_json($cmd);
>
> - my $raw = eval { $sendcmd->($self, 'M', $json) };
> + my $ret = eval { $sendcmd->($self, 'M', $json, undef, $noerr) };
I'd rather like to avoid chaining through that $noerr every where, rather pass all the
info via the die (errors can be references to structured data too, like PVE::Exception is),
or just avoid the die at the lower level completely and map the error inside the struct
too, it can then be thrown here, depending on $noerr parameters or what not.
> die "error with '$cmd->{prefix}': $@" if $@;
>
> + my $raw = decode_json($ret);
> +
> + my $data = '';
> if ($cmd->{format} && $cmd->{format} eq 'json') {
> - return length($raw) ? decode_json($raw) : undef;
> + $data = length($raw->{data}) ? decode_json($raw->{data}) : undef;
> + } else {
> + $data = $raw->{data};
> }
> - return $raw;
> + return wantarray ? ($raw->{code}, $raw->{status}, $data) : $data;
> }
>
>
> diff --git a/RADOS.xs b/RADOS.xs
> index 1eb0b5a..3d828e1 100644
> --- a/RADOS.xs
> +++ b/RADOS.xs
> @@ -98,11 +98,12 @@ CODE:
> rados_shutdown(cluster);
> }
>
> -SV *
> -pve_rados_mon_command(cluster, cmds)
> +HV *
> +pve_rados_mon_command(cluster, cmds, noerr=false)
> rados_t cluster
> AV *cmds
> -PROTOTYPE: $$
> +bool noerr
> +PROTOTYPE: $$;$
> CODE:
> {
> const char *cmd[64];
> @@ -129,7 +130,7 @@ CODE:
> &outbuf, &outbuflen,
> &outs, &outslen);
>
> - if (ret < 0) {
> + if (ret < 0 && noerr == false) {
> char msg[4096];
> if (outslen > sizeof(msg)) {
> outslen = sizeof(msg);
> @@ -142,9 +143,22 @@ CODE:
> die(msg);
> }
>
> - RETVAL = newSVpv(outbuf, outbuflen);
> + char status[(int)outslen + 1];
this is on the stack and could be to large to guarantee it always fits, but...
> + if (outslen > sizeof(status)) {
> + outslen = sizeof(status);
> + }
> + snprintf(status, sizeof(status), "%.*s\n", (int)outslen, outs);
...why not just chain outs through instead of re-allocating it and writing it out in a
relatively expensive way?
> +
> + HV * rh = (HV *)sv_2mortal((SV *)newHV());
> +
> + (void)hv_store(rh, "code", 4, newSViv(ret), 0);
> + (void)hv_store(rh, "data", 4, newSVpv(outbuf, outbuflen), 0);
> + (void)hv_store(rh, "status", 6, newSVpv(status, sizeof(status) - 1), 0);
> + RETVAL = rh;
>
> - rados_buffer_free(outbuf);
> + if (outbuf != NULL) {
> + rados_buffer_free(outbuf);
> + }
>
> if (outs != NULL) {
> rados_buffer_free(outs);
next prev parent reply other threads:[~2022-02-21 15:44 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-18 11:38 [pve-devel] [PATCH librados2-perl manager 0/6] Add Ceph safety checks Aaron Lauterer
2022-02-18 11:38 ` [pve-devel] [PATCH librados2-perl 1/6] mon_command: free outs buffer Aaron Lauterer
2022-02-21 15:35 ` Thomas Lamprecht
2022-02-18 11:38 ` [pve-devel] [PATCH librados2-perl 2/6] mon_command: optionally ignore errors and return hashmap Aaron Lauterer
2022-02-21 15:44 ` Thomas Lamprecht [this message]
2022-02-22 12:42 ` Aaron Lauterer
2022-02-18 11:38 ` [pve-devel] [PATCH manager 3/6] api: osd: force mon_command to scalar context Aaron Lauterer
2022-02-18 11:38 ` [pve-devel] [PATCH manager 4/6] api: mon: mds: osd: add safety check endpoints Aaron Lauterer
2022-02-22 8:44 ` Thomas Lamprecht
2022-03-14 16:49 ` Aaron Lauterer
2022-03-14 17:02 ` Thomas Lamprecht
2022-02-18 11:38 ` [pve-devel] [PATCH manager 5/6] ui: osd: warn if removal could be problematic Aaron Lauterer
2022-02-24 12:46 ` Thomas Lamprecht
2022-02-18 11:38 ` [pve-devel] [PATCH manager 6/6] ui: osd: mon: mds: warn if stop/destroy actions are problematic Aaron Lauterer
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=b7fb21fd-f991-9945-ac95-94562454b6c8@proxmox.com \
--to=t.lamprecht@proxmox.com \
--cc=a.lauterer@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