#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.
* 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 };
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[] = {
#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),