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> 10*b9710123SAndreas Jaekel #include <sys/sysmacros.h> 112bb8e5e2SAndreas Jaekel 12e9a5e479SAndreas Jaekel #define ZEV_DEVICE "/devices/pseudo/zev@0:ctrl" 132bb8e5e2SAndreas Jaekel 142bb8e5e2SAndreas Jaekel static char *zev_device = ZEV_DEVICE; 152bb8e5e2SAndreas Jaekel 169193e9c2SAndreas Jaekel static char *zev_op_name[] = { 179193e9c2SAndreas Jaekel "ZEV_OP_ERROR", 1801c2c787SAndreas Jaekel "ZEV_OP_MARK", 199193e9c2SAndreas Jaekel "ZEV_OP_ZFS_MOUNT", 209193e9c2SAndreas Jaekel "ZEV_OP_ZFS_UMOUNT", 219193e9c2SAndreas Jaekel "ZEV_OP_ZVOL_WRITE", 229193e9c2SAndreas Jaekel "ZEV_OP_ZVOL_TRUNCATE", 239193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE", 249193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_CREATE", 259193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_MKDIR", 269193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_MAKE_XATTR_DIR", 279193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_REMOVE", 289193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_RMDIR", 299193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_LINK", 309193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_SYMLINK", 319193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_RENAME", 329193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_WRITE", 339193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_TRUNCATE", 349193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_SETATTR", 359193e9c2SAndreas Jaekel "ZEV_OP_ZNODE_ACL", 369193e9c2SAndreas Jaekel NULL 379193e9c2SAndreas Jaekel }; 389193e9c2SAndreas Jaekel 395e286361SAndreas Jaekel static int verbose = 0; 405e286361SAndreas Jaekel 41e9a5e479SAndreas Jaekel static int 422bb8e5e2SAndreas Jaekel zev_statistics(int fd) 432bb8e5e2SAndreas Jaekel { 442bb8e5e2SAndreas Jaekel zev_statistics_t zs; 45e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) { 462bb8e5e2SAndreas Jaekel perror("getting statistics data failed"); 47e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 482bb8e5e2SAndreas Jaekel } 492bb8e5e2SAndreas Jaekel printf("ZEV module state:\n"); 502bb8e5e2SAndreas Jaekel 512bb8e5e2SAndreas Jaekel printf(" queue length in bytes : %lu\n", zs.zev_queue_len); 522bb8e5e2SAndreas Jaekel printf(" queue length limit : %lu\n", zs.zev_max_queue_len); 532bb8e5e2SAndreas Jaekel printf(" bytes read from device : %lu\n", zs.zev_bytes_read); 542bb8e5e2SAndreas Jaekel printf(" module internal errors : %lu\n\n", zs.zev_cnt_errors); 552bb8e5e2SAndreas Jaekel 56e9a5e479SAndreas Jaekel printf(" discarded events : %lu\n", 57e9a5e479SAndreas Jaekel zs.zev_cnt_discarded_events); 58e9a5e479SAndreas Jaekel printf(" discarded bytes : %lu\n\n", zs.zev_bytes_discarded); 59e9a5e479SAndreas Jaekel 602bb8e5e2SAndreas Jaekel printf("ZFS event statistics:\n"); 612bb8e5e2SAndreas Jaekel 622bb8e5e2SAndreas Jaekel printf(" total ZFS events : %lu\n", zs.zev_cnt_total_events); 632bb8e5e2SAndreas Jaekel printf(" ZFS mount : %lu\n", zs.zev_cnt_zfs_mount); 642bb8e5e2SAndreas Jaekel printf(" ZFS umount : %lu\n", zs.zev_cnt_zfs_umount); 652bb8e5e2SAndreas Jaekel printf(" ZVOL write : %lu\n", zs.zev_cnt_zvol_write); 662bb8e5e2SAndreas Jaekel printf(" ZVOL truncate : %lu\n", zs.zev_cnt_zvol_truncate); 672bb8e5e2SAndreas Jaekel printf(" ZNODE close after update: %lu\n", 682bb8e5e2SAndreas Jaekel zs.zev_cnt_znode_close_after_update); 692bb8e5e2SAndreas Jaekel printf(" ZNODE create : %lu\n", zs.zev_cnt_znode_create); 702bb8e5e2SAndreas Jaekel printf(" ZNODE remove : %lu\n", zs.zev_cnt_znode_remove); 712bb8e5e2SAndreas Jaekel printf(" ZNODE link : %lu\n", zs.zev_cnt_znode_link); 722bb8e5e2SAndreas Jaekel printf(" ZNODE symlink : %lu\n", zs.zev_cnt_znode_symlink); 732bb8e5e2SAndreas Jaekel printf(" ZNODE rename : %lu\n", zs.zev_cnt_znode_rename); 742bb8e5e2SAndreas Jaekel printf(" ZNODE write : %lu\n", zs.zev_cnt_znode_write); 752bb8e5e2SAndreas Jaekel printf(" ZNODE truncate : %lu\n", 762bb8e5e2SAndreas Jaekel zs.zev_cnt_znode_truncate); 772bb8e5e2SAndreas Jaekel printf(" ZNODE setattr : %lu\n", zs.zev_cnt_znode_setattr); 782bb8e5e2SAndreas Jaekel printf(" ZNODE acl : %lu\n", zs.zev_cnt_znode_acl); 79e9a5e479SAndreas Jaekel return EXIT_SUCCESS; 802bb8e5e2SAndreas Jaekel } 812bb8e5e2SAndreas Jaekel 822bb8e5e2SAndreas Jaekel static void 8363aba447SAndreas Jaekel zev_print_error(char *buf) 8463aba447SAndreas Jaekel { 8563aba447SAndreas Jaekel zev_error_t *rec = (zev_error_t *)buf; 8663aba447SAndreas Jaekel time_t op_time = rec->op_time; 8763aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 8863aba447SAndreas Jaekel 8963aba447SAndreas Jaekel printf("%s %s: failed_op=%s msg=%s\n", 9063aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 9163aba447SAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN], ZEV_ERRSTR(rec)); 9263aba447SAndreas Jaekel } 9363aba447SAndreas Jaekel 9463aba447SAndreas Jaekel static void 9501c2c787SAndreas Jaekel zev_print_mark(char *buf) 9601c2c787SAndreas Jaekel { 9701c2c787SAndreas Jaekel zev_mark_t *rec = (zev_mark_t *)buf; 9801c2c787SAndreas Jaekel time_t op_time = rec->op_time; 9901c2c787SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 10001c2c787SAndreas Jaekel 10101c2c787SAndreas Jaekel printf("%s %s: guid=%llu mark_id=%lld payload_len=%ld\n", 10201c2c787SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], rec->guid, rec->mark_id, 10301c2c787SAndreas Jaekel rec->payload_len); 10401c2c787SAndreas Jaekel } 10501c2c787SAndreas Jaekel 10601c2c787SAndreas Jaekel static void 10763aba447SAndreas Jaekel zev_print_zfs_mount(char *buf) 10863aba447SAndreas Jaekel { 10963aba447SAndreas Jaekel zev_zfs_mount_t *rec = (zev_zfs_mount_t *)buf; 11063aba447SAndreas Jaekel time_t op_time = rec->op_time; 11163aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 11263aba447SAndreas Jaekel 11363aba447SAndreas Jaekel printf("%s %s: guid=%llu remount=%s dataset='%s' mountpoint='%s'\n", 11463aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 11563aba447SAndreas Jaekel rec->guid, 11663aba447SAndreas Jaekel rec->remount ? "true" : "false", 11763aba447SAndreas Jaekel ZEV_DATASET(rec), 11863aba447SAndreas Jaekel ZEV_MOUNTPOINT(rec)); 11963aba447SAndreas Jaekel } 12063aba447SAndreas Jaekel 12163aba447SAndreas Jaekel static void 12263aba447SAndreas Jaekel zev_print_zfs_umount(char *buf) 12363aba447SAndreas Jaekel { 12463aba447SAndreas Jaekel zev_zfs_umount_t *rec = (zev_zfs_umount_t *)buf; 12563aba447SAndreas Jaekel time_t op_time = rec->op_time; 12663aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 12763aba447SAndreas Jaekel 12863aba447SAndreas Jaekel printf("%s %s: guid=%llu\n", 12963aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 13063aba447SAndreas Jaekel rec->guid); 13163aba447SAndreas Jaekel } 13263aba447SAndreas Jaekel 13363aba447SAndreas Jaekel static void 13463aba447SAndreas Jaekel zev_print_zvol_truncate(char *buf) 13563aba447SAndreas Jaekel { 13663aba447SAndreas Jaekel zev_zvol_truncate_t *rec = (zev_zvol_truncate_t *)buf; 13763aba447SAndreas Jaekel time_t op_time = rec->op_time; 13863aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 13963aba447SAndreas Jaekel 14063aba447SAndreas Jaekel printf("%s %s: guid=%llu offset=%llu length=%llu\n", 14163aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 14263aba447SAndreas Jaekel rec->guid, 14363aba447SAndreas Jaekel rec->offset, 14463aba447SAndreas Jaekel rec->length); 14563aba447SAndreas Jaekel } 14663aba447SAndreas Jaekel 14763aba447SAndreas Jaekel static void 14863aba447SAndreas Jaekel zev_print_zvol_write(char *buf) 14963aba447SAndreas Jaekel { 15063aba447SAndreas Jaekel zev_print_zvol_truncate(buf); 15163aba447SAndreas Jaekel } 15263aba447SAndreas Jaekel 15363aba447SAndreas Jaekel static void 15463aba447SAndreas Jaekel zev_print_znode_close_after_update(char *buf) 15563aba447SAndreas Jaekel { 15663aba447SAndreas Jaekel zev_znode_close_after_update_t *rec = 15763aba447SAndreas Jaekel (zev_znode_close_after_update_t *)buf; 15863aba447SAndreas Jaekel time_t op_time = rec->op_time; 15963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 16063aba447SAndreas Jaekel 16163aba447SAndreas Jaekel printf("%s %s: guid=%llu file=%llu.%llu\n", 16263aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 16363aba447SAndreas Jaekel rec->guid, 16463aba447SAndreas Jaekel rec->file.ino, rec->file.gen); 16563aba447SAndreas Jaekel } 16663aba447SAndreas Jaekel 16763aba447SAndreas Jaekel static void 16863aba447SAndreas Jaekel zev_print_znode_create(char *buf) 16963aba447SAndreas Jaekel { 17063aba447SAndreas Jaekel zev_znode_create_t *rec = (zev_znode_create_t *)buf; 17163aba447SAndreas Jaekel time_t op_time = rec->op_time; 17263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 17363aba447SAndreas Jaekel 174c035b1e8SAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu file=%llu.%llu " 175c035b1e8SAndreas Jaekel "file.mtime=%llu, parent.mtime=%llu, name='%s'\n", 17663aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 17763aba447SAndreas Jaekel rec->guid, 17863aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 17963aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 180c035b1e8SAndreas Jaekel rec->file.mtime, rec->parent.mtime, 18163aba447SAndreas Jaekel ZEV_NAME(rec)); 18263aba447SAndreas Jaekel } 18363aba447SAndreas Jaekel 18463aba447SAndreas Jaekel static void 18563aba447SAndreas Jaekel zev_print_znode_mkdir(char *buf) 18663aba447SAndreas Jaekel { 18763aba447SAndreas Jaekel zev_print_znode_create(buf); 18863aba447SAndreas Jaekel } 18963aba447SAndreas Jaekel 19063aba447SAndreas Jaekel static void 19163aba447SAndreas Jaekel zev_print_znode_make_xattr_dir(char *buf) 19263aba447SAndreas Jaekel { 19363aba447SAndreas Jaekel zev_print_znode_create(buf); 19463aba447SAndreas Jaekel } 19563aba447SAndreas Jaekel 19663aba447SAndreas Jaekel static void 19763aba447SAndreas Jaekel zev_print_znode_remove(char *buf) 19863aba447SAndreas Jaekel { 19963aba447SAndreas Jaekel zev_znode_remove_t *rec = (zev_znode_remove_t *)buf; 20063aba447SAndreas Jaekel time_t op_time = rec->op_time; 20163aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 20263aba447SAndreas Jaekel 2036db5d4ecSAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu file.mtime=%llu name='%s'\n", 20463aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 20563aba447SAndreas Jaekel rec->guid, 20663aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 2076db5d4ecSAndreas Jaekel rec->file.mtime, 20863aba447SAndreas Jaekel ZEV_NAME(rec)); 20963aba447SAndreas Jaekel } 21063aba447SAndreas Jaekel 21163aba447SAndreas Jaekel static void 21263aba447SAndreas Jaekel zev_print_znode_rmdir(char *buf) 21363aba447SAndreas Jaekel { 21463aba447SAndreas Jaekel zev_print_znode_remove(buf); 21563aba447SAndreas Jaekel } 21663aba447SAndreas Jaekel 21763aba447SAndreas Jaekel static void 21863aba447SAndreas Jaekel zev_print_znode_link(char *buf) 21963aba447SAndreas Jaekel { 22063aba447SAndreas Jaekel zev_znode_link_t *rec = (zev_znode_link_t *)buf; 22163aba447SAndreas Jaekel time_t op_time = rec->op_time; 22263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 22363aba447SAndreas Jaekel 22403101f54SAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu " 22503101f54SAndreas Jaekel "file.ctime=%llu parent.ctime=%llu name='%s'\n", 22663aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 22763aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 22863aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 22903101f54SAndreas Jaekel rec->file.ctime, rec->parent.ctime, 23063aba447SAndreas Jaekel ZEV_NAME(rec)); 23163aba447SAndreas Jaekel printf("links: %d\n", rec->file.links); 23263aba447SAndreas Jaekel } 23363aba447SAndreas Jaekel 23463aba447SAndreas Jaekel static void 23563aba447SAndreas Jaekel zev_print_znode_symlink(char *buf) 23663aba447SAndreas Jaekel { 23763aba447SAndreas Jaekel zev_znode_symlink_t *rec = (zev_znode_symlink_t *)buf; 23863aba447SAndreas Jaekel time_t op_time = rec->op_time; 23963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 24063aba447SAndreas Jaekel 24163aba447SAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu name='%s' link='%s'\n", 24263aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 24363aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 24463aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 24563aba447SAndreas Jaekel ZEV_NAME(rec), 24663aba447SAndreas Jaekel ZEV_LINK(rec)); 24763aba447SAndreas Jaekel } 24863aba447SAndreas Jaekel 24963aba447SAndreas Jaekel static void 25063aba447SAndreas Jaekel zev_print_znode_rename(char *buf) 25163aba447SAndreas Jaekel { 25263aba447SAndreas Jaekel zev_znode_rename_t *rec = (zev_znode_rename_t *)buf; 25363aba447SAndreas Jaekel time_t op_time = rec->op_time; 25463aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 25563aba447SAndreas Jaekel 25663aba447SAndreas Jaekel printf("%s %s: srcdir=%llu.%llu dstdir=%llu.%llu file=%llu.%llu " 257c035b1e8SAndreas Jaekel "file.mtime=%llu, file.ctime=%llu, srcdir.mtime=%llu, " 258c035b1e8SAndreas Jaekel "srcdir.ctime=%llu, dstdir.mtime=%llu, dstdir.ctime=%llu, " 25963aba447SAndreas Jaekel "srcname='%s' dstname='%s'\n", 26063aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 26163aba447SAndreas Jaekel rec->srcdir.ino, rec->srcdir.gen, 26263aba447SAndreas Jaekel rec->dstdir.ino, rec->dstdir.gen, 26363aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 264c035b1e8SAndreas Jaekel rec->file.mtime, rec->file.ctime, 265c035b1e8SAndreas Jaekel rec->srcdir.mtime, rec->srcdir.ctime, 266c035b1e8SAndreas Jaekel rec->dstdir.mtime, rec->dstdir.ctime, 26763aba447SAndreas Jaekel ZEV_SRCNAME(rec), 26863aba447SAndreas Jaekel ZEV_DSTNAME(rec)); 26963aba447SAndreas Jaekel } 27063aba447SAndreas Jaekel 27163aba447SAndreas Jaekel static void 2725e286361SAndreas Jaekel sig2hex_direct(const uint8_t *sig, char *hex) 2735e286361SAndreas Jaekel { 2745e286361SAndreas Jaekel int i; 2755e286361SAndreas Jaekel 2765e286361SAndreas Jaekel for (i = 0; i < SHA1_DIGEST_LENGTH; ++i) { 2775e286361SAndreas Jaekel sprintf(hex + 2 * i, "%02x", sig[i]); 2785e286361SAndreas Jaekel } 2795e286361SAndreas Jaekel hex[SHA1_DIGEST_LENGTH * 2] = '\0'; 2805e286361SAndreas Jaekel } 2815e286361SAndreas Jaekel 2825e286361SAndreas Jaekel static void 28363aba447SAndreas Jaekel zev_print_znode_write(char *buf) 28463aba447SAndreas Jaekel { 28563aba447SAndreas Jaekel zev_znode_write_t *rec = (zev_znode_write_t *)buf; 28663aba447SAndreas Jaekel time_t op_time = rec->op_time; 28763aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 2885e286361SAndreas Jaekel zev_sig_t *sig; 2895e286361SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 2905e286361SAndreas Jaekel int i; 29163aba447SAndreas Jaekel 29263aba447SAndreas Jaekel printf("%s %s: file=%llu.%llu offset=%llu length=%llu\n", 29363aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 29463aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 29563aba447SAndreas Jaekel rec->offset, rec->length); 2965e286361SAndreas Jaekel if (verbose) { 2975e286361SAndreas Jaekel for (i=0; i<rec->signature_cnt; i++) { 2985e286361SAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(rec); 2995e286361SAndreas Jaekel sig += i; 3005e286361SAndreas Jaekel sig2hex_direct(sig->value, sigval); 3015e286361SAndreas Jaekel printf(" sig: level %d, offset %llu, value %s\n", 3025e286361SAndreas Jaekel sig->level, sig->block_offset, sigval); 3035e286361SAndreas Jaekel } 3045e286361SAndreas Jaekel } 30563aba447SAndreas Jaekel } 30663aba447SAndreas Jaekel 30763aba447SAndreas Jaekel static void 30863aba447SAndreas Jaekel zev_print_znode_truncate(char *buf) 30963aba447SAndreas Jaekel { 31063aba447SAndreas Jaekel zev_print_znode_write(buf); 31163aba447SAndreas Jaekel } 31263aba447SAndreas Jaekel 31363aba447SAndreas Jaekel static void 31463aba447SAndreas Jaekel zev_print_znode_setattr(char *buf) 31563aba447SAndreas Jaekel { 31663aba447SAndreas Jaekel zev_znode_setattr_t *rec = (zev_znode_setattr_t *)buf; 31763aba447SAndreas Jaekel time_t op_time = rec->op_time; 31863aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 31963aba447SAndreas Jaekel 320c035b1e8SAndreas Jaekel printf("%s %s: file=%llu.%llu mtime=%llu\n", 32163aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 322c035b1e8SAndreas Jaekel rec->file.ino, rec->file.gen, rec->file.mtime); 32363aba447SAndreas Jaekel } 32463aba447SAndreas Jaekel 32563aba447SAndreas Jaekel static void 32663aba447SAndreas Jaekel zev_print_znode_acl(char *buf) 32763aba447SAndreas Jaekel { 32863aba447SAndreas Jaekel zev_print_znode_setattr(buf); 32963aba447SAndreas Jaekel } 33063aba447SAndreas Jaekel 33163aba447SAndreas Jaekel static void 3329193e9c2SAndreas Jaekel zev_print_event(char *buf, int len) 3339193e9c2SAndreas Jaekel { 33463aba447SAndreas Jaekel int record_len; 33563aba447SAndreas Jaekel int op; 3369193e9c2SAndreas Jaekel 33763aba447SAndreas Jaekel record_len = *(uint32_t *)buf; 33863aba447SAndreas Jaekel if (record_len != len) { 33963aba447SAndreas Jaekel fprintf(stderr, "record length mismatch: got %d, expected %d\n", 34063aba447SAndreas Jaekel record_len, len); 3419193e9c2SAndreas Jaekel exit(1); 3429193e9c2SAndreas Jaekel } 34363aba447SAndreas Jaekel op = *((uint32_t *)buf + 1); 3449193e9c2SAndreas Jaekel if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) { 34563aba447SAndreas Jaekel fprintf(stderr, "unknown op code: %d\n", op); 3469193e9c2SAndreas Jaekel exit(1); 3479193e9c2SAndreas Jaekel } 34863aba447SAndreas Jaekel switch (op) { 34963aba447SAndreas Jaekel case ZEV_OP_ERROR: 35063aba447SAndreas Jaekel zev_print_error(buf); 3519193e9c2SAndreas Jaekel break; 35201c2c787SAndreas Jaekel case ZEV_OP_MARK: 35301c2c787SAndreas Jaekel zev_print_mark(buf); 35401c2c787SAndreas Jaekel break; 35563aba447SAndreas Jaekel case ZEV_OP_ZFS_MOUNT: 35663aba447SAndreas Jaekel zev_print_zfs_mount(buf); 3579193e9c2SAndreas Jaekel break; 35863aba447SAndreas Jaekel case ZEV_OP_ZFS_UMOUNT: 35963aba447SAndreas Jaekel zev_print_zfs_umount(buf); 3609193e9c2SAndreas Jaekel break; 36163aba447SAndreas Jaekel case ZEV_OP_ZVOL_TRUNCATE: 36263aba447SAndreas Jaekel zev_print_zvol_truncate(buf); 3639193e9c2SAndreas Jaekel break; 36463aba447SAndreas Jaekel case ZEV_OP_ZVOL_WRITE: 36563aba447SAndreas Jaekel zev_print_zvol_write(buf); 36663aba447SAndreas Jaekel break; 36763aba447SAndreas Jaekel case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE: 36863aba447SAndreas Jaekel zev_print_znode_close_after_update(buf); 36963aba447SAndreas Jaekel break; 37063aba447SAndreas Jaekel case ZEV_OP_ZNODE_CREATE: 37163aba447SAndreas Jaekel zev_print_znode_create(buf); 37263aba447SAndreas Jaekel break; 37363aba447SAndreas Jaekel case ZEV_OP_ZNODE_MKDIR: 37463aba447SAndreas Jaekel zev_print_znode_mkdir(buf); 37563aba447SAndreas Jaekel break; 37663aba447SAndreas Jaekel case ZEV_OP_ZNODE_MAKE_XATTR_DIR: 37763aba447SAndreas Jaekel zev_print_znode_make_xattr_dir(buf); 37863aba447SAndreas Jaekel break; 37963aba447SAndreas Jaekel case ZEV_OP_ZNODE_REMOVE: 38063aba447SAndreas Jaekel zev_print_znode_remove(buf); 38163aba447SAndreas Jaekel break; 38263aba447SAndreas Jaekel case ZEV_OP_ZNODE_RMDIR: 38363aba447SAndreas Jaekel zev_print_znode_rmdir(buf); 38463aba447SAndreas Jaekel break; 38563aba447SAndreas Jaekel case ZEV_OP_ZNODE_LINK: 38663aba447SAndreas Jaekel zev_print_znode_link(buf); 38763aba447SAndreas Jaekel break; 38863aba447SAndreas Jaekel case ZEV_OP_ZNODE_SYMLINK: 38963aba447SAndreas Jaekel zev_print_znode_symlink(buf); 39063aba447SAndreas Jaekel break; 39163aba447SAndreas Jaekel case ZEV_OP_ZNODE_RENAME: 39263aba447SAndreas Jaekel zev_print_znode_rename(buf); 39363aba447SAndreas Jaekel break; 39463aba447SAndreas Jaekel case ZEV_OP_ZNODE_WRITE: 39563aba447SAndreas Jaekel zev_print_znode_write(buf); 39663aba447SAndreas Jaekel break; 39763aba447SAndreas Jaekel case ZEV_OP_ZNODE_TRUNCATE: 39863aba447SAndreas Jaekel zev_print_znode_truncate(buf); 39963aba447SAndreas Jaekel break; 40063aba447SAndreas Jaekel case ZEV_OP_ZNODE_SETATTR: 40163aba447SAndreas Jaekel zev_print_znode_setattr(buf); 40263aba447SAndreas Jaekel break; 40363aba447SAndreas Jaekel case ZEV_OP_ZNODE_ACL: 40463aba447SAndreas Jaekel zev_print_znode_acl(buf); 4059193e9c2SAndreas Jaekel break; 4069193e9c2SAndreas Jaekel default: 40763aba447SAndreas Jaekel fprintf(stderr, "unhandled op code: %d\n", op); 4089193e9c2SAndreas Jaekel exit(1); 4099193e9c2SAndreas Jaekel } 4109193e9c2SAndreas Jaekel } 4119193e9c2SAndreas Jaekel 412e9a5e479SAndreas Jaekel static int 4134ca7dd5eSAndreas Jaekel zev_poll_events(int fd, int create_tmp_queue) 4142bb8e5e2SAndreas Jaekel { 4152bb8e5e2SAndreas Jaekel struct pollfd pfd[1]; 4162bb8e5e2SAndreas Jaekel int ret; 4179193e9c2SAndreas Jaekel char buf[4096]; 41868a46c64SAndreas Jaekel zev_event_t *ev; 41968a46c64SAndreas Jaekel int off = 0; 420e9a5e479SAndreas Jaekel zev_ioctl_add_queue_t aq; 421e9a5e479SAndreas Jaekel int q_fd; 422e9a5e479SAndreas Jaekel 4234ca7dd5eSAndreas Jaekel if (create_tmp_queue) { 424e9a5e479SAndreas Jaekel aq.zev_max_queue_len = 0; 425e9a5e479SAndreas Jaekel aq.zev_flags = ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 426e9a5e479SAndreas Jaekel snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN, 427e9a5e479SAndreas Jaekel "zevadm.%ld.%ld", time(NULL), getpid()); 428e9a5e479SAndreas Jaekel aq.zev_namelen = strlen(aq.zev_name); 429e9a5e479SAndreas Jaekel 430e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) { 431e9a5e479SAndreas Jaekel perror("adding temporary queue failed"); 432e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 433e9a5e479SAndreas Jaekel } 434e9a5e479SAndreas Jaekel 4354ca7dd5eSAndreas Jaekel snprintf(buf, sizeof(buf), 4364ca7dd5eSAndreas Jaekel "/devices/pseudo/zev@0:%s", aq.zev_name); 437e9a5e479SAndreas Jaekel q_fd = open(buf, O_RDONLY); 438e9a5e479SAndreas Jaekel if (q_fd < 0) { 439e9a5e479SAndreas Jaekel perror("opening queue device failed"); 440e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 441e9a5e479SAndreas Jaekel } 4424ca7dd5eSAndreas Jaekel } else { 4434ca7dd5eSAndreas Jaekel q_fd = fd; 4444ca7dd5eSAndreas Jaekel } 445e9a5e479SAndreas Jaekel 4462bb8e5e2SAndreas Jaekel while (1) { 447e9a5e479SAndreas Jaekel pfd[0].fd = q_fd; 4482bb8e5e2SAndreas Jaekel pfd[0].events = POLLIN; 4492bb8e5e2SAndreas Jaekel ret = poll(pfd, 1, 1000); 4502bb8e5e2SAndreas Jaekel if (ret < 0) { 4512bb8e5e2SAndreas Jaekel perror("poll failed"); 4524ca7dd5eSAndreas Jaekel close(q_fd); 453e9a5e479SAndreas Jaekel return(EXIT_FAILURE); 4542bb8e5e2SAndreas Jaekel } 4552bb8e5e2SAndreas Jaekel if (!(pfd[0].revents & POLLIN)) 4562bb8e5e2SAndreas Jaekel continue; 4572bb8e5e2SAndreas Jaekel /* data available */ 458e9a5e479SAndreas Jaekel ret = read(q_fd, buf, sizeof(buf)); 4592bb8e5e2SAndreas Jaekel if (ret < 0) { 4602bb8e5e2SAndreas Jaekel perror("read failed"); 4614ca7dd5eSAndreas Jaekel close(q_fd); 462e9a5e479SAndreas Jaekel return(EXIT_FAILURE); 4632bb8e5e2SAndreas Jaekel } 4642bb8e5e2SAndreas Jaekel if (ret == 0) 4652bb8e5e2SAndreas Jaekel continue; 46668a46c64SAndreas Jaekel while (ret > off) { 46768a46c64SAndreas Jaekel ev = (zev_event_t *)(buf + off); 46868a46c64SAndreas Jaekel zev_print_event(buf + off, ev->header.record_len); 46968a46c64SAndreas Jaekel off += ev->header.record_len; 47068a46c64SAndreas Jaekel } 471108668daSAndreas Jaekel off = 0; 4722bb8e5e2SAndreas Jaekel } 4734ca7dd5eSAndreas Jaekel if (create_tmp_queue) 474e9a5e479SAndreas Jaekel close(q_fd); 475e9a5e479SAndreas Jaekel return EXIT_SUCCESS; 4762bb8e5e2SAndreas Jaekel } 4772bb8e5e2SAndreas Jaekel 4782bb8e5e2SAndreas Jaekel static void 4792bb8e5e2SAndreas Jaekel usage(char *progname) 4802bb8e5e2SAndreas Jaekel { 481e9a5e479SAndreas Jaekel fprintf(stderr, "usage: %s [-d <dev>] [options]\n", progname); 482e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 483e9a5e479SAndreas Jaekel fprintf(stderr, " Status information:\n"); 4842bb8e5e2SAndreas Jaekel fprintf(stderr, " -s show zev statistics\n"); 4852bb8e5e2SAndreas Jaekel fprintf(stderr, " -p poll for ZFS events\n"); 486e9a5e479SAndreas Jaekel fprintf(stderr, " -D print zev module debug " 487e9a5e479SAndreas Jaekel "information\n"); 488e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 489e9a5e479SAndreas Jaekel fprintf(stderr, " Tune zev module settings:\n"); 490e9a5e479SAndreas Jaekel fprintf(stderr, " -Q <bytes> set maximum event queue " 491e9a5e479SAndreas Jaekel "length\n"); 492e9a5e479SAndreas Jaekel fprintf(stderr, " -m <pool> mute pool, no events for " 493e9a5e479SAndreas Jaekel "this pool\n"); 4942bb8e5e2SAndreas Jaekel fprintf(stderr, " -M <pool> unmute pool\n"); 495e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 496e9a5e479SAndreas Jaekel fprintf(stderr, " Queue management:\n"); 497e9a5e479SAndreas Jaekel fprintf(stderr, " -l list queues\n"); 4984ca7dd5eSAndreas Jaekel fprintf(stderr, " -a <name> add non-blocking queue\n"); 4994ca7dd5eSAndreas Jaekel fprintf(stderr, " -A <name> add blocking queue\n"); 500e9a5e479SAndreas Jaekel fprintf(stderr, " -r <name> remove queue\n"); 501e9a5e479SAndreas Jaekel fprintf(stderr, " -b <name> make queue non-blocking " 502e9a5e479SAndreas Jaekel "(default)\n"); 503e9a5e479SAndreas Jaekel fprintf(stderr, " -B <name> make queue block when full\n"); 504e9a5e479SAndreas Jaekel fprintf(stderr, " -P <name> display queue properties\n"); 5054ca7dd5eSAndreas Jaekel fprintf(stderr, " -L <name> <bytes> set maximum event queue " 506e9a5e479SAndreas Jaekel "length\n"); 507e9a5e479SAndreas Jaekel fprintf(stderr, " -t <name> <bytes> set queue length poll " 508e9a5e479SAndreas Jaekel "throttle\n"); 509e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 510e9a5e479SAndreas Jaekel fprintf(stderr, " Other options:\n"); 511e9a5e479SAndreas Jaekel fprintf(stderr, " -d <dev> non-default device file. " 512e9a5e479SAndreas Jaekel "('%s')\n", ZEV_DEVICE); 5134ca7dd5eSAndreas Jaekel fprintf(stderr, " -q <name> use device file for this " 5144ca7dd5eSAndreas Jaekel "queue name\n"); 51501c2c787SAndreas Jaekel fprintf(stderr, " -k <guid>:<payload> queue mark event\n"); 516*b9710123SAndreas Jaekel fprintf(stderr, " -c <filename> list file's content " 517*b9710123SAndreas Jaekel "checksums\n"); 5185e286361SAndreas Jaekel fprintf(stderr, " -v verbose: addition output " 5195e286361SAndreas Jaekel "for some operations\n"); 5202bb8e5e2SAndreas Jaekel exit (EXIT_FAILURE); 5212bb8e5e2SAndreas Jaekel } 5222bb8e5e2SAndreas Jaekel 5232bb8e5e2SAndreas Jaekel static int 5244ca7dd5eSAndreas Jaekel zev_add_queue(int fd, char *arg, int blocking) 5252bb8e5e2SAndreas Jaekel { 526e9a5e479SAndreas Jaekel zev_ioctl_add_queue_t aq; 527e9a5e479SAndreas Jaekel int namelen; 5282bb8e5e2SAndreas Jaekel 529e9a5e479SAndreas Jaekel namelen = strlen(arg); 530e9a5e479SAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) { 531e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg); 5322bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 5332bb8e5e2SAndreas Jaekel } 534e9a5e479SAndreas Jaekel 535e9a5e479SAndreas Jaekel aq.zev_namelen = namelen; 536e9a5e479SAndreas Jaekel strcpy(aq.zev_name, arg); 5374ca7dd5eSAndreas Jaekel aq.zev_flags = ZEV_FL_PERSISTENT; 5384ca7dd5eSAndreas Jaekel if (blocking) { 5394ca7dd5eSAndreas Jaekel aq.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 5404ca7dd5eSAndreas Jaekel aq.zev_max_queue_len = ZEV_MAX_QUEUE_LEN; 5414ca7dd5eSAndreas Jaekel } else { 542e9a5e479SAndreas Jaekel aq.zev_max_queue_len = (1024 * 1024); 5434ca7dd5eSAndreas Jaekel } 544e9a5e479SAndreas Jaekel 545e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) { 546e9a5e479SAndreas Jaekel perror("adding queue failed"); 5472bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 5482bb8e5e2SAndreas Jaekel } 5492bb8e5e2SAndreas Jaekel return (0); 5502bb8e5e2SAndreas Jaekel } 5512bb8e5e2SAndreas Jaekel 5522bb8e5e2SAndreas Jaekel static int 553e9a5e479SAndreas Jaekel zev_remove_queue(int fd, char *arg) 554205a9bc9SAndreas Jaekel { 555e9a5e479SAndreas Jaekel zev_ioctl_remove_queue_t aq; 556e9a5e479SAndreas Jaekel int namelen; 557205a9bc9SAndreas Jaekel 558e9a5e479SAndreas Jaekel namelen = strlen(arg); 559e9a5e479SAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) { 560e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg); 561205a9bc9SAndreas Jaekel return (EXIT_FAILURE); 562205a9bc9SAndreas Jaekel } 563e9a5e479SAndreas Jaekel 5644ca7dd5eSAndreas Jaekel aq.zev_queue_name.zev_namelen = namelen; 5654ca7dd5eSAndreas Jaekel strcpy(aq.zev_queue_name.zev_name, arg); 566e9a5e479SAndreas Jaekel 567e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_REMOVE_QUEUE, &aq)) { 568e9a5e479SAndreas Jaekel perror("removing queue failed"); 569e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 570e9a5e479SAndreas Jaekel } 571e9a5e479SAndreas Jaekel return (0); 572e9a5e479SAndreas Jaekel } 573e9a5e479SAndreas Jaekel 574e9a5e479SAndreas Jaekel static int 575e9a5e479SAndreas Jaekel zev_set_global_max_queue_len(int fd, char *arg) 576e9a5e479SAndreas Jaekel { 577e9a5e479SAndreas Jaekel uint64_t maxqueuelen; 578e9a5e479SAndreas Jaekel 579e9a5e479SAndreas Jaekel errno = 0; 580e9a5e479SAndreas Jaekel maxqueuelen = strtol(arg, (char **)NULL, 10); 581e9a5e479SAndreas Jaekel if (errno) { 582e9a5e479SAndreas Jaekel fprintf(stderr, "invalid queue length parameter: %s\n", arg); 583e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 584e9a5e479SAndreas Jaekel } 585e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_MAX_QUEUE_LEN, &maxqueuelen)) { 586e9a5e479SAndreas Jaekel perror("setting max queue length failed"); 587205a9bc9SAndreas Jaekel return (EXIT_FAILURE); 588205a9bc9SAndreas Jaekel } 589205a9bc9SAndreas Jaekel return (0); 590205a9bc9SAndreas Jaekel } 591205a9bc9SAndreas Jaekel 592205a9bc9SAndreas Jaekel static int 5932bb8e5e2SAndreas Jaekel zev_mute_unmute_impl(int fd, char *poolname, int mute) 5942bb8e5e2SAndreas Jaekel { 5952bb8e5e2SAndreas Jaekel zev_ioctl_poolarg_t pa; 5962bb8e5e2SAndreas Jaekel int len; 5972bb8e5e2SAndreas Jaekel int op = mute ? ZEV_IOC_MUTE_POOL : ZEV_IOC_UNMUTE_POOL; 5982bb8e5e2SAndreas Jaekel len = strlen(poolname); 5992bb8e5e2SAndreas Jaekel if (len <= 0 || len >= sizeof(pa.zev_poolname)) { 6002bb8e5e2SAndreas Jaekel fprintf(stderr, "invalid poolname: %s\n", poolname); 6012bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 6022bb8e5e2SAndreas Jaekel } 6032bb8e5e2SAndreas Jaekel strcpy(pa.zev_poolname, poolname); 6042bb8e5e2SAndreas Jaekel pa.zev_poolname_len = len; 6052bb8e5e2SAndreas Jaekel if (ioctl(fd, op, &pa)) { 6062bb8e5e2SAndreas Jaekel perror("muting pool data failed"); 6072bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 6082bb8e5e2SAndreas Jaekel } 6092bb8e5e2SAndreas Jaekel return (0); 6102bb8e5e2SAndreas Jaekel } 6112bb8e5e2SAndreas Jaekel 6122bb8e5e2SAndreas Jaekel int 6132bb8e5e2SAndreas Jaekel zev_mute_pool(int fd, char *poolname) 6142bb8e5e2SAndreas Jaekel { 6152bb8e5e2SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 1); 6162bb8e5e2SAndreas Jaekel } 6172bb8e5e2SAndreas Jaekel 6182bb8e5e2SAndreas Jaekel int 6192bb8e5e2SAndreas Jaekel zev_unmute_pool(int fd, char *poolname) 6202bb8e5e2SAndreas Jaekel { 6212bb8e5e2SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 0); 6222bb8e5e2SAndreas Jaekel } 6232bb8e5e2SAndreas Jaekel 62401c2c787SAndreas Jaekel static int 625e9a5e479SAndreas Jaekel zev_debug_info(int fd) 626e9a5e479SAndreas Jaekel { 627e9a5e479SAndreas Jaekel zev_ioctl_debug_info_t di; 628e9a5e479SAndreas Jaekel 629e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_DEBUG_INFO, &di)) { 630e9a5e479SAndreas Jaekel perror("getting zev debug info failed"); 631e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 632e9a5e479SAndreas Jaekel } 633e9a5e479SAndreas Jaekel 634e9a5e479SAndreas Jaekel printf("memory allocated: %llu bytes\n", di.zev_memory_allocated); 6355e286361SAndreas Jaekel printf("checksum cache size: %llu\n", di.zev_chksum_cache_size); 6365e286361SAndreas Jaekel printf("checksum cache hits: %llu\n", di.zev_chksum_cache_hits); 6375e286361SAndreas Jaekel printf("checksum cache misses: %llu\n", di.zev_chksum_cache_misses); 638e9a5e479SAndreas Jaekel return 0; 639e9a5e479SAndreas Jaekel } 640e9a5e479SAndreas Jaekel 641e9a5e479SAndreas Jaekel static int 64201c2c787SAndreas Jaekel zev_mark(int fd, char *arg) 64301c2c787SAndreas Jaekel { 64401c2c787SAndreas Jaekel zev_ioctl_mark_t *mark; 64501c2c787SAndreas Jaekel uint64_t guid; 64601c2c787SAndreas Jaekel int len; 64701c2c787SAndreas Jaekel char *p; 64801c2c787SAndreas Jaekel 64901c2c787SAndreas Jaekel p = strchr(arg, ':'); 65001c2c787SAndreas Jaekel if (!p) { 65101c2c787SAndreas Jaekel fprintf(stderr, "expected value is <guid>:<payload>, " 65201c2c787SAndreas Jaekel "e.g. '123:hello'\n"); 65301c2c787SAndreas Jaekel exit (EXIT_FAILURE); 65401c2c787SAndreas Jaekel } 65501c2c787SAndreas Jaekel *p = '\n'; 65601c2c787SAndreas Jaekel p++; 65701c2c787SAndreas Jaekel 65801c2c787SAndreas Jaekel errno = 0; 659e9a5e479SAndreas Jaekel guid = strtoll(arg, (char **)NULL, 10); 66001c2c787SAndreas Jaekel if (errno) { 66101c2c787SAndreas Jaekel fprintf(stderr, "guid must be a number.\n"); 66201c2c787SAndreas Jaekel exit (EXIT_FAILURE); 66301c2c787SAndreas Jaekel } 66401c2c787SAndreas Jaekel 66501c2c787SAndreas Jaekel len = strlen(p); 66601c2c787SAndreas Jaekel 66701c2c787SAndreas Jaekel mark = malloc(sizeof(*mark) + len + 1); 66801c2c787SAndreas Jaekel if (!mark) { 66901c2c787SAndreas Jaekel fprintf(stderr, "can't allocate mark structure: %s\n", 67001c2c787SAndreas Jaekel strerror(errno)); 67101c2c787SAndreas Jaekel exit (EXIT_FAILURE); 67201c2c787SAndreas Jaekel } 67301c2c787SAndreas Jaekel mark->zev_guid = guid; 67401c2c787SAndreas Jaekel mark->zev_mark_id = 0; 67501c2c787SAndreas Jaekel mark->zev_payload_len = len; 67601c2c787SAndreas Jaekel strcpy(ZEV_PAYLOAD(mark), p); 67701c2c787SAndreas Jaekel 67801c2c787SAndreas Jaekel if (ioctl(fd, ZEV_IOC_MARK, mark)) { 67901c2c787SAndreas Jaekel perror("queueing mark failed"); 68001c2c787SAndreas Jaekel return (EXIT_FAILURE); 68101c2c787SAndreas Jaekel } 68201c2c787SAndreas Jaekel 68301c2c787SAndreas Jaekel printf("mark id: %lu\n", mark->zev_mark_id); 68401c2c787SAndreas Jaekel return (0); 68501c2c787SAndreas Jaekel } 68601c2c787SAndreas Jaekel 687e9a5e479SAndreas Jaekel static int 688e9a5e479SAndreas Jaekel zev_queue_blocking(int fd, char *arg, int block) 689e9a5e479SAndreas Jaekel { 690e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 691e9a5e479SAndreas Jaekel 6924ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 6934ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 694e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 695e9a5e479SAndreas Jaekel return EXIT_FAILURE; 696e9a5e479SAndreas Jaekel } 6974ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 698e9a5e479SAndreas Jaekel 699e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 700e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 701e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 702e9a5e479SAndreas Jaekel } 703e9a5e479SAndreas Jaekel if (block) { 704e9a5e479SAndreas Jaekel gqp.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 705e9a5e479SAndreas Jaekel } else { 706e9a5e479SAndreas Jaekel gqp.zev_flags &= ~ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 707e9a5e479SAndreas Jaekel } 708e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 709e9a5e479SAndreas Jaekel perror("setting queue properties failed"); 710e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 711e9a5e479SAndreas Jaekel } 712e9a5e479SAndreas Jaekel return (0); 713e9a5e479SAndreas Jaekel } 714e9a5e479SAndreas Jaekel 715e9a5e479SAndreas Jaekel static int 716e9a5e479SAndreas Jaekel zev_set_max_queue_len(int fd, char *arg, char *len) 717e9a5e479SAndreas Jaekel { 718e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 719e9a5e479SAndreas Jaekel 720e9a5e479SAndreas Jaekel if (!len) { 721e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter missing.\n"); 722e9a5e479SAndreas Jaekel return EXIT_FAILURE; 723e9a5e479SAndreas Jaekel } 724e9a5e479SAndreas Jaekel 7254ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 7264ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 727e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 728e9a5e479SAndreas Jaekel return EXIT_FAILURE; 729e9a5e479SAndreas Jaekel } 7304ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 731e9a5e479SAndreas Jaekel 732e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 733e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 734e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 735e9a5e479SAndreas Jaekel } 736e9a5e479SAndreas Jaekel gqp.zev_max_queue_len = atol(len); 737e9a5e479SAndreas Jaekel if (gqp.zev_max_queue_len == 0 && strcmp("0", len)) { 738e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter garbled.\n"); 739e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 740e9a5e479SAndreas Jaekel } 741e9a5e479SAndreas Jaekel if (gqp.zev_max_queue_len > ZEV_MAX_QUEUE_LEN) { 742e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter out of bounds.\n"); 743e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 744e9a5e479SAndreas Jaekel } 745e9a5e479SAndreas Jaekel 746e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 747e9a5e479SAndreas Jaekel perror("setting queue properties failed"); 748e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 749e9a5e479SAndreas Jaekel } 750e9a5e479SAndreas Jaekel return (0); 751e9a5e479SAndreas Jaekel } 752e9a5e479SAndreas Jaekel 753e9a5e479SAndreas Jaekel static int 754e9a5e479SAndreas Jaekel zev_set_poll_wakeup_queue_len(int fd, char *arg, char *len) 755e9a5e479SAndreas Jaekel { 756e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 757e9a5e479SAndreas Jaekel 758e9a5e479SAndreas Jaekel if (!len) { 759e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter missing.\n"); 760e9a5e479SAndreas Jaekel return EXIT_FAILURE; 761e9a5e479SAndreas Jaekel } 762e9a5e479SAndreas Jaekel 7634ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 7644ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 765e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 766e9a5e479SAndreas Jaekel return EXIT_FAILURE; 767e9a5e479SAndreas Jaekel } 7684ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 769e9a5e479SAndreas Jaekel 770e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 771e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 772e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 773e9a5e479SAndreas Jaekel } 774e9a5e479SAndreas Jaekel gqp.zev_poll_wakeup_threshold = atol(len); 775e9a5e479SAndreas Jaekel if (gqp.zev_poll_wakeup_threshold == 0 && strcmp("0", len)) { 776e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter garbled.\n"); 777e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 778e9a5e479SAndreas Jaekel } 7794ca7dd5eSAndreas Jaekel if (gqp.zev_poll_wakeup_threshold > ZEV_MAX_POLL_WAKEUP_QUEUE_LEN) { 780e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter out of bounds.\n"); 781e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 782e9a5e479SAndreas Jaekel } 783e9a5e479SAndreas Jaekel 784e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 785e9a5e479SAndreas Jaekel perror("setting queue properties failed"); 786e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 787e9a5e479SAndreas Jaekel } 788e9a5e479SAndreas Jaekel return (0); 789e9a5e479SAndreas Jaekel } 790e9a5e479SAndreas Jaekel 791e9a5e479SAndreas Jaekel static int 792e9a5e479SAndreas Jaekel zev_queue_properties(int fd, char *arg) 793e9a5e479SAndreas Jaekel { 794e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 795e9a5e479SAndreas Jaekel 7964ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 7974ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 798e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 799e9a5e479SAndreas Jaekel return EXIT_FAILURE; 800e9a5e479SAndreas Jaekel } 8014ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 802e9a5e479SAndreas Jaekel 803e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 804e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 805e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 806e9a5e479SAndreas Jaekel } 807e9a5e479SAndreas Jaekel 808e9a5e479SAndreas Jaekel printf("queue : %s\n", arg); 809e9a5e479SAndreas Jaekel printf("max size : %" PRIu64 "\n", gqp.zev_max_queue_len); 810e9a5e479SAndreas Jaekel printf("poll throttle: %" PRIu64 "\n", gqp.zev_poll_wakeup_threshold); 811e9a5e479SAndreas Jaekel printf("persistent : %s\n", 812e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no"); 813e9a5e479SAndreas Jaekel printf("blocking : %s\n", 814e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? "yes" : "no"); 815e9a5e479SAndreas Jaekel 816e9a5e479SAndreas Jaekel return (0); 817e9a5e479SAndreas Jaekel } 818e9a5e479SAndreas Jaekel 819e9a5e479SAndreas Jaekel static int 820e9a5e479SAndreas Jaekel zev_list_queues(int fd) 821e9a5e479SAndreas Jaekel { 822e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 823e9a5e479SAndreas Jaekel zev_ioctl_get_queue_list_t gql; 824e9a5e479SAndreas Jaekel zev_ioctl_get_queue_statistics_t gs; 825e9a5e479SAndreas Jaekel uint64_t i; 826e9a5e479SAndreas Jaekel char name[ZEV_MAX_QUEUE_NAME_LEN+1]; 827e9a5e479SAndreas Jaekel 828e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_LIST, &gql)) { 829e9a5e479SAndreas Jaekel perror("getting queue list failed"); 830e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 831e9a5e479SAndreas Jaekel } 832e9a5e479SAndreas Jaekel 833e9a5e479SAndreas Jaekel printf("Name Size " 834e9a5e479SAndreas Jaekel "Max Size Wakeup Per Block\n"); 835e9a5e479SAndreas Jaekel 836e9a5e479SAndreas Jaekel for (i=0; i<gql.zev_n_queues; i++) { 837e9a5e479SAndreas Jaekel strncpy(name, gql.zev_queue_name[i].zev_name, 838e9a5e479SAndreas Jaekel ZEV_MAX_QUEUE_NAME_LEN); 839e9a5e479SAndreas Jaekel name[gql.zev_queue_name[i].zev_namelen] = '\0'; 840e9a5e479SAndreas Jaekel 8414ca7dd5eSAndreas Jaekel memcpy(gqp.zev_queue_name.zev_name, 8424ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN); 8434ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = 8444ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_namelen; 845e9a5e479SAndreas Jaekel 846e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 847e9a5e479SAndreas Jaekel if (errno == ENOENT) 848e9a5e479SAndreas Jaekel continue; 849e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 850e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 851e9a5e479SAndreas Jaekel } 852e9a5e479SAndreas Jaekel 8534ca7dd5eSAndreas Jaekel memcpy(gs.zev_queue_name.zev_name, 8544ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN); 8554ca7dd5eSAndreas Jaekel gs.zev_queue_name.zev_namelen = 8564ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_namelen; 857e9a5e479SAndreas Jaekel 858e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_STATISTICS, &gs)) { 859e9a5e479SAndreas Jaekel if (errno == ENOENT) 860e9a5e479SAndreas Jaekel continue; 861e9a5e479SAndreas Jaekel perror("getting statistics data failed"); 862e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 863e9a5e479SAndreas Jaekel } 864e9a5e479SAndreas Jaekel 865e9a5e479SAndreas Jaekel printf("%-40s %-10" PRIu64 " %-10" PRIu64 " %-6" PRIu64 866e9a5e479SAndreas Jaekel " %-3s %-3s\n", 867e9a5e479SAndreas Jaekel name, 868e9a5e479SAndreas Jaekel gs.zev_statistics.zev_queue_len, 869e9a5e479SAndreas Jaekel gqp.zev_max_queue_len, 870e9a5e479SAndreas Jaekel gqp.zev_poll_wakeup_threshold, 871e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no", 872e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? 873e9a5e479SAndreas Jaekel "yes" : "no"); 874e9a5e479SAndreas Jaekel } 875e9a5e479SAndreas Jaekel 876e9a5e479SAndreas Jaekel return (0); 877e9a5e479SAndreas Jaekel } 878e9a5e479SAndreas Jaekel 879*b9710123SAndreas Jaekel static int 880*b9710123SAndreas Jaekel zev_checksum(int dev_fd, char *filename) 881*b9710123SAndreas Jaekel { 882*b9710123SAndreas Jaekel int fd; 883*b9710123SAndreas Jaekel offset_t off; 884*b9710123SAndreas Jaekel offset_t data; 885*b9710123SAndreas Jaekel zev_sig_t *sig; 886*b9710123SAndreas Jaekel char *buf; 887*b9710123SAndreas Jaekel zev_ioctl_get_signatures_t *gs; 888*b9710123SAndreas Jaekel int i; 889*b9710123SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 890*b9710123SAndreas Jaekel int buf_size; 891*b9710123SAndreas Jaekel 892*b9710123SAndreas Jaekel /* control struct, one lv1 signature and up to 256 lv0 signatures */ 893*b9710123SAndreas Jaekel buf_size = (1 + 256) * sizeof(zev_sig_t); 894*b9710123SAndreas Jaekel buf = malloc(sizeof(zev_ioctl_get_signatures_t) + buf_size); 895*b9710123SAndreas Jaekel if (!buf) { 896*b9710123SAndreas Jaekel perror("can't allocate checksum buffer"); 897*b9710123SAndreas Jaekel return (EXIT_FAILURE); 898*b9710123SAndreas Jaekel } 899*b9710123SAndreas Jaekel 900*b9710123SAndreas Jaekel fd = open(filename, O_RDONLY); 901*b9710123SAndreas Jaekel if (fd < 0) { 902*b9710123SAndreas Jaekel perror("can't open file"); 903*b9710123SAndreas Jaekel return (EXIT_FAILURE); 904*b9710123SAndreas Jaekel } 905*b9710123SAndreas Jaekel 906*b9710123SAndreas Jaekel gs = (zev_ioctl_get_signatures_t *)buf; 907*b9710123SAndreas Jaekel gs->zev_fd = fd; 908*b9710123SAndreas Jaekel gs->zev_bufsize = buf_size; 909*b9710123SAndreas Jaekel 910*b9710123SAndreas Jaekel off = 0; 911*b9710123SAndreas Jaekel data = 0; 912*b9710123SAndreas Jaekel while (1) { 913*b9710123SAndreas Jaekel errno = 0; 914*b9710123SAndreas Jaekel data = llseek(fd, off, SEEK_DATA); 915*b9710123SAndreas Jaekel if (data < 0) { 916*b9710123SAndreas Jaekel if (errno == ENXIO) /* no more data */ 917*b9710123SAndreas Jaekel break; 918*b9710123SAndreas Jaekel perror("llseek failed"); 919*b9710123SAndreas Jaekel goto err; 920*b9710123SAndreas Jaekel } 921*b9710123SAndreas Jaekel data = P2ALIGN(data, ZEV_L1_SIZE); 922*b9710123SAndreas Jaekel off = data + ZEV_L1_SIZE; 923*b9710123SAndreas Jaekel 924*b9710123SAndreas Jaekel gs->zev_offset = data; 925*b9710123SAndreas Jaekel gs->zev_len = ZEV_L1_SIZE; 926*b9710123SAndreas Jaekel 927*b9710123SAndreas Jaekel if (ioctl(dev_fd, ZEV_IOC_GET_FILE_SIGNATURES, gs)) { 928*b9710123SAndreas Jaekel perror("ioctl to get signatures failed"); 929*b9710123SAndreas Jaekel goto err; 930*b9710123SAndreas Jaekel } 931*b9710123SAndreas Jaekel 932*b9710123SAndreas Jaekel for (i=0; i<gs->zev_signature_cnt; i++) { 933*b9710123SAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(gs); 934*b9710123SAndreas Jaekel sig += i; 935*b9710123SAndreas Jaekel sig2hex_direct(sig->value, sigval); 936*b9710123SAndreas Jaekel printf("level %d, offset %llu, value %s\n", 937*b9710123SAndreas Jaekel sig->level, sig->block_offset, sigval); 938*b9710123SAndreas Jaekel } 939*b9710123SAndreas Jaekel } 940*b9710123SAndreas Jaekel 941*b9710123SAndreas Jaekel free(buf); 942*b9710123SAndreas Jaekel close(fd); 943*b9710123SAndreas Jaekel return 0; 944*b9710123SAndreas Jaekel err: 945*b9710123SAndreas Jaekel free(buf); 946*b9710123SAndreas Jaekel close(fd); 947*b9710123SAndreas Jaekel return (EXIT_FAILURE); 948*b9710123SAndreas Jaekel } 949*b9710123SAndreas Jaekel 9502bb8e5e2SAndreas Jaekel int 9512bb8e5e2SAndreas Jaekel main(int argc, char **argv) 9522bb8e5e2SAndreas Jaekel { 9532bb8e5e2SAndreas Jaekel int fd; 9542bb8e5e2SAndreas Jaekel int c; 9552bb8e5e2SAndreas Jaekel extern char *optarg; 9564ca7dd5eSAndreas Jaekel int create_tmp_queue = 1; 9574ca7dd5eSAndreas Jaekel char buf[MAXPATHLEN]; 9582bb8e5e2SAndreas Jaekel 9592bb8e5e2SAndreas Jaekel /* open device */ 9602bb8e5e2SAndreas Jaekel fd = open(zev_device, O_RDONLY); 9612bb8e5e2SAndreas Jaekel if (fd < 0) { 9622bb8e5e2SAndreas Jaekel perror("opening zev device failed"); 9632bb8e5e2SAndreas Jaekel return EXIT_FAILURE; 9642bb8e5e2SAndreas Jaekel } 9654ca7dd5eSAndreas Jaekel while ((c = getopt(argc, argv, 966*b9710123SAndreas Jaekel "vspc:d:Dlk:L:q:Qt:m:M:a:A:r:P:b:B:h?")) != -1){ 9672bb8e5e2SAndreas Jaekel switch(c) { 9685e286361SAndreas Jaekel case 'v': 9695e286361SAndreas Jaekel verbose++; 9705e286361SAndreas Jaekel break; 9712bb8e5e2SAndreas Jaekel case 's': 972e9a5e479SAndreas Jaekel return zev_statistics(fd); 9732bb8e5e2SAndreas Jaekel case 'p': 9744ca7dd5eSAndreas Jaekel return zev_poll_events(fd, create_tmp_queue); 975*b9710123SAndreas Jaekel case 'c': 976*b9710123SAndreas Jaekel return zev_checksum(fd, optarg); 977e9a5e479SAndreas Jaekel case 'D': 978e9a5e479SAndreas Jaekel return zev_debug_info(fd); 9792bb8e5e2SAndreas Jaekel case 'd': 980e9a5e479SAndreas Jaekel close(fd); 9812bb8e5e2SAndreas Jaekel zev_device = optarg; 982e9a5e479SAndreas Jaekel fd = open(zev_device, O_RDONLY); 983e9a5e479SAndreas Jaekel if (fd < 0) { 984e9a5e479SAndreas Jaekel perror("opening zev device failed"); 985e9a5e479SAndreas Jaekel return EXIT_FAILURE; 986e9a5e479SAndreas Jaekel } 9874ca7dd5eSAndreas Jaekel create_tmp_queue = 0; 9884ca7dd5eSAndreas Jaekel break; 9894ca7dd5eSAndreas Jaekel case 'q': 9904ca7dd5eSAndreas Jaekel snprintf(buf, sizeof(buf), 9914ca7dd5eSAndreas Jaekel "/devices/pseudo/zev@0:%s", optarg); 9924ca7dd5eSAndreas Jaekel close(fd); 9934ca7dd5eSAndreas Jaekel zev_device = buf; 9944ca7dd5eSAndreas Jaekel fd = open(zev_device, O_RDONLY); 9954ca7dd5eSAndreas Jaekel if (fd < 0) { 9964ca7dd5eSAndreas Jaekel perror("opening zev device failed"); 9974ca7dd5eSAndreas Jaekel return EXIT_FAILURE; 9984ca7dd5eSAndreas Jaekel } 9994ca7dd5eSAndreas Jaekel create_tmp_queue = 0; 10002bb8e5e2SAndreas Jaekel break; 1001e9a5e479SAndreas Jaekel case 'l': 1002e9a5e479SAndreas Jaekel return zev_list_queues(fd); 1003e9a5e479SAndreas Jaekel case 'Q': 1004e9a5e479SAndreas Jaekel return zev_set_global_max_queue_len(fd, optarg); 10054ca7dd5eSAndreas Jaekel case 'L': 1006e9a5e479SAndreas Jaekel return zev_set_max_queue_len(fd, optarg, argv[optind]); 1007205a9bc9SAndreas Jaekel case 't': 1008e9a5e479SAndreas Jaekel return zev_set_poll_wakeup_queue_len(fd, optarg, 1009e9a5e479SAndreas Jaekel argv[optind]); 10102bb8e5e2SAndreas Jaekel case 'm': 10112bb8e5e2SAndreas Jaekel return zev_mute_pool(fd, optarg); 10122bb8e5e2SAndreas Jaekel case 'M': 10132bb8e5e2SAndreas Jaekel return zev_unmute_pool(fd, optarg); 101401c2c787SAndreas Jaekel case 'k': 101501c2c787SAndreas Jaekel return zev_mark(fd, optarg); 1016e9a5e479SAndreas Jaekel case 'a': 10174ca7dd5eSAndreas Jaekel return zev_add_queue(fd, optarg, 0); 10184ca7dd5eSAndreas Jaekel case 'A': 10194ca7dd5eSAndreas Jaekel return zev_add_queue(fd, optarg, 1); 1020e9a5e479SAndreas Jaekel case 'r': 1021e9a5e479SAndreas Jaekel return zev_remove_queue(fd, optarg); 1022e9a5e479SAndreas Jaekel case 'b': 1023e9a5e479SAndreas Jaekel return zev_queue_blocking(fd, optarg, 0); 1024e9a5e479SAndreas Jaekel case 'B': 1025e9a5e479SAndreas Jaekel return zev_queue_blocking(fd, optarg, 1); 1026e9a5e479SAndreas Jaekel case 'P': 1027e9a5e479SAndreas Jaekel return zev_queue_properties(fd, optarg); 10282bb8e5e2SAndreas Jaekel case 'h': 10292bb8e5e2SAndreas Jaekel case '?': 10302bb8e5e2SAndreas Jaekel default: 10312bb8e5e2SAndreas Jaekel usage(argv[0]); 10322bb8e5e2SAndreas Jaekel } 10332bb8e5e2SAndreas Jaekel } 10342bb8e5e2SAndreas Jaekel usage(argv[0]); 10352bb8e5e2SAndreas Jaekel close(fd); 1036e9a5e479SAndreas Jaekel return EXIT_FAILURE; 10372bb8e5e2SAndreas Jaekel } 10382bb8e5e2SAndreas Jaekel 1039