HAMMER Utilities: Feature add
authorMatthew Dillon <dillon@dragonflybsd.org>
Tue, 13 May 2008 20:49:34 +0000 (20:49 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Tue, 13 May 2008 20:49:34 +0000 (20:49 +0000)
Add a new command 'synctid <filesystem>' which provides a formal transaction
id representing the state of the filesystem as of when it is called.  The
filesystem will be properly synced by the command and an interlocked
timestamp will be returned.

Remove the -x option, remove the calls to sync() by the 'now' and 'now64'
directives.  No longer sleep for one second in 'now'.  Document that these
directives do not return a guaranteed transaction id.

sbin/hammer/Makefile
sbin/hammer/cmd_synctid.c [copied from sbin/hammer/hammer.h with 60% similarity]
sbin/hammer/hammer.8
sbin/hammer/hammer.c
sbin/hammer/hammer.h

index 88b14ee..a9519b0 100644 (file)
@@ -1,10 +1,10 @@
 #
-# $DragonFly: src/sbin/hammer/Makefile,v 1.10 2008/05/11 20:44:44 dillon Exp $
+# $DragonFly: src/sbin/hammer/Makefile,v 1.11 2008/05/13 20:49:34 dillon Exp $
 
 PROG=  hammer
 SRCS=  hammer.c ondisk.c blockmap.c cache.c misc.c cycle.c \
        cmd_show.c cmd_prune.c cmd_history.c cmd_blockmap.c \
-       cmd_reblock.c
+       cmd_reblock.c cmd_synctid.c
 MAN=   hammer.8
 
 CFLAGS+= -I${.CURDIR}/../../sys -DALIST_NO_DEBUG
similarity index 60%
copy from sbin/hammer/hammer.h
copy to sbin/hammer/cmd_synctid.c
index 000d1a2..2da8aa0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
+ * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
  * 
  * This code is derived from software contributed to The DragonFly Project
  * by Matthew Dillon <dillon@backplane.com>
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sbin/hammer/hammer.h,v 1.11 2008/05/12 05:13:48 dillon Exp $
+ * $DragonFly: src/sbin/hammer/cmd_synctid.c,v 1.1 2008/05/13 20:49:34 dillon Exp $
  */
 
-#include <sys/types.h>
-#include <sys/diskslice.h>
-#include <sys/diskmbr.h>
-#include <sys/stat.h>
-#include <sys/time.h>
+#include "hammer.h"
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <err.h>
-#include <ctype.h>
-#include <dirent.h>
+static void synctid_usage(int exit_code);
 
-#include "hammer_util.h"
-#include <vfs/hammer/hammer_ioctl.h>
+/*
+ * synctid <filesystem> [quick]
+ */
+void
+hammer_cmd_synctid(char **av, int ac)
+{
+       struct hammer_ioc_synctid synctid;
+       const char *filesystem;
+       int fd;
 
-extern int RecurseOpt;
-extern int VerboseOpt;
-extern const char *LinkPath;
-extern const char *CyclePath;
+       bzero(&synctid, sizeof(synctid));
+       synctid.op = HAMMER_SYNCTID_SYNC2;
 
-void hammer_cmd_show(hammer_tid_t node_offset, int depth,
-               hammer_base_elm_t left_bound, hammer_base_elm_t right_bound);
-void hammer_cmd_prune(char **av, int ac);
-void hammer_cmd_history(const char *offset_str, char **av, int ac);
-void hammer_cmd_blockmap(void);
-void hammer_cmd_reblock(char **av, int ac, int flags);
+       if (ac == 0 || ac > 2)
+               synctid_usage(1);
+       filesystem = av[0];
+       if (ac == 2) {
+               if (strcmp(av[1], "quick") == 0)
+                       synctid.op = HAMMER_SYNCTID_SYNC1;
+               else
+                       synctid_usage(1);
+       }
+       fd = open(filesystem, O_RDONLY);
+       if (fd < 0)
+               err(1, "Unable to open %s", filesystem);
+       if (ioctl(fd, HAMMERIOC_SYNCTID, &synctid) < 0) {
+               fprintf(stderr, "Synctid %s failed: %s\n", filesystem, strerror(errno));
+       } else {
+               printf("0x%016llx\n", synctid.tid);
+       }
+       close(fd);
+}
 
-int64_t hammer_get_cycle(int64_t default_obj_id);
-void hammer_set_cycle(int64_t obj_id);
-void hammer_reset_cycle(void);
+static
+void
+synctid_usage(int exit_code)
+{
+       fprintf(stderr, "hammer synctid <filesystem> [quick]\n");
+       exit(exit_code);
+}
 
index 53b11cb..87dabf2 100644 (file)
@@ -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.15 2008/05/12 05:13:47 dillon Exp $
+.\" $DragonFly: src/sbin/hammer/hammer.8,v 1.16 2008/05/13 20:49:34 dillon Exp $
 .Dd December 31, 2007
 .Dt HAMMER 8
 .Os
@@ -76,10 +76,6 @@ certain period of time.  This option is used along with the cycle file
 option to prune or reblock a portion of the filesystem incrementally.
 .It Fl v
 Increase verboseness.  May be specified multiple times.
-.It Fl x
-Do not call sync() when running commands which sync() by default.
-Timestamp commands such as 'hammer now' sync() by default.  This also
-disables any sleeps the timestamp commands would otherwise perform.
 .El
 .Pp
 The commands are as follows:
@@ -87,17 +83,16 @@ The commands are as follows:
 .It Ar now
 Generate a timestamp suitable for use in the @@ filename extension,
 representing right now.
-Unless
-.Fl x
-is specified, this command will automatically sync() and
-wait for the seconds hand to turn over (sleep for up to one second) prior
-to generating a seconds-denominated timestamp.
 .It Ar now64
 Generate a full 64 bit timestamp.
-Unless
-.Fl x
-is specified, this command will automatically sync(), but not sleep,
-prior to generating the timestamp.
+The
+.Ar now
+and
+.Ar now64
+directives do not generate a guaranteed transaction id.
+Please use the
+.Nm Ar synctid
+command to generate a guaranteed transaction id.
 .It Ar stamp
 Generate a timestamp suitable for use in the @@ filename extension.
 This command does not sync() or sleep and care should be taken if
@@ -112,6 +107,17 @@ if you wish to specify the time by some other means.
 Same as the
 .Ar stamp
 command but generates a 64 bit timestamp.
+.It Ar synctid Ar filesystem Op quick
+Generates a guaranteed, formal 64 bit transaction id representing the
+current state of the specified HAMMER filesystem.  The filesystem will
+be synced to the media.
+.Pp
+If the
+.Ar quick
+keyword is specified the filesystem will be soft-synced, meaning that a
+crash might still undo the state of the filesystem as of the transaction
+id returned but any new modifications will occur after the returned
+transaction id as expected.
 .It Ar date
 Output a date equivalent given a transaction id or time stamp.
 .It Ar history Ar path
index 1ccb6b7..5efcf3d 100644 (file)
@@ -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.17 2008/05/12 05:13:48 dillon Exp $
+ * $DragonFly: src/sbin/hammer/hammer.c,v 1.18 2008/05/13 20:49:34 dillon Exp $
  */
 
 #include "hammer.h"
@@ -39,7 +39,6 @@
 #include <math.h>
 
 static void hammer_parsetime(u_int64_t *tidp, const char *timestr);
-static void hammer_waitsync(int dosleep);
 static void hammer_parsedevs(const char *blkdevs);
 static void sigalrm(int signo);
 static void usage(int exit_code);
@@ -60,7 +59,7 @@ main(int ac, char **av)
        u_int32_t status;
        char *blkdevs = NULL;
 
-       while ((ch = getopt(ac, av, "c:dhf:rs:t:vx")) != -1) {
+       while ((ch = getopt(ac, av, "c:dhf:rs:t:v")) != -1) {
                switch(ch) {
                case 'c':
                        CyclePath = optarg;
@@ -86,9 +85,6 @@ main(int ac, char **av)
                case 'v':
                        ++VerboseOpt;
                        break;
-               case 'x':
-                       ++NoSyncOpt;
-                       break;
                default:
                        usage(1);
                        /* not reached */
@@ -107,19 +103,21 @@ main(int ac, char **av)
        }
 
        if (strcmp(av[0], "now") == 0) {
-               hammer_waitsync(1);
                tid = (hammer_tid_t)time(NULL) * 1000000000LLU;
                printf("0x%08x\n", (int)(tid / 1000000000LL));
                exit(0);
        }
        if (strcmp(av[0], "now64") == 0) {
-               hammer_waitsync(0);
                gettimeofday(&tv, NULL);
                tid = (hammer_tid_t)tv.tv_sec * 1000000000LLU +
                        tv.tv_usec * 1000LLU;
                printf("0x%016llx\n", tid);
                exit(0);
        }
+       if (strcmp(av[0], "synctid") == 0) {
+               hammer_cmd_synctid(av + 1, ac - 1);
+               exit(0);
+       }
        if (strcmp(av[0], "stamp") == 0) {
                if (av[1] == NULL)
                        usage(1);
@@ -286,29 +284,6 @@ hammer_parsetime(u_int64_t *tidp, const char *timestr)
                tv.tv_usec * 1000LLU;
 }
 
-/*
- * If the TID is within 60 seconds of the current time we sync().  If
- * dosleep is non-zero and the TID is within 1 second of the current time
- * we wait for the second-hand to turn over.
- *
- * The NoSyncOpt prevents both the sync() call and any sleeps from occuring.
- */
-static
-void
-hammer_waitsync(int dosleep)
-{
-       time_t t1, t2;
-
-       if (NoSyncOpt == 0) {
-               sync();
-               t1 = t2 = time(NULL);
-               while (dosleep && t1 == t2) {
-                       usleep(100000);
-                       t2 = time(NULL);
-               }
-       }
-}
-
 static
 void
 hammer_parsedevs(const char *blkdevs)
index 000d1a2..0eff450 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sbin/hammer/hammer.h,v 1.11 2008/05/12 05:13:48 dillon Exp $
+ * $DragonFly: src/sbin/hammer/hammer.h,v 1.12 2008/05/13 20:49:34 dillon Exp $
  */
 
 #include <sys/types.h>
@@ -64,6 +64,7 @@ extern const char *CyclePath;
 void hammer_cmd_show(hammer_tid_t node_offset, int depth,
                hammer_base_elm_t left_bound, hammer_base_elm_t right_bound);
 void hammer_cmd_prune(char **av, int ac);
+void hammer_cmd_synctid(char **av, int ac);
 void hammer_cmd_history(const char *offset_str, char **av, int ac);
 void hammer_cmd_blockmap(void);
 void hammer_cmd_reblock(char **av, int ac, int flags);