sbin/hammer: Make hammer commands print root volume path
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Sat, 2 Apr 2016 23:34:44 +0000 (08:34 +0900)
committerTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Sun, 3 Apr 2016 03:29:47 +0000 (12:29 +0900)
Base on the change made by the previous commit, this commit adds
the root volume path information (not root volume#) to hammer info
and hammer volume-list commands. hammer volume-list shows the path
only on -v. This enables users to explicitly know the root volume.

 [A] The existing /sbin/hammer
 # hammer -v volume-list /HAMMER
 /dev/da1
 /dev/da2
 /dev/da3
 # hammer info /HAMMER | grep Root
         Root Volume         0

 [B] With this commit
 # ./hammer -v volume-list /HAMMER
 0       /dev/da1 (Root Volume)
 1       /dev/da2
 2       /dev/da3
 # hammer info /HAMMER | grep Root
         Root Volume         /dev/da1

sbin/hammer/cmd_info.c
sbin/hammer/cmd_volume.c
sbin/hammer/hammer.8
sbin/hammer/hammer.c
sbin/hammer/hammer.h
sbin/hammer/misc.c

index b6934db..018efe2 100644 (file)
@@ -87,6 +87,7 @@ show_info(char *path)
        int64_t     totalbytes, freebytes;
        char        *fsid;
        char        buf[6];
+       char        rootvol[MAXPATHLEN];
 
        fsid = NULL;
        usedbigblocks = 0;
@@ -102,11 +103,17 @@ show_info(char *path)
        /* Find out the UUID strings */
        uuid_to_string(&fip->vol_fsid, &fsid, NULL);
 
+       /* Get the root volume path */
+       if (hammer_fs_to_rootvol(path, rootvol, sizeof(rootvol)) == -1) {
+               fprintf(stderr, "Failed to get root volume path\n");
+               exit(1);
+       }
+
        /* Volume information */
        fprintf(stdout, "Volume identification\n");
        fprintf(stdout, "\tLabel               %s\n", fip->vol_name);
        fprintf(stdout, "\tNo. Volumes         %d\n", fip->nvolumes);
-       fprintf(stdout, "\tRoot Volume         %d\n", fip->rootvol);
+       fprintf(stdout, "\tRoot Volume         %s\n", rootvol);
        fprintf(stdout, "\tFSID                %s\n", fsid);
        fprintf(stdout, "\tHAMMER Version      %d\n", fip->version);
 
index 48266ea..e83319d 100644 (file)
@@ -141,72 +141,66 @@ hammer_cmd_volume_del(char **av, int ac)
        close(fd);
 }
 
-static void
-hammer_print_volumes(char **av, int ac, const char *cmd, const char sep)
+/*
+ * volume-list <filesystem>
+ */
+void
+hammer_cmd_volume_list(char **av, int ac)
 {
        struct hammer_ioc_volume_list ioc;
-       int fd;
-       int i;
-       const char *filesystem;
+       char *device_name;
+       int vol_no, i;
 
-       if (ac != 1) {
-               fprintf(stderr, "hammer %s <filesystem>\n", cmd);
+       if (ac < 1) {
+               fprintf(stderr, "hammer volume-list <filesystem>\n");
                exit(1);
        }
 
-       filesystem = av[0];
-
-       fd = open(filesystem, O_RDONLY);
-       if (fd < 0) {
-               fprintf(stderr,
-                   "hammer %s: unable to access %s: %s\n",
-                   cmd, filesystem, strerror(errno));
+       if (hammer_fs_to_vol(av[0], &ioc) == -1) {
+               fprintf(stderr, "hammer volume-list: failed\n");
                exit(1);
        }
 
-       bzero(&ioc, sizeof(ioc));
-       ioc.vols = malloc(HAMMER_MAX_VOLUMES *
-                         sizeof(struct hammer_ioc_volume));
-       if (ioc.vols == NULL) {
-               fprintf(stderr,
-                   "hammer %s: unable to allocate memory: %s\n",
-                   cmd, strerror(errno));
+       for (i = 0; i < ioc.nvols; i++) {
+               device_name = ioc.vols[i].device_name;
+               vol_no = ioc.vols[i].vol_no;
+               if (VerboseOpt) {
+                       printf("%d\t%s%s\n", vol_no, device_name,
+                               (vol_no == HAMMER_ROOT_VOLNO ?
+                               " (Root Volume)" : ""));
+               } else {
+                       printf("%s\n", device_name);
+               }
+       }
+
+       free(ioc.vols);
+}
+
+/*
+ * volume-blkdevs <filesystem>
+ */
+void
+hammer_cmd_volume_blkdevs(char **av, int ac)
+{
+       struct hammer_ioc_volume_list ioc;
+       int i;
+
+       if (ac < 1) {
+               fprintf(stderr, "hammer volume-blkdevs <filesystem>\n");
                exit(1);
        }
-       ioc.nvols = HAMMER_MAX_VOLUMES;
 
-       if (ioctl(fd, HAMMERIOC_LIST_VOLUMES, &ioc) < 0) {
-               fprintf(stderr, "hammer %s ioctl: %s\n",
-                       cmd, strerror(errno));
-               free(ioc.vols);
+       if (hammer_fs_to_vol(av[0], &ioc) == -1) {
+               fprintf(stderr, "hammer volume-list: failed\n");
                exit(1);
        }
 
        for (i = 0; i < ioc.nvols; i++) {
                printf("%s", ioc.vols[i].device_name);
                if (i != ioc.nvols - 1)
-                       printf("%c", sep);
+                       printf(":");
        }
        printf("\n");
 
        free(ioc.vols);
-       close(fd);
-}
-
-/*
- * volume-list <filesystem>
- */
-void
-hammer_cmd_volume_list(char **av, int ac, const char *cmd)
-{
-       hammer_print_volumes(av, ac, cmd, '\n');
-}
-
-/*
- * volume-blkdevs <filesystem>
- */
-void
-hammer_cmd_volume_blkdevs(char **av, int ac, const char *cmd)
-{
-       hammer_print_volumes(av, ac, cmd, ':');
 }
index 2287e49..1967938 100644 (file)
@@ -807,6 +807,9 @@ filesystem before it attempts to remove the volume if the volume is not empty.
 .It Cm volume-list Ar filesystem
 List the volumes that make up
 .Ar filesystem .
+If -v is specified the command shows volume number for each volume as well as
+.Ar root-volume
+information.
 .\" ==== volume-blkdevs ====
 .It Cm volume-blkdevs Ar filesystem
 List the volumes that make up
index 793ec0d..dbdd15d 100644 (file)
@@ -519,11 +519,11 @@ main(int ac, char **av)
                exit(0);
        }
        if (strcmp(av[0], "volume-list") == 0) {
-               hammer_cmd_volume_list(av + 1, ac - 1, av[0]);
+               hammer_cmd_volume_list(av + 1, ac - 1);
                exit(0);
        }
        if (strcmp(av[0], "volume-blkdevs") == 0) {
-               hammer_cmd_volume_blkdevs(av + 1, ac - 1, av[0]);
+               hammer_cmd_volume_blkdevs(av + 1, ac - 1);
                exit(0);
        }
 
index 3679b90..adf9e4b 100644 (file)
@@ -119,8 +119,8 @@ void hammer_cmd_get_version(char **av, int ac);
 void hammer_cmd_set_version(char **av, int ac);
 void hammer_cmd_volume_add(char **av, int ac);
 void hammer_cmd_volume_del(char **av, int ac);
-void hammer_cmd_volume_list(char **av, int ac, const char *cmd);
-void hammer_cmd_volume_blkdevs(char **av, int ac, const char *cmd);
+void hammer_cmd_volume_list(char **av, int ac);
+void hammer_cmd_volume_blkdevs(char **av, int ac);
 void hammer_cmd_dedup_simulate(char **av, int ac);
 void hammer_cmd_dedup(char **av, int ac);
 void hammer_cmd_abort_cleanup(char **av, int ac);
@@ -133,6 +133,8 @@ int getpfs(struct hammer_ioc_pseudofs_rw *pfs, char *path);
 void relpfs(int fd, struct hammer_ioc_pseudofs_rw *pfs);
 void dump_pfsd(hammer_pseudofs_data_t, int);
 void hammer_check_restrict(const char *path);
+int hammer_fs_to_vol(const char *fs, struct hammer_ioc_volume_list *iocp);
+int hammer_fs_to_rootvol(const char *fs, char *buf, int len);
 void hammer_softprune_scandir(struct softprune **basep,
                          struct hammer_ioc_prune *template,
                          const char *dirname);
index f686cfa..a340d8c 100644 (file)
@@ -197,6 +197,59 @@ hammer_check_restrict(const char *filesystem)
        }
 }
 
+int hammer_fs_to_vol(const char *fs, struct hammer_ioc_volume_list *p)
+{
+       struct hammer_ioc_volume_list ioc;
+       int fd;
+
+       fd = open(fs, O_RDONLY);
+       if (fd < 0) {
+               perror("open");
+               return(-1);
+       }
+
+       bzero(&ioc, sizeof(ioc));
+       ioc.nvols = HAMMER_MAX_VOLUMES;
+       ioc.vols = malloc(ioc.nvols * sizeof(*ioc.vols));
+       if (ioc.vols == NULL) {
+               perror("malloc");
+               close(fd);
+               return(-1);
+       }
+
+       if (ioctl(fd, HAMMERIOC_LIST_VOLUMES, &ioc) < 0) {
+               perror("ioctl");
+               close(fd);
+               free(ioc.vols);
+               return(-1);
+       }
+
+       bcopy(&ioc, p, sizeof(ioc));
+       close(fd);
+
+       return(0);
+}
+
+int hammer_fs_to_rootvol(const char *fs, char *buf, int len)
+{
+       struct hammer_ioc_volume_list ioc;
+       int i;
+
+       if (hammer_fs_to_vol(fs, &ioc) == -1)
+               return(-1);
+
+       for (i = 0; i < ioc.nvols; i++) {
+               if (ioc.vols[i].vol_no == HAMMER_ROOT_VOLNO) {
+                       strlcpy(buf, ioc.vols[i].device_name, len);
+                       break;
+               }
+       }
+       assert(i != ioc.nvols);  /* root volume must exist */
+
+       free(ioc.vols);
+       return(0);
+}
+
 /*
  * Functions and data structure for zone statistics
  */