xref: /titanic_50/usr/src/cmd/zevadm/zevadm.c (revision 6a3d43bf55bd8eaf42c06ebe6bc0d0dcf17fcaab)
12bb8e5e2SAndreas Jaekel #include <stdio.h>
22bb8e5e2SAndreas Jaekel #include <unistd.h>
32bb8e5e2SAndreas Jaekel #include <stdlib.h>
42bb8e5e2SAndreas Jaekel #include <fcntl.h>
52bb8e5e2SAndreas Jaekel #include <stropts.h>
62bb8e5e2SAndreas Jaekel #include <poll.h>
72bb8e5e2SAndreas Jaekel #include <string.h>
82bb8e5e2SAndreas Jaekel #include <sys/fs/zev.h>
92bb8e5e2SAndreas Jaekel #include <errno.h>
10b9710123SAndreas Jaekel #include <sys/sysmacros.h>
11d65b2fffSAndreas Jaekel #include <stdarg.h>
122bb8e5e2SAndreas Jaekel 
13e9a5e479SAndreas Jaekel #define ZEV_DEVICE "/devices/pseudo/zev@0:ctrl"
142bb8e5e2SAndreas Jaekel 
152bb8e5e2SAndreas Jaekel static char *zev_device = ZEV_DEVICE;
162bb8e5e2SAndreas Jaekel 
179193e9c2SAndreas Jaekel static char *zev_op_name[] = {
18d65b2fffSAndreas Jaekel 	"ERROR",
19d65b2fffSAndreas Jaekel 	"MARK",
20d65b2fffSAndreas Jaekel 	"ZFS_MOUNT",
21d65b2fffSAndreas Jaekel 	"ZFS_UMOUNT",
22d65b2fffSAndreas Jaekel 	"ZVOL_WRITE",
23d65b2fffSAndreas Jaekel 	"ZVOL_TRUNCATE",
24d65b2fffSAndreas Jaekel 	"ZNODE_CLOSE_AFTER_UPDATE",
25d65b2fffSAndreas Jaekel 	"ZNODE_CREATE",
26d65b2fffSAndreas Jaekel 	"ZNODE_MKDIR",
27d65b2fffSAndreas Jaekel 	"ZNODE_MAKE_XATTR_DIR",
28d65b2fffSAndreas Jaekel 	"ZNODE_REMOVE",
29d65b2fffSAndreas Jaekel 	"ZNODE_RMDIR",
30d65b2fffSAndreas Jaekel 	"ZNODE_LINK",
31d65b2fffSAndreas Jaekel 	"ZNODE_SYMLINK",
32d65b2fffSAndreas Jaekel 	"ZNODE_RENAME",
33d65b2fffSAndreas Jaekel 	"ZNODE_WRITE",
34d65b2fffSAndreas Jaekel 	"ZNODE_TRUNCATE",
35d65b2fffSAndreas Jaekel 	"ZNODE_SETATTR",
36d65b2fffSAndreas Jaekel 	"ZNODE_ACL",
379193e9c2SAndreas Jaekel 	NULL
389193e9c2SAndreas Jaekel };
399193e9c2SAndreas Jaekel 
40*6a3d43bfSAndreas Jaekel #define MD_STATISTICS			1
41*6a3d43bfSAndreas Jaekel #define MD_POLL_EVENTS			2
42*6a3d43bfSAndreas Jaekel #define MD_CHECKSUMS			3
43*6a3d43bfSAndreas Jaekel #define MD_DEBUG_INFO			4
44*6a3d43bfSAndreas Jaekel #define MD_LIST_QUEUES			5
45*6a3d43bfSAndreas Jaekel #define MD_SET_GLOBAL_MAX_QUEUE_LEN	6
46*6a3d43bfSAndreas Jaekel #define MD_SET_MAX_QUEUE_LEN		7
47*6a3d43bfSAndreas Jaekel #define MD_SET_POLL_WAKEUP_QUEUE_LEN	8
48*6a3d43bfSAndreas Jaekel #define MD_MUTE_POOL			9
49*6a3d43bfSAndreas Jaekel #define MD_UNMUTE_POOL			10
50*6a3d43bfSAndreas Jaekel #define MD_MARK				11
51*6a3d43bfSAndreas Jaekel #define MD_ADD_QUEUE			12
52*6a3d43bfSAndreas Jaekel #define MD_ADD_BLOCKING_QUEUE		13
53*6a3d43bfSAndreas Jaekel #define MD_REMOVE_QUEUE			14
54*6a3d43bfSAndreas Jaekel #define MD_QUEUE_BLOCKING		15
55*6a3d43bfSAndreas Jaekel #define MD_QUEUE_NONBLOCKING		16
56*6a3d43bfSAndreas Jaekel #define MD_QUEUE_PROPERTIES		17
57*6a3d43bfSAndreas Jaekel 
585e286361SAndreas Jaekel static int verbose = 0;
59d65b2fffSAndreas Jaekel static int grep_friendly = 0;
60d65b2fffSAndreas Jaekel 
61d65b2fffSAndreas Jaekel static void
62d65b2fffSAndreas Jaekel zpf(char *fmt, ...)
63d65b2fffSAndreas Jaekel {
64d65b2fffSAndreas Jaekel 	va_list	ap;
65d65b2fffSAndreas Jaekel 
66d65b2fffSAndreas Jaekel 	va_start(ap, fmt);
67d65b2fffSAndreas Jaekel 	vprintf(fmt, ap);
68d65b2fffSAndreas Jaekel 	va_end(ap);
69d65b2fffSAndreas Jaekel 	if (grep_friendly) {
70d65b2fffSAndreas Jaekel 		printf(" ");
71d65b2fffSAndreas Jaekel 	} else {
72d65b2fffSAndreas Jaekel 		printf("\n");
73d65b2fffSAndreas Jaekel 	}
74d65b2fffSAndreas Jaekel }
75d65b2fffSAndreas Jaekel 
76d65b2fffSAndreas Jaekel static void
77d65b2fffSAndreas Jaekel znl(void)
78d65b2fffSAndreas Jaekel {
79d65b2fffSAndreas Jaekel 	if (grep_friendly)
80d65b2fffSAndreas Jaekel 		printf("\n");
81d65b2fffSAndreas Jaekel }
825e286361SAndreas Jaekel 
831ca5a13bSAndreas Jaekel static void
841ca5a13bSAndreas Jaekel sig2hex_direct(const uint8_t *sig, char *hex)
851ca5a13bSAndreas Jaekel {
861ca5a13bSAndreas Jaekel 	int     i;
871ca5a13bSAndreas Jaekel 
881ca5a13bSAndreas Jaekel 	for (i = 0; i < SHA1_DIGEST_LENGTH; ++i) {
891ca5a13bSAndreas Jaekel 		sprintf(hex + 2 * i, "%02x", sig[i]);
901ca5a13bSAndreas Jaekel 	}
911ca5a13bSAndreas Jaekel 	hex[SHA1_DIGEST_LENGTH * 2] = '\0';
921ca5a13bSAndreas Jaekel }
931ca5a13bSAndreas Jaekel 
94e9a5e479SAndreas Jaekel static int
952bb8e5e2SAndreas Jaekel zev_statistics(int fd)
962bb8e5e2SAndreas Jaekel {
972bb8e5e2SAndreas Jaekel 	zev_statistics_t zs;
98e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) {
992bb8e5e2SAndreas Jaekel 		perror("getting statistics data failed");
100e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
1012bb8e5e2SAndreas Jaekel 	}
1022bb8e5e2SAndreas Jaekel 	printf("ZEV module state:\n");
1032bb8e5e2SAndreas Jaekel 
1042bb8e5e2SAndreas Jaekel 	printf("    queue length in bytes   : %lu\n", zs.zev_queue_len);
1052bb8e5e2SAndreas Jaekel 	printf("    queue length limit      : %lu\n", zs.zev_max_queue_len);
1062bb8e5e2SAndreas Jaekel 	printf("    bytes read from device  : %lu\n", zs.zev_bytes_read);
1072bb8e5e2SAndreas Jaekel 	printf("    module internal errors  : %lu\n\n", zs.zev_cnt_errors);
1082bb8e5e2SAndreas Jaekel 
109e9a5e479SAndreas Jaekel 	printf("    discarded events        : %lu\n",
110e9a5e479SAndreas Jaekel 	    zs.zev_cnt_discarded_events);
111e9a5e479SAndreas Jaekel 	printf("    discarded bytes         : %lu\n\n", zs.zev_bytes_discarded);
112e9a5e479SAndreas Jaekel 
1132bb8e5e2SAndreas Jaekel 	printf("ZFS event statistics:\n");
1142bb8e5e2SAndreas Jaekel 
1152bb8e5e2SAndreas Jaekel 	printf("    total ZFS events        : %lu\n", zs.zev_cnt_total_events);
1162bb8e5e2SAndreas Jaekel 	printf("    ZFS mount               : %lu\n", zs.zev_cnt_zfs_mount);
1172bb8e5e2SAndreas Jaekel 	printf("    ZFS umount              : %lu\n", zs.zev_cnt_zfs_umount);
1182bb8e5e2SAndreas Jaekel 	printf("    ZVOL write              : %lu\n", zs.zev_cnt_zvol_write);
1192bb8e5e2SAndreas Jaekel 	printf("    ZVOL truncate           : %lu\n", zs.zev_cnt_zvol_truncate);
1202bb8e5e2SAndreas Jaekel 	printf("    ZNODE close after update: %lu\n",
1212bb8e5e2SAndreas Jaekel 	    zs.zev_cnt_znode_close_after_update);
1222bb8e5e2SAndreas Jaekel 	printf("    ZNODE create            : %lu\n", zs.zev_cnt_znode_create);
1232bb8e5e2SAndreas Jaekel 	printf("    ZNODE remove            : %lu\n", zs.zev_cnt_znode_remove);
1242bb8e5e2SAndreas Jaekel 	printf("    ZNODE link              : %lu\n", zs.zev_cnt_znode_link);
1252bb8e5e2SAndreas Jaekel 	printf("    ZNODE symlink           : %lu\n", zs.zev_cnt_znode_symlink);
1262bb8e5e2SAndreas Jaekel 	printf("    ZNODE rename            : %lu\n", zs.zev_cnt_znode_rename);
1272bb8e5e2SAndreas Jaekel 	printf("    ZNODE write             : %lu\n", zs.zev_cnt_znode_write);
1282bb8e5e2SAndreas Jaekel 	printf("    ZNODE truncate          : %lu\n",
1292bb8e5e2SAndreas Jaekel 	    zs.zev_cnt_znode_truncate);
1302bb8e5e2SAndreas Jaekel 	printf("    ZNODE setattr           : %lu\n", zs.zev_cnt_znode_setattr);
1312bb8e5e2SAndreas Jaekel 	printf("    ZNODE acl               : %lu\n", zs.zev_cnt_znode_acl);
132e9a5e479SAndreas Jaekel 	return EXIT_SUCCESS;
1332bb8e5e2SAndreas Jaekel }
1342bb8e5e2SAndreas Jaekel 
1352bb8e5e2SAndreas Jaekel static void
136d65b2fffSAndreas Jaekel zev_print_inode_info(char *name, zev_inode_info_t *info)
137d65b2fffSAndreas Jaekel {
138d65b2fffSAndreas Jaekel 	zpf("  %s.inode: %llu", name, info->ino);
139d65b2fffSAndreas Jaekel 	zpf("  %s.gen: %llu", name, info->gen);
140d65b2fffSAndreas Jaekel 	zpf("  %s.mtime: %llu", name, info->mtime);
141d65b2fffSAndreas Jaekel 	zpf("  %s.ctime: %llu", name, info->ctime);
142d65b2fffSAndreas Jaekel 	zpf("  %s.size: %llu", name, info->size);
143d65b2fffSAndreas Jaekel 	zpf("  %s.mode: %llo", name, info->mode);
144d65b2fffSAndreas Jaekel 	zpf("  %s.links: %llu", name, info->links);
145d65b2fffSAndreas Jaekel 	zpf("  %s.type: %lu", name, info->type);
146d65b2fffSAndreas Jaekel 	zpf("  %s.flags: %lu", name, info->flags);
147d65b2fffSAndreas Jaekel }
148d65b2fffSAndreas Jaekel 
149d65b2fffSAndreas Jaekel static void
150d65b2fffSAndreas Jaekel zev_print_mark_payload(zev_mark_t *rec)
151d65b2fffSAndreas Jaekel {
152d65b2fffSAndreas Jaekel 	int i;
153d65b2fffSAndreas Jaekel 	int j;
154d65b2fffSAndreas Jaekel 	uint8_t *p;
155d65b2fffSAndreas Jaekel 	char c;
156d65b2fffSAndreas Jaekel 
157d65b2fffSAndreas Jaekel 	zpf("  payload:");
158d65b2fffSAndreas Jaekel 	p = (uint8_t *)ZEV_PAYLOAD(rec);
159d65b2fffSAndreas Jaekel 	for (i=0; i<rec->payload_len; i+=16) {
160d65b2fffSAndreas Jaekel 		printf("  ");
161d65b2fffSAndreas Jaekel 		for (j=i; j<rec->payload_len && j<i+16; j++) {
162d65b2fffSAndreas Jaekel 			printf("%02x ", p[j]);
163d65b2fffSAndreas Jaekel 			if (j == i + 7)
164d65b2fffSAndreas Jaekel 				printf(" ");
165d65b2fffSAndreas Jaekel 		}
166d65b2fffSAndreas Jaekel 		if (grep_friendly)
167d65b2fffSAndreas Jaekel 			continue;
168d65b2fffSAndreas Jaekel 		for (; j<i+16; j++) {
169d65b2fffSAndreas Jaekel 			printf("   ");
170d65b2fffSAndreas Jaekel 			if (j == i + 7)
171d65b2fffSAndreas Jaekel 				printf(" ");
172d65b2fffSAndreas Jaekel 		}
173d65b2fffSAndreas Jaekel 		printf("    ");
174d65b2fffSAndreas Jaekel 		for (j=i; j<rec->payload_len && j<i+16; j++) {
175d65b2fffSAndreas Jaekel 			c = '.';
176d65b2fffSAndreas Jaekel 			if (p[j] >= ' ' && p[j] <= '~')
177d65b2fffSAndreas Jaekel 				c = p[j];
178d65b2fffSAndreas Jaekel 			printf("%c", c);
179d65b2fffSAndreas Jaekel 			if (j == i + 7)
180d65b2fffSAndreas Jaekel 				printf(" ");
181d65b2fffSAndreas Jaekel 		}
182d65b2fffSAndreas Jaekel 		printf("\n");
183d65b2fffSAndreas Jaekel 	}
184d65b2fffSAndreas Jaekel }
185d65b2fffSAndreas Jaekel 
186d65b2fffSAndreas Jaekel static void
18763aba447SAndreas Jaekel zev_print_error(char *buf)
18863aba447SAndreas Jaekel {
18963aba447SAndreas Jaekel 	zev_error_t *rec = (zev_error_t *)buf;
19063aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
19163aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
19263aba447SAndreas Jaekel 
193d65b2fffSAndreas Jaekel 	if (verbose) {
194d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
195d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
196d65b2fffSAndreas Jaekel 		zpf("  failed.op: %s",
197d65b2fffSAndreas Jaekel 		    zev_op_name[rec->failed_op - ZEV_OP_MIN]);
198d65b2fffSAndreas Jaekel 		zpf("  message: %s", ZEV_ERRSTR(rec));
199d65b2fffSAndreas Jaekel 		znl();
200d65b2fffSAndreas Jaekel 	} else {
20163aba447SAndreas Jaekel 		printf("%s %s: failed_op=%s msg=%s\n",
20263aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
203d65b2fffSAndreas Jaekel 		       zev_op_name[rec->failed_op - ZEV_OP_MIN],
204d65b2fffSAndreas Jaekel 		       ZEV_ERRSTR(rec));
205d65b2fffSAndreas Jaekel 	}
20663aba447SAndreas Jaekel }
20763aba447SAndreas Jaekel 
20863aba447SAndreas Jaekel static void
20901c2c787SAndreas Jaekel zev_print_mark(char *buf)
21001c2c787SAndreas Jaekel {
21101c2c787SAndreas Jaekel 	zev_mark_t *rec = (zev_mark_t *)buf;
21201c2c787SAndreas Jaekel 	time_t op_time = rec->op_time;
21301c2c787SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
21401c2c787SAndreas Jaekel 
215d65b2fffSAndreas Jaekel 	if (verbose) {
216d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
217d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
218d65b2fffSAndreas Jaekel 		zpf("  mark.id: %llu", rec->mark_id);
219d65b2fffSAndreas Jaekel 		zpf("  payload.len: %llu", rec->payload_len);
220d65b2fffSAndreas Jaekel 		if (rec->payload_len)
221d65b2fffSAndreas Jaekel 			zev_print_mark_payload(rec);
222d65b2fffSAndreas Jaekel 		znl();
223d65b2fffSAndreas Jaekel 	} else {
22401c2c787SAndreas Jaekel 		printf("%s %s: guid=%llu mark_id=%lld payload_len=%ld\n",
225d65b2fffSAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN], rec->guid,
226d65b2fffSAndreas Jaekel 		       rec->mark_id, rec->payload_len);
227d65b2fffSAndreas Jaekel 	}
22801c2c787SAndreas Jaekel }
22901c2c787SAndreas Jaekel 
23001c2c787SAndreas Jaekel static void
23163aba447SAndreas Jaekel zev_print_zfs_mount(char *buf)
23263aba447SAndreas Jaekel {
23363aba447SAndreas Jaekel 	zev_zfs_mount_t *rec = (zev_zfs_mount_t *)buf;
23463aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
23563aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
23663aba447SAndreas Jaekel 
237d65b2fffSAndreas Jaekel 	if (verbose) {
238d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
239d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
240d65b2fffSAndreas Jaekel 		zpf("  dataset: %s", ZEV_DATASET(rec));
241d65b2fffSAndreas Jaekel 		zpf("  mountpoint: %s", ZEV_MOUNTPOINT(rec));
242d65b2fffSAndreas Jaekel 		zpf("  remount: %s", rec->remount ? "true" : "false");
243d65b2fffSAndreas Jaekel 		zev_print_inode_info("root", &rec->root);
244d65b2fffSAndreas Jaekel 		znl();
245d65b2fffSAndreas Jaekel 	} else {
246d65b2fffSAndreas Jaekel 		printf("%s %s: guid=%llu remount=%s dataset='%s' "
247d65b2fffSAndreas Jaekel 		       "mountpoint='%s'\n",
24863aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
24963aba447SAndreas Jaekel 		       rec->guid,
25063aba447SAndreas Jaekel 		       rec->remount ? "true" : "false",
25163aba447SAndreas Jaekel 		       ZEV_DATASET(rec),
25263aba447SAndreas Jaekel 		       ZEV_MOUNTPOINT(rec));
25363aba447SAndreas Jaekel 	}
254d65b2fffSAndreas Jaekel }
25563aba447SAndreas Jaekel 
25663aba447SAndreas Jaekel static void
25763aba447SAndreas Jaekel zev_print_zfs_umount(char *buf)
25863aba447SAndreas Jaekel {
25963aba447SAndreas Jaekel 	zev_zfs_umount_t *rec = (zev_zfs_umount_t *)buf;
26063aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
26163aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
26263aba447SAndreas Jaekel 
263d65b2fffSAndreas Jaekel 	if (verbose) {
264d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
265d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
266d65b2fffSAndreas Jaekel 		znl();
267d65b2fffSAndreas Jaekel 	} else {
26863aba447SAndreas Jaekel 		printf("%s %s: guid=%llu\n",
26963aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
27063aba447SAndreas Jaekel 		       rec->guid);
27163aba447SAndreas Jaekel 	}
272d65b2fffSAndreas Jaekel }
27363aba447SAndreas Jaekel 
27463aba447SAndreas Jaekel static void
27563aba447SAndreas Jaekel zev_print_zvol_truncate(char *buf)
27663aba447SAndreas Jaekel {
27763aba447SAndreas Jaekel 	zev_zvol_truncate_t *rec = (zev_zvol_truncate_t *)buf;
27863aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
27963aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
28063aba447SAndreas Jaekel 
281d65b2fffSAndreas Jaekel 	if (verbose) {
282d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
283d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
284e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
285d65b2fffSAndreas Jaekel 		zpf("  offset: %llu", rec->offset);
286d65b2fffSAndreas Jaekel 		zpf("  length: %llu", rec->length);
287d65b2fffSAndreas Jaekel 		znl();
288d65b2fffSAndreas Jaekel 	} else {
28963aba447SAndreas Jaekel 		printf("%s %s: guid=%llu offset=%llu length=%llu\n",
29063aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
29163aba447SAndreas Jaekel 		       rec->guid,
29263aba447SAndreas Jaekel 		       rec->offset,
29363aba447SAndreas Jaekel 		       rec->length);
29463aba447SAndreas Jaekel 	}
295d65b2fffSAndreas Jaekel }
29663aba447SAndreas Jaekel 
29763aba447SAndreas Jaekel static void
29863aba447SAndreas Jaekel zev_print_zvol_write(char *buf)
29963aba447SAndreas Jaekel {
30063aba447SAndreas Jaekel 	zev_print_zvol_truncate(buf);
30163aba447SAndreas Jaekel }
30263aba447SAndreas Jaekel 
30363aba447SAndreas Jaekel static void
30463aba447SAndreas Jaekel zev_print_znode_close_after_update(char *buf)
30563aba447SAndreas Jaekel {
30663aba447SAndreas Jaekel 	zev_znode_close_after_update_t *rec =
30763aba447SAndreas Jaekel 	    (zev_znode_close_after_update_t *)buf;
30863aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
30963aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
31063aba447SAndreas Jaekel 
311d65b2fffSAndreas Jaekel 	if (verbose) {
312d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
313d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
314d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
315d65b2fffSAndreas Jaekel 		znl();
316d65b2fffSAndreas Jaekel 	} else {
31763aba447SAndreas Jaekel 		printf("%s %s: guid=%llu file=%llu.%llu\n",
31863aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
31963aba447SAndreas Jaekel 		       rec->guid,
32063aba447SAndreas Jaekel 		       rec->file.ino, rec->file.gen);
32163aba447SAndreas Jaekel 	}
322d65b2fffSAndreas Jaekel }
32363aba447SAndreas Jaekel 
32463aba447SAndreas Jaekel static void
32563aba447SAndreas Jaekel zev_print_znode_create(char *buf)
32663aba447SAndreas Jaekel {
32763aba447SAndreas Jaekel 	zev_znode_create_t *rec = (zev_znode_create_t *)buf;
32863aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
32963aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
3301ca5a13bSAndreas Jaekel 	zev_sig_t *sig;
3311ca5a13bSAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
33263aba447SAndreas Jaekel 
333d65b2fffSAndreas Jaekel 	if (verbose) {
334d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
335d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
336e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
337d65b2fffSAndreas Jaekel 		zpf("  name: '%s'", ZEV_NAME(rec));
3381ca5a13bSAndreas Jaekel 		sig = &rec->signature;
3391ca5a13bSAndreas Jaekel 		sig2hex_direct(sig->value, sigval);
3401ca5a13bSAndreas Jaekel 		zpf("  sig: level %d, offset %llu, value %s",
3411ca5a13bSAndreas Jaekel 		    sig->level, sig->block_offset, sigval);
342d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
343e206ace3SAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
344d65b2fffSAndreas Jaekel 		znl();
345d65b2fffSAndreas Jaekel 	} else {
346c035b1e8SAndreas Jaekel 		printf("%s %s: guid=%llu parent=%llu.%llu file=%llu.%llu "
347c035b1e8SAndreas Jaekel 		       "file.mtime=%llu, parent.mtime=%llu, name='%s'\n",
34863aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
34963aba447SAndreas Jaekel 		       rec->guid,
35063aba447SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
35163aba447SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
352c035b1e8SAndreas Jaekel 		       rec->file.mtime, rec->parent.mtime,
35363aba447SAndreas Jaekel 		       ZEV_NAME(rec));
35463aba447SAndreas Jaekel 	}
355d65b2fffSAndreas Jaekel }
35663aba447SAndreas Jaekel 
35763aba447SAndreas Jaekel static void
35863aba447SAndreas Jaekel zev_print_znode_mkdir(char *buf)
35963aba447SAndreas Jaekel {
36063aba447SAndreas Jaekel 	zev_print_znode_create(buf);
36163aba447SAndreas Jaekel }
36263aba447SAndreas Jaekel 
36363aba447SAndreas Jaekel static void
36463aba447SAndreas Jaekel zev_print_znode_make_xattr_dir(char *buf)
36563aba447SAndreas Jaekel {
36663aba447SAndreas Jaekel 	zev_print_znode_create(buf);
36763aba447SAndreas Jaekel }
36863aba447SAndreas Jaekel 
36963aba447SAndreas Jaekel static void
37063aba447SAndreas Jaekel zev_print_znode_remove(char *buf)
37163aba447SAndreas Jaekel {
37263aba447SAndreas Jaekel 	zev_znode_remove_t *rec = (zev_znode_remove_t *)buf;
37363aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
37463aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
37563aba447SAndreas Jaekel 
376d65b2fffSAndreas Jaekel 	if (verbose) {
377d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
378d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
379e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
380d65b2fffSAndreas Jaekel 		zpf("  file.name: '%s'", ZEV_NAME(rec));
381d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
382e206ace3SAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
383d65b2fffSAndreas Jaekel 		znl();
384d65b2fffSAndreas Jaekel 	} else {
385d65b2fffSAndreas Jaekel 		printf("%s %s: guid=%llu parent=%llu.%llu "
386d65b2fffSAndreas Jaekel 		       "file.mtime=%llu name='%s'\n",
38763aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
38863aba447SAndreas Jaekel 		       rec->guid,
38963aba447SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
3906db5d4ecSAndreas Jaekel 		       rec->file.mtime,
39163aba447SAndreas Jaekel 		       ZEV_NAME(rec));
39263aba447SAndreas Jaekel 	}
393d65b2fffSAndreas Jaekel }
39463aba447SAndreas Jaekel 
39563aba447SAndreas Jaekel static void
39663aba447SAndreas Jaekel zev_print_znode_rmdir(char *buf)
39763aba447SAndreas Jaekel {
39863aba447SAndreas Jaekel 	zev_print_znode_remove(buf);
39963aba447SAndreas Jaekel }
40063aba447SAndreas Jaekel 
40163aba447SAndreas Jaekel static void
40263aba447SAndreas Jaekel zev_print_znode_link(char *buf)
40363aba447SAndreas Jaekel {
40463aba447SAndreas Jaekel 	zev_znode_link_t *rec = (zev_znode_link_t *)buf;
40563aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
40663aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
40763aba447SAndreas Jaekel 
408d65b2fffSAndreas Jaekel 	if (verbose) {
409d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
410d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
411e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
412d65b2fffSAndreas Jaekel 		zpf("  link.name: '%s'", ZEV_NAME(rec));
413d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
414e206ace3SAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
415d65b2fffSAndreas Jaekel 		znl();
416d65b2fffSAndreas Jaekel 	} else {
41703101f54SAndreas Jaekel 		printf("%s %s: parent=%llu.%llu file=%llu.%llu "
41803101f54SAndreas Jaekel 		       "file.ctime=%llu parent.ctime=%llu name='%s'\n",
41963aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
42063aba447SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
42163aba447SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
42203101f54SAndreas Jaekel 		       rec->file.ctime, rec->parent.ctime,
42363aba447SAndreas Jaekel 		       ZEV_NAME(rec));
424d65b2fffSAndreas Jaekel 	}
42563aba447SAndreas Jaekel }
42663aba447SAndreas Jaekel 
42763aba447SAndreas Jaekel static void
42863aba447SAndreas Jaekel zev_print_znode_symlink(char *buf)
42963aba447SAndreas Jaekel {
43063aba447SAndreas Jaekel 	zev_znode_symlink_t *rec = (zev_znode_symlink_t *)buf;
43163aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
43263aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
4331ca5a13bSAndreas Jaekel 	zev_sig_t *sig;
4341ca5a13bSAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
43563aba447SAndreas Jaekel 
436d65b2fffSAndreas Jaekel 	if (verbose) {
437d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
438d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
439e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
440d65b2fffSAndreas Jaekel 		zpf("  symlink.name: '%s'", ZEV_NAME(rec));
441d65b2fffSAndreas Jaekel 		zpf("  symlink.link: '%s'", ZEV_LINK(rec));
4421ca5a13bSAndreas Jaekel 		sig = &rec->signature;
4431ca5a13bSAndreas Jaekel 		sig2hex_direct(sig->value, sigval);
4441ca5a13bSAndreas Jaekel 		zpf("  sig: level %d, offset %llu, value %s",
4451ca5a13bSAndreas Jaekel 		    sig->level, sig->block_offset, sigval);
446d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
447e206ace3SAndreas Jaekel 		zev_print_inode_info("parent", &rec->parent);
448d65b2fffSAndreas Jaekel 		znl();
449d65b2fffSAndreas Jaekel 	} else {
450d65b2fffSAndreas Jaekel 		printf("%s %s: parent=%llu.%llu file=%llu.%llu "
451d65b2fffSAndreas Jaekel 		       "name='%s' link='%s'\n",
45263aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
45363aba447SAndreas Jaekel 		       rec->parent.ino, rec->parent.gen,
45463aba447SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
45563aba447SAndreas Jaekel 		       ZEV_NAME(rec),
45663aba447SAndreas Jaekel 		       ZEV_LINK(rec));
45763aba447SAndreas Jaekel 	}
458d65b2fffSAndreas Jaekel }
45963aba447SAndreas Jaekel 
46063aba447SAndreas Jaekel static void
46163aba447SAndreas Jaekel zev_print_znode_rename(char *buf)
46263aba447SAndreas Jaekel {
46363aba447SAndreas Jaekel 	zev_znode_rename_t *rec = (zev_znode_rename_t *)buf;
46463aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
46563aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
46663aba447SAndreas Jaekel 
467d65b2fffSAndreas Jaekel 	if (verbose) {
468d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
469d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
470e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
471d65b2fffSAndreas Jaekel 		zpf("  file.srcname: '%s'", ZEV_SRCNAME(rec));
472d65b2fffSAndreas Jaekel 		zpf("  file.dstname: '%s'", ZEV_DSTNAME(rec));
473d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
474d65b2fffSAndreas Jaekel 		zev_print_inode_info("srcdir", &rec->srcdir);
475d65b2fffSAndreas Jaekel 		zev_print_inode_info("dstdir", &rec->dstdir);
476d65b2fffSAndreas Jaekel 		znl();
477d65b2fffSAndreas Jaekel 	} else {
478d65b2fffSAndreas Jaekel 		printf("%s %s: srcdir=%llu.%llu dstdir=%llu.%llu "
479d65b2fffSAndreas Jaekel 		       "file=%llu.%llu file.mtime=%llu, file.ctime=%llu, "
480d65b2fffSAndreas Jaekel 		       "srcdir.mtime=%llu, srcdir.ctime=%llu, "
481d65b2fffSAndreas Jaekel 		       "dstdir.mtime=%llu, dstdir.ctime=%llu, "
48263aba447SAndreas Jaekel 		       "srcname='%s' dstname='%s'\n",
48363aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
48463aba447SAndreas Jaekel 		       rec->srcdir.ino, rec->srcdir.gen,
48563aba447SAndreas Jaekel 		       rec->dstdir.ino, rec->dstdir.gen,
48663aba447SAndreas Jaekel 		       rec->file.ino, rec->file.gen,
487c035b1e8SAndreas Jaekel 		       rec->file.mtime, rec->file.ctime,
488c035b1e8SAndreas Jaekel 		       rec->srcdir.mtime, rec->srcdir.ctime,
489c035b1e8SAndreas Jaekel 		       rec->dstdir.mtime, rec->dstdir.ctime,
49063aba447SAndreas Jaekel 		       ZEV_SRCNAME(rec),
49163aba447SAndreas Jaekel 		       ZEV_DSTNAME(rec));
49263aba447SAndreas Jaekel 	}
493d65b2fffSAndreas Jaekel }
49463aba447SAndreas Jaekel 
49563aba447SAndreas Jaekel static void
49663aba447SAndreas Jaekel zev_print_znode_write(char *buf)
49763aba447SAndreas Jaekel {
49863aba447SAndreas Jaekel 	zev_znode_write_t *rec = (zev_znode_write_t *)buf;
49963aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
50063aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
5015e286361SAndreas Jaekel 	zev_sig_t *sig;
5025e286361SAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
5035e286361SAndreas Jaekel 	int i;
50463aba447SAndreas Jaekel 
5055e286361SAndreas Jaekel 	if (verbose) {
506d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
507d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
508e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
509d65b2fffSAndreas Jaekel 		zpf("  offset: %llu", rec->offset);
510d65b2fffSAndreas Jaekel 		zpf("  length: %llu", rec->length);
511d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
512d65b2fffSAndreas Jaekel 		znl();
5135e286361SAndreas Jaekel 		for (i=0; i<rec->signature_cnt; i++) {
5145e286361SAndreas Jaekel 			sig = (zev_sig_t *)ZEV_SIGNATURES(rec);
5155e286361SAndreas Jaekel 			sig += i;
5165e286361SAndreas Jaekel 			sig2hex_direct(sig->value, sigval);
5171ca5a13bSAndreas Jaekel 			zpf("  sig: level %d, offset %llu, value %s",
5185e286361SAndreas Jaekel 			    sig->level, sig->block_offset, sigval);
5195e286361SAndreas Jaekel 		}
520d65b2fffSAndreas Jaekel 	} else {
521d65b2fffSAndreas Jaekel 		printf("%s %s: file=%llu.%llu offset=%llu length=%llu\n",
522d65b2fffSAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
523d65b2fffSAndreas Jaekel 		       rec->file.ino, rec->file.gen,
524d65b2fffSAndreas Jaekel 		       rec->offset, rec->length);
5255e286361SAndreas Jaekel 	}
52663aba447SAndreas Jaekel }
52763aba447SAndreas Jaekel 
52863aba447SAndreas Jaekel static void
52963aba447SAndreas Jaekel zev_print_znode_truncate(char *buf)
53063aba447SAndreas Jaekel {
53163aba447SAndreas Jaekel 	zev_print_znode_write(buf);
53263aba447SAndreas Jaekel }
53363aba447SAndreas Jaekel 
53463aba447SAndreas Jaekel static void
53563aba447SAndreas Jaekel zev_print_znode_setattr(char *buf)
53663aba447SAndreas Jaekel {
53763aba447SAndreas Jaekel 	zev_znode_setattr_t *rec = (zev_znode_setattr_t *)buf;
53863aba447SAndreas Jaekel 	time_t op_time = rec->op_time;
53963aba447SAndreas Jaekel 	char *ct = ctime(&op_time); ct[24] = '\0';
54063aba447SAndreas Jaekel 
541d65b2fffSAndreas Jaekel 	if (verbose) {
542d65b2fffSAndreas Jaekel 		zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
543d65b2fffSAndreas Jaekel 		zpf("  guid: %llu", rec->guid);
544e206ace3SAndreas Jaekel 		zpf("  txg: %llu", rec->txg);
545d65b2fffSAndreas Jaekel 		zev_print_inode_info("file", &rec->file);
546d65b2fffSAndreas Jaekel 		znl();
547d65b2fffSAndreas Jaekel 	} else {
548c035b1e8SAndreas Jaekel 		printf("%s %s: file=%llu.%llu mtime=%llu\n",
54963aba447SAndreas Jaekel 		       ct, zev_op_name[rec->op - ZEV_OP_MIN],
550c035b1e8SAndreas Jaekel 		       rec->file.ino, rec->file.gen, rec->file.mtime);
55163aba447SAndreas Jaekel 	}
552d65b2fffSAndreas Jaekel }
55363aba447SAndreas Jaekel 
55463aba447SAndreas Jaekel static void
55563aba447SAndreas Jaekel zev_print_znode_acl(char *buf)
55663aba447SAndreas Jaekel {
55763aba447SAndreas Jaekel 	zev_print_znode_setattr(buf);
55863aba447SAndreas Jaekel }
55963aba447SAndreas Jaekel 
56063aba447SAndreas Jaekel static void
5619193e9c2SAndreas Jaekel zev_print_event(char *buf, int len)
5629193e9c2SAndreas Jaekel {
56363aba447SAndreas Jaekel 	int record_len;
56463aba447SAndreas Jaekel 	int op;
5659193e9c2SAndreas Jaekel 
56663aba447SAndreas Jaekel 	record_len = *(uint32_t *)buf;
56763aba447SAndreas Jaekel 	if (record_len != len) {
56863aba447SAndreas Jaekel 		fprintf(stderr, "record length mismatch: got %d, expected %d\n",
56963aba447SAndreas Jaekel 		        record_len, len);
5709193e9c2SAndreas Jaekel 		exit(1);
5719193e9c2SAndreas Jaekel 	}
57263aba447SAndreas Jaekel 	op = *((uint32_t *)buf + 1);
5739193e9c2SAndreas Jaekel 	if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) {
57463aba447SAndreas Jaekel 		fprintf(stderr, "unknown op code: %d\n", op);
5759193e9c2SAndreas Jaekel 		exit(1);
5769193e9c2SAndreas Jaekel 	}
57763aba447SAndreas Jaekel 	switch (op) {
57863aba447SAndreas Jaekel 	case ZEV_OP_ERROR:
57963aba447SAndreas Jaekel 		zev_print_error(buf);
5809193e9c2SAndreas Jaekel 		break;
58101c2c787SAndreas Jaekel 	case ZEV_OP_MARK:
58201c2c787SAndreas Jaekel 		zev_print_mark(buf);
58301c2c787SAndreas Jaekel 		break;
58463aba447SAndreas Jaekel 	case ZEV_OP_ZFS_MOUNT:
58563aba447SAndreas Jaekel 		zev_print_zfs_mount(buf);
5869193e9c2SAndreas Jaekel 		break;
58763aba447SAndreas Jaekel 	case ZEV_OP_ZFS_UMOUNT:
58863aba447SAndreas Jaekel 		zev_print_zfs_umount(buf);
5899193e9c2SAndreas Jaekel 		break;
59063aba447SAndreas Jaekel 	case ZEV_OP_ZVOL_TRUNCATE:
59163aba447SAndreas Jaekel 		zev_print_zvol_truncate(buf);
5929193e9c2SAndreas Jaekel 		break;
59363aba447SAndreas Jaekel 	case ZEV_OP_ZVOL_WRITE:
59463aba447SAndreas Jaekel 		zev_print_zvol_write(buf);
59563aba447SAndreas Jaekel 		break;
59663aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE:
59763aba447SAndreas Jaekel 		zev_print_znode_close_after_update(buf);
59863aba447SAndreas Jaekel 		break;
59963aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_CREATE:
60063aba447SAndreas Jaekel 		zev_print_znode_create(buf);
60163aba447SAndreas Jaekel 		break;
60263aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_MKDIR:
60363aba447SAndreas Jaekel 		zev_print_znode_mkdir(buf);
60463aba447SAndreas Jaekel 		break;
60563aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_MAKE_XATTR_DIR:
60663aba447SAndreas Jaekel 		zev_print_znode_make_xattr_dir(buf);
60763aba447SAndreas Jaekel 		break;
60863aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_REMOVE:
60963aba447SAndreas Jaekel 		zev_print_znode_remove(buf);
61063aba447SAndreas Jaekel 		break;
61163aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_RMDIR:
61263aba447SAndreas Jaekel 		zev_print_znode_rmdir(buf);
61363aba447SAndreas Jaekel 		break;
61463aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_LINK:
61563aba447SAndreas Jaekel 		zev_print_znode_link(buf);
61663aba447SAndreas Jaekel 		break;
61763aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_SYMLINK:
61863aba447SAndreas Jaekel 		zev_print_znode_symlink(buf);
61963aba447SAndreas Jaekel 		break;
62063aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_RENAME:
62163aba447SAndreas Jaekel 		zev_print_znode_rename(buf);
62263aba447SAndreas Jaekel 		break;
62363aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_WRITE:
62463aba447SAndreas Jaekel 		zev_print_znode_write(buf);
62563aba447SAndreas Jaekel 		break;
62663aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_TRUNCATE:
62763aba447SAndreas Jaekel 		zev_print_znode_truncate(buf);
62863aba447SAndreas Jaekel 		break;
62963aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_SETATTR:
63063aba447SAndreas Jaekel 		zev_print_znode_setattr(buf);
63163aba447SAndreas Jaekel 		break;
63263aba447SAndreas Jaekel 	case ZEV_OP_ZNODE_ACL:
63363aba447SAndreas Jaekel 		zev_print_znode_acl(buf);
6349193e9c2SAndreas Jaekel 		break;
6359193e9c2SAndreas Jaekel 	default:
63663aba447SAndreas Jaekel 		fprintf(stderr, "unhandled op code: %d\n", op);
6379193e9c2SAndreas Jaekel 		exit(1);
6389193e9c2SAndreas Jaekel 	}
6399193e9c2SAndreas Jaekel }
6409193e9c2SAndreas Jaekel 
641e9a5e479SAndreas Jaekel static int
6424ca7dd5eSAndreas Jaekel zev_poll_events(int fd, int create_tmp_queue)
6432bb8e5e2SAndreas Jaekel {
6442bb8e5e2SAndreas Jaekel 	struct pollfd pfd[1];
6452bb8e5e2SAndreas Jaekel 	int ret;
6469193e9c2SAndreas Jaekel 	char buf[4096];
64768a46c64SAndreas Jaekel 	zev_event_t *ev;
64868a46c64SAndreas Jaekel 	int off = 0;
649e9a5e479SAndreas Jaekel 	zev_ioctl_add_queue_t aq;
650e9a5e479SAndreas Jaekel 	int q_fd;
651e9a5e479SAndreas Jaekel 
6524ca7dd5eSAndreas Jaekel 	if (create_tmp_queue) {
653e9a5e479SAndreas Jaekel 		aq.zev_max_queue_len = 0;
654e9a5e479SAndreas Jaekel 		aq.zev_flags = ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
655e9a5e479SAndreas Jaekel 		snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN,
656e9a5e479SAndreas Jaekel 			 "zevadm.%ld.%ld", time(NULL), getpid());
657e9a5e479SAndreas Jaekel 		aq.zev_namelen = strlen(aq.zev_name);
658e9a5e479SAndreas Jaekel 
659e9a5e479SAndreas Jaekel 		if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
660e9a5e479SAndreas Jaekel 			perror("adding temporary queue failed");
661e9a5e479SAndreas Jaekel 			return (EXIT_FAILURE);
662e9a5e479SAndreas Jaekel 		}
663e9a5e479SAndreas Jaekel 
6644ca7dd5eSAndreas Jaekel 		snprintf(buf, sizeof(buf),
6654ca7dd5eSAndreas Jaekel 		         "/devices/pseudo/zev@0:%s", aq.zev_name);
666e9a5e479SAndreas Jaekel 		q_fd = open(buf, O_RDONLY);
667e9a5e479SAndreas Jaekel 		if (q_fd < 0) {
668e9a5e479SAndreas Jaekel 			perror("opening queue device failed");
669e9a5e479SAndreas Jaekel 			return (EXIT_FAILURE);
670e9a5e479SAndreas Jaekel 		}
6714ca7dd5eSAndreas Jaekel 	} else {
6724ca7dd5eSAndreas Jaekel 		q_fd = fd;
6734ca7dd5eSAndreas Jaekel 	}
674e9a5e479SAndreas Jaekel 
6752bb8e5e2SAndreas Jaekel 	while (1) {
676e9a5e479SAndreas Jaekel 		pfd[0].fd = q_fd;
6772bb8e5e2SAndreas Jaekel 		pfd[0].events = POLLIN;
6782bb8e5e2SAndreas Jaekel 		ret = poll(pfd, 1, 1000);
6792bb8e5e2SAndreas Jaekel 		if (ret < 0) {
6802bb8e5e2SAndreas Jaekel 			perror("poll failed");
6814ca7dd5eSAndreas Jaekel 			close(q_fd);
682e9a5e479SAndreas Jaekel 			return(EXIT_FAILURE);
6832bb8e5e2SAndreas Jaekel 		}
6842bb8e5e2SAndreas Jaekel 		if (!(pfd[0].revents & POLLIN))
6852bb8e5e2SAndreas Jaekel 			continue;
6862bb8e5e2SAndreas Jaekel 		/* data available */
687e9a5e479SAndreas Jaekel 		ret = read(q_fd, buf, sizeof(buf));
6882bb8e5e2SAndreas Jaekel 		if (ret < 0) {
6892bb8e5e2SAndreas Jaekel 			perror("read failed");
6904ca7dd5eSAndreas Jaekel 			close(q_fd);
691e9a5e479SAndreas Jaekel 			return(EXIT_FAILURE);
6922bb8e5e2SAndreas Jaekel 		}
6932bb8e5e2SAndreas Jaekel 		if (ret == 0)
6942bb8e5e2SAndreas Jaekel 			continue;
69568a46c64SAndreas Jaekel 		while (ret > off) {
69668a46c64SAndreas Jaekel 			ev = (zev_event_t *)(buf + off);
69768a46c64SAndreas Jaekel 			zev_print_event(buf + off, ev->header.record_len);
69868a46c64SAndreas Jaekel 			off += ev->header.record_len;
69968a46c64SAndreas Jaekel 		}
700108668daSAndreas Jaekel 		off = 0;
7012bb8e5e2SAndreas Jaekel 	}
7024ca7dd5eSAndreas Jaekel 	if (create_tmp_queue)
703e9a5e479SAndreas Jaekel 		close(q_fd);
704e9a5e479SAndreas Jaekel 	return EXIT_SUCCESS;
7052bb8e5e2SAndreas Jaekel }
7062bb8e5e2SAndreas Jaekel 
7072bb8e5e2SAndreas Jaekel static void
7082bb8e5e2SAndreas Jaekel usage(char *progname)
7092bb8e5e2SAndreas Jaekel {
710e9a5e479SAndreas Jaekel 	fprintf(stderr, "usage: %s [-d <dev>] [options]\n", progname);
711e9a5e479SAndreas Jaekel 	fprintf(stderr, "\n");
712e9a5e479SAndreas Jaekel 	fprintf(stderr, " Status information:\n");
7132bb8e5e2SAndreas Jaekel 	fprintf(stderr, "   -s                   show zev statistics\n");
7142bb8e5e2SAndreas Jaekel 	fprintf(stderr, "   -p                   poll for ZFS events\n");
715e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -D                   print zev module debug "
716e9a5e479SAndreas Jaekel 	        "information\n");
717e9a5e479SAndreas Jaekel 	fprintf(stderr, "\n");
718e9a5e479SAndreas Jaekel 	fprintf(stderr, " Tune zev module settings:\n");
719e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -Q <bytes>           set maximum event queue "
720e9a5e479SAndreas Jaekel 	        "length\n");
721e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -m <pool>            mute pool, no events for "
722e9a5e479SAndreas Jaekel 	        "this pool\n");
7232bb8e5e2SAndreas Jaekel 	fprintf(stderr, "   -M <pool>            unmute pool\n");
724e9a5e479SAndreas Jaekel 	fprintf(stderr, "\n");
725e9a5e479SAndreas Jaekel 	fprintf(stderr, " Queue management:\n");
726e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -l                   list queues\n");
7274ca7dd5eSAndreas Jaekel 	fprintf(stderr, "   -a <name>            add non-blocking queue\n");
7284ca7dd5eSAndreas Jaekel 	fprintf(stderr, "   -A <name>            add blocking queue\n");
729e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -r <name>            remove queue\n");
730e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -b <name>            make queue non-blocking "
731e9a5e479SAndreas Jaekel 	        "(default)\n");
732e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -B <name>            make queue block when full\n");
733e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -P <name>            display queue properties\n");
7344ca7dd5eSAndreas Jaekel 	fprintf(stderr, "   -L <name> <bytes>    set maximum event queue "
735e9a5e479SAndreas Jaekel 	        "length\n");
736e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -t <name> <bytes>    set queue length poll "
737e9a5e479SAndreas Jaekel 	        "throttle\n");
738e9a5e479SAndreas Jaekel 	fprintf(stderr, "\n");
739e9a5e479SAndreas Jaekel 	fprintf(stderr, " Other options:\n");
740e9a5e479SAndreas Jaekel 	fprintf(stderr, "   -d <dev>             non-default device file. "
741e9a5e479SAndreas Jaekel 	        "('%s')\n", ZEV_DEVICE);
7424ca7dd5eSAndreas Jaekel 	fprintf(stderr, "   -q <name>            use device file for this "
7434ca7dd5eSAndreas Jaekel 		"queue name\n");
74401c2c787SAndreas Jaekel 	fprintf(stderr, "   -k <guid>:<payload>  queue mark event\n");
745b9710123SAndreas Jaekel 	fprintf(stderr, "   -c <filename>        list file's content "
746b9710123SAndreas Jaekel 		"checksums\n");
747d65b2fffSAndreas Jaekel 	fprintf(stderr, "   -v                   verbose: additional output "
7485e286361SAndreas Jaekel 	        "for some operations\n");
749d65b2fffSAndreas Jaekel 	fprintf(stderr, "   -g                   grep-friendly event output, "
750d65b2fffSAndreas Jaekel 	        "one event per line\n");
7512bb8e5e2SAndreas Jaekel 	exit (EXIT_FAILURE);
7522bb8e5e2SAndreas Jaekel }
7532bb8e5e2SAndreas Jaekel 
7542bb8e5e2SAndreas Jaekel static int
7554ca7dd5eSAndreas Jaekel zev_add_queue(int fd, char *arg, int blocking)
7562bb8e5e2SAndreas Jaekel {
757e9a5e479SAndreas Jaekel 	zev_ioctl_add_queue_t aq;
758e9a5e479SAndreas Jaekel 	int namelen;
7592bb8e5e2SAndreas Jaekel 
760e9a5e479SAndreas Jaekel 	namelen = strlen(arg);
761e9a5e479SAndreas Jaekel 	if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
762e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue name too long: %s\n", arg);
7632bb8e5e2SAndreas Jaekel 		return (EXIT_FAILURE);
7642bb8e5e2SAndreas Jaekel 	}
765e9a5e479SAndreas Jaekel 
766e9a5e479SAndreas Jaekel 	aq.zev_namelen = namelen;
767e9a5e479SAndreas Jaekel 	strcpy(aq.zev_name, arg);
7684ca7dd5eSAndreas Jaekel 	aq.zev_flags = ZEV_FL_PERSISTENT;
7694ca7dd5eSAndreas Jaekel 	if (blocking) {
7704ca7dd5eSAndreas Jaekel 		aq.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
7714ca7dd5eSAndreas Jaekel 		aq.zev_max_queue_len = ZEV_MAX_QUEUE_LEN;
7724ca7dd5eSAndreas Jaekel 	} else {
773e9a5e479SAndreas Jaekel 		aq.zev_max_queue_len = (1024 * 1024);
7744ca7dd5eSAndreas Jaekel 	}
775e9a5e479SAndreas Jaekel 
776e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
777e9a5e479SAndreas Jaekel 		perror("adding queue failed");
7782bb8e5e2SAndreas Jaekel 		return (EXIT_FAILURE);
7792bb8e5e2SAndreas Jaekel 	}
7802bb8e5e2SAndreas Jaekel 	return (0);
7812bb8e5e2SAndreas Jaekel }
7822bb8e5e2SAndreas Jaekel 
7832bb8e5e2SAndreas Jaekel static int
784e9a5e479SAndreas Jaekel zev_remove_queue(int fd, char *arg)
785205a9bc9SAndreas Jaekel {
786e9a5e479SAndreas Jaekel 	zev_ioctl_remove_queue_t aq;
787e9a5e479SAndreas Jaekel 	int namelen;
788205a9bc9SAndreas Jaekel 
789e9a5e479SAndreas Jaekel 	namelen = strlen(arg);
790e9a5e479SAndreas Jaekel 	if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
791e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue name too long: %s\n", arg);
792205a9bc9SAndreas Jaekel 		return (EXIT_FAILURE);
793205a9bc9SAndreas Jaekel 	}
794e9a5e479SAndreas Jaekel 
7954ca7dd5eSAndreas Jaekel 	aq.zev_queue_name.zev_namelen = namelen;
7964ca7dd5eSAndreas Jaekel 	strcpy(aq.zev_queue_name.zev_name, arg);
797e9a5e479SAndreas Jaekel 
798e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_REMOVE_QUEUE, &aq)) {
799e9a5e479SAndreas Jaekel 		perror("removing queue failed");
800e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
801e9a5e479SAndreas Jaekel 	}
802e9a5e479SAndreas Jaekel 	return (0);
803e9a5e479SAndreas Jaekel }
804e9a5e479SAndreas Jaekel 
805e9a5e479SAndreas Jaekel static int
806e9a5e479SAndreas Jaekel zev_set_global_max_queue_len(int fd, char *arg)
807e9a5e479SAndreas Jaekel {
808e9a5e479SAndreas Jaekel 	uint64_t maxqueuelen;
809e9a5e479SAndreas Jaekel 
810e9a5e479SAndreas Jaekel 	errno = 0;
811e9a5e479SAndreas Jaekel 	maxqueuelen = strtol(arg, (char **)NULL, 10);
812e9a5e479SAndreas Jaekel 	if (errno) {
813e9a5e479SAndreas Jaekel 		fprintf(stderr, "invalid queue length parameter: %s\n", arg);
814e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
815e9a5e479SAndreas Jaekel 	}
816e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_MAX_QUEUE_LEN, &maxqueuelen)) {
817e9a5e479SAndreas Jaekel 		perror("setting max queue length failed");
818205a9bc9SAndreas Jaekel 		return (EXIT_FAILURE);
819205a9bc9SAndreas Jaekel 	}
820205a9bc9SAndreas Jaekel 	return (0);
821205a9bc9SAndreas Jaekel }
822205a9bc9SAndreas Jaekel 
823205a9bc9SAndreas Jaekel static int
8242bb8e5e2SAndreas Jaekel zev_mute_unmute_impl(int fd, char *poolname, int mute)
8252bb8e5e2SAndreas Jaekel {
8262bb8e5e2SAndreas Jaekel 	zev_ioctl_poolarg_t pa;
8272bb8e5e2SAndreas Jaekel 	int len;
8282bb8e5e2SAndreas Jaekel 	int op = mute ? ZEV_IOC_MUTE_POOL : ZEV_IOC_UNMUTE_POOL;
8292bb8e5e2SAndreas Jaekel 	len = strlen(poolname);
8302bb8e5e2SAndreas Jaekel 	if (len <= 0 || len >= sizeof(pa.zev_poolname)) {
8312bb8e5e2SAndreas Jaekel 		fprintf(stderr, "invalid poolname: %s\n", poolname);
8322bb8e5e2SAndreas Jaekel 		return (EXIT_FAILURE);
8332bb8e5e2SAndreas Jaekel 	}
8342bb8e5e2SAndreas Jaekel 	strcpy(pa.zev_poolname, poolname);
8352bb8e5e2SAndreas Jaekel 	pa.zev_poolname_len = len;
8362bb8e5e2SAndreas Jaekel 	if (ioctl(fd, op, &pa)) {
8372bb8e5e2SAndreas Jaekel 		perror("muting pool data failed");
8382bb8e5e2SAndreas Jaekel 		return (EXIT_FAILURE);
8392bb8e5e2SAndreas Jaekel 	}
8402bb8e5e2SAndreas Jaekel 	return (0);
8412bb8e5e2SAndreas Jaekel }
8422bb8e5e2SAndreas Jaekel 
8432bb8e5e2SAndreas Jaekel int
8442bb8e5e2SAndreas Jaekel zev_mute_pool(int fd, char *poolname)
8452bb8e5e2SAndreas Jaekel {
8462bb8e5e2SAndreas Jaekel 	return zev_mute_unmute_impl(fd, poolname, 1);
8472bb8e5e2SAndreas Jaekel }
8482bb8e5e2SAndreas Jaekel 
8492bb8e5e2SAndreas Jaekel int
8502bb8e5e2SAndreas Jaekel zev_unmute_pool(int fd, char *poolname)
8512bb8e5e2SAndreas Jaekel {
8522bb8e5e2SAndreas Jaekel 	return zev_mute_unmute_impl(fd, poolname, 0);
8532bb8e5e2SAndreas Jaekel }
8542bb8e5e2SAndreas Jaekel 
85501c2c787SAndreas Jaekel static int
856e9a5e479SAndreas Jaekel zev_debug_info(int fd)
857e9a5e479SAndreas Jaekel {
858e9a5e479SAndreas Jaekel 	zev_ioctl_debug_info_t di;
859e9a5e479SAndreas Jaekel 
860e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_DEBUG_INFO, &di)) {
861e9a5e479SAndreas Jaekel 		perror("getting zev debug info failed");
862e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
863e9a5e479SAndreas Jaekel 	}
864e9a5e479SAndreas Jaekel 
865e9a5e479SAndreas Jaekel 	printf("memory allocated: %llu bytes\n", di.zev_memory_allocated);
8665e286361SAndreas Jaekel 	printf("checksum cache size: %llu\n", di.zev_chksum_cache_size);
8675e286361SAndreas Jaekel 	printf("checksum cache hits: %llu\n", di.zev_chksum_cache_hits);
8685e286361SAndreas Jaekel 	printf("checksum cache misses: %llu\n", di.zev_chksum_cache_misses);
869e9a5e479SAndreas Jaekel 	return 0;
870e9a5e479SAndreas Jaekel }
871e9a5e479SAndreas Jaekel 
872e9a5e479SAndreas Jaekel static int
87301c2c787SAndreas Jaekel zev_mark(int fd, char *arg)
87401c2c787SAndreas Jaekel {
87501c2c787SAndreas Jaekel 	zev_ioctl_mark_t *mark;
87601c2c787SAndreas Jaekel 	uint64_t guid;
87701c2c787SAndreas Jaekel 	int len;
87801c2c787SAndreas Jaekel 	char *p;
87901c2c787SAndreas Jaekel 
88001c2c787SAndreas Jaekel 	p = strchr(arg, ':');
88101c2c787SAndreas Jaekel 	if (!p) {
88201c2c787SAndreas Jaekel 		fprintf(stderr, "expected value is <guid>:<payload>, "
88301c2c787SAndreas Jaekel 		        "e.g. '123:hello'\n");
88401c2c787SAndreas Jaekel 		exit (EXIT_FAILURE);
88501c2c787SAndreas Jaekel 	}
88601c2c787SAndreas Jaekel 	*p = '\n';
88701c2c787SAndreas Jaekel 	p++;
88801c2c787SAndreas Jaekel 
88901c2c787SAndreas Jaekel 	errno = 0;
890e9a5e479SAndreas Jaekel 	guid = strtoll(arg, (char **)NULL, 10);
89101c2c787SAndreas Jaekel 	if (errno) {
89201c2c787SAndreas Jaekel 		fprintf(stderr, "guid must be a number.\n");
89301c2c787SAndreas Jaekel 		exit (EXIT_FAILURE);
89401c2c787SAndreas Jaekel 	}
89501c2c787SAndreas Jaekel 
89601c2c787SAndreas Jaekel 	len = strlen(p);
89701c2c787SAndreas Jaekel 
89801c2c787SAndreas Jaekel 	mark = malloc(sizeof(*mark) + len + 1);
89901c2c787SAndreas Jaekel 	if (!mark) {
90001c2c787SAndreas Jaekel 		fprintf(stderr, "can't allocate mark structure: %s\n",
90101c2c787SAndreas Jaekel 		        strerror(errno));
90201c2c787SAndreas Jaekel 		exit (EXIT_FAILURE);
90301c2c787SAndreas Jaekel 	}
90401c2c787SAndreas Jaekel 	mark->zev_guid = guid;
90501c2c787SAndreas Jaekel 	mark->zev_mark_id = 0;
90601c2c787SAndreas Jaekel 	mark->zev_payload_len = len;
90701c2c787SAndreas Jaekel 	strcpy(ZEV_PAYLOAD(mark), p);
90801c2c787SAndreas Jaekel 
90901c2c787SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_MARK, mark)) {
91001c2c787SAndreas Jaekel 		perror("queueing mark failed");
91101c2c787SAndreas Jaekel 		return (EXIT_FAILURE);
91201c2c787SAndreas Jaekel 	}
91301c2c787SAndreas Jaekel 
91401c2c787SAndreas Jaekel 	printf("mark id: %lu\n", mark->zev_mark_id);
91501c2c787SAndreas Jaekel 	return (0);
91601c2c787SAndreas Jaekel }
91701c2c787SAndreas Jaekel 
918e9a5e479SAndreas Jaekel static int
919e9a5e479SAndreas Jaekel zev_queue_blocking(int fd, char *arg, int block)
920e9a5e479SAndreas Jaekel {
921e9a5e479SAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
922e9a5e479SAndreas Jaekel 
9234ca7dd5eSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
9244ca7dd5eSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
925e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
926e9a5e479SAndreas Jaekel 		return EXIT_FAILURE;
927e9a5e479SAndreas Jaekel 	}
9284ca7dd5eSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
929e9a5e479SAndreas Jaekel 
930e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
931e9a5e479SAndreas Jaekel 		perror("getting queue properties failed");
932e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
933e9a5e479SAndreas Jaekel 	}
934e9a5e479SAndreas Jaekel 	if (block) {
935e9a5e479SAndreas Jaekel 		gqp.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
936e9a5e479SAndreas Jaekel 	} else {
937e9a5e479SAndreas Jaekel 		gqp.zev_flags &= ~ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
938e9a5e479SAndreas Jaekel 	}
939e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
940e9a5e479SAndreas Jaekel 		perror("setting queue properties failed");
941e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
942e9a5e479SAndreas Jaekel 	}
943e9a5e479SAndreas Jaekel 	return (0);
944e9a5e479SAndreas Jaekel }
945e9a5e479SAndreas Jaekel 
946e9a5e479SAndreas Jaekel static int
947e9a5e479SAndreas Jaekel zev_set_max_queue_len(int fd, char *arg, char *len)
948e9a5e479SAndreas Jaekel {
949e9a5e479SAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
950e9a5e479SAndreas Jaekel 
951e9a5e479SAndreas Jaekel 	if (!len) {
952e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue size parameter missing.\n");
953e9a5e479SAndreas Jaekel 		return EXIT_FAILURE;
954e9a5e479SAndreas Jaekel 	}
955e9a5e479SAndreas Jaekel 
9564ca7dd5eSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
9574ca7dd5eSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
958e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
959e9a5e479SAndreas Jaekel 		return EXIT_FAILURE;
960e9a5e479SAndreas Jaekel 	}
9614ca7dd5eSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
962e9a5e479SAndreas Jaekel 
963e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
964e9a5e479SAndreas Jaekel 		perror("getting queue properties failed");
965e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
966e9a5e479SAndreas Jaekel 	}
967e9a5e479SAndreas Jaekel 	gqp.zev_max_queue_len = atol(len);
968e9a5e479SAndreas Jaekel 	if (gqp.zev_max_queue_len == 0 && strcmp("0", len)) {
969e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue size parameter garbled.\n");
970e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
971e9a5e479SAndreas Jaekel 	}
972e9a5e479SAndreas Jaekel 	if (gqp.zev_max_queue_len > ZEV_MAX_QUEUE_LEN) {
973e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue size parameter out of bounds.\n");
974e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
975e9a5e479SAndreas Jaekel 	}
976e9a5e479SAndreas Jaekel 
977e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
978e9a5e479SAndreas Jaekel 		perror("setting queue properties failed");
979e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
980e9a5e479SAndreas Jaekel 	}
981e9a5e479SAndreas Jaekel 	return (0);
982e9a5e479SAndreas Jaekel }
983e9a5e479SAndreas Jaekel 
984e9a5e479SAndreas Jaekel static int
985e9a5e479SAndreas Jaekel zev_set_poll_wakeup_queue_len(int fd, char *arg, char *len)
986e9a5e479SAndreas Jaekel {
987e9a5e479SAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
988e9a5e479SAndreas Jaekel 
989e9a5e479SAndreas Jaekel 	if (!len) {
990e9a5e479SAndreas Jaekel 		fprintf(stderr, "poll throttle parameter missing.\n");
991e9a5e479SAndreas Jaekel 		return EXIT_FAILURE;
992e9a5e479SAndreas Jaekel 	}
993e9a5e479SAndreas Jaekel 
9944ca7dd5eSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
9954ca7dd5eSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
996e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
997e9a5e479SAndreas Jaekel 		return EXIT_FAILURE;
998e9a5e479SAndreas Jaekel 	}
9994ca7dd5eSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
1000e9a5e479SAndreas Jaekel 
1001e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1002e9a5e479SAndreas Jaekel 		perror("getting queue properties failed");
1003e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
1004e9a5e479SAndreas Jaekel 	}
1005e9a5e479SAndreas Jaekel 	gqp.zev_poll_wakeup_threshold = atol(len);
1006e9a5e479SAndreas Jaekel 	if (gqp.zev_poll_wakeup_threshold == 0 && strcmp("0", len)) {
1007e9a5e479SAndreas Jaekel 		fprintf(stderr, "poll throttle parameter garbled.\n");
1008e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
1009e9a5e479SAndreas Jaekel 	}
10104ca7dd5eSAndreas Jaekel 	if (gqp.zev_poll_wakeup_threshold > ZEV_MAX_POLL_WAKEUP_QUEUE_LEN) {
1011e9a5e479SAndreas Jaekel 		fprintf(stderr, "poll throttle parameter out of bounds.\n");
1012e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
1013e9a5e479SAndreas Jaekel 	}
1014e9a5e479SAndreas Jaekel 
1015e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1016e9a5e479SAndreas Jaekel 		perror("setting queue properties failed");
1017e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
1018e9a5e479SAndreas Jaekel 	}
1019e9a5e479SAndreas Jaekel 	return (0);
1020e9a5e479SAndreas Jaekel }
1021e9a5e479SAndreas Jaekel 
1022e9a5e479SAndreas Jaekel static int
1023e9a5e479SAndreas Jaekel zev_queue_properties(int fd, char *arg)
1024e9a5e479SAndreas Jaekel {
1025e9a5e479SAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
1026e9a5e479SAndreas Jaekel 
10274ca7dd5eSAndreas Jaekel 	gqp.zev_queue_name.zev_namelen = strlen(arg);
10284ca7dd5eSAndreas Jaekel 	if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1029e9a5e479SAndreas Jaekel 		fprintf(stderr, "queue name too long.\n");
1030e9a5e479SAndreas Jaekel 		return EXIT_FAILURE;
1031e9a5e479SAndreas Jaekel 	}
10324ca7dd5eSAndreas Jaekel 	strcpy(gqp.zev_queue_name.zev_name, arg);
1033e9a5e479SAndreas Jaekel 
1034e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1035e9a5e479SAndreas Jaekel 		perror("getting queue properties failed");
1036e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
1037e9a5e479SAndreas Jaekel 	}
1038e9a5e479SAndreas Jaekel 
1039e9a5e479SAndreas Jaekel 	printf("queue        : %s\n", arg);
1040e9a5e479SAndreas Jaekel 	printf("max size     : %" PRIu64 "\n", gqp.zev_max_queue_len);
1041e9a5e479SAndreas Jaekel 	printf("poll throttle: %" PRIu64 "\n", gqp.zev_poll_wakeup_threshold);
1042e9a5e479SAndreas Jaekel 	printf("persistent   : %s\n",
1043e9a5e479SAndreas Jaekel 		gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no");
1044e9a5e479SAndreas Jaekel 	printf("blocking     : %s\n",
1045e9a5e479SAndreas Jaekel 		gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? "yes" : "no");
1046e9a5e479SAndreas Jaekel 
1047e9a5e479SAndreas Jaekel 	return (0);
1048e9a5e479SAndreas Jaekel }
1049e9a5e479SAndreas Jaekel 
1050e9a5e479SAndreas Jaekel static int
1051e9a5e479SAndreas Jaekel zev_list_queues(int fd)
1052e9a5e479SAndreas Jaekel {
1053e9a5e479SAndreas Jaekel 	zev_ioctl_get_queue_properties_t gqp;
1054e9a5e479SAndreas Jaekel 	zev_ioctl_get_queue_list_t gql;
1055e9a5e479SAndreas Jaekel 	zev_ioctl_get_queue_statistics_t gs;
1056e9a5e479SAndreas Jaekel 	uint64_t	i;
1057e9a5e479SAndreas Jaekel 	char		name[ZEV_MAX_QUEUE_NAME_LEN+1];
1058e9a5e479SAndreas Jaekel 
1059e9a5e479SAndreas Jaekel 	if (ioctl(fd, ZEV_IOC_GET_QUEUE_LIST, &gql)) {
1060e9a5e479SAndreas Jaekel 		perror("getting queue list failed");
1061e9a5e479SAndreas Jaekel 		return (EXIT_FAILURE);
1062e9a5e479SAndreas Jaekel 	}
1063e9a5e479SAndreas Jaekel 
1064e9a5e479SAndreas Jaekel 	printf("Name                                     Size       "
1065e9a5e479SAndreas Jaekel 	       "Max Size   Wakeup Per Block\n");
1066e9a5e479SAndreas Jaekel 
1067e9a5e479SAndreas Jaekel 	for (i=0; i<gql.zev_n_queues; i++) {
1068e9a5e479SAndreas Jaekel 		strncpy(name, gql.zev_queue_name[i].zev_name,
1069e9a5e479SAndreas Jaekel 		        ZEV_MAX_QUEUE_NAME_LEN);
1070e9a5e479SAndreas Jaekel 		name[gql.zev_queue_name[i].zev_namelen] = '\0';
1071e9a5e479SAndreas Jaekel 
10724ca7dd5eSAndreas Jaekel 		memcpy(gqp.zev_queue_name.zev_name,
10734ca7dd5eSAndreas Jaekel 		    gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
10744ca7dd5eSAndreas Jaekel 		gqp.zev_queue_name.zev_namelen =
10754ca7dd5eSAndreas Jaekel 		    gql.zev_queue_name[i].zev_namelen;
1076e9a5e479SAndreas Jaekel 
1077e9a5e479SAndreas Jaekel 		if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1078e9a5e479SAndreas Jaekel 			if (errno == ENOENT)
1079e9a5e479SAndreas Jaekel 				continue;
1080e9a5e479SAndreas Jaekel 			perror("getting queue properties failed");
1081e9a5e479SAndreas Jaekel 			return (EXIT_FAILURE);
1082e9a5e479SAndreas Jaekel 		}
1083e9a5e479SAndreas Jaekel 
10844ca7dd5eSAndreas Jaekel 		memcpy(gs.zev_queue_name.zev_name,
10854ca7dd5eSAndreas Jaekel 		    gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
10864ca7dd5eSAndreas Jaekel 		gs.zev_queue_name.zev_namelen =
10874ca7dd5eSAndreas Jaekel 		    gql.zev_queue_name[i].zev_namelen;
1088e9a5e479SAndreas Jaekel 
1089e9a5e479SAndreas Jaekel 		if (ioctl(fd, ZEV_IOC_GET_QUEUE_STATISTICS, &gs)) {
1090e9a5e479SAndreas Jaekel 			if (errno == ENOENT)
1091e9a5e479SAndreas Jaekel 				continue;
1092e9a5e479SAndreas Jaekel 			perror("getting statistics data failed");
1093e9a5e479SAndreas Jaekel 			return (EXIT_FAILURE);
1094e9a5e479SAndreas Jaekel 		}
1095e9a5e479SAndreas Jaekel 
1096e9a5e479SAndreas Jaekel 		printf("%-40s %-10" PRIu64 " %-10" PRIu64 " %-6" PRIu64
1097e9a5e479SAndreas Jaekel 		       " %-3s %-3s\n",
1098e9a5e479SAndreas Jaekel 			name,
1099e9a5e479SAndreas Jaekel 			gs.zev_statistics.zev_queue_len,
1100e9a5e479SAndreas Jaekel 			gqp.zev_max_queue_len,
1101e9a5e479SAndreas Jaekel 			gqp.zev_poll_wakeup_threshold,
1102e9a5e479SAndreas Jaekel 			gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no",
1103e9a5e479SAndreas Jaekel 			gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ?
1104e9a5e479SAndreas Jaekel 				 "yes" : "no");
1105e9a5e479SAndreas Jaekel 	}
1106e9a5e479SAndreas Jaekel 
1107e9a5e479SAndreas Jaekel 	return (0);
1108e9a5e479SAndreas Jaekel }
1109e9a5e479SAndreas Jaekel 
1110b9710123SAndreas Jaekel static int
1111b9710123SAndreas Jaekel zev_checksum(int dev_fd, char *filename)
1112b9710123SAndreas Jaekel {
1113b9710123SAndreas Jaekel 	int fd;
1114b9710123SAndreas Jaekel 	offset_t off;
1115b9710123SAndreas Jaekel 	offset_t data;
1116b9710123SAndreas Jaekel 	zev_sig_t *sig;
1117b9710123SAndreas Jaekel 	char *buf;
1118b9710123SAndreas Jaekel 	zev_ioctl_get_signatures_t *gs;
1119b9710123SAndreas Jaekel 	int i;
1120b9710123SAndreas Jaekel 	char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
1121b9710123SAndreas Jaekel 	int buf_size;
1122b9710123SAndreas Jaekel 
1123b9710123SAndreas Jaekel 	/* control struct, one lv1 signature and up to 256 lv0 signatures */
1124b9710123SAndreas Jaekel 	buf_size = (1 + 256) * sizeof(zev_sig_t);
1125b9710123SAndreas Jaekel 	buf = malloc(sizeof(zev_ioctl_get_signatures_t) + buf_size);
1126b9710123SAndreas Jaekel 	if (!buf) {
1127b9710123SAndreas Jaekel 		perror("can't allocate checksum buffer");
1128b9710123SAndreas Jaekel 		return (EXIT_FAILURE);
1129b9710123SAndreas Jaekel 	}
1130b9710123SAndreas Jaekel 
1131b9710123SAndreas Jaekel 	fd = open(filename, O_RDONLY);
1132b9710123SAndreas Jaekel 	if (fd < 0) {
1133b9710123SAndreas Jaekel 		perror("can't open file");
1134b9710123SAndreas Jaekel 		return (EXIT_FAILURE);
1135b9710123SAndreas Jaekel 	}
1136b9710123SAndreas Jaekel 
1137b9710123SAndreas Jaekel 	gs = (zev_ioctl_get_signatures_t *)buf;
1138b9710123SAndreas Jaekel 	gs->zev_fd = fd;
1139b9710123SAndreas Jaekel 	gs->zev_bufsize = buf_size;
1140b9710123SAndreas Jaekel 
1141b9710123SAndreas Jaekel 	off = 0;
1142b9710123SAndreas Jaekel 	data = 0;
1143b9710123SAndreas Jaekel 	while (1) {
1144b9710123SAndreas Jaekel 		errno = 0;
1145b9710123SAndreas Jaekel 		data = llseek(fd, off, SEEK_DATA);
1146b9710123SAndreas Jaekel 		if (data < 0) {
1147b9710123SAndreas Jaekel 			if (errno == ENXIO)	/* no more data */
1148b9710123SAndreas Jaekel 				break;
1149b9710123SAndreas Jaekel 			perror("llseek failed");
1150b9710123SAndreas Jaekel 			goto err;
1151b9710123SAndreas Jaekel 		}
1152b9710123SAndreas Jaekel 		data = P2ALIGN(data, ZEV_L1_SIZE);
1153b9710123SAndreas Jaekel 		off = data + ZEV_L1_SIZE;
1154b9710123SAndreas Jaekel 
1155b9710123SAndreas Jaekel 		gs->zev_offset = data;
1156b9710123SAndreas Jaekel 		gs->zev_len = ZEV_L1_SIZE;
1157b9710123SAndreas Jaekel 
1158b9710123SAndreas Jaekel 		if (ioctl(dev_fd, ZEV_IOC_GET_FILE_SIGNATURES, gs)) {
1159b9710123SAndreas Jaekel 			perror("ioctl to get signatures failed");
1160b9710123SAndreas Jaekel 			goto err;
1161b9710123SAndreas Jaekel 		}
1162b9710123SAndreas Jaekel 
1163b9710123SAndreas Jaekel 		for (i=0; i<gs->zev_signature_cnt; i++) {
1164b9710123SAndreas Jaekel 			sig = (zev_sig_t *)ZEV_SIGNATURES(gs);
1165b9710123SAndreas Jaekel 			sig += i;
1166b9710123SAndreas Jaekel 			sig2hex_direct(sig->value, sigval);
1167b9710123SAndreas Jaekel 			printf("level %d, offset %llu, value %s\n",
1168b9710123SAndreas Jaekel 			       sig->level, sig->block_offset, sigval);
1169b9710123SAndreas Jaekel 		}
1170b9710123SAndreas Jaekel 	}
1171b9710123SAndreas Jaekel 
1172b9710123SAndreas Jaekel 	free(buf);
1173b9710123SAndreas Jaekel 	close(fd);
1174b9710123SAndreas Jaekel 	return 0;
1175b9710123SAndreas Jaekel err:
1176b9710123SAndreas Jaekel 	free(buf);
1177b9710123SAndreas Jaekel 	close(fd);
1178b9710123SAndreas Jaekel 	return (EXIT_FAILURE);
1179b9710123SAndreas Jaekel }
1180b9710123SAndreas Jaekel 
11812bb8e5e2SAndreas Jaekel int
11822bb8e5e2SAndreas Jaekel main(int argc, char **argv)
11832bb8e5e2SAndreas Jaekel {
11842bb8e5e2SAndreas Jaekel 	int fd;
11852bb8e5e2SAndreas Jaekel 	int c;
11862bb8e5e2SAndreas Jaekel 	extern char *optarg;
11874ca7dd5eSAndreas Jaekel 	int create_tmp_queue = 1;
11884ca7dd5eSAndreas Jaekel 	char buf[MAXPATHLEN];
1189*6a3d43bfSAndreas Jaekel 	int mode = 0;
1190*6a3d43bfSAndreas Jaekel 	char *arg = NULL;
1191*6a3d43bfSAndreas Jaekel 	char *arg2 = NULL;
11922bb8e5e2SAndreas Jaekel 
11932bb8e5e2SAndreas Jaekel 	/* open device */
11942bb8e5e2SAndreas Jaekel 	fd = open(zev_device, O_RDONLY);
11952bb8e5e2SAndreas Jaekel 	if (fd < 0) {
11962bb8e5e2SAndreas Jaekel 		perror("opening zev device failed");
11972bb8e5e2SAndreas Jaekel 		return EXIT_FAILURE;
11982bb8e5e2SAndreas Jaekel 	}
11994ca7dd5eSAndreas Jaekel 	while ((c = getopt(argc, argv,
1200d65b2fffSAndreas Jaekel 	                   "gvspc:d:Dlk:L:q:Qt:m:M:a:A:r:P:b:B:h?")) != -1){
12012bb8e5e2SAndreas Jaekel 		switch(c) {
1202d65b2fffSAndreas Jaekel 		case 'g':
1203d65b2fffSAndreas Jaekel 			grep_friendly++;
1204d65b2fffSAndreas Jaekel 			verbose++;
1205d65b2fffSAndreas Jaekel 			break;
12065e286361SAndreas Jaekel 		case 'v':
12075e286361SAndreas Jaekel 			verbose++;
12085e286361SAndreas Jaekel 			break;
12092bb8e5e2SAndreas Jaekel 		case 's':
1210*6a3d43bfSAndreas Jaekel 			mode = MD_STATISTICS;
1211*6a3d43bfSAndreas Jaekel 			break;
12122bb8e5e2SAndreas Jaekel 		case 'p':
1213*6a3d43bfSAndreas Jaekel 			mode = MD_POLL_EVENTS;
1214*6a3d43bfSAndreas Jaekel 			break;
1215b9710123SAndreas Jaekel 		case 'c':
1216*6a3d43bfSAndreas Jaekel 			mode = MD_CHECKSUMS;
1217*6a3d43bfSAndreas Jaekel 			arg = optarg;
1218*6a3d43bfSAndreas Jaekel 			break;
1219e9a5e479SAndreas Jaekel 		case 'D':
1220*6a3d43bfSAndreas Jaekel 			mode = MD_DEBUG_INFO;
1221*6a3d43bfSAndreas Jaekel 			break;
12222bb8e5e2SAndreas Jaekel 		case 'd':
1223e9a5e479SAndreas Jaekel 			close(fd);
12242bb8e5e2SAndreas Jaekel 			zev_device = optarg;
1225e9a5e479SAndreas Jaekel 			fd = open(zev_device, O_RDONLY);
1226e9a5e479SAndreas Jaekel 			if (fd < 0) {
1227e9a5e479SAndreas Jaekel 				perror("opening zev device failed");
1228e9a5e479SAndreas Jaekel 				return EXIT_FAILURE;
1229e9a5e479SAndreas Jaekel 			}
12304ca7dd5eSAndreas Jaekel 			create_tmp_queue = 0;
12314ca7dd5eSAndreas Jaekel 			break;
12324ca7dd5eSAndreas Jaekel 		case 'q':
12334ca7dd5eSAndreas Jaekel 			snprintf(buf, sizeof(buf),
12344ca7dd5eSAndreas Jaekel 				 "/devices/pseudo/zev@0:%s", optarg);
12354ca7dd5eSAndreas Jaekel 			close(fd);
12364ca7dd5eSAndreas Jaekel 			zev_device = buf;
12374ca7dd5eSAndreas Jaekel 			fd = open(zev_device, O_RDONLY);
12384ca7dd5eSAndreas Jaekel 			if (fd < 0) {
12394ca7dd5eSAndreas Jaekel 				perror("opening zev device failed");
12404ca7dd5eSAndreas Jaekel 				return EXIT_FAILURE;
12414ca7dd5eSAndreas Jaekel 			}
12424ca7dd5eSAndreas Jaekel 			create_tmp_queue = 0;
12432bb8e5e2SAndreas Jaekel 			break;
1244e9a5e479SAndreas Jaekel 		case 'l':
1245*6a3d43bfSAndreas Jaekel 			mode = MD_LIST_QUEUES;
1246*6a3d43bfSAndreas Jaekel 			break;
1247e9a5e479SAndreas Jaekel 		case 'Q':
1248*6a3d43bfSAndreas Jaekel 			mode = MD_SET_GLOBAL_MAX_QUEUE_LEN;
1249*6a3d43bfSAndreas Jaekel 			arg = optarg;
1250*6a3d43bfSAndreas Jaekel 			break;
12514ca7dd5eSAndreas Jaekel 		case 'L':
1252*6a3d43bfSAndreas Jaekel 			mode = MD_SET_MAX_QUEUE_LEN;
1253*6a3d43bfSAndreas Jaekel 			arg = optarg;
1254*6a3d43bfSAndreas Jaekel 			arg2 = argv[optind];
1255*6a3d43bfSAndreas Jaekel 			break;
1256205a9bc9SAndreas Jaekel 		case 't':
1257*6a3d43bfSAndreas Jaekel 			mode = MD_SET_POLL_WAKEUP_QUEUE_LEN;
1258*6a3d43bfSAndreas Jaekel 			arg = optarg;
1259*6a3d43bfSAndreas Jaekel 			arg2 = argv[optind];
1260*6a3d43bfSAndreas Jaekel 			break;
12612bb8e5e2SAndreas Jaekel 		case 'm':
1262*6a3d43bfSAndreas Jaekel 			mode = MD_MUTE_POOL;
1263*6a3d43bfSAndreas Jaekel 			arg = optarg;
1264*6a3d43bfSAndreas Jaekel 			break;
12652bb8e5e2SAndreas Jaekel 		case 'M':
1266*6a3d43bfSAndreas Jaekel 			mode = MD_UNMUTE_POOL;
1267*6a3d43bfSAndreas Jaekel 			arg = optarg;
1268*6a3d43bfSAndreas Jaekel 			break;
126901c2c787SAndreas Jaekel 		case 'k':
1270*6a3d43bfSAndreas Jaekel 			mode = MD_MARK;
1271*6a3d43bfSAndreas Jaekel 			arg = optarg;
1272*6a3d43bfSAndreas Jaekel 			break;
1273e9a5e479SAndreas Jaekel 		case 'a':
1274*6a3d43bfSAndreas Jaekel 			mode = MD_ADD_QUEUE;
1275*6a3d43bfSAndreas Jaekel 			arg = optarg;
1276*6a3d43bfSAndreas Jaekel 			break;
12774ca7dd5eSAndreas Jaekel 		case 'A':
1278*6a3d43bfSAndreas Jaekel 			mode = MD_ADD_BLOCKING_QUEUE;
1279*6a3d43bfSAndreas Jaekel 			arg = optarg;
1280*6a3d43bfSAndreas Jaekel 			break;
1281e9a5e479SAndreas Jaekel 		case 'r':
1282*6a3d43bfSAndreas Jaekel 			mode = MD_REMOVE_QUEUE;
1283*6a3d43bfSAndreas Jaekel 			arg = optarg;
1284*6a3d43bfSAndreas Jaekel 			break;
1285e9a5e479SAndreas Jaekel 		case 'b':
1286*6a3d43bfSAndreas Jaekel 			mode = MD_QUEUE_BLOCKING;
1287*6a3d43bfSAndreas Jaekel 			arg = optarg;
1288*6a3d43bfSAndreas Jaekel 			break;
1289e9a5e479SAndreas Jaekel 		case 'B':
1290*6a3d43bfSAndreas Jaekel 			mode = MD_QUEUE_NONBLOCKING;
1291*6a3d43bfSAndreas Jaekel 			arg = optarg;
1292*6a3d43bfSAndreas Jaekel 			break;
1293e9a5e479SAndreas Jaekel 		case 'P':
1294*6a3d43bfSAndreas Jaekel 			mode = MD_QUEUE_PROPERTIES;
1295*6a3d43bfSAndreas Jaekel 			arg = optarg;
1296*6a3d43bfSAndreas Jaekel 			break;
12972bb8e5e2SAndreas Jaekel 		case 'h':
12982bb8e5e2SAndreas Jaekel 		case '?':
12992bb8e5e2SAndreas Jaekel 		default:
13002bb8e5e2SAndreas Jaekel 			usage(argv[0]);
13012bb8e5e2SAndreas Jaekel 		}
13022bb8e5e2SAndreas Jaekel 	}
1303*6a3d43bfSAndreas Jaekel 
1304*6a3d43bfSAndreas Jaekel 	switch (mode) {
1305*6a3d43bfSAndreas Jaekel 	case MD_STATISTICS:
1306*6a3d43bfSAndreas Jaekel 		return zev_statistics(fd);
1307*6a3d43bfSAndreas Jaekel 	case MD_POLL_EVENTS:
1308*6a3d43bfSAndreas Jaekel 		return zev_poll_events(fd, create_tmp_queue);
1309*6a3d43bfSAndreas Jaekel 	case MD_CHECKSUMS:
1310*6a3d43bfSAndreas Jaekel 		return zev_checksum(fd, arg);
1311*6a3d43bfSAndreas Jaekel 	case MD_DEBUG_INFO:
1312*6a3d43bfSAndreas Jaekel 		return zev_debug_info(fd);
1313*6a3d43bfSAndreas Jaekel 	case MD_LIST_QUEUES:
1314*6a3d43bfSAndreas Jaekel 		return zev_list_queues(fd);
1315*6a3d43bfSAndreas Jaekel 	case MD_SET_GLOBAL_MAX_QUEUE_LEN:
1316*6a3d43bfSAndreas Jaekel 		return zev_set_global_max_queue_len(fd, arg);
1317*6a3d43bfSAndreas Jaekel 	case MD_SET_MAX_QUEUE_LEN:
1318*6a3d43bfSAndreas Jaekel 		return zev_set_max_queue_len(fd, arg, arg2);
1319*6a3d43bfSAndreas Jaekel 	case MD_SET_POLL_WAKEUP_QUEUE_LEN:
1320*6a3d43bfSAndreas Jaekel 		return zev_set_poll_wakeup_queue_len(fd, arg, arg2);
1321*6a3d43bfSAndreas Jaekel 	case MD_MUTE_POOL:
1322*6a3d43bfSAndreas Jaekel 		return zev_mute_pool(fd, arg);
1323*6a3d43bfSAndreas Jaekel 	case MD_UNMUTE_POOL:
1324*6a3d43bfSAndreas Jaekel 		return zev_unmute_pool(fd, arg);
1325*6a3d43bfSAndreas Jaekel 	case MD_MARK:
1326*6a3d43bfSAndreas Jaekel 		return zev_mark(fd, arg);
1327*6a3d43bfSAndreas Jaekel 	case MD_ADD_QUEUE:
1328*6a3d43bfSAndreas Jaekel 		return zev_add_queue(fd, arg, 0);
1329*6a3d43bfSAndreas Jaekel 	case MD_ADD_BLOCKING_QUEUE:
1330*6a3d43bfSAndreas Jaekel 		return zev_add_queue(fd, arg, 1);
1331*6a3d43bfSAndreas Jaekel 	case MD_REMOVE_QUEUE:
1332*6a3d43bfSAndreas Jaekel 		return zev_remove_queue(fd, arg);
1333*6a3d43bfSAndreas Jaekel 	case MD_QUEUE_BLOCKING:
1334*6a3d43bfSAndreas Jaekel 		return zev_queue_blocking(fd, arg, 0);
1335*6a3d43bfSAndreas Jaekel 	case MD_QUEUE_NONBLOCKING:
1336*6a3d43bfSAndreas Jaekel 		return zev_queue_blocking(fd, arg, 1);
1337*6a3d43bfSAndreas Jaekel 	case MD_QUEUE_PROPERTIES:
1338*6a3d43bfSAndreas Jaekel 		return zev_queue_properties(fd, arg);
1339*6a3d43bfSAndreas Jaekel 	default:
13402bb8e5e2SAndreas Jaekel 		close(fd);
1341*6a3d43bfSAndreas Jaekel 		usage(argv[0]);
1342e9a5e479SAndreas Jaekel 		return EXIT_FAILURE;
1343*6a3d43bfSAndreas Jaekel 	};
13442bb8e5e2SAndreas Jaekel }
13452bb8e5e2SAndreas Jaekel 
1346