[PATCH v2] block/rbd: report a better error when namespace does not exist

Stefano Garzarella posted 1 patch 1 year, 11 months ago
meson.build |  6 ++++++
block/rbd.c | 24 ++++++++++++++++++++++++
2 files changed, 30 insertions(+)
[PATCH v2] block/rbd: report a better error when namespace does not exist
Posted by Stefano Garzarella 1 year, 11 months ago
If the namespace does not exist, rbd_create() fails with -ENOENT and
QEMU reports a generic "error rbd create: No such file or directory":

    $ qemu-img create rbd:rbd/namespace/image 1M
    Formatting 'rbd:rbd/namespace/image', fmt=raw size=1048576
    qemu-img: rbd:rbd/namespace/image: error rbd create: No such file or directory

Unfortunately rados_ioctx_set_namespace() does not fail if the namespace
does not exist, so let's use rbd_namespace_exists() in qemu_rbd_connect()
to check if the namespace exists, reporting a more understandable error:

    $ qemu-img create rbd:rbd/namespace/image 1M
    Formatting 'rbd:rbd/namespace/image', fmt=raw size=1048576
    qemu-img: rbd:rbd/namespace/image: namespace 'namespace' does not exist

Reported-by: Tingting Mao <timao@redhat.com>
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
v2:
- check r < 0 for consistency (librbd errors are always negative) [Ilya]
---
 meson.build |  6 ++++++
 block/rbd.c | 24 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/meson.build b/meson.build
index 9b20dcd143..e6c0afd62b 100644
--- a/meson.build
+++ b/meson.build
@@ -1828,6 +1828,12 @@ config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
+if rbd.found()
+  config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
+                       cc.has_function('rbd_namespace_exists',
+                                       dependencies: rbd,
+                                       prefix: '#include <rbd/librbd.h>'))
+endif
 if rdma.found()
   config_host_data.set('HAVE_IBV_ADVISE_MR',
                        cc.has_function('ibv_advise_mr',
diff --git a/block/rbd.c b/block/rbd.c
index 6caf35cbba..f826410f40 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -831,6 +831,26 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
         error_setg_errno(errp, -r, "error opening pool %s", opts->pool);
         goto failed_shutdown;
     }
+
+#ifdef HAVE_RBD_NAMESPACE_EXISTS
+    if (opts->has_q_namespace && strlen(opts->q_namespace) > 0) {
+        bool exists;
+
+        r = rbd_namespace_exists(*io_ctx, opts->q_namespace, &exists);
+        if (r < 0) {
+            error_setg_errno(errp, -r, "error checking namespace");
+            goto failed_ioctx_destroy;
+        }
+
+        if (!exists) {
+            error_setg(errp, "namespace '%s' does not exist",
+                       opts->q_namespace);
+            r = -ENOENT;
+            goto failed_ioctx_destroy;
+        }
+    }
+#endif
+
     /*
      * Set the namespace after opening the io context on the pool,
      * if nspace == NULL or if nspace == "", it is just as we did nothing
@@ -840,6 +860,10 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
     r = 0;
     goto out;
 
+#ifdef HAVE_RBD_NAMESPACE_EXISTS
+failed_ioctx_destroy:
+    rados_ioctx_destroy(*io_ctx);
+#endif
 failed_shutdown:
     rados_shutdown(*cluster);
 out:
-- 
2.35.3
Re: [PATCH v2] block/rbd: report a better error when namespace does not exist
Posted by Kevin Wolf 1 year, 10 months ago
Am 17.05.2022 um 09:10 hat Stefano Garzarella geschrieben:
> If the namespace does not exist, rbd_create() fails with -ENOENT and
> QEMU reports a generic "error rbd create: No such file or directory":
> 
>     $ qemu-img create rbd:rbd/namespace/image 1M
>     Formatting 'rbd:rbd/namespace/image', fmt=raw size=1048576
>     qemu-img: rbd:rbd/namespace/image: error rbd create: No such file or directory
> 
> Unfortunately rados_ioctx_set_namespace() does not fail if the namespace
> does not exist, so let's use rbd_namespace_exists() in qemu_rbd_connect()
> to check if the namespace exists, reporting a more understandable error:
> 
>     $ qemu-img create rbd:rbd/namespace/image 1M
>     Formatting 'rbd:rbd/namespace/image', fmt=raw size=1048576
>     qemu-img: rbd:rbd/namespace/image: namespace 'namespace' does not exist
> 
> Reported-by: Tingting Mao <timao@redhat.com>
> Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>

Thanks, applied to the block branch.

Kevin
Re: [PATCH v2] block/rbd: report a better error when namespace does not exist
Posted by Stefano Garzarella 1 year, 10 months ago
Gentle ping :-)

@Kevin, can this patch go with your tree?
Ilya already reviewed it.

Thanks,
Stefano

On Tue, May 17, 2022 at 09:10:12AM +0200, Stefano Garzarella wrote:
>If the namespace does not exist, rbd_create() fails with -ENOENT and
>QEMU reports a generic "error rbd create: No such file or directory":
>
>    $ qemu-img create rbd:rbd/namespace/image 1M
>    Formatting 'rbd:rbd/namespace/image', fmt=raw size=1048576
>    qemu-img: rbd:rbd/namespace/image: error rbd create: No such file or directory
>
>Unfortunately rados_ioctx_set_namespace() does not fail if the namespace
>does not exist, so let's use rbd_namespace_exists() in qemu_rbd_connect()
>to check if the namespace exists, reporting a more understandable 
>error:
>
>    $ qemu-img create rbd:rbd/namespace/image 1M
>    Formatting 'rbd:rbd/namespace/image', fmt=raw size=1048576
>    qemu-img: rbd:rbd/namespace/image: namespace 'namespace' does not exist
>
>Reported-by: Tingting Mao <timao@redhat.com>
>Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
>Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
>---
>v2:
>- check r < 0 for consistency (librbd errors are always negative) [Ilya]
>---
> meson.build |  6 ++++++
> block/rbd.c | 24 ++++++++++++++++++++++++
> 2 files changed, 30 insertions(+)
>
>diff --git a/meson.build b/meson.build
>index 9b20dcd143..e6c0afd62b 100644
>--- a/meson.build
>+++ b/meson.build
>@@ -1828,6 +1828,12 @@ config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
> config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
> config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
> config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
>+if rbd.found()
>+  config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
>+                       cc.has_function('rbd_namespace_exists',
>+                                       dependencies: rbd,
>+                                       prefix: '#include <rbd/librbd.h>'))
>+endif
> if rdma.found()
>   config_host_data.set('HAVE_IBV_ADVISE_MR',
>                        cc.has_function('ibv_advise_mr',
>diff --git a/block/rbd.c b/block/rbd.c
>index 6caf35cbba..f826410f40 100644
>--- a/block/rbd.c
>+++ b/block/rbd.c
>@@ -831,6 +831,26 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
>         error_setg_errno(errp, -r, "error opening pool %s", opts->pool);
>         goto failed_shutdown;
>     }
>+
>+#ifdef HAVE_RBD_NAMESPACE_EXISTS
>+    if (opts->has_q_namespace && strlen(opts->q_namespace) > 0) {
>+        bool exists;
>+
>+        r = rbd_namespace_exists(*io_ctx, opts->q_namespace, &exists);
>+        if (r < 0) {
>+            error_setg_errno(errp, -r, "error checking namespace");
>+            goto failed_ioctx_destroy;
>+        }
>+
>+        if (!exists) {
>+            error_setg(errp, "namespace '%s' does not exist",
>+                       opts->q_namespace);
>+            r = -ENOENT;
>+            goto failed_ioctx_destroy;
>+        }
>+    }
>+#endif
>+
>     /*
>      * Set the namespace after opening the io context on the pool,
>      * if nspace == NULL or if nspace == "", it is just as we did nothing
>@@ -840,6 +860,10 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
>     r = 0;
>     goto out;
>
>+#ifdef HAVE_RBD_NAMESPACE_EXISTS
>+failed_ioctx_destroy:
>+    rados_ioctx_destroy(*io_ctx);
>+#endif
> failed_shutdown:
>     rados_shutdown(*cluster);
> out:
>-- 
>2.35.3
>