From e914c91d6da07b3c7540200e787d9a95159b611f Mon Sep 17 00:00:00 2001 From: Stathis Kamperis Date: Fri, 12 Nov 2010 15:52:07 +0200 Subject: [PATCH 1/1] HAMMER - Implement volume-list command Dragonfly-bug: --- sbin/hammer/cmd_volume.c | 54 ++++++++++++++++++++++++++++++++++ sbin/hammer/hammer.8 | 4 +++ sbin/hammer/hammer.c | 5 ++++ sbin/hammer/hammer.h | 1 + sys/vfs/hammer/hammer.h | 2 ++ sys/vfs/hammer/hammer_ioctl.c | 4 +++ sys/vfs/hammer/hammer_ioctl.h | 6 ++++ sys/vfs/hammer/hammer_volume.c | 34 +++++++++++++++++++++ 8 files changed, 110 insertions(+) diff --git a/sbin/hammer/cmd_volume.c b/sbin/hammer/cmd_volume.c index 020751a37a..f1844691f4 100644 --- a/sbin/hammer/cmd_volume.c +++ b/sbin/hammer/cmd_volume.c @@ -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" @@ -128,6 +129,59 @@ hammer_cmd_volume_del(char **av, int ac) close(fd); } +/* + * volume-list + */ +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 \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. diff --git a/sbin/hammer/hammer.8 b/sbin/hammer/hammer.8 index 7f4949a0cf..3ca6cd99ca 100644 --- a/sbin/hammer/hammer.8 +++ b/sbin/hammer/hammer.8 @@ -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 diff --git a/sbin/hammer/hammer.c b/sbin/hammer/hammer.c index b5c7f37529..88b51c441e 100644 --- a/sbin/hammer/hammer.c +++ b/sbin/hammer/hammer.c @@ -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 [force]\n" "hammer volume-add \n" "hammer volume-del \n" + "hammer volume-list \n" ); fprintf(stderr, "\nHAMMER utility version 3+ commands:\n"); diff --git a/sbin/hammer/hammer.h b/sbin/hammer/hammer.h index 91ca70e2c8..2311a1a879 100644 --- a/sbin/hammer/hammer.h +++ b/sbin/hammer/hammer.h @@ -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); diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index 3f8c5a68da..d06bcf952a 100644 --- a/sys/vfs/hammer/hammer.h +++ b/sys/vfs/hammer/hammer.h @@ -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); diff --git a/sys/vfs/hammer/hammer_ioctl.c b/sys/vfs/hammer/hammer_ioctl.c index dbe7e7f79d..9bd73c8f10 100644 --- a/sys/vfs/hammer/hammer_ioctl.c +++ b/sys/vfs/hammer/hammer_ioctl.c @@ -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( diff --git a/sys/vfs/hammer/hammer_ioctl.h b/sys/vfs/hammer/hammer_ioctl.h index 2c8e979ceb..6db417a1cc 100644 --- a/sys/vfs/hammer/hammer_ioctl.h +++ b/sys/vfs/hammer/hammer_ioctl.h @@ -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 diff --git a/sys/vfs/hammer/hammer_volume.c b/sys/vfs/hammer/hammer_volume.c index 212235f9f5..323c31ad87 100644 --- a/sys/vfs/hammer/hammer_volume.c +++ b/sys/vfs/hammer/hammer_volume.c @@ -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. -- 2.41.0