2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sbin/hammer/cmd_history.c,v 1.4 2008/06/24 17:40:21 dillon Exp $
39 static void hammer_do_history(const char *path
, off_t off
, int len
);
40 static void dumpat(const char *path
, off_t off
, int len
);
41 static const char *timestr32(u_int32_t time32
);
44 * history <file1> ... <fileN>
47 hammer_cmd_history(const char *offset_str
, char **av
, int ac
)
55 if (*offset_str
== '@') {
56 off
= strtoll(offset_str
+ 1, &rptr
, 0);
58 len
= strtol(rptr
+ 1, NULL
, 0);
63 for (i
= 0; i
< ac
; ++i
)
64 hammer_do_history(av
[i
], off
, len
);
68 hammer_do_history(const char *path
, off_t off
, int len
)
70 struct hammer_ioc_history hist
;
76 fd
= open(path
, O_RDONLY
);
78 printf("%s\n", strerror(errno
));
81 bzero(&hist
, sizeof(hist
));
82 hist
.beg_tid
= HAMMER_MIN_TID
;
83 hist
.end_tid
= HAMMER_MAX_TID
;
86 hist
.head
.flags
|= HAMMER_IOC_HISTORY_ATKEY
;
88 hist
.nxt_key
= off
+ 1;
92 if (ioctl(fd
, HAMMERIOC_GETHISTORY
, &hist
) < 0) {
93 printf("%s\n", strerror(errno
));
97 status
= ((hist
.head
.flags
& HAMMER_IOC_HISTORY_UNSYNCED
) ?
99 printf("%016llx %s {\n", hist
.obj_id
, status
);
101 for (i
= 0; i
< hist
.count
; ++i
) {
102 char *hist_path
= NULL
;
104 asprintf(&hist_path
, "%s@@0x%016llx",
105 path
, hist
.hist_ary
[i
].tid
);
106 printf(" %016llx %s",
107 hist
.hist_ary
[i
].tid
,
108 timestr32(hist
.hist_ary
[i
].time32
));
112 dumpat(hist_path
, off
, len
);
119 if (hist
.head
.flags
& HAMMER_IOC_HISTORY_EOF
)
121 if (hist
.head
.flags
& HAMMER_IOC_HISTORY_NEXT_KEY
)
123 if ((hist
.head
.flags
& HAMMER_IOC_HISTORY_NEXT_TID
) == 0)
125 hist
.beg_tid
= hist
.nxt_tid
;
126 if (ioctl(fd
, HAMMERIOC_GETHISTORY
, &hist
) < 0) {
127 printf(" error: %s\n", strerror(errno
));
136 dumpat(const char *path
, off_t off
, int len
)
143 fd
= open(path
, O_RDONLY
);
148 n
= (len
> (int)sizeof(buf
)) ? (int)sizeof(buf
) : len
;
149 r
= read(fd
, buf
, n
);
153 for (n
= 0; n
< r
; ++n
) {
155 putc(buf
[n
], stdout
);
163 * Return a human-readable timestamp
166 timestr32(u_int32_t time32
)
168 static char timebuf
[64];
169 time_t t
= (time_t)time32
;
173 strftime(timebuf
, sizeof(timebuf
), "%d-%b-%Y %H:%M:%S", tp
);