+my sub get_rbd_dev_path {
+ my ($scfg, $storeid, $volume) = @_;
+
+ my $cluster_id = '';
+ if ($scfg->{fsid}) {
+ # NOTE: the config doesn't support this currently (but it could!), hack for qemu-server tests
+ $cluster_id = $scfg->{fsid};
+ } elsif ($scfg->{monhost}) {
+ my $rados = $librados_connect->($scfg, $storeid);
+ $cluster_id = $rados->mon_command({ prefix => 'fsid', format => 'json' })->{fsid};
+ } else {
+ $cluster_id = cfs_read_file('ceph.conf')->{global}->{fsid};
+ }
+
+ my $uuid_pattern = "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})";
+ if ($cluster_id =~ qr/^${uuid_pattern}$/is) {
+ $cluster_id = $1; # use untained value
+ } else {
+ die "cluster fsid has invalid format\n";
+ }
+
+ my $rbd_path = get_rbd_path($scfg, $volume);
+ my $pve_path = "/dev/rbd-pve/${cluster_id}/${rbd_path}";
+ my $path = "/dev/rbd/${rbd_path}";
+
+ if (!-e $pve_path && -e $path) {
+ # possibly mapped before rbd-pve rule existed
+ my $real_dev = abs_path($path);
+ my ($rbd_id) = ($real_dev =~ m|/dev/rbd([0-9]+)$|);
+ my $dev_cluster_id = file_read_firstline("/sys/devices/rbd/${rbd_id}/cluster_fsid");
+ return $path if $cluster_id eq $dev_cluster_id;
+ }
+ return $pve_path;
+}
+