1a18c35b9SAndreas Jaekel #include <stdio.h>
2a18c35b9SAndreas Jaekel #include <unistd.h>
3a18c35b9SAndreas Jaekel #include <stdlib.h>
4a18c35b9SAndreas Jaekel #include <fcntl.h>
5a18c35b9SAndreas Jaekel #include <stropts.h>
6a18c35b9SAndreas Jaekel #include <poll.h>
7a18c35b9SAndreas Jaekel #include <string.h>
8a18c35b9SAndreas Jaekel #include <sys/fs/zev.h>
9a18c35b9SAndreas Jaekel #include <errno.h>
1042110aacSAndreas Jaekel #include <sys/sysmacros.h>
1116ff6b2fSAndreas Jaekel #include <stdarg.h>
12b690436dSAndreas Jaekel #include <sys/avl.h>
13f432e238SAndreas Jaekel #include <sys/stat.h>
14a18c35b9SAndreas Jaekel
15add9520fSAndreas Jaekel #define ZEV_DEVICE "/devices/pseudo/zev@0:ctrl"
16a18c35b9SAndreas Jaekel
17b690436dSAndreas Jaekel #if !defined(offsetof)
18b690436dSAndreas Jaekel #define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
19b690436dSAndreas Jaekel #endif
20b690436dSAndreas Jaekel
21a18c35b9SAndreas Jaekel static char *zev_device = ZEV_DEVICE;
22342055d2SArne Jansen static int do_flush = 0;
23a18c35b9SAndreas Jaekel
24aafc540fSAndreas Jaekel static char *zev_op_name[] = {
2516ff6b2fSAndreas Jaekel "ERROR",
2616ff6b2fSAndreas Jaekel "MARK",
2716ff6b2fSAndreas Jaekel "ZFS_MOUNT",
2816ff6b2fSAndreas Jaekel "ZFS_UMOUNT",
2916ff6b2fSAndreas Jaekel "ZVOL_WRITE",
3016ff6b2fSAndreas Jaekel "ZVOL_TRUNCATE",
3116ff6b2fSAndreas Jaekel "ZNODE_CLOSE_AFTER_UPDATE",
3216ff6b2fSAndreas Jaekel "ZNODE_CREATE",
3316ff6b2fSAndreas Jaekel "ZNODE_MKDIR",
3416ff6b2fSAndreas Jaekel "ZNODE_MAKE_XATTR_DIR",
3516ff6b2fSAndreas Jaekel "ZNODE_REMOVE",
3616ff6b2fSAndreas Jaekel "ZNODE_RMDIR",
3716ff6b2fSAndreas Jaekel "ZNODE_LINK",
3816ff6b2fSAndreas Jaekel "ZNODE_SYMLINK",
3916ff6b2fSAndreas Jaekel "ZNODE_RENAME",
4016ff6b2fSAndreas Jaekel "ZNODE_WRITE",
4116ff6b2fSAndreas Jaekel "ZNODE_TRUNCATE",
4216ff6b2fSAndreas Jaekel "ZNODE_SETATTR",
4316ff6b2fSAndreas Jaekel "ZNODE_ACL",
44aafc540fSAndreas Jaekel NULL
45aafc540fSAndreas Jaekel };
46aafc540fSAndreas Jaekel
47a5090b97SAndreas Jaekel #define MD_STATISTICS 1
48a5090b97SAndreas Jaekel #define MD_POLL_EVENTS 2
49a5090b97SAndreas Jaekel #define MD_CHECKSUMS 3
50a5090b97SAndreas Jaekel #define MD_DEBUG_INFO 4
51a5090b97SAndreas Jaekel #define MD_LIST_QUEUES 5
52a5090b97SAndreas Jaekel #define MD_SET_GLOBAL_MAX_QUEUE_LEN 6
53a5090b97SAndreas Jaekel #define MD_SET_MAX_QUEUE_LEN 7
54a5090b97SAndreas Jaekel #define MD_SET_POLL_WAKEUP_QUEUE_LEN 8
55a5090b97SAndreas Jaekel #define MD_MUTE_POOL 9
56a5090b97SAndreas Jaekel #define MD_UNMUTE_POOL 10
57a5090b97SAndreas Jaekel #define MD_MARK 11
58a5090b97SAndreas Jaekel #define MD_ADD_QUEUE 12
59a5090b97SAndreas Jaekel #define MD_ADD_BLOCKING_QUEUE 13
60a5090b97SAndreas Jaekel #define MD_REMOVE_QUEUE 14
61a5090b97SAndreas Jaekel #define MD_QUEUE_BLOCKING 15
62a5090b97SAndreas Jaekel #define MD_QUEUE_NONBLOCKING 16
63a5090b97SAndreas Jaekel #define MD_QUEUE_PROPERTIES 17
64b690436dSAndreas Jaekel #define MD_ZEVSTAT 18
65f432e238SAndreas Jaekel #define MD_ZEV_REPORT 19
6635526fb3SArne Jansen #define MD_DUMP_SPOOL 20
67e3455c18SAndreas Jaekel #define MD_GET_ZEV_VERSION 21
68a5090b97SAndreas Jaekel
69205ed6bfSAndreas Jaekel static int verbose = 0;
7016ff6b2fSAndreas Jaekel static int grep_friendly = 0;
7116ff6b2fSAndreas Jaekel
72*8cfb36b9SArne Jansen #define MAX_GUID 10000
73*8cfb36b9SArne Jansen static int num_guid_filter = 0;
74*8cfb36b9SArne Jansen static uint64_t guid_filter[MAX_GUID];
75*8cfb36b9SArne Jansen
7616ff6b2fSAndreas Jaekel static void
zpf(char * fmt,...)7716ff6b2fSAndreas Jaekel zpf(char *fmt, ...)
7816ff6b2fSAndreas Jaekel {
7916ff6b2fSAndreas Jaekel va_list ap;
8016ff6b2fSAndreas Jaekel
8116ff6b2fSAndreas Jaekel va_start(ap, fmt);
8216ff6b2fSAndreas Jaekel vprintf(fmt, ap);
8316ff6b2fSAndreas Jaekel va_end(ap);
8416ff6b2fSAndreas Jaekel if (grep_friendly) {
8516ff6b2fSAndreas Jaekel printf(" ");
8616ff6b2fSAndreas Jaekel } else {
8716ff6b2fSAndreas Jaekel printf("\n");
8816ff6b2fSAndreas Jaekel }
8916ff6b2fSAndreas Jaekel }
9016ff6b2fSAndreas Jaekel
9116ff6b2fSAndreas Jaekel static void
znl(void)9216ff6b2fSAndreas Jaekel znl(void)
9316ff6b2fSAndreas Jaekel {
9416ff6b2fSAndreas Jaekel if (grep_friendly)
9516ff6b2fSAndreas Jaekel printf("\n");
9616ff6b2fSAndreas Jaekel }
97205ed6bfSAndreas Jaekel
982eabeab5SAndreas Jaekel static void
sig2hex_direct(const uint8_t * sig,char * hex)992eabeab5SAndreas Jaekel sig2hex_direct(const uint8_t *sig, char *hex)
1002eabeab5SAndreas Jaekel {
1012eabeab5SAndreas Jaekel int i;
1022eabeab5SAndreas Jaekel
1032eabeab5SAndreas Jaekel for (i = 0; i < SHA1_DIGEST_LENGTH; ++i) {
1042eabeab5SAndreas Jaekel sprintf(hex + 2 * i, "%02x", sig[i]);
1052eabeab5SAndreas Jaekel }
1062eabeab5SAndreas Jaekel hex[SHA1_DIGEST_LENGTH * 2] = '\0';
1072eabeab5SAndreas Jaekel }
1082eabeab5SAndreas Jaekel
109add9520fSAndreas Jaekel static int
zev_statistics(int fd)110a18c35b9SAndreas Jaekel zev_statistics(int fd)
111a18c35b9SAndreas Jaekel {
112a18c35b9SAndreas Jaekel zev_statistics_t zs;
113add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) {
114a18c35b9SAndreas Jaekel perror("getting statistics data failed");
115add9520fSAndreas Jaekel return (EXIT_FAILURE);
116a18c35b9SAndreas Jaekel }
117a18c35b9SAndreas Jaekel printf("ZEV module state:\n");
118a18c35b9SAndreas Jaekel
119a18c35b9SAndreas Jaekel printf(" queue length in bytes : %lu\n", zs.zev_queue_len);
120a18c35b9SAndreas Jaekel printf(" queue length limit : %lu\n", zs.zev_max_queue_len);
121a18c35b9SAndreas Jaekel printf(" bytes read from device : %lu\n", zs.zev_bytes_read);
122a18c35b9SAndreas Jaekel printf(" module internal errors : %lu\n\n", zs.zev_cnt_errors);
123a18c35b9SAndreas Jaekel
124add9520fSAndreas Jaekel printf(" discarded events : %lu\n",
125add9520fSAndreas Jaekel zs.zev_cnt_discarded_events);
126add9520fSAndreas Jaekel printf(" discarded bytes : %lu\n\n", zs.zev_bytes_discarded);
127add9520fSAndreas Jaekel
128a18c35b9SAndreas Jaekel printf("ZFS event statistics:\n");
129a18c35b9SAndreas Jaekel
130a18c35b9SAndreas Jaekel printf(" total ZFS events : %lu\n", zs.zev_cnt_total_events);
131a18c35b9SAndreas Jaekel printf(" ZFS mount : %lu\n", zs.zev_cnt_zfs_mount);
132a18c35b9SAndreas Jaekel printf(" ZFS umount : %lu\n", zs.zev_cnt_zfs_umount);
133a18c35b9SAndreas Jaekel printf(" ZVOL write : %lu\n", zs.zev_cnt_zvol_write);
134a18c35b9SAndreas Jaekel printf(" ZVOL truncate : %lu\n", zs.zev_cnt_zvol_truncate);
135a18c35b9SAndreas Jaekel printf(" ZNODE close after update: %lu\n",
136a18c35b9SAndreas Jaekel zs.zev_cnt_znode_close_after_update);
137a18c35b9SAndreas Jaekel printf(" ZNODE create : %lu\n", zs.zev_cnt_znode_create);
138a18c35b9SAndreas Jaekel printf(" ZNODE remove : %lu\n", zs.zev_cnt_znode_remove);
139a18c35b9SAndreas Jaekel printf(" ZNODE link : %lu\n", zs.zev_cnt_znode_link);
140a18c35b9SAndreas Jaekel printf(" ZNODE symlink : %lu\n", zs.zev_cnt_znode_symlink);
141a18c35b9SAndreas Jaekel printf(" ZNODE rename : %lu\n", zs.zev_cnt_znode_rename);
142a18c35b9SAndreas Jaekel printf(" ZNODE write : %lu\n", zs.zev_cnt_znode_write);
143a18c35b9SAndreas Jaekel printf(" ZNODE truncate : %lu\n",
144a18c35b9SAndreas Jaekel zs.zev_cnt_znode_truncate);
145a18c35b9SAndreas Jaekel printf(" ZNODE setattr : %lu\n", zs.zev_cnt_znode_setattr);
146a18c35b9SAndreas Jaekel printf(" ZNODE acl : %lu\n", zs.zev_cnt_znode_acl);
147add9520fSAndreas Jaekel return EXIT_SUCCESS;
148a18c35b9SAndreas Jaekel }
149a18c35b9SAndreas Jaekel
150a18c35b9SAndreas Jaekel static void
zev_print_inode_info(char * name,zev_inode_info_t * info)15116ff6b2fSAndreas Jaekel zev_print_inode_info(char *name, zev_inode_info_t *info)
15216ff6b2fSAndreas Jaekel {
15316ff6b2fSAndreas Jaekel zpf(" %s.inode: %llu", name, info->ino);
15416ff6b2fSAndreas Jaekel zpf(" %s.gen: %llu", name, info->gen);
15516ff6b2fSAndreas Jaekel zpf(" %s.mtime: %llu", name, info->mtime);
15616ff6b2fSAndreas Jaekel zpf(" %s.ctime: %llu", name, info->ctime);
15716ff6b2fSAndreas Jaekel zpf(" %s.size: %llu", name, info->size);
15816ff6b2fSAndreas Jaekel zpf(" %s.mode: %llo", name, info->mode);
15916ff6b2fSAndreas Jaekel zpf(" %s.links: %llu", name, info->links);
16016ff6b2fSAndreas Jaekel zpf(" %s.type: %lu", name, info->type);
16116ff6b2fSAndreas Jaekel zpf(" %s.flags: %lu", name, info->flags);
16216ff6b2fSAndreas Jaekel }
16316ff6b2fSAndreas Jaekel
16416ff6b2fSAndreas Jaekel static void
zev_print_mark_payload(zev_mark_t * rec)16516ff6b2fSAndreas Jaekel zev_print_mark_payload(zev_mark_t *rec)
16616ff6b2fSAndreas Jaekel {
16716ff6b2fSAndreas Jaekel int i;
16816ff6b2fSAndreas Jaekel int j;
16916ff6b2fSAndreas Jaekel uint8_t *p;
17016ff6b2fSAndreas Jaekel char c;
17116ff6b2fSAndreas Jaekel
17216ff6b2fSAndreas Jaekel zpf(" payload:");
17316ff6b2fSAndreas Jaekel p = (uint8_t *)ZEV_PAYLOAD(rec);
17416ff6b2fSAndreas Jaekel for (i=0; i<rec->payload_len; i+=16) {
17516ff6b2fSAndreas Jaekel printf(" ");
17616ff6b2fSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) {
17716ff6b2fSAndreas Jaekel printf("%02x ", p[j]);
17816ff6b2fSAndreas Jaekel if (j == i + 7)
17916ff6b2fSAndreas Jaekel printf(" ");
18016ff6b2fSAndreas Jaekel }
18116ff6b2fSAndreas Jaekel if (grep_friendly)
18216ff6b2fSAndreas Jaekel continue;
18316ff6b2fSAndreas Jaekel for (; j<i+16; j++) {
18416ff6b2fSAndreas Jaekel printf(" ");
18516ff6b2fSAndreas Jaekel if (j == i + 7)
18616ff6b2fSAndreas Jaekel printf(" ");
18716ff6b2fSAndreas Jaekel }
18816ff6b2fSAndreas Jaekel printf(" ");
18916ff6b2fSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) {
19016ff6b2fSAndreas Jaekel c = '.';
19116ff6b2fSAndreas Jaekel if (p[j] >= ' ' && p[j] <= '~')
19216ff6b2fSAndreas Jaekel c = p[j];
19316ff6b2fSAndreas Jaekel printf("%c", c);
19416ff6b2fSAndreas Jaekel if (j == i + 7)
19516ff6b2fSAndreas Jaekel printf(" ");
19616ff6b2fSAndreas Jaekel }
19716ff6b2fSAndreas Jaekel printf("\n");
19816ff6b2fSAndreas Jaekel }
19916ff6b2fSAndreas Jaekel }
20016ff6b2fSAndreas Jaekel
20116ff6b2fSAndreas Jaekel static void
zev_print_error(char * buf)202f2dd45e5SAndreas Jaekel zev_print_error(char *buf)
203f2dd45e5SAndreas Jaekel {
204f2dd45e5SAndreas Jaekel zev_error_t *rec = (zev_error_t *)buf;
205f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
206f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
207f2dd45e5SAndreas Jaekel
20816ff6b2fSAndreas Jaekel if (verbose) {
20916ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
21016ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
21116ff6b2fSAndreas Jaekel zpf(" failed.op: %s",
21216ff6b2fSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN]);
21316ff6b2fSAndreas Jaekel zpf(" message: %s", ZEV_ERRSTR(rec));
21416ff6b2fSAndreas Jaekel znl();
21516ff6b2fSAndreas Jaekel } else {
216f2dd45e5SAndreas Jaekel printf("%s %s: failed_op=%s msg=%s\n",
217f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
21816ff6b2fSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN],
21916ff6b2fSAndreas Jaekel ZEV_ERRSTR(rec));
22016ff6b2fSAndreas Jaekel }
221f2dd45e5SAndreas Jaekel }
222f2dd45e5SAndreas Jaekel
223f2dd45e5SAndreas Jaekel static void
zev_print_mark(char * buf)224888fea18SAndreas Jaekel zev_print_mark(char *buf)
225888fea18SAndreas Jaekel {
226888fea18SAndreas Jaekel zev_mark_t *rec = (zev_mark_t *)buf;
227888fea18SAndreas Jaekel time_t op_time = rec->op_time;
228888fea18SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
229888fea18SAndreas Jaekel
23016ff6b2fSAndreas Jaekel if (verbose) {
23116ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
23216ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
23316ff6b2fSAndreas Jaekel zpf(" mark.id: %llu", rec->mark_id);
23416ff6b2fSAndreas Jaekel zpf(" payload.len: %llu", rec->payload_len);
23516ff6b2fSAndreas Jaekel if (rec->payload_len)
23616ff6b2fSAndreas Jaekel zev_print_mark_payload(rec);
23716ff6b2fSAndreas Jaekel znl();
23816ff6b2fSAndreas Jaekel } else {
239647b4f9eSJan Schlien printf("%s %s: guid=%llu mark_id=%lld payload_len=%ld "
240647b4f9eSJan Schlien "payload=\"%.*s\"\n",
24116ff6b2fSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], rec->guid,
242647b4f9eSJan Schlien rec->mark_id, rec->payload_len,
243647b4f9eSJan Schlien rec->payload_len, (char *)(rec + 1));
24416ff6b2fSAndreas Jaekel }
245888fea18SAndreas Jaekel }
246888fea18SAndreas Jaekel
247888fea18SAndreas Jaekel static void
zev_print_zfs_mount(char * buf)248f2dd45e5SAndreas Jaekel zev_print_zfs_mount(char *buf)
249f2dd45e5SAndreas Jaekel {
250f2dd45e5SAndreas Jaekel zev_zfs_mount_t *rec = (zev_zfs_mount_t *)buf;
251f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
252f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
253f2dd45e5SAndreas Jaekel
25416ff6b2fSAndreas Jaekel if (verbose) {
25516ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
25616ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
25703a64974SSimon Klinkert zpf(" txg: %llu", rec->txg);
25816ff6b2fSAndreas Jaekel zpf(" dataset: %s", ZEV_DATASET(rec));
25916ff6b2fSAndreas Jaekel zpf(" mountpoint: %s", ZEV_MOUNTPOINT(rec));
26016ff6b2fSAndreas Jaekel zpf(" remount: %s", rec->remount ? "true" : "false");
26116ff6b2fSAndreas Jaekel zev_print_inode_info("root", &rec->root);
26216ff6b2fSAndreas Jaekel znl();
26316ff6b2fSAndreas Jaekel } else {
26416ff6b2fSAndreas Jaekel printf("%s %s: guid=%llu remount=%s dataset='%s' "
26516ff6b2fSAndreas Jaekel "mountpoint='%s'\n",
266f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
267f2dd45e5SAndreas Jaekel rec->guid,
268f2dd45e5SAndreas Jaekel rec->remount ? "true" : "false",
269f2dd45e5SAndreas Jaekel ZEV_DATASET(rec),
270f2dd45e5SAndreas Jaekel ZEV_MOUNTPOINT(rec));
271f2dd45e5SAndreas Jaekel }
27216ff6b2fSAndreas Jaekel }
273f2dd45e5SAndreas Jaekel
274f2dd45e5SAndreas Jaekel static void
zev_print_zfs_umount(char * buf)275f2dd45e5SAndreas Jaekel zev_print_zfs_umount(char *buf)
276f2dd45e5SAndreas Jaekel {
277f2dd45e5SAndreas Jaekel zev_zfs_umount_t *rec = (zev_zfs_umount_t *)buf;
278f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
279f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
280f2dd45e5SAndreas Jaekel
28116ff6b2fSAndreas Jaekel if (verbose) {
28216ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
28316ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
28403a64974SSimon Klinkert zpf(" txg: %llu", rec->txg);
28594875cb8SAndreas Jaekel zev_print_inode_info("covered", &rec->covered);
28616ff6b2fSAndreas Jaekel znl();
28716ff6b2fSAndreas Jaekel } else {
288f2dd45e5SAndreas Jaekel printf("%s %s: guid=%llu\n",
289f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
290f2dd45e5SAndreas Jaekel rec->guid);
291f2dd45e5SAndreas Jaekel }
29216ff6b2fSAndreas Jaekel }
293f2dd45e5SAndreas Jaekel
294f2dd45e5SAndreas Jaekel static void
zev_print_zvol_truncate(char * buf)295f2dd45e5SAndreas Jaekel zev_print_zvol_truncate(char *buf)
296f2dd45e5SAndreas Jaekel {
297f2dd45e5SAndreas Jaekel zev_zvol_truncate_t *rec = (zev_zvol_truncate_t *)buf;
298f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
299f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
300f2dd45e5SAndreas Jaekel
30116ff6b2fSAndreas Jaekel if (verbose) {
30216ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
30316ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
30412119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
30516ff6b2fSAndreas Jaekel zpf(" offset: %llu", rec->offset);
30616ff6b2fSAndreas Jaekel zpf(" length: %llu", rec->length);
30716ff6b2fSAndreas Jaekel znl();
30816ff6b2fSAndreas Jaekel } else {
309f2dd45e5SAndreas Jaekel printf("%s %s: guid=%llu offset=%llu length=%llu\n",
310f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
311f2dd45e5SAndreas Jaekel rec->guid,
312f2dd45e5SAndreas Jaekel rec->offset,
313f2dd45e5SAndreas Jaekel rec->length);
314f2dd45e5SAndreas Jaekel }
31516ff6b2fSAndreas Jaekel }
316f2dd45e5SAndreas Jaekel
317f2dd45e5SAndreas Jaekel static void
zev_print_zvol_write(char * buf)318f2dd45e5SAndreas Jaekel zev_print_zvol_write(char *buf)
319f2dd45e5SAndreas Jaekel {
320f2dd45e5SAndreas Jaekel zev_print_zvol_truncate(buf);
321f2dd45e5SAndreas Jaekel }
322f2dd45e5SAndreas Jaekel
323f2dd45e5SAndreas Jaekel static void
zev_print_znode_close_after_update(char * buf)324f2dd45e5SAndreas Jaekel zev_print_znode_close_after_update(char *buf)
325f2dd45e5SAndreas Jaekel {
326f2dd45e5SAndreas Jaekel zev_znode_close_after_update_t *rec =
327f2dd45e5SAndreas Jaekel (zev_znode_close_after_update_t *)buf;
328f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
329f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
330f2dd45e5SAndreas Jaekel
33116ff6b2fSAndreas Jaekel if (verbose) {
33216ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
33316ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
33416ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
33516ff6b2fSAndreas Jaekel znl();
33616ff6b2fSAndreas Jaekel } else {
337f2dd45e5SAndreas Jaekel printf("%s %s: guid=%llu file=%llu.%llu\n",
338f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
339f2dd45e5SAndreas Jaekel rec->guid,
340f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen);
341f2dd45e5SAndreas Jaekel }
34216ff6b2fSAndreas Jaekel }
343f2dd45e5SAndreas Jaekel
344f2dd45e5SAndreas Jaekel static void
zev_print_znode_create(char * buf)345f2dd45e5SAndreas Jaekel zev_print_znode_create(char *buf)
346f2dd45e5SAndreas Jaekel {
347f2dd45e5SAndreas Jaekel zev_znode_create_t *rec = (zev_znode_create_t *)buf;
348f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
349f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
3502eabeab5SAndreas Jaekel zev_sig_t *sig;
3512eabeab5SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
352f2dd45e5SAndreas Jaekel
35316ff6b2fSAndreas Jaekel if (verbose) {
35416ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
35516ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
35612119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
35716ff6b2fSAndreas Jaekel zpf(" name: '%s'", ZEV_NAME(rec));
3582eabeab5SAndreas Jaekel sig = &rec->signature;
3592eabeab5SAndreas Jaekel sig2hex_direct(sig->value, sigval);
3602eabeab5SAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s",
3612eabeab5SAndreas Jaekel sig->level, sig->block_offset, sigval);
36216ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
36312119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
36416ff6b2fSAndreas Jaekel znl();
36516ff6b2fSAndreas Jaekel } else {
36635d4e8ddSAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu file=%llu.%llu "
36735d4e8ddSAndreas Jaekel "file.mtime=%llu, parent.mtime=%llu, name='%s'\n",
368f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
369f2dd45e5SAndreas Jaekel rec->guid,
370f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen,
371f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen,
37235d4e8ddSAndreas Jaekel rec->file.mtime, rec->parent.mtime,
373f2dd45e5SAndreas Jaekel ZEV_NAME(rec));
374f2dd45e5SAndreas Jaekel }
37516ff6b2fSAndreas Jaekel }
376f2dd45e5SAndreas Jaekel
377f2dd45e5SAndreas Jaekel static void
zev_print_znode_mkdir(char * buf)378f2dd45e5SAndreas Jaekel zev_print_znode_mkdir(char *buf)
379f2dd45e5SAndreas Jaekel {
380f2dd45e5SAndreas Jaekel zev_print_znode_create(buf);
381f2dd45e5SAndreas Jaekel }
382f2dd45e5SAndreas Jaekel
383f2dd45e5SAndreas Jaekel static void
zev_print_znode_make_xattr_dir(char * buf)384f2dd45e5SAndreas Jaekel zev_print_znode_make_xattr_dir(char *buf)
385f2dd45e5SAndreas Jaekel {
386f2dd45e5SAndreas Jaekel zev_print_znode_create(buf);
387f2dd45e5SAndreas Jaekel }
388f2dd45e5SAndreas Jaekel
389f2dd45e5SAndreas Jaekel static void
zev_print_znode_remove(char * buf)390f2dd45e5SAndreas Jaekel zev_print_znode_remove(char *buf)
391f2dd45e5SAndreas Jaekel {
392f2dd45e5SAndreas Jaekel zev_znode_remove_t *rec = (zev_znode_remove_t *)buf;
393f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
394f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
395f2dd45e5SAndreas Jaekel
39616ff6b2fSAndreas Jaekel if (verbose) {
39716ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
39816ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
39912119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
40016ff6b2fSAndreas Jaekel zpf(" file.name: '%s'", ZEV_NAME(rec));
40116ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
40212119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
40316ff6b2fSAndreas Jaekel znl();
40416ff6b2fSAndreas Jaekel } else {
40516ff6b2fSAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu "
40616ff6b2fSAndreas Jaekel "file.mtime=%llu name='%s'\n",
407f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
408f2dd45e5SAndreas Jaekel rec->guid,
409f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen,
41097dcf88dSAndreas Jaekel rec->file.mtime,
411f2dd45e5SAndreas Jaekel ZEV_NAME(rec));
412f2dd45e5SAndreas Jaekel }
41316ff6b2fSAndreas Jaekel }
414f2dd45e5SAndreas Jaekel
415f2dd45e5SAndreas Jaekel static void
zev_print_znode_rmdir(char * buf)416f2dd45e5SAndreas Jaekel zev_print_znode_rmdir(char *buf)
417f2dd45e5SAndreas Jaekel {
418f2dd45e5SAndreas Jaekel zev_print_znode_remove(buf);
419f2dd45e5SAndreas Jaekel }
420f2dd45e5SAndreas Jaekel
421f2dd45e5SAndreas Jaekel static void
zev_print_znode_link(char * buf)422f2dd45e5SAndreas Jaekel zev_print_znode_link(char *buf)
423f2dd45e5SAndreas Jaekel {
424f2dd45e5SAndreas Jaekel zev_znode_link_t *rec = (zev_znode_link_t *)buf;
425f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
426f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
427f2dd45e5SAndreas Jaekel
42816ff6b2fSAndreas Jaekel if (verbose) {
42916ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
43016ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
43112119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
43216ff6b2fSAndreas Jaekel zpf(" link.name: '%s'", ZEV_NAME(rec));
43316ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
43412119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
43516ff6b2fSAndreas Jaekel znl();
43616ff6b2fSAndreas Jaekel } else {
437a01b300aSAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu "
438a01b300aSAndreas Jaekel "file.ctime=%llu parent.ctime=%llu name='%s'\n",
439f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
440f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen,
441f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen,
442a01b300aSAndreas Jaekel rec->file.ctime, rec->parent.ctime,
443f2dd45e5SAndreas Jaekel ZEV_NAME(rec));
44416ff6b2fSAndreas Jaekel }
445f2dd45e5SAndreas Jaekel }
446f2dd45e5SAndreas Jaekel
447f2dd45e5SAndreas Jaekel static void
zev_print_znode_symlink(char * buf)448f2dd45e5SAndreas Jaekel zev_print_znode_symlink(char *buf)
449f2dd45e5SAndreas Jaekel {
450f2dd45e5SAndreas Jaekel zev_znode_symlink_t *rec = (zev_znode_symlink_t *)buf;
451f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
452f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
4532eabeab5SAndreas Jaekel zev_sig_t *sig;
4542eabeab5SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
455f2dd45e5SAndreas Jaekel
45616ff6b2fSAndreas Jaekel if (verbose) {
45716ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
45816ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
45912119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
46016ff6b2fSAndreas Jaekel zpf(" symlink.name: '%s'", ZEV_NAME(rec));
46116ff6b2fSAndreas Jaekel zpf(" symlink.link: '%s'", ZEV_LINK(rec));
4622eabeab5SAndreas Jaekel sig = &rec->signature;
4632eabeab5SAndreas Jaekel sig2hex_direct(sig->value, sigval);
4642eabeab5SAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s",
4652eabeab5SAndreas Jaekel sig->level, sig->block_offset, sigval);
46616ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
46712119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
46816ff6b2fSAndreas Jaekel znl();
46916ff6b2fSAndreas Jaekel } else {
47016ff6b2fSAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu "
47116ff6b2fSAndreas Jaekel "name='%s' link='%s'\n",
472f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
473f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen,
474f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen,
475f2dd45e5SAndreas Jaekel ZEV_NAME(rec),
476f2dd45e5SAndreas Jaekel ZEV_LINK(rec));
477f2dd45e5SAndreas Jaekel }
47816ff6b2fSAndreas Jaekel }
479f2dd45e5SAndreas Jaekel
480f2dd45e5SAndreas Jaekel static void
zev_print_znode_rename(char * buf)481f2dd45e5SAndreas Jaekel zev_print_znode_rename(char *buf)
482f2dd45e5SAndreas Jaekel {
483f2dd45e5SAndreas Jaekel zev_znode_rename_t *rec = (zev_znode_rename_t *)buf;
484f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
485f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
486f2dd45e5SAndreas Jaekel
48716ff6b2fSAndreas Jaekel if (verbose) {
48816ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
48916ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
49012119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
49116ff6b2fSAndreas Jaekel zpf(" file.srcname: '%s'", ZEV_SRCNAME(rec));
49216ff6b2fSAndreas Jaekel zpf(" file.dstname: '%s'", ZEV_DSTNAME(rec));
49316ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
4948aa47a6bSAndreas Jaekel if (rec->clobbered_file.ino)
4958aa47a6bSAndreas Jaekel zev_print_inode_info("clobbered_file",
4968aa47a6bSAndreas Jaekel &rec->clobbered_file);
49716ff6b2fSAndreas Jaekel zev_print_inode_info("srcdir", &rec->srcdir);
49816ff6b2fSAndreas Jaekel zev_print_inode_info("dstdir", &rec->dstdir);
49916ff6b2fSAndreas Jaekel znl();
50016ff6b2fSAndreas Jaekel } else {
50116ff6b2fSAndreas Jaekel printf("%s %s: srcdir=%llu.%llu dstdir=%llu.%llu "
50216ff6b2fSAndreas Jaekel "file=%llu.%llu file.mtime=%llu, file.ctime=%llu, "
50316ff6b2fSAndreas Jaekel "srcdir.mtime=%llu, srcdir.ctime=%llu, "
50416ff6b2fSAndreas Jaekel "dstdir.mtime=%llu, dstdir.ctime=%llu, "
505f2dd45e5SAndreas Jaekel "srcname='%s' dstname='%s'\n",
506f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
507f2dd45e5SAndreas Jaekel rec->srcdir.ino, rec->srcdir.gen,
508f2dd45e5SAndreas Jaekel rec->dstdir.ino, rec->dstdir.gen,
509f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen,
51035d4e8ddSAndreas Jaekel rec->file.mtime, rec->file.ctime,
51135d4e8ddSAndreas Jaekel rec->srcdir.mtime, rec->srcdir.ctime,
51235d4e8ddSAndreas Jaekel rec->dstdir.mtime, rec->dstdir.ctime,
513f2dd45e5SAndreas Jaekel ZEV_SRCNAME(rec),
514f2dd45e5SAndreas Jaekel ZEV_DSTNAME(rec));
515f2dd45e5SAndreas Jaekel }
51616ff6b2fSAndreas Jaekel }
517f2dd45e5SAndreas Jaekel
518f2dd45e5SAndreas Jaekel static void
zev_print_znode_write(char * buf)519f2dd45e5SAndreas Jaekel zev_print_znode_write(char *buf)
520f2dd45e5SAndreas Jaekel {
521f2dd45e5SAndreas Jaekel zev_znode_write_t *rec = (zev_znode_write_t *)buf;
522f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
523f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
524205ed6bfSAndreas Jaekel zev_sig_t *sig;
525205ed6bfSAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
526205ed6bfSAndreas Jaekel int i;
527f2dd45e5SAndreas Jaekel
528205ed6bfSAndreas Jaekel if (verbose) {
52916ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
53016ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
53112119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
53216ff6b2fSAndreas Jaekel zpf(" offset: %llu", rec->offset);
53316ff6b2fSAndreas Jaekel zpf(" length: %llu", rec->length);
53416ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
53516ff6b2fSAndreas Jaekel znl();
536205ed6bfSAndreas Jaekel for (i=0; i<rec->signature_cnt; i++) {
537205ed6bfSAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(rec);
538205ed6bfSAndreas Jaekel sig += i;
539205ed6bfSAndreas Jaekel sig2hex_direct(sig->value, sigval);
5402eabeab5SAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s",
541205ed6bfSAndreas Jaekel sig->level, sig->block_offset, sigval);
542205ed6bfSAndreas Jaekel }
54316ff6b2fSAndreas Jaekel } else {
54416ff6b2fSAndreas Jaekel printf("%s %s: file=%llu.%llu offset=%llu length=%llu\n",
54516ff6b2fSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
54616ff6b2fSAndreas Jaekel rec->file.ino, rec->file.gen,
54716ff6b2fSAndreas Jaekel rec->offset, rec->length);
548205ed6bfSAndreas Jaekel }
549f2dd45e5SAndreas Jaekel }
550f2dd45e5SAndreas Jaekel
551f2dd45e5SAndreas Jaekel static void
zev_print_znode_truncate(char * buf)552f2dd45e5SAndreas Jaekel zev_print_znode_truncate(char *buf)
553f2dd45e5SAndreas Jaekel {
554f2dd45e5SAndreas Jaekel zev_print_znode_write(buf);
555f2dd45e5SAndreas Jaekel }
556f2dd45e5SAndreas Jaekel
557f2dd45e5SAndreas Jaekel static void
zev_print_znode_setattr(char * buf)558f2dd45e5SAndreas Jaekel zev_print_znode_setattr(char *buf)
559f2dd45e5SAndreas Jaekel {
560f2dd45e5SAndreas Jaekel zev_znode_setattr_t *rec = (zev_znode_setattr_t *)buf;
561f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time;
562f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
563f2dd45e5SAndreas Jaekel
56416ff6b2fSAndreas Jaekel if (verbose) {
56516ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
56616ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid);
56712119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg);
56816ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file);
56916ff6b2fSAndreas Jaekel znl();
57016ff6b2fSAndreas Jaekel } else {
57135d4e8ddSAndreas Jaekel printf("%s %s: file=%llu.%llu mtime=%llu\n",
572f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
57335d4e8ddSAndreas Jaekel rec->file.ino, rec->file.gen, rec->file.mtime);
574f2dd45e5SAndreas Jaekel }
57516ff6b2fSAndreas Jaekel }
576f2dd45e5SAndreas Jaekel
577f2dd45e5SAndreas Jaekel static void
zev_print_znode_acl(char * buf)578f2dd45e5SAndreas Jaekel zev_print_znode_acl(char *buf)
579f2dd45e5SAndreas Jaekel {
580f2dd45e5SAndreas Jaekel zev_print_znode_setattr(buf);
581f2dd45e5SAndreas Jaekel }
582f2dd45e5SAndreas Jaekel
583f2dd45e5SAndreas Jaekel static void
zev_print_event(char * buf,int len)584aafc540fSAndreas Jaekel zev_print_event(char *buf, int len)
585aafc540fSAndreas Jaekel {
586f2dd45e5SAndreas Jaekel int record_len;
587f2dd45e5SAndreas Jaekel int op;
588aafc540fSAndreas Jaekel
589f2dd45e5SAndreas Jaekel record_len = *(uint32_t *)buf;
590f2dd45e5SAndreas Jaekel if (record_len != len) {
591f2dd45e5SAndreas Jaekel fprintf(stderr, "record length mismatch: got %d, expected %d\n",
592f2dd45e5SAndreas Jaekel record_len, len);
593aafc540fSAndreas Jaekel exit(1);
594aafc540fSAndreas Jaekel }
595f2dd45e5SAndreas Jaekel op = *((uint32_t *)buf + 1);
596aafc540fSAndreas Jaekel if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) {
597f2dd45e5SAndreas Jaekel fprintf(stderr, "unknown op code: %d\n", op);
598aafc540fSAndreas Jaekel exit(1);
599aafc540fSAndreas Jaekel }
600*8cfb36b9SArne Jansen if (num_guid_filter) {
601*8cfb36b9SArne Jansen uint64_t guid = *((uint64_t *)buf + 2);
602*8cfb36b9SArne Jansen int i;
603*8cfb36b9SArne Jansen
604*8cfb36b9SArne Jansen for (i = 0; i < num_guid_filter; ++i)
605*8cfb36b9SArne Jansen if (guid_filter[i] == guid)
606*8cfb36b9SArne Jansen break;
607*8cfb36b9SArne Jansen
608*8cfb36b9SArne Jansen if (i == num_guid_filter)
609*8cfb36b9SArne Jansen /* no match, filtered */
610*8cfb36b9SArne Jansen return;
611*8cfb36b9SArne Jansen }
612f2dd45e5SAndreas Jaekel switch (op) {
613f2dd45e5SAndreas Jaekel case ZEV_OP_ERROR:
614f2dd45e5SAndreas Jaekel zev_print_error(buf);
615aafc540fSAndreas Jaekel break;
616888fea18SAndreas Jaekel case ZEV_OP_MARK:
617888fea18SAndreas Jaekel zev_print_mark(buf);
618888fea18SAndreas Jaekel break;
619f2dd45e5SAndreas Jaekel case ZEV_OP_ZFS_MOUNT:
620f2dd45e5SAndreas Jaekel zev_print_zfs_mount(buf);
621aafc540fSAndreas Jaekel break;
622f2dd45e5SAndreas Jaekel case ZEV_OP_ZFS_UMOUNT:
623f2dd45e5SAndreas Jaekel zev_print_zfs_umount(buf);
624aafc540fSAndreas Jaekel break;
625f2dd45e5SAndreas Jaekel case ZEV_OP_ZVOL_TRUNCATE:
626f2dd45e5SAndreas Jaekel zev_print_zvol_truncate(buf);
627aafc540fSAndreas Jaekel break;
628f2dd45e5SAndreas Jaekel case ZEV_OP_ZVOL_WRITE:
629f2dd45e5SAndreas Jaekel zev_print_zvol_write(buf);
630f2dd45e5SAndreas Jaekel break;
631f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE:
632f2dd45e5SAndreas Jaekel zev_print_znode_close_after_update(buf);
633f2dd45e5SAndreas Jaekel break;
634f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_CREATE:
635f2dd45e5SAndreas Jaekel zev_print_znode_create(buf);
636f2dd45e5SAndreas Jaekel break;
637f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_MKDIR:
638f2dd45e5SAndreas Jaekel zev_print_znode_mkdir(buf);
639f2dd45e5SAndreas Jaekel break;
640f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_MAKE_XATTR_DIR:
641f2dd45e5SAndreas Jaekel zev_print_znode_make_xattr_dir(buf);
642f2dd45e5SAndreas Jaekel break;
643f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_REMOVE:
644f2dd45e5SAndreas Jaekel zev_print_znode_remove(buf);
645f2dd45e5SAndreas Jaekel break;
646f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_RMDIR:
647f2dd45e5SAndreas Jaekel zev_print_znode_rmdir(buf);
648f2dd45e5SAndreas Jaekel break;
649f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_LINK:
650f2dd45e5SAndreas Jaekel zev_print_znode_link(buf);
651f2dd45e5SAndreas Jaekel break;
652f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_SYMLINK:
653f2dd45e5SAndreas Jaekel zev_print_znode_symlink(buf);
654f2dd45e5SAndreas Jaekel break;
655f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_RENAME:
656f2dd45e5SAndreas Jaekel zev_print_znode_rename(buf);
657f2dd45e5SAndreas Jaekel break;
658f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_WRITE:
659f2dd45e5SAndreas Jaekel zev_print_znode_write(buf);
660f2dd45e5SAndreas Jaekel break;
661f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_TRUNCATE:
662f2dd45e5SAndreas Jaekel zev_print_znode_truncate(buf);
663f2dd45e5SAndreas Jaekel break;
664f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_SETATTR:
665f2dd45e5SAndreas Jaekel zev_print_znode_setattr(buf);
666f2dd45e5SAndreas Jaekel break;
667f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_ACL:
668f2dd45e5SAndreas Jaekel zev_print_znode_acl(buf);
669aafc540fSAndreas Jaekel break;
670aafc540fSAndreas Jaekel default:
671f2dd45e5SAndreas Jaekel fprintf(stderr, "unhandled op code: %d\n", op);
672aafc540fSAndreas Jaekel exit(1);
673aafc540fSAndreas Jaekel }
674342055d2SArne Jansen if (do_flush)
675342055d2SArne Jansen fflush(stdout);
676aafc540fSAndreas Jaekel }
677aafc540fSAndreas Jaekel
678add9520fSAndreas Jaekel static int
zev_poll_events(int fd,int create_tmp_queue)679b64581b1SAndreas Jaekel zev_poll_events(int fd, int create_tmp_queue)
680a18c35b9SAndreas Jaekel {
681a18c35b9SAndreas Jaekel struct pollfd pfd[1];
682a18c35b9SAndreas Jaekel int ret;
683aafc540fSAndreas Jaekel char buf[4096];
684d979f56cSAndreas Jaekel zev_event_t *ev;
685d979f56cSAndreas Jaekel int off = 0;
686add9520fSAndreas Jaekel int q_fd;
687add9520fSAndreas Jaekel
6886a6a51eeSAndreas Jaekel if (create_tmp_queue) {
6896a6a51eeSAndreas Jaekel snprintf(buf, sizeof(buf),
690b64581b1SAndreas Jaekel "/devices/pseudo/zev@0:%s", ZEV_TMPQUEUE_DEVICE_NAME);
691add9520fSAndreas Jaekel q_fd = open(buf, O_RDONLY);
692add9520fSAndreas Jaekel if (q_fd < 0) {
693add9520fSAndreas Jaekel perror("opening queue device failed");
694add9520fSAndreas Jaekel return (EXIT_FAILURE);
695add9520fSAndreas Jaekel }
6966a6a51eeSAndreas Jaekel } else {
6976a6a51eeSAndreas Jaekel q_fd = fd;
6986a6a51eeSAndreas Jaekel }
699add9520fSAndreas Jaekel
700a18c35b9SAndreas Jaekel while (1) {
701add9520fSAndreas Jaekel pfd[0].fd = q_fd;
702a18c35b9SAndreas Jaekel pfd[0].events = POLLIN;
703a18c35b9SAndreas Jaekel ret = poll(pfd, 1, 1000);
704a18c35b9SAndreas Jaekel if (ret < 0) {
705a18c35b9SAndreas Jaekel perror("poll failed");
7066a6a51eeSAndreas Jaekel close(q_fd);
707add9520fSAndreas Jaekel return(EXIT_FAILURE);
708a18c35b9SAndreas Jaekel }
709a18c35b9SAndreas Jaekel if (!(pfd[0].revents & POLLIN))
710a18c35b9SAndreas Jaekel continue;
711a18c35b9SAndreas Jaekel /* data available */
712add9520fSAndreas Jaekel ret = read(q_fd, buf, sizeof(buf));
713a18c35b9SAndreas Jaekel if (ret < 0) {
714a18c35b9SAndreas Jaekel perror("read failed");
7156a6a51eeSAndreas Jaekel close(q_fd);
716add9520fSAndreas Jaekel return(EXIT_FAILURE);
717a18c35b9SAndreas Jaekel }
718a18c35b9SAndreas Jaekel if (ret == 0)
719a18c35b9SAndreas Jaekel continue;
720d979f56cSAndreas Jaekel while (ret > off) {
721d979f56cSAndreas Jaekel ev = (zev_event_t *)(buf + off);
722d979f56cSAndreas Jaekel zev_print_event(buf + off, ev->header.record_len);
723d979f56cSAndreas Jaekel off += ev->header.record_len;
724d979f56cSAndreas Jaekel }
725149d0affSAndreas Jaekel off = 0;
726a18c35b9SAndreas Jaekel }
7276a6a51eeSAndreas Jaekel if (create_tmp_queue)
728add9520fSAndreas Jaekel close(q_fd);
729add9520fSAndreas Jaekel return EXIT_SUCCESS;
730a18c35b9SAndreas Jaekel }
731a18c35b9SAndreas Jaekel
73235526fb3SArne Jansen static int
zev_dump_spool(int fd)73335526fb3SArne Jansen zev_dump_spool(int fd)
73435526fb3SArne Jansen {
73535526fb3SArne Jansen int len;
73635526fb3SArne Jansen char buf[4096];
73735526fb3SArne Jansen int off = 0;
73835526fb3SArne Jansen
73935526fb3SArne Jansen while (1) {
74035526fb3SArne Jansen len = read(fd, buf + off, sizeof(buf) - off);
74135526fb3SArne Jansen if (len == -1) {
74235526fb3SArne Jansen fprintf(stderr, "reading from spool failed: %s\n",
74335526fb3SArne Jansen strerror(errno));
74435526fb3SArne Jansen return EXIT_FAILURE;
74535526fb3SArne Jansen }
74635526fb3SArne Jansen if (len == 0)
74735526fb3SArne Jansen break;
74835526fb3SArne Jansen
74935526fb3SArne Jansen len += off;
75035526fb3SArne Jansen off = 0;
75135526fb3SArne Jansen while (len > off + sizeof(uint32_t)) {
75235526fb3SArne Jansen uint32_t evlen;
75335526fb3SArne Jansen char *mp;
75435526fb3SArne Jansen zev_event_t *ev;
75535526fb3SArne Jansen
75635526fb3SArne Jansen ev = (zev_event_t *)(buf + off);
75735526fb3SArne Jansen evlen = ev->header.record_len;
75835526fb3SArne Jansen if (len < off + evlen + 1)
75935526fb3SArne Jansen break;
76035526fb3SArne Jansen mp = buf + off + evlen;
76135526fb3SArne Jansen if (!memchr(mp, 0, len - off - evlen))
76235526fb3SArne Jansen break;
76335526fb3SArne Jansen zev_print_event(buf + off, ev->header.record_len);
76435526fb3SArne Jansen off += ev->header.record_len + strlen(mp) + 1;
76535526fb3SArne Jansen }
76635526fb3SArne Jansen
76735526fb3SArne Jansen memmove(buf, buf + off, len - off);
76835526fb3SArne Jansen off = len - off;
76935526fb3SArne Jansen }
77035526fb3SArne Jansen
77135526fb3SArne Jansen return EXIT_SUCCESS;
77235526fb3SArne Jansen }
77335526fb3SArne Jansen
774a18c35b9SAndreas Jaekel static void
usage(char * progname)775a18c35b9SAndreas Jaekel usage(char *progname)
776a18c35b9SAndreas Jaekel {
777add9520fSAndreas Jaekel fprintf(stderr, "usage: %s [-d <dev>] [options]\n", progname);
778add9520fSAndreas Jaekel fprintf(stderr, "\n");
779add9520fSAndreas Jaekel fprintf(stderr, " Status information:\n");
780a18c35b9SAndreas Jaekel fprintf(stderr, " -s show zev statistics\n");
781a18c35b9SAndreas Jaekel fprintf(stderr, " -p poll for ZFS events\n");
78235526fb3SArne Jansen fprintf(stderr, " -f <name> dump events from spool\n");
783add9520fSAndreas Jaekel fprintf(stderr, " -D print zev module debug "
784add9520fSAndreas Jaekel "information\n");
785b690436dSAndreas Jaekel fprintf(stderr, " -T <interval> <cnt> zevstat mode\n");
786f432e238SAndreas Jaekel fprintf(stderr, " -R <base filename> zevreport mode\n");
787add9520fSAndreas Jaekel fprintf(stderr, "\n");
788add9520fSAndreas Jaekel fprintf(stderr, " Tune zev module settings:\n");
789add9520fSAndreas Jaekel fprintf(stderr, " -Q <bytes> set maximum event queue "
790add9520fSAndreas Jaekel "length\n");
791add9520fSAndreas Jaekel fprintf(stderr, " -m <pool> mute pool, no events for "
792add9520fSAndreas Jaekel "this pool\n");
793a18c35b9SAndreas Jaekel fprintf(stderr, " -M <pool> unmute pool\n");
794add9520fSAndreas Jaekel fprintf(stderr, "\n");
795add9520fSAndreas Jaekel fprintf(stderr, " Queue management:\n");
796add9520fSAndreas Jaekel fprintf(stderr, " -l list queues\n");
7976a6a51eeSAndreas Jaekel fprintf(stderr, " -a <name> add non-blocking queue\n");
7986a6a51eeSAndreas Jaekel fprintf(stderr, " -A <name> add blocking queue\n");
799add9520fSAndreas Jaekel fprintf(stderr, " -r <name> remove queue\n");
800add9520fSAndreas Jaekel fprintf(stderr, " -b <name> make queue non-blocking "
801add9520fSAndreas Jaekel "(default)\n");
802add9520fSAndreas Jaekel fprintf(stderr, " -B <name> make queue block when full\n");
803add9520fSAndreas Jaekel fprintf(stderr, " -P <name> display queue properties\n");
8046a6a51eeSAndreas Jaekel fprintf(stderr, " -L <name> <bytes> set maximum event queue "
805add9520fSAndreas Jaekel "length\n");
806add9520fSAndreas Jaekel fprintf(stderr, " -t <name> <bytes> set queue length poll "
807add9520fSAndreas Jaekel "throttle\n");
808add9520fSAndreas Jaekel fprintf(stderr, "\n");
809add9520fSAndreas Jaekel fprintf(stderr, " Other options:\n");
810add9520fSAndreas Jaekel fprintf(stderr, " -d <dev> non-default device file. "
811add9520fSAndreas Jaekel "('%s')\n", ZEV_DEVICE);
8126a6a51eeSAndreas Jaekel fprintf(stderr, " -q <name> use device file for this "
8136a6a51eeSAndreas Jaekel "queue name\n");
814888fea18SAndreas Jaekel fprintf(stderr, " -k <guid>:<payload> queue mark event\n");
81542110aacSAndreas Jaekel fprintf(stderr, " -c <filename> list file's content "
81642110aacSAndreas Jaekel "checksums\n");
81716ff6b2fSAndreas Jaekel fprintf(stderr, " -v verbose: additional output "
818205ed6bfSAndreas Jaekel "for some operations\n");
81916ff6b2fSAndreas Jaekel fprintf(stderr, " -g grep-friendly event output, "
82016ff6b2fSAndreas Jaekel "one event per line\n");
821*8cfb36b9SArne Jansen fprintf(stderr, " -G <guid> filter event output by guid, "
822*8cfb36b9SArne Jansen "can be given more than once\n");
823e3455c18SAndreas Jaekel fprintf(stderr, " -V query zev module version\n");
824342055d2SArne Jansen fprintf(stderr, " -F flush output after each line\n");
825a18c35b9SAndreas Jaekel exit (EXIT_FAILURE);
826a18c35b9SAndreas Jaekel }
827a18c35b9SAndreas Jaekel
82850da9edeSAndreas Jaekel static void
zevstat_usage(char * progname)82950da9edeSAndreas Jaekel zevstat_usage(char *progname)
83050da9edeSAndreas Jaekel {
83150da9edeSAndreas Jaekel fprintf(stderr, "usage: %s [-v] <interval> [count]\n", progname);
83250da9edeSAndreas Jaekel fprintf(stderr, " -v verbose, show counters for all event types\n");
83350da9edeSAndreas Jaekel exit (EXIT_FAILURE);
83450da9edeSAndreas Jaekel }
83550da9edeSAndreas Jaekel
836f432e238SAndreas Jaekel static void
zevreport_usage(char * progname)837f432e238SAndreas Jaekel zevreport_usage(char *progname)
838f432e238SAndreas Jaekel {
839f432e238SAndreas Jaekel fprintf(stderr, "usage: %s <output base filename>\n", progname);
840f432e238SAndreas Jaekel exit (EXIT_FAILURE);
841f432e238SAndreas Jaekel }
842f432e238SAndreas Jaekel
843a18c35b9SAndreas Jaekel static int
zev_add_queue(int fd,char * arg,int blocking)8446a6a51eeSAndreas Jaekel zev_add_queue(int fd, char *arg, int blocking)
845a18c35b9SAndreas Jaekel {
846add9520fSAndreas Jaekel zev_ioctl_add_queue_t aq;
847add9520fSAndreas Jaekel int namelen;
848a18c35b9SAndreas Jaekel
849add9520fSAndreas Jaekel namelen = strlen(arg);
850add9520fSAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
851add9520fSAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg);
852a18c35b9SAndreas Jaekel return (EXIT_FAILURE);
853a18c35b9SAndreas Jaekel }
854add9520fSAndreas Jaekel
855add9520fSAndreas Jaekel aq.zev_namelen = namelen;
856add9520fSAndreas Jaekel strcpy(aq.zev_name, arg);
857c99a1a25SAndreas Jaekel aq.zev_flags = ZEV_FL_PERSISTENT | ZEV_FL_INITIALLY_EMPTY;
8586a6a51eeSAndreas Jaekel if (blocking) {
8596a6a51eeSAndreas Jaekel aq.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
8606a6a51eeSAndreas Jaekel aq.zev_max_queue_len = ZEV_MAX_QUEUE_LEN;
8616a6a51eeSAndreas Jaekel } else {
862add9520fSAndreas Jaekel aq.zev_max_queue_len = (1024 * 1024);
8636a6a51eeSAndreas Jaekel }
864add9520fSAndreas Jaekel
865add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
866add9520fSAndreas Jaekel perror("adding queue failed");
867a18c35b9SAndreas Jaekel return (EXIT_FAILURE);
868a18c35b9SAndreas Jaekel }
869a18c35b9SAndreas Jaekel return (0);
870a18c35b9SAndreas Jaekel }
871a18c35b9SAndreas Jaekel
872a18c35b9SAndreas Jaekel static int
zev_remove_queue(int fd,char * arg)873add9520fSAndreas Jaekel zev_remove_queue(int fd, char *arg)
874fec460f8SAndreas Jaekel {
875add9520fSAndreas Jaekel zev_ioctl_remove_queue_t aq;
876add9520fSAndreas Jaekel int namelen;
877fec460f8SAndreas Jaekel
878add9520fSAndreas Jaekel namelen = strlen(arg);
879add9520fSAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
880add9520fSAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg);
881fec460f8SAndreas Jaekel return (EXIT_FAILURE);
882fec460f8SAndreas Jaekel }
883add9520fSAndreas Jaekel
8846a6a51eeSAndreas Jaekel aq.zev_queue_name.zev_namelen = namelen;
8856a6a51eeSAndreas Jaekel strcpy(aq.zev_queue_name.zev_name, arg);
886add9520fSAndreas Jaekel
887add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_REMOVE_QUEUE, &aq)) {
888add9520fSAndreas Jaekel perror("removing queue failed");
889add9520fSAndreas Jaekel return (EXIT_FAILURE);
890add9520fSAndreas Jaekel }
891add9520fSAndreas Jaekel return (0);
892add9520fSAndreas Jaekel }
893add9520fSAndreas Jaekel
894add9520fSAndreas Jaekel static int
zev_set_global_max_queue_len(int fd,char * arg)895add9520fSAndreas Jaekel zev_set_global_max_queue_len(int fd, char *arg)
896add9520fSAndreas Jaekel {
897add9520fSAndreas Jaekel uint64_t maxqueuelen;
898add9520fSAndreas Jaekel
899174dc952SAndreas Jaekel if (!arg) {
900174dc952SAndreas Jaekel fprintf(stderr, "missing queue length parameter\n");
901174dc952SAndreas Jaekel return (EXIT_FAILURE);
902174dc952SAndreas Jaekel }
903174dc952SAndreas Jaekel
904add9520fSAndreas Jaekel errno = 0;
905add9520fSAndreas Jaekel maxqueuelen = strtol(arg, (char **)NULL, 10);
906add9520fSAndreas Jaekel if (errno) {
907add9520fSAndreas Jaekel fprintf(stderr, "invalid queue length parameter: %s\n", arg);
908add9520fSAndreas Jaekel return (EXIT_FAILURE);
909add9520fSAndreas Jaekel }
910add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_MAX_QUEUE_LEN, &maxqueuelen)) {
911add9520fSAndreas Jaekel perror("setting max queue length failed");
912fec460f8SAndreas Jaekel return (EXIT_FAILURE);
913fec460f8SAndreas Jaekel }
914fec460f8SAndreas Jaekel return (0);
915fec460f8SAndreas Jaekel }
916fec460f8SAndreas Jaekel
917fec460f8SAndreas Jaekel static int
zev_mute_unmute_impl(int fd,char * poolname,int mute)918a18c35b9SAndreas Jaekel zev_mute_unmute_impl(int fd, char *poolname, int mute)
919a18c35b9SAndreas Jaekel {
920a18c35b9SAndreas Jaekel zev_ioctl_poolarg_t pa;
921a18c35b9SAndreas Jaekel int len;
922a18c35b9SAndreas Jaekel int op = mute ? ZEV_IOC_MUTE_POOL : ZEV_IOC_UNMUTE_POOL;
923a18c35b9SAndreas Jaekel len = strlen(poolname);
924a18c35b9SAndreas Jaekel if (len <= 0 || len >= sizeof(pa.zev_poolname)) {
925a18c35b9SAndreas Jaekel fprintf(stderr, "invalid poolname: %s\n", poolname);
926a18c35b9SAndreas Jaekel return (EXIT_FAILURE);
927a18c35b9SAndreas Jaekel }
928a18c35b9SAndreas Jaekel strcpy(pa.zev_poolname, poolname);
929a18c35b9SAndreas Jaekel pa.zev_poolname_len = len;
930a18c35b9SAndreas Jaekel if (ioctl(fd, op, &pa)) {
931a18c35b9SAndreas Jaekel perror("muting pool data failed");
932a18c35b9SAndreas Jaekel return (EXIT_FAILURE);
933a18c35b9SAndreas Jaekel }
934a18c35b9SAndreas Jaekel return (0);
935a18c35b9SAndreas Jaekel }
936a18c35b9SAndreas Jaekel
937a18c35b9SAndreas Jaekel int
zev_mute_pool(int fd,char * poolname)938a18c35b9SAndreas Jaekel zev_mute_pool(int fd, char *poolname)
939a18c35b9SAndreas Jaekel {
940a18c35b9SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 1);
941a18c35b9SAndreas Jaekel }
942a18c35b9SAndreas Jaekel
943a18c35b9SAndreas Jaekel int
zev_unmute_pool(int fd,char * poolname)944a18c35b9SAndreas Jaekel zev_unmute_pool(int fd, char *poolname)
945a18c35b9SAndreas Jaekel {
946a18c35b9SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 0);
947a18c35b9SAndreas Jaekel }
948a18c35b9SAndreas Jaekel
949888fea18SAndreas Jaekel static int
zev_debug_info(int fd)950add9520fSAndreas Jaekel zev_debug_info(int fd)
951add9520fSAndreas Jaekel {
952add9520fSAndreas Jaekel zev_ioctl_debug_info_t di;
953add9520fSAndreas Jaekel
954add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_DEBUG_INFO, &di)) {
955add9520fSAndreas Jaekel perror("getting zev debug info failed");
956add9520fSAndreas Jaekel return (EXIT_FAILURE);
957add9520fSAndreas Jaekel }
958add9520fSAndreas Jaekel
959add9520fSAndreas Jaekel printf("memory allocated: %llu bytes\n", di.zev_memory_allocated);
960205ed6bfSAndreas Jaekel printf("checksum cache size: %llu\n", di.zev_chksum_cache_size);
961205ed6bfSAndreas Jaekel printf("checksum cache hits: %llu\n", di.zev_chksum_cache_hits);
962205ed6bfSAndreas Jaekel printf("checksum cache misses: %llu\n", di.zev_chksum_cache_misses);
963add9520fSAndreas Jaekel return 0;
964add9520fSAndreas Jaekel }
965add9520fSAndreas Jaekel
966add9520fSAndreas Jaekel static int
zev_mark(int fd,char * arg)967888fea18SAndreas Jaekel zev_mark(int fd, char *arg)
968888fea18SAndreas Jaekel {
969888fea18SAndreas Jaekel zev_ioctl_mark_t *mark;
970888fea18SAndreas Jaekel uint64_t guid;
971888fea18SAndreas Jaekel int len;
972888fea18SAndreas Jaekel char *p;
973888fea18SAndreas Jaekel
974888fea18SAndreas Jaekel p = strchr(arg, ':');
975888fea18SAndreas Jaekel if (!p) {
976888fea18SAndreas Jaekel fprintf(stderr, "expected value is <guid>:<payload>, "
977888fea18SAndreas Jaekel "e.g. '123:hello'\n");
978888fea18SAndreas Jaekel exit (EXIT_FAILURE);
979888fea18SAndreas Jaekel }
980888fea18SAndreas Jaekel *p = '\n';
981888fea18SAndreas Jaekel p++;
982888fea18SAndreas Jaekel
983888fea18SAndreas Jaekel errno = 0;
984add9520fSAndreas Jaekel guid = strtoll(arg, (char **)NULL, 10);
985888fea18SAndreas Jaekel if (errno) {
986888fea18SAndreas Jaekel fprintf(stderr, "guid must be a number.\n");
987888fea18SAndreas Jaekel exit (EXIT_FAILURE);
988888fea18SAndreas Jaekel }
989888fea18SAndreas Jaekel
990888fea18SAndreas Jaekel len = strlen(p);
991888fea18SAndreas Jaekel
992888fea18SAndreas Jaekel mark = malloc(sizeof(*mark) + len + 1);
993888fea18SAndreas Jaekel if (!mark) {
994888fea18SAndreas Jaekel fprintf(stderr, "can't allocate mark structure: %s\n",
995888fea18SAndreas Jaekel strerror(errno));
996888fea18SAndreas Jaekel exit (EXIT_FAILURE);
997888fea18SAndreas Jaekel }
998888fea18SAndreas Jaekel mark->zev_guid = guid;
999888fea18SAndreas Jaekel mark->zev_mark_id = 0;
1000888fea18SAndreas Jaekel mark->zev_payload_len = len;
1001888fea18SAndreas Jaekel strcpy(ZEV_PAYLOAD(mark), p);
1002888fea18SAndreas Jaekel
1003888fea18SAndreas Jaekel if (ioctl(fd, ZEV_IOC_MARK, mark)) {
1004888fea18SAndreas Jaekel perror("queueing mark failed");
1005888fea18SAndreas Jaekel return (EXIT_FAILURE);
1006888fea18SAndreas Jaekel }
1007888fea18SAndreas Jaekel
1008888fea18SAndreas Jaekel printf("mark id: %lu\n", mark->zev_mark_id);
1009888fea18SAndreas Jaekel return (0);
1010888fea18SAndreas Jaekel }
1011888fea18SAndreas Jaekel
1012add9520fSAndreas Jaekel static int
zev_queue_blocking(int fd,char * arg,int block)1013add9520fSAndreas Jaekel zev_queue_blocking(int fd, char *arg, int block)
1014add9520fSAndreas Jaekel {
1015add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1016add9520fSAndreas Jaekel
10176a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
10186a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1019add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1020add9520fSAndreas Jaekel return EXIT_FAILURE;
1021add9520fSAndreas Jaekel }
10226a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1023add9520fSAndreas Jaekel
1024add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1025add9520fSAndreas Jaekel perror("getting queue properties failed");
1026add9520fSAndreas Jaekel return (EXIT_FAILURE);
1027add9520fSAndreas Jaekel }
1028add9520fSAndreas Jaekel if (block) {
1029add9520fSAndreas Jaekel gqp.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
1030add9520fSAndreas Jaekel } else {
1031add9520fSAndreas Jaekel gqp.zev_flags &= ~ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
1032add9520fSAndreas Jaekel }
1033add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1034add9520fSAndreas Jaekel perror("setting queue properties failed");
1035add9520fSAndreas Jaekel return (EXIT_FAILURE);
1036add9520fSAndreas Jaekel }
1037add9520fSAndreas Jaekel return (0);
1038add9520fSAndreas Jaekel }
1039add9520fSAndreas Jaekel
1040add9520fSAndreas Jaekel static int
zev_set_max_queue_len(int fd,char * arg,char * len)1041add9520fSAndreas Jaekel zev_set_max_queue_len(int fd, char *arg, char *len)
1042add9520fSAndreas Jaekel {
1043add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1044add9520fSAndreas Jaekel
1045add9520fSAndreas Jaekel if (!len) {
1046add9520fSAndreas Jaekel fprintf(stderr, "queue size parameter missing.\n");
1047add9520fSAndreas Jaekel return EXIT_FAILURE;
1048add9520fSAndreas Jaekel }
1049add9520fSAndreas Jaekel
10506a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
10516a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1052add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1053add9520fSAndreas Jaekel return EXIT_FAILURE;
1054add9520fSAndreas Jaekel }
10556a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1056add9520fSAndreas Jaekel
1057add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1058add9520fSAndreas Jaekel perror("getting queue properties failed");
1059add9520fSAndreas Jaekel return (EXIT_FAILURE);
1060add9520fSAndreas Jaekel }
1061add9520fSAndreas Jaekel gqp.zev_max_queue_len = atol(len);
1062add9520fSAndreas Jaekel if (gqp.zev_max_queue_len == 0 && strcmp("0", len)) {
1063add9520fSAndreas Jaekel fprintf(stderr, "queue size parameter garbled.\n");
1064add9520fSAndreas Jaekel return (EXIT_FAILURE);
1065add9520fSAndreas Jaekel }
1066add9520fSAndreas Jaekel if (gqp.zev_max_queue_len > ZEV_MAX_QUEUE_LEN) {
1067add9520fSAndreas Jaekel fprintf(stderr, "queue size parameter out of bounds.\n");
1068add9520fSAndreas Jaekel return (EXIT_FAILURE);
1069add9520fSAndreas Jaekel }
1070add9520fSAndreas Jaekel
1071add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1072add9520fSAndreas Jaekel perror("setting queue properties failed");
1073add9520fSAndreas Jaekel return (EXIT_FAILURE);
1074add9520fSAndreas Jaekel }
1075add9520fSAndreas Jaekel return (0);
1076add9520fSAndreas Jaekel }
1077add9520fSAndreas Jaekel
1078add9520fSAndreas Jaekel static int
zev_set_poll_wakeup_queue_len(int fd,char * arg,char * len)1079add9520fSAndreas Jaekel zev_set_poll_wakeup_queue_len(int fd, char *arg, char *len)
1080add9520fSAndreas Jaekel {
1081add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1082add9520fSAndreas Jaekel
1083add9520fSAndreas Jaekel if (!len) {
1084add9520fSAndreas Jaekel fprintf(stderr, "poll throttle parameter missing.\n");
1085add9520fSAndreas Jaekel return EXIT_FAILURE;
1086add9520fSAndreas Jaekel }
1087add9520fSAndreas Jaekel
10886a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
10896a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1090add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1091add9520fSAndreas Jaekel return EXIT_FAILURE;
1092add9520fSAndreas Jaekel }
10936a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1094add9520fSAndreas Jaekel
1095add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1096add9520fSAndreas Jaekel perror("getting queue properties failed");
1097add9520fSAndreas Jaekel return (EXIT_FAILURE);
1098add9520fSAndreas Jaekel }
1099add9520fSAndreas Jaekel gqp.zev_poll_wakeup_threshold = atol(len);
1100add9520fSAndreas Jaekel if (gqp.zev_poll_wakeup_threshold == 0 && strcmp("0", len)) {
1101add9520fSAndreas Jaekel fprintf(stderr, "poll throttle parameter garbled.\n");
1102add9520fSAndreas Jaekel return (EXIT_FAILURE);
1103add9520fSAndreas Jaekel }
11046a6a51eeSAndreas Jaekel if (gqp.zev_poll_wakeup_threshold > ZEV_MAX_POLL_WAKEUP_QUEUE_LEN) {
1105add9520fSAndreas Jaekel fprintf(stderr, "poll throttle parameter out of bounds.\n");
1106add9520fSAndreas Jaekel return (EXIT_FAILURE);
1107add9520fSAndreas Jaekel }
1108add9520fSAndreas Jaekel
1109add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1110add9520fSAndreas Jaekel perror("setting queue properties failed");
1111add9520fSAndreas Jaekel return (EXIT_FAILURE);
1112add9520fSAndreas Jaekel }
1113add9520fSAndreas Jaekel return (0);
1114add9520fSAndreas Jaekel }
1115add9520fSAndreas Jaekel
1116add9520fSAndreas Jaekel static int
zev_queue_properties(int fd,char * arg)1117add9520fSAndreas Jaekel zev_queue_properties(int fd, char *arg)
1118add9520fSAndreas Jaekel {
1119add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1120add9520fSAndreas Jaekel
11216a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
11226a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1123add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1124add9520fSAndreas Jaekel return EXIT_FAILURE;
1125add9520fSAndreas Jaekel }
11266a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1127add9520fSAndreas Jaekel
1128add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1129add9520fSAndreas Jaekel perror("getting queue properties failed");
1130add9520fSAndreas Jaekel return (EXIT_FAILURE);
1131add9520fSAndreas Jaekel }
1132add9520fSAndreas Jaekel
1133add9520fSAndreas Jaekel printf("queue : %s\n", arg);
1134add9520fSAndreas Jaekel printf("max size : %" PRIu64 "\n", gqp.zev_max_queue_len);
1135add9520fSAndreas Jaekel printf("poll throttle: %" PRIu64 "\n", gqp.zev_poll_wakeup_threshold);
1136add9520fSAndreas Jaekel printf("persistent : %s\n",
1137add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no");
1138add9520fSAndreas Jaekel printf("blocking : %s\n",
1139add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? "yes" : "no");
1140add9520fSAndreas Jaekel
1141add9520fSAndreas Jaekel return (0);
1142add9520fSAndreas Jaekel }
1143add9520fSAndreas Jaekel
1144add9520fSAndreas Jaekel static int
zev_list_queues(int fd)1145add9520fSAndreas Jaekel zev_list_queues(int fd)
1146add9520fSAndreas Jaekel {
1147add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1148add9520fSAndreas Jaekel zev_ioctl_get_queue_list_t gql;
1149add9520fSAndreas Jaekel zev_ioctl_get_queue_statistics_t gs;
1150add9520fSAndreas Jaekel uint64_t i;
1151add9520fSAndreas Jaekel char name[ZEV_MAX_QUEUE_NAME_LEN+1];
115293bacbbdSAndreas Jaekel zev_statistics_t zs;
115393bacbbdSAndreas Jaekel
115493bacbbdSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) {
115593bacbbdSAndreas Jaekel perror("getting statistics data failed");
115693bacbbdSAndreas Jaekel return (EXIT_FAILURE);
115793bacbbdSAndreas Jaekel }
1158add9520fSAndreas Jaekel
1159add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_LIST, &gql)) {
1160add9520fSAndreas Jaekel perror("getting queue list failed");
1161add9520fSAndreas Jaekel return (EXIT_FAILURE);
1162add9520fSAndreas Jaekel }
1163add9520fSAndreas Jaekel
1164add9520fSAndreas Jaekel printf("Name Size "
116593bacbbdSAndreas Jaekel "Size%% Max Size Per Block\n");
1166add9520fSAndreas Jaekel
1167add9520fSAndreas Jaekel for (i=0; i<gql.zev_n_queues; i++) {
1168add9520fSAndreas Jaekel strncpy(name, gql.zev_queue_name[i].zev_name,
1169add9520fSAndreas Jaekel ZEV_MAX_QUEUE_NAME_LEN);
1170add9520fSAndreas Jaekel name[gql.zev_queue_name[i].zev_namelen] = '\0';
1171add9520fSAndreas Jaekel
11726a6a51eeSAndreas Jaekel memcpy(gqp.zev_queue_name.zev_name,
11736a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
11746a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen =
11756a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_namelen;
1176add9520fSAndreas Jaekel
1177add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1178add9520fSAndreas Jaekel if (errno == ENOENT)
1179add9520fSAndreas Jaekel continue;
1180add9520fSAndreas Jaekel perror("getting queue properties failed");
1181add9520fSAndreas Jaekel return (EXIT_FAILURE);
1182add9520fSAndreas Jaekel }
1183add9520fSAndreas Jaekel
11846a6a51eeSAndreas Jaekel memcpy(gs.zev_queue_name.zev_name,
11856a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
11866a6a51eeSAndreas Jaekel gs.zev_queue_name.zev_namelen =
11876a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_namelen;
1188add9520fSAndreas Jaekel
1189add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_STATISTICS, &gs)) {
1190add9520fSAndreas Jaekel if (errno == ENOENT)
1191add9520fSAndreas Jaekel continue;
1192add9520fSAndreas Jaekel perror("getting statistics data failed");
1193add9520fSAndreas Jaekel return (EXIT_FAILURE);
1194add9520fSAndreas Jaekel }
1195add9520fSAndreas Jaekel
119693bacbbdSAndreas Jaekel if (gqp.zev_max_queue_len == 0) {
119793bacbbdSAndreas Jaekel gqp.zev_max_queue_len = zs.zev_max_queue_len;
119893bacbbdSAndreas Jaekel }
119993bacbbdSAndreas Jaekel printf("%-40s %-10" PRIu64 " %5.1f %-10" PRIu64
1200add9520fSAndreas Jaekel " %-3s %-3s\n",
1201add9520fSAndreas Jaekel name,
120293bacbbdSAndreas Jaekel gs.zev_statistics.zev_queue_len * 100.0 /
120393bacbbdSAndreas Jaekel gqp.zev_max_queue_len,
1204add9520fSAndreas Jaekel gs.zev_statistics.zev_queue_len,
1205add9520fSAndreas Jaekel gqp.zev_max_queue_len,
1206add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no",
1207add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ?
1208add9520fSAndreas Jaekel "yes" : "no");
1209add9520fSAndreas Jaekel }
1210add9520fSAndreas Jaekel
1211add9520fSAndreas Jaekel return (0);
1212add9520fSAndreas Jaekel }
1213add9520fSAndreas Jaekel
121442110aacSAndreas Jaekel static int
zev_checksum(int dev_fd,char * filename)121542110aacSAndreas Jaekel zev_checksum(int dev_fd, char *filename)
121642110aacSAndreas Jaekel {
121742110aacSAndreas Jaekel int fd;
121842110aacSAndreas Jaekel offset_t off;
121942110aacSAndreas Jaekel offset_t data;
122042110aacSAndreas Jaekel zev_sig_t *sig;
122142110aacSAndreas Jaekel char *buf;
122242110aacSAndreas Jaekel zev_ioctl_get_signatures_t *gs;
122342110aacSAndreas Jaekel int i;
122442110aacSAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
122542110aacSAndreas Jaekel int buf_size;
122642110aacSAndreas Jaekel
122742110aacSAndreas Jaekel /* control struct, one lv1 signature and up to 256 lv0 signatures */
122842110aacSAndreas Jaekel buf_size = (1 + 256) * sizeof(zev_sig_t);
122942110aacSAndreas Jaekel buf = malloc(sizeof(zev_ioctl_get_signatures_t) + buf_size);
123042110aacSAndreas Jaekel if (!buf) {
123142110aacSAndreas Jaekel perror("can't allocate checksum buffer");
123242110aacSAndreas Jaekel return (EXIT_FAILURE);
123342110aacSAndreas Jaekel }
123442110aacSAndreas Jaekel
123542110aacSAndreas Jaekel fd = open(filename, O_RDONLY);
123642110aacSAndreas Jaekel if (fd < 0) {
123742110aacSAndreas Jaekel perror("can't open file");
123842110aacSAndreas Jaekel return (EXIT_FAILURE);
123942110aacSAndreas Jaekel }
124042110aacSAndreas Jaekel
124142110aacSAndreas Jaekel gs = (zev_ioctl_get_signatures_t *)buf;
124242110aacSAndreas Jaekel gs->zev_fd = fd;
124342110aacSAndreas Jaekel gs->zev_bufsize = buf_size;
124442110aacSAndreas Jaekel
124542110aacSAndreas Jaekel off = 0;
124642110aacSAndreas Jaekel data = 0;
124742110aacSAndreas Jaekel while (1) {
124842110aacSAndreas Jaekel errno = 0;
124942110aacSAndreas Jaekel data = llseek(fd, off, SEEK_DATA);
125042110aacSAndreas Jaekel if (data < 0) {
125142110aacSAndreas Jaekel if (errno == ENXIO) /* no more data */
125242110aacSAndreas Jaekel break;
125342110aacSAndreas Jaekel perror("llseek failed");
125442110aacSAndreas Jaekel goto err;
125542110aacSAndreas Jaekel }
125642110aacSAndreas Jaekel data = P2ALIGN(data, ZEV_L1_SIZE);
125742110aacSAndreas Jaekel off = data + ZEV_L1_SIZE;
125842110aacSAndreas Jaekel
125942110aacSAndreas Jaekel gs->zev_offset = data;
126042110aacSAndreas Jaekel gs->zev_len = ZEV_L1_SIZE;
126142110aacSAndreas Jaekel
126242110aacSAndreas Jaekel if (ioctl(dev_fd, ZEV_IOC_GET_FILE_SIGNATURES, gs)) {
126342110aacSAndreas Jaekel perror("ioctl to get signatures failed");
126442110aacSAndreas Jaekel goto err;
126542110aacSAndreas Jaekel }
126642110aacSAndreas Jaekel
126742110aacSAndreas Jaekel for (i=0; i<gs->zev_signature_cnt; i++) {
126842110aacSAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(gs);
126942110aacSAndreas Jaekel sig += i;
127042110aacSAndreas Jaekel sig2hex_direct(sig->value, sigval);
127142110aacSAndreas Jaekel printf("level %d, offset %llu, value %s\n",
127242110aacSAndreas Jaekel sig->level, sig->block_offset, sigval);
127342110aacSAndreas Jaekel }
127442110aacSAndreas Jaekel }
127542110aacSAndreas Jaekel
127642110aacSAndreas Jaekel free(buf);
127742110aacSAndreas Jaekel close(fd);
127842110aacSAndreas Jaekel return 0;
127942110aacSAndreas Jaekel err:
128042110aacSAndreas Jaekel free(buf);
128142110aacSAndreas Jaekel close(fd);
128242110aacSAndreas Jaekel return (EXIT_FAILURE);
128342110aacSAndreas Jaekel }
128442110aacSAndreas Jaekel
1285b690436dSAndreas Jaekel typedef struct zevstat {
1286b690436dSAndreas Jaekel uint64_t ns_start;
1287b690436dSAndreas Jaekel uint64_t events[ZEV_OP_MIN + ZEV_OP_MAX];
1288b690436dSAndreas Jaekel uint64_t guids;
1289b690436dSAndreas Jaekel uint64_t total_events;
1290b690436dSAndreas Jaekel uint64_t total_guids;
1291b690436dSAndreas Jaekel avl_tree_t guids_interval;
1292b690436dSAndreas Jaekel avl_tree_t guids_runtime;
1293b690436dSAndreas Jaekel } zevstat_t;
1294b690436dSAndreas Jaekel
1295b690436dSAndreas Jaekel typedef struct zev_guidtrack_t {
1296b690436dSAndreas Jaekel uint64_t guid;
1297b690436dSAndreas Jaekel avl_node_t avl_interval;
1298b690436dSAndreas Jaekel avl_node_t avl_runtime;
1299b690436dSAndreas Jaekel } zev_guidtrack_t;
1300b690436dSAndreas Jaekel
1301b690436dSAndreas Jaekel zevstat_t zevstat;
1302b690436dSAndreas Jaekel
1303b690436dSAndreas Jaekel static void
zev_eventstat(char * buf,int len)1304b690436dSAndreas Jaekel zev_eventstat(char *buf, int len)
1305b690436dSAndreas Jaekel {
1306b690436dSAndreas Jaekel zev_header_t *rec = (zev_header_t *)buf;
1307b690436dSAndreas Jaekel zev_guidtrack_t *gt;
1308b690436dSAndreas Jaekel zev_guidtrack_t *gt_int;
1309b690436dSAndreas Jaekel zev_guidtrack_t to_find;
1310b690436dSAndreas Jaekel avl_index_t where;
1311b690436dSAndreas Jaekel
1312b690436dSAndreas Jaekel zevstat.total_events++;
1313b690436dSAndreas Jaekel zevstat.events[rec->op]++;
1314b690436dSAndreas Jaekel
1315b690436dSAndreas Jaekel to_find.guid = rec->guid;
1316b690436dSAndreas Jaekel gt = avl_find(&zevstat.guids_runtime, &to_find, &where);
1317b690436dSAndreas Jaekel if (!gt) {
1318b690436dSAndreas Jaekel gt = malloc(sizeof(*gt));
1319b690436dSAndreas Jaekel if (!gt) {
1320b690436dSAndreas Jaekel perror("can't get guid tracking record");
1321b690436dSAndreas Jaekel exit (EXIT_FAILURE);
1322b690436dSAndreas Jaekel }
1323b690436dSAndreas Jaekel gt->guid = rec->guid;
1324b690436dSAndreas Jaekel avl_insert(&zevstat.guids_runtime, gt, where);
1325b690436dSAndreas Jaekel }
1326b690436dSAndreas Jaekel gt_int = avl_find(&zevstat.guids_interval, &to_find, &where);
1327b690436dSAndreas Jaekel if (!gt_int)
1328b690436dSAndreas Jaekel avl_insert(&zevstat.guids_interval, gt, where);
1329b690436dSAndreas Jaekel }
1330b690436dSAndreas Jaekel
1331b690436dSAndreas Jaekel static void
zev_eventstat_interval(FILE * out)1332f432e238SAndreas Jaekel zev_eventstat_interval(FILE *out)
1333b690436dSAndreas Jaekel {
1334b690436dSAndreas Jaekel uint64_t events;
1335b690436dSAndreas Jaekel int i;
1336b690436dSAndreas Jaekel zev_guidtrack_t *gt;
1337b690436dSAndreas Jaekel
1338b690436dSAndreas Jaekel events = 0;
1339b690436dSAndreas Jaekel for (i = ZEV_OP_MIN; i <= ZEV_OP_MAX; i++) {
1340b690436dSAndreas Jaekel events += zevstat.events[i];
1341b690436dSAndreas Jaekel }
1342b690436dSAndreas Jaekel
1343b690436dSAndreas Jaekel if (verbose) {
1344f432e238SAndreas Jaekel fprintf(out, "%u %6llu %6llu %6llu %6llu ",
1345b690436dSAndreas Jaekel time(NULL),
1346b690436dSAndreas Jaekel events,
1347b690436dSAndreas Jaekel zevstat.total_events,
1348b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_interval),
1349b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_runtime));
1350b690436dSAndreas Jaekel for (i = ZEV_OP_MIN; i <= ZEV_OP_MAX; i++)
1351f432e238SAndreas Jaekel fprintf(out, "%6llu ", zevstat.events[i]);
1352f432e238SAndreas Jaekel fprintf(out, "\n");
1353b690436dSAndreas Jaekel } else {
1354f432e238SAndreas Jaekel fprintf(out, "%u %6llu %6llu %6llu %6llu\n",
1355b690436dSAndreas Jaekel time(NULL),
1356b690436dSAndreas Jaekel events,
1357b690436dSAndreas Jaekel zevstat.total_events,
1358b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_interval),
1359b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_runtime));
1360b690436dSAndreas Jaekel }
1361b690436dSAndreas Jaekel memset(&zevstat.events, 0, sizeof(zevstat.events));
1362b690436dSAndreas Jaekel zevstat.guids = 0;
1363b690436dSAndreas Jaekel while (gt = avl_first(&zevstat.guids_interval))
1364b690436dSAndreas Jaekel avl_remove(&zevstat.guids_interval, gt);
1365f432e238SAndreas Jaekel fflush(out);
1366b690436dSAndreas Jaekel }
1367b690436dSAndreas Jaekel
1368b690436dSAndreas Jaekel static int
zev_evcompar(const void * a,const void * b)1369b690436dSAndreas Jaekel zev_evcompar(const void *a, const void *b)
1370b690436dSAndreas Jaekel {
1371b690436dSAndreas Jaekel const zev_guidtrack_t *ga = a;
1372b690436dSAndreas Jaekel const zev_guidtrack_t *gb = b;
1373b690436dSAndreas Jaekel
1374b690436dSAndreas Jaekel if (ga->guid > gb->guid)
1375b690436dSAndreas Jaekel return 1;
1376b690436dSAndreas Jaekel if (ga->guid < gb->guid)
1377b690436dSAndreas Jaekel return -1;
1378b690436dSAndreas Jaekel return 0;
1379b690436dSAndreas Jaekel }
1380b690436dSAndreas Jaekel
1381b690436dSAndreas Jaekel static int
zev_zevstat(int fd,char * s_interval,char * s_count,char * outfile)1382f432e238SAndreas Jaekel zev_zevstat(int fd, char *s_interval, char *s_count, char *outfile)
1383b690436dSAndreas Jaekel {
1384b690436dSAndreas Jaekel uint64_t interval = 1000;
1385b690436dSAndreas Jaekel uint64_t ms;
1386b690436dSAndreas Jaekel uint64_t t_until;
1387b690436dSAndreas Jaekel uint64_t t_now;
1388b690436dSAndreas Jaekel int cnt = -1;
1389b690436dSAndreas Jaekel struct pollfd pfd[1];
1390b690436dSAndreas Jaekel int ret;
1391b690436dSAndreas Jaekel char buf[4096];
1392b690436dSAndreas Jaekel zev_event_t *ev;
1393b690436dSAndreas Jaekel int off = 0;
1394b690436dSAndreas Jaekel zev_ioctl_add_queue_t aq;
1395b690436dSAndreas Jaekel int q_fd;
1396b690436dSAndreas Jaekel zev_guidtrack_t *gt;
1397f432e238SAndreas Jaekel FILE *out = stdout;
1398f432e238SAndreas Jaekel struct stat st;
1399f432e238SAndreas Jaekel char filename[MAXPATHLEN];
1400f432e238SAndreas Jaekel int retry;
1401f432e238SAndreas Jaekel
1402f432e238SAndreas Jaekel if (outfile) {
1403f432e238SAndreas Jaekel retry = 0;
1404f432e238SAndreas Jaekel strncpy(filename, outfile, sizeof(filename));
1405f432e238SAndreas Jaekel while (stat(filename, &st) == 0) {
1406f432e238SAndreas Jaekel /* file exists */
1407f432e238SAndreas Jaekel snprintf(filename, sizeof(filename),
1408f432e238SAndreas Jaekel "%s.%d", outfile, retry);
1409f432e238SAndreas Jaekel retry++;
1410f432e238SAndreas Jaekel }
1411f432e238SAndreas Jaekel out = fopen(filename, "wb+");
1412f432e238SAndreas Jaekel if (!out) {
1413f432e238SAndreas Jaekel perror("opening output file failed");
1414f432e238SAndreas Jaekel return (EXIT_FAILURE);
1415f432e238SAndreas Jaekel }
1416f432e238SAndreas Jaekel }
1417b690436dSAndreas Jaekel
1418b690436dSAndreas Jaekel memset(&zevstat, 0, sizeof(zevstat));
1419b690436dSAndreas Jaekel avl_create(&zevstat.guids_runtime, zev_evcompar,
1420b690436dSAndreas Jaekel sizeof(zev_guidtrack_t),
1421b690436dSAndreas Jaekel offsetof(zev_guidtrack_t, avl_runtime));
1422b690436dSAndreas Jaekel avl_create(&zevstat.guids_interval, zev_evcompar,
1423b690436dSAndreas Jaekel sizeof(zev_guidtrack_t),
1424b690436dSAndreas Jaekel offsetof(zev_guidtrack_t, avl_interval));
1425b690436dSAndreas Jaekel
142619695134SAndreas Jaekel if (s_interval) {
1427b690436dSAndreas Jaekel interval = atol(s_interval);
1428b690436dSAndreas Jaekel if (interval == 0) {
1429b690436dSAndreas Jaekel fprintf(stderr, "invalid interval.\n");
1430b690436dSAndreas Jaekel return (EXIT_FAILURE);
1431b690436dSAndreas Jaekel }
1432b690436dSAndreas Jaekel interval *= 1000;
143319695134SAndreas Jaekel }
1434b690436dSAndreas Jaekel if (s_count) {
1435b690436dSAndreas Jaekel cnt = atol(s_count);
1436b690436dSAndreas Jaekel if (interval == 0) {
1437b690436dSAndreas Jaekel fprintf(stderr, "invalid count.\n");
1438b690436dSAndreas Jaekel return (EXIT_FAILURE);
1439b690436dSAndreas Jaekel }
1440b690436dSAndreas Jaekel }
1441b690436dSAndreas Jaekel
1442b690436dSAndreas Jaekel aq.zev_max_queue_len = 1024 * 1024;
1443c99a1a25SAndreas Jaekel aq.zev_flags = ZEV_FL_INITIALLY_EMPTY;
1444b690436dSAndreas Jaekel snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN,
1445b690436dSAndreas Jaekel "zevstat.%ld.%ld", time(NULL), getpid());
1446b690436dSAndreas Jaekel aq.zev_namelen = strlen(aq.zev_name);
1447b690436dSAndreas Jaekel
1448b690436dSAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
1449b690436dSAndreas Jaekel perror("adding temporary queue failed");
1450b690436dSAndreas Jaekel return (EXIT_FAILURE);
1451b690436dSAndreas Jaekel }
1452b690436dSAndreas Jaekel
1453b690436dSAndreas Jaekel snprintf(buf, sizeof(buf),
1454b690436dSAndreas Jaekel "/devices/pseudo/zev@0:%s", aq.zev_name);
1455b690436dSAndreas Jaekel q_fd = open(buf, O_RDONLY);
1456b690436dSAndreas Jaekel if (q_fd < 0) {
1457b690436dSAndreas Jaekel perror("opening queue device failed");
1458b690436dSAndreas Jaekel return (EXIT_FAILURE);
1459b690436dSAndreas Jaekel }
1460b690436dSAndreas Jaekel
1461b690436dSAndreas Jaekel pfd[0].fd = q_fd;
1462b690436dSAndreas Jaekel pfd[0].events = POLLIN;
1463b690436dSAndreas Jaekel
1464b690436dSAndreas Jaekel /* drain queue */
146519695134SAndreas Jaekel while ((ret = poll(pfd, 1, 0)) > 0) {
1466b690436dSAndreas Jaekel if (read(q_fd, buf, sizeof(buf)) < 0) {
1467b690436dSAndreas Jaekel perror("read failed");
1468b690436dSAndreas Jaekel close(q_fd);
1469b690436dSAndreas Jaekel return(EXIT_FAILURE);
1470b690436dSAndreas Jaekel }
1471b690436dSAndreas Jaekel }
1472b690436dSAndreas Jaekel if (ret < 0) {
1473b690436dSAndreas Jaekel perror("poll failed");
1474b690436dSAndreas Jaekel close(q_fd);
1475b690436dSAndreas Jaekel return(EXIT_FAILURE);
1476b690436dSAndreas Jaekel }
1477b690436dSAndreas Jaekel
1478f432e238SAndreas Jaekel fprintf(out, "timestamp events tevents guids tguids");
1479b690436dSAndreas Jaekel if (verbose) {
1480f432e238SAndreas Jaekel fprintf(out, " error mark mount umount zvol_w ");
1481f432e238SAndreas Jaekel fprintf(out, "zvol_t close create mkdir mxattr ");
1482f432e238SAndreas Jaekel fprintf(out, "remove rmdir link symlnk rename ");
1483f432e238SAndreas Jaekel fprintf(out, "write trunc setatt acl");
1484b690436dSAndreas Jaekel }
1485f432e238SAndreas Jaekel fprintf(out, "\n");
1486b690436dSAndreas Jaekel while (cnt) {
1487b690436dSAndreas Jaekel t_until = gethrtime() + (interval * 1000000);
1488b690436dSAndreas Jaekel ms = interval;
1489b690436dSAndreas Jaekel do {
1490b690436dSAndreas Jaekel ret = poll(pfd, 1, ms);
1491b690436dSAndreas Jaekel t_now = gethrtime();
1492b690436dSAndreas Jaekel if (t_now < t_until) {
1493b690436dSAndreas Jaekel ms = t_until - t_now;
1494b690436dSAndreas Jaekel ms /= 1000000ull;
1495b690436dSAndreas Jaekel }
1496b690436dSAndreas Jaekel if (ret < 0) {
1497b690436dSAndreas Jaekel perror("poll failed");
1498b690436dSAndreas Jaekel close(q_fd);
1499b690436dSAndreas Jaekel return(EXIT_FAILURE);
1500b690436dSAndreas Jaekel }
1501b690436dSAndreas Jaekel if (!(pfd[0].revents & POLLIN))
1502b690436dSAndreas Jaekel continue;
1503b690436dSAndreas Jaekel /* data available */
1504b690436dSAndreas Jaekel ret = read(q_fd, buf, sizeof(buf));
1505b690436dSAndreas Jaekel if (ret < 0) {
1506b690436dSAndreas Jaekel perror("read failed");
1507b690436dSAndreas Jaekel close(q_fd);
1508b690436dSAndreas Jaekel return(EXIT_FAILURE);
1509b690436dSAndreas Jaekel }
1510b690436dSAndreas Jaekel if (ret == 0)
1511b690436dSAndreas Jaekel continue;
1512b690436dSAndreas Jaekel while (ret > off) {
1513b690436dSAndreas Jaekel ev = (zev_event_t *)(buf + off);
1514b690436dSAndreas Jaekel zev_eventstat(buf + off, ev->header.record_len);
1515b690436dSAndreas Jaekel off += ev->header.record_len;
1516b690436dSAndreas Jaekel }
1517b690436dSAndreas Jaekel off = 0;
1518b690436dSAndreas Jaekel } while ((t_now) < t_until && (ms > 0));
1519f432e238SAndreas Jaekel zev_eventstat_interval(out);
1520b690436dSAndreas Jaekel if (cnt > 0)
1521b690436dSAndreas Jaekel cnt--;
1522b690436dSAndreas Jaekel }
1523b690436dSAndreas Jaekel close(q_fd);
1524f432e238SAndreas Jaekel if (outfile)
1525f432e238SAndreas Jaekel fclose(out);
1526b690436dSAndreas Jaekel while (gt = avl_first(&zevstat.guids_interval))
1527b690436dSAndreas Jaekel avl_remove(&zevstat.guids_interval, gt);
1528b690436dSAndreas Jaekel while (gt = avl_first(&zevstat.guids_runtime)) {
1529b690436dSAndreas Jaekel avl_remove(&zevstat.guids_runtime, gt);
1530b690436dSAndreas Jaekel free(gt);
1531b690436dSAndreas Jaekel }
1532b690436dSAndreas Jaekel return EXIT_SUCCESS;
1533b690436dSAndreas Jaekel }
1534b690436dSAndreas Jaekel
1535f432e238SAndreas Jaekel static int
zev_report(int fd,char * basename)1536f432e238SAndreas Jaekel zev_report(int fd, char *basename)
1537f432e238SAndreas Jaekel {
1538f432e238SAndreas Jaekel char filename[MAXPATHLEN];
1539f432e238SAndreas Jaekel char count[10];
1540f432e238SAndreas Jaekel time_t now;
1541f432e238SAndreas Jaekel time_t midnight;
1542f432e238SAndreas Jaekel struct tm tm;
1543f432e238SAndreas Jaekel int minutes;
1544f432e238SAndreas Jaekel int ret;
1545f432e238SAndreas Jaekel
1546f432e238SAndreas Jaekel verbose++;
1547f432e238SAndreas Jaekel while (1) {
1548f432e238SAndreas Jaekel now = time(NULL);
1549f432e238SAndreas Jaekel localtime_r(&now, &tm);
1550f432e238SAndreas Jaekel snprintf(filename, sizeof(filename), "%s.%04d-%02d-%02d",
1551f432e238SAndreas Jaekel basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
1552f432e238SAndreas Jaekel tm.tm_sec = 0;
1553f432e238SAndreas Jaekel tm.tm_min = 0;
1554f432e238SAndreas Jaekel tm.tm_hour = 0;
1555f432e238SAndreas Jaekel tm.tm_mday++; /* works for Jan 32nd, Feb 30th, etc. */
1556f432e238SAndreas Jaekel midnight = mktime(&tm);
1557f432e238SAndreas Jaekel if (now % 60)
1558f432e238SAndreas Jaekel sleep(60 - (now % 60));
1559f432e238SAndreas Jaekel minutes = (midnight - time(NULL)) / 60;
1560f432e238SAndreas Jaekel snprintf(count, sizeof(count), "%d", minutes);
1561f432e238SAndreas Jaekel ret = zev_zevstat(fd, "60", count, filename);
1562f432e238SAndreas Jaekel if (ret)
1563f432e238SAndreas Jaekel return EXIT_FAILURE;
1564f432e238SAndreas Jaekel }
1565f432e238SAndreas Jaekel return EXIT_SUCCESS; /* never reached */
1566f432e238SAndreas Jaekel }
1567f432e238SAndreas Jaekel
1568e3455c18SAndreas Jaekel static int
zev_get_zev_version(int fd)1569e3455c18SAndreas Jaekel zev_get_zev_version(int fd)
1570e3455c18SAndreas Jaekel {
1571e3455c18SAndreas Jaekel zev_ioctl_get_zev_version vi;
1572e3455c18SAndreas Jaekel
1573e3455c18SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_ZEV_VERSION, &vi)) {
1574e3455c18SAndreas Jaekel perror("getting zev cersion info failed");
1575e3455c18SAndreas Jaekel return (EXIT_FAILURE);
1576e3455c18SAndreas Jaekel }
1577e3455c18SAndreas Jaekel
1578e3455c18SAndreas Jaekel printf("zev major version: %llu\n", vi.zev_major_version);
1579e3455c18SAndreas Jaekel printf("zev minor version: %llu\n", vi.zev_minor_version);
1580e3455c18SAndreas Jaekel return 0;
1581e3455c18SAndreas Jaekel }
1582e3455c18SAndreas Jaekel
1583a0d677d8SAndreas Jaekel static void
zev_sigint(int sig)1584a0d677d8SAndreas Jaekel zev_sigint(int sig)
1585a0d677d8SAndreas Jaekel {
1586a0d677d8SAndreas Jaekel fflush(stdout);
1587a0d677d8SAndreas Jaekel }
1588a0d677d8SAndreas Jaekel
1589a18c35b9SAndreas Jaekel int
main(int argc,char ** argv)1590a18c35b9SAndreas Jaekel main(int argc, char **argv)
1591a18c35b9SAndreas Jaekel {
1592a18c35b9SAndreas Jaekel int fd;
1593a18c35b9SAndreas Jaekel int c;
1594a18c35b9SAndreas Jaekel extern char *optarg;
15956a6a51eeSAndreas Jaekel int create_tmp_queue = 1;
15966a6a51eeSAndreas Jaekel char buf[MAXPATHLEN];
1597a5090b97SAndreas Jaekel int mode = 0;
1598a5090b97SAndreas Jaekel char *arg = NULL;
1599a5090b97SAndreas Jaekel char *arg2 = NULL;
1600b690436dSAndreas Jaekel char *p;
1601b690436dSAndreas Jaekel
1602a0d677d8SAndreas Jaekel sigset(SIGINT, zev_sigint);
1603a0d677d8SAndreas Jaekel
160450da9edeSAndreas Jaekel /* open device */
160550da9edeSAndreas Jaekel fd = open(zev_device, O_RDONLY);
160650da9edeSAndreas Jaekel if (fd < 0) {
160750da9edeSAndreas Jaekel perror("opening zev device failed");
160850da9edeSAndreas Jaekel return EXIT_FAILURE;
160950da9edeSAndreas Jaekel }
161050da9edeSAndreas Jaekel
1611b690436dSAndreas Jaekel p = strrchr(argv[0], '/');
1612b690436dSAndreas Jaekel if (!p) {
1613b690436dSAndreas Jaekel p = argv[0];
1614b690436dSAndreas Jaekel } else {
1615b690436dSAndreas Jaekel p++;
1616b690436dSAndreas Jaekel }
1617b690436dSAndreas Jaekel if (!strcmp(p, "zevstat")) {
1618b690436dSAndreas Jaekel mode = MD_ZEVSTAT;
161950da9edeSAndreas Jaekel if (argc < 2)
162050da9edeSAndreas Jaekel zevstat_usage(argv[0]);
162150da9edeSAndreas Jaekel if (!strcmp(argv[1], "-v")) {
162250da9edeSAndreas Jaekel if (argc < 3)
162350da9edeSAndreas Jaekel zevstat_usage(argv[0]);
162450da9edeSAndreas Jaekel verbose++;
162550da9edeSAndreas Jaekel arg = argv[2];
162650da9edeSAndreas Jaekel arg2 = argv[3];
162750da9edeSAndreas Jaekel } else {
162850da9edeSAndreas Jaekel arg = argv[1];
162950da9edeSAndreas Jaekel arg2 = argv[2];
163050da9edeSAndreas Jaekel }
1631f432e238SAndreas Jaekel return zev_zevstat(fd, arg, arg2, NULL);
1632f432e238SAndreas Jaekel } else if(!strcmp(p, "zevreport")) {
1633f432e238SAndreas Jaekel mode = MD_ZEV_REPORT;
1634f432e238SAndreas Jaekel if (argc != 2)
1635f432e238SAndreas Jaekel zevreport_usage(argv[0]);
1636f432e238SAndreas Jaekel return zev_report(fd, argv[1]);
1637b690436dSAndreas Jaekel }
1638a18c35b9SAndreas Jaekel
16396a6a51eeSAndreas Jaekel while ((c = getopt(argc, argv,
1640*8cfb36b9SArne Jansen "a:A:b:B:c:d:Df:FgG:hk:lL:m:M:pP:q:Q:r:R:st:T:vV?")) != -1) {
1641a18c35b9SAndreas Jaekel switch(c) {
164216ff6b2fSAndreas Jaekel case 'g':
164316ff6b2fSAndreas Jaekel grep_friendly++;
164416ff6b2fSAndreas Jaekel verbose++;
164516ff6b2fSAndreas Jaekel break;
1646205ed6bfSAndreas Jaekel case 'v':
1647205ed6bfSAndreas Jaekel verbose++;
1648205ed6bfSAndreas Jaekel break;
1649a18c35b9SAndreas Jaekel case 's':
1650a5090b97SAndreas Jaekel mode = MD_STATISTICS;
1651a5090b97SAndreas Jaekel break;
1652a18c35b9SAndreas Jaekel case 'p':
1653a5090b97SAndreas Jaekel mode = MD_POLL_EVENTS;
1654a5090b97SAndreas Jaekel break;
165542110aacSAndreas Jaekel case 'c':
1656a5090b97SAndreas Jaekel mode = MD_CHECKSUMS;
1657a5090b97SAndreas Jaekel arg = optarg;
1658a5090b97SAndreas Jaekel break;
1659add9520fSAndreas Jaekel case 'D':
1660a5090b97SAndreas Jaekel mode = MD_DEBUG_INFO;
1661a5090b97SAndreas Jaekel break;
1662a18c35b9SAndreas Jaekel case 'd':
1663add9520fSAndreas Jaekel close(fd);
1664a18c35b9SAndreas Jaekel zev_device = optarg;
1665add9520fSAndreas Jaekel fd = open(zev_device, O_RDONLY);
1666add9520fSAndreas Jaekel if (fd < 0) {
1667add9520fSAndreas Jaekel perror("opening zev device failed");
1668add9520fSAndreas Jaekel return EXIT_FAILURE;
1669add9520fSAndreas Jaekel }
16706a6a51eeSAndreas Jaekel create_tmp_queue = 0;
16716a6a51eeSAndreas Jaekel break;
16726a6a51eeSAndreas Jaekel case 'q':
16736a6a51eeSAndreas Jaekel snprintf(buf, sizeof(buf),
16746a6a51eeSAndreas Jaekel "/devices/pseudo/zev@0:%s", optarg);
16756a6a51eeSAndreas Jaekel close(fd);
16766a6a51eeSAndreas Jaekel zev_device = buf;
16776a6a51eeSAndreas Jaekel fd = open(zev_device, O_RDONLY);
16786a6a51eeSAndreas Jaekel if (fd < 0) {
16796a6a51eeSAndreas Jaekel perror("opening zev device failed");
16806a6a51eeSAndreas Jaekel return EXIT_FAILURE;
16816a6a51eeSAndreas Jaekel }
16826a6a51eeSAndreas Jaekel create_tmp_queue = 0;
1683a18c35b9SAndreas Jaekel break;
168435526fb3SArne Jansen case 'f':
168535526fb3SArne Jansen fd = open(optarg, O_RDONLY);
168635526fb3SArne Jansen if (fd < 0) {
168735526fb3SArne Jansen perror("opening spool file failed");
168835526fb3SArne Jansen return EXIT_FAILURE;
168935526fb3SArne Jansen }
169035526fb3SArne Jansen mode = MD_DUMP_SPOOL;
169135526fb3SArne Jansen break;
1692add9520fSAndreas Jaekel case 'l':
1693a5090b97SAndreas Jaekel mode = MD_LIST_QUEUES;
1694a5090b97SAndreas Jaekel break;
1695add9520fSAndreas Jaekel case 'Q':
1696a5090b97SAndreas Jaekel mode = MD_SET_GLOBAL_MAX_QUEUE_LEN;
1697a5090b97SAndreas Jaekel arg = optarg;
1698a5090b97SAndreas Jaekel break;
16996a6a51eeSAndreas Jaekel case 'L':
1700a5090b97SAndreas Jaekel mode = MD_SET_MAX_QUEUE_LEN;
1701a5090b97SAndreas Jaekel arg = optarg;
1702a5090b97SAndreas Jaekel arg2 = argv[optind];
1703a5090b97SAndreas Jaekel break;
1704b690436dSAndreas Jaekel case 'T':
1705b690436dSAndreas Jaekel mode = MD_ZEVSTAT;
1706b690436dSAndreas Jaekel arg = optarg;
1707b690436dSAndreas Jaekel arg2 = argv[optind];
1708b690436dSAndreas Jaekel break;
1709f432e238SAndreas Jaekel case 'R':
1710f432e238SAndreas Jaekel mode = MD_ZEV_REPORT;
1711f432e238SAndreas Jaekel arg = optarg;
1712f432e238SAndreas Jaekel break;
1713fec460f8SAndreas Jaekel case 't':
1714a5090b97SAndreas Jaekel mode = MD_SET_POLL_WAKEUP_QUEUE_LEN;
1715a5090b97SAndreas Jaekel arg = optarg;
1716a5090b97SAndreas Jaekel arg2 = argv[optind];
1717a5090b97SAndreas Jaekel break;
1718a18c35b9SAndreas Jaekel case 'm':
1719a5090b97SAndreas Jaekel mode = MD_MUTE_POOL;
1720a5090b97SAndreas Jaekel arg = optarg;
1721a5090b97SAndreas Jaekel break;
1722a18c35b9SAndreas Jaekel case 'M':
1723a5090b97SAndreas Jaekel mode = MD_UNMUTE_POOL;
1724a5090b97SAndreas Jaekel arg = optarg;
1725a5090b97SAndreas Jaekel break;
1726888fea18SAndreas Jaekel case 'k':
1727a5090b97SAndreas Jaekel mode = MD_MARK;
1728a5090b97SAndreas Jaekel arg = optarg;
1729a5090b97SAndreas Jaekel break;
1730add9520fSAndreas Jaekel case 'a':
1731a5090b97SAndreas Jaekel mode = MD_ADD_QUEUE;
1732a5090b97SAndreas Jaekel arg = optarg;
1733a5090b97SAndreas Jaekel break;
17346a6a51eeSAndreas Jaekel case 'A':
1735a5090b97SAndreas Jaekel mode = MD_ADD_BLOCKING_QUEUE;
1736a5090b97SAndreas Jaekel arg = optarg;
1737a5090b97SAndreas Jaekel break;
1738add9520fSAndreas Jaekel case 'r':
1739a5090b97SAndreas Jaekel mode = MD_REMOVE_QUEUE;
1740a5090b97SAndreas Jaekel arg = optarg;
1741a5090b97SAndreas Jaekel break;
1742add9520fSAndreas Jaekel case 'b':
1743a5090b97SAndreas Jaekel mode = MD_QUEUE_BLOCKING;
1744a5090b97SAndreas Jaekel arg = optarg;
1745a5090b97SAndreas Jaekel break;
1746add9520fSAndreas Jaekel case 'B':
1747a5090b97SAndreas Jaekel mode = MD_QUEUE_NONBLOCKING;
1748a5090b97SAndreas Jaekel arg = optarg;
1749a5090b97SAndreas Jaekel break;
1750add9520fSAndreas Jaekel case 'P':
1751a5090b97SAndreas Jaekel mode = MD_QUEUE_PROPERTIES;
1752a5090b97SAndreas Jaekel arg = optarg;
1753a5090b97SAndreas Jaekel break;
1754*8cfb36b9SArne Jansen case 'G':
1755*8cfb36b9SArne Jansen if (num_guid_filter == MAX_GUID) {
1756*8cfb36b9SArne Jansen fprintf(stderr,
1757*8cfb36b9SArne Jansen "too many guids given, max is %d\n", MAX_GUID);
1758*8cfb36b9SArne Jansen exit(1);
1759*8cfb36b9SArne Jansen }
1760*8cfb36b9SArne Jansen guid_filter[num_guid_filter++] = atoll(optarg);
1761*8cfb36b9SArne Jansen break;
1762e3455c18SAndreas Jaekel case 'V':
1763e3455c18SAndreas Jaekel mode = MD_GET_ZEV_VERSION;
1764e3455c18SAndreas Jaekel break;
1765342055d2SArne Jansen case 'F':
1766342055d2SArne Jansen do_flush = 1;
1767342055d2SArne Jansen break;
1768a18c35b9SAndreas Jaekel case 'h':
1769a18c35b9SAndreas Jaekel case '?':
1770a18c35b9SAndreas Jaekel default:
1771a18c35b9SAndreas Jaekel usage(argv[0]);
1772a18c35b9SAndreas Jaekel }
1773a18c35b9SAndreas Jaekel }
1774a5090b97SAndreas Jaekel
1775a5090b97SAndreas Jaekel switch (mode) {
1776a5090b97SAndreas Jaekel case MD_STATISTICS:
1777a5090b97SAndreas Jaekel return zev_statistics(fd);
1778a5090b97SAndreas Jaekel case MD_POLL_EVENTS:
1779b64581b1SAndreas Jaekel return zev_poll_events(fd, create_tmp_queue);
178035526fb3SArne Jansen case MD_DUMP_SPOOL:
178135526fb3SArne Jansen return zev_dump_spool(fd);
1782a5090b97SAndreas Jaekel case MD_CHECKSUMS:
1783a5090b97SAndreas Jaekel return zev_checksum(fd, arg);
1784a5090b97SAndreas Jaekel case MD_DEBUG_INFO:
1785a5090b97SAndreas Jaekel return zev_debug_info(fd);
1786a5090b97SAndreas Jaekel case MD_LIST_QUEUES:
1787a5090b97SAndreas Jaekel return zev_list_queues(fd);
1788a5090b97SAndreas Jaekel case MD_SET_GLOBAL_MAX_QUEUE_LEN:
1789a5090b97SAndreas Jaekel return zev_set_global_max_queue_len(fd, arg);
1790a5090b97SAndreas Jaekel case MD_SET_MAX_QUEUE_LEN:
1791a5090b97SAndreas Jaekel return zev_set_max_queue_len(fd, arg, arg2);
1792a5090b97SAndreas Jaekel case MD_SET_POLL_WAKEUP_QUEUE_LEN:
1793a5090b97SAndreas Jaekel return zev_set_poll_wakeup_queue_len(fd, arg, arg2);
1794b690436dSAndreas Jaekel case MD_ZEVSTAT:
1795f432e238SAndreas Jaekel return zev_zevstat(fd, arg, arg2, NULL);
1796f432e238SAndreas Jaekel case MD_ZEV_REPORT:
1797f432e238SAndreas Jaekel return zev_report(fd, arg);
1798a5090b97SAndreas Jaekel case MD_MUTE_POOL:
1799a5090b97SAndreas Jaekel return zev_mute_pool(fd, arg);
1800a5090b97SAndreas Jaekel case MD_UNMUTE_POOL:
1801a5090b97SAndreas Jaekel return zev_unmute_pool(fd, arg);
1802a5090b97SAndreas Jaekel case MD_MARK:
1803a5090b97SAndreas Jaekel return zev_mark(fd, arg);
1804a5090b97SAndreas Jaekel case MD_ADD_QUEUE:
1805a5090b97SAndreas Jaekel return zev_add_queue(fd, arg, 0);
1806a5090b97SAndreas Jaekel case MD_ADD_BLOCKING_QUEUE:
1807a5090b97SAndreas Jaekel return zev_add_queue(fd, arg, 1);
1808a5090b97SAndreas Jaekel case MD_REMOVE_QUEUE:
1809a5090b97SAndreas Jaekel return zev_remove_queue(fd, arg);
1810a5090b97SAndreas Jaekel case MD_QUEUE_BLOCKING:
1811a5090b97SAndreas Jaekel return zev_queue_blocking(fd, arg, 0);
1812a5090b97SAndreas Jaekel case MD_QUEUE_NONBLOCKING:
1813a5090b97SAndreas Jaekel return zev_queue_blocking(fd, arg, 1);
1814a5090b97SAndreas Jaekel case MD_QUEUE_PROPERTIES:
1815a5090b97SAndreas Jaekel return zev_queue_properties(fd, arg);
1816e3455c18SAndreas Jaekel case MD_GET_ZEV_VERSION:
1817e3455c18SAndreas Jaekel return zev_get_zev_version(fd);
1818a5090b97SAndreas Jaekel default:
1819a18c35b9SAndreas Jaekel close(fd);
1820a5090b97SAndreas Jaekel usage(argv[0]);
1821add9520fSAndreas Jaekel return EXIT_FAILURE;
1822a5090b97SAndreas Jaekel };
1823a18c35b9SAndreas Jaekel }
1824a18c35b9SAndreas Jaekel
1825