all lists on lists.proxmox.com
 help / color / mirror / Atom feed
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);





  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal