+sub rbd_ls_snap {
+ my ($scfg, $storeid, $name) = @_;
+
+ my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'ls', $name, '--format', 'json');
+
+ my $raw = '';
+ run_rbd_command($cmd, errmsg => "rbd error", errfunc => sub {}, outfunc => sub { $raw .= shift; });
+
+ my $list;
+ if ($raw =~ m/^(\[.*\])$/s) { # untaint
+ $list = eval { JSON::decode_json($1) };
+ die "invalid JSON output from 'rbd snap ls $name': $@\n" if $@;
+ } else {
+ die "got unexpected data from 'rbd snap ls $name': '$raw'\n";
+ }
+
+ $list = [] if !defined($list);
+
+ my $res = {};
+ foreach my $el (@$list) {
+ my $snap = $el->{name};
+ my $protected = defined($el->{protected}) && $el->{protected} eq "true" ? 1 : undef;
+ $res->{$snap} = {
+ name => $snap,
+ id => $el->{id} // undef,
+ size => $el->{size} // 0,
+ protected => $protected,
+ };
+ }
+ return $res;
+}
+