HAMMER - Implement volume-list command
authorStathis Kamperis <beket@dragonflybsd.org>
Fri, 12 Nov 2010 13:52:07 +0000 (15:52 +0200)
committerStathis Kamperis <beket@dragonflybsd.org>
Fri, 12 Nov 2010 16:54:37 +0000 (18:54 +0200)
Dragonfly-bug: <http://bugs.dragonflybsd.org/issue1863>

sbin/hammer/cmd_volume.c
sbin/hammer/hammer.8
sbin/hammer/hammer.c
sbin/hammer/hammer.h
sys/vfs/hammer/hammer.h
sys/vfs/hammer/hammer_ioctl.c
sys/vfs/hammer/hammer_ioctl.h
sys/vfs/hammer/hammer_volume.c

index 020751a..f184469 100644 (file)
@@ -38,6 +38,7 @@
  *
  *   - volume-add: Add new volume to HAMMER filesystem
  *   - volume-del: Remove volume from HAMMER filesystem
+ *   - volume-list: List volumes making up a HAMMER filesystem
  */
 
 #include "hammer.h"
@@ -129,6 +130,59 @@ hammer_cmd_volume_del(char **av, int ac)
 }
 
 /*
+ * volume-list <filesystem>
+ */
+void
+hammer_cmd_volume_list(char **av, int ac)
+{
+       struct hammer_ioc_volume_list ioc;
+       int fd;
+
+       if (ac != 1) {
+               fprintf(stderr, "hammer volume-list <filesystem>\n");
+               exit(1);
+       }
+
+       char *filesystem = av[0];
+
+       fd = open(filesystem, O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr,
+                   "hammer volume-list: unable to access %s: %s\n",
+                   filesystem, strerror(errno));
+               exit(1);
+       }
+
+       /*
+        * volume-list ioctl
+        */
+       bzero(&ioc, sizeof(ioc));
+       ioc.vols = malloc(HAMMER_MAX_VOLUMES *
+                         sizeof(struct hammer_ioc_volume));
+       if (ioc.vols == NULL) {
+               fprintf(stderr,
+                   "hammer volume-list: unable to allocate memory: %s\n",
+                   strerror(errno));
+               exit(1);
+       }
+       ioc.nvols = HAMMER_MAX_VOLUMES;
+
+       if (ioctl(fd, HAMMERIOC_LIST_VOLUMES, &ioc) < 0) {
+               fprintf(stderr, "hammer volume-list ioctl: %s\n",
+                       strerror(errno));
+               free(ioc.vols);
+               exit(1);
+       }
+
+       int i;
+       for (i = 0; i < ioc.nvols; i++)
+               printf("%s\n", ioc.vols[i].device_name);
+
+       free(ioc.vols);
+       close(fd);
+}
+
+/*
  * Check basic volume characteristics.  HAMMER filesystems use a minimum
  * of a 16KB filesystem buffer size.
  *
index 7f4949a..3ca6cd9 100644 (file)
@@ -630,6 +630,10 @@ from the colon-separated list in
 .Pa /etc/fstab
 and
 .Xr mount_hammer 8 .
+.\" ==== volume-list ====
+.It Cm volume-list Ar filesystem
+This command will list the volumes that make up
+.Ar filesystem .
 .\" ==== snapshot ====
 .It Cm snapshot Oo Ar filesystem Oc Ar snapshot-dir
 .It Cm snapshot Ar filesystem Ar snapshot-dir Op Ar note
index b5c7f37..88b51c4 100644 (file)
@@ -440,6 +440,10 @@ main(int ac, char **av)
                hammer_cmd_volume_del(av + 1, ac - 1);
                exit(0);
        }
+       if (strcmp(av[0], "volume-list") == 0) {
+               hammer_cmd_volume_list(av + 1, ac - 1);
+               exit(0);
+       }
 
        uuid_name_lookup(&Hammer_FSType, "DragonFly HAMMER", &status);
        if (status != uuid_s_ok) {
@@ -577,6 +581,7 @@ usage(int exit_code)
                "hammer version-upgrade <filesystem> <version> [force]\n"
                "hammer volume-add <device> <filesystem>\n"
                "hammer volume-del <device> <filesystem>\n"
+               "hammer volume-list <filesystem>\n"
        );
 
        fprintf(stderr, "\nHAMMER utility version 3+ commands:\n");
index 91ca70e..2311a1a 100644 (file)
@@ -116,6 +116,7 @@ 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);
 void hammer_cmd_dedup_simulate(char **av, int ac);
 void hammer_cmd_dedup(char **av, int ac);
 
index 3f8c5a6..d06bcf9 100644 (file)
@@ -1414,6 +1414,8 @@ int hammer_ioc_volume_add(hammer_transaction_t trans, hammer_inode_t ip,
                         struct hammer_ioc_volume *ioc);
 int hammer_ioc_volume_del(hammer_transaction_t trans, hammer_inode_t ip,
                         struct hammer_ioc_volume *ioc);
+int hammer_ioc_volume_list(hammer_transaction_t trans, hammer_inode_t ip,
+                       struct hammer_ioc_volume_list *ioc);
 int hammer_ioc_dedup(hammer_transaction_t trans, hammer_inode_t ip,
                        struct hammer_ioc_dedup *dedup);
 
index dbe7e7f..9bd73c8 100644 (file)
@@ -186,6 +186,10 @@ hammer_ioctl(hammer_inode_t ip, u_long com, caddr_t data, int fflag,
                                            (struct hammer_ioc_volume *)data);
                }
                break;
+       case HAMMERIOC_LIST_VOLUMES:
+               error = hammer_ioc_volume_list(&trans, ip,
+                   (struct hammer_ioc_volume_list *)data);
+               break;
        case HAMMERIOC_ADD_SNAPSHOT:
                if (error == 0) {
                        error = hammer_ioc_add_snapshot(
index 2c8e979..6db417a 100644 (file)
@@ -345,6 +345,11 @@ struct hammer_ioc_volume {
        int64_t                 mem_area_size;
 };
 
+struct hammer_ioc_volume_list {
+       struct hammer_ioc_volume *vols;
+       int nvols;
+};
+
 union hammer_ioc_mrecord_any {
        struct hammer_ioc_mrecord_head  head;
        struct hammer_ioc_mrecord_rec   rec;
@@ -489,6 +494,7 @@ struct hammer_ioc_data {
 #define HAMMERIOC_DEL_VOLUME   _IOWR('h',24,struct hammer_ioc_volume)
 #define HAMMERIOC_DEDUP                _IOWR('h',25,struct hammer_ioc_dedup)
 #define HAMMERIOC_GET_DATA     _IOWR('h',26,struct hammer_ioc_data)
+#define HAMMERIOC_LIST_VOLUMES _IOWR('h',27,struct hammer_ioc_volume_list)
 
 #endif
 
index 212235f..323c31a 100644 (file)
@@ -438,6 +438,40 @@ end:
 }
 
 
+int
+hammer_ioc_volume_list(hammer_transaction_t trans, hammer_inode_t ip,
+    struct hammer_ioc_volume_list *ioc)
+{
+       struct hammer_mount *hmp = trans->hmp;
+       hammer_volume_t volume;
+       int error = 0;
+       int i, cnt, len;
+
+       for (i = 0, cnt = 0; i < HAMMER_MAX_VOLUMES && cnt < ioc->nvols; i++) {
+               volume = hammer_get_volume(hmp, i, &error);
+               if (volume == NULL && error == ENOENT) {
+                       error = 0;
+                       continue;
+               }
+               KKASSERT(volume != NULL && error == 0);
+
+               len = strlen(volume->vol_name) + 1;
+               KKASSERT(len <= MAXPATHLEN);
+
+               error = copyout(volume->vol_name, ioc->vols[cnt].device_name,
+                               len);
+               if (error) {
+                       hammer_rel_volume(volume, 0);
+                       return (error);
+               }
+               cnt++;
+               hammer_rel_volume(volume, 0);
+       }
+       ioc->nvols = cnt;
+
+       return (error);
+}
+
 /*
  * Iterate over all usable L1 entries of the volume and
  * the corresponding L2 entries.