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 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 92d65b2fffSAndreas Jaekel znl(void) 93d65b2fffSAndreas Jaekel { 94d65b2fffSAndreas Jaekel if (grep_friendly) 95d65b2fffSAndreas Jaekel printf("\n"); 96d65b2fffSAndreas Jaekel } 975e286361SAndreas Jaekel 981ca5a13bSAndreas Jaekel static void 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1584c69e8453SAndreas Jaekel zev_sigint(int sig) 1585c69e8453SAndreas Jaekel { 1586c69e8453SAndreas Jaekel fflush(stdout); 1587c69e8453SAndreas Jaekel } 1588c69e8453SAndreas Jaekel 15892bb8e5e2SAndreas Jaekel int 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