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