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>
120abdde4aSAndreas Jaekel #include <sys/avl.h>
139fd83c76SAndreas Jaekel #include <sys/stat.h>
142bb8e5e2SAndreas Jaekel
15e9a5e479SAndreas Jaekel #define ZEV_DEVICE "/devices/pseudo/zev@0:ctrl"
162bb8e5e2SAndreas Jaekel
170abdde4aSAndreas Jaekel #if !defined(offsetof)
180abdde4aSAndreas Jaekel #define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
190abdde4aSAndreas Jaekel #endif
200abdde4aSAndreas Jaekel
212bb8e5e2SAndreas Jaekel static char *zev_device = ZEV_DEVICE;
22c07f6d81SArne Jansen static int do_flush = 0;
232bb8e5e2SAndreas Jaekel
249193e9c2SAndreas Jaekel static char *zev_op_name[] = {
25d65b2fffSAndreas Jaekel "ERROR",
26d65b2fffSAndreas Jaekel "MARK",
27d65b2fffSAndreas Jaekel "ZFS_MOUNT",
28d65b2fffSAndreas Jaekel "ZFS_UMOUNT",
29d65b2fffSAndreas Jaekel "ZVOL_WRITE",
30d65b2fffSAndreas Jaekel "ZVOL_TRUNCATE",
31d65b2fffSAndreas Jaekel "ZNODE_CLOSE_AFTER_UPDATE",
32d65b2fffSAndreas Jaekel "ZNODE_CREATE",
33d65b2fffSAndreas Jaekel "ZNODE_MKDIR",
34d65b2fffSAndreas Jaekel "ZNODE_MAKE_XATTR_DIR",
35d65b2fffSAndreas Jaekel "ZNODE_REMOVE",
36d65b2fffSAndreas Jaekel "ZNODE_RMDIR",
37d65b2fffSAndreas Jaekel "ZNODE_LINK",
38d65b2fffSAndreas Jaekel "ZNODE_SYMLINK",
39d65b2fffSAndreas Jaekel "ZNODE_RENAME",
40d65b2fffSAndreas Jaekel "ZNODE_WRITE",
41d65b2fffSAndreas Jaekel "ZNODE_TRUNCATE",
42d65b2fffSAndreas Jaekel "ZNODE_SETATTR",
43d65b2fffSAndreas Jaekel "ZNODE_ACL",
449193e9c2SAndreas Jaekel NULL
459193e9c2SAndreas Jaekel };
469193e9c2SAndreas Jaekel
476a3d43bfSAndreas Jaekel #define MD_STATISTICS 1
486a3d43bfSAndreas Jaekel #define MD_POLL_EVENTS 2
496a3d43bfSAndreas Jaekel #define MD_CHECKSUMS 3
506a3d43bfSAndreas Jaekel #define MD_DEBUG_INFO 4
516a3d43bfSAndreas Jaekel #define MD_LIST_QUEUES 5
526a3d43bfSAndreas Jaekel #define MD_SET_GLOBAL_MAX_QUEUE_LEN 6
536a3d43bfSAndreas Jaekel #define MD_SET_MAX_QUEUE_LEN 7
546a3d43bfSAndreas Jaekel #define MD_SET_POLL_WAKEUP_QUEUE_LEN 8
556a3d43bfSAndreas Jaekel #define MD_MUTE_POOL 9
566a3d43bfSAndreas Jaekel #define MD_UNMUTE_POOL 10
576a3d43bfSAndreas Jaekel #define MD_MARK 11
586a3d43bfSAndreas Jaekel #define MD_ADD_QUEUE 12
596a3d43bfSAndreas Jaekel #define MD_ADD_BLOCKING_QUEUE 13
606a3d43bfSAndreas Jaekel #define MD_REMOVE_QUEUE 14
616a3d43bfSAndreas Jaekel #define MD_QUEUE_BLOCKING 15
626a3d43bfSAndreas Jaekel #define MD_QUEUE_NONBLOCKING 16
636a3d43bfSAndreas Jaekel #define MD_QUEUE_PROPERTIES 17
640abdde4aSAndreas Jaekel #define MD_ZEVSTAT 18
659fd83c76SAndreas Jaekel #define MD_ZEV_REPORT 19
66797b8adfSArne Jansen #define MD_DUMP_SPOOL 20
67c62d8367SAndreas Jaekel #define MD_GET_ZEV_VERSION 21
686a3d43bfSAndreas Jaekel
695e286361SAndreas Jaekel static int verbose = 0;
70d65b2fffSAndreas Jaekel static int grep_friendly = 0;
71d65b2fffSAndreas Jaekel
72*0f07b41bSArne Jansen #define MAX_GUID 10000
73*0f07b41bSArne Jansen static int num_guid_filter = 0;
74*0f07b41bSArne Jansen static uint64_t guid_filter[MAX_GUID];
75*0f07b41bSArne Jansen
76d65b2fffSAndreas Jaekel static void
zpf(char * fmt,...)77d65b2fffSAndreas Jaekel zpf(char *fmt, ...)
78d65b2fffSAndreas Jaekel {
79d65b2fffSAndreas Jaekel va_list ap;
80d65b2fffSAndreas Jaekel
81d65b2fffSAndreas Jaekel va_start(ap, fmt);
82d65b2fffSAndreas Jaekel vprintf(fmt, ap);
83d65b2fffSAndreas Jaekel va_end(ap);
84d65b2fffSAndreas Jaekel if (grep_friendly) {
85d65b2fffSAndreas Jaekel printf(" ");
86d65b2fffSAndreas Jaekel } else {
87d65b2fffSAndreas Jaekel printf("\n");
88d65b2fffSAndreas Jaekel }
89d65b2fffSAndreas Jaekel }
90d65b2fffSAndreas Jaekel
91d65b2fffSAndreas Jaekel static void
znl(void)92d65b2fffSAndreas Jaekel znl(void)
93d65b2fffSAndreas Jaekel {
94d65b2fffSAndreas Jaekel if (grep_friendly)
95d65b2fffSAndreas Jaekel printf("\n");
96d65b2fffSAndreas Jaekel }
975e286361SAndreas Jaekel
981ca5a13bSAndreas Jaekel static void
sig2hex_direct(const uint8_t * sig,char * hex)991ca5a13bSAndreas Jaekel sig2hex_direct(const uint8_t *sig, char *hex)
1001ca5a13bSAndreas Jaekel {
1011ca5a13bSAndreas Jaekel int i;
1021ca5a13bSAndreas Jaekel
1031ca5a13bSAndreas Jaekel for (i = 0; i < SHA1_DIGEST_LENGTH; ++i) {
1041ca5a13bSAndreas Jaekel sprintf(hex + 2 * i, "%02x", sig[i]);
1051ca5a13bSAndreas Jaekel }
1061ca5a13bSAndreas Jaekel hex[SHA1_DIGEST_LENGTH * 2] = '\0';
1071ca5a13bSAndreas Jaekel }
1081ca5a13bSAndreas Jaekel
109e9a5e479SAndreas Jaekel static int
zev_statistics(int fd)1102bb8e5e2SAndreas Jaekel zev_statistics(int fd)
1112bb8e5e2SAndreas Jaekel {
1122bb8e5e2SAndreas Jaekel zev_statistics_t zs;
113e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) {
1142bb8e5e2SAndreas Jaekel perror("getting statistics data failed");
115e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1162bb8e5e2SAndreas Jaekel }
1172bb8e5e2SAndreas Jaekel printf("ZEV module state:\n");
1182bb8e5e2SAndreas Jaekel
1192bb8e5e2SAndreas Jaekel printf(" queue length in bytes : %lu\n", zs.zev_queue_len);
1202bb8e5e2SAndreas Jaekel printf(" queue length limit : %lu\n", zs.zev_max_queue_len);
1212bb8e5e2SAndreas Jaekel printf(" bytes read from device : %lu\n", zs.zev_bytes_read);
1222bb8e5e2SAndreas Jaekel printf(" module internal errors : %lu\n\n", zs.zev_cnt_errors);
1232bb8e5e2SAndreas Jaekel
124e9a5e479SAndreas Jaekel printf(" discarded events : %lu\n",
125e9a5e479SAndreas Jaekel zs.zev_cnt_discarded_events);
126e9a5e479SAndreas Jaekel printf(" discarded bytes : %lu\n\n", zs.zev_bytes_discarded);
127e9a5e479SAndreas Jaekel
1282bb8e5e2SAndreas Jaekel printf("ZFS event statistics:\n");
1292bb8e5e2SAndreas Jaekel
1302bb8e5e2SAndreas Jaekel printf(" total ZFS events : %lu\n", zs.zev_cnt_total_events);
1312bb8e5e2SAndreas Jaekel printf(" ZFS mount : %lu\n", zs.zev_cnt_zfs_mount);
1322bb8e5e2SAndreas Jaekel printf(" ZFS umount : %lu\n", zs.zev_cnt_zfs_umount);
1332bb8e5e2SAndreas Jaekel printf(" ZVOL write : %lu\n", zs.zev_cnt_zvol_write);
1342bb8e5e2SAndreas Jaekel printf(" ZVOL truncate : %lu\n", zs.zev_cnt_zvol_truncate);
1352bb8e5e2SAndreas Jaekel printf(" ZNODE close after update: %lu\n",
1362bb8e5e2SAndreas Jaekel zs.zev_cnt_znode_close_after_update);
1372bb8e5e2SAndreas Jaekel printf(" ZNODE create : %lu\n", zs.zev_cnt_znode_create);
1382bb8e5e2SAndreas Jaekel printf(" ZNODE remove : %lu\n", zs.zev_cnt_znode_remove);
1392bb8e5e2SAndreas Jaekel printf(" ZNODE link : %lu\n", zs.zev_cnt_znode_link);
1402bb8e5e2SAndreas Jaekel printf(" ZNODE symlink : %lu\n", zs.zev_cnt_znode_symlink);
1412bb8e5e2SAndreas Jaekel printf(" ZNODE rename : %lu\n", zs.zev_cnt_znode_rename);
1422bb8e5e2SAndreas Jaekel printf(" ZNODE write : %lu\n", zs.zev_cnt_znode_write);
1432bb8e5e2SAndreas Jaekel printf(" ZNODE truncate : %lu\n",
1442bb8e5e2SAndreas Jaekel zs.zev_cnt_znode_truncate);
1452bb8e5e2SAndreas Jaekel printf(" ZNODE setattr : %lu\n", zs.zev_cnt_znode_setattr);
1462bb8e5e2SAndreas Jaekel printf(" ZNODE acl : %lu\n", zs.zev_cnt_znode_acl);
147e9a5e479SAndreas Jaekel return EXIT_SUCCESS;
1482bb8e5e2SAndreas Jaekel }
1492bb8e5e2SAndreas Jaekel
1502bb8e5e2SAndreas Jaekel static void
zev_print_inode_info(char * name,zev_inode_info_t * info)151d65b2fffSAndreas Jaekel zev_print_inode_info(char *name, zev_inode_info_t *info)
152d65b2fffSAndreas Jaekel {
153d65b2fffSAndreas Jaekel zpf(" %s.inode: %llu", name, info->ino);
154d65b2fffSAndreas Jaekel zpf(" %s.gen: %llu", name, info->gen);
155d65b2fffSAndreas Jaekel zpf(" %s.mtime: %llu", name, info->mtime);
156d65b2fffSAndreas Jaekel zpf(" %s.ctime: %llu", name, info->ctime);
157d65b2fffSAndreas Jaekel zpf(" %s.size: %llu", name, info->size);
158d65b2fffSAndreas Jaekel zpf(" %s.mode: %llo", name, info->mode);
159d65b2fffSAndreas Jaekel zpf(" %s.links: %llu", name, info->links);
160d65b2fffSAndreas Jaekel zpf(" %s.type: %lu", name, info->type);
161d65b2fffSAndreas Jaekel zpf(" %s.flags: %lu", name, info->flags);
162d65b2fffSAndreas Jaekel }
163d65b2fffSAndreas Jaekel
164d65b2fffSAndreas Jaekel static void
zev_print_mark_payload(zev_mark_t * rec)165d65b2fffSAndreas Jaekel zev_print_mark_payload(zev_mark_t *rec)
166d65b2fffSAndreas Jaekel {
167d65b2fffSAndreas Jaekel int i;
168d65b2fffSAndreas Jaekel int j;
169d65b2fffSAndreas Jaekel uint8_t *p;
170d65b2fffSAndreas Jaekel char c;
171d65b2fffSAndreas Jaekel
172d65b2fffSAndreas Jaekel zpf(" payload:");
173d65b2fffSAndreas Jaekel p = (uint8_t *)ZEV_PAYLOAD(rec);
174d65b2fffSAndreas Jaekel for (i=0; i<rec->payload_len; i+=16) {
175d65b2fffSAndreas Jaekel printf(" ");
176d65b2fffSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) {
177d65b2fffSAndreas Jaekel printf("%02x ", p[j]);
178d65b2fffSAndreas Jaekel if (j == i + 7)
179d65b2fffSAndreas Jaekel printf(" ");
180d65b2fffSAndreas Jaekel }
181d65b2fffSAndreas Jaekel if (grep_friendly)
182d65b2fffSAndreas Jaekel continue;
183d65b2fffSAndreas Jaekel for (; j<i+16; j++) {
184d65b2fffSAndreas Jaekel printf(" ");
185d65b2fffSAndreas Jaekel if (j == i + 7)
186d65b2fffSAndreas Jaekel printf(" ");
187d65b2fffSAndreas Jaekel }
188d65b2fffSAndreas Jaekel printf(" ");
189d65b2fffSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) {
190d65b2fffSAndreas Jaekel c = '.';
191d65b2fffSAndreas Jaekel if (p[j] >= ' ' && p[j] <= '~')
192d65b2fffSAndreas Jaekel c = p[j];
193d65b2fffSAndreas Jaekel printf("%c", c);
194d65b2fffSAndreas Jaekel if (j == i + 7)
195d65b2fffSAndreas Jaekel printf(" ");
196d65b2fffSAndreas Jaekel }
197d65b2fffSAndreas Jaekel printf("\n");
198d65b2fffSAndreas Jaekel }
199d65b2fffSAndreas Jaekel }
200d65b2fffSAndreas Jaekel
201d65b2fffSAndreas Jaekel static void
zev_print_error(char * buf)20263aba447SAndreas Jaekel zev_print_error(char *buf)
20363aba447SAndreas Jaekel {
20463aba447SAndreas Jaekel zev_error_t *rec = (zev_error_t *)buf;
20563aba447SAndreas Jaekel time_t op_time = rec->op_time;
20663aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
20763aba447SAndreas Jaekel
208d65b2fffSAndreas Jaekel if (verbose) {
209d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
210d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
211d65b2fffSAndreas Jaekel zpf(" failed.op: %s",
212d65b2fffSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN]);
213d65b2fffSAndreas Jaekel zpf(" message: %s", ZEV_ERRSTR(rec));
214d65b2fffSAndreas Jaekel znl();
215d65b2fffSAndreas Jaekel } else {
21663aba447SAndreas Jaekel printf("%s %s: failed_op=%s msg=%s\n",
21763aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
218d65b2fffSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN],
219d65b2fffSAndreas Jaekel ZEV_ERRSTR(rec));
220d65b2fffSAndreas Jaekel }
22163aba447SAndreas Jaekel }
22263aba447SAndreas Jaekel
22363aba447SAndreas Jaekel static void
zev_print_mark(char * buf)22401c2c787SAndreas Jaekel zev_print_mark(char *buf)
22501c2c787SAndreas Jaekel {
22601c2c787SAndreas Jaekel zev_mark_t *rec = (zev_mark_t *)buf;
22701c2c787SAndreas Jaekel time_t op_time = rec->op_time;
22801c2c787SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
22901c2c787SAndreas Jaekel
230d65b2fffSAndreas Jaekel if (verbose) {
231d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
232d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
233d65b2fffSAndreas Jaekel zpf(" mark.id: %llu", rec->mark_id);
234d65b2fffSAndreas Jaekel zpf(" payload.len: %llu", rec->payload_len);
235d65b2fffSAndreas Jaekel if (rec->payload_len)
236d65b2fffSAndreas Jaekel zev_print_mark_payload(rec);
237d65b2fffSAndreas Jaekel znl();
238d65b2fffSAndreas Jaekel } else {
23957340784SJan Schlien printf("%s %s: guid=%llu mark_id=%lld payload_len=%ld "
24057340784SJan Schlien "payload=\"%.*s\"\n",
241d65b2fffSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], rec->guid,
24257340784SJan Schlien rec->mark_id, rec->payload_len,
24357340784SJan Schlien rec->payload_len, (char *)(rec + 1));
244d65b2fffSAndreas Jaekel }
24501c2c787SAndreas Jaekel }
24601c2c787SAndreas Jaekel
24701c2c787SAndreas Jaekel static void
zev_print_zfs_mount(char * buf)24863aba447SAndreas Jaekel zev_print_zfs_mount(char *buf)
24963aba447SAndreas Jaekel {
25063aba447SAndreas Jaekel zev_zfs_mount_t *rec = (zev_zfs_mount_t *)buf;
25163aba447SAndreas Jaekel time_t op_time = rec->op_time;
25263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
25363aba447SAndreas Jaekel
254d65b2fffSAndreas Jaekel if (verbose) {
255d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
256d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
257d3b66d30SSimon Klinkert zpf(" txg: %llu", rec->txg);
258d65b2fffSAndreas Jaekel zpf(" dataset: %s", ZEV_DATASET(rec));
259d65b2fffSAndreas Jaekel zpf(" mountpoint: %s", ZEV_MOUNTPOINT(rec));
260d65b2fffSAndreas Jaekel zpf(" remount: %s", rec->remount ? "true" : "false");
261d65b2fffSAndreas Jaekel zev_print_inode_info("root", &rec->root);
262d65b2fffSAndreas Jaekel znl();
263d65b2fffSAndreas Jaekel } else {
264d65b2fffSAndreas Jaekel printf("%s %s: guid=%llu remount=%s dataset='%s' "
265d65b2fffSAndreas Jaekel "mountpoint='%s'\n",
26663aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
26763aba447SAndreas Jaekel rec->guid,
26863aba447SAndreas Jaekel rec->remount ? "true" : "false",
26963aba447SAndreas Jaekel ZEV_DATASET(rec),
27063aba447SAndreas Jaekel ZEV_MOUNTPOINT(rec));
27163aba447SAndreas Jaekel }
272d65b2fffSAndreas Jaekel }
27363aba447SAndreas Jaekel
27463aba447SAndreas Jaekel static void
zev_print_zfs_umount(char * buf)27563aba447SAndreas Jaekel zev_print_zfs_umount(char *buf)
27663aba447SAndreas Jaekel {
27763aba447SAndreas Jaekel zev_zfs_umount_t *rec = (zev_zfs_umount_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);
284d3b66d30SSimon Klinkert zpf(" txg: %llu", rec->txg);
285443f0cd2SAndreas Jaekel zev_print_inode_info("covered", &rec->covered);
286d65b2fffSAndreas Jaekel znl();
287d65b2fffSAndreas Jaekel } else {
28863aba447SAndreas Jaekel printf("%s %s: guid=%llu\n",
28963aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
29063aba447SAndreas Jaekel rec->guid);
29163aba447SAndreas Jaekel }
292d65b2fffSAndreas Jaekel }
29363aba447SAndreas Jaekel
29463aba447SAndreas Jaekel static void
zev_print_zvol_truncate(char * buf)29563aba447SAndreas Jaekel zev_print_zvol_truncate(char *buf)
29663aba447SAndreas Jaekel {
29763aba447SAndreas Jaekel zev_zvol_truncate_t *rec = (zev_zvol_truncate_t *)buf;
29863aba447SAndreas Jaekel time_t op_time = rec->op_time;
29963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
30063aba447SAndreas Jaekel
301d65b2fffSAndreas Jaekel if (verbose) {
302d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
303d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
304e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
305d65b2fffSAndreas Jaekel zpf(" offset: %llu", rec->offset);
306d65b2fffSAndreas Jaekel zpf(" length: %llu", rec->length);
307d65b2fffSAndreas Jaekel znl();
308d65b2fffSAndreas Jaekel } else {
30963aba447SAndreas Jaekel printf("%s %s: guid=%llu offset=%llu length=%llu\n",
31063aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
31163aba447SAndreas Jaekel rec->guid,
31263aba447SAndreas Jaekel rec->offset,
31363aba447SAndreas Jaekel rec->length);
31463aba447SAndreas Jaekel }
315d65b2fffSAndreas Jaekel }
31663aba447SAndreas Jaekel
31763aba447SAndreas Jaekel static void
zev_print_zvol_write(char * buf)31863aba447SAndreas Jaekel zev_print_zvol_write(char *buf)
31963aba447SAndreas Jaekel {
32063aba447SAndreas Jaekel zev_print_zvol_truncate(buf);
32163aba447SAndreas Jaekel }
32263aba447SAndreas Jaekel
32363aba447SAndreas Jaekel static void
zev_print_znode_close_after_update(char * buf)32463aba447SAndreas Jaekel zev_print_znode_close_after_update(char *buf)
32563aba447SAndreas Jaekel {
32663aba447SAndreas Jaekel zev_znode_close_after_update_t *rec =
32763aba447SAndreas Jaekel (zev_znode_close_after_update_t *)buf;
32863aba447SAndreas Jaekel time_t op_time = rec->op_time;
32963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
33063aba447SAndreas Jaekel
331d65b2fffSAndreas Jaekel if (verbose) {
332d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
333d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
334d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
335d65b2fffSAndreas Jaekel znl();
336d65b2fffSAndreas Jaekel } else {
33763aba447SAndreas Jaekel printf("%s %s: guid=%llu file=%llu.%llu\n",
33863aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
33963aba447SAndreas Jaekel rec->guid,
34063aba447SAndreas Jaekel rec->file.ino, rec->file.gen);
34163aba447SAndreas Jaekel }
342d65b2fffSAndreas Jaekel }
34363aba447SAndreas Jaekel
34463aba447SAndreas Jaekel static void
zev_print_znode_create(char * buf)34563aba447SAndreas Jaekel zev_print_znode_create(char *buf)
34663aba447SAndreas Jaekel {
34763aba447SAndreas Jaekel zev_znode_create_t *rec = (zev_znode_create_t *)buf;
34863aba447SAndreas Jaekel time_t op_time = rec->op_time;
34963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
3501ca5a13bSAndreas Jaekel zev_sig_t *sig;
3511ca5a13bSAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
35263aba447SAndreas Jaekel
353d65b2fffSAndreas Jaekel if (verbose) {
354d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
355d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
356e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
357d65b2fffSAndreas Jaekel zpf(" name: '%s'", ZEV_NAME(rec));
3581ca5a13bSAndreas Jaekel sig = &rec->signature;
3591ca5a13bSAndreas Jaekel sig2hex_direct(sig->value, sigval);
3601ca5a13bSAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s",
3611ca5a13bSAndreas Jaekel sig->level, sig->block_offset, sigval);
362d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
363e206ace3SAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
364d65b2fffSAndreas Jaekel znl();
365d65b2fffSAndreas Jaekel } else {
366c035b1e8SAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu file=%llu.%llu "
367c035b1e8SAndreas Jaekel "file.mtime=%llu, parent.mtime=%llu, name='%s'\n",
36863aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
36963aba447SAndreas Jaekel rec->guid,
37063aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen,
37163aba447SAndreas Jaekel rec->file.ino, rec->file.gen,
372c035b1e8SAndreas Jaekel rec->file.mtime, rec->parent.mtime,
37363aba447SAndreas Jaekel ZEV_NAME(rec));
37463aba447SAndreas Jaekel }
375d65b2fffSAndreas Jaekel }
37663aba447SAndreas Jaekel
37763aba447SAndreas Jaekel static void
zev_print_znode_mkdir(char * buf)37863aba447SAndreas Jaekel zev_print_znode_mkdir(char *buf)
37963aba447SAndreas Jaekel {
38063aba447SAndreas Jaekel zev_print_znode_create(buf);
38163aba447SAndreas Jaekel }
38263aba447SAndreas Jaekel
38363aba447SAndreas Jaekel static void
zev_print_znode_make_xattr_dir(char * buf)38463aba447SAndreas Jaekel zev_print_znode_make_xattr_dir(char *buf)
38563aba447SAndreas Jaekel {
38663aba447SAndreas Jaekel zev_print_znode_create(buf);
38763aba447SAndreas Jaekel }
38863aba447SAndreas Jaekel
38963aba447SAndreas Jaekel static void
zev_print_znode_remove(char * buf)39063aba447SAndreas Jaekel zev_print_znode_remove(char *buf)
39163aba447SAndreas Jaekel {
39263aba447SAndreas Jaekel zev_znode_remove_t *rec = (zev_znode_remove_t *)buf;
39363aba447SAndreas Jaekel time_t op_time = rec->op_time;
39463aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
39563aba447SAndreas Jaekel
396d65b2fffSAndreas Jaekel if (verbose) {
397d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
398d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
399e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
400d65b2fffSAndreas Jaekel zpf(" file.name: '%s'", ZEV_NAME(rec));
401d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
402e206ace3SAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
403d65b2fffSAndreas Jaekel znl();
404d65b2fffSAndreas Jaekel } else {
405d65b2fffSAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu "
406d65b2fffSAndreas Jaekel "file.mtime=%llu name='%s'\n",
40763aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
40863aba447SAndreas Jaekel rec->guid,
40963aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen,
4106db5d4ecSAndreas Jaekel rec->file.mtime,
41163aba447SAndreas Jaekel ZEV_NAME(rec));
41263aba447SAndreas Jaekel }
413d65b2fffSAndreas Jaekel }
41463aba447SAndreas Jaekel
41563aba447SAndreas Jaekel static void
zev_print_znode_rmdir(char * buf)41663aba447SAndreas Jaekel zev_print_znode_rmdir(char *buf)
41763aba447SAndreas Jaekel {
41863aba447SAndreas Jaekel zev_print_znode_remove(buf);
41963aba447SAndreas Jaekel }
42063aba447SAndreas Jaekel
42163aba447SAndreas Jaekel static void
zev_print_znode_link(char * buf)42263aba447SAndreas Jaekel zev_print_znode_link(char *buf)
42363aba447SAndreas Jaekel {
42463aba447SAndreas Jaekel zev_znode_link_t *rec = (zev_znode_link_t *)buf;
42563aba447SAndreas Jaekel time_t op_time = rec->op_time;
42663aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
42763aba447SAndreas Jaekel
428d65b2fffSAndreas Jaekel if (verbose) {
429d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
430d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
431e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
432d65b2fffSAndreas Jaekel zpf(" link.name: '%s'", ZEV_NAME(rec));
433d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
434e206ace3SAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
435d65b2fffSAndreas Jaekel znl();
436d65b2fffSAndreas Jaekel } else {
43703101f54SAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu "
43803101f54SAndreas Jaekel "file.ctime=%llu parent.ctime=%llu name='%s'\n",
43963aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
44063aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen,
44163aba447SAndreas Jaekel rec->file.ino, rec->file.gen,
44203101f54SAndreas Jaekel rec->file.ctime, rec->parent.ctime,
44363aba447SAndreas Jaekel ZEV_NAME(rec));
444d65b2fffSAndreas Jaekel }
44563aba447SAndreas Jaekel }
44663aba447SAndreas Jaekel
44763aba447SAndreas Jaekel static void
zev_print_znode_symlink(char * buf)44863aba447SAndreas Jaekel zev_print_znode_symlink(char *buf)
44963aba447SAndreas Jaekel {
45063aba447SAndreas Jaekel zev_znode_symlink_t *rec = (zev_znode_symlink_t *)buf;
45163aba447SAndreas Jaekel time_t op_time = rec->op_time;
45263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
4531ca5a13bSAndreas Jaekel zev_sig_t *sig;
4541ca5a13bSAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
45563aba447SAndreas Jaekel
456d65b2fffSAndreas Jaekel if (verbose) {
457d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
458d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
459e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
460d65b2fffSAndreas Jaekel zpf(" symlink.name: '%s'", ZEV_NAME(rec));
461d65b2fffSAndreas Jaekel zpf(" symlink.link: '%s'", ZEV_LINK(rec));
4621ca5a13bSAndreas Jaekel sig = &rec->signature;
4631ca5a13bSAndreas Jaekel sig2hex_direct(sig->value, sigval);
4641ca5a13bSAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s",
4651ca5a13bSAndreas Jaekel sig->level, sig->block_offset, sigval);
466d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
467e206ace3SAndreas Jaekel zev_print_inode_info("parent", &rec->parent);
468d65b2fffSAndreas Jaekel znl();
469d65b2fffSAndreas Jaekel } else {
470d65b2fffSAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu "
471d65b2fffSAndreas Jaekel "name='%s' link='%s'\n",
47263aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
47363aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen,
47463aba447SAndreas Jaekel rec->file.ino, rec->file.gen,
47563aba447SAndreas Jaekel ZEV_NAME(rec),
47663aba447SAndreas Jaekel ZEV_LINK(rec));
47763aba447SAndreas Jaekel }
478d65b2fffSAndreas Jaekel }
47963aba447SAndreas Jaekel
48063aba447SAndreas Jaekel static void
zev_print_znode_rename(char * buf)48163aba447SAndreas Jaekel zev_print_znode_rename(char *buf)
48263aba447SAndreas Jaekel {
48363aba447SAndreas Jaekel zev_znode_rename_t *rec = (zev_znode_rename_t *)buf;
48463aba447SAndreas Jaekel time_t op_time = rec->op_time;
48563aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
48663aba447SAndreas Jaekel
487d65b2fffSAndreas Jaekel if (verbose) {
488d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
489d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
490e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
491d65b2fffSAndreas Jaekel zpf(" file.srcname: '%s'", ZEV_SRCNAME(rec));
492d65b2fffSAndreas Jaekel zpf(" file.dstname: '%s'", ZEV_DSTNAME(rec));
493d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
494f8e3fee2SAndreas Jaekel if (rec->clobbered_file.ino)
495f8e3fee2SAndreas Jaekel zev_print_inode_info("clobbered_file",
496f8e3fee2SAndreas Jaekel &rec->clobbered_file);
497d65b2fffSAndreas Jaekel zev_print_inode_info("srcdir", &rec->srcdir);
498d65b2fffSAndreas Jaekel zev_print_inode_info("dstdir", &rec->dstdir);
499d65b2fffSAndreas Jaekel znl();
500d65b2fffSAndreas Jaekel } else {
501d65b2fffSAndreas Jaekel printf("%s %s: srcdir=%llu.%llu dstdir=%llu.%llu "
502d65b2fffSAndreas Jaekel "file=%llu.%llu file.mtime=%llu, file.ctime=%llu, "
503d65b2fffSAndreas Jaekel "srcdir.mtime=%llu, srcdir.ctime=%llu, "
504d65b2fffSAndreas Jaekel "dstdir.mtime=%llu, dstdir.ctime=%llu, "
50563aba447SAndreas Jaekel "srcname='%s' dstname='%s'\n",
50663aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
50763aba447SAndreas Jaekel rec->srcdir.ino, rec->srcdir.gen,
50863aba447SAndreas Jaekel rec->dstdir.ino, rec->dstdir.gen,
50963aba447SAndreas Jaekel rec->file.ino, rec->file.gen,
510c035b1e8SAndreas Jaekel rec->file.mtime, rec->file.ctime,
511c035b1e8SAndreas Jaekel rec->srcdir.mtime, rec->srcdir.ctime,
512c035b1e8SAndreas Jaekel rec->dstdir.mtime, rec->dstdir.ctime,
51363aba447SAndreas Jaekel ZEV_SRCNAME(rec),
51463aba447SAndreas Jaekel ZEV_DSTNAME(rec));
51563aba447SAndreas Jaekel }
516d65b2fffSAndreas Jaekel }
51763aba447SAndreas Jaekel
51863aba447SAndreas Jaekel static void
zev_print_znode_write(char * buf)51963aba447SAndreas Jaekel zev_print_znode_write(char *buf)
52063aba447SAndreas Jaekel {
52163aba447SAndreas Jaekel zev_znode_write_t *rec = (zev_znode_write_t *)buf;
52263aba447SAndreas Jaekel time_t op_time = rec->op_time;
52363aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
5245e286361SAndreas Jaekel zev_sig_t *sig;
5255e286361SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
5265e286361SAndreas Jaekel int i;
52763aba447SAndreas Jaekel
5285e286361SAndreas Jaekel if (verbose) {
529d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
530d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
531e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
532d65b2fffSAndreas Jaekel zpf(" offset: %llu", rec->offset);
533d65b2fffSAndreas Jaekel zpf(" length: %llu", rec->length);
534d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
535d65b2fffSAndreas Jaekel znl();
5365e286361SAndreas Jaekel for (i=0; i<rec->signature_cnt; i++) {
5375e286361SAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(rec);
5385e286361SAndreas Jaekel sig += i;
5395e286361SAndreas Jaekel sig2hex_direct(sig->value, sigval);
5401ca5a13bSAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s",
5415e286361SAndreas Jaekel sig->level, sig->block_offset, sigval);
5425e286361SAndreas Jaekel }
543d65b2fffSAndreas Jaekel } else {
544d65b2fffSAndreas Jaekel printf("%s %s: file=%llu.%llu offset=%llu length=%llu\n",
545d65b2fffSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
546d65b2fffSAndreas Jaekel rec->file.ino, rec->file.gen,
547d65b2fffSAndreas Jaekel rec->offset, rec->length);
5485e286361SAndreas Jaekel }
54963aba447SAndreas Jaekel }
55063aba447SAndreas Jaekel
55163aba447SAndreas Jaekel static void
zev_print_znode_truncate(char * buf)55263aba447SAndreas Jaekel zev_print_znode_truncate(char *buf)
55363aba447SAndreas Jaekel {
55463aba447SAndreas Jaekel zev_print_znode_write(buf);
55563aba447SAndreas Jaekel }
55663aba447SAndreas Jaekel
55763aba447SAndreas Jaekel static void
zev_print_znode_setattr(char * buf)55863aba447SAndreas Jaekel zev_print_znode_setattr(char *buf)
55963aba447SAndreas Jaekel {
56063aba447SAndreas Jaekel zev_znode_setattr_t *rec = (zev_znode_setattr_t *)buf;
56163aba447SAndreas Jaekel time_t op_time = rec->op_time;
56263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0';
56363aba447SAndreas Jaekel
564d65b2fffSAndreas Jaekel if (verbose) {
565d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]);
566d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid);
567e206ace3SAndreas Jaekel zpf(" txg: %llu", rec->txg);
568d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file);
569d65b2fffSAndreas Jaekel znl();
570d65b2fffSAndreas Jaekel } else {
571c035b1e8SAndreas Jaekel printf("%s %s: file=%llu.%llu mtime=%llu\n",
57263aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN],
573c035b1e8SAndreas Jaekel rec->file.ino, rec->file.gen, rec->file.mtime);
57463aba447SAndreas Jaekel }
575d65b2fffSAndreas Jaekel }
57663aba447SAndreas Jaekel
57763aba447SAndreas Jaekel static void
zev_print_znode_acl(char * buf)57863aba447SAndreas Jaekel zev_print_znode_acl(char *buf)
57963aba447SAndreas Jaekel {
58063aba447SAndreas Jaekel zev_print_znode_setattr(buf);
58163aba447SAndreas Jaekel }
58263aba447SAndreas Jaekel
58363aba447SAndreas Jaekel static void
zev_print_event(char * buf,int len)5849193e9c2SAndreas Jaekel zev_print_event(char *buf, int len)
5859193e9c2SAndreas Jaekel {
58663aba447SAndreas Jaekel int record_len;
58763aba447SAndreas Jaekel int op;
5889193e9c2SAndreas Jaekel
58963aba447SAndreas Jaekel record_len = *(uint32_t *)buf;
59063aba447SAndreas Jaekel if (record_len != len) {
59163aba447SAndreas Jaekel fprintf(stderr, "record length mismatch: got %d, expected %d\n",
59263aba447SAndreas Jaekel record_len, len);
5939193e9c2SAndreas Jaekel exit(1);
5949193e9c2SAndreas Jaekel }
59563aba447SAndreas Jaekel op = *((uint32_t *)buf + 1);
5969193e9c2SAndreas Jaekel if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) {
59763aba447SAndreas Jaekel fprintf(stderr, "unknown op code: %d\n", op);
5989193e9c2SAndreas Jaekel exit(1);
5999193e9c2SAndreas Jaekel }
600*0f07b41bSArne Jansen if (num_guid_filter) {
601*0f07b41bSArne Jansen uint64_t guid = *((uint64_t *)buf + 2);
602*0f07b41bSArne Jansen int i;
603*0f07b41bSArne Jansen
604*0f07b41bSArne Jansen for (i = 0; i < num_guid_filter; ++i)
605*0f07b41bSArne Jansen if (guid_filter[i] == guid)
606*0f07b41bSArne Jansen break;
607*0f07b41bSArne Jansen
608*0f07b41bSArne Jansen if (i == num_guid_filter)
609*0f07b41bSArne Jansen /* no match, filtered */
610*0f07b41bSArne Jansen return;
611*0f07b41bSArne Jansen }
61263aba447SAndreas Jaekel switch (op) {
61363aba447SAndreas Jaekel case ZEV_OP_ERROR:
61463aba447SAndreas Jaekel zev_print_error(buf);
6159193e9c2SAndreas Jaekel break;
61601c2c787SAndreas Jaekel case ZEV_OP_MARK:
61701c2c787SAndreas Jaekel zev_print_mark(buf);
61801c2c787SAndreas Jaekel break;
61963aba447SAndreas Jaekel case ZEV_OP_ZFS_MOUNT:
62063aba447SAndreas Jaekel zev_print_zfs_mount(buf);
6219193e9c2SAndreas Jaekel break;
62263aba447SAndreas Jaekel case ZEV_OP_ZFS_UMOUNT:
62363aba447SAndreas Jaekel zev_print_zfs_umount(buf);
6249193e9c2SAndreas Jaekel break;
62563aba447SAndreas Jaekel case ZEV_OP_ZVOL_TRUNCATE:
62663aba447SAndreas Jaekel zev_print_zvol_truncate(buf);
6279193e9c2SAndreas Jaekel break;
62863aba447SAndreas Jaekel case ZEV_OP_ZVOL_WRITE:
62963aba447SAndreas Jaekel zev_print_zvol_write(buf);
63063aba447SAndreas Jaekel break;
63163aba447SAndreas Jaekel case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE:
63263aba447SAndreas Jaekel zev_print_znode_close_after_update(buf);
63363aba447SAndreas Jaekel break;
63463aba447SAndreas Jaekel case ZEV_OP_ZNODE_CREATE:
63563aba447SAndreas Jaekel zev_print_znode_create(buf);
63663aba447SAndreas Jaekel break;
63763aba447SAndreas Jaekel case ZEV_OP_ZNODE_MKDIR:
63863aba447SAndreas Jaekel zev_print_znode_mkdir(buf);
63963aba447SAndreas Jaekel break;
64063aba447SAndreas Jaekel case ZEV_OP_ZNODE_MAKE_XATTR_DIR:
64163aba447SAndreas Jaekel zev_print_znode_make_xattr_dir(buf);
64263aba447SAndreas Jaekel break;
64363aba447SAndreas Jaekel case ZEV_OP_ZNODE_REMOVE:
64463aba447SAndreas Jaekel zev_print_znode_remove(buf);
64563aba447SAndreas Jaekel break;
64663aba447SAndreas Jaekel case ZEV_OP_ZNODE_RMDIR:
64763aba447SAndreas Jaekel zev_print_znode_rmdir(buf);
64863aba447SAndreas Jaekel break;
64963aba447SAndreas Jaekel case ZEV_OP_ZNODE_LINK:
65063aba447SAndreas Jaekel zev_print_znode_link(buf);
65163aba447SAndreas Jaekel break;
65263aba447SAndreas Jaekel case ZEV_OP_ZNODE_SYMLINK:
65363aba447SAndreas Jaekel zev_print_znode_symlink(buf);
65463aba447SAndreas Jaekel break;
65563aba447SAndreas Jaekel case ZEV_OP_ZNODE_RENAME:
65663aba447SAndreas Jaekel zev_print_znode_rename(buf);
65763aba447SAndreas Jaekel break;
65863aba447SAndreas Jaekel case ZEV_OP_ZNODE_WRITE:
65963aba447SAndreas Jaekel zev_print_znode_write(buf);
66063aba447SAndreas Jaekel break;
66163aba447SAndreas Jaekel case ZEV_OP_ZNODE_TRUNCATE:
66263aba447SAndreas Jaekel zev_print_znode_truncate(buf);
66363aba447SAndreas Jaekel break;
66463aba447SAndreas Jaekel case ZEV_OP_ZNODE_SETATTR:
66563aba447SAndreas Jaekel zev_print_znode_setattr(buf);
66663aba447SAndreas Jaekel break;
66763aba447SAndreas Jaekel case ZEV_OP_ZNODE_ACL:
66863aba447SAndreas Jaekel zev_print_znode_acl(buf);
6699193e9c2SAndreas Jaekel break;
6709193e9c2SAndreas Jaekel default:
67163aba447SAndreas Jaekel fprintf(stderr, "unhandled op code: %d\n", op);
6729193e9c2SAndreas Jaekel exit(1);
6739193e9c2SAndreas Jaekel }
674c07f6d81SArne Jansen if (do_flush)
675c07f6d81SArne Jansen fflush(stdout);
6769193e9c2SAndreas Jaekel }
6779193e9c2SAndreas Jaekel
678e9a5e479SAndreas Jaekel static int
zev_poll_events(int fd,int create_tmp_queue)679bfe96c74SAndreas Jaekel zev_poll_events(int fd, int create_tmp_queue)
6802bb8e5e2SAndreas Jaekel {
6812bb8e5e2SAndreas Jaekel struct pollfd pfd[1];
6822bb8e5e2SAndreas Jaekel int ret;
6839193e9c2SAndreas Jaekel char buf[4096];
68468a46c64SAndreas Jaekel zev_event_t *ev;
68568a46c64SAndreas Jaekel int off = 0;
686e9a5e479SAndreas Jaekel int q_fd;
687e9a5e479SAndreas Jaekel
6884ca7dd5eSAndreas Jaekel if (create_tmp_queue) {
6894ca7dd5eSAndreas Jaekel snprintf(buf, sizeof(buf),
690bfe96c74SAndreas Jaekel "/devices/pseudo/zev@0:%s", ZEV_TMPQUEUE_DEVICE_NAME);
691e9a5e479SAndreas Jaekel q_fd = open(buf, O_RDONLY);
692e9a5e479SAndreas Jaekel if (q_fd < 0) {
693e9a5e479SAndreas Jaekel perror("opening queue device failed");
694e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
695e9a5e479SAndreas Jaekel }
6964ca7dd5eSAndreas Jaekel } else {
6974ca7dd5eSAndreas Jaekel q_fd = fd;
6984ca7dd5eSAndreas Jaekel }
699e9a5e479SAndreas Jaekel
7002bb8e5e2SAndreas Jaekel while (1) {
701e9a5e479SAndreas Jaekel pfd[0].fd = q_fd;
7022bb8e5e2SAndreas Jaekel pfd[0].events = POLLIN;
7032bb8e5e2SAndreas Jaekel ret = poll(pfd, 1, 1000);
7042bb8e5e2SAndreas Jaekel if (ret < 0) {
7052bb8e5e2SAndreas Jaekel perror("poll failed");
7064ca7dd5eSAndreas Jaekel close(q_fd);
707e9a5e479SAndreas Jaekel return(EXIT_FAILURE);
7082bb8e5e2SAndreas Jaekel }
7092bb8e5e2SAndreas Jaekel if (!(pfd[0].revents & POLLIN))
7102bb8e5e2SAndreas Jaekel continue;
7112bb8e5e2SAndreas Jaekel /* data available */
712e9a5e479SAndreas Jaekel ret = read(q_fd, buf, sizeof(buf));
7132bb8e5e2SAndreas Jaekel if (ret < 0) {
7142bb8e5e2SAndreas Jaekel perror("read failed");
7154ca7dd5eSAndreas Jaekel close(q_fd);
716e9a5e479SAndreas Jaekel return(EXIT_FAILURE);
7172bb8e5e2SAndreas Jaekel }
7182bb8e5e2SAndreas Jaekel if (ret == 0)
7192bb8e5e2SAndreas Jaekel continue;
72068a46c64SAndreas Jaekel while (ret > off) {
72168a46c64SAndreas Jaekel ev = (zev_event_t *)(buf + off);
72268a46c64SAndreas Jaekel zev_print_event(buf + off, ev->header.record_len);
72368a46c64SAndreas Jaekel off += ev->header.record_len;
72468a46c64SAndreas Jaekel }
725108668daSAndreas Jaekel off = 0;
7262bb8e5e2SAndreas Jaekel }
7274ca7dd5eSAndreas Jaekel if (create_tmp_queue)
728e9a5e479SAndreas Jaekel close(q_fd);
729e9a5e479SAndreas Jaekel return EXIT_SUCCESS;
7302bb8e5e2SAndreas Jaekel }
7312bb8e5e2SAndreas Jaekel
732797b8adfSArne Jansen static int
zev_dump_spool(int fd)733797b8adfSArne Jansen zev_dump_spool(int fd)
734797b8adfSArne Jansen {
735797b8adfSArne Jansen int len;
736797b8adfSArne Jansen char buf[4096];
737797b8adfSArne Jansen int off = 0;
738797b8adfSArne Jansen
739797b8adfSArne Jansen while (1) {
740797b8adfSArne Jansen len = read(fd, buf + off, sizeof(buf) - off);
741797b8adfSArne Jansen if (len == -1) {
742797b8adfSArne Jansen fprintf(stderr, "reading from spool failed: %s\n",
743797b8adfSArne Jansen strerror(errno));
744797b8adfSArne Jansen return EXIT_FAILURE;
745797b8adfSArne Jansen }
746797b8adfSArne Jansen if (len == 0)
747797b8adfSArne Jansen break;
748797b8adfSArne Jansen
749797b8adfSArne Jansen len += off;
750797b8adfSArne Jansen off = 0;
751797b8adfSArne Jansen while (len > off + sizeof(uint32_t)) {
752797b8adfSArne Jansen uint32_t evlen;
753797b8adfSArne Jansen char *mp;
754797b8adfSArne Jansen zev_event_t *ev;
755797b8adfSArne Jansen
756797b8adfSArne Jansen ev = (zev_event_t *)(buf + off);
757797b8adfSArne Jansen evlen = ev->header.record_len;
758797b8adfSArne Jansen if (len < off + evlen + 1)
759797b8adfSArne Jansen break;
760797b8adfSArne Jansen mp = buf + off + evlen;
761797b8adfSArne Jansen if (!memchr(mp, 0, len - off - evlen))
762797b8adfSArne Jansen break;
763797b8adfSArne Jansen zev_print_event(buf + off, ev->header.record_len);
764797b8adfSArne Jansen off += ev->header.record_len + strlen(mp) + 1;
765797b8adfSArne Jansen }
766797b8adfSArne Jansen
767797b8adfSArne Jansen memmove(buf, buf + off, len - off);
768797b8adfSArne Jansen off = len - off;
769797b8adfSArne Jansen }
770797b8adfSArne Jansen
771797b8adfSArne Jansen return EXIT_SUCCESS;
772797b8adfSArne Jansen }
773797b8adfSArne Jansen
7742bb8e5e2SAndreas Jaekel static void
usage(char * progname)7752bb8e5e2SAndreas Jaekel usage(char *progname)
7762bb8e5e2SAndreas Jaekel {
777e9a5e479SAndreas Jaekel fprintf(stderr, "usage: %s [-d <dev>] [options]\n", progname);
778e9a5e479SAndreas Jaekel fprintf(stderr, "\n");
779e9a5e479SAndreas Jaekel fprintf(stderr, " Status information:\n");
7802bb8e5e2SAndreas Jaekel fprintf(stderr, " -s show zev statistics\n");
7812bb8e5e2SAndreas Jaekel fprintf(stderr, " -p poll for ZFS events\n");
782797b8adfSArne Jansen fprintf(stderr, " -f <name> dump events from spool\n");
783e9a5e479SAndreas Jaekel fprintf(stderr, " -D print zev module debug "
784e9a5e479SAndreas Jaekel "information\n");
7850abdde4aSAndreas Jaekel fprintf(stderr, " -T <interval> <cnt> zevstat mode\n");
7869fd83c76SAndreas Jaekel fprintf(stderr, " -R <base filename> zevreport mode\n");
787e9a5e479SAndreas Jaekel fprintf(stderr, "\n");
788e9a5e479SAndreas Jaekel fprintf(stderr, " Tune zev module settings:\n");
789e9a5e479SAndreas Jaekel fprintf(stderr, " -Q <bytes> set maximum event queue "
790e9a5e479SAndreas Jaekel "length\n");
791e9a5e479SAndreas Jaekel fprintf(stderr, " -m <pool> mute pool, no events for "
792e9a5e479SAndreas Jaekel "this pool\n");
7932bb8e5e2SAndreas Jaekel fprintf(stderr, " -M <pool> unmute pool\n");
794e9a5e479SAndreas Jaekel fprintf(stderr, "\n");
795e9a5e479SAndreas Jaekel fprintf(stderr, " Queue management:\n");
796e9a5e479SAndreas Jaekel fprintf(stderr, " -l list queues\n");
7974ca7dd5eSAndreas Jaekel fprintf(stderr, " -a <name> add non-blocking queue\n");
7984ca7dd5eSAndreas Jaekel fprintf(stderr, " -A <name> add blocking queue\n");
799e9a5e479SAndreas Jaekel fprintf(stderr, " -r <name> remove queue\n");
800e9a5e479SAndreas Jaekel fprintf(stderr, " -b <name> make queue non-blocking "
801e9a5e479SAndreas Jaekel "(default)\n");
802e9a5e479SAndreas Jaekel fprintf(stderr, " -B <name> make queue block when full\n");
803e9a5e479SAndreas Jaekel fprintf(stderr, " -P <name> display queue properties\n");
8044ca7dd5eSAndreas Jaekel fprintf(stderr, " -L <name> <bytes> set maximum event queue "
805e9a5e479SAndreas Jaekel "length\n");
806e9a5e479SAndreas Jaekel fprintf(stderr, " -t <name> <bytes> set queue length poll "
807e9a5e479SAndreas Jaekel "throttle\n");
808e9a5e479SAndreas Jaekel fprintf(stderr, "\n");
809e9a5e479SAndreas Jaekel fprintf(stderr, " Other options:\n");
810e9a5e479SAndreas Jaekel fprintf(stderr, " -d <dev> non-default device file. "
811e9a5e479SAndreas Jaekel "('%s')\n", ZEV_DEVICE);
8124ca7dd5eSAndreas Jaekel fprintf(stderr, " -q <name> use device file for this "
8134ca7dd5eSAndreas Jaekel "queue name\n");
81401c2c787SAndreas Jaekel fprintf(stderr, " -k <guid>:<payload> queue mark event\n");
815b9710123SAndreas Jaekel fprintf(stderr, " -c <filename> list file's content "
816b9710123SAndreas Jaekel "checksums\n");
817d65b2fffSAndreas Jaekel fprintf(stderr, " -v verbose: additional output "
8185e286361SAndreas Jaekel "for some operations\n");
819d65b2fffSAndreas Jaekel fprintf(stderr, " -g grep-friendly event output, "
820d65b2fffSAndreas Jaekel "one event per line\n");
821*0f07b41bSArne Jansen fprintf(stderr, " -G <guid> filter event output by guid, "
822*0f07b41bSArne Jansen "can be given more than once\n");
823c62d8367SAndreas Jaekel fprintf(stderr, " -V query zev module version\n");
824c07f6d81SArne Jansen fprintf(stderr, " -F flush output after each line\n");
8252bb8e5e2SAndreas Jaekel exit (EXIT_FAILURE);
8262bb8e5e2SAndreas Jaekel }
8272bb8e5e2SAndreas Jaekel
82829fab2f9SAndreas Jaekel static void
zevstat_usage(char * progname)82929fab2f9SAndreas Jaekel zevstat_usage(char *progname)
83029fab2f9SAndreas Jaekel {
83129fab2f9SAndreas Jaekel fprintf(stderr, "usage: %s [-v] <interval> [count]\n", progname);
83229fab2f9SAndreas Jaekel fprintf(stderr, " -v verbose, show counters for all event types\n");
83329fab2f9SAndreas Jaekel exit (EXIT_FAILURE);
83429fab2f9SAndreas Jaekel }
83529fab2f9SAndreas Jaekel
8369fd83c76SAndreas Jaekel static void
zevreport_usage(char * progname)8379fd83c76SAndreas Jaekel zevreport_usage(char *progname)
8389fd83c76SAndreas Jaekel {
8399fd83c76SAndreas Jaekel fprintf(stderr, "usage: %s <output base filename>\n", progname);
8409fd83c76SAndreas Jaekel exit (EXIT_FAILURE);
8419fd83c76SAndreas Jaekel }
8429fd83c76SAndreas Jaekel
8432bb8e5e2SAndreas Jaekel static int
zev_add_queue(int fd,char * arg,int blocking)8444ca7dd5eSAndreas Jaekel zev_add_queue(int fd, char *arg, int blocking)
8452bb8e5e2SAndreas Jaekel {
846e9a5e479SAndreas Jaekel zev_ioctl_add_queue_t aq;
847e9a5e479SAndreas Jaekel int namelen;
8482bb8e5e2SAndreas Jaekel
849e9a5e479SAndreas Jaekel namelen = strlen(arg);
850e9a5e479SAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
851e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg);
8522bb8e5e2SAndreas Jaekel return (EXIT_FAILURE);
8532bb8e5e2SAndreas Jaekel }
854e9a5e479SAndreas Jaekel
855e9a5e479SAndreas Jaekel aq.zev_namelen = namelen;
856e9a5e479SAndreas Jaekel strcpy(aq.zev_name, arg);
857b434d29cSAndreas Jaekel aq.zev_flags = ZEV_FL_PERSISTENT | ZEV_FL_INITIALLY_EMPTY;
8584ca7dd5eSAndreas Jaekel if (blocking) {
8594ca7dd5eSAndreas Jaekel aq.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
8604ca7dd5eSAndreas Jaekel aq.zev_max_queue_len = ZEV_MAX_QUEUE_LEN;
8614ca7dd5eSAndreas Jaekel } else {
862e9a5e479SAndreas Jaekel aq.zev_max_queue_len = (1024 * 1024);
8634ca7dd5eSAndreas Jaekel }
864e9a5e479SAndreas Jaekel
865e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
866e9a5e479SAndreas Jaekel perror("adding queue failed");
8672bb8e5e2SAndreas Jaekel return (EXIT_FAILURE);
8682bb8e5e2SAndreas Jaekel }
8692bb8e5e2SAndreas Jaekel return (0);
8702bb8e5e2SAndreas Jaekel }
8712bb8e5e2SAndreas Jaekel
8722bb8e5e2SAndreas Jaekel static int
zev_remove_queue(int fd,char * arg)873e9a5e479SAndreas Jaekel zev_remove_queue(int fd, char *arg)
874205a9bc9SAndreas Jaekel {
875e9a5e479SAndreas Jaekel zev_ioctl_remove_queue_t aq;
876e9a5e479SAndreas Jaekel int namelen;
877205a9bc9SAndreas Jaekel
878e9a5e479SAndreas Jaekel namelen = strlen(arg);
879e9a5e479SAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) {
880e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg);
881205a9bc9SAndreas Jaekel return (EXIT_FAILURE);
882205a9bc9SAndreas Jaekel }
883e9a5e479SAndreas Jaekel
8844ca7dd5eSAndreas Jaekel aq.zev_queue_name.zev_namelen = namelen;
8854ca7dd5eSAndreas Jaekel strcpy(aq.zev_queue_name.zev_name, arg);
886e9a5e479SAndreas Jaekel
887e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_REMOVE_QUEUE, &aq)) {
888e9a5e479SAndreas Jaekel perror("removing queue failed");
889e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
890e9a5e479SAndreas Jaekel }
891e9a5e479SAndreas Jaekel return (0);
892e9a5e479SAndreas Jaekel }
893e9a5e479SAndreas Jaekel
894e9a5e479SAndreas Jaekel static int
zev_set_global_max_queue_len(int fd,char * arg)895e9a5e479SAndreas Jaekel zev_set_global_max_queue_len(int fd, char *arg)
896e9a5e479SAndreas Jaekel {
897e9a5e479SAndreas Jaekel uint64_t maxqueuelen;
898e9a5e479SAndreas Jaekel
899f36f5f13SAndreas Jaekel if (!arg) {
900f36f5f13SAndreas Jaekel fprintf(stderr, "missing queue length parameter\n");
901f36f5f13SAndreas Jaekel return (EXIT_FAILURE);
902f36f5f13SAndreas Jaekel }
903f36f5f13SAndreas Jaekel
904e9a5e479SAndreas Jaekel errno = 0;
905e9a5e479SAndreas Jaekel maxqueuelen = strtol(arg, (char **)NULL, 10);
906e9a5e479SAndreas Jaekel if (errno) {
907e9a5e479SAndreas Jaekel fprintf(stderr, "invalid queue length parameter: %s\n", arg);
908e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
909e9a5e479SAndreas Jaekel }
910e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_MAX_QUEUE_LEN, &maxqueuelen)) {
911e9a5e479SAndreas Jaekel perror("setting max queue length failed");
912205a9bc9SAndreas Jaekel return (EXIT_FAILURE);
913205a9bc9SAndreas Jaekel }
914205a9bc9SAndreas Jaekel return (0);
915205a9bc9SAndreas Jaekel }
916205a9bc9SAndreas Jaekel
917205a9bc9SAndreas Jaekel static int
zev_mute_unmute_impl(int fd,char * poolname,int mute)9182bb8e5e2SAndreas Jaekel zev_mute_unmute_impl(int fd, char *poolname, int mute)
9192bb8e5e2SAndreas Jaekel {
9202bb8e5e2SAndreas Jaekel zev_ioctl_poolarg_t pa;
9212bb8e5e2SAndreas Jaekel int len;
9222bb8e5e2SAndreas Jaekel int op = mute ? ZEV_IOC_MUTE_POOL : ZEV_IOC_UNMUTE_POOL;
9232bb8e5e2SAndreas Jaekel len = strlen(poolname);
9242bb8e5e2SAndreas Jaekel if (len <= 0 || len >= sizeof(pa.zev_poolname)) {
9252bb8e5e2SAndreas Jaekel fprintf(stderr, "invalid poolname: %s\n", poolname);
9262bb8e5e2SAndreas Jaekel return (EXIT_FAILURE);
9272bb8e5e2SAndreas Jaekel }
9282bb8e5e2SAndreas Jaekel strcpy(pa.zev_poolname, poolname);
9292bb8e5e2SAndreas Jaekel pa.zev_poolname_len = len;
9302bb8e5e2SAndreas Jaekel if (ioctl(fd, op, &pa)) {
9312bb8e5e2SAndreas Jaekel perror("muting pool data failed");
9322bb8e5e2SAndreas Jaekel return (EXIT_FAILURE);
9332bb8e5e2SAndreas Jaekel }
9342bb8e5e2SAndreas Jaekel return (0);
9352bb8e5e2SAndreas Jaekel }
9362bb8e5e2SAndreas Jaekel
9372bb8e5e2SAndreas Jaekel int
zev_mute_pool(int fd,char * poolname)9382bb8e5e2SAndreas Jaekel zev_mute_pool(int fd, char *poolname)
9392bb8e5e2SAndreas Jaekel {
9402bb8e5e2SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 1);
9412bb8e5e2SAndreas Jaekel }
9422bb8e5e2SAndreas Jaekel
9432bb8e5e2SAndreas Jaekel int
zev_unmute_pool(int fd,char * poolname)9442bb8e5e2SAndreas Jaekel zev_unmute_pool(int fd, char *poolname)
9452bb8e5e2SAndreas Jaekel {
9462bb8e5e2SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 0);
9472bb8e5e2SAndreas Jaekel }
9482bb8e5e2SAndreas Jaekel
94901c2c787SAndreas Jaekel static int
zev_debug_info(int fd)950e9a5e479SAndreas Jaekel zev_debug_info(int fd)
951e9a5e479SAndreas Jaekel {
952e9a5e479SAndreas Jaekel zev_ioctl_debug_info_t di;
953e9a5e479SAndreas Jaekel
954e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_DEBUG_INFO, &di)) {
955e9a5e479SAndreas Jaekel perror("getting zev debug info failed");
956e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
957e9a5e479SAndreas Jaekel }
958e9a5e479SAndreas Jaekel
959e9a5e479SAndreas Jaekel printf("memory allocated: %llu bytes\n", di.zev_memory_allocated);
9605e286361SAndreas Jaekel printf("checksum cache size: %llu\n", di.zev_chksum_cache_size);
9615e286361SAndreas Jaekel printf("checksum cache hits: %llu\n", di.zev_chksum_cache_hits);
9625e286361SAndreas Jaekel printf("checksum cache misses: %llu\n", di.zev_chksum_cache_misses);
963e9a5e479SAndreas Jaekel return 0;
964e9a5e479SAndreas Jaekel }
965e9a5e479SAndreas Jaekel
966e9a5e479SAndreas Jaekel static int
zev_mark(int fd,char * arg)96701c2c787SAndreas Jaekel zev_mark(int fd, char *arg)
96801c2c787SAndreas Jaekel {
96901c2c787SAndreas Jaekel zev_ioctl_mark_t *mark;
97001c2c787SAndreas Jaekel uint64_t guid;
97101c2c787SAndreas Jaekel int len;
97201c2c787SAndreas Jaekel char *p;
97301c2c787SAndreas Jaekel
97401c2c787SAndreas Jaekel p = strchr(arg, ':');
97501c2c787SAndreas Jaekel if (!p) {
97601c2c787SAndreas Jaekel fprintf(stderr, "expected value is <guid>:<payload>, "
97701c2c787SAndreas Jaekel "e.g. '123:hello'\n");
97801c2c787SAndreas Jaekel exit (EXIT_FAILURE);
97901c2c787SAndreas Jaekel }
98001c2c787SAndreas Jaekel *p = '\n';
98101c2c787SAndreas Jaekel p++;
98201c2c787SAndreas Jaekel
98301c2c787SAndreas Jaekel errno = 0;
984e9a5e479SAndreas Jaekel guid = strtoll(arg, (char **)NULL, 10);
98501c2c787SAndreas Jaekel if (errno) {
98601c2c787SAndreas Jaekel fprintf(stderr, "guid must be a number.\n");
98701c2c787SAndreas Jaekel exit (EXIT_FAILURE);
98801c2c787SAndreas Jaekel }
98901c2c787SAndreas Jaekel
99001c2c787SAndreas Jaekel len = strlen(p);
99101c2c787SAndreas Jaekel
99201c2c787SAndreas Jaekel mark = malloc(sizeof(*mark) + len + 1);
99301c2c787SAndreas Jaekel if (!mark) {
99401c2c787SAndreas Jaekel fprintf(stderr, "can't allocate mark structure: %s\n",
99501c2c787SAndreas Jaekel strerror(errno));
99601c2c787SAndreas Jaekel exit (EXIT_FAILURE);
99701c2c787SAndreas Jaekel }
99801c2c787SAndreas Jaekel mark->zev_guid = guid;
99901c2c787SAndreas Jaekel mark->zev_mark_id = 0;
100001c2c787SAndreas Jaekel mark->zev_payload_len = len;
100101c2c787SAndreas Jaekel strcpy(ZEV_PAYLOAD(mark), p);
100201c2c787SAndreas Jaekel
100301c2c787SAndreas Jaekel if (ioctl(fd, ZEV_IOC_MARK, mark)) {
100401c2c787SAndreas Jaekel perror("queueing mark failed");
100501c2c787SAndreas Jaekel return (EXIT_FAILURE);
100601c2c787SAndreas Jaekel }
100701c2c787SAndreas Jaekel
100801c2c787SAndreas Jaekel printf("mark id: %lu\n", mark->zev_mark_id);
100901c2c787SAndreas Jaekel return (0);
101001c2c787SAndreas Jaekel }
101101c2c787SAndreas Jaekel
1012e9a5e479SAndreas Jaekel static int
zev_queue_blocking(int fd,char * arg,int block)1013e9a5e479SAndreas Jaekel zev_queue_blocking(int fd, char *arg, int block)
1014e9a5e479SAndreas Jaekel {
1015e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1016e9a5e479SAndreas Jaekel
10174ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
10184ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1019e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1020e9a5e479SAndreas Jaekel return EXIT_FAILURE;
1021e9a5e479SAndreas Jaekel }
10224ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1023e9a5e479SAndreas Jaekel
1024e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1025e9a5e479SAndreas Jaekel perror("getting queue properties failed");
1026e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1027e9a5e479SAndreas Jaekel }
1028e9a5e479SAndreas Jaekel if (block) {
1029e9a5e479SAndreas Jaekel gqp.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
1030e9a5e479SAndreas Jaekel } else {
1031e9a5e479SAndreas Jaekel gqp.zev_flags &= ~ZEV_FL_BLOCK_WHILE_QUEUE_FULL;
1032e9a5e479SAndreas Jaekel }
1033e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1034e9a5e479SAndreas Jaekel perror("setting queue properties failed");
1035e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1036e9a5e479SAndreas Jaekel }
1037e9a5e479SAndreas Jaekel return (0);
1038e9a5e479SAndreas Jaekel }
1039e9a5e479SAndreas Jaekel
1040e9a5e479SAndreas Jaekel static int
zev_set_max_queue_len(int fd,char * arg,char * len)1041e9a5e479SAndreas Jaekel zev_set_max_queue_len(int fd, char *arg, char *len)
1042e9a5e479SAndreas Jaekel {
1043e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1044e9a5e479SAndreas Jaekel
1045e9a5e479SAndreas Jaekel if (!len) {
1046e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter missing.\n");
1047e9a5e479SAndreas Jaekel return EXIT_FAILURE;
1048e9a5e479SAndreas Jaekel }
1049e9a5e479SAndreas Jaekel
10504ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
10514ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1052e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1053e9a5e479SAndreas Jaekel return EXIT_FAILURE;
1054e9a5e479SAndreas Jaekel }
10554ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1056e9a5e479SAndreas Jaekel
1057e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1058e9a5e479SAndreas Jaekel perror("getting queue properties failed");
1059e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1060e9a5e479SAndreas Jaekel }
1061e9a5e479SAndreas Jaekel gqp.zev_max_queue_len = atol(len);
1062e9a5e479SAndreas Jaekel if (gqp.zev_max_queue_len == 0 && strcmp("0", len)) {
1063e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter garbled.\n");
1064e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1065e9a5e479SAndreas Jaekel }
1066e9a5e479SAndreas Jaekel if (gqp.zev_max_queue_len > ZEV_MAX_QUEUE_LEN) {
1067e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter out of bounds.\n");
1068e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1069e9a5e479SAndreas Jaekel }
1070e9a5e479SAndreas Jaekel
1071e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1072e9a5e479SAndreas Jaekel perror("setting queue properties failed");
1073e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1074e9a5e479SAndreas Jaekel }
1075e9a5e479SAndreas Jaekel return (0);
1076e9a5e479SAndreas Jaekel }
1077e9a5e479SAndreas Jaekel
1078e9a5e479SAndreas Jaekel static int
zev_set_poll_wakeup_queue_len(int fd,char * arg,char * len)1079e9a5e479SAndreas Jaekel zev_set_poll_wakeup_queue_len(int fd, char *arg, char *len)
1080e9a5e479SAndreas Jaekel {
1081e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1082e9a5e479SAndreas Jaekel
1083e9a5e479SAndreas Jaekel if (!len) {
1084e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter missing.\n");
1085e9a5e479SAndreas Jaekel return EXIT_FAILURE;
1086e9a5e479SAndreas Jaekel }
1087e9a5e479SAndreas Jaekel
10884ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
10894ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1090e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1091e9a5e479SAndreas Jaekel return EXIT_FAILURE;
1092e9a5e479SAndreas Jaekel }
10934ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1094e9a5e479SAndreas Jaekel
1095e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1096e9a5e479SAndreas Jaekel perror("getting queue properties failed");
1097e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1098e9a5e479SAndreas Jaekel }
1099e9a5e479SAndreas Jaekel gqp.zev_poll_wakeup_threshold = atol(len);
1100e9a5e479SAndreas Jaekel if (gqp.zev_poll_wakeup_threshold == 0 && strcmp("0", len)) {
1101e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter garbled.\n");
1102e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1103e9a5e479SAndreas Jaekel }
11044ca7dd5eSAndreas Jaekel if (gqp.zev_poll_wakeup_threshold > ZEV_MAX_POLL_WAKEUP_QUEUE_LEN) {
1105e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter out of bounds.\n");
1106e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1107e9a5e479SAndreas Jaekel }
1108e9a5e479SAndreas Jaekel
1109e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) {
1110e9a5e479SAndreas Jaekel perror("setting queue properties failed");
1111e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1112e9a5e479SAndreas Jaekel }
1113e9a5e479SAndreas Jaekel return (0);
1114e9a5e479SAndreas Jaekel }
1115e9a5e479SAndreas Jaekel
1116e9a5e479SAndreas Jaekel static int
zev_queue_properties(int fd,char * arg)1117e9a5e479SAndreas Jaekel zev_queue_properties(int fd, char *arg)
1118e9a5e479SAndreas Jaekel {
1119e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1120e9a5e479SAndreas Jaekel
11214ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg);
11224ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) {
1123e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n");
1124e9a5e479SAndreas Jaekel return EXIT_FAILURE;
1125e9a5e479SAndreas Jaekel }
11264ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg);
1127e9a5e479SAndreas Jaekel
1128e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1129e9a5e479SAndreas Jaekel perror("getting queue properties failed");
1130e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1131e9a5e479SAndreas Jaekel }
1132e9a5e479SAndreas Jaekel
1133e9a5e479SAndreas Jaekel printf("queue : %s\n", arg);
1134e9a5e479SAndreas Jaekel printf("max size : %" PRIu64 "\n", gqp.zev_max_queue_len);
1135e9a5e479SAndreas Jaekel printf("poll throttle: %" PRIu64 "\n", gqp.zev_poll_wakeup_threshold);
1136e9a5e479SAndreas Jaekel printf("persistent : %s\n",
1137e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no");
1138e9a5e479SAndreas Jaekel printf("blocking : %s\n",
1139e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? "yes" : "no");
1140e9a5e479SAndreas Jaekel
1141e9a5e479SAndreas Jaekel return (0);
1142e9a5e479SAndreas Jaekel }
1143e9a5e479SAndreas Jaekel
1144e9a5e479SAndreas Jaekel static int
zev_list_queues(int fd)1145e9a5e479SAndreas Jaekel zev_list_queues(int fd)
1146e9a5e479SAndreas Jaekel {
1147e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp;
1148e9a5e479SAndreas Jaekel zev_ioctl_get_queue_list_t gql;
1149e9a5e479SAndreas Jaekel zev_ioctl_get_queue_statistics_t gs;
1150e9a5e479SAndreas Jaekel uint64_t i;
1151e9a5e479SAndreas Jaekel char name[ZEV_MAX_QUEUE_NAME_LEN+1];
1152662d8e03SAndreas Jaekel zev_statistics_t zs;
1153662d8e03SAndreas Jaekel
1154662d8e03SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) {
1155662d8e03SAndreas Jaekel perror("getting statistics data failed");
1156662d8e03SAndreas Jaekel return (EXIT_FAILURE);
1157662d8e03SAndreas Jaekel }
1158e9a5e479SAndreas Jaekel
1159e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_LIST, &gql)) {
1160e9a5e479SAndreas Jaekel perror("getting queue list failed");
1161e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1162e9a5e479SAndreas Jaekel }
1163e9a5e479SAndreas Jaekel
1164e9a5e479SAndreas Jaekel printf("Name Size "
1165662d8e03SAndreas Jaekel "Size%% Max Size Per Block\n");
1166e9a5e479SAndreas Jaekel
1167e9a5e479SAndreas Jaekel for (i=0; i<gql.zev_n_queues; i++) {
1168e9a5e479SAndreas Jaekel strncpy(name, gql.zev_queue_name[i].zev_name,
1169e9a5e479SAndreas Jaekel ZEV_MAX_QUEUE_NAME_LEN);
1170e9a5e479SAndreas Jaekel name[gql.zev_queue_name[i].zev_namelen] = '\0';
1171e9a5e479SAndreas Jaekel
11724ca7dd5eSAndreas Jaekel memcpy(gqp.zev_queue_name.zev_name,
11734ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
11744ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen =
11754ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_namelen;
1176e9a5e479SAndreas Jaekel
1177e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) {
1178e9a5e479SAndreas Jaekel if (errno == ENOENT)
1179e9a5e479SAndreas Jaekel continue;
1180e9a5e479SAndreas Jaekel perror("getting queue properties failed");
1181e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1182e9a5e479SAndreas Jaekel }
1183e9a5e479SAndreas Jaekel
11844ca7dd5eSAndreas Jaekel memcpy(gs.zev_queue_name.zev_name,
11854ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN);
11864ca7dd5eSAndreas Jaekel gs.zev_queue_name.zev_namelen =
11874ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_namelen;
1188e9a5e479SAndreas Jaekel
1189e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_STATISTICS, &gs)) {
1190e9a5e479SAndreas Jaekel if (errno == ENOENT)
1191e9a5e479SAndreas Jaekel continue;
1192e9a5e479SAndreas Jaekel perror("getting statistics data failed");
1193e9a5e479SAndreas Jaekel return (EXIT_FAILURE);
1194e9a5e479SAndreas Jaekel }
1195e9a5e479SAndreas Jaekel
1196662d8e03SAndreas Jaekel if (gqp.zev_max_queue_len == 0) {
1197662d8e03SAndreas Jaekel gqp.zev_max_queue_len = zs.zev_max_queue_len;
1198662d8e03SAndreas Jaekel }
1199662d8e03SAndreas Jaekel printf("%-40s %-10" PRIu64 " %5.1f %-10" PRIu64
1200e9a5e479SAndreas Jaekel " %-3s %-3s\n",
1201e9a5e479SAndreas Jaekel name,
1202662d8e03SAndreas Jaekel gs.zev_statistics.zev_queue_len * 100.0 /
1203662d8e03SAndreas Jaekel gqp.zev_max_queue_len,
1204e9a5e479SAndreas Jaekel gs.zev_statistics.zev_queue_len,
1205e9a5e479SAndreas Jaekel gqp.zev_max_queue_len,
1206e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no",
1207e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ?
1208e9a5e479SAndreas Jaekel "yes" : "no");
1209e9a5e479SAndreas Jaekel }
1210e9a5e479SAndreas Jaekel
1211e9a5e479SAndreas Jaekel return (0);
1212e9a5e479SAndreas Jaekel }
1213e9a5e479SAndreas Jaekel
1214b9710123SAndreas Jaekel static int
zev_checksum(int dev_fd,char * filename)1215b9710123SAndreas Jaekel zev_checksum(int dev_fd, char *filename)
1216b9710123SAndreas Jaekel {
1217b9710123SAndreas Jaekel int fd;
1218b9710123SAndreas Jaekel offset_t off;
1219b9710123SAndreas Jaekel offset_t data;
1220b9710123SAndreas Jaekel zev_sig_t *sig;
1221b9710123SAndreas Jaekel char *buf;
1222b9710123SAndreas Jaekel zev_ioctl_get_signatures_t *gs;
1223b9710123SAndreas Jaekel int i;
1224b9710123SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1];
1225b9710123SAndreas Jaekel int buf_size;
1226b9710123SAndreas Jaekel
1227b9710123SAndreas Jaekel /* control struct, one lv1 signature and up to 256 lv0 signatures */
1228b9710123SAndreas Jaekel buf_size = (1 + 256) * sizeof(zev_sig_t);
1229b9710123SAndreas Jaekel buf = malloc(sizeof(zev_ioctl_get_signatures_t) + buf_size);
1230b9710123SAndreas Jaekel if (!buf) {
1231b9710123SAndreas Jaekel perror("can't allocate checksum buffer");
1232b9710123SAndreas Jaekel return (EXIT_FAILURE);
1233b9710123SAndreas Jaekel }
1234b9710123SAndreas Jaekel
1235b9710123SAndreas Jaekel fd = open(filename, O_RDONLY);
1236b9710123SAndreas Jaekel if (fd < 0) {
1237b9710123SAndreas Jaekel perror("can't open file");
1238b9710123SAndreas Jaekel return (EXIT_FAILURE);
1239b9710123SAndreas Jaekel }
1240b9710123SAndreas Jaekel
1241b9710123SAndreas Jaekel gs = (zev_ioctl_get_signatures_t *)buf;
1242b9710123SAndreas Jaekel gs->zev_fd = fd;
1243b9710123SAndreas Jaekel gs->zev_bufsize = buf_size;
1244b9710123SAndreas Jaekel
1245b9710123SAndreas Jaekel off = 0;
1246b9710123SAndreas Jaekel data = 0;
1247b9710123SAndreas Jaekel while (1) {
1248b9710123SAndreas Jaekel errno = 0;
1249b9710123SAndreas Jaekel data = llseek(fd, off, SEEK_DATA);
1250b9710123SAndreas Jaekel if (data < 0) {
1251b9710123SAndreas Jaekel if (errno == ENXIO) /* no more data */
1252b9710123SAndreas Jaekel break;
1253b9710123SAndreas Jaekel perror("llseek failed");
1254b9710123SAndreas Jaekel goto err;
1255b9710123SAndreas Jaekel }
1256b9710123SAndreas Jaekel data = P2ALIGN(data, ZEV_L1_SIZE);
1257b9710123SAndreas Jaekel off = data + ZEV_L1_SIZE;
1258b9710123SAndreas Jaekel
1259b9710123SAndreas Jaekel gs->zev_offset = data;
1260b9710123SAndreas Jaekel gs->zev_len = ZEV_L1_SIZE;
1261b9710123SAndreas Jaekel
1262b9710123SAndreas Jaekel if (ioctl(dev_fd, ZEV_IOC_GET_FILE_SIGNATURES, gs)) {
1263b9710123SAndreas Jaekel perror("ioctl to get signatures failed");
1264b9710123SAndreas Jaekel goto err;
1265b9710123SAndreas Jaekel }
1266b9710123SAndreas Jaekel
1267b9710123SAndreas Jaekel for (i=0; i<gs->zev_signature_cnt; i++) {
1268b9710123SAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(gs);
1269b9710123SAndreas Jaekel sig += i;
1270b9710123SAndreas Jaekel sig2hex_direct(sig->value, sigval);
1271b9710123SAndreas Jaekel printf("level %d, offset %llu, value %s\n",
1272b9710123SAndreas Jaekel sig->level, sig->block_offset, sigval);
1273b9710123SAndreas Jaekel }
1274b9710123SAndreas Jaekel }
1275b9710123SAndreas Jaekel
1276b9710123SAndreas Jaekel free(buf);
1277b9710123SAndreas Jaekel close(fd);
1278b9710123SAndreas Jaekel return 0;
1279b9710123SAndreas Jaekel err:
1280b9710123SAndreas Jaekel free(buf);
1281b9710123SAndreas Jaekel close(fd);
1282b9710123SAndreas Jaekel return (EXIT_FAILURE);
1283b9710123SAndreas Jaekel }
1284b9710123SAndreas Jaekel
12850abdde4aSAndreas Jaekel typedef struct zevstat {
12860abdde4aSAndreas Jaekel uint64_t ns_start;
12870abdde4aSAndreas Jaekel uint64_t events[ZEV_OP_MIN + ZEV_OP_MAX];
12880abdde4aSAndreas Jaekel uint64_t guids;
12890abdde4aSAndreas Jaekel uint64_t total_events;
12900abdde4aSAndreas Jaekel uint64_t total_guids;
12910abdde4aSAndreas Jaekel avl_tree_t guids_interval;
12920abdde4aSAndreas Jaekel avl_tree_t guids_runtime;
12930abdde4aSAndreas Jaekel } zevstat_t;
12940abdde4aSAndreas Jaekel
12950abdde4aSAndreas Jaekel typedef struct zev_guidtrack_t {
12960abdde4aSAndreas Jaekel uint64_t guid;
12970abdde4aSAndreas Jaekel avl_node_t avl_interval;
12980abdde4aSAndreas Jaekel avl_node_t avl_runtime;
12990abdde4aSAndreas Jaekel } zev_guidtrack_t;
13000abdde4aSAndreas Jaekel
13010abdde4aSAndreas Jaekel zevstat_t zevstat;
13020abdde4aSAndreas Jaekel
13030abdde4aSAndreas Jaekel static void
zev_eventstat(char * buf,int len)13040abdde4aSAndreas Jaekel zev_eventstat(char *buf, int len)
13050abdde4aSAndreas Jaekel {
13060abdde4aSAndreas Jaekel zev_header_t *rec = (zev_header_t *)buf;
13070abdde4aSAndreas Jaekel zev_guidtrack_t *gt;
13080abdde4aSAndreas Jaekel zev_guidtrack_t *gt_int;
13090abdde4aSAndreas Jaekel zev_guidtrack_t to_find;
13100abdde4aSAndreas Jaekel avl_index_t where;
13110abdde4aSAndreas Jaekel
13120abdde4aSAndreas Jaekel zevstat.total_events++;
13130abdde4aSAndreas Jaekel zevstat.events[rec->op]++;
13140abdde4aSAndreas Jaekel
13150abdde4aSAndreas Jaekel to_find.guid = rec->guid;
13160abdde4aSAndreas Jaekel gt = avl_find(&zevstat.guids_runtime, &to_find, &where);
13170abdde4aSAndreas Jaekel if (!gt) {
13180abdde4aSAndreas Jaekel gt = malloc(sizeof(*gt));
13190abdde4aSAndreas Jaekel if (!gt) {
13200abdde4aSAndreas Jaekel perror("can't get guid tracking record");
13210abdde4aSAndreas Jaekel exit (EXIT_FAILURE);
13220abdde4aSAndreas Jaekel }
13230abdde4aSAndreas Jaekel gt->guid = rec->guid;
13240abdde4aSAndreas Jaekel avl_insert(&zevstat.guids_runtime, gt, where);
13250abdde4aSAndreas Jaekel }
13260abdde4aSAndreas Jaekel gt_int = avl_find(&zevstat.guids_interval, &to_find, &where);
13270abdde4aSAndreas Jaekel if (!gt_int)
13280abdde4aSAndreas Jaekel avl_insert(&zevstat.guids_interval, gt, where);
13290abdde4aSAndreas Jaekel }
13300abdde4aSAndreas Jaekel
13310abdde4aSAndreas Jaekel static void
zev_eventstat_interval(FILE * out)13329fd83c76SAndreas Jaekel zev_eventstat_interval(FILE *out)
13330abdde4aSAndreas Jaekel {
13340abdde4aSAndreas Jaekel uint64_t events;
13350abdde4aSAndreas Jaekel int i;
13360abdde4aSAndreas Jaekel zev_guidtrack_t *gt;
13370abdde4aSAndreas Jaekel
13380abdde4aSAndreas Jaekel events = 0;
13390abdde4aSAndreas Jaekel for (i = ZEV_OP_MIN; i <= ZEV_OP_MAX; i++) {
13400abdde4aSAndreas Jaekel events += zevstat.events[i];
13410abdde4aSAndreas Jaekel }
13420abdde4aSAndreas Jaekel
13430abdde4aSAndreas Jaekel if (verbose) {
13449fd83c76SAndreas Jaekel fprintf(out, "%u %6llu %6llu %6llu %6llu ",
13450abdde4aSAndreas Jaekel time(NULL),
13460abdde4aSAndreas Jaekel events,
13470abdde4aSAndreas Jaekel zevstat.total_events,
13480abdde4aSAndreas Jaekel avl_numnodes(&zevstat.guids_interval),
13490abdde4aSAndreas Jaekel avl_numnodes(&zevstat.guids_runtime));
13500abdde4aSAndreas Jaekel for (i = ZEV_OP_MIN; i <= ZEV_OP_MAX; i++)
13519fd83c76SAndreas Jaekel fprintf(out, "%6llu ", zevstat.events[i]);
13529fd83c76SAndreas Jaekel fprintf(out, "\n");
13530abdde4aSAndreas Jaekel } else {
13549fd83c76SAndreas Jaekel fprintf(out, "%u %6llu %6llu %6llu %6llu\n",
13550abdde4aSAndreas Jaekel time(NULL),
13560abdde4aSAndreas Jaekel events,
13570abdde4aSAndreas Jaekel zevstat.total_events,
13580abdde4aSAndreas Jaekel avl_numnodes(&zevstat.guids_interval),
13590abdde4aSAndreas Jaekel avl_numnodes(&zevstat.guids_runtime));
13600abdde4aSAndreas Jaekel }
13610abdde4aSAndreas Jaekel memset(&zevstat.events, 0, sizeof(zevstat.events));
13620abdde4aSAndreas Jaekel zevstat.guids = 0;
13630abdde4aSAndreas Jaekel while (gt = avl_first(&zevstat.guids_interval))
13640abdde4aSAndreas Jaekel avl_remove(&zevstat.guids_interval, gt);
13659fd83c76SAndreas Jaekel fflush(out);
13660abdde4aSAndreas Jaekel }
13670abdde4aSAndreas Jaekel
13680abdde4aSAndreas Jaekel static int
zev_evcompar(const void * a,const void * b)13690abdde4aSAndreas Jaekel zev_evcompar(const void *a, const void *b)
13700abdde4aSAndreas Jaekel {
13710abdde4aSAndreas Jaekel const zev_guidtrack_t *ga = a;
13720abdde4aSAndreas Jaekel const zev_guidtrack_t *gb = b;
13730abdde4aSAndreas Jaekel
13740abdde4aSAndreas Jaekel if (ga->guid > gb->guid)
13750abdde4aSAndreas Jaekel return 1;
13760abdde4aSAndreas Jaekel if (ga->guid < gb->guid)
13770abdde4aSAndreas Jaekel return -1;
13780abdde4aSAndreas Jaekel return 0;
13790abdde4aSAndreas Jaekel }
13800abdde4aSAndreas Jaekel
13810abdde4aSAndreas Jaekel static int
zev_zevstat(int fd,char * s_interval,char * s_count,char * outfile)13829fd83c76SAndreas Jaekel zev_zevstat(int fd, char *s_interval, char *s_count, char *outfile)
13830abdde4aSAndreas Jaekel {
13840abdde4aSAndreas Jaekel uint64_t interval = 1000;
13850abdde4aSAndreas Jaekel uint64_t ms;
13860abdde4aSAndreas Jaekel uint64_t t_until;
13870abdde4aSAndreas Jaekel uint64_t t_now;
13880abdde4aSAndreas Jaekel int cnt = -1;
13890abdde4aSAndreas Jaekel struct pollfd pfd[1];
13900abdde4aSAndreas Jaekel int ret;
13910abdde4aSAndreas Jaekel char buf[4096];
13920abdde4aSAndreas Jaekel zev_event_t *ev;
13930abdde4aSAndreas Jaekel int off = 0;
13940abdde4aSAndreas Jaekel zev_ioctl_add_queue_t aq;
13950abdde4aSAndreas Jaekel int q_fd;
13960abdde4aSAndreas Jaekel zev_guidtrack_t *gt;
13979fd83c76SAndreas Jaekel FILE *out = stdout;
13989fd83c76SAndreas Jaekel struct stat st;
13999fd83c76SAndreas Jaekel char filename[MAXPATHLEN];
14009fd83c76SAndreas Jaekel int retry;
14019fd83c76SAndreas Jaekel
14029fd83c76SAndreas Jaekel if (outfile) {
14039fd83c76SAndreas Jaekel retry = 0;
14049fd83c76SAndreas Jaekel strncpy(filename, outfile, sizeof(filename));
14059fd83c76SAndreas Jaekel while (stat(filename, &st) == 0) {
14069fd83c76SAndreas Jaekel /* file exists */
14079fd83c76SAndreas Jaekel snprintf(filename, sizeof(filename),
14089fd83c76SAndreas Jaekel "%s.%d", outfile, retry);
14099fd83c76SAndreas Jaekel retry++;
14109fd83c76SAndreas Jaekel }
14119fd83c76SAndreas Jaekel out = fopen(filename, "wb+");
14129fd83c76SAndreas Jaekel if (!out) {
14139fd83c76SAndreas Jaekel perror("opening output file failed");
14149fd83c76SAndreas Jaekel return (EXIT_FAILURE);
14159fd83c76SAndreas Jaekel }
14169fd83c76SAndreas Jaekel }
14170abdde4aSAndreas Jaekel
14180abdde4aSAndreas Jaekel memset(&zevstat, 0, sizeof(zevstat));
14190abdde4aSAndreas Jaekel avl_create(&zevstat.guids_runtime, zev_evcompar,
14200abdde4aSAndreas Jaekel sizeof(zev_guidtrack_t),
14210abdde4aSAndreas Jaekel offsetof(zev_guidtrack_t, avl_runtime));
14220abdde4aSAndreas Jaekel avl_create(&zevstat.guids_interval, zev_evcompar,
14230abdde4aSAndreas Jaekel sizeof(zev_guidtrack_t),
14240abdde4aSAndreas Jaekel offsetof(zev_guidtrack_t, avl_interval));
14250abdde4aSAndreas Jaekel
1426ddaa5fcfSAndreas Jaekel if (s_interval) {
14270abdde4aSAndreas Jaekel interval = atol(s_interval);
14280abdde4aSAndreas Jaekel if (interval == 0) {
14290abdde4aSAndreas Jaekel fprintf(stderr, "invalid interval.\n");
14300abdde4aSAndreas Jaekel return (EXIT_FAILURE);
14310abdde4aSAndreas Jaekel }
14320abdde4aSAndreas Jaekel interval *= 1000;
1433ddaa5fcfSAndreas Jaekel }
14340abdde4aSAndreas Jaekel if (s_count) {
14350abdde4aSAndreas Jaekel cnt = atol(s_count);
14360abdde4aSAndreas Jaekel if (interval == 0) {
14370abdde4aSAndreas Jaekel fprintf(stderr, "invalid count.\n");
14380abdde4aSAndreas Jaekel return (EXIT_FAILURE);
14390abdde4aSAndreas Jaekel }
14400abdde4aSAndreas Jaekel }
14410abdde4aSAndreas Jaekel
14420abdde4aSAndreas Jaekel aq.zev_max_queue_len = 1024 * 1024;
1443b434d29cSAndreas Jaekel aq.zev_flags = ZEV_FL_INITIALLY_EMPTY;
14440abdde4aSAndreas Jaekel snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN,
14450abdde4aSAndreas Jaekel "zevstat.%ld.%ld", time(NULL), getpid());
14460abdde4aSAndreas Jaekel aq.zev_namelen = strlen(aq.zev_name);
14470abdde4aSAndreas Jaekel
14480abdde4aSAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) {
14490abdde4aSAndreas Jaekel perror("adding temporary queue failed");
14500abdde4aSAndreas Jaekel return (EXIT_FAILURE);
14510abdde4aSAndreas Jaekel }
14520abdde4aSAndreas Jaekel
14530abdde4aSAndreas Jaekel snprintf(buf, sizeof(buf),
14540abdde4aSAndreas Jaekel "/devices/pseudo/zev@0:%s", aq.zev_name);
14550abdde4aSAndreas Jaekel q_fd = open(buf, O_RDONLY);
14560abdde4aSAndreas Jaekel if (q_fd < 0) {
14570abdde4aSAndreas Jaekel perror("opening queue device failed");
14580abdde4aSAndreas Jaekel return (EXIT_FAILURE);
14590abdde4aSAndreas Jaekel }
14600abdde4aSAndreas Jaekel
14610abdde4aSAndreas Jaekel pfd[0].fd = q_fd;
14620abdde4aSAndreas Jaekel pfd[0].events = POLLIN;
14630abdde4aSAndreas Jaekel
14640abdde4aSAndreas Jaekel /* drain queue */
1465ddaa5fcfSAndreas Jaekel while ((ret = poll(pfd, 1, 0)) > 0) {
14660abdde4aSAndreas Jaekel if (read(q_fd, buf, sizeof(buf)) < 0) {
14670abdde4aSAndreas Jaekel perror("read failed");
14680abdde4aSAndreas Jaekel close(q_fd);
14690abdde4aSAndreas Jaekel return(EXIT_FAILURE);
14700abdde4aSAndreas Jaekel }
14710abdde4aSAndreas Jaekel }
14720abdde4aSAndreas Jaekel if (ret < 0) {
14730abdde4aSAndreas Jaekel perror("poll failed");
14740abdde4aSAndreas Jaekel close(q_fd);
14750abdde4aSAndreas Jaekel return(EXIT_FAILURE);
14760abdde4aSAndreas Jaekel }
14770abdde4aSAndreas Jaekel
14789fd83c76SAndreas Jaekel fprintf(out, "timestamp events tevents guids tguids");
14790abdde4aSAndreas Jaekel if (verbose) {
14809fd83c76SAndreas Jaekel fprintf(out, " error mark mount umount zvol_w ");
14819fd83c76SAndreas Jaekel fprintf(out, "zvol_t close create mkdir mxattr ");
14829fd83c76SAndreas Jaekel fprintf(out, "remove rmdir link symlnk rename ");
14839fd83c76SAndreas Jaekel fprintf(out, "write trunc setatt acl");
14840abdde4aSAndreas Jaekel }
14859fd83c76SAndreas Jaekel fprintf(out, "\n");
14860abdde4aSAndreas Jaekel while (cnt) {
14870abdde4aSAndreas Jaekel t_until = gethrtime() + (interval * 1000000);
14880abdde4aSAndreas Jaekel ms = interval;
14890abdde4aSAndreas Jaekel do {
14900abdde4aSAndreas Jaekel ret = poll(pfd, 1, ms);
14910abdde4aSAndreas Jaekel t_now = gethrtime();
14920abdde4aSAndreas Jaekel if (t_now < t_until) {
14930abdde4aSAndreas Jaekel ms = t_until - t_now;
14940abdde4aSAndreas Jaekel ms /= 1000000ull;
14950abdde4aSAndreas Jaekel }
14960abdde4aSAndreas Jaekel if (ret < 0) {
14970abdde4aSAndreas Jaekel perror("poll failed");
14980abdde4aSAndreas Jaekel close(q_fd);
14990abdde4aSAndreas Jaekel return(EXIT_FAILURE);
15000abdde4aSAndreas Jaekel }
15010abdde4aSAndreas Jaekel if (!(pfd[0].revents & POLLIN))
15020abdde4aSAndreas Jaekel continue;
15030abdde4aSAndreas Jaekel /* data available */
15040abdde4aSAndreas Jaekel ret = read(q_fd, buf, sizeof(buf));
15050abdde4aSAndreas Jaekel if (ret < 0) {
15060abdde4aSAndreas Jaekel perror("read failed");
15070abdde4aSAndreas Jaekel close(q_fd);
15080abdde4aSAndreas Jaekel return(EXIT_FAILURE);
15090abdde4aSAndreas Jaekel }
15100abdde4aSAndreas Jaekel if (ret == 0)
15110abdde4aSAndreas Jaekel continue;
15120abdde4aSAndreas Jaekel while (ret > off) {
15130abdde4aSAndreas Jaekel ev = (zev_event_t *)(buf + off);
15140abdde4aSAndreas Jaekel zev_eventstat(buf + off, ev->header.record_len);
15150abdde4aSAndreas Jaekel off += ev->header.record_len;
15160abdde4aSAndreas Jaekel }
15170abdde4aSAndreas Jaekel off = 0;
15180abdde4aSAndreas Jaekel } while ((t_now) < t_until && (ms > 0));
15199fd83c76SAndreas Jaekel zev_eventstat_interval(out);
15200abdde4aSAndreas Jaekel if (cnt > 0)
15210abdde4aSAndreas Jaekel cnt--;
15220abdde4aSAndreas Jaekel }
15230abdde4aSAndreas Jaekel close(q_fd);
15249fd83c76SAndreas Jaekel if (outfile)
15259fd83c76SAndreas Jaekel fclose(out);
15260abdde4aSAndreas Jaekel while (gt = avl_first(&zevstat.guids_interval))
15270abdde4aSAndreas Jaekel avl_remove(&zevstat.guids_interval, gt);
15280abdde4aSAndreas Jaekel while (gt = avl_first(&zevstat.guids_runtime)) {
15290abdde4aSAndreas Jaekel avl_remove(&zevstat.guids_runtime, gt);
15300abdde4aSAndreas Jaekel free(gt);
15310abdde4aSAndreas Jaekel }
15320abdde4aSAndreas Jaekel return EXIT_SUCCESS;
15330abdde4aSAndreas Jaekel }
15340abdde4aSAndreas Jaekel
15359fd83c76SAndreas Jaekel static int
zev_report(int fd,char * basename)15369fd83c76SAndreas Jaekel zev_report(int fd, char *basename)
15379fd83c76SAndreas Jaekel {
15389fd83c76SAndreas Jaekel char filename[MAXPATHLEN];
15399fd83c76SAndreas Jaekel char count[10];
15409fd83c76SAndreas Jaekel time_t now;
15419fd83c76SAndreas Jaekel time_t midnight;
15429fd83c76SAndreas Jaekel struct tm tm;
15439fd83c76SAndreas Jaekel int minutes;
15449fd83c76SAndreas Jaekel int ret;
15459fd83c76SAndreas Jaekel
15469fd83c76SAndreas Jaekel verbose++;
15479fd83c76SAndreas Jaekel while (1) {
15489fd83c76SAndreas Jaekel now = time(NULL);
15499fd83c76SAndreas Jaekel localtime_r(&now, &tm);
15509fd83c76SAndreas Jaekel snprintf(filename, sizeof(filename), "%s.%04d-%02d-%02d",
15519fd83c76SAndreas Jaekel basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
15529fd83c76SAndreas Jaekel tm.tm_sec = 0;
15539fd83c76SAndreas Jaekel tm.tm_min = 0;
15549fd83c76SAndreas Jaekel tm.tm_hour = 0;
15559fd83c76SAndreas Jaekel tm.tm_mday++; /* works for Jan 32nd, Feb 30th, etc. */
15569fd83c76SAndreas Jaekel midnight = mktime(&tm);
15579fd83c76SAndreas Jaekel if (now % 60)
15589fd83c76SAndreas Jaekel sleep(60 - (now % 60));
15599fd83c76SAndreas Jaekel minutes = (midnight - time(NULL)) / 60;
15609fd83c76SAndreas Jaekel snprintf(count, sizeof(count), "%d", minutes);
15619fd83c76SAndreas Jaekel ret = zev_zevstat(fd, "60", count, filename);
15629fd83c76SAndreas Jaekel if (ret)
15639fd83c76SAndreas Jaekel return EXIT_FAILURE;
15649fd83c76SAndreas Jaekel }
15659fd83c76SAndreas Jaekel return EXIT_SUCCESS; /* never reached */
15669fd83c76SAndreas Jaekel }
15679fd83c76SAndreas Jaekel
1568c62d8367SAndreas Jaekel static int
zev_get_zev_version(int fd)1569c62d8367SAndreas Jaekel zev_get_zev_version(int fd)
1570c62d8367SAndreas Jaekel {
1571c62d8367SAndreas Jaekel zev_ioctl_get_zev_version vi;
1572c62d8367SAndreas Jaekel
1573c62d8367SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_ZEV_VERSION, &vi)) {
1574c62d8367SAndreas Jaekel perror("getting zev cersion info failed");
1575c62d8367SAndreas Jaekel return (EXIT_FAILURE);
1576c62d8367SAndreas Jaekel }
1577c62d8367SAndreas Jaekel
1578c62d8367SAndreas Jaekel printf("zev major version: %llu\n", vi.zev_major_version);
1579c62d8367SAndreas Jaekel printf("zev minor version: %llu\n", vi.zev_minor_version);
1580c62d8367SAndreas Jaekel return 0;
1581c62d8367SAndreas Jaekel }
1582c62d8367SAndreas Jaekel
1583c69e8453SAndreas Jaekel static void
zev_sigint(int sig)1584c69e8453SAndreas Jaekel zev_sigint(int sig)
1585c69e8453SAndreas Jaekel {
1586c69e8453SAndreas Jaekel fflush(stdout);
1587c69e8453SAndreas Jaekel }
1588c69e8453SAndreas Jaekel
15892bb8e5e2SAndreas Jaekel int
main(int argc,char ** argv)15902bb8e5e2SAndreas Jaekel main(int argc, char **argv)
15912bb8e5e2SAndreas Jaekel {
15922bb8e5e2SAndreas Jaekel int fd;
15932bb8e5e2SAndreas Jaekel int c;
15942bb8e5e2SAndreas Jaekel extern char *optarg;
15954ca7dd5eSAndreas Jaekel int create_tmp_queue = 1;
15964ca7dd5eSAndreas Jaekel char buf[MAXPATHLEN];
15976a3d43bfSAndreas Jaekel int mode = 0;
15986a3d43bfSAndreas Jaekel char *arg = NULL;
15996a3d43bfSAndreas Jaekel char *arg2 = NULL;
16000abdde4aSAndreas Jaekel char *p;
16010abdde4aSAndreas Jaekel
1602c69e8453SAndreas Jaekel sigset(SIGINT, zev_sigint);
1603c69e8453SAndreas Jaekel
160429fab2f9SAndreas Jaekel /* open device */
160529fab2f9SAndreas Jaekel fd = open(zev_device, O_RDONLY);
160629fab2f9SAndreas Jaekel if (fd < 0) {
160729fab2f9SAndreas Jaekel perror("opening zev device failed");
160829fab2f9SAndreas Jaekel return EXIT_FAILURE;
160929fab2f9SAndreas Jaekel }
161029fab2f9SAndreas Jaekel
16110abdde4aSAndreas Jaekel p = strrchr(argv[0], '/');
16120abdde4aSAndreas Jaekel if (!p) {
16130abdde4aSAndreas Jaekel p = argv[0];
16140abdde4aSAndreas Jaekel } else {
16150abdde4aSAndreas Jaekel p++;
16160abdde4aSAndreas Jaekel }
16170abdde4aSAndreas Jaekel if (!strcmp(p, "zevstat")) {
16180abdde4aSAndreas Jaekel mode = MD_ZEVSTAT;
161929fab2f9SAndreas Jaekel if (argc < 2)
162029fab2f9SAndreas Jaekel zevstat_usage(argv[0]);
162129fab2f9SAndreas Jaekel if (!strcmp(argv[1], "-v")) {
162229fab2f9SAndreas Jaekel if (argc < 3)
162329fab2f9SAndreas Jaekel zevstat_usage(argv[0]);
162429fab2f9SAndreas Jaekel verbose++;
162529fab2f9SAndreas Jaekel arg = argv[2];
162629fab2f9SAndreas Jaekel arg2 = argv[3];
162729fab2f9SAndreas Jaekel } else {
162829fab2f9SAndreas Jaekel arg = argv[1];
162929fab2f9SAndreas Jaekel arg2 = argv[2];
163029fab2f9SAndreas Jaekel }
16319fd83c76SAndreas Jaekel return zev_zevstat(fd, arg, arg2, NULL);
16329fd83c76SAndreas Jaekel } else if(!strcmp(p, "zevreport")) {
16339fd83c76SAndreas Jaekel mode = MD_ZEV_REPORT;
16349fd83c76SAndreas Jaekel if (argc != 2)
16359fd83c76SAndreas Jaekel zevreport_usage(argv[0]);
16369fd83c76SAndreas Jaekel return zev_report(fd, argv[1]);
16370abdde4aSAndreas Jaekel }
16382bb8e5e2SAndreas Jaekel
16394ca7dd5eSAndreas Jaekel while ((c = getopt(argc, argv,
1640*0f07b41bSArne Jansen "a:A:b:B:c:d:Df:FgG:hk:lL:m:M:pP:q:Q:r:R:st:T:vV?")) != -1) {
16412bb8e5e2SAndreas Jaekel switch(c) {
1642d65b2fffSAndreas Jaekel case 'g':
1643d65b2fffSAndreas Jaekel grep_friendly++;
1644d65b2fffSAndreas Jaekel verbose++;
1645d65b2fffSAndreas Jaekel break;
16465e286361SAndreas Jaekel case 'v':
16475e286361SAndreas Jaekel verbose++;
16485e286361SAndreas Jaekel break;
16492bb8e5e2SAndreas Jaekel case 's':
16506a3d43bfSAndreas Jaekel mode = MD_STATISTICS;
16516a3d43bfSAndreas Jaekel break;
16522bb8e5e2SAndreas Jaekel case 'p':
16536a3d43bfSAndreas Jaekel mode = MD_POLL_EVENTS;
16546a3d43bfSAndreas Jaekel break;
1655b9710123SAndreas Jaekel case 'c':
16566a3d43bfSAndreas Jaekel mode = MD_CHECKSUMS;
16576a3d43bfSAndreas Jaekel arg = optarg;
16586a3d43bfSAndreas Jaekel break;
1659e9a5e479SAndreas Jaekel case 'D':
16606a3d43bfSAndreas Jaekel mode = MD_DEBUG_INFO;
16616a3d43bfSAndreas Jaekel break;
16622bb8e5e2SAndreas Jaekel case 'd':
1663e9a5e479SAndreas Jaekel close(fd);
16642bb8e5e2SAndreas Jaekel zev_device = optarg;
1665e9a5e479SAndreas Jaekel fd = open(zev_device, O_RDONLY);
1666e9a5e479SAndreas Jaekel if (fd < 0) {
1667e9a5e479SAndreas Jaekel perror("opening zev device failed");
1668e9a5e479SAndreas Jaekel return EXIT_FAILURE;
1669e9a5e479SAndreas Jaekel }
16704ca7dd5eSAndreas Jaekel create_tmp_queue = 0;
16714ca7dd5eSAndreas Jaekel break;
16724ca7dd5eSAndreas Jaekel case 'q':
16734ca7dd5eSAndreas Jaekel snprintf(buf, sizeof(buf),
16744ca7dd5eSAndreas Jaekel "/devices/pseudo/zev@0:%s", optarg);
16754ca7dd5eSAndreas Jaekel close(fd);
16764ca7dd5eSAndreas Jaekel zev_device = buf;
16774ca7dd5eSAndreas Jaekel fd = open(zev_device, O_RDONLY);
16784ca7dd5eSAndreas Jaekel if (fd < 0) {
16794ca7dd5eSAndreas Jaekel perror("opening zev device failed");
16804ca7dd5eSAndreas Jaekel return EXIT_FAILURE;
16814ca7dd5eSAndreas Jaekel }
16824ca7dd5eSAndreas Jaekel create_tmp_queue = 0;
16832bb8e5e2SAndreas Jaekel break;
1684797b8adfSArne Jansen case 'f':
1685797b8adfSArne Jansen fd = open(optarg, O_RDONLY);
1686797b8adfSArne Jansen if (fd < 0) {
1687797b8adfSArne Jansen perror("opening spool file failed");
1688797b8adfSArne Jansen return EXIT_FAILURE;
1689797b8adfSArne Jansen }
1690797b8adfSArne Jansen mode = MD_DUMP_SPOOL;
1691797b8adfSArne Jansen break;
1692e9a5e479SAndreas Jaekel case 'l':
16936a3d43bfSAndreas Jaekel mode = MD_LIST_QUEUES;
16946a3d43bfSAndreas Jaekel break;
1695e9a5e479SAndreas Jaekel case 'Q':
16966a3d43bfSAndreas Jaekel mode = MD_SET_GLOBAL_MAX_QUEUE_LEN;
16976a3d43bfSAndreas Jaekel arg = optarg;
16986a3d43bfSAndreas Jaekel break;
16994ca7dd5eSAndreas Jaekel case 'L':
17006a3d43bfSAndreas Jaekel mode = MD_SET_MAX_QUEUE_LEN;
17016a3d43bfSAndreas Jaekel arg = optarg;
17026a3d43bfSAndreas Jaekel arg2 = argv[optind];
17036a3d43bfSAndreas Jaekel break;
17040abdde4aSAndreas Jaekel case 'T':
17050abdde4aSAndreas Jaekel mode = MD_ZEVSTAT;
17060abdde4aSAndreas Jaekel arg = optarg;
17070abdde4aSAndreas Jaekel arg2 = argv[optind];
17080abdde4aSAndreas Jaekel break;
17099fd83c76SAndreas Jaekel case 'R':
17109fd83c76SAndreas Jaekel mode = MD_ZEV_REPORT;
17119fd83c76SAndreas Jaekel arg = optarg;
17129fd83c76SAndreas Jaekel break;
1713205a9bc9SAndreas Jaekel case 't':
17146a3d43bfSAndreas Jaekel mode = MD_SET_POLL_WAKEUP_QUEUE_LEN;
17156a3d43bfSAndreas Jaekel arg = optarg;
17166a3d43bfSAndreas Jaekel arg2 = argv[optind];
17176a3d43bfSAndreas Jaekel break;
17182bb8e5e2SAndreas Jaekel case 'm':
17196a3d43bfSAndreas Jaekel mode = MD_MUTE_POOL;
17206a3d43bfSAndreas Jaekel arg = optarg;
17216a3d43bfSAndreas Jaekel break;
17222bb8e5e2SAndreas Jaekel case 'M':
17236a3d43bfSAndreas Jaekel mode = MD_UNMUTE_POOL;
17246a3d43bfSAndreas Jaekel arg = optarg;
17256a3d43bfSAndreas Jaekel break;
172601c2c787SAndreas Jaekel case 'k':
17276a3d43bfSAndreas Jaekel mode = MD_MARK;
17286a3d43bfSAndreas Jaekel arg = optarg;
17296a3d43bfSAndreas Jaekel break;
1730e9a5e479SAndreas Jaekel case 'a':
17316a3d43bfSAndreas Jaekel mode = MD_ADD_QUEUE;
17326a3d43bfSAndreas Jaekel arg = optarg;
17336a3d43bfSAndreas Jaekel break;
17344ca7dd5eSAndreas Jaekel case 'A':
17356a3d43bfSAndreas Jaekel mode = MD_ADD_BLOCKING_QUEUE;
17366a3d43bfSAndreas Jaekel arg = optarg;
17376a3d43bfSAndreas Jaekel break;
1738e9a5e479SAndreas Jaekel case 'r':
17396a3d43bfSAndreas Jaekel mode = MD_REMOVE_QUEUE;
17406a3d43bfSAndreas Jaekel arg = optarg;
17416a3d43bfSAndreas Jaekel break;
1742e9a5e479SAndreas Jaekel case 'b':
17436a3d43bfSAndreas Jaekel mode = MD_QUEUE_BLOCKING;
17446a3d43bfSAndreas Jaekel arg = optarg;
17456a3d43bfSAndreas Jaekel break;
1746e9a5e479SAndreas Jaekel case 'B':
17476a3d43bfSAndreas Jaekel mode = MD_QUEUE_NONBLOCKING;
17486a3d43bfSAndreas Jaekel arg = optarg;
17496a3d43bfSAndreas Jaekel break;
1750e9a5e479SAndreas Jaekel case 'P':
17516a3d43bfSAndreas Jaekel mode = MD_QUEUE_PROPERTIES;
17526a3d43bfSAndreas Jaekel arg = optarg;
17536a3d43bfSAndreas Jaekel break;
1754*0f07b41bSArne Jansen case 'G':
1755*0f07b41bSArne Jansen if (num_guid_filter == MAX_GUID) {
1756*0f07b41bSArne Jansen fprintf(stderr,
1757*0f07b41bSArne Jansen "too many guids given, max is %d\n", MAX_GUID);
1758*0f07b41bSArne Jansen exit(1);
1759*0f07b41bSArne Jansen }
1760*0f07b41bSArne Jansen guid_filter[num_guid_filter++] = atoll(optarg);
1761*0f07b41bSArne Jansen break;
1762c62d8367SAndreas Jaekel case 'V':
1763c62d8367SAndreas Jaekel mode = MD_GET_ZEV_VERSION;
1764c62d8367SAndreas Jaekel break;
1765c07f6d81SArne Jansen case 'F':
1766c07f6d81SArne Jansen do_flush = 1;
1767c07f6d81SArne Jansen break;
17682bb8e5e2SAndreas Jaekel case 'h':
17692bb8e5e2SAndreas Jaekel case '?':
17702bb8e5e2SAndreas Jaekel default:
17712bb8e5e2SAndreas Jaekel usage(argv[0]);
17722bb8e5e2SAndreas Jaekel }
17732bb8e5e2SAndreas Jaekel }
17746a3d43bfSAndreas Jaekel
17756a3d43bfSAndreas Jaekel switch (mode) {
17766a3d43bfSAndreas Jaekel case MD_STATISTICS:
17776a3d43bfSAndreas Jaekel return zev_statistics(fd);
17786a3d43bfSAndreas Jaekel case MD_POLL_EVENTS:
1779bfe96c74SAndreas Jaekel return zev_poll_events(fd, create_tmp_queue);
1780797b8adfSArne Jansen case MD_DUMP_SPOOL:
1781797b8adfSArne Jansen return zev_dump_spool(fd);
17826a3d43bfSAndreas Jaekel case MD_CHECKSUMS:
17836a3d43bfSAndreas Jaekel return zev_checksum(fd, arg);
17846a3d43bfSAndreas Jaekel case MD_DEBUG_INFO:
17856a3d43bfSAndreas Jaekel return zev_debug_info(fd);
17866a3d43bfSAndreas Jaekel case MD_LIST_QUEUES:
17876a3d43bfSAndreas Jaekel return zev_list_queues(fd);
17886a3d43bfSAndreas Jaekel case MD_SET_GLOBAL_MAX_QUEUE_LEN:
17896a3d43bfSAndreas Jaekel return zev_set_global_max_queue_len(fd, arg);
17906a3d43bfSAndreas Jaekel case MD_SET_MAX_QUEUE_LEN:
17916a3d43bfSAndreas Jaekel return zev_set_max_queue_len(fd, arg, arg2);
17926a3d43bfSAndreas Jaekel case MD_SET_POLL_WAKEUP_QUEUE_LEN:
17936a3d43bfSAndreas Jaekel return zev_set_poll_wakeup_queue_len(fd, arg, arg2);
17940abdde4aSAndreas Jaekel case MD_ZEVSTAT:
17959fd83c76SAndreas Jaekel return zev_zevstat(fd, arg, arg2, NULL);
17969fd83c76SAndreas Jaekel case MD_ZEV_REPORT:
17979fd83c76SAndreas Jaekel return zev_report(fd, arg);
17986a3d43bfSAndreas Jaekel case MD_MUTE_POOL:
17996a3d43bfSAndreas Jaekel return zev_mute_pool(fd, arg);
18006a3d43bfSAndreas Jaekel case MD_UNMUTE_POOL:
18016a3d43bfSAndreas Jaekel return zev_unmute_pool(fd, arg);
18026a3d43bfSAndreas Jaekel case MD_MARK:
18036a3d43bfSAndreas Jaekel return zev_mark(fd, arg);
18046a3d43bfSAndreas Jaekel case MD_ADD_QUEUE:
18056a3d43bfSAndreas Jaekel return zev_add_queue(fd, arg, 0);
18066a3d43bfSAndreas Jaekel case MD_ADD_BLOCKING_QUEUE:
18076a3d43bfSAndreas Jaekel return zev_add_queue(fd, arg, 1);
18086a3d43bfSAndreas Jaekel case MD_REMOVE_QUEUE:
18096a3d43bfSAndreas Jaekel return zev_remove_queue(fd, arg);
18106a3d43bfSAndreas Jaekel case MD_QUEUE_BLOCKING:
18116a3d43bfSAndreas Jaekel return zev_queue_blocking(fd, arg, 0);
18126a3d43bfSAndreas Jaekel case MD_QUEUE_NONBLOCKING:
18136a3d43bfSAndreas Jaekel return zev_queue_blocking(fd, arg, 1);
18146a3d43bfSAndreas Jaekel case MD_QUEUE_PROPERTIES:
18156a3d43bfSAndreas Jaekel return zev_queue_properties(fd, arg);
1816c62d8367SAndreas Jaekel case MD_GET_ZEV_VERSION:
1817c62d8367SAndreas Jaekel return zev_get_zev_version(fd);
18186a3d43bfSAndreas Jaekel default:
18192bb8e5e2SAndreas Jaekel close(fd);
18206a3d43bfSAndreas Jaekel usage(argv[0]);
1821e9a5e479SAndreas Jaekel return EXIT_FAILURE;
18226a3d43bfSAndreas Jaekel };
18232bb8e5e2SAndreas Jaekel }
18242bb8e5e2SAndreas Jaekel
1825