]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rbd_fuse/rbd-fuse.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / rbd_fuse / rbd-fuse.cc
index 6295097ca7fce5a868943137b012886067960e9c..64398faae40866d787123005d3094bdfadb56b29 100644 (file)
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <string>
 #include <mutex>
+#include <limits.h>
 
 #if defined(__FreeBSD__)
 #include <sys/param.h>
 
 #include "include/compat.h"
 #include "include/rbd/librbd.h"
+#include "include/ceph_assert.h"
+
+#include "common/ceph_argparse.h"
+#include "common/ceph_context.h"
+
+#include "global/global_init.h"
+#include "global/global_context.h"
 
 static int gotrados = 0;
 char *pool_name;
+char *nspace_name;
 char *mount_image_name;
 rados_t cluster;
 rados_ioctx_t ioctx;
@@ -42,8 +51,8 @@ struct rbd_stat {
 };
 
 struct rbd_options {
-       char *ceph_config;
        char *pool_name;
+       char *nspace_name;
        char *image_name;
 };
 
@@ -52,8 +61,9 @@ struct rbd_image {
        struct rbd_image *next;
 };
 struct rbd_image_data {
-    struct rbd_image *images;
-    void *buf;
+       struct rbd_image *images;
+       rbd_image_spec_t *image_specs;
+       size_t image_spec_count;
 };
 struct rbd_image_data rbd_image_data;
 
@@ -65,8 +75,7 @@ struct rbd_openimage {
 #define MAX_RBD_IMAGES         128
 struct rbd_openimage opentbl[MAX_RBD_IMAGES];
 
-struct rbd_options rbd_options = {(char*) "/etc/ceph/ceph.conf", (char*) "rbd",
-                                 NULL};
+struct rbd_options rbd_options = {(char*) "rbd", (char*) "", NULL};
 
 #define rbdsize(fd)    opentbl[fd].rbd_stat.rbd_info.size
 #define rbdblksize(fd) opentbl[fd].rbd_stat.rbd_info.obj_size
@@ -91,10 +100,7 @@ void
 enumerate_images(struct rbd_image_data *data)
 {
        struct rbd_image **head = &data->images;
-       char *ibuf = NULL;
-       size_t ibuf_len = 0;
        struct rbd_image *im, *next;
-       char *ip;
        int ret;
 
        if (*head != NULL) {
@@ -104,45 +110,44 @@ enumerate_images(struct rbd_image_data *data)
                        im = next;
                }
                *head = NULL;
-               free(data->buf);
-               data->buf = NULL;
+               rbd_image_spec_list_cleanup(data->image_specs,
+                                           data->image_spec_count);
+               free(data->image_specs);
+               data->image_specs = NULL;
+               data->image_spec_count = 0;
        }
 
-       ret = rbd_list(ioctx, ibuf, &ibuf_len);
-       if (ret == -ERANGE) {
-               assert(ibuf_len > 0);
-               ibuf = (char*) malloc(ibuf_len);
-               if (!ibuf) {
-                       simple_err("Failed to get ibuf", -ENOMEM);
-                       return;
+       while (true) {
+               ret = rbd_list2(ioctx, data->image_specs,
+                               &data->image_spec_count);
+               if (ret == -ERANGE) {
+                       data->image_specs = static_cast<rbd_image_spec_t *>(
+                               realloc(data->image_specs,
+                                       sizeof(rbd_image_spec_t) * data->image_spec_count));
+               } else if (ret < 0) {
+                       simple_err("Failed to list images", ret);
+               } else {
+                       break;
                }
-       } else if (ret < 0) {
-               simple_err("Failed to get ibuf_len", ret);
-               return;
        }
 
-       ret = rbd_list(ioctx, ibuf, &ibuf_len);
-       if (ret < 0) {
-               simple_err("Failed to populate ibuf", ret);
-               free(ibuf);
-               return;
+       if (*nspace_name != '\0') {
+           fprintf(stderr, "pool/namespace %s/%s: ", pool_name, nspace_name);
+       } else {
+           fprintf(stderr, "pool %s: ", pool_name);
        }
-       assert(ret == (int)ibuf_len);
-
-       fprintf(stderr, "pool %s: ", pool_name);
-       for (ip = ibuf; ip < &ibuf[ibuf_len]; ip += strlen(ip) + 1)  {
+       for (size_t idx = 0; idx < data->image_spec_count; ++idx) {
                if ((mount_image_name == NULL) ||
                    ((strlen(mount_image_name) > 0) &&
-                   (strcmp(ip, mount_image_name) == 0))) {
-                       fprintf(stderr, "%s, ", ip);
+                   (strcmp(data->image_specs[idx].name, mount_image_name) == 0))) {
+                       fprintf(stderr, "%s, ", data->image_specs[idx].name);
                        im = static_cast<rbd_image*>(malloc(sizeof(*im)));
-                       im->image_name = ip;
+                       im->image_name = data->image_specs[idx].name;
                        im->next = *head;
                        *head = im;
                }
        }
        fprintf(stderr, "\n");
-       data->buf = ibuf;
 }
 
 int
@@ -495,6 +500,7 @@ rbdfs_init(struct fuse_conn_info *conn)
                exit(90);
 
        pool_name = rbd_options.pool_name;
+       nspace_name = rbd_options.nspace_name;
        mount_image_name = rbd_options.image_name;
        ret = rados_ioctx_create(cluster, pool_name, &ioctx);
        if (ret < 0)
@@ -502,6 +508,7 @@ rbdfs_init(struct fuse_conn_info *conn)
 #if FUSE_VERSION >= FUSE_MAKE_VERSION(2, 8)
        conn->want |= FUSE_CAP_BIG_WRITES;
 #endif
+       rados_ioctx_set_namespace(ioctx, nspace_name);
        gotrados = 1;
 
        // init's return value shows up in fuse_context.private_data,
@@ -756,10 +763,10 @@ const static struct fuse_operations rbdfs_oper = {
 enum {
        KEY_HELP,
        KEY_VERSION,
-       KEY_CEPH_CONFIG,
-       KEY_CEPH_CONFIG_LONG,
        KEY_RADOS_POOLNAME,
        KEY_RADOS_POOLNAME_LONG,
+       KEY_RADOS_NSPACENAME,
+       KEY_RADOS_NSPACENAME_LONG,
        KEY_RBD_IMAGENAME,
        KEY_RBD_IMAGENAME_LONG
 };
@@ -769,15 +776,16 @@ static struct fuse_opt rbdfs_opts[] = {
        FUSE_OPT_KEY("--help", KEY_HELP),
        FUSE_OPT_KEY("-V", KEY_VERSION),
        FUSE_OPT_KEY("--version", KEY_VERSION),
-       {"-c %s", offsetof(struct rbd_options, ceph_config), KEY_CEPH_CONFIG},
-       {"--configfile=%s", offsetof(struct rbd_options, ceph_config),
-        KEY_CEPH_CONFIG_LONG},
        {"-p %s", offsetof(struct rbd_options, pool_name), KEY_RADOS_POOLNAME},
        {"--poolname=%s", offsetof(struct rbd_options, pool_name),
         KEY_RADOS_POOLNAME_LONG},
+       {"-s %s", offsetof(struct rbd_options, nspace_name), KEY_RADOS_NSPACENAME},
+       {"--namespace=%s", offsetof(struct rbd_options, nspace_name),
+        KEY_RADOS_NSPACENAME_LONG},
        {"-r %s", offsetof(struct rbd_options, image_name), KEY_RBD_IMAGENAME},
        {"--image=%s", offsetof(struct rbd_options, image_name),
        KEY_RBD_IMAGENAME_LONG},
+       FUSE_OPT_END
 };
 
 static void usage(const char *progname)
@@ -788,8 +796,9 @@ static void usage(const char *progname)
 "General options:\n"
 "    -h   --help            print help\n"
 "    -V   --version         print version\n"
-"    -c   --configfile      ceph configuration file [/etc/ceph/ceph.conf]\n"
+"    -c   --conf            ceph configuration file [/etc/ceph/ceph.conf]\n"
 "    -p   --poolname        rados pool name [rbd]\n"
+"    -s   --namespace       rados namespace name []\n"
 "    -r   --image           RBD image name\n"
 "\n", progname);
 }
@@ -810,15 +819,6 @@ static int rbdfs_opt_proc(void *data, const char *arg, int key,
                exit(0);
        }
 
-       if (key == KEY_CEPH_CONFIG) {
-               if (rbd_options.ceph_config != NULL) {
-                       free(rbd_options.ceph_config);
-                       rbd_options.ceph_config = NULL;
-               }
-               rbd_options.ceph_config = strdup(arg+2);
-               return 0;
-       }
-
        if (key == KEY_RADOS_POOLNAME) {
                if (rbd_options.pool_name != NULL) {
                        free(rbd_options.pool_name);
@@ -828,6 +828,15 @@ static int rbdfs_opt_proc(void *data, const char *arg, int key,
                return 0;
        }
 
+       if (key == KEY_RADOS_NSPACENAME) {
+               if (rbd_options.nspace_name != NULL) {
+                       free(rbd_options.nspace_name);
+                       rbd_options.nspace_name = NULL;
+               }
+               rbd_options.nspace_name = strdup(arg+2);
+               return 0;
+       }
+
        if (key == KEY_RBD_IMAGENAME) {
                if (rbd_options.image_name!= NULL) {
                        free(rbd_options.image_name);
@@ -851,36 +860,65 @@ int
 connect_to_cluster(rados_t *pcluster)
 {
        int r;
+       global_init_postfork_start(g_ceph_context);
+       common_init_finish(g_ceph_context);
+       global_init_postfork_finish(g_ceph_context);
 
-       r = rados_create(pcluster, NULL);
+       r = rados_create_with_context(pcluster, g_ceph_context);
        if (r < 0) {
                simple_err("Could not create cluster handle", r);
                return r;
        }
-       rados_conf_parse_env(*pcluster, NULL);
-       r = rados_conf_read_file(*pcluster, rbd_options.ceph_config);
-       if (r < 0) {
-               simple_err("Error reading Ceph config file", r);
-               goto failed_shutdown;
-       }
+
        r = rados_connect(*pcluster);
        if (r < 0) {
                simple_err("Error connecting to cluster", r);
-               goto failed_shutdown;
+               rados_shutdown(*pcluster);
+               return r;
        }
 
        return 0;
-
-failed_shutdown:
-       rados_shutdown(*pcluster);
-       return r;
 }
 
-int main(int argc, char *argv[])
+int main(int argc, const char *argv[])
 {
-       struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+       memset(&rbd_image_data, 0, sizeof(rbd_image_data));
+
+       // librados will filter out -f/-d options from command-line
+       std::map<std::string, bool> filter_args = {
+               {"-f", false},
+               {"-d", false}};
+
+       std::vector<const char*> arg_vector;
+       for (auto idx = 0; idx < argc; ++idx) {
+               auto it = filter_args.find(argv[idx]);
+               if (it != filter_args.end()) {
+                       it->second = true;
+               }
+               arg_vector.push_back(argv[idx]);
+       }
+
+       auto cct = global_init(NULL, arg_vector, CEPH_ENTITY_TYPE_CLIENT,
+                              CODE_ENVIRONMENT_DAEMON,
+                              CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS);
+       g_ceph_context->_conf.set_val_or_die("pid_file", "");
+       g_ceph_context->_conf.set_val_or_die("daemonize", "true");
+
+       if (global_init_prefork(g_ceph_context) < 0) {
+               fprintf(stderr, "Failed to initialize librados\n");
+               exit(1);
+       }
+
+       for (auto& it : filter_args) {
+               if (it.second) {
+                       arg_vector.push_back(it.first.c_str());
+               }
+       }
 
-       if (fuse_opt_parse(&args, &rbd_options, rbdfs_opts, rbdfs_opt_proc) == -1) {
+       struct fuse_args args = FUSE_ARGS_INIT((int)arg_vector.size(),
+                                              (char**)&arg_vector.front());
+       if (fuse_opt_parse(&args, &rbd_options, rbdfs_opts,
+                          rbdfs_opt_proc) == -1) {
                exit(1);
        }