]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: expose options available to rbd map
authorIlya Dryomov <ilya.dryomov@inktank.com>
Fri, 27 Dec 2013 17:40:59 +0000 (19:40 +0200)
committerJosh Durgin <josh.durgin@inktank.com>
Fri, 27 Dec 2013 17:56:24 +0000 (09:56 -0800)
Add a -o / --options option, which would allow users to specify
rbd-specific and generic ceph client and osd options available at
mapping time in a comma separated list (similar to mount(8) mount
options).

Exposed options are:

- fsid=%s
- ip=%s
- share
- noshare
- crc
- nocrc
- osdkeepalive=%d
- osd_idle_ttl=%d
- rw
- ro (equivalent to existing --read-only flag)

The rw/ro < 3.7 kernels compatibility kludge added in commit
fb0f1986449b is preserved.

Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
doc/man/8/rbd.rst
man/rbd.8
src/rbd.cc
src/test/cli/rbd/help.t

index 8370d4d2de37a8cb43273ed3148f23475bfdd0c5..215aa9204e695fd8a89ceabe008bc7b0784a2989 100644 (file)
@@ -113,9 +113,15 @@ Parameters
 
    Make json or xml formatted output more human-readable.
 
+.. option:: -o map-options, --options map-options
+
+   Specifies which options to use when mapping an image.  map-options is
+   a comma-separated string of options (similar to mount(8) mount options).
+   See map options section below for more details.
+
 .. option:: --read-only
 
-   Set device readonly when mapping image.
+   Map the image read-only.  Equivalent to -o ro.
 
 
 Commands
@@ -235,7 +241,7 @@ Commands
 
   This requires image format 2.
 
-:command:`map` [*image-name*]
+:command:`map` [*image-name*] [-o | --options *map-options* ] [--read-only]
   Maps the specified image to a block device via the rbd kernel module.
 
 :command:`unmap` [*device-path*]
@@ -306,6 +312,35 @@ By default, [*stripe_unit*] is the same as the object size and [*stripe_count*]
 used.
 
 
+Map options
+===========
+
+Most of these options are useful mainly for debugging and benchmarking.  The
+default values are set in the kernel and may therefore depend on the version of
+the running kernel.
+
+* fsid=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee - FSID that should be assumed by
+  the client.
+
+* ip=a.b.c.d[:p] - IP and, optionally, port the client should use.
+
+* share - Enable sharing of client instances with other mappings (default).
+
+* noshare - Disable sharing of client instances with other mappings.
+
+* crc - Enable CRC32C checksumming for data writes (default).
+
+* nocrc - Disable CRC32C checksumming for data writes.
+
+* osdkeepalive=x - OSD keepalive timeout (default is 5 seconds).
+
+* osd_idle_ttl=x - OSD idle TTL (default is 60 seconds).
+
+* rw - Map the image read-write (default).
+
+* ro - Map the image read-only.  Equivalent to --read-only.
+
+
 Examples
 ========
 
index 59fbf52ca2fb7355d526bb12029fac3ed85e5361..910f19cf52bffccecc51da4dbc6c32df97100586 100644 (file)
--- a/man/rbd.8
+++ b/man/rbd.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD" "8" "December 09, 2013" "dev" "Ceph"
+.TH "RBD" "8" "December 27, 2013" "dev" "Ceph"
 .SH NAME
 rbd \- manage rados block device (RBD) images
 .
@@ -177,8 +177,15 @@ Make json or xml formatted output more human\-readable.
 .UNINDENT
 .INDENT 0.0
 .TP
+.B \-o map\-options, \-\-options map\-options
+Specifies which options to use when mapping an image.  map\-options is
+a comma\-separated string of options (similar to mount(8) mount options).
+See map options section below for more details.
+.UNINDENT
+.INDENT 0.0
+.TP
 .B \-\-read\-only
-Set device readonly when mapping image.
+Map the image read\-only.  Equivalent to \-o ro.
 .UNINDENT
 .SH COMMANDS
 .INDENT 0.0
@@ -295,7 +302,7 @@ in different pools than the parent snapshot.)
 .sp
 This requires image format 2.
 .TP
-.B \fBmap\fP [\fIimage\-name\fP]
+.B \fBmap\fP [\fIimage\-name\fP] [\-o | \-\-options \fImap\-options\fP ] [\-\-read\-only]
 Maps the specified image to a block device via the rbd kernel module.
 .TP
 .B \fBunmap\fP [\fIdevice\-path\fP]
@@ -381,6 +388,34 @@ The striping is controlled by three parameters:
 By default, [\fIstripe_unit\fP] is the same as the object size and [\fIstripe_count\fP] is 1.  Specifying a different
 [\fIstripe_unit\fP] requires that the STRIPINGV2 feature be supported (added in Ceph v0.53) and format 2 images be
 used.
+.SH MAP OPTIONS
+.sp
+Most of these options are useful mainly for debugging and benchmarking.  The
+default values are set in the kernel and may therefore depend on the version of
+the running kernel.
+.INDENT 0.0
+.IP \(bu 2
+fsid=aaaaaaaa\-bbbb\-cccc\-dddd\-eeeeeeeeeeee \- FSID that should be assumed by
+the client.
+.IP \(bu 2
+ip=a.b.c.d[:p] \- IP and, optionally, port the client should use.
+.IP \(bu 2
+share \- Enable sharing of client instances with other mappings (default).
+.IP \(bu 2
+noshare \- Disable sharing of client instances with other mappings.
+.IP \(bu 2
+crc \- Enable CRC32C checksumming for data writes (default).
+.IP \(bu 2
+nocrc \- Disable CRC32C checksumming for data writes.
+.IP \(bu 2
+osdkeepalive=x \- OSD keepalive timeout (default is 5 seconds).
+.IP \(bu 2
+osd_idle_ttl=x \- OSD idle TTL (default is 60 seconds).
+.IP \(bu 2
+rw \- Map the image read\-write (default).
+.IP \(bu 2
+ro \- Map the image read\-only.  Equivalent to \-\-read\-only.
+.UNINDENT
 .SH EXAMPLES
 .sp
 To create a new rbd image that is 100 GB:
index 6a8e6029a262dd03887e56702c1c1f609489809f..2e87b62664d85967f54bf691a8efa207c8f641ec 100644 (file)
@@ -70,7 +70,8 @@ static string dir_info_oid = RBD_INFO;
 bool udevadm_settle = true;
 bool progress = true;
 bool resize_allow_shrink = false;
-bool read_only = false;
+
+map<string, string> map_options; // -o / --options map
 
 #define dout_subsys ceph_subsys_rbd
 
@@ -154,6 +155,7 @@ void usage()
 "  --pretty-format                    make json or xml output more readable\n"
 "  --no-settle                        do not wait for udevadm to settle on map/unmap\n"
 "  --no-progress                      do not show progress for long-running commands\n"
+"  -o, --options <map-options>        options to use when mapping an image\n"
 "  --read-only                        set device readonly when mapping image\n"
 "  --allow-shrink                     allow shrinking of an image when resizing\n";
 }
@@ -1649,13 +1651,8 @@ static int do_kernel_add(const char *poolname, const char *imgname,
       oss << ",";
   }
 
-  if (read_only)
-    oss << " ro,";
-  else
-    oss << " ";
-
   const char *user = g_conf->name.get_id().c_str();
-  oss << "name=" << user;
+  oss << " name=" << user;
 
   char key_name[strlen(user) + strlen("client.") + 1];
   snprintf(key_name, sizeof(key_name), "client.%s", user);
@@ -1691,6 +1688,18 @@ static int do_kernel_add(const char *poolname, const char *imgname,
     oss << ",key=" << key_name;
   }
 
+  for (map<string, string>::const_iterator it = map_options.begin();
+       it != map_options.end();
+       ++it) {
+    // for compatibility with < 3.7 kernels, assume that rw is on by
+    // default and omit it even if it was specified by the user
+    // (see ceph.git commit fb0f1986449b)
+    if (it->first == "rw" && it->second == "rw")
+      continue;
+
+    oss << "," << it->second;
+  }
+
   oss << " " << poolname << " " << imgname;
 
   if (snapname) {
@@ -2056,6 +2065,109 @@ static int do_kernel_rm(const char *dev)
   return r;
 }
 
+static string map_option_uuid_cb(const char *value_char)
+{
+  uuid_d u;
+  if (!u.parse(value_char))
+    return "";
+
+  ostringstream oss;
+  oss << u;
+  return oss.str();
+}
+
+static string map_option_ip_cb(const char *value_char)
+{
+  entity_addr_t a;
+  const char *endptr;
+  if (!a.parse(value_char, &endptr) ||
+      endptr != value_char + strlen(value_char)) {
+    return "";
+  }
+
+  ostringstream oss;
+  oss << a.addr;
+  return oss.str();
+}
+
+static string map_option_int_cb(const char *value_char)
+{
+  string err;
+  int d = strict_strtol(value_char, 10, &err);
+  if (!err.empty() || d < 0)
+    return "";
+
+  ostringstream oss;
+  oss << d;
+  return oss.str();
+}
+
+static void put_map_option(const string key, string val)
+{
+  map<string, string>::const_iterator it = map_options.find(key);
+  if (it != map_options.end()) {
+    cerr << "rbd: warning: redefining map option " << key << ": '"
+         << it->second << "' -> '" << val << "'" << std::endl;
+  }
+  map_options[key] = val;
+}
+
+static int put_map_option_value(const string opt, const char *value_char,
+                                string (*parse_cb)(const char *))
+{
+  if (!value_char || *value_char == '\0') {
+    cerr << "rbd: " << opt << " option requires a value" << std::endl;
+    return 1;
+  }
+
+  string value = parse_cb(value_char);
+  if (value.empty()) {
+    cerr << "rbd: invalid " << opt << " value '" << value_char << "'"
+         << std::endl;
+    return 1;
+  }
+
+  put_map_option(opt, opt + "=" + value);
+  return 0;
+}
+
+static int parse_map_options(char *options)
+{
+  for (char *this_char = strtok(options, ", ");
+       this_char != NULL;
+       this_char = strtok(NULL, ",")) {
+    char *value_char;
+
+    if ((value_char = strchr(this_char, '=')) != NULL)
+      *value_char++ = '\0';
+
+    if (!strcmp(this_char, "fsid")) {
+      if (put_map_option_value("fsid", value_char, map_option_uuid_cb))
+        return 1;
+    } else if (!strcmp(this_char, "ip")) {
+      if (put_map_option_value("ip", value_char, map_option_ip_cb))
+        return 1;
+    } else if (!strcmp(this_char, "share") || !strcmp(this_char, "noshare")) {
+      put_map_option("share", this_char);
+    } else if (!strcmp(this_char, "crc") || !strcmp(this_char, "nocrc")) {
+      put_map_option("crc", this_char);
+    } else if (!strcmp(this_char, "osdkeepalive")) {
+      if (put_map_option_value("osdkeepalive", value_char, map_option_int_cb))
+        return 1;
+    } else if (!strcmp(this_char, "osd_idle_ttl")) {
+      if (put_map_option_value("osd_idle_ttl", value_char, map_option_int_cb))
+        return 1;
+    } else if (!strcmp(this_char, "rw") || !strcmp(this_char, "ro")) {
+      put_map_option("rw", this_char);
+    } else {
+      cerr << "rbd: unknown map option '" << this_char << "'" << std::endl;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
 enum {
   OPT_NO_CMD = 0,
   OPT_LIST,
@@ -2291,8 +2403,15 @@ int main(int argc, const char **argv)
       lock_tag = strdup(val.c_str());
     } else if (ceph_argparse_flag(args, i, "--no-settle", (char *)NULL)) {
       udevadm_settle = false;
+    } else if (ceph_argparse_witharg(args, i, &val, "-o", "--options", (char*)NULL)) {
+      char *map_options = strdup(val.c_str());
+      if (parse_map_options(map_options)) {
+        cerr << "rbd: couldn't parse map options" << std::endl;
+        return EXIT_FAILURE;
+      }
     } else if (ceph_argparse_flag(args, i, "--read-only", (char *)NULL)) {
-      read_only = true;
+      // --read-only is equivalent to -o ro
+      put_map_option("rw", "ro");
     } else if (ceph_argparse_flag(args, i, "--no-progress", (char *)NULL)) {
       progress = false;
     } else if (ceph_argparse_flag(args, i , "--allow-shrink", (char *)NULL)) {
index 754e11f9357062c0a055ce75cd91d1e86bf9b703..5723bef8417b95c458feeb387de70db924cd24c6 100644 (file)
@@ -76,5 +76,6 @@
     --pretty-format                    make json or xml output more readable
     --no-settle                        do not wait for udevadm to settle on map/unmap
     --no-progress                      do not show progress for long-running commands
+    -o, --options <map-options>        options to use when mapping an image
     --read-only                        set device readonly when mapping image
     --allow-shrink                     allow shrinking of an image when resizing