]> git.neil.brown.name Git - lafs-utils.git/commitdiff
lafs: add 'add_device' command
authorNeilBrown <neilb@suse.de>
Sun, 13 Mar 2011 23:12:20 +0000 (10:12 +1100)
committerNeilBrown <neilb@suse.de>
Sun, 13 Mar 2011 23:12:20 +0000 (10:12 +1100)
Signed-off-by: NeilBrown <neilb@suse.de>
tools/lafs.c

index 97c3848be7b41f1785756cd9e16ec32c22730dc3..102732ce8697f564d85ea3981005c00a5c4c0f0c 100644 (file)
@@ -41,6 +41,7 @@
 #include <lafs/lafs.h>
 #include <talloc.h>
 #include <uuid/uuid.h>
+#include "internal.h"
 
 /* This is the global state which is passed around among
  * the various commands.
@@ -636,6 +637,24 @@ after_message:
  * and must be listed in lafs_cmds below.
  */
 
+/* common helper functions... */
+static long long parse_size_print(char *arg, char **error, char *func, char *name)
+{
+       long long rv = parse_size(arg, error);
+       if (*error)
+               printf("%s: %s: %s for %s\n", func, *error, arg, name);
+       return rv;
+}
+static long parse_num_print(char *arg, char **error, char *func, char *name)
+{
+       char *endp;
+       long rv = strtol(arg, &endp, 0);
+       if (!*arg || *endp) {
+               *error = "Not a valid number";
+               printf("%s: %s: %s for %s\n", func, *error, arg, name);
+       }
+       return rv;
+}
 /****** EXIT ******/
 static char help_exit[] = "Exit lafs";
 static struct args args_exit[] = { TERMINAL_ARG };
@@ -791,6 +810,106 @@ static void c_newfs(struct state *st, void **args)
        return;
 }
 
+/****** ADD_DEVICE ******/
+static char help_add_device[] = "Add a device to the current LaFS";
+static struct args args_add_device[] = {
+/*1*/  { "DEVNAME", external, -1, {NULL}, "Device to store filesystem on"},
+/*2*/  { "-file",   external, 0, {NULL}, "Regular file to use like a device"},
+/*3*/  { "-size",   opaque, -1, {NULL}, "Size of regular file (K,M,G prefix allowed)"},
+/*4*/  { "-segsize",opaque, -1, {NULL}, "Segment size for this device"},
+/*5*/  { "-stride", opaque, -1, {NULL}, "Stride (from one member device to next)"},
+/*6*/  { "-width",  opaque, -1, {NULL}, "Width of array in data-devices"},
+/*7*/  { "-usage_inum", opaque, -1, {NULL}, "Inode number for segment-usage file"},
+       TERMINAL_ARG
+};
+static void c_add_device(struct state *st, void **args)
+{
+       long block_bytes, segment_bytes = 0, stride_bytes = 0;
+       int width = 0;
+       long long device_bytes = 0;
+       int usage_inum = 0;
+       char *err = NULL;
+       char *devname = args[1];
+       int fd;
+       struct lafs_device *dev;
+
+       if (!devname) {
+               printf("add_device: No device or file name given to add\n");
+               return;
+       }
+
+       if (st->lafs->blocksize == 0) {
+               printf("add_device: filesystem is not ready for devices"
+                      " - consider \"newfs\".\n");
+               return;
+       }
+       block_bytes = st->lafs->blocksize;
+
+       if (args[3]) {
+               device_bytes = parse_size_print(args[3], &err, "add_device",
+                                          "file size");
+               if (err)
+                       return;
+       }
+       if (args[4]) {
+               segment_bytes = parse_size_print(args[4], &err, "add_device",
+                                          "segment size");
+               if (err)
+                       return;
+       }
+       if (args[5]) {
+               stride_bytes = parse_size_print(args[5], &err, "add_device",
+                                         "stride size");
+               if (err)
+                       return;
+       }
+       if (args[6]) {
+               width = parse_num_print(args[6], &err, "add_device", "width");
+               if (err)
+                       return;
+       }
+       if (args[7]) {
+               usage_inum = parse_num_print(args[7], &err,
+                                            "add_device", "inode number");
+               if (err)
+                       return;
+       }
+
+       fd = open_device(devname, &device_bytes, args[2] != NULL, &err);
+
+       if (fd < 0) {
+               printf("add_device: %s\n", err);
+               free(err);
+               return;
+       }
+
+       err = lafs_validate_geometry(&block_bytes, &segment_bytes,
+                                    &stride_bytes, &width, device_bytes);
+
+       if (err) {
+               printf("add_device: %s\n", err);
+               free(err);
+               return;
+       }
+
+       if (!usage_inum) {
+               printf("FIXME defaulting usage inum to 16 "
+                      "- should check if in-use\n");
+               usage_inum = 16;
+       }
+       dev = lafs_add_device(st->lafs, devname, fd,
+                             segment_bytes / block_bytes,
+                             stride_bytes / block_bytes,
+                             width,
+                             usage_inum);
+       printf("Added device %s at %llu with %llu segments of %llu %dk blocks\n",
+              devname, (unsigned long long)dev->start,
+                      (unsigned long long)dev->segment_count,
+              (unsigned long long)dev->segment_size,
+              st->lafs->blocksize/1024);
+
+}
+
 /****** STORE ******/
 static char help_store[] = "Create a file in the LaFS from an external file";
 static struct args args_store[] = {
@@ -815,6 +934,7 @@ static void c_store(struct state *st, void **args)
 #define CMD(x) {#x, c_##x, args_##x, help_##x}
 static struct cmd lafs_cmds[] = {
        {"?", c_help, args_help, help_help},
+       CMD(add_device),
        CMD(exit),
        CMD(help),
        CMD(newfs),