From 98cdb5aaffb9695875cf13e92647277f908f9956 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 9 Sep 2008 23:41:13 +0000 Subject: [PATCH] HAMMER Utilities: MFC work to date. * Better usage tests and usage() summary. * Fix bug when using a remote source specification with the mirror command * Improved PFS commands. --- sbin/hammer/cmd_mirror.c | 25 ++++++--- sbin/hammer/cmd_pseudofs.c | 18 ++++-- sbin/hammer/cmd_softprune.c | 4 +- sbin/hammer/hammer.8 | 133 +++++++++++++++++++++++++++++--------------- sbin/hammer/hammer.c | 9 ++- sbin/hammer/ondisk.c | 5 +- 6 files changed, 130 insertions(+), 64 deletions(-) diff --git a/sbin/hammer/cmd_mirror.c b/sbin/hammer/cmd_mirror.c index 9b2368945f..2e5c003837 100644 --- a/sbin/hammer/cmd_mirror.c +++ b/sbin/hammer/cmd_mirror.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_mirror.c,v 1.9.2.3 2008/08/04 19:41:25 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_mirror.c,v 1.9.2.4 2008/09/09 23:41:13 dillon Exp $ */ #include "hammer.h" @@ -83,7 +83,7 @@ hammer_cmd_mirror_read(char **av, int ac, int streaming) struct timeval bwtv; u_int64_t bwcount; - if (ac > 2) + if (ac == 0 || ac > 2) mirror_usage(1); filesystem = av[0]; @@ -245,7 +245,8 @@ done: if (interrupted) { if (CyclePath) { hammer_set_cycle(&mirror.key_cur, mirror.tid_beg); - fprintf(stderr, "Cyclefile %s updated for continuation\n", CyclePath); + fprintf(stderr, "Cyclefile %s updated for " + "continuation\n", CyclePath); } } else { sync_tid = mrec->update.tid; @@ -337,7 +338,7 @@ hammer_cmd_mirror_write(char **av, int ac) int fd; int n; - if (ac > 2) + if (ac != 1) mirror_usage(1); filesystem = av[0]; @@ -614,7 +615,7 @@ hammer_cmd_mirror_copy(char **av, int ac, int streaming) xav[xac++] = tbuf; } if (streaming) - xav[xac++] = "mirror-read-streaming"; + xav[xac++] = "mirror-read-stream"; else xav[xac++] = "mirror-read"; xav[xac++] = ptr; @@ -712,13 +713,15 @@ read_mrecords(int fd, char *buf, u_int size, hammer_ioc_mrecord_head_t pickup) } if (pickup->signature != HAMMER_IOC_MIRROR_SIGNATURE) { - fprintf(stderr, "read_mrecords: malformed record on pipe, bad signature\n"); + fprintf(stderr, "read_mrecords: malformed record on pipe, " + "bad signature\n"); exit(1); } } if (pickup->rec_size < HAMMER_MREC_HEADSIZE || pickup->rec_size > sizeof(*mrec) + HAMMER_XBUFSIZE) { - fprintf(stderr, "read_mrecords: malformed record on pipe, illegal rec_size\n"); + fprintf(stderr, "read_mrecords: malformed record on pipe, " + "illegal rec_size\n"); exit(1); } @@ -1098,10 +1101,14 @@ static void mirror_usage(int code) { fprintf(stderr, - "hammer mirror-read \n" + "hammer mirror-read [begin-tid]\n" + "hammer mirror-read-stream [begin-tid]\n" "hammer mirror-write \n" "hammer mirror-dump\n" - "hammer mirror-copy [[user@]host:]fs [[user@]host:]fs\n" + "hammer mirror-copy [[user@]host:]" + " [[user@]host:]\n" + "hammer mirror-stream [[user@]host:]" + " [[user@]host:]\n" ); exit(code); } diff --git a/sbin/hammer/cmd_pseudofs.c b/sbin/hammer/cmd_pseudofs.c index 95aeb418df..25039563bd 100644 --- a/sbin/hammer/cmd_pseudofs.c +++ b/sbin/hammer/cmd_pseudofs.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_pseudofs.c,v 1.6.2.2 2008/08/04 19:41:25 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_pseudofs.c,v 1.6.2.3 2008/09/09 23:41:13 dillon Exp $ */ #include "hammer.h" @@ -67,6 +67,10 @@ getpfs(struct hammer_ioc_pseudofs_rw *pfs, const char *path) dirpath = strdup(path); if (strrchr(dirpath, '/')) { *strrchr(dirpath, '/') = 0; + if (strlen(dirpath) == 0) { + free(dirpath); + dirpath = strdup("/"); + } } else { free(dirpath); dirpath = strdup("."); @@ -162,6 +166,9 @@ hammer_cmd_pseudofs_status(char **av, int ac) int i; int fd; + if (ac == 0) + pseudofs_usage(1); + for (i = 0; i < ac; ++i) { printf("%s\t", av[i]); fd = getpfs(&pfs, av[i]); @@ -422,11 +429,14 @@ hammer_cmd_pseudofs_update(char **av, int ac) if (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) == 0) { dump_pfsd(pfs.ondisk); } else { - printf("Unable to retrieve pfs configuration after successful update: %s\n", strerror(errno)); + printf("Unable to retrieve pfs configuration " + "after successful update: %s\n", + strerror(errno)); exit(1); } } else { - printf("Unable to adjust pfs configuration: %s\n", strerror(errno)); + printf("Unable to adjust pfs configuration: %s\n", + strerror(errno)); exit(1); } } @@ -533,7 +543,7 @@ void pseudofs_usage(int code) { fprintf(stderr, - "hammer pfs-status ...\n" + "hammer pfs-status ...\n" "hammer pfs-master [options]\n" "hammer pfs-slave [options]\n" "hammer pfs-update [options]\n" diff --git a/sbin/hammer/cmd_softprune.c b/sbin/hammer/cmd_softprune.c index b2aa898edb..09aaaee01e 100644 --- a/sbin/hammer/cmd_softprune.c +++ b/sbin/hammer/cmd_softprune.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_softprune.c,v 1.6 2008/07/07 00:27:22 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_softprune.c,v 1.6.2.1 2008/09/09 23:41:13 dillon Exp $ */ #include "hammer.h" @@ -386,7 +386,7 @@ void softprune_usage(int code) { fprintf(stderr, "Badly formed prune command, use:\n"); - fprintf(stderr, "hammer prune \n"); + fprintf(stderr, "hammer prune \n"); fprintf(stderr, "hammer prune-everything \n"); exit(code); } diff --git a/sbin/hammer/hammer.8 b/sbin/hammer/hammer.8 index 73f9175544..6443658469 100644 --- a/sbin/hammer/hammer.8 +++ b/sbin/hammer/hammer.8 @@ -30,7 +30,7 @@ .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $DragonFly: src/sbin/hammer/hammer.8,v 1.38.2.4 2008/08/04 19:41:25 dillon Exp $ +.\" $DragonFly: src/sbin/hammer/hammer.8,v 1.38.2.5 2008/09/09 23:41:13 dillon Exp $ .Dd July 27, 2008 .Dt HAMMER 8 .Os @@ -47,7 +47,7 @@ .Op Fl i Ar delay .Op Fl t Ar seconds .Ar command -.Ar [argument ...] +.Op Ar argument ... .Sh DESCRIPTION This manual page documents the .Nm @@ -76,7 +76,12 @@ Specify recursion for those commands which support it. Specify a bandwidth limit in bytes per second for mirroring streams. This option is typically used to prevent batch mirroring operations from loading down the machine. -The bandwidth may be suffixed with 'k', 'm', or 'g' to specify +The bandwidth may be suffixed with +.Sq k , +.Sq m , +or +.Sq g +to specify values in kilobytes, megabytes, and gigabytes per second. .It Fl c Ar cyclefile When pruning and reblocking you can instruction @@ -84,10 +89,10 @@ When pruning and reblocking you can instruction to start at the object id stored in the specified file. If the file does not exist -Nm +.Nm will start at the beginning. If -Nm +.Nm is told to run for a specific period of time and is unable to complete the operation it will write out the current object id so the next run can pick up where it left @@ -118,6 +123,7 @@ Increase verboseness. May be specified multiple times. .Pp The commands are as follows: .Bl -tag -width indent +.\" ==== synctid ==== .It Ar synctid Ar filesystem Op quick Generates a guaranteed, formal 64 bit transaction id representing the current state of the specified @@ -131,6 +137,7 @@ keyword is specified the file system will be soft-synced, meaning that a crash might still undo the state of the file system as of the transaction id returned but any new modifications will occur after the returned transaction id as expected. +.\" ==== bstats ==== .It Ar bstats Op interval Output .Nm HAMMER @@ -139,6 +146,7 @@ Pause .Ar interval seconds between each display. The default interval is one second. +.\" ==== iostats ==== .It Ar iostats Op interval Output .Nm HAMMER @@ -147,10 +155,12 @@ Pause .Ar interval seconds between each display. The default interval is one second. +.\" ==== history ==== .It Ar history Ar path ... Show the modification history for .Nm HAMMER file's inode and data. +.\" ==== show ==== .It Ar show Dump the B-tree. This command needs the .Fl f @@ -158,17 +168,20 @@ flag. .\" .It Ar blockmap .\" Dump the B-tree, record, large-data, and small-data blockmaps, showing .\" physical block assignments and free space percentages. +.\" ==== namekey ==== .It Ar namekey Ar filename Generate a .Nm HAMMER 64 bit directory hash for the specified file name. The low 32 bits are used as an iterator for hash collisions and will be output as 0. +.\" ==== namekey32 ==== .It Ar namekey32 Ar filename Generate the top 32 bits of a .Nm HAMMER 64 bit directory hash for the specified file name. +.\" ==== prune ==== .It Ar prune Ar softlink-dir Prune the file system based on previously created snapshot softlinks. Pruning is the act of deleting file system history. @@ -192,7 +205,6 @@ command. .Pp As a safety measure pruning only occurs if one or more softlinks are found containing the @@ snapshot id extension. -.Pp Currently the scanned softlink directory must contain softlinks pointing to a single .Nm HAMMER @@ -201,6 +213,15 @@ paths. Softlinks must use 20-character (@@0x%016llx) transaction ids, as might be returned from .Dq Nm Ar synctid filesystem . .Pp +Pruning is a per-PFS operation, so a +.Nm HAMMER +file system and each PFS in it have to be pruned separately. +.Pp +Note that pruning a file system may not immediately free-up space, +though typically some space will be freed if a large number of records are +pruned out. The file system must be reblocked to completely recover all +available space. +.Pp Example, lets say your snapshot directory contains the following links: .Bd -literal lrwxr-xr-x 1 root wheel 29 May 31 17:57 snap1 -> @@ -228,14 +249,11 @@ If you then delete the snap2 softlink and rerun the .Ar prune command, history for modifications pertaining to that snapshot would be destroyed. +.\" ==== prune-everything ==== .It Ar prune-everything Ar filesystem This command will remove all historical records from the file system. This directive is not normally used on a production system. -.Pp -Note that pruning a file system may not immediately free-up space, -though typically some space will be freed if a large number of records are -pruned out. The file system must be reblocked to completely recover all -available space. +.\" ==== snapshot ==== .It Ar snapshot Ar snapshot-dir .It Ar snapshot Ar filesystem snapshot-dir Takes a snapshot of the file system either explicitly given by @@ -255,7 +273,8 @@ If .Ar snapshot-dir refers to an existing directory, a default format string of "snap-%Y%d%m-%H%M" is assumed and used as name for the newly created symlink. -Assuming that +.Pp +Example, assuming that .Pa /mysnapshots is on file system .Pa / @@ -278,6 +297,7 @@ would create symlinks similar to: /mysnapshots/obj-2008-06-27 -> /obj@@0x10d2cd05b7270d16 .Ed +.\" ==== reblock ==== .It Ar reblock Ar filesystem Op Ar fill_percentage .It Ar reblock-btree Ar filesystem Op Ar fill_percentage .It Ar reblock-inodes Ar filesystem Op Ar fill_percentage @@ -295,7 +315,9 @@ defragmenting the file system. The default fill percentage is 100% and will cause the file system to be completely defragmented. All specified element types will be reallocated and rewritten. If you wish to quickly free up space instead try specifying -a smaller fill percentage, such as 90% or 80% (the '%' suffix is not needed). +a smaller fill percentage, such as 90% or 80% (the +.Sq % +suffix is not needed). .Pp Since this command may rewrite the entire contents of the disk it is best to do it incrementally from a @@ -311,10 +333,16 @@ It is recommended that separate invocations be used for each data type. B-tree nodes, inodes, and directories are typically the most important elements needing defragmentation. Data can be defragmented over a longer period of time. -.It Ar pfs-status Ar dirpath +.Pp +Reblocking is a per-PFS operation, so a +.Nm HAMMER +file system and each PFS in it have to be reblocked separately. +.\" ==== pfs-status ==== +.It Ar pfs-status Ar dirpath ... Retrieve the mirroring configuration parameters for the specified .Nm HAMMER -file system or pseudo-filesystem. +file systems or pseudo-filesystems. +.\" ==== pfs-master ==== .It Ar pfs-master Ar dirpath Op options Create a pseudo-filesystem (PFS) inside a .Nm HAMMER @@ -327,6 +355,7 @@ The .Ar pfs-master directive creates a PFS that you can read, write, and use as a mirroring source. +.\" ==== pfs-slave ==== .It Ar pfs-slave Ar dirpath Op options Create a pseudo-filesystem (PFS) inside a .Nm HAMMER @@ -355,31 +384,7 @@ A PFS can only be truly destroyed with the .Ar pfs-destroy directive. Removing the softlink will not destroy the underlying PFS. -.It Ar pfs-upgrade Ar dirpath -Upgrade a PFS from slave to master operation. The PFS will be rolled back -to the current end synchronization tid (removing any partial synchronizations), -and will then becomes writable. -.Pp -.Em WARNING! -.Nm HAMMER -currently supports only single masters and using -this command can easily result in file system corruption if you don't -know what you are doing. -.Pp -This directive will refuse to run if any programs have open descriptors -in the PFS, including programs chdir'd into the PFS. -.It Ar pfs-downgrade Ar dirpath -Downgrade a master PFS from master to slave operation. The PFS becomes -read-only and access will be locked to its -.Ar sync-end-tid . -.Pp -This directive will refuse to run if any programs have open descriptors -in the PFS, including programs chdir'd into the PFS. -.It Ar pfs-destroy Ar dirpath -This permanently destroys a PFS. -.Pp -This directive will refuse to run if any programs have open descriptors -in the PFS, including programs chdir'd into the PFS. +.\" ==== pfs-update ==== .It Ar pfs-update Ar dirpath Op options Update the configuration parameters for an existing .Nm HAMMER @@ -409,7 +414,9 @@ Manually modifying this field is dangerous and can result in a broken mirror. .It shared-uuid= Set the shared UUID for this file system. All mirrors must have the same -shared UUID. For safety purposes the mirror-write directives will refuse +shared UUID. For safety purposes the +.Ar mirror-write +directives will refuse to operate on a target with a different shared UUID. .Pp Changing the shared UUID on an existing, non-empty mirroring target, @@ -421,23 +428,60 @@ anywhere else, even on exact copies of the file system. .It label= Set a descriptive label for this file system. .El +.\" ==== pfs-upgrade ==== +.It Ar pfs-upgrade Ar dirpath +Upgrade a PFS from slave to master operation. The PFS will be rolled back +to the current end synchronization tid (removing any partial synchronizations), +and will then becomes writable. +.Pp +.Em WARNING! +.Nm HAMMER +currently supports only single masters and using +this command can easily result in file system corruption if you don't +know what you are doing. +.Pp +This directive will refuse to run if any programs have open descriptors +in the PFS, including programs chdir'd into the PFS. +.\" ==== pfs-downgrade ==== +.It Ar pfs-downgrade Ar dirpath +Downgrade a master PFS from master to slave operation. The PFS becomes +read-only and access will be locked to its +.Ar sync-end-tid . +.Pp +This directive will refuse to run if any programs have open descriptors +in the PFS, including programs chdir'd into the PFS. +.\" ==== pfs-destroy ==== +.It Ar pfs-destroy Ar dirpath +This permanently destroys a PFS. +.Pp +This directive will refuse to run if any programs have open descriptors +in the PFS, including programs chdir'd into the PFS. +.\" ==== mirror-read ==== .It Ar mirror-read Ar filesystem Op Ar Generate a mirroring stream to stdout. The stream ends when the transaction id space has been exhausted. +.\" ==== mirror-read-stream ==== .It Ar mirror-read-stream Ar filesystem Op Ar Generate a mirroring stream to stdout. Upon completion the stream is paused until new data is synced to the master, then resumed. Operation continues until the pipe is broken. -.It Ar mirror-write Ar filesystem Op Ar -Take a mirroring stream on stdin and output it to stdout. +.\" ==== mirror-write ==== +.It Ar mirror-write Ar filesystem +Take a mirroring stream on stdin. .Pp This command will fail if the .Ar shared-uuid configuration field for the two file systems do not match. +.\" ==== mirror-dump ==== .It Ar mirror-dump -A mirror-read can be piped into a mirror-dump to dump an ascii +A +.Ar mirror-read +can be piped into a +.Ar mirror-dump +to dump an ascii representation of the mirroring stream. +.\" ==== mirror-copy ==== .It Ar mirror-copy Ar [[user@]host:]filesystem Ar [[user@]host:]filesystem This is a shortcut which pipes a .Ar mirror-read @@ -460,6 +504,7 @@ If the operation completes successfully the target PFS's will be updated. Note that you must re-chdir into the target PFS to see the updated information. If you do not you will still be in the previous snapshot. +.\" ==== mirror-stream ==== .It Ar mirror-stream Ar [[user@]host:]filesystem Ar [[user@]host:]filesystem This command works similarly to .Ar mirror-copy diff --git a/sbin/hammer/hammer.c b/sbin/hammer/hammer.c index 379d0ceb33..23d557bb56 100644 --- a/sbin/hammer/hammer.c +++ b/sbin/hammer/hammer.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/hammer.c,v 1.33.2.2 2008/08/04 19:41:25 dillon Exp $ + * $DragonFly: src/sbin/hammer/hammer.c,v 1.33.2.3 2008/09/09 23:41:13 dillon Exp $ */ #include "hammer.h" @@ -308,13 +308,16 @@ usage(int exit_code) "hammer bstats [interval]\n" "hammer iostats [interval]\n" "hammer mirror-read [begin-tid]\n" - "hammer mirror-write [file ...]\n" + "hammer mirror-read-stream [begin-tid]\n" + "hammer mirror-write \n" "hammer mirror-dump\n" "hammer mirror-copy [[user@]host:]" " [[user@]host:]\n" + "hammer mirror-stream [[user@]host:]" + " [[user@]host:]\n" "hammer reblock[-btree/inodes/dirs/data] " " [fill_percentage]\n" - "hammer pfs-status \n" + "hammer pfs-status ...\n" "hammer pfs-master [options]\n" "hammer pfs-slave [options]\n" "hammer pfs-update [options]\n" diff --git a/sbin/hammer/ondisk.c b/sbin/hammer/ondisk.c index 2cf8190839..d2e4fbb924 100644 --- a/sbin/hammer/ondisk.c +++ b/sbin/hammer/ondisk.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/ondisk.c,v 1.23.2.1 2008/07/24 05:41:56 dillon Exp $ + * $DragonFly: src/sbin/hammer/ondisk.c,v 1.23.2.2 2008/09/09 23:41:13 dillon Exp $ */ #include @@ -701,7 +701,8 @@ again: assert(layer2->append_off == 0); } if (layer2->zone != zone) { - blockmap->next_offset = (blockmap->next_offset + HAMMER_LARGEBLOCK_SIZE) & ~HAMMER_LARGEBLOCK_MASK64; + blockmap->next_offset = (blockmap->next_offset + HAMMER_LARGEBLOCK_SIZE) & + ~HAMMER_LARGEBLOCK_MASK64; goto again; } -- 2.11.4.GIT