xref: /titanic_44/usr/src/cmd/zevadm/zevadm.c (revision a5090b9741e120422364ca8a3496e0341d917e05)
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>
12a18c35b9SAndreas Jaekel 
13add9520fSAndreas Jaekel #define ZEV_DEVICE "/devices/pseudo/zev@0:ctrl"
14a18c35b9SAndreas Jaekel 
15a18c35b9SAndreas Jaekel static char *zev_device = ZEV_DEVICE;
16a18c35b9SAndreas Jaekel 
17aafc540fSAndreas Jaekel static char *zev_op_name[] = {
1816ff6b2fSAndreas Jaekel 	"ERROR",
1916ff6b2fSAndreas Jaekel 	"MARK",
2016ff6b2fSAndreas Jaekel 	"ZFS_MOUNT",
2116ff6b2fSAndreas Jaekel 	"ZFS_UMOUNT",
2216ff6b2fSAndreas Jaekel 	"ZVOL_WRITE",
2316ff6b2fSAndreas Jaekel 	"ZVOL_TRUNCATE",
2416ff6b2fSAndreas Jaekel 	"ZNODE_CLOSE_AFTER_UPDATE",
2516ff6b2fSAndreas Jaekel 	"ZNODE_CREATE",
2616ff6b2fSAndreas Jaekel 	"ZNODE_MKDIR",
2716ff6b2fSAndreas Jaekel 	"ZNODE_MAKE_XATTR_DIR",
2816ff6b2fSAndreas Jaekel 	"ZNODE_REMOVE",
2916ff6b2fSAndreas Jaekel 	"ZNODE_RMDIR",
3016ff6b2fSAndreas Jaekel 	"ZNODE_LINK",
3116ff6b2fSAndreas Jaekel 	"ZNODE_SYMLINK",
3216ff6b2fSAndreas Jaekel 	"ZNODE_RENAME",
3316ff6b2fSAndreas Jaekel 	"ZNODE_WRITE",
3416ff6b2fSAndreas Jaekel 	"ZNODE_TRUNCATE",
3516ff6b2fSAndreas Jaekel 	"ZNODE_SETATTR",
3616ff6b2fSAndreas Jaekel 	"ZNODE_ACL",
37aafc540fSAndreas Jaekel 	NULL
38aafc540fSAndreas Jaekel };
39aafc540fSAndreas Jaekel 
40*a5090b97SAndreas Jaekel #define MD_STATISTICS			1
41*a5090b97SAndreas Jaekel #define MD_POLL_EVENTS			2
42*a5090b97SAndreas Jaekel #define MD_CHECKSUMS			3
43*a5090b97SAndreas Jaekel #define MD_DEBUG_INFO			4
44*a5090b97SAndreas Jaekel #define MD_LIST_QUEUES			5
45*a5090b97SAndreas Jaekel #define MD_SET_GLOBAL_MAX_QUEUE_LEN	6
46*a5090b97SAndreas Jaekel #define MD_SET_MAX_QUEUE_LEN		7
47*a5090b97SAndreas Jaekel #define MD_SET_POLL_WAKEUP_QUEUE_LEN	8
48*a5090b97SAndreas Jaekel #define MD_MUTE_POOL			9
49*a5090b97SAndreas Jaekel #define MD_UNMUTE_POOL			10
50*a5090b97SAndreas Jaekel #define MD_MARK				11
51*a5090b97SAndreas Jaekel #define MD_ADD_QUEUE			12
52*a5090b97SAndreas Jaekel #define MD_ADD_BLOCKING_QUEUE		13
53*a5090b97SAndreas Jaekel #define MD_REMOVE_QUEUE			14
54*a5090b97SAndreas Jaekel #define MD_QUEUE_BLOCKING		15
55*a5090b97SAndreas Jaekel #define MD_QUEUE_NONBLOCKING		16
56*a5090b97SAndreas Jaekel #define MD_QUEUE_PROPERTIES		17
57*a5090b97SAndreas Jaekel 
58205ed6bfSAndreas Jaekel static int verbose = 0;
5916ff6b2fSAndreas Jaekel static int grep_friendly = 0;
6016ff6b2fSAndreas Jaekel 
6116ff6b2fSAndreas Jaekel static void
6216ff6b2fSAndreas Jaekel zpf(char *fmt, ...)
6316ff6b2fSAndreas Jaekel {
6416ff6b2fSAndreas Jaekel 	va_list	ap;
6516ff6b2fSAndreas Jaekel 
6616ff6b2fSAndreas Jaekel 	va_start(ap, fmt);
6716ff6b2fSAndreas Jaekel 	vprintf(fmt, ap);
6816ff6b2fSAndreas Jaekel 	va_end(ap);
6916ff6b2fSAndreas Jaekel 	if (grep_friendly) {
7016ff6b2fSAndreas Jaekel 		printf(" ");
7116ff6b2fSAndreas Jaekel 	} else {
7216ff6b2fSAndreas Jaekel 		printf("\n");
7316ff6b2fSAndreas Jaekel 	}
7416ff6b2fSAndreas Jaekel }
7516ff6b2fSAndreas Jaekel 
7616ff6b2fSAndreas Jaekel static void
7716ff6b2fSAndreas Jaekel znl(void)
7816ff6b2fSAndreas Jaekel {
7916ff6b2fSAndreas Jaekel 	if (grep_friendly)
8016ff6b2fSAndreas Jaekel 		printf("\n");
8116ff6b2fSAndreas Jaekel }
82205ed6bfSAndreas Jaekel 
832eabeab5SAndreas Jaekel static void
842eabeab5SAndreas Jaekel sig2hex_direct(const uint8_t *sig, char *hex)
852eabeab5SAndreas Jaekel {
862eabeab5SAndreas Jaekel 	int     i;
872eabeab5SAndreas Jaekel 
882eabeab5SAndreas Jaekel 	for (i = 0; i < SHA1_DIGEST_LENGTH; ++i) {
892eabeab5SAndreas Jaekel 		sprintf(hex + 2 * i, "%02x", sig[i]);
902eabeab5SAndreas Jaekel 	}
912eabeab5SAndreas Jaekel 	hex[SHA1_DIGEST_LENGTH * 2] = '\0';
922eabeab5SAndreas Jaekel }
932eabeab5SAndreas Jaekel 
94add9520fSAndreas Jaekel static int
95a18c35b9SAndreas Jaekel zev_statistics(int fd)
96a18c35b9SAndreas Jaekel {
97a18c35b9SAndreas Jaekel 	zev_statistics_t zs;
98add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) {
99a18c35b9SAndreas Jaekel 		perror("getting statistics data failed");
100add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
101a18c35b9SAndreas Jaekel 	}
102a18c35b9SAndreas Jaekel 	printf("ZEV module state:\n");
103a18c35b9SAndreas Jaekel 
104a18c35b9SAndreas Jaekel 	printf("    queue length in bytes   : %lu\n", zs.zev_queue_len);
105a18c35b9SAndreas Jaekel 	printf("    queue length limit      : %lu\n", zs.zev_max_queue_len);
106a18c35b9SAndreas Jaekel 	printf("    bytes read from device  : %lu\n", zs.zev_bytes_read);
107a18c35b9SAndreas Jaekel 	printf("    module internal errors  : %lu\n\n", zs.zev_cnt_errors);
108a18c35b9SAndreas Jaekel 
109add9520fSAndreas Jaekel 	printf("    discarded events        : %lu\n",
110add9520fSAndreas Jaekel 	    zs.zev_cnt_discarded_events);
111add9520fSAndreas Jaekel 	printf("    discarded bytes         : %lu\n\n", zs.zev_bytes_discarded);
112add9520fSAndreas Jaekel 
113a18c35b9SAndreas Jaekel 	printf("ZFS event statistics:\n");
114a18c35b9SAndreas Jaekel 
115a18c35b9SAndreas Jaekel 	printf("    total ZFS events        : %lu\n", zs.zev_cnt_total_events);
116a18c35b9SAndreas Jaekel 	printf("    ZFS mount               : %lu\n", zs.zev_cnt_zfs_mount);
117a18c35b9SAndreas Jaekel 	printf("    ZFS umount              : %lu\n", zs.zev_cnt_zfs_umount);
118a18c35b9SAndreas Jaekel 	printf("    ZVOL write              : %lu\n", zs.zev_cnt_zvol_write);
119a18c35b9SAndreas Jaekel 	printf("    ZVOL truncate           : %lu\n", zs.zev_cnt_zvol_truncate);
120a18c35b9SAndreas Jaekel 	printf("    ZNODE close after update: %lu\n",
121a18c35b9SAndreas Jaekel 	    zs.zev_cnt_znode_close_after_update);
122a18c35b9SAndreas Jaekel 	printf("    ZNODE create            : %lu\n", zs.zev_cnt_znode_create);
123a18c35b9SAndreas Jaekel 	printf("    ZNODE remove            : %lu\n", zs.zev_cnt_znode_remove);
124a18c35b9SAndreas Jaekel 	printf("    ZNODE link              : %lu\n", zs.zev_cnt_znode_link);
125a18c35b9SAndreas Jaekel 	printf("    ZNODE symlink           : %lu\n", zs.zev_cnt_znode_symlink);
126a18c35b9SAndreas Jaekel 	printf("    ZNODE rename            : %lu\n", zs.zev_cnt_znode_rename);
127a18c35b9SAndreas Jaekel 	printf("    ZNODE write             : %lu\n", zs.zev_cnt_znode_write);
128a18c35b9SAndreas Jaekel 	printf("    ZNODE truncate          : %lu\n",
129a18c35b9SAndreas Jaekel 	    zs.zev_cnt_znode_truncate);
130a18c35b9SAndreas Jaekel 	printf("    ZNODE setattr           : %lu\n", zs.zev_cnt_znode_setattr);
131a18c35b9SAndreas Jaekel 	printf("    ZNODE acl               : %lu\n", zs.zev_cnt_znode_acl);
132add9520fSAndreas Jaekel 	return EXIT_SUCCESS;
133a18c35b9SAndreas Jaekel }
134a18c35b9SAndreas Jaekel 
135a18c35b9SAndreas Jaekel static void
13616ff6b2fSAndreas Jaekel zev_print_inode_info(char *name, zev_inode_info_t *info)
13716ff6b2fSAndreas Jaekel {
13816ff6b2fSAndreas Jaekel 	zpf("  %s.inode: %llu", name, info->ino);
13916ff6b2fSAndreas Jaekel 	zpf("  %s.gen: %llu", name, info->gen);
14016ff6b2fSAndreas Jaekel 	zpf("  %s.mtime: %llu", name, info->mtime);
14116ff6b2fSAndreas Jaekel 	zpf("  %s.ctime: %llu", name, info->ctime);
14216ff6b2fSAndreas Jaekel 	zpf("  %s.size: %llu", name, info->size);
14316ff6b2fSAndreas Jaekel 	zpf("  %s.mode: %llo", name, info->mode);
14416ff6b2fSAndreas Jaekel 	zpf("  %s.links: %llu", name, info->links);
14516ff6b2fSAndreas Jaekel 	zpf("  %s.type: %lu", name, info->type);
14616ff6b2fSAndreas Jaekel 	zpf("  %s.flags: %lu", name, info->flags);
14716ff6b2fSAndreas Jaekel }
14816ff6b2fSAndreas Jaekel 
14916ff6b2fSAndreas Jaekel static void
15016ff6b2fSAndreas Jaekel zev_print_mark_payload(zev_mark_t *rec)
15116ff6b2fSAndreas Jaekel {
15216ff6b2fSAndreas Jaekel 	int i;
15316ff6b2fSAndreas Jaekel 	int j;
15416ff6b2fSAndreas Jaekel 	uint8_t *p;
15516ff6b2fSAndreas Jaekel 	char c;
15616ff6b2fSAndreas Jaekel 
15716ff6b2fSAndreas Jaekel 	zpf("  payload:");
15816ff6b2fSAndreas Jaekel 	p = (uint8_t *)ZEV_PAYLOAD(rec);
15916ff6b2fSAndreas Jaekel 	for (i=0; i<rec->payload_len; i+=16) {
16016ff6b2fSAndreas Jaekel 		printf("  ");
16116ff6b2fSAndreas Jaekel 		for (j=i; j<rec->payload_len && j<i+16; j++) {
16216ff6b2fSAndreas Jaekel 			printf("%02x ", p[j]);
16316ff6b2fSAndreas Jaekel 			if (j == i + 7)
16416ff6b2fSAndreas Jaekel 				printf(" ");
16516ff6b2fSAndreas Jaekel 		}
16616ff6b2fSAndreas Jaekel 		if (grep_friendly)
16716ff6b2fSAndreas Jaekel 			continue;
16816ff6b2fSAndreas Jaekel 		for (; j<i+16; j++) {
16916ff6b2fSAndreas Jaekel 			printf("   ");
17016ff6b2fSAndreas Jaekel 			if (j == i + 7)
17116ff6b2fSAndreas Jaekel 				printf(" ");
17216ff6b2fSAndreas Jaekel 		}
17316ff6b2fSAndreas Jaekel 		printf("    ");
17416ff6b2fSAndreas Jaekel 		for (j=i; j<rec->payload_len && j<i+16; j++) {
17516ff6b2fSAndreas Jaekel 			c = '.';
17616ff6b2fSAndreas Jaekel 			if (p[j] >= ' ' && p[j] <= '~')
17716ff6b2fSAndreas Jaekel 				c = p[j];
17816ff6b2fSAndreas Jaekel 			printf("%c", c);
17916ff6b2fSAndreas Jaekel 			if (j == i + 7)
18016ff6b2fSAndreas Jaekel 				printf(" ");
18116ff6b2fSAndreas Jaekel 		}
18216ff6b2fSAndreas Jaekel 		printf("\n");
18316ff6b2fSAndreas Jaekel 	}
18416ff6b2fSAndreas Jaekel }
18516ff6b2fSAndreas Jaekel 
18616ff6b2fSAndreas Jaekel static void
187f2dd45e5SAndreas Jaekel zev_print_error(char *buf)
188f2dd45e5SAndreas Jaekel {
189f2dd45e5SAndreas Jaekel 	zev_error_t *rec = (zev_error_t *)buf;
190f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
191f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
192f2dd45e5SAndreas Jaekel 
19316ff6b2fSAndreas Jaekel 	if (verbose) {
19416ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
19516ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
19616ff6b2fSAndreas Jaekel 		zpf("  failed.op: %s",
19716ff6b2fSAndreas Jaekel 		    zev_op_name[rec->failed_op - ZEV_OP_MIN]);
19816ff6b2fSAndreas Jaekel 		zpf("  message: %s", ZEV_ERRSTR(rec));
19916ff6b2fSAndreas Jaekel 		znl();
20016ff6b2fSAndreas Jaekel 	} else {
201f2dd45e5SAndreas Jaekel 		printf("%s %s: failed_op=%s msg=%s\n",
202f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
20316ff6b2fSAndreas Jaekel 		       zev_op_name[rec->failed_op - ZEV_OP_MIN],
20416ff6b2fSAndreas Jaekel 		       ZEV_ERRSTR(rec));
20516ff6b2fSAndreas Jaekel 	}
206f2dd45e5SAndreas Jaekel }
207f2dd45e5SAndreas Jaekel 
208f2dd45e5SAndreas Jaekel static void
209888fea18SAndreas Jaekel zev_print_mark(char *buf)
210888fea18SAndreas Jaekel {
211888fea18SAndreas Jaekel 	zev_mark_t *rec = (zev_mark_t *)buf;
212888fea18SAndreas Jaekel 	time_t op_time = rec->op_time;
213888fea18SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
214888fea18SAndreas Jaekel 
21516ff6b2fSAndreas Jaekel 	if (verbose) {
21616ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
21716ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
21816ff6b2fSAndreas Jaekel 		zpf("  mark.id: %llu", rec->mark_id);
21916ff6b2fSAndreas Jaekel 		zpf("  payload.len: %llu", rec->payload_len);
22016ff6b2fSAndreas Jaekel 		if (rec->payload_len)
22116ff6b2fSAndreas Jaekel 			zev_print_mark_payload(rec);
22216ff6b2fSAndreas Jaekel 		znl();
22316ff6b2fSAndreas Jaekel 	} else {
224888fea18SAndreas Jaekel 		printf("%s %s: guid=%llu mark_id=%lld payload_len=%ld\n",
22516ff6b2fSAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN], rec->guid,
22616ff6b2fSAndreas Jaekel 		       rec->mark_id, rec->payload_len);
22716ff6b2fSAndreas Jaekel 	}
228888fea18SAndreas Jaekel }
229888fea18SAndreas Jaekel 
230888fea18SAndreas Jaekel static void
231f2dd45e5SAndreas Jaekel zev_print_zfs_mount(char *buf)
232f2dd45e5SAndreas Jaekel {
233f2dd45e5SAndreas Jaekel 	zev_zfs_mount_t *rec = (zev_zfs_mount_t *)buf;
234f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
235f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
236f2dd45e5SAndreas Jaekel 
23716ff6b2fSAndreas Jaekel 	if (verbose) {
23816ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
23916ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
24016ff6b2fSAndreas Jaekel 		zpf("  dataset: %s", ZEV_DATASET(rec));
24116ff6b2fSAndreas Jaekel 		zpf("  mountpoint: %s", ZEV_MOUNTPOINT(rec));
24216ff6b2fSAndreas Jaekel 		zpf("  remount: %s", rec->remount ? "true" : "false");
24316ff6b2fSAndreas Jaekel 		zev_print_inode_info("root", &rec->root);
24416ff6b2fSAndreas Jaekel 		znl();
24516ff6b2fSAndreas Jaekel 	} else {
24616ff6b2fSAndreas Jaekel 		printf("%s %s: guid=%llu remount=%s dataset='%s' "
24716ff6b2fSAndreas Jaekel 		       "mountpoint='%s'\n",
248f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
249f2dd45e5SAndreas Jaekel 		       rec->guid,
250f2dd45e5SAndreas Jaekel 		       rec->remount ? "true" : "false",
251f2dd45e5SAndreas Jaekel 		       ZEV_DATASET(rec),
252f2dd45e5SAndreas Jaekel 		       ZEV_MOUNTPOINT(rec));
253f2dd45e5SAndreas Jaekel 	}
25416ff6b2fSAndreas Jaekel }
255f2dd45e5SAndreas Jaekel 
256f2dd45e5SAndreas Jaekel static void
257f2dd45e5SAndreas Jaekel zev_print_zfs_umount(char *buf)
258f2dd45e5SAndreas Jaekel {
259f2dd45e5SAndreas Jaekel 	zev_zfs_umount_t *rec = (zev_zfs_umount_t *)buf;
260f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
261f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
262f2dd45e5SAndreas Jaekel 
26316ff6b2fSAndreas Jaekel 	if (verbose) {
26416ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
26516ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
26616ff6b2fSAndreas Jaekel 		znl();
26716ff6b2fSAndreas Jaekel 	} else {
268f2dd45e5SAndreas Jaekel 		printf("%s %s: guid=%llu\n",
269f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
270f2dd45e5SAndreas Jaekel 		       rec->guid);
271f2dd45e5SAndreas Jaekel 	}
27216ff6b2fSAndreas Jaekel }
273f2dd45e5SAndreas Jaekel 
274f2dd45e5SAndreas Jaekel static void
275f2dd45e5SAndreas Jaekel zev_print_zvol_truncate(char *buf)
276f2dd45e5SAndreas Jaekel {
277f2dd45e5SAndreas Jaekel 	zev_zvol_truncate_t *rec = (zev_zvol_truncate_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);
28412119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
28516ff6b2fSAndreas Jaekel 		zpf("  offset: %llu", rec->offset);
28616ff6b2fSAndreas Jaekel 		zpf("  length: %llu", rec->length);
28716ff6b2fSAndreas Jaekel 		znl();
28816ff6b2fSAndreas Jaekel 	} else {
289f2dd45e5SAndreas Jaekel 		printf("%s %s: guid=%llu offset=%llu length=%llu\n",
290f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
291f2dd45e5SAndreas Jaekel 		       rec->guid,
292f2dd45e5SAndreas Jaekel 		       rec->offset,
293f2dd45e5SAndreas Jaekel 		       rec->length);
294f2dd45e5SAndreas Jaekel 	}
29516ff6b2fSAndreas Jaekel }
296f2dd45e5SAndreas Jaekel 
297f2dd45e5SAndreas Jaekel static void
298f2dd45e5SAndreas Jaekel zev_print_zvol_write(char *buf)
299f2dd45e5SAndreas Jaekel {
300f2dd45e5SAndreas Jaekel 	zev_print_zvol_truncate(buf);
301f2dd45e5SAndreas Jaekel }
302f2dd45e5SAndreas Jaekel 
303f2dd45e5SAndreas Jaekel static void
304f2dd45e5SAndreas Jaekel zev_print_znode_close_after_update(char *buf)
305f2dd45e5SAndreas Jaekel {
306f2dd45e5SAndreas Jaekel 	zev_znode_close_after_update_t *rec =
307f2dd45e5SAndreas Jaekel 	    (zev_znode_close_after_update_t *)buf;
308f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
309f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
310f2dd45e5SAndreas Jaekel 
31116ff6b2fSAndreas Jaekel 	if (verbose) {
31216ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
31316ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
31416ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
31516ff6b2fSAndreas Jaekel 		znl();
31616ff6b2fSAndreas Jaekel 	} else {
317f2dd45e5SAndreas Jaekel 		printf("%s %s: guid=%llu file=%llu.%llu\n",
318f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
319f2dd45e5SAndreas Jaekel 		       rec->guid,
320f2dd45e5SAndreas Jaekel 		       rec->file.ino, rec->file.gen);
321f2dd45e5SAndreas Jaekel 	}
32216ff6b2fSAndreas Jaekel }
323f2dd45e5SAndreas Jaekel 
324f2dd45e5SAndreas Jaekel static void
325f2dd45e5SAndreas Jaekel zev_print_znode_create(char *buf)
326f2dd45e5SAndreas Jaekel {
327f2dd45e5SAndreas Jaekel 	zev_znode_create_t *rec = (zev_znode_create_t *)buf;
328f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
329f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
3302eabeab5SAndreas Jaekel 	zev_sig_t *sig;
3312eabeab5SAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
332f2dd45e5SAndreas Jaekel 
33316ff6b2fSAndreas Jaekel 	if (verbose) {
33416ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
33516ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
33612119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
33716ff6b2fSAndreas Jaekel 		zpf("  name: '%s'", ZEV_NAME(rec));
3382eabeab5SAndreas Jaekel 		sig = &rec->signature;
3392eabeab5SAndreas Jaekel 		sig2hex_direct(sig->value, sigval);
3402eabeab5SAndreas Jaekel 		zpf("  sig: level %d, offset %llu, value %s",
3412eabeab5SAndreas Jaekel 		    sig->level, sig->block_offset, sigval);
34216ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
34312119a7eSAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
34416ff6b2fSAndreas Jaekel 		znl();
34516ff6b2fSAndreas Jaekel 	} else {
34635d4e8ddSAndreas Jaekel 		printf("%s %s: guid=%llu parent=%llu.%llu file=%llu.%llu "
34735d4e8ddSAndreas Jaekel 		       "file.mtime=%llu, parent.mtime=%llu, name='%s'\n",
348f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
349f2dd45e5SAndreas Jaekel 		       rec->guid,
350f2dd45e5SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
351f2dd45e5SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
35235d4e8ddSAndreas Jaekel 		       rec->file.mtime, rec->parent.mtime,
353f2dd45e5SAndreas Jaekel 		       ZEV_NAME(rec));
354f2dd45e5SAndreas Jaekel 	}
35516ff6b2fSAndreas Jaekel }
356f2dd45e5SAndreas Jaekel 
357f2dd45e5SAndreas Jaekel static void
358f2dd45e5SAndreas Jaekel zev_print_znode_mkdir(char *buf)
359f2dd45e5SAndreas Jaekel {
360f2dd45e5SAndreas Jaekel 	zev_print_znode_create(buf);
361f2dd45e5SAndreas Jaekel }
362f2dd45e5SAndreas Jaekel 
363f2dd45e5SAndreas Jaekel static void
364f2dd45e5SAndreas Jaekel zev_print_znode_make_xattr_dir(char *buf)
365f2dd45e5SAndreas Jaekel {
366f2dd45e5SAndreas Jaekel 	zev_print_znode_create(buf);
367f2dd45e5SAndreas Jaekel }
368f2dd45e5SAndreas Jaekel 
369f2dd45e5SAndreas Jaekel static void
370f2dd45e5SAndreas Jaekel zev_print_znode_remove(char *buf)
371f2dd45e5SAndreas Jaekel {
372f2dd45e5SAndreas Jaekel 	zev_znode_remove_t *rec = (zev_znode_remove_t *)buf;
373f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
374f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
375f2dd45e5SAndreas Jaekel 
37616ff6b2fSAndreas Jaekel 	if (verbose) {
37716ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
37816ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
37912119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
38016ff6b2fSAndreas Jaekel 		zpf("  file.name: '%s'", ZEV_NAME(rec));
38116ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
38212119a7eSAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
38316ff6b2fSAndreas Jaekel 		znl();
38416ff6b2fSAndreas Jaekel 	} else {
38516ff6b2fSAndreas Jaekel 		printf("%s %s: guid=%llu parent=%llu.%llu "
38616ff6b2fSAndreas Jaekel 		       "file.mtime=%llu name='%s'\n",
387f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
388f2dd45e5SAndreas Jaekel 		       rec->guid,
389f2dd45e5SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
39097dcf88dSAndreas Jaekel 		       rec->file.mtime,
391f2dd45e5SAndreas Jaekel 		       ZEV_NAME(rec));
392f2dd45e5SAndreas Jaekel 	}
39316ff6b2fSAndreas Jaekel }
394f2dd45e5SAndreas Jaekel 
395f2dd45e5SAndreas Jaekel static void
396f2dd45e5SAndreas Jaekel zev_print_znode_rmdir(char *buf)
397f2dd45e5SAndreas Jaekel {
398f2dd45e5SAndreas Jaekel 	zev_print_znode_remove(buf);
399f2dd45e5SAndreas Jaekel }
400f2dd45e5SAndreas Jaekel 
401f2dd45e5SAndreas Jaekel static void
402f2dd45e5SAndreas Jaekel zev_print_znode_link(char *buf)
403f2dd45e5SAndreas Jaekel {
404f2dd45e5SAndreas Jaekel 	zev_znode_link_t *rec = (zev_znode_link_t *)buf;
405f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
406f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
407f2dd45e5SAndreas Jaekel 
40816ff6b2fSAndreas Jaekel 	if (verbose) {
40916ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
41016ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
41112119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
41216ff6b2fSAndreas Jaekel 		zpf("  link.name: '%s'", ZEV_NAME(rec));
41316ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
41412119a7eSAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
41516ff6b2fSAndreas Jaekel 		znl();
41616ff6b2fSAndreas Jaekel 	} else {
417a01b300aSAndreas Jaekel 		printf("%s %s: parent=%llu.%llu file=%llu.%llu "
418a01b300aSAndreas Jaekel 		       "file.ctime=%llu parent.ctime=%llu name='%s'\n",
419f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
420f2dd45e5SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
421f2dd45e5SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
422a01b300aSAndreas Jaekel 		       rec->file.ctime, rec->parent.ctime,
423f2dd45e5SAndreas Jaekel 		       ZEV_NAME(rec));
42416ff6b2fSAndreas Jaekel 	}
425f2dd45e5SAndreas Jaekel }
426f2dd45e5SAndreas Jaekel 
427f2dd45e5SAndreas Jaekel static void
428f2dd45e5SAndreas Jaekel zev_print_znode_symlink(char *buf)
429f2dd45e5SAndreas Jaekel {
430f2dd45e5SAndreas Jaekel 	zev_znode_symlink_t *rec = (zev_znode_symlink_t *)buf;
431f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
432f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
4332eabeab5SAndreas Jaekel 	zev_sig_t *sig;
4342eabeab5SAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
435f2dd45e5SAndreas Jaekel 
43616ff6b2fSAndreas Jaekel 	if (verbose) {
43716ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
43816ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
43912119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
44016ff6b2fSAndreas Jaekel 		zpf("  symlink.name: '%s'", ZEV_NAME(rec));
44116ff6b2fSAndreas Jaekel 		zpf("  symlink.link: '%s'", ZEV_LINK(rec));
4422eabeab5SAndreas Jaekel 		sig = &rec->signature;
4432eabeab5SAndreas Jaekel 		sig2hex_direct(sig->value, sigval);
4442eabeab5SAndreas Jaekel 		zpf("  sig: level %d, offset %llu, value %s",
4452eabeab5SAndreas Jaekel 		    sig->level, sig->block_offset, sigval);
44616ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
44712119a7eSAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
44816ff6b2fSAndreas Jaekel 		znl();
44916ff6b2fSAndreas Jaekel 	} else {
45016ff6b2fSAndreas Jaekel 		printf("%s %s: parent=%llu.%llu file=%llu.%llu "
45116ff6b2fSAndreas Jaekel 		       "name='%s' link='%s'\n",
452f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
453f2dd45e5SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
454f2dd45e5SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
455f2dd45e5SAndreas Jaekel 		       ZEV_NAME(rec),
456f2dd45e5SAndreas Jaekel 		       ZEV_LINK(rec));
457f2dd45e5SAndreas Jaekel 	}
45816ff6b2fSAndreas Jaekel }
459f2dd45e5SAndreas Jaekel 
460f2dd45e5SAndreas Jaekel static void
461f2dd45e5SAndreas Jaekel zev_print_znode_rename(char *buf)
462f2dd45e5SAndreas Jaekel {
463f2dd45e5SAndreas Jaekel 	zev_znode_rename_t *rec = (zev_znode_rename_t *)buf;
464f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
465f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
466f2dd45e5SAndreas Jaekel 
46716ff6b2fSAndreas Jaekel 	if (verbose) {
46816ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
46916ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
47012119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
47116ff6b2fSAndreas Jaekel 		zpf("  file.srcname: '%s'", ZEV_SRCNAME(rec));
47216ff6b2fSAndreas Jaekel 		zpf("  file.dstname: '%s'", ZEV_DSTNAME(rec));
47316ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
47416ff6b2fSAndreas Jaekel 		zev_print_inode_info("srcdir", &rec->srcdir);
47516ff6b2fSAndreas Jaekel 		zev_print_inode_info("dstdir", &rec->dstdir);
47616ff6b2fSAndreas Jaekel 		znl();
47716ff6b2fSAndreas Jaekel 	} else {
47816ff6b2fSAndreas Jaekel 		printf("%s %s: srcdir=%llu.%llu dstdir=%llu.%llu "
47916ff6b2fSAndreas Jaekel 		       "file=%llu.%llu file.mtime=%llu, file.ctime=%llu, "
48016ff6b2fSAndreas Jaekel 		       "srcdir.mtime=%llu, srcdir.ctime=%llu, "
48116ff6b2fSAndreas Jaekel 		       "dstdir.mtime=%llu, dstdir.ctime=%llu, "
482f2dd45e5SAndreas Jaekel 		       "srcname='%s' dstname='%s'\n",
483f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
484f2dd45e5SAndreas Jaekel 		       rec->srcdir.ino, rec->srcdir.gen,
485f2dd45e5SAndreas Jaekel 		       rec->dstdir.ino, rec->dstdir.gen,
486f2dd45e5SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
48735d4e8ddSAndreas Jaekel 		       rec->file.mtime, rec->file.ctime,
48835d4e8ddSAndreas Jaekel 		       rec->srcdir.mtime, rec->srcdir.ctime,
48935d4e8ddSAndreas Jaekel 		       rec->dstdir.mtime, rec->dstdir.ctime,
490f2dd45e5SAndreas Jaekel 		       ZEV_SRCNAME(rec),
491f2dd45e5SAndreas Jaekel 		       ZEV_DSTNAME(rec));
492f2dd45e5SAndreas Jaekel 	}
49316ff6b2fSAndreas Jaekel }
494f2dd45e5SAndreas Jaekel 
495f2dd45e5SAndreas Jaekel static void
496f2dd45e5SAndreas Jaekel zev_print_znode_write(char *buf)
497f2dd45e5SAndreas Jaekel {
498f2dd45e5SAndreas Jaekel 	zev_znode_write_t *rec = (zev_znode_write_t *)buf;
499f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
500f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
501205ed6bfSAndreas Jaekel 	zev_sig_t *sig;
502205ed6bfSAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
503205ed6bfSAndreas Jaekel 	int i;
504f2dd45e5SAndreas Jaekel 
505205ed6bfSAndreas Jaekel 	if (verbose) {
50616ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
50716ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
50812119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
50916ff6b2fSAndreas Jaekel 		zpf("  offset: %llu", rec->offset);
51016ff6b2fSAndreas Jaekel 		zpf("  length: %llu", rec->length);
51116ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
51216ff6b2fSAndreas Jaekel 		znl();
513205ed6bfSAndreas Jaekel 		for (i=0; i<rec->signature_cnt; i++) {
514205ed6bfSAndreas Jaekel 			sig = (zev_sig_t *)ZEV_SIGNATURES(rec);
515205ed6bfSAndreas Jaekel 			sig += i;
516205ed6bfSAndreas Jaekel 			sig2hex_direct(sig->value, sigval);
5172eabeab5SAndreas Jaekel 			zpf("  sig: level %d, offset %llu, value %s",
518205ed6bfSAndreas Jaekel 			    sig->level, sig->block_offset, sigval);
519205ed6bfSAndreas Jaekel 		}
52016ff6b2fSAndreas Jaekel 	} else {
52116ff6b2fSAndreas Jaekel 		printf("%s %s: file=%llu.%llu offset=%llu length=%llu\n",
52216ff6b2fSAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
52316ff6b2fSAndreas Jaekel 		       rec->file.ino, rec->file.gen,
52416ff6b2fSAndreas Jaekel 		       rec->offset, rec->length);
525205ed6bfSAndreas Jaekel 	}
526f2dd45e5SAndreas Jaekel }
527f2dd45e5SAndreas Jaekel 
528f2dd45e5SAndreas Jaekel static void
529f2dd45e5SAndreas Jaekel zev_print_znode_truncate(char *buf)
530f2dd45e5SAndreas Jaekel {
531f2dd45e5SAndreas Jaekel 	zev_print_znode_write(buf);
532f2dd45e5SAndreas Jaekel }
533f2dd45e5SAndreas Jaekel 
534f2dd45e5SAndreas Jaekel static void
535f2dd45e5SAndreas Jaekel zev_print_znode_setattr(char *buf)
536f2dd45e5SAndreas Jaekel {
537f2dd45e5SAndreas Jaekel 	zev_znode_setattr_t *rec = (zev_znode_setattr_t *)buf;
538f2dd45e5SAndreas Jaekel 	time_t op_time = rec->op_time;
539f2dd45e5SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
540f2dd45e5SAndreas Jaekel 
54116ff6b2fSAndreas Jaekel 	if (verbose) {
54216ff6b2fSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
54316ff6b2fSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
54412119a7eSAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
54516ff6b2fSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
54616ff6b2fSAndreas Jaekel 		znl();
54716ff6b2fSAndreas Jaekel 	} else {
54835d4e8ddSAndreas Jaekel 		printf("%s %s: file=%llu.%llu mtime=%llu\n",
549f2dd45e5SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
55035d4e8ddSAndreas Jaekel 		       rec->file.ino, rec->file.gen, rec->file.mtime);
551f2dd45e5SAndreas Jaekel 	}
55216ff6b2fSAndreas Jaekel }
553f2dd45e5SAndreas Jaekel 
554f2dd45e5SAndreas Jaekel static void
555f2dd45e5SAndreas Jaekel zev_print_znode_acl(char *buf)
556f2dd45e5SAndreas Jaekel {
557f2dd45e5SAndreas Jaekel 	zev_print_znode_setattr(buf);
558f2dd45e5SAndreas Jaekel }
559f2dd45e5SAndreas Jaekel 
560f2dd45e5SAndreas Jaekel static void
561aafc540fSAndreas Jaekel zev_print_event(char *buf, int len)
562aafc540fSAndreas Jaekel {
563f2dd45e5SAndreas Jaekel 	int record_len;
564f2dd45e5SAndreas Jaekel 	int op;
565aafc540fSAndreas Jaekel 
566f2dd45e5SAndreas Jaekel 	record_len = *(uint32_t *)buf;
567f2dd45e5SAndreas Jaekel 	if (record_len != len) {
568f2dd45e5SAndreas Jaekel 		fprintf(stderr, "record length mismatch: got %d, expected %d\n",
569f2dd45e5SAndreas Jaekel 		        record_len, len);
570aafc540fSAndreas Jaekel 		exit(1);
571aafc540fSAndreas Jaekel 	}
572f2dd45e5SAndreas Jaekel 	op = *((uint32_t *)buf + 1);
573aafc540fSAndreas Jaekel 	if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) {
574f2dd45e5SAndreas Jaekel 		fprintf(stderr, "unknown op code: %d\n", op);
575aafc540fSAndreas Jaekel 		exit(1);
576aafc540fSAndreas Jaekel 	}
577f2dd45e5SAndreas Jaekel 	switch (op) {
578f2dd45e5SAndreas Jaekel 	case ZEV_OP_ERROR:
579f2dd45e5SAndreas Jaekel 		zev_print_error(buf);
580aafc540fSAndreas Jaekel 		break;
581888fea18SAndreas Jaekel 	case ZEV_OP_MARK:
582888fea18SAndreas Jaekel 		zev_print_mark(buf);
583888fea18SAndreas Jaekel 		break;
584f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZFS_MOUNT:
585f2dd45e5SAndreas Jaekel 		zev_print_zfs_mount(buf);
586aafc540fSAndreas Jaekel 		break;
587f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZFS_UMOUNT:
588f2dd45e5SAndreas Jaekel 		zev_print_zfs_umount(buf);
589aafc540fSAndreas Jaekel 		break;
590f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZVOL_TRUNCATE:
591f2dd45e5SAndreas Jaekel 		zev_print_zvol_truncate(buf);
592aafc540fSAndreas Jaekel 		break;
593f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZVOL_WRITE:
594f2dd45e5SAndreas Jaekel 		zev_print_zvol_write(buf);
595f2dd45e5SAndreas Jaekel 		break;
596f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE:
597f2dd45e5SAndreas Jaekel 		zev_print_znode_close_after_update(buf);
598f2dd45e5SAndreas Jaekel 		break;
599f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_CREATE:
600f2dd45e5SAndreas Jaekel 		zev_print_znode_create(buf);
601f2dd45e5SAndreas Jaekel 		break;
602f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_MKDIR:
603f2dd45e5SAndreas Jaekel 		zev_print_znode_mkdir(buf);
604f2dd45e5SAndreas Jaekel 		break;
605f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_MAKE_XATTR_DIR:
606f2dd45e5SAndreas Jaekel 		zev_print_znode_make_xattr_dir(buf);
607f2dd45e5SAndreas Jaekel 		break;
608f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_REMOVE:
609f2dd45e5SAndreas Jaekel 		zev_print_znode_remove(buf);
610f2dd45e5SAndreas Jaekel 		break;
611f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_RMDIR:
612f2dd45e5SAndreas Jaekel 		zev_print_znode_rmdir(buf);
613f2dd45e5SAndreas Jaekel 		break;
614f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_LINK:
615f2dd45e5SAndreas Jaekel 		zev_print_znode_link(buf);
616f2dd45e5SAndreas Jaekel 		break;
617f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_SYMLINK:
618f2dd45e5SAndreas Jaekel 		zev_print_znode_symlink(buf);
619f2dd45e5SAndreas Jaekel 		break;
620f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_RENAME:
621f2dd45e5SAndreas Jaekel 		zev_print_znode_rename(buf);
622f2dd45e5SAndreas Jaekel 		break;
623f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_WRITE:
624f2dd45e5SAndreas Jaekel 		zev_print_znode_write(buf);
625f2dd45e5SAndreas Jaekel 		break;
626f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_TRUNCATE:
627f2dd45e5SAndreas Jaekel 		zev_print_znode_truncate(buf);
628f2dd45e5SAndreas Jaekel 		break;
629f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_SETATTR:
630f2dd45e5SAndreas Jaekel 		zev_print_znode_setattr(buf);
631f2dd45e5SAndreas Jaekel 		break;
632f2dd45e5SAndreas Jaekel 	case ZEV_OP_ZNODE_ACL:
633f2dd45e5SAndreas Jaekel 		zev_print_znode_acl(buf);
634aafc540fSAndreas Jaekel 		break;
635aafc540fSAndreas Jaekel 	default:
636f2dd45e5SAndreas Jaekel 		fprintf(stderr, "unhandled op code: %d\n", op);
637aafc540fSAndreas Jaekel 		exit(1);
638aafc540fSAndreas Jaekel 	}
639aafc540fSAndreas Jaekel }
640aafc540fSAndreas Jaekel 
641add9520fSAndreas Jaekel static int
6426a6a51eeSAndreas Jaekel zev_poll_events(int fd, int create_tmp_queue)
643a18c35b9SAndreas Jaekel {
644a18c35b9SAndreas Jaekel 	struct pollfd pfd[1];
645a18c35b9SAndreas Jaekel 	int ret;
646aafc540fSAndreas Jaekel 	char buf[4096];
647d979f56cSAndreas Jaekel 	zev_event_t *ev;
648d979f56cSAndreas Jaekel 	int off = 0;
649add9520fSAndreas Jaekel 	zev_ioctl_add_queue_t aq;
650add9520fSAndreas Jaekel 	int q_fd;
651add9520fSAndreas Jaekel 
6526a6a51eeSAndreas Jaekel 	if (create_tmp_queue) {
653add9520fSAndreas Jaekel 		aq.zev_max_queue_len = 0;
654add9520fSAndreas Jaekel 		aq.zev_flags = ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
655add9520fSAndreas Jaekel 		snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN,
656add9520fSAndreas Jaekel 			 "zevadm.%ld.%ld", time(NULL), getpid());
657add9520fSAndreas Jaekel 		aq.zev_namelen = strlen(aq.zev_name);
658add9520fSAndreas Jaekel 
659add9520fSAndreas Jaekel 		if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
660add9520fSAndreas Jaekel 			perror("adding temporary queue failed");
661add9520fSAndreas Jaekel 			return (EXIT_FAILURE);
662add9520fSAndreas Jaekel 		}
663add9520fSAndreas Jaekel 
6646a6a51eeSAndreas Jaekel 		snprintf(buf, sizeof(buf),
6656a6a51eeSAndreas Jaekel 		         "/devices/pseudo/zev@0:%s", aq.zev_name);
666add9520fSAndreas Jaekel 		q_fd = open(buf, O_RDONLY);
667add9520fSAndreas Jaekel 		if (q_fd < 0) {
668add9520fSAndreas Jaekel 			perror("opening queue device failed");
669add9520fSAndreas Jaekel 			return (EXIT_FAILURE);
670add9520fSAndreas Jaekel 		}
6716a6a51eeSAndreas Jaekel 	} else {
6726a6a51eeSAndreas Jaekel 		q_fd = fd;
6736a6a51eeSAndreas Jaekel 	}
674add9520fSAndreas Jaekel 
675a18c35b9SAndreas Jaekel 	while (1) {
676add9520fSAndreas Jaekel 		pfd[0].fd = q_fd;
677a18c35b9SAndreas Jaekel 		pfd[0].events = POLLIN;
678a18c35b9SAndreas Jaekel 		ret = poll(pfd, 1, 1000);
679a18c35b9SAndreas Jaekel 		if (ret < 0) {
680a18c35b9SAndreas Jaekel 			perror("poll failed");
6816a6a51eeSAndreas Jaekel 			close(q_fd);
682add9520fSAndreas Jaekel 			return(EXIT_FAILURE);
683a18c35b9SAndreas Jaekel 		}
684a18c35b9SAndreas Jaekel 		if (!(pfd[0].revents & POLLIN))
685a18c35b9SAndreas Jaekel 			continue;
686a18c35b9SAndreas Jaekel 		/* data available */
687add9520fSAndreas Jaekel 		ret = read(q_fd, buf, sizeof(buf));
688a18c35b9SAndreas Jaekel 		if (ret < 0) {
689a18c35b9SAndreas Jaekel 			perror("read failed");
6906a6a51eeSAndreas Jaekel 			close(q_fd);
691add9520fSAndreas Jaekel 			return(EXIT_FAILURE);
692a18c35b9SAndreas Jaekel 		}
693a18c35b9SAndreas Jaekel 		if (ret == 0)
694a18c35b9SAndreas Jaekel 			continue;
695d979f56cSAndreas Jaekel 		while (ret > off) {
696d979f56cSAndreas Jaekel 			ev = (zev_event_t *)(buf + off);
697d979f56cSAndreas Jaekel 			zev_print_event(buf + off, ev->header.record_len);
698d979f56cSAndreas Jaekel 			off += ev->header.record_len;
699d979f56cSAndreas Jaekel 		}
700149d0affSAndreas Jaekel 		off = 0;
701a18c35b9SAndreas Jaekel 	}
7026a6a51eeSAndreas Jaekel 	if (create_tmp_queue)
703add9520fSAndreas Jaekel 		close(q_fd);
704add9520fSAndreas Jaekel 	return EXIT_SUCCESS;
705a18c35b9SAndreas Jaekel }
706a18c35b9SAndreas Jaekel 
707a18c35b9SAndreas Jaekel static void
708a18c35b9SAndreas Jaekel usage(char *progname)
709a18c35b9SAndreas Jaekel {
710add9520fSAndreas Jaekel 	fprintf(stderr, "usage: %s [-d <dev>] [options]\n", progname);
711add9520fSAndreas Jaekel 	fprintf(stderr, "\n");
712add9520fSAndreas Jaekel 	fprintf(stderr, " Status information:\n");
713a18c35b9SAndreas Jaekel 	fprintf(stderr, "   -s                   show zev statistics\n");
714a18c35b9SAndreas Jaekel 	fprintf(stderr, "   -p                   poll for ZFS events\n");
715add9520fSAndreas Jaekel 	fprintf(stderr, "   -D                   print zev module debug "
716add9520fSAndreas Jaekel 	        "information\n");
717add9520fSAndreas Jaekel 	fprintf(stderr, "\n");
718add9520fSAndreas Jaekel 	fprintf(stderr, " Tune zev module settings:\n");
719add9520fSAndreas Jaekel 	fprintf(stderr, "   -Q <bytes>           set maximum event queue "
720add9520fSAndreas Jaekel 	        "length\n");
721add9520fSAndreas Jaekel 	fprintf(stderr, "   -m <pool>            mute pool, no events for "
722add9520fSAndreas Jaekel 	        "this pool\n");
723a18c35b9SAndreas Jaekel 	fprintf(stderr, "   -M <pool>            unmute pool\n");
724add9520fSAndreas Jaekel 	fprintf(stderr, "\n");
725add9520fSAndreas Jaekel 	fprintf(stderr, " Queue management:\n");
726add9520fSAndreas Jaekel 	fprintf(stderr, "   -l                   list queues\n");
7276a6a51eeSAndreas Jaekel 	fprintf(stderr, "   -a <name>            add non-blocking queue\n");
7286a6a51eeSAndreas Jaekel 	fprintf(stderr, "   -A <name>            add blocking queue\n");
729add9520fSAndreas Jaekel 	fprintf(stderr, "   -r <name>            remove queue\n");
730add9520fSAndreas Jaekel 	fprintf(stderr, "   -b <name>            make queue non-blocking "
731add9520fSAndreas Jaekel 	        "(default)\n");
732add9520fSAndreas Jaekel 	fprintf(stderr, "   -B <name>            make queue block when full\n");
733add9520fSAndreas Jaekel 	fprintf(stderr, "   -P <name>            display queue properties\n");
7346a6a51eeSAndreas Jaekel 	fprintf(stderr, "   -L <name> <bytes>    set maximum event queue "
735add9520fSAndreas Jaekel 	        "length\n");
736add9520fSAndreas Jaekel 	fprintf(stderr, "   -t <name> <bytes>    set queue length poll "
737add9520fSAndreas Jaekel 	        "throttle\n");
738add9520fSAndreas Jaekel 	fprintf(stderr, "\n");
739add9520fSAndreas Jaekel 	fprintf(stderr, " Other options:\n");
740add9520fSAndreas Jaekel 	fprintf(stderr, "   -d <dev>             non-default device file. "
741add9520fSAndreas Jaekel 	        "('%s')\n", ZEV_DEVICE);
7426a6a51eeSAndreas Jaekel 	fprintf(stderr, "   -q <name>            use device file for this "
7436a6a51eeSAndreas Jaekel 		"queue name\n");
744888fea18SAndreas Jaekel 	fprintf(stderr, "   -k <guid>:<payload>  queue mark event\n");
74542110aacSAndreas Jaekel 	fprintf(stderr, "   -c <filename>        list file's content "
74642110aacSAndreas Jaekel 		"checksums\n");
74716ff6b2fSAndreas Jaekel 	fprintf(stderr, "   -v                   verbose: additional output "
748205ed6bfSAndreas Jaekel 	        "for some operations\n");
74916ff6b2fSAndreas Jaekel 	fprintf(stderr, "   -g                   grep-friendly event output, "
75016ff6b2fSAndreas Jaekel 	        "one event per line\n");
751a18c35b9SAndreas Jaekel 	exit (EXIT_FAILURE);
752a18c35b9SAndreas Jaekel }
753a18c35b9SAndreas Jaekel 
754a18c35b9SAndreas Jaekel static int
7556a6a51eeSAndreas Jaekel zev_add_queue(int fd, char *arg, int blocking)
756a18c35b9SAndreas Jaekel {
757add9520fSAndreas Jaekel 	zev_ioctl_add_queue_t aq;
758add9520fSAndreas Jaekel 	int namelen;
759a18c35b9SAndreas Jaekel 
760add9520fSAndreas Jaekel 	namelen = strlen(arg);
761add9520fSAndreas Jaekel 	if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
762add9520fSAndreas Jaekel 		fprintf(stderr, "queue name too long: %s\n", arg);
763a18c35b9SAndreas Jaekel 		return (EXIT_FAILURE);
764a18c35b9SAndreas Jaekel 	}
765add9520fSAndreas Jaekel 
766add9520fSAndreas Jaekel 	aq.zev_namelen = namelen;
767add9520fSAndreas Jaekel 	strcpy(aq.zev_name, arg);
7686a6a51eeSAndreas Jaekel 	aq.zev_flags = ZEV_FL_PERSISTENT;
7696a6a51eeSAndreas Jaekel 	if (blocking) {
7706a6a51eeSAndreas Jaekel 		aq.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
7716a6a51eeSAndreas Jaekel 		aq.zev_max_queue_len = ZEV_MAX_QUEUE_LEN;
7726a6a51eeSAndreas Jaekel 	} else {
773add9520fSAndreas Jaekel 		aq.zev_max_queue_len = (1024 * 1024);
7746a6a51eeSAndreas Jaekel 	}
775add9520fSAndreas Jaekel 
776add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
777add9520fSAndreas Jaekel 		perror("adding queue failed");
778a18c35b9SAndreas Jaekel 		return (EXIT_FAILURE);
779a18c35b9SAndreas Jaekel 	}
780a18c35b9SAndreas Jaekel 	return (0);
781a18c35b9SAndreas Jaekel }
782a18c35b9SAndreas Jaekel 
783a18c35b9SAndreas Jaekel static int
784add9520fSAndreas Jaekel zev_remove_queue(int fd, char *arg)
785fec460f8SAndreas Jaekel {
786add9520fSAndreas Jaekel 	zev_ioctl_remove_queue_t aq;
787add9520fSAndreas Jaekel 	int namelen;
788fec460f8SAndreas Jaekel 
789add9520fSAndreas Jaekel 	namelen = strlen(arg);
790add9520fSAndreas Jaekel 	if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
791add9520fSAndreas Jaekel 		fprintf(stderr, "queue name too long: %s\n", arg);
792fec460f8SAndreas Jaekel 		return (EXIT_FAILURE);
793fec460f8SAndreas Jaekel 	}
794add9520fSAndreas Jaekel 
7956a6a51eeSAndreas Jaekel 	aq.zev_queue_name.zev_namelen = namelen;
7966a6a51eeSAndreas Jaekel 	strcpy(aq.zev_queue_name.zev_name, arg);
797add9520fSAndreas Jaekel 
798add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_REMOVE_QUEUE, &aq)) {
799add9520fSAndreas Jaekel 		perror("removing queue failed");
800add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
801add9520fSAndreas Jaekel 	}
802add9520fSAndreas Jaekel 	return (0);
803add9520fSAndreas Jaekel }
804add9520fSAndreas Jaekel 
805add9520fSAndreas Jaekel static int
806add9520fSAndreas Jaekel zev_set_global_max_queue_len(int fd, char *arg)
807add9520fSAndreas Jaekel {
808add9520fSAndreas Jaekel 	uint64_t maxqueuelen;
809add9520fSAndreas Jaekel 
810add9520fSAndreas Jaekel 	errno = 0;
811add9520fSAndreas Jaekel 	maxqueuelen = strtol(arg, (char **)NULL, 10);
812add9520fSAndreas Jaekel 	if (errno) {
813add9520fSAndreas Jaekel 		fprintf(stderr, "invalid queue length parameter: %s\n", arg);
814add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
815add9520fSAndreas Jaekel 	}
816add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_MAX_QUEUE_LEN, &maxqueuelen)) {
817add9520fSAndreas Jaekel 		perror("setting max queue length failed");
818fec460f8SAndreas Jaekel 		return (EXIT_FAILURE);
819fec460f8SAndreas Jaekel 	}
820fec460f8SAndreas Jaekel 	return (0);
821fec460f8SAndreas Jaekel }
822fec460f8SAndreas Jaekel 
823fec460f8SAndreas Jaekel static int
824a18c35b9SAndreas Jaekel zev_mute_unmute_impl(int fd, char *poolname, int mute)
825a18c35b9SAndreas Jaekel {
826a18c35b9SAndreas Jaekel 	zev_ioctl_poolarg_t pa;
827a18c35b9SAndreas Jaekel 	int len;
828a18c35b9SAndreas Jaekel 	int op = mute ? ZEV_IOC_MUTE_POOL : ZEV_IOC_UNMUTE_POOL;
829a18c35b9SAndreas Jaekel 	len = strlen(poolname);
830a18c35b9SAndreas Jaekel 	if (len <= 0 || len >= sizeof(pa.zev_poolname)) {
831a18c35b9SAndreas Jaekel 		fprintf(stderr, "invalid poolname: %s\n", poolname);
832a18c35b9SAndreas Jaekel 		return (EXIT_FAILURE);
833a18c35b9SAndreas Jaekel 	}
834a18c35b9SAndreas Jaekel 	strcpy(pa.zev_poolname, poolname);
835a18c35b9SAndreas Jaekel 	pa.zev_poolname_len = len;
836a18c35b9SAndreas Jaekel 	if (ioctl(fd, op, &pa)) {
837a18c35b9SAndreas Jaekel 		perror("muting pool data failed");
838a18c35b9SAndreas Jaekel 		return (EXIT_FAILURE);
839a18c35b9SAndreas Jaekel 	}
840a18c35b9SAndreas Jaekel 	return (0);
841a18c35b9SAndreas Jaekel }
842a18c35b9SAndreas Jaekel 
843a18c35b9SAndreas Jaekel int
844a18c35b9SAndreas Jaekel zev_mute_pool(int fd, char *poolname)
845a18c35b9SAndreas Jaekel {
846a18c35b9SAndreas Jaekel 	return zev_mute_unmute_impl(fd, poolname, 1);
847a18c35b9SAndreas Jaekel }
848a18c35b9SAndreas Jaekel 
849a18c35b9SAndreas Jaekel int
850a18c35b9SAndreas Jaekel zev_unmute_pool(int fd, char *poolname)
851a18c35b9SAndreas Jaekel {
852a18c35b9SAndreas Jaekel 	return zev_mute_unmute_impl(fd, poolname, 0);
853a18c35b9SAndreas Jaekel }
854a18c35b9SAndreas Jaekel 
855888fea18SAndreas Jaekel static int
856add9520fSAndreas Jaekel zev_debug_info(int fd)
857add9520fSAndreas Jaekel {
858add9520fSAndreas Jaekel 	zev_ioctl_debug_info_t di;
859add9520fSAndreas Jaekel 
860add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_DEBUG_INFO, &di)) {
861add9520fSAndreas Jaekel 		perror("getting zev debug info failed");
862add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
863add9520fSAndreas Jaekel 	}
864add9520fSAndreas Jaekel 
865add9520fSAndreas Jaekel 	printf("memory allocated: %llu bytes\n", di.zev_memory_allocated);
866205ed6bfSAndreas Jaekel 	printf("checksum cache size: %llu\n", di.zev_chksum_cache_size);
867205ed6bfSAndreas Jaekel 	printf("checksum cache hits: %llu\n", di.zev_chksum_cache_hits);
868205ed6bfSAndreas Jaekel 	printf("checksum cache misses: %llu\n", di.zev_chksum_cache_misses);
869add9520fSAndreas Jaekel 	return 0;
870add9520fSAndreas Jaekel }
871add9520fSAndreas Jaekel 
872add9520fSAndreas Jaekel static int
873888fea18SAndreas Jaekel zev_mark(int fd, char *arg)
874888fea18SAndreas Jaekel {
875888fea18SAndreas Jaekel 	zev_ioctl_mark_t *mark;
876888fea18SAndreas Jaekel 	uint64_t guid;
877888fea18SAndreas Jaekel 	int len;
878888fea18SAndreas Jaekel 	char *p;
879888fea18SAndreas Jaekel 
880888fea18SAndreas Jaekel 	p = strchr(arg, ':');
881888fea18SAndreas Jaekel 	if (!p) {
882888fea18SAndreas Jaekel 		fprintf(stderr, "expected value is <guid>:<payload>, "
883888fea18SAndreas Jaekel 		        "e.g. '123:hello'\n");
884888fea18SAndreas Jaekel 		exit (EXIT_FAILURE);
885888fea18SAndreas Jaekel 	}
886888fea18SAndreas Jaekel 	*p = '\n';
887888fea18SAndreas Jaekel 	p++;
888888fea18SAndreas Jaekel 
889888fea18SAndreas Jaekel 	errno = 0;
890add9520fSAndreas Jaekel 	guid = strtoll(arg, (char **)NULL, 10);
891888fea18SAndreas Jaekel 	if (errno) {
892888fea18SAndreas Jaekel 		fprintf(stderr, "guid must be a number.\n");
893888fea18SAndreas Jaekel 		exit (EXIT_FAILURE);
894888fea18SAndreas Jaekel 	}
895888fea18SAndreas Jaekel 
896888fea18SAndreas Jaekel 	len = strlen(p);
897888fea18SAndreas Jaekel 
898888fea18SAndreas Jaekel 	mark = malloc(sizeof(*mark) + len + 1);
899888fea18SAndreas Jaekel 	if (!mark) {
900888fea18SAndreas Jaekel 		fprintf(stderr, "can't allocate mark structure: %s\n",
901888fea18SAndreas Jaekel 		        strerror(errno));
902888fea18SAndreas Jaekel 		exit (EXIT_FAILURE);
903888fea18SAndreas Jaekel 	}
904888fea18SAndreas Jaekel 	mark->zev_guid = guid;
905888fea18SAndreas Jaekel 	mark->zev_mark_id = 0;
906888fea18SAndreas Jaekel 	mark->zev_payload_len = len;
907888fea18SAndreas Jaekel 	strcpy(ZEV_PAYLOAD(mark), p);
908888fea18SAndreas Jaekel 
909888fea18SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_MARK, mark)) {
910888fea18SAndreas Jaekel 		perror("queueing mark failed");
911888fea18SAndreas Jaekel 		return (EXIT_FAILURE);
912888fea18SAndreas Jaekel 	}
913888fea18SAndreas Jaekel 
914888fea18SAndreas Jaekel 	printf("mark id: %lu\n", mark->zev_mark_id);
915888fea18SAndreas Jaekel 	return (0);
916888fea18SAndreas Jaekel }
917888fea18SAndreas Jaekel 
918add9520fSAndreas Jaekel static int
919add9520fSAndreas Jaekel zev_queue_blocking(int fd, char *arg, int block)
920add9520fSAndreas Jaekel {
921add9520fSAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
922add9520fSAndreas Jaekel 
9236a6a51eeSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
9246a6a51eeSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
925add9520fSAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
926add9520fSAndreas Jaekel 		return EXIT_FAILURE;
927add9520fSAndreas Jaekel 	}
9286a6a51eeSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
929add9520fSAndreas Jaekel 
930add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
931add9520fSAndreas Jaekel 		perror("getting queue properties failed");
932add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
933add9520fSAndreas Jaekel 	}
934add9520fSAndreas Jaekel 	if (block) {
935add9520fSAndreas Jaekel 		gqp.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
936add9520fSAndreas Jaekel 	} else {
937add9520fSAndreas Jaekel 		gqp.zev_flags &= ~ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
938add9520fSAndreas Jaekel 	}
939add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
940add9520fSAndreas Jaekel 		perror("setting queue properties failed");
941add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
942add9520fSAndreas Jaekel 	}
943add9520fSAndreas Jaekel 	return (0);
944add9520fSAndreas Jaekel }
945add9520fSAndreas Jaekel 
946add9520fSAndreas Jaekel static int
947add9520fSAndreas Jaekel zev_set_max_queue_len(int fd, char *arg, char *len)
948add9520fSAndreas Jaekel {
949add9520fSAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
950add9520fSAndreas Jaekel 
951add9520fSAndreas Jaekel 	if (!len) {
952add9520fSAndreas Jaekel 		fprintf(stderr, "queue size parameter missing.\n");
953add9520fSAndreas Jaekel 		return EXIT_FAILURE;
954add9520fSAndreas Jaekel 	}
955add9520fSAndreas Jaekel 
9566a6a51eeSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
9576a6a51eeSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
958add9520fSAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
959add9520fSAndreas Jaekel 		return EXIT_FAILURE;
960add9520fSAndreas Jaekel 	}
9616a6a51eeSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
962add9520fSAndreas Jaekel 
963add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
964add9520fSAndreas Jaekel 		perror("getting queue properties failed");
965add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
966add9520fSAndreas Jaekel 	}
967add9520fSAndreas Jaekel 	gqp.zev_max_queue_len = atol(len);
968add9520fSAndreas Jaekel 	if (gqp.zev_max_queue_len == 0 && strcmp("0", len)) {
969add9520fSAndreas Jaekel 		fprintf(stderr, "queue size parameter garbled.\n");
970add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
971add9520fSAndreas Jaekel 	}
972add9520fSAndreas Jaekel 	if (gqp.zev_max_queue_len > ZEV_MAX_QUEUE_LEN) {
973add9520fSAndreas Jaekel 		fprintf(stderr, "queue size parameter out of bounds.\n");
974add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
975add9520fSAndreas Jaekel 	}
976add9520fSAndreas Jaekel 
977add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
978add9520fSAndreas Jaekel 		perror("setting queue properties failed");
979add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
980add9520fSAndreas Jaekel 	}
981add9520fSAndreas Jaekel 	return (0);
982add9520fSAndreas Jaekel }
983add9520fSAndreas Jaekel 
984add9520fSAndreas Jaekel static int
985add9520fSAndreas Jaekel zev_set_poll_wakeup_queue_len(int fd, char *arg, char *len)
986add9520fSAndreas Jaekel {
987add9520fSAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
988add9520fSAndreas Jaekel 
989add9520fSAndreas Jaekel 	if (!len) {
990add9520fSAndreas Jaekel 		fprintf(stderr, "poll throttle parameter missing.\n");
991add9520fSAndreas Jaekel 		return EXIT_FAILURE;
992add9520fSAndreas Jaekel 	}
993add9520fSAndreas Jaekel 
9946a6a51eeSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
9956a6a51eeSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
996add9520fSAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
997add9520fSAndreas Jaekel 		return EXIT_FAILURE;
998add9520fSAndreas Jaekel 	}
9996a6a51eeSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
1000add9520fSAndreas Jaekel 
1001add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1002add9520fSAndreas Jaekel 		perror("getting queue properties failed");
1003add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
1004add9520fSAndreas Jaekel 	}
1005add9520fSAndreas Jaekel 	gqp.zev_poll_wakeup_threshold = atol(len);
1006add9520fSAndreas Jaekel 	if (gqp.zev_poll_wakeup_threshold == 0 && strcmp("0", len)) {
1007add9520fSAndreas Jaekel 		fprintf(stderr, "poll throttle parameter garbled.\n");
1008add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
1009add9520fSAndreas Jaekel 	}
10106a6a51eeSAndreas Jaekel 	if (gqp.zev_poll_wakeup_threshold > ZEV_MAX_POLL_WAKEUP_QUEUE_LEN) {
1011add9520fSAndreas Jaekel 		fprintf(stderr, "poll throttle parameter out of bounds.\n");
1012add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
1013add9520fSAndreas Jaekel 	}
1014add9520fSAndreas Jaekel 
1015add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1016add9520fSAndreas Jaekel 		perror("setting queue properties failed");
1017add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
1018add9520fSAndreas Jaekel 	}
1019add9520fSAndreas Jaekel 	return (0);
1020add9520fSAndreas Jaekel }
1021add9520fSAndreas Jaekel 
1022add9520fSAndreas Jaekel static int
1023add9520fSAndreas Jaekel zev_queue_properties(int fd, char *arg)
1024add9520fSAndreas Jaekel {
1025add9520fSAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
1026add9520fSAndreas Jaekel 
10276a6a51eeSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
10286a6a51eeSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1029add9520fSAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
1030add9520fSAndreas Jaekel 		return EXIT_FAILURE;
1031add9520fSAndreas Jaekel 	}
10326a6a51eeSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
1033add9520fSAndreas Jaekel 
1034add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1035add9520fSAndreas Jaekel 		perror("getting queue properties failed");
1036add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
1037add9520fSAndreas Jaekel 	}
1038add9520fSAndreas Jaekel 
1039add9520fSAndreas Jaekel 	printf("queue        : %s\n", arg);
1040add9520fSAndreas Jaekel 	printf("max size     : %" PRIu64 "\n", gqp.zev_max_queue_len);
1041add9520fSAndreas Jaekel 	printf("poll throttle: %" PRIu64 "\n", gqp.zev_poll_wakeup_threshold);
1042add9520fSAndreas Jaekel 	printf("persistent   : %s\n",
1043add9520fSAndreas Jaekel 		gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no");
1044add9520fSAndreas Jaekel 	printf("blocking     : %s\n",
1045add9520fSAndreas Jaekel 		gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? "yes" : "no");
1046add9520fSAndreas Jaekel 
1047add9520fSAndreas Jaekel 	return (0);
1048add9520fSAndreas Jaekel }
1049add9520fSAndreas Jaekel 
1050add9520fSAndreas Jaekel static int
1051add9520fSAndreas Jaekel zev_list_queues(int fd)
1052add9520fSAndreas Jaekel {
1053add9520fSAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
1054add9520fSAndreas Jaekel 	zev_ioctl_get_queue_list_t gql;
1055add9520fSAndreas Jaekel 	zev_ioctl_get_queue_statistics_t gs;
1056add9520fSAndreas Jaekel 	uint64_t	i;
1057add9520fSAndreas Jaekel 	char		name[ZEV_MAX_QUEUE_NAME_LEN+1];
1058add9520fSAndreas Jaekel 
1059add9520fSAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_LIST, &gql)) {
1060add9520fSAndreas Jaekel 		perror("getting queue list failed");
1061add9520fSAndreas Jaekel 		return (EXIT_FAILURE);
1062add9520fSAndreas Jaekel 	}
1063add9520fSAndreas Jaekel 
1064add9520fSAndreas Jaekel 	printf("Name                                     Size       "
1065add9520fSAndreas Jaekel 	       "Max Size   Wakeup Per Block\n");
1066add9520fSAndreas Jaekel 
1067add9520fSAndreas Jaekel 	for (i=0; i<gql.zev_n_queues; i++) {
1068add9520fSAndreas Jaekel 		strncpy(name, gql.zev_queue_name[i].zev_name,
1069add9520fSAndreas Jaekel 		        ZEV_MAX_QUEUE_NAME_LEN);
1070add9520fSAndreas Jaekel 		name[gql.zev_queue_name[i].zev_namelen] = '\0';
1071add9520fSAndreas Jaekel 
10726a6a51eeSAndreas Jaekel 		memcpy(gqp.zev_queue_name.zev_name,
10736a6a51eeSAndreas Jaekel 		    gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
10746a6a51eeSAndreas Jaekel 		gqp.zev_queue_name.zev_namelen =
10756a6a51eeSAndreas Jaekel 		    gql.zev_queue_name[i].zev_namelen;
1076add9520fSAndreas Jaekel 
1077add9520fSAndreas Jaekel 		if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1078add9520fSAndreas Jaekel 			if (errno == ENOENT)
1079add9520fSAndreas Jaekel 				continue;
1080add9520fSAndreas Jaekel 			perror("getting queue properties failed");
1081add9520fSAndreas Jaekel 			return (EXIT_FAILURE);
1082add9520fSAndreas Jaekel 		}
1083add9520fSAndreas Jaekel 
10846a6a51eeSAndreas Jaekel 		memcpy(gs.zev_queue_name.zev_name,
10856a6a51eeSAndreas Jaekel 		    gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
10866a6a51eeSAndreas Jaekel 		gs.zev_queue_name.zev_namelen =
10876a6a51eeSAndreas Jaekel 		    gql.zev_queue_name[i].zev_namelen;
1088add9520fSAndreas Jaekel 
1089add9520fSAndreas Jaekel 		if (ioctl(fd, ZEV_IOC_GET_QUEUE_STATISTICS, &gs)) {
1090add9520fSAndreas Jaekel 			if (errno == ENOENT)
1091add9520fSAndreas Jaekel 				continue;
1092add9520fSAndreas Jaekel 			perror("getting statistics data failed");
1093add9520fSAndreas Jaekel 			return (EXIT_FAILURE);
1094add9520fSAndreas Jaekel 		}
1095add9520fSAndreas Jaekel 
1096add9520fSAndreas Jaekel 		printf("%-40s %-10" PRIu64 " %-10" PRIu64 " %-6" PRIu64
1097add9520fSAndreas Jaekel 		       " %-3s %-3s\n",
1098add9520fSAndreas Jaekel 			name,
1099add9520fSAndreas Jaekel 			gs.zev_statistics.zev_queue_len,
1100add9520fSAndreas Jaekel 			gqp.zev_max_queue_len,
1101add9520fSAndreas Jaekel 			gqp.zev_poll_wakeup_threshold,
1102add9520fSAndreas Jaekel 			gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no",
1103add9520fSAndreas Jaekel 			gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ?
1104add9520fSAndreas Jaekel 				 "yes" : "no");
1105add9520fSAndreas Jaekel 	}
1106add9520fSAndreas Jaekel 
1107add9520fSAndreas Jaekel 	return (0);
1108add9520fSAndreas Jaekel }
1109add9520fSAndreas Jaekel 
111042110aacSAndreas Jaekel static int
111142110aacSAndreas Jaekel zev_checksum(int dev_fd, char *filename)
111242110aacSAndreas Jaekel {
111342110aacSAndreas Jaekel 	int fd;
111442110aacSAndreas Jaekel 	offset_t off;
111542110aacSAndreas Jaekel 	offset_t data;
111642110aacSAndreas Jaekel 	zev_sig_t *sig;
111742110aacSAndreas Jaekel 	char *buf;
111842110aacSAndreas Jaekel 	zev_ioctl_get_signatures_t *gs;
111942110aacSAndreas Jaekel 	int i;
112042110aacSAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
112142110aacSAndreas Jaekel 	int buf_size;
112242110aacSAndreas Jaekel 
112342110aacSAndreas Jaekel 	/* control struct, one lv1 signature and up to 256 lv0 signatures */
112442110aacSAndreas Jaekel 	buf_size = (1 + 256) * sizeof(zev_sig_t);
112542110aacSAndreas Jaekel 	buf = malloc(sizeof(zev_ioctl_get_signatures_t) + buf_size);
112642110aacSAndreas Jaekel 	if (!buf) {
112742110aacSAndreas Jaekel 		perror("can't allocate checksum buffer");
112842110aacSAndreas Jaekel 		return (EXIT_FAILURE);
112942110aacSAndreas Jaekel 	}
113042110aacSAndreas Jaekel 
113142110aacSAndreas Jaekel 	fd = open(filename, O_RDONLY);
113242110aacSAndreas Jaekel 	if (fd < 0) {
113342110aacSAndreas Jaekel 		perror("can't open file");
113442110aacSAndreas Jaekel 		return (EXIT_FAILURE);
113542110aacSAndreas Jaekel 	}
113642110aacSAndreas Jaekel 
113742110aacSAndreas Jaekel 	gs = (zev_ioctl_get_signatures_t *)buf;
113842110aacSAndreas Jaekel 	gs->zev_fd = fd;
113942110aacSAndreas Jaekel 	gs->zev_bufsize = buf_size;
114042110aacSAndreas Jaekel 
114142110aacSAndreas Jaekel 	off = 0;
114242110aacSAndreas Jaekel 	data = 0;
114342110aacSAndreas Jaekel 	while (1) {
114442110aacSAndreas Jaekel 		errno = 0;
114542110aacSAndreas Jaekel 		data = llseek(fd, off, SEEK_DATA);
114642110aacSAndreas Jaekel 		if (data < 0) {
114742110aacSAndreas Jaekel 			if (errno == ENXIO)	/* no more data */
114842110aacSAndreas Jaekel 				break;
114942110aacSAndreas Jaekel 			perror("llseek failed");
115042110aacSAndreas Jaekel 			goto err;
115142110aacSAndreas Jaekel 		}
115242110aacSAndreas Jaekel 		data = P2ALIGN(data, ZEV_L1_SIZE);
115342110aacSAndreas Jaekel 		off = data + ZEV_L1_SIZE;
115442110aacSAndreas Jaekel 
115542110aacSAndreas Jaekel 		gs->zev_offset = data;
115642110aacSAndreas Jaekel 		gs->zev_len = ZEV_L1_SIZE;
115742110aacSAndreas Jaekel 
115842110aacSAndreas Jaekel 		if (ioctl(dev_fd, ZEV_IOC_GET_FILE_SIGNATURES, gs)) {
115942110aacSAndreas Jaekel 			perror("ioctl to get signatures failed");
116042110aacSAndreas Jaekel 			goto err;
116142110aacSAndreas Jaekel 		}
116242110aacSAndreas Jaekel 
116342110aacSAndreas Jaekel 		for (i=0; i<gs->zev_signature_cnt; i++) {
116442110aacSAndreas Jaekel 			sig = (zev_sig_t *)ZEV_SIGNATURES(gs);
116542110aacSAndreas Jaekel 			sig += i;
116642110aacSAndreas Jaekel 			sig2hex_direct(sig->value, sigval);
116742110aacSAndreas Jaekel 			printf("level %d, offset %llu, value %s\n",
116842110aacSAndreas Jaekel 			       sig->level, sig->block_offset, sigval);
116942110aacSAndreas Jaekel 		}
117042110aacSAndreas Jaekel 	}
117142110aacSAndreas Jaekel 
117242110aacSAndreas Jaekel 	free(buf);
117342110aacSAndreas Jaekel 	close(fd);
117442110aacSAndreas Jaekel 	return 0;
117542110aacSAndreas Jaekel err:
117642110aacSAndreas Jaekel 	free(buf);
117742110aacSAndreas Jaekel 	close(fd);
117842110aacSAndreas Jaekel 	return (EXIT_FAILURE);
117942110aacSAndreas Jaekel }
118042110aacSAndreas Jaekel 
1181a18c35b9SAndreas Jaekel int
1182a18c35b9SAndreas Jaekel main(int argc, char **argv)
1183a18c35b9SAndreas Jaekel {
1184a18c35b9SAndreas Jaekel 	int fd;
1185a18c35b9SAndreas Jaekel 	int c;
1186a18c35b9SAndreas Jaekel 	extern char *optarg;
11876a6a51eeSAndreas Jaekel 	int create_tmp_queue = 1;
11886a6a51eeSAndreas Jaekel 	char buf[MAXPATHLEN];
1189*a5090b97SAndreas Jaekel 	int mode = 0;
1190*a5090b97SAndreas Jaekel 	char *arg = NULL;
1191*a5090b97SAndreas Jaekel 	char *arg2 = NULL;
1192a18c35b9SAndreas Jaekel 
1193a18c35b9SAndreas Jaekel 	/* open device */
1194a18c35b9SAndreas Jaekel 	fd = open(zev_device, O_RDONLY);
1195a18c35b9SAndreas Jaekel 	if (fd < 0) {
1196a18c35b9SAndreas Jaekel 		perror("opening zev device failed");
1197a18c35b9SAndreas Jaekel 		return EXIT_FAILURE;
1198a18c35b9SAndreas Jaekel 	}
11996a6a51eeSAndreas Jaekel 	while ((c = getopt(argc, argv,
120016ff6b2fSAndreas Jaekel 	                   "gvspc:d:Dlk:L:q:Qt:m:M:a:A:r:P:b:B:h?")) != -1){
1201a18c35b9SAndreas Jaekel 		switch(c) {
120216ff6b2fSAndreas Jaekel 		case 'g':
120316ff6b2fSAndreas Jaekel 			grep_friendly++;
120416ff6b2fSAndreas Jaekel 			verbose++;
120516ff6b2fSAndreas Jaekel 			break;
1206205ed6bfSAndreas Jaekel 		case 'v':
1207205ed6bfSAndreas Jaekel 			verbose++;
1208205ed6bfSAndreas Jaekel 			break;
1209a18c35b9SAndreas Jaekel 		case 's':
1210*a5090b97SAndreas Jaekel 			mode = MD_STATISTICS;
1211*a5090b97SAndreas Jaekel 			break;
1212a18c35b9SAndreas Jaekel 		case 'p':
1213*a5090b97SAndreas Jaekel 			mode = MD_POLL_EVENTS;
1214*a5090b97SAndreas Jaekel 			break;
121542110aacSAndreas Jaekel 		case 'c':
1216*a5090b97SAndreas Jaekel 			mode = MD_CHECKSUMS;
1217*a5090b97SAndreas Jaekel 			arg = optarg;
1218*a5090b97SAndreas Jaekel 			break;
1219add9520fSAndreas Jaekel 		case 'D':
1220*a5090b97SAndreas Jaekel 			mode = MD_DEBUG_INFO;
1221*a5090b97SAndreas Jaekel 			break;
1222a18c35b9SAndreas Jaekel 		case 'd':
1223add9520fSAndreas Jaekel 			close(fd);
1224a18c35b9SAndreas Jaekel 			zev_device = optarg;
1225add9520fSAndreas Jaekel 			fd = open(zev_device, O_RDONLY);
1226add9520fSAndreas Jaekel 			if (fd < 0) {
1227add9520fSAndreas Jaekel 				perror("opening zev device failed");
1228add9520fSAndreas Jaekel 				return EXIT_FAILURE;
1229add9520fSAndreas Jaekel 			}
12306a6a51eeSAndreas Jaekel 			create_tmp_queue = 0;
12316a6a51eeSAndreas Jaekel 			break;
12326a6a51eeSAndreas Jaekel 		case 'q':
12336a6a51eeSAndreas Jaekel 			snprintf(buf, sizeof(buf),
12346a6a51eeSAndreas Jaekel 				 "/devices/pseudo/zev@0:%s", optarg);
12356a6a51eeSAndreas Jaekel 			close(fd);
12366a6a51eeSAndreas Jaekel 			zev_device = buf;
12376a6a51eeSAndreas Jaekel 			fd = open(zev_device, O_RDONLY);
12386a6a51eeSAndreas Jaekel 			if (fd < 0) {
12396a6a51eeSAndreas Jaekel 				perror("opening zev device failed");
12406a6a51eeSAndreas Jaekel 				return EXIT_FAILURE;
12416a6a51eeSAndreas Jaekel 			}
12426a6a51eeSAndreas Jaekel 			create_tmp_queue = 0;
1243a18c35b9SAndreas Jaekel 			break;
1244add9520fSAndreas Jaekel 		case 'l':
1245*a5090b97SAndreas Jaekel 			mode = MD_LIST_QUEUES;
1246*a5090b97SAndreas Jaekel 			break;
1247add9520fSAndreas Jaekel 		case 'Q':
1248*a5090b97SAndreas Jaekel 			mode = MD_SET_GLOBAL_MAX_QUEUE_LEN;
1249*a5090b97SAndreas Jaekel 			arg = optarg;
1250*a5090b97SAndreas Jaekel 			break;
12516a6a51eeSAndreas Jaekel 		case 'L':
1252*a5090b97SAndreas Jaekel 			mode = MD_SET_MAX_QUEUE_LEN;
1253*a5090b97SAndreas Jaekel 			arg = optarg;
1254*a5090b97SAndreas Jaekel 			arg2 = argv[optind];
1255*a5090b97SAndreas Jaekel 			break;
1256fec460f8SAndreas Jaekel 		case 't':
1257*a5090b97SAndreas Jaekel 			mode = MD_SET_POLL_WAKEUP_QUEUE_LEN;
1258*a5090b97SAndreas Jaekel 			arg = optarg;
1259*a5090b97SAndreas Jaekel 			arg2 = argv[optind];
1260*a5090b97SAndreas Jaekel 			break;
1261a18c35b9SAndreas Jaekel 		case 'm':
1262*a5090b97SAndreas Jaekel 			mode = MD_MUTE_POOL;
1263*a5090b97SAndreas Jaekel 			arg = optarg;
1264*a5090b97SAndreas Jaekel 			break;
1265a18c35b9SAndreas Jaekel 		case 'M':
1266*a5090b97SAndreas Jaekel 			mode = MD_UNMUTE_POOL;
1267*a5090b97SAndreas Jaekel 			arg = optarg;
1268*a5090b97SAndreas Jaekel 			break;
1269888fea18SAndreas Jaekel 		case 'k':
1270*a5090b97SAndreas Jaekel 			mode = MD_MARK;
1271*a5090b97SAndreas Jaekel 			arg = optarg;
1272*a5090b97SAndreas Jaekel 			break;
1273add9520fSAndreas Jaekel 		case 'a':
1274*a5090b97SAndreas Jaekel 			mode = MD_ADD_QUEUE;
1275*a5090b97SAndreas Jaekel 			arg = optarg;
1276*a5090b97SAndreas Jaekel 			break;
12776a6a51eeSAndreas Jaekel 		case 'A':
1278*a5090b97SAndreas Jaekel 			mode = MD_ADD_BLOCKING_QUEUE;
1279*a5090b97SAndreas Jaekel 			arg = optarg;
1280*a5090b97SAndreas Jaekel 			break;
1281add9520fSAndreas Jaekel 		case 'r':
1282*a5090b97SAndreas Jaekel 			mode = MD_REMOVE_QUEUE;
1283*a5090b97SAndreas Jaekel 			arg = optarg;
1284*a5090b97SAndreas Jaekel 			break;
1285add9520fSAndreas Jaekel 		case 'b':
1286*a5090b97SAndreas Jaekel 			mode = MD_QUEUE_BLOCKING;
1287*a5090b97SAndreas Jaekel 			arg = optarg;
1288*a5090b97SAndreas Jaekel 			break;
1289add9520fSAndreas Jaekel 		case 'B':
1290*a5090b97SAndreas Jaekel 			mode = MD_QUEUE_NONBLOCKING;
1291*a5090b97SAndreas Jaekel 			arg = optarg;
1292*a5090b97SAndreas Jaekel 			break;
1293add9520fSAndreas Jaekel 		case 'P':
1294*a5090b97SAndreas Jaekel 			mode = MD_QUEUE_PROPERTIES;
1295*a5090b97SAndreas Jaekel 			arg = optarg;
1296*a5090b97SAndreas Jaekel 			break;
1297a18c35b9SAndreas Jaekel 		case 'h':
1298a18c35b9SAndreas Jaekel 		case '?':
1299a18c35b9SAndreas Jaekel 		default:
1300a18c35b9SAndreas Jaekel 			usage(argv[0]);
1301a18c35b9SAndreas Jaekel 		}
1302a18c35b9SAndreas Jaekel 	}
1303*a5090b97SAndreas Jaekel 
1304*a5090b97SAndreas Jaekel 	switch (mode) {
1305*a5090b97SAndreas Jaekel 	case MD_STATISTICS:
1306*a5090b97SAndreas Jaekel 		return zev_statistics(fd);
1307*a5090b97SAndreas Jaekel 	case MD_POLL_EVENTS:
1308*a5090b97SAndreas Jaekel 		return zev_poll_events(fd, create_tmp_queue);
1309*a5090b97SAndreas Jaekel 	case MD_CHECKSUMS:
1310*a5090b97SAndreas Jaekel 		return zev_checksum(fd, arg);
1311*a5090b97SAndreas Jaekel 	case MD_DEBUG_INFO:
1312*a5090b97SAndreas Jaekel 		return zev_debug_info(fd);
1313*a5090b97SAndreas Jaekel 	case MD_LIST_QUEUES:
1314*a5090b97SAndreas Jaekel 		return zev_list_queues(fd);
1315*a5090b97SAndreas Jaekel 	case MD_SET_GLOBAL_MAX_QUEUE_LEN:
1316*a5090b97SAndreas Jaekel 		return zev_set_global_max_queue_len(fd, arg);
1317*a5090b97SAndreas Jaekel 	case MD_SET_MAX_QUEUE_LEN:
1318*a5090b97SAndreas Jaekel 		return zev_set_max_queue_len(fd, arg, arg2);
1319*a5090b97SAndreas Jaekel 	case MD_SET_POLL_WAKEUP_QUEUE_LEN:
1320*a5090b97SAndreas Jaekel 		return zev_set_poll_wakeup_queue_len(fd, arg, arg2);
1321*a5090b97SAndreas Jaekel 	case MD_MUTE_POOL:
1322*a5090b97SAndreas Jaekel 		return zev_mute_pool(fd, arg);
1323*a5090b97SAndreas Jaekel 	case MD_UNMUTE_POOL:
1324*a5090b97SAndreas Jaekel 		return zev_unmute_pool(fd, arg);
1325*a5090b97SAndreas Jaekel 	case MD_MARK:
1326*a5090b97SAndreas Jaekel 		return zev_mark(fd, arg);
1327*a5090b97SAndreas Jaekel 	case MD_ADD_QUEUE:
1328*a5090b97SAndreas Jaekel 		return zev_add_queue(fd, arg, 0);
1329*a5090b97SAndreas Jaekel 	case MD_ADD_BLOCKING_QUEUE:
1330*a5090b97SAndreas Jaekel 		return zev_add_queue(fd, arg, 1);
1331*a5090b97SAndreas Jaekel 	case MD_REMOVE_QUEUE:
1332*a5090b97SAndreas Jaekel 		return zev_remove_queue(fd, arg);
1333*a5090b97SAndreas Jaekel 	case MD_QUEUE_BLOCKING:
1334*a5090b97SAndreas Jaekel 		return zev_queue_blocking(fd, arg, 0);
1335*a5090b97SAndreas Jaekel 	case MD_QUEUE_NONBLOCKING:
1336*a5090b97SAndreas Jaekel 		return zev_queue_blocking(fd, arg, 1);
1337*a5090b97SAndreas Jaekel 	case MD_QUEUE_PROPERTIES:
1338*a5090b97SAndreas Jaekel 		return zev_queue_properties(fd, arg);
1339*a5090b97SAndreas Jaekel 	default:
1340a18c35b9SAndreas Jaekel 		close(fd);
1341*a5090b97SAndreas Jaekel 		usage(argv[0]);
1342add9520fSAndreas Jaekel 		return EXIT_FAILURE;
1343*a5090b97SAndreas Jaekel 	};
1344a18c35b9SAndreas Jaekel }
1345a18c35b9SAndreas Jaekel 
1346