1a18c35b9SAndreas Jaekel #include <stdio.h> 2a18c35b9SAndreas Jaekel #include <unistd.h> 3a18c35b9SAndreas Jaekel #include <stdlib.h> 4a18c35b9SAndreas Jaekel #include <fcntl.h> 5a18c35b9SAndreas Jaekel #include <stropts.h> 6a18c35b9SAndreas Jaekel #include <poll.h> 7a18c35b9SAndreas Jaekel #include <string.h> 8a18c35b9SAndreas Jaekel #include <sys/fs/zev.h> 9a18c35b9SAndreas Jaekel #include <errno.h> 1042110aacSAndreas Jaekel #include <sys/sysmacros.h> 1116ff6b2fSAndreas Jaekel #include <stdarg.h> 12b690436dSAndreas Jaekel #include <sys/avl.h> 13f432e238SAndreas Jaekel #include <sys/stat.h> 14a18c35b9SAndreas Jaekel 15add9520fSAndreas Jaekel #define ZEV_DEVICE "/devices/pseudo/zev@0:ctrl" 16a18c35b9SAndreas Jaekel 17b690436dSAndreas Jaekel #if !defined(offsetof) 18b690436dSAndreas Jaekel #define offsetof(s, m) ((size_t)(&(((s *)0)->m))) 19b690436dSAndreas Jaekel #endif 20b690436dSAndreas Jaekel 21a18c35b9SAndreas Jaekel static char *zev_device = ZEV_DEVICE; 22a18c35b9SAndreas Jaekel 23aafc540fSAndreas Jaekel static char *zev_op_name[] = { 2416ff6b2fSAndreas Jaekel "ERROR", 2516ff6b2fSAndreas Jaekel "MARK", 2616ff6b2fSAndreas Jaekel "ZFS_MOUNT", 2716ff6b2fSAndreas Jaekel "ZFS_UMOUNT", 2816ff6b2fSAndreas Jaekel "ZVOL_WRITE", 2916ff6b2fSAndreas Jaekel "ZVOL_TRUNCATE", 3016ff6b2fSAndreas Jaekel "ZNODE_CLOSE_AFTER_UPDATE", 3116ff6b2fSAndreas Jaekel "ZNODE_CREATE", 3216ff6b2fSAndreas Jaekel "ZNODE_MKDIR", 3316ff6b2fSAndreas Jaekel "ZNODE_MAKE_XATTR_DIR", 3416ff6b2fSAndreas Jaekel "ZNODE_REMOVE", 3516ff6b2fSAndreas Jaekel "ZNODE_RMDIR", 3616ff6b2fSAndreas Jaekel "ZNODE_LINK", 3716ff6b2fSAndreas Jaekel "ZNODE_SYMLINK", 3816ff6b2fSAndreas Jaekel "ZNODE_RENAME", 3916ff6b2fSAndreas Jaekel "ZNODE_WRITE", 4016ff6b2fSAndreas Jaekel "ZNODE_TRUNCATE", 4116ff6b2fSAndreas Jaekel "ZNODE_SETATTR", 4216ff6b2fSAndreas Jaekel "ZNODE_ACL", 43aafc540fSAndreas Jaekel NULL 44aafc540fSAndreas Jaekel }; 45aafc540fSAndreas Jaekel 46a5090b97SAndreas Jaekel #define MD_STATISTICS 1 47a5090b97SAndreas Jaekel #define MD_POLL_EVENTS 2 48a5090b97SAndreas Jaekel #define MD_CHECKSUMS 3 49a5090b97SAndreas Jaekel #define MD_DEBUG_INFO 4 50a5090b97SAndreas Jaekel #define MD_LIST_QUEUES 5 51a5090b97SAndreas Jaekel #define MD_SET_GLOBAL_MAX_QUEUE_LEN 6 52a5090b97SAndreas Jaekel #define MD_SET_MAX_QUEUE_LEN 7 53a5090b97SAndreas Jaekel #define MD_SET_POLL_WAKEUP_QUEUE_LEN 8 54a5090b97SAndreas Jaekel #define MD_MUTE_POOL 9 55a5090b97SAndreas Jaekel #define MD_UNMUTE_POOL 10 56a5090b97SAndreas Jaekel #define MD_MARK 11 57a5090b97SAndreas Jaekel #define MD_ADD_QUEUE 12 58a5090b97SAndreas Jaekel #define MD_ADD_BLOCKING_QUEUE 13 59a5090b97SAndreas Jaekel #define MD_REMOVE_QUEUE 14 60a5090b97SAndreas Jaekel #define MD_QUEUE_BLOCKING 15 61a5090b97SAndreas Jaekel #define MD_QUEUE_NONBLOCKING 16 62a5090b97SAndreas Jaekel #define MD_QUEUE_PROPERTIES 17 63b690436dSAndreas Jaekel #define MD_ZEVSTAT 18 64f432e238SAndreas Jaekel #define MD_ZEV_REPORT 19 65*35526fb3SArne Jansen #define MD_DUMP_SPOOL 20 66a5090b97SAndreas Jaekel 67205ed6bfSAndreas Jaekel static int verbose = 0; 6816ff6b2fSAndreas Jaekel static int grep_friendly = 0; 6916ff6b2fSAndreas Jaekel 7016ff6b2fSAndreas Jaekel static void 7116ff6b2fSAndreas Jaekel zpf(char *fmt, ...) 7216ff6b2fSAndreas Jaekel { 7316ff6b2fSAndreas Jaekel va_list ap; 7416ff6b2fSAndreas Jaekel 7516ff6b2fSAndreas Jaekel va_start(ap, fmt); 7616ff6b2fSAndreas Jaekel vprintf(fmt, ap); 7716ff6b2fSAndreas Jaekel va_end(ap); 7816ff6b2fSAndreas Jaekel if (grep_friendly) { 7916ff6b2fSAndreas Jaekel printf(" "); 8016ff6b2fSAndreas Jaekel } else { 8116ff6b2fSAndreas Jaekel printf("\n"); 8216ff6b2fSAndreas Jaekel } 8316ff6b2fSAndreas Jaekel } 8416ff6b2fSAndreas Jaekel 8516ff6b2fSAndreas Jaekel static void 8616ff6b2fSAndreas Jaekel znl(void) 8716ff6b2fSAndreas Jaekel { 8816ff6b2fSAndreas Jaekel if (grep_friendly) 8916ff6b2fSAndreas Jaekel printf("\n"); 9016ff6b2fSAndreas Jaekel } 91205ed6bfSAndreas Jaekel 922eabeab5SAndreas Jaekel static void 932eabeab5SAndreas Jaekel sig2hex_direct(const uint8_t *sig, char *hex) 942eabeab5SAndreas Jaekel { 952eabeab5SAndreas Jaekel int i; 962eabeab5SAndreas Jaekel 972eabeab5SAndreas Jaekel for (i = 0; i < SHA1_DIGEST_LENGTH; ++i) { 982eabeab5SAndreas Jaekel sprintf(hex + 2 * i, "%02x", sig[i]); 992eabeab5SAndreas Jaekel } 1002eabeab5SAndreas Jaekel hex[SHA1_DIGEST_LENGTH * 2] = '\0'; 1012eabeab5SAndreas Jaekel } 1022eabeab5SAndreas Jaekel 103add9520fSAndreas Jaekel static int 104a18c35b9SAndreas Jaekel zev_statistics(int fd) 105a18c35b9SAndreas Jaekel { 106a18c35b9SAndreas Jaekel zev_statistics_t zs; 107add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) { 108a18c35b9SAndreas Jaekel perror("getting statistics data failed"); 109add9520fSAndreas Jaekel return (EXIT_FAILURE); 110a18c35b9SAndreas Jaekel } 111a18c35b9SAndreas Jaekel printf("ZEV module state:\n"); 112a18c35b9SAndreas Jaekel 113a18c35b9SAndreas Jaekel printf(" queue length in bytes : %lu\n", zs.zev_queue_len); 114a18c35b9SAndreas Jaekel printf(" queue length limit : %lu\n", zs.zev_max_queue_len); 115a18c35b9SAndreas Jaekel printf(" bytes read from device : %lu\n", zs.zev_bytes_read); 116a18c35b9SAndreas Jaekel printf(" module internal errors : %lu\n\n", zs.zev_cnt_errors); 117a18c35b9SAndreas Jaekel 118add9520fSAndreas Jaekel printf(" discarded events : %lu\n", 119add9520fSAndreas Jaekel zs.zev_cnt_discarded_events); 120add9520fSAndreas Jaekel printf(" discarded bytes : %lu\n\n", zs.zev_bytes_discarded); 121add9520fSAndreas Jaekel 122a18c35b9SAndreas Jaekel printf("ZFS event statistics:\n"); 123a18c35b9SAndreas Jaekel 124a18c35b9SAndreas Jaekel printf(" total ZFS events : %lu\n", zs.zev_cnt_total_events); 125a18c35b9SAndreas Jaekel printf(" ZFS mount : %lu\n", zs.zev_cnt_zfs_mount); 126a18c35b9SAndreas Jaekel printf(" ZFS umount : %lu\n", zs.zev_cnt_zfs_umount); 127a18c35b9SAndreas Jaekel printf(" ZVOL write : %lu\n", zs.zev_cnt_zvol_write); 128a18c35b9SAndreas Jaekel printf(" ZVOL truncate : %lu\n", zs.zev_cnt_zvol_truncate); 129a18c35b9SAndreas Jaekel printf(" ZNODE close after update: %lu\n", 130a18c35b9SAndreas Jaekel zs.zev_cnt_znode_close_after_update); 131a18c35b9SAndreas Jaekel printf(" ZNODE create : %lu\n", zs.zev_cnt_znode_create); 132a18c35b9SAndreas Jaekel printf(" ZNODE remove : %lu\n", zs.zev_cnt_znode_remove); 133a18c35b9SAndreas Jaekel printf(" ZNODE link : %lu\n", zs.zev_cnt_znode_link); 134a18c35b9SAndreas Jaekel printf(" ZNODE symlink : %lu\n", zs.zev_cnt_znode_symlink); 135a18c35b9SAndreas Jaekel printf(" ZNODE rename : %lu\n", zs.zev_cnt_znode_rename); 136a18c35b9SAndreas Jaekel printf(" ZNODE write : %lu\n", zs.zev_cnt_znode_write); 137a18c35b9SAndreas Jaekel printf(" ZNODE truncate : %lu\n", 138a18c35b9SAndreas Jaekel zs.zev_cnt_znode_truncate); 139a18c35b9SAndreas Jaekel printf(" ZNODE setattr : %lu\n", zs.zev_cnt_znode_setattr); 140a18c35b9SAndreas Jaekel printf(" ZNODE acl : %lu\n", zs.zev_cnt_znode_acl); 141add9520fSAndreas Jaekel return EXIT_SUCCESS; 142a18c35b9SAndreas Jaekel } 143a18c35b9SAndreas Jaekel 144a18c35b9SAndreas Jaekel static void 14516ff6b2fSAndreas Jaekel zev_print_inode_info(char *name, zev_inode_info_t *info) 14616ff6b2fSAndreas Jaekel { 14716ff6b2fSAndreas Jaekel zpf(" %s.inode: %llu", name, info->ino); 14816ff6b2fSAndreas Jaekel zpf(" %s.gen: %llu", name, info->gen); 14916ff6b2fSAndreas Jaekel zpf(" %s.mtime: %llu", name, info->mtime); 15016ff6b2fSAndreas Jaekel zpf(" %s.ctime: %llu", name, info->ctime); 15116ff6b2fSAndreas Jaekel zpf(" %s.size: %llu", name, info->size); 15216ff6b2fSAndreas Jaekel zpf(" %s.mode: %llo", name, info->mode); 15316ff6b2fSAndreas Jaekel zpf(" %s.links: %llu", name, info->links); 15416ff6b2fSAndreas Jaekel zpf(" %s.type: %lu", name, info->type); 15516ff6b2fSAndreas Jaekel zpf(" %s.flags: %lu", name, info->flags); 15616ff6b2fSAndreas Jaekel } 15716ff6b2fSAndreas Jaekel 15816ff6b2fSAndreas Jaekel static void 15916ff6b2fSAndreas Jaekel zev_print_mark_payload(zev_mark_t *rec) 16016ff6b2fSAndreas Jaekel { 16116ff6b2fSAndreas Jaekel int i; 16216ff6b2fSAndreas Jaekel int j; 16316ff6b2fSAndreas Jaekel uint8_t *p; 16416ff6b2fSAndreas Jaekel char c; 16516ff6b2fSAndreas Jaekel 16616ff6b2fSAndreas Jaekel zpf(" payload:"); 16716ff6b2fSAndreas Jaekel p = (uint8_t *)ZEV_PAYLOAD(rec); 16816ff6b2fSAndreas Jaekel for (i=0; i<rec->payload_len; i+=16) { 16916ff6b2fSAndreas Jaekel printf(" "); 17016ff6b2fSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) { 17116ff6b2fSAndreas Jaekel printf("%02x ", p[j]); 17216ff6b2fSAndreas Jaekel if (j == i + 7) 17316ff6b2fSAndreas Jaekel printf(" "); 17416ff6b2fSAndreas Jaekel } 17516ff6b2fSAndreas Jaekel if (grep_friendly) 17616ff6b2fSAndreas Jaekel continue; 17716ff6b2fSAndreas Jaekel for (; j<i+16; j++) { 17816ff6b2fSAndreas Jaekel printf(" "); 17916ff6b2fSAndreas Jaekel if (j == i + 7) 18016ff6b2fSAndreas Jaekel printf(" "); 18116ff6b2fSAndreas Jaekel } 18216ff6b2fSAndreas Jaekel printf(" "); 18316ff6b2fSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) { 18416ff6b2fSAndreas Jaekel c = '.'; 18516ff6b2fSAndreas Jaekel if (p[j] >= ' ' && p[j] <= '~') 18616ff6b2fSAndreas Jaekel c = p[j]; 18716ff6b2fSAndreas Jaekel printf("%c", c); 18816ff6b2fSAndreas Jaekel if (j == i + 7) 18916ff6b2fSAndreas Jaekel printf(" "); 19016ff6b2fSAndreas Jaekel } 19116ff6b2fSAndreas Jaekel printf("\n"); 19216ff6b2fSAndreas Jaekel } 19316ff6b2fSAndreas Jaekel } 19416ff6b2fSAndreas Jaekel 19516ff6b2fSAndreas Jaekel static void 196f2dd45e5SAndreas Jaekel zev_print_error(char *buf) 197f2dd45e5SAndreas Jaekel { 198f2dd45e5SAndreas Jaekel zev_error_t *rec = (zev_error_t *)buf; 199f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 200f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 201f2dd45e5SAndreas Jaekel 20216ff6b2fSAndreas Jaekel if (verbose) { 20316ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 20416ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 20516ff6b2fSAndreas Jaekel zpf(" failed.op: %s", 20616ff6b2fSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN]); 20716ff6b2fSAndreas Jaekel zpf(" message: %s", ZEV_ERRSTR(rec)); 20816ff6b2fSAndreas Jaekel znl(); 20916ff6b2fSAndreas Jaekel } else { 210f2dd45e5SAndreas Jaekel printf("%s %s: failed_op=%s msg=%s\n", 211f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 21216ff6b2fSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN], 21316ff6b2fSAndreas Jaekel ZEV_ERRSTR(rec)); 21416ff6b2fSAndreas Jaekel } 215f2dd45e5SAndreas Jaekel } 216f2dd45e5SAndreas Jaekel 217f2dd45e5SAndreas Jaekel static void 218888fea18SAndreas Jaekel zev_print_mark(char *buf) 219888fea18SAndreas Jaekel { 220888fea18SAndreas Jaekel zev_mark_t *rec = (zev_mark_t *)buf; 221888fea18SAndreas Jaekel time_t op_time = rec->op_time; 222888fea18SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 223888fea18SAndreas Jaekel 22416ff6b2fSAndreas Jaekel if (verbose) { 22516ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 22616ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 22716ff6b2fSAndreas Jaekel zpf(" mark.id: %llu", rec->mark_id); 22816ff6b2fSAndreas Jaekel zpf(" payload.len: %llu", rec->payload_len); 22916ff6b2fSAndreas Jaekel if (rec->payload_len) 23016ff6b2fSAndreas Jaekel zev_print_mark_payload(rec); 23116ff6b2fSAndreas Jaekel znl(); 23216ff6b2fSAndreas Jaekel } else { 233647b4f9eSJan Schlien printf("%s %s: guid=%llu mark_id=%lld payload_len=%ld " 234647b4f9eSJan Schlien "payload=\"%.*s\"\n", 23516ff6b2fSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], rec->guid, 236647b4f9eSJan Schlien rec->mark_id, rec->payload_len, 237647b4f9eSJan Schlien rec->payload_len, (char *)(rec + 1)); 23816ff6b2fSAndreas Jaekel } 239888fea18SAndreas Jaekel } 240888fea18SAndreas Jaekel 241888fea18SAndreas Jaekel static void 242f2dd45e5SAndreas Jaekel zev_print_zfs_mount(char *buf) 243f2dd45e5SAndreas Jaekel { 244f2dd45e5SAndreas Jaekel zev_zfs_mount_t *rec = (zev_zfs_mount_t *)buf; 245f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 246f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 247f2dd45e5SAndreas Jaekel 24816ff6b2fSAndreas Jaekel if (verbose) { 24916ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 25016ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 25116ff6b2fSAndreas Jaekel zpf(" dataset: %s", ZEV_DATASET(rec)); 25216ff6b2fSAndreas Jaekel zpf(" mountpoint: %s", ZEV_MOUNTPOINT(rec)); 25316ff6b2fSAndreas Jaekel zpf(" remount: %s", rec->remount ? "true" : "false"); 25416ff6b2fSAndreas Jaekel zev_print_inode_info("root", &rec->root); 25516ff6b2fSAndreas Jaekel znl(); 25616ff6b2fSAndreas Jaekel } else { 25716ff6b2fSAndreas Jaekel printf("%s %s: guid=%llu remount=%s dataset='%s' " 25816ff6b2fSAndreas Jaekel "mountpoint='%s'\n", 259f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 260f2dd45e5SAndreas Jaekel rec->guid, 261f2dd45e5SAndreas Jaekel rec->remount ? "true" : "false", 262f2dd45e5SAndreas Jaekel ZEV_DATASET(rec), 263f2dd45e5SAndreas Jaekel ZEV_MOUNTPOINT(rec)); 264f2dd45e5SAndreas Jaekel } 26516ff6b2fSAndreas Jaekel } 266f2dd45e5SAndreas Jaekel 267f2dd45e5SAndreas Jaekel static void 268f2dd45e5SAndreas Jaekel zev_print_zfs_umount(char *buf) 269f2dd45e5SAndreas Jaekel { 270f2dd45e5SAndreas Jaekel zev_zfs_umount_t *rec = (zev_zfs_umount_t *)buf; 271f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 272f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 273f2dd45e5SAndreas Jaekel 27416ff6b2fSAndreas Jaekel if (verbose) { 27516ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 27616ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 27794875cb8SAndreas Jaekel zev_print_inode_info("covered", &rec->covered); 27816ff6b2fSAndreas Jaekel znl(); 27916ff6b2fSAndreas Jaekel } else { 280f2dd45e5SAndreas Jaekel printf("%s %s: guid=%llu\n", 281f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 282f2dd45e5SAndreas Jaekel rec->guid); 283f2dd45e5SAndreas Jaekel } 28416ff6b2fSAndreas Jaekel } 285f2dd45e5SAndreas Jaekel 286f2dd45e5SAndreas Jaekel static void 287f2dd45e5SAndreas Jaekel zev_print_zvol_truncate(char *buf) 288f2dd45e5SAndreas Jaekel { 289f2dd45e5SAndreas Jaekel zev_zvol_truncate_t *rec = (zev_zvol_truncate_t *)buf; 290f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 291f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 292f2dd45e5SAndreas Jaekel 29316ff6b2fSAndreas Jaekel if (verbose) { 29416ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 29516ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 29612119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 29716ff6b2fSAndreas Jaekel zpf(" offset: %llu", rec->offset); 29816ff6b2fSAndreas Jaekel zpf(" length: %llu", rec->length); 29916ff6b2fSAndreas Jaekel znl(); 30016ff6b2fSAndreas Jaekel } else { 301f2dd45e5SAndreas Jaekel printf("%s %s: guid=%llu offset=%llu length=%llu\n", 302f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 303f2dd45e5SAndreas Jaekel rec->guid, 304f2dd45e5SAndreas Jaekel rec->offset, 305f2dd45e5SAndreas Jaekel rec->length); 306f2dd45e5SAndreas Jaekel } 30716ff6b2fSAndreas Jaekel } 308f2dd45e5SAndreas Jaekel 309f2dd45e5SAndreas Jaekel static void 310f2dd45e5SAndreas Jaekel zev_print_zvol_write(char *buf) 311f2dd45e5SAndreas Jaekel { 312f2dd45e5SAndreas Jaekel zev_print_zvol_truncate(buf); 313f2dd45e5SAndreas Jaekel } 314f2dd45e5SAndreas Jaekel 315f2dd45e5SAndreas Jaekel static void 316f2dd45e5SAndreas Jaekel zev_print_znode_close_after_update(char *buf) 317f2dd45e5SAndreas Jaekel { 318f2dd45e5SAndreas Jaekel zev_znode_close_after_update_t *rec = 319f2dd45e5SAndreas Jaekel (zev_znode_close_after_update_t *)buf; 320f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 321f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 322f2dd45e5SAndreas Jaekel 32316ff6b2fSAndreas Jaekel if (verbose) { 32416ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 32516ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 32616ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 32716ff6b2fSAndreas Jaekel znl(); 32816ff6b2fSAndreas Jaekel } else { 329f2dd45e5SAndreas Jaekel printf("%s %s: guid=%llu file=%llu.%llu\n", 330f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 331f2dd45e5SAndreas Jaekel rec->guid, 332f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen); 333f2dd45e5SAndreas Jaekel } 33416ff6b2fSAndreas Jaekel } 335f2dd45e5SAndreas Jaekel 336f2dd45e5SAndreas Jaekel static void 337f2dd45e5SAndreas Jaekel zev_print_znode_create(char *buf) 338f2dd45e5SAndreas Jaekel { 339f2dd45e5SAndreas Jaekel zev_znode_create_t *rec = (zev_znode_create_t *)buf; 340f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 341f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 3422eabeab5SAndreas Jaekel zev_sig_t *sig; 3432eabeab5SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 344f2dd45e5SAndreas Jaekel 34516ff6b2fSAndreas Jaekel if (verbose) { 34616ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 34716ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 34812119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 34916ff6b2fSAndreas Jaekel zpf(" name: '%s'", ZEV_NAME(rec)); 3502eabeab5SAndreas Jaekel sig = &rec->signature; 3512eabeab5SAndreas Jaekel sig2hex_direct(sig->value, sigval); 3522eabeab5SAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s", 3532eabeab5SAndreas Jaekel sig->level, sig->block_offset, sigval); 35416ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 35512119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent); 35616ff6b2fSAndreas Jaekel znl(); 35716ff6b2fSAndreas Jaekel } else { 35835d4e8ddSAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu file=%llu.%llu " 35935d4e8ddSAndreas Jaekel "file.mtime=%llu, parent.mtime=%llu, name='%s'\n", 360f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 361f2dd45e5SAndreas Jaekel rec->guid, 362f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen, 363f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen, 36435d4e8ddSAndreas Jaekel rec->file.mtime, rec->parent.mtime, 365f2dd45e5SAndreas Jaekel ZEV_NAME(rec)); 366f2dd45e5SAndreas Jaekel } 36716ff6b2fSAndreas Jaekel } 368f2dd45e5SAndreas Jaekel 369f2dd45e5SAndreas Jaekel static void 370f2dd45e5SAndreas Jaekel zev_print_znode_mkdir(char *buf) 371f2dd45e5SAndreas Jaekel { 372f2dd45e5SAndreas Jaekel zev_print_znode_create(buf); 373f2dd45e5SAndreas Jaekel } 374f2dd45e5SAndreas Jaekel 375f2dd45e5SAndreas Jaekel static void 376f2dd45e5SAndreas Jaekel zev_print_znode_make_xattr_dir(char *buf) 377f2dd45e5SAndreas Jaekel { 378f2dd45e5SAndreas Jaekel zev_print_znode_create(buf); 379f2dd45e5SAndreas Jaekel } 380f2dd45e5SAndreas Jaekel 381f2dd45e5SAndreas Jaekel static void 382f2dd45e5SAndreas Jaekel zev_print_znode_remove(char *buf) 383f2dd45e5SAndreas Jaekel { 384f2dd45e5SAndreas Jaekel zev_znode_remove_t *rec = (zev_znode_remove_t *)buf; 385f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 386f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 387f2dd45e5SAndreas Jaekel 38816ff6b2fSAndreas Jaekel if (verbose) { 38916ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 39016ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 39112119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 39216ff6b2fSAndreas Jaekel zpf(" file.name: '%s'", ZEV_NAME(rec)); 39316ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 39412119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent); 39516ff6b2fSAndreas Jaekel znl(); 39616ff6b2fSAndreas Jaekel } else { 39716ff6b2fSAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu " 39816ff6b2fSAndreas Jaekel "file.mtime=%llu name='%s'\n", 399f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 400f2dd45e5SAndreas Jaekel rec->guid, 401f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen, 40297dcf88dSAndreas Jaekel rec->file.mtime, 403f2dd45e5SAndreas Jaekel ZEV_NAME(rec)); 404f2dd45e5SAndreas Jaekel } 40516ff6b2fSAndreas Jaekel } 406f2dd45e5SAndreas Jaekel 407f2dd45e5SAndreas Jaekel static void 408f2dd45e5SAndreas Jaekel zev_print_znode_rmdir(char *buf) 409f2dd45e5SAndreas Jaekel { 410f2dd45e5SAndreas Jaekel zev_print_znode_remove(buf); 411f2dd45e5SAndreas Jaekel } 412f2dd45e5SAndreas Jaekel 413f2dd45e5SAndreas Jaekel static void 414f2dd45e5SAndreas Jaekel zev_print_znode_link(char *buf) 415f2dd45e5SAndreas Jaekel { 416f2dd45e5SAndreas Jaekel zev_znode_link_t *rec = (zev_znode_link_t *)buf; 417f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 418f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 419f2dd45e5SAndreas Jaekel 42016ff6b2fSAndreas Jaekel if (verbose) { 42116ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 42216ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 42312119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 42416ff6b2fSAndreas Jaekel zpf(" link.name: '%s'", ZEV_NAME(rec)); 42516ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 42612119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent); 42716ff6b2fSAndreas Jaekel znl(); 42816ff6b2fSAndreas Jaekel } else { 429a01b300aSAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu " 430a01b300aSAndreas Jaekel "file.ctime=%llu parent.ctime=%llu name='%s'\n", 431f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 432f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen, 433f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen, 434a01b300aSAndreas Jaekel rec->file.ctime, rec->parent.ctime, 435f2dd45e5SAndreas Jaekel ZEV_NAME(rec)); 43616ff6b2fSAndreas Jaekel } 437f2dd45e5SAndreas Jaekel } 438f2dd45e5SAndreas Jaekel 439f2dd45e5SAndreas Jaekel static void 440f2dd45e5SAndreas Jaekel zev_print_znode_symlink(char *buf) 441f2dd45e5SAndreas Jaekel { 442f2dd45e5SAndreas Jaekel zev_znode_symlink_t *rec = (zev_znode_symlink_t *)buf; 443f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 444f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 4452eabeab5SAndreas Jaekel zev_sig_t *sig; 4462eabeab5SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 447f2dd45e5SAndreas Jaekel 44816ff6b2fSAndreas Jaekel if (verbose) { 44916ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 45016ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 45112119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 45216ff6b2fSAndreas Jaekel zpf(" symlink.name: '%s'", ZEV_NAME(rec)); 45316ff6b2fSAndreas Jaekel zpf(" symlink.link: '%s'", ZEV_LINK(rec)); 4542eabeab5SAndreas Jaekel sig = &rec->signature; 4552eabeab5SAndreas Jaekel sig2hex_direct(sig->value, sigval); 4562eabeab5SAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s", 4572eabeab5SAndreas Jaekel sig->level, sig->block_offset, sigval); 45816ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 45912119a7eSAndreas Jaekel zev_print_inode_info("parent", &rec->parent); 46016ff6b2fSAndreas Jaekel znl(); 46116ff6b2fSAndreas Jaekel } else { 46216ff6b2fSAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu " 46316ff6b2fSAndreas Jaekel "name='%s' link='%s'\n", 464f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 465f2dd45e5SAndreas Jaekel rec->parent.ino, rec->parent.gen, 466f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen, 467f2dd45e5SAndreas Jaekel ZEV_NAME(rec), 468f2dd45e5SAndreas Jaekel ZEV_LINK(rec)); 469f2dd45e5SAndreas Jaekel } 47016ff6b2fSAndreas Jaekel } 471f2dd45e5SAndreas Jaekel 472f2dd45e5SAndreas Jaekel static void 473f2dd45e5SAndreas Jaekel zev_print_znode_rename(char *buf) 474f2dd45e5SAndreas Jaekel { 475f2dd45e5SAndreas Jaekel zev_znode_rename_t *rec = (zev_znode_rename_t *)buf; 476f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 477f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 478f2dd45e5SAndreas Jaekel 47916ff6b2fSAndreas Jaekel if (verbose) { 48016ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 48116ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 48212119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 48316ff6b2fSAndreas Jaekel zpf(" file.srcname: '%s'", ZEV_SRCNAME(rec)); 48416ff6b2fSAndreas Jaekel zpf(" file.dstname: '%s'", ZEV_DSTNAME(rec)); 48516ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 4868aa47a6bSAndreas Jaekel if (rec->clobbered_file.ino) 4878aa47a6bSAndreas Jaekel zev_print_inode_info("clobbered_file", 4888aa47a6bSAndreas Jaekel &rec->clobbered_file); 48916ff6b2fSAndreas Jaekel zev_print_inode_info("srcdir", &rec->srcdir); 49016ff6b2fSAndreas Jaekel zev_print_inode_info("dstdir", &rec->dstdir); 49116ff6b2fSAndreas Jaekel znl(); 49216ff6b2fSAndreas Jaekel } else { 49316ff6b2fSAndreas Jaekel printf("%s %s: srcdir=%llu.%llu dstdir=%llu.%llu " 49416ff6b2fSAndreas Jaekel "file=%llu.%llu file.mtime=%llu, file.ctime=%llu, " 49516ff6b2fSAndreas Jaekel "srcdir.mtime=%llu, srcdir.ctime=%llu, " 49616ff6b2fSAndreas Jaekel "dstdir.mtime=%llu, dstdir.ctime=%llu, " 497f2dd45e5SAndreas Jaekel "srcname='%s' dstname='%s'\n", 498f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 499f2dd45e5SAndreas Jaekel rec->srcdir.ino, rec->srcdir.gen, 500f2dd45e5SAndreas Jaekel rec->dstdir.ino, rec->dstdir.gen, 501f2dd45e5SAndreas Jaekel rec->file.ino, rec->file.gen, 50235d4e8ddSAndreas Jaekel rec->file.mtime, rec->file.ctime, 50335d4e8ddSAndreas Jaekel rec->srcdir.mtime, rec->srcdir.ctime, 50435d4e8ddSAndreas Jaekel rec->dstdir.mtime, rec->dstdir.ctime, 505f2dd45e5SAndreas Jaekel ZEV_SRCNAME(rec), 506f2dd45e5SAndreas Jaekel ZEV_DSTNAME(rec)); 507f2dd45e5SAndreas Jaekel } 50816ff6b2fSAndreas Jaekel } 509f2dd45e5SAndreas Jaekel 510f2dd45e5SAndreas Jaekel static void 511f2dd45e5SAndreas Jaekel zev_print_znode_write(char *buf) 512f2dd45e5SAndreas Jaekel { 513f2dd45e5SAndreas Jaekel zev_znode_write_t *rec = (zev_znode_write_t *)buf; 514f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 515f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 516205ed6bfSAndreas Jaekel zev_sig_t *sig; 517205ed6bfSAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 518205ed6bfSAndreas Jaekel int i; 519f2dd45e5SAndreas Jaekel 520205ed6bfSAndreas Jaekel if (verbose) { 52116ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 52216ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 52312119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 52416ff6b2fSAndreas Jaekel zpf(" offset: %llu", rec->offset); 52516ff6b2fSAndreas Jaekel zpf(" length: %llu", rec->length); 52616ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 52716ff6b2fSAndreas Jaekel znl(); 528205ed6bfSAndreas Jaekel for (i=0; i<rec->signature_cnt; i++) { 529205ed6bfSAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(rec); 530205ed6bfSAndreas Jaekel sig += i; 531205ed6bfSAndreas Jaekel sig2hex_direct(sig->value, sigval); 5322eabeab5SAndreas Jaekel zpf(" sig: level %d, offset %llu, value %s", 533205ed6bfSAndreas Jaekel sig->level, sig->block_offset, sigval); 534205ed6bfSAndreas Jaekel } 53516ff6b2fSAndreas Jaekel } else { 53616ff6b2fSAndreas Jaekel printf("%s %s: file=%llu.%llu offset=%llu length=%llu\n", 53716ff6b2fSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 53816ff6b2fSAndreas Jaekel rec->file.ino, rec->file.gen, 53916ff6b2fSAndreas Jaekel rec->offset, rec->length); 540205ed6bfSAndreas Jaekel } 541f2dd45e5SAndreas Jaekel } 542f2dd45e5SAndreas Jaekel 543f2dd45e5SAndreas Jaekel static void 544f2dd45e5SAndreas Jaekel zev_print_znode_truncate(char *buf) 545f2dd45e5SAndreas Jaekel { 546f2dd45e5SAndreas Jaekel zev_print_znode_write(buf); 547f2dd45e5SAndreas Jaekel } 548f2dd45e5SAndreas Jaekel 549f2dd45e5SAndreas Jaekel static void 550f2dd45e5SAndreas Jaekel zev_print_znode_setattr(char *buf) 551f2dd45e5SAndreas Jaekel { 552f2dd45e5SAndreas Jaekel zev_znode_setattr_t *rec = (zev_znode_setattr_t *)buf; 553f2dd45e5SAndreas Jaekel time_t op_time = rec->op_time; 554f2dd45e5SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 555f2dd45e5SAndreas Jaekel 55616ff6b2fSAndreas Jaekel if (verbose) { 55716ff6b2fSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 55816ff6b2fSAndreas Jaekel zpf(" guid: %llu", rec->guid); 55912119a7eSAndreas Jaekel zpf(" txg: %llu", rec->txg); 56016ff6b2fSAndreas Jaekel zev_print_inode_info("file", &rec->file); 56116ff6b2fSAndreas Jaekel znl(); 56216ff6b2fSAndreas Jaekel } else { 56335d4e8ddSAndreas Jaekel printf("%s %s: file=%llu.%llu mtime=%llu\n", 564f2dd45e5SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 56535d4e8ddSAndreas Jaekel rec->file.ino, rec->file.gen, rec->file.mtime); 566f2dd45e5SAndreas Jaekel } 56716ff6b2fSAndreas Jaekel } 568f2dd45e5SAndreas Jaekel 569f2dd45e5SAndreas Jaekel static void 570f2dd45e5SAndreas Jaekel zev_print_znode_acl(char *buf) 571f2dd45e5SAndreas Jaekel { 572f2dd45e5SAndreas Jaekel zev_print_znode_setattr(buf); 573f2dd45e5SAndreas Jaekel } 574f2dd45e5SAndreas Jaekel 575f2dd45e5SAndreas Jaekel static void 576aafc540fSAndreas Jaekel zev_print_event(char *buf, int len) 577aafc540fSAndreas Jaekel { 578f2dd45e5SAndreas Jaekel int record_len; 579f2dd45e5SAndreas Jaekel int op; 580aafc540fSAndreas Jaekel 581f2dd45e5SAndreas Jaekel record_len = *(uint32_t *)buf; 582f2dd45e5SAndreas Jaekel if (record_len != len) { 583f2dd45e5SAndreas Jaekel fprintf(stderr, "record length mismatch: got %d, expected %d\n", 584f2dd45e5SAndreas Jaekel record_len, len); 585aafc540fSAndreas Jaekel exit(1); 586aafc540fSAndreas Jaekel } 587f2dd45e5SAndreas Jaekel op = *((uint32_t *)buf + 1); 588aafc540fSAndreas Jaekel if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) { 589f2dd45e5SAndreas Jaekel fprintf(stderr, "unknown op code: %d\n", op); 590aafc540fSAndreas Jaekel exit(1); 591aafc540fSAndreas Jaekel } 592f2dd45e5SAndreas Jaekel switch (op) { 593f2dd45e5SAndreas Jaekel case ZEV_OP_ERROR: 594f2dd45e5SAndreas Jaekel zev_print_error(buf); 595aafc540fSAndreas Jaekel break; 596888fea18SAndreas Jaekel case ZEV_OP_MARK: 597888fea18SAndreas Jaekel zev_print_mark(buf); 598888fea18SAndreas Jaekel break; 599f2dd45e5SAndreas Jaekel case ZEV_OP_ZFS_MOUNT: 600f2dd45e5SAndreas Jaekel zev_print_zfs_mount(buf); 601aafc540fSAndreas Jaekel break; 602f2dd45e5SAndreas Jaekel case ZEV_OP_ZFS_UMOUNT: 603f2dd45e5SAndreas Jaekel zev_print_zfs_umount(buf); 604aafc540fSAndreas Jaekel break; 605f2dd45e5SAndreas Jaekel case ZEV_OP_ZVOL_TRUNCATE: 606f2dd45e5SAndreas Jaekel zev_print_zvol_truncate(buf); 607aafc540fSAndreas Jaekel break; 608f2dd45e5SAndreas Jaekel case ZEV_OP_ZVOL_WRITE: 609f2dd45e5SAndreas Jaekel zev_print_zvol_write(buf); 610f2dd45e5SAndreas Jaekel break; 611f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE: 612f2dd45e5SAndreas Jaekel zev_print_znode_close_after_update(buf); 613f2dd45e5SAndreas Jaekel break; 614f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_CREATE: 615f2dd45e5SAndreas Jaekel zev_print_znode_create(buf); 616f2dd45e5SAndreas Jaekel break; 617f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_MKDIR: 618f2dd45e5SAndreas Jaekel zev_print_znode_mkdir(buf); 619f2dd45e5SAndreas Jaekel break; 620f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_MAKE_XATTR_DIR: 621f2dd45e5SAndreas Jaekel zev_print_znode_make_xattr_dir(buf); 622f2dd45e5SAndreas Jaekel break; 623f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_REMOVE: 624f2dd45e5SAndreas Jaekel zev_print_znode_remove(buf); 625f2dd45e5SAndreas Jaekel break; 626f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_RMDIR: 627f2dd45e5SAndreas Jaekel zev_print_znode_rmdir(buf); 628f2dd45e5SAndreas Jaekel break; 629f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_LINK: 630f2dd45e5SAndreas Jaekel zev_print_znode_link(buf); 631f2dd45e5SAndreas Jaekel break; 632f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_SYMLINK: 633f2dd45e5SAndreas Jaekel zev_print_znode_symlink(buf); 634f2dd45e5SAndreas Jaekel break; 635f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_RENAME: 636f2dd45e5SAndreas Jaekel zev_print_znode_rename(buf); 637f2dd45e5SAndreas Jaekel break; 638f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_WRITE: 639f2dd45e5SAndreas Jaekel zev_print_znode_write(buf); 640f2dd45e5SAndreas Jaekel break; 641f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_TRUNCATE: 642f2dd45e5SAndreas Jaekel zev_print_znode_truncate(buf); 643f2dd45e5SAndreas Jaekel break; 644f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_SETATTR: 645f2dd45e5SAndreas Jaekel zev_print_znode_setattr(buf); 646f2dd45e5SAndreas Jaekel break; 647f2dd45e5SAndreas Jaekel case ZEV_OP_ZNODE_ACL: 648f2dd45e5SAndreas Jaekel zev_print_znode_acl(buf); 649aafc540fSAndreas Jaekel break; 650aafc540fSAndreas Jaekel default: 651f2dd45e5SAndreas Jaekel fprintf(stderr, "unhandled op code: %d\n", op); 652aafc540fSAndreas Jaekel exit(1); 653aafc540fSAndreas Jaekel } 654aafc540fSAndreas Jaekel } 655aafc540fSAndreas Jaekel 656add9520fSAndreas Jaekel static int 6576a6a51eeSAndreas Jaekel zev_poll_events(int fd, int create_tmp_queue) 658a18c35b9SAndreas Jaekel { 659a18c35b9SAndreas Jaekel struct pollfd pfd[1]; 660a18c35b9SAndreas Jaekel int ret; 661aafc540fSAndreas Jaekel char buf[4096]; 662d979f56cSAndreas Jaekel zev_event_t *ev; 663d979f56cSAndreas Jaekel int off = 0; 664add9520fSAndreas Jaekel zev_ioctl_add_queue_t aq; 665add9520fSAndreas Jaekel int q_fd; 666add9520fSAndreas Jaekel 6676a6a51eeSAndreas Jaekel if (create_tmp_queue) { 668add9520fSAndreas Jaekel aq.zev_max_queue_len = 0; 669113f4c19SJan Schlien aq.zev_flags = ZEV_FL_INITIALLY_EMPTY; 670add9520fSAndreas Jaekel snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN, 671add9520fSAndreas Jaekel "zevadm.%ld.%ld", time(NULL), getpid()); 672add9520fSAndreas Jaekel aq.zev_namelen = strlen(aq.zev_name); 673add9520fSAndreas Jaekel 674add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) { 675add9520fSAndreas Jaekel perror("adding temporary queue failed"); 676add9520fSAndreas Jaekel return (EXIT_FAILURE); 677add9520fSAndreas Jaekel } 678add9520fSAndreas Jaekel 6796a6a51eeSAndreas Jaekel snprintf(buf, sizeof(buf), 6806a6a51eeSAndreas Jaekel "/devices/pseudo/zev@0:%s", aq.zev_name); 681add9520fSAndreas Jaekel q_fd = open(buf, O_RDONLY); 682add9520fSAndreas Jaekel if (q_fd < 0) { 683add9520fSAndreas Jaekel perror("opening queue device failed"); 684add9520fSAndreas Jaekel return (EXIT_FAILURE); 685add9520fSAndreas Jaekel } 6866a6a51eeSAndreas Jaekel } else { 6876a6a51eeSAndreas Jaekel q_fd = fd; 6886a6a51eeSAndreas Jaekel } 689add9520fSAndreas Jaekel 690a18c35b9SAndreas Jaekel while (1) { 691add9520fSAndreas Jaekel pfd[0].fd = q_fd; 692a18c35b9SAndreas Jaekel pfd[0].events = POLLIN; 693a18c35b9SAndreas Jaekel ret = poll(pfd, 1, 1000); 694a18c35b9SAndreas Jaekel if (ret < 0) { 695a18c35b9SAndreas Jaekel perror("poll failed"); 6966a6a51eeSAndreas Jaekel close(q_fd); 697add9520fSAndreas Jaekel return(EXIT_FAILURE); 698a18c35b9SAndreas Jaekel } 699a18c35b9SAndreas Jaekel if (!(pfd[0].revents & POLLIN)) 700a18c35b9SAndreas Jaekel continue; 701a18c35b9SAndreas Jaekel /* data available */ 702add9520fSAndreas Jaekel ret = read(q_fd, buf, sizeof(buf)); 703a18c35b9SAndreas Jaekel if (ret < 0) { 704a18c35b9SAndreas Jaekel perror("read failed"); 7056a6a51eeSAndreas Jaekel close(q_fd); 706add9520fSAndreas Jaekel return(EXIT_FAILURE); 707a18c35b9SAndreas Jaekel } 708a18c35b9SAndreas Jaekel if (ret == 0) 709a18c35b9SAndreas Jaekel continue; 710d979f56cSAndreas Jaekel while (ret > off) { 711d979f56cSAndreas Jaekel ev = (zev_event_t *)(buf + off); 712d979f56cSAndreas Jaekel zev_print_event(buf + off, ev->header.record_len); 713d979f56cSAndreas Jaekel off += ev->header.record_len; 714d979f56cSAndreas Jaekel } 715149d0affSAndreas Jaekel off = 0; 716a18c35b9SAndreas Jaekel } 7176a6a51eeSAndreas Jaekel if (create_tmp_queue) 718add9520fSAndreas Jaekel close(q_fd); 719add9520fSAndreas Jaekel return EXIT_SUCCESS; 720a18c35b9SAndreas Jaekel } 721a18c35b9SAndreas Jaekel 722*35526fb3SArne Jansen static int 723*35526fb3SArne Jansen zev_dump_spool(int fd) 724*35526fb3SArne Jansen { 725*35526fb3SArne Jansen int len; 726*35526fb3SArne Jansen char buf[4096]; 727*35526fb3SArne Jansen int off = 0; 728*35526fb3SArne Jansen 729*35526fb3SArne Jansen while (1) { 730*35526fb3SArne Jansen len = read(fd, buf + off, sizeof(buf) - off); 731*35526fb3SArne Jansen if (len == -1) { 732*35526fb3SArne Jansen fprintf(stderr, "reading from spool failed: %s\n", 733*35526fb3SArne Jansen strerror(errno)); 734*35526fb3SArne Jansen return EXIT_FAILURE; 735*35526fb3SArne Jansen } 736*35526fb3SArne Jansen if (len == 0) 737*35526fb3SArne Jansen break; 738*35526fb3SArne Jansen 739*35526fb3SArne Jansen len += off; 740*35526fb3SArne Jansen off = 0; 741*35526fb3SArne Jansen while (len > off + sizeof(uint32_t)) { 742*35526fb3SArne Jansen uint32_t evlen; 743*35526fb3SArne Jansen char *mp; 744*35526fb3SArne Jansen zev_event_t *ev; 745*35526fb3SArne Jansen 746*35526fb3SArne Jansen ev = (zev_event_t *)(buf + off); 747*35526fb3SArne Jansen evlen = ev->header.record_len; 748*35526fb3SArne Jansen if (len < off + evlen + 1) 749*35526fb3SArne Jansen break; 750*35526fb3SArne Jansen mp = buf + off + evlen; 751*35526fb3SArne Jansen if (!memchr(mp, 0, len - off - evlen)) 752*35526fb3SArne Jansen break; 753*35526fb3SArne Jansen zev_print_event(buf + off, ev->header.record_len); 754*35526fb3SArne Jansen off += ev->header.record_len + strlen(mp) + 1; 755*35526fb3SArne Jansen } 756*35526fb3SArne Jansen 757*35526fb3SArne Jansen memmove(buf, buf + off, len - off); 758*35526fb3SArne Jansen off = len - off; 759*35526fb3SArne Jansen } 760*35526fb3SArne Jansen 761*35526fb3SArne Jansen return EXIT_SUCCESS; 762*35526fb3SArne Jansen } 763*35526fb3SArne Jansen 764a18c35b9SAndreas Jaekel static void 765a18c35b9SAndreas Jaekel usage(char *progname) 766a18c35b9SAndreas Jaekel { 767add9520fSAndreas Jaekel fprintf(stderr, "usage: %s [-d <dev>] [options]\n", progname); 768add9520fSAndreas Jaekel fprintf(stderr, "\n"); 769add9520fSAndreas Jaekel fprintf(stderr, " Status information:\n"); 770a18c35b9SAndreas Jaekel fprintf(stderr, " -s show zev statistics\n"); 771a18c35b9SAndreas Jaekel fprintf(stderr, " -p poll for ZFS events\n"); 772*35526fb3SArne Jansen fprintf(stderr, " -f <name> dump events from spool\n"); 773add9520fSAndreas Jaekel fprintf(stderr, " -D print zev module debug " 774add9520fSAndreas Jaekel "information\n"); 775b690436dSAndreas Jaekel fprintf(stderr, " -T <interval> <cnt> zevstat mode\n"); 776f432e238SAndreas Jaekel fprintf(stderr, " -R <base filename> zevreport mode\n"); 777add9520fSAndreas Jaekel fprintf(stderr, "\n"); 778add9520fSAndreas Jaekel fprintf(stderr, " Tune zev module settings:\n"); 779add9520fSAndreas Jaekel fprintf(stderr, " -Q <bytes> set maximum event queue " 780add9520fSAndreas Jaekel "length\n"); 781add9520fSAndreas Jaekel fprintf(stderr, " -m <pool> mute pool, no events for " 782add9520fSAndreas Jaekel "this pool\n"); 783a18c35b9SAndreas Jaekel fprintf(stderr, " -M <pool> unmute pool\n"); 784add9520fSAndreas Jaekel fprintf(stderr, "\n"); 785add9520fSAndreas Jaekel fprintf(stderr, " Queue management:\n"); 786add9520fSAndreas Jaekel fprintf(stderr, " -l list queues\n"); 7876a6a51eeSAndreas Jaekel fprintf(stderr, " -a <name> add non-blocking queue\n"); 7886a6a51eeSAndreas Jaekel fprintf(stderr, " -A <name> add blocking queue\n"); 789add9520fSAndreas Jaekel fprintf(stderr, " -r <name> remove queue\n"); 790add9520fSAndreas Jaekel fprintf(stderr, " -b <name> make queue non-blocking " 791add9520fSAndreas Jaekel "(default)\n"); 792add9520fSAndreas Jaekel fprintf(stderr, " -B <name> make queue block when full\n"); 793add9520fSAndreas Jaekel fprintf(stderr, " -P <name> display queue properties\n"); 7946a6a51eeSAndreas Jaekel fprintf(stderr, " -L <name> <bytes> set maximum event queue " 795add9520fSAndreas Jaekel "length\n"); 796add9520fSAndreas Jaekel fprintf(stderr, " -t <name> <bytes> set queue length poll " 797add9520fSAndreas Jaekel "throttle\n"); 798add9520fSAndreas Jaekel fprintf(stderr, "\n"); 799add9520fSAndreas Jaekel fprintf(stderr, " Other options:\n"); 800add9520fSAndreas Jaekel fprintf(stderr, " -d <dev> non-default device file. " 801add9520fSAndreas Jaekel "('%s')\n", ZEV_DEVICE); 8026a6a51eeSAndreas Jaekel fprintf(stderr, " -q <name> use device file for this " 8036a6a51eeSAndreas Jaekel "queue name\n"); 804888fea18SAndreas Jaekel fprintf(stderr, " -k <guid>:<payload> queue mark event\n"); 80542110aacSAndreas Jaekel fprintf(stderr, " -c <filename> list file's content " 80642110aacSAndreas Jaekel "checksums\n"); 80716ff6b2fSAndreas Jaekel fprintf(stderr, " -v verbose: additional output " 808205ed6bfSAndreas Jaekel "for some operations\n"); 80916ff6b2fSAndreas Jaekel fprintf(stderr, " -g grep-friendly event output, " 81016ff6b2fSAndreas Jaekel "one event per line\n"); 811a18c35b9SAndreas Jaekel exit (EXIT_FAILURE); 812a18c35b9SAndreas Jaekel } 813a18c35b9SAndreas Jaekel 81450da9edeSAndreas Jaekel static void 81550da9edeSAndreas Jaekel zevstat_usage(char *progname) 81650da9edeSAndreas Jaekel { 81750da9edeSAndreas Jaekel fprintf(stderr, "usage: %s [-v] <interval> [count]\n", progname); 81850da9edeSAndreas Jaekel fprintf(stderr, " -v verbose, show counters for all event types\n"); 81950da9edeSAndreas Jaekel exit (EXIT_FAILURE); 82050da9edeSAndreas Jaekel } 82150da9edeSAndreas Jaekel 822f432e238SAndreas Jaekel static void 823f432e238SAndreas Jaekel zevreport_usage(char *progname) 824f432e238SAndreas Jaekel { 825f432e238SAndreas Jaekel fprintf(stderr, "usage: %s <output base filename>\n", progname); 826f432e238SAndreas Jaekel exit (EXIT_FAILURE); 827f432e238SAndreas Jaekel } 828f432e238SAndreas Jaekel 829a18c35b9SAndreas Jaekel static int 8306a6a51eeSAndreas Jaekel zev_add_queue(int fd, char *arg, int blocking) 831a18c35b9SAndreas Jaekel { 832add9520fSAndreas Jaekel zev_ioctl_add_queue_t aq; 833add9520fSAndreas Jaekel int namelen; 834a18c35b9SAndreas Jaekel 835add9520fSAndreas Jaekel namelen = strlen(arg); 836add9520fSAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) { 837add9520fSAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg); 838a18c35b9SAndreas Jaekel return (EXIT_FAILURE); 839a18c35b9SAndreas Jaekel } 840add9520fSAndreas Jaekel 841add9520fSAndreas Jaekel aq.zev_namelen = namelen; 842add9520fSAndreas Jaekel strcpy(aq.zev_name, arg); 843c99a1a25SAndreas Jaekel aq.zev_flags = ZEV_FL_PERSISTENT | ZEV_FL_INITIALLY_EMPTY; 8446a6a51eeSAndreas Jaekel if (blocking) { 8456a6a51eeSAndreas Jaekel aq.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 8466a6a51eeSAndreas Jaekel aq.zev_max_queue_len = ZEV_MAX_QUEUE_LEN; 8476a6a51eeSAndreas Jaekel } else { 848add9520fSAndreas Jaekel aq.zev_max_queue_len = (1024 * 1024); 8496a6a51eeSAndreas Jaekel } 850add9520fSAndreas Jaekel 851add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) { 852add9520fSAndreas Jaekel perror("adding queue failed"); 853a18c35b9SAndreas Jaekel return (EXIT_FAILURE); 854a18c35b9SAndreas Jaekel } 855a18c35b9SAndreas Jaekel return (0); 856a18c35b9SAndreas Jaekel } 857a18c35b9SAndreas Jaekel 858a18c35b9SAndreas Jaekel static int 859add9520fSAndreas Jaekel zev_remove_queue(int fd, char *arg) 860fec460f8SAndreas Jaekel { 861add9520fSAndreas Jaekel zev_ioctl_remove_queue_t aq; 862add9520fSAndreas Jaekel int namelen; 863fec460f8SAndreas Jaekel 864add9520fSAndreas Jaekel namelen = strlen(arg); 865add9520fSAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) { 866add9520fSAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg); 867fec460f8SAndreas Jaekel return (EXIT_FAILURE); 868fec460f8SAndreas Jaekel } 869add9520fSAndreas Jaekel 8706a6a51eeSAndreas Jaekel aq.zev_queue_name.zev_namelen = namelen; 8716a6a51eeSAndreas Jaekel strcpy(aq.zev_queue_name.zev_name, arg); 872add9520fSAndreas Jaekel 873add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_REMOVE_QUEUE, &aq)) { 874add9520fSAndreas Jaekel perror("removing queue failed"); 875add9520fSAndreas Jaekel return (EXIT_FAILURE); 876add9520fSAndreas Jaekel } 877add9520fSAndreas Jaekel return (0); 878add9520fSAndreas Jaekel } 879add9520fSAndreas Jaekel 880add9520fSAndreas Jaekel static int 881add9520fSAndreas Jaekel zev_set_global_max_queue_len(int fd, char *arg) 882add9520fSAndreas Jaekel { 883add9520fSAndreas Jaekel uint64_t maxqueuelen; 884add9520fSAndreas Jaekel 885174dc952SAndreas Jaekel if (!arg) { 886174dc952SAndreas Jaekel fprintf(stderr, "missing queue length parameter\n"); 887174dc952SAndreas Jaekel return (EXIT_FAILURE); 888174dc952SAndreas Jaekel } 889174dc952SAndreas Jaekel 890add9520fSAndreas Jaekel errno = 0; 891add9520fSAndreas Jaekel maxqueuelen = strtol(arg, (char **)NULL, 10); 892add9520fSAndreas Jaekel if (errno) { 893add9520fSAndreas Jaekel fprintf(stderr, "invalid queue length parameter: %s\n", arg); 894add9520fSAndreas Jaekel return (EXIT_FAILURE); 895add9520fSAndreas Jaekel } 896add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_MAX_QUEUE_LEN, &maxqueuelen)) { 897add9520fSAndreas Jaekel perror("setting max queue length failed"); 898fec460f8SAndreas Jaekel return (EXIT_FAILURE); 899fec460f8SAndreas Jaekel } 900fec460f8SAndreas Jaekel return (0); 901fec460f8SAndreas Jaekel } 902fec460f8SAndreas Jaekel 903fec460f8SAndreas Jaekel static int 904a18c35b9SAndreas Jaekel zev_mute_unmute_impl(int fd, char *poolname, int mute) 905a18c35b9SAndreas Jaekel { 906a18c35b9SAndreas Jaekel zev_ioctl_poolarg_t pa; 907a18c35b9SAndreas Jaekel int len; 908a18c35b9SAndreas Jaekel int op = mute ? ZEV_IOC_MUTE_POOL : ZEV_IOC_UNMUTE_POOL; 909a18c35b9SAndreas Jaekel len = strlen(poolname); 910a18c35b9SAndreas Jaekel if (len <= 0 || len >= sizeof(pa.zev_poolname)) { 911a18c35b9SAndreas Jaekel fprintf(stderr, "invalid poolname: %s\n", poolname); 912a18c35b9SAndreas Jaekel return (EXIT_FAILURE); 913a18c35b9SAndreas Jaekel } 914a18c35b9SAndreas Jaekel strcpy(pa.zev_poolname, poolname); 915a18c35b9SAndreas Jaekel pa.zev_poolname_len = len; 916a18c35b9SAndreas Jaekel if (ioctl(fd, op, &pa)) { 917a18c35b9SAndreas Jaekel perror("muting pool data failed"); 918a18c35b9SAndreas Jaekel return (EXIT_FAILURE); 919a18c35b9SAndreas Jaekel } 920a18c35b9SAndreas Jaekel return (0); 921a18c35b9SAndreas Jaekel } 922a18c35b9SAndreas Jaekel 923a18c35b9SAndreas Jaekel int 924a18c35b9SAndreas Jaekel zev_mute_pool(int fd, char *poolname) 925a18c35b9SAndreas Jaekel { 926a18c35b9SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 1); 927a18c35b9SAndreas Jaekel } 928a18c35b9SAndreas Jaekel 929a18c35b9SAndreas Jaekel int 930a18c35b9SAndreas Jaekel zev_unmute_pool(int fd, char *poolname) 931a18c35b9SAndreas Jaekel { 932a18c35b9SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 0); 933a18c35b9SAndreas Jaekel } 934a18c35b9SAndreas Jaekel 935888fea18SAndreas Jaekel static int 936add9520fSAndreas Jaekel zev_debug_info(int fd) 937add9520fSAndreas Jaekel { 938add9520fSAndreas Jaekel zev_ioctl_debug_info_t di; 939add9520fSAndreas Jaekel 940add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_DEBUG_INFO, &di)) { 941add9520fSAndreas Jaekel perror("getting zev debug info failed"); 942add9520fSAndreas Jaekel return (EXIT_FAILURE); 943add9520fSAndreas Jaekel } 944add9520fSAndreas Jaekel 945add9520fSAndreas Jaekel printf("memory allocated: %llu bytes\n", di.zev_memory_allocated); 946205ed6bfSAndreas Jaekel printf("checksum cache size: %llu\n", di.zev_chksum_cache_size); 947205ed6bfSAndreas Jaekel printf("checksum cache hits: %llu\n", di.zev_chksum_cache_hits); 948205ed6bfSAndreas Jaekel printf("checksum cache misses: %llu\n", di.zev_chksum_cache_misses); 949add9520fSAndreas Jaekel return 0; 950add9520fSAndreas Jaekel } 951add9520fSAndreas Jaekel 952add9520fSAndreas Jaekel static int 953888fea18SAndreas Jaekel zev_mark(int fd, char *arg) 954888fea18SAndreas Jaekel { 955888fea18SAndreas Jaekel zev_ioctl_mark_t *mark; 956888fea18SAndreas Jaekel uint64_t guid; 957888fea18SAndreas Jaekel int len; 958888fea18SAndreas Jaekel char *p; 959888fea18SAndreas Jaekel 960888fea18SAndreas Jaekel p = strchr(arg, ':'); 961888fea18SAndreas Jaekel if (!p) { 962888fea18SAndreas Jaekel fprintf(stderr, "expected value is <guid>:<payload>, " 963888fea18SAndreas Jaekel "e.g. '123:hello'\n"); 964888fea18SAndreas Jaekel exit (EXIT_FAILURE); 965888fea18SAndreas Jaekel } 966888fea18SAndreas Jaekel *p = '\n'; 967888fea18SAndreas Jaekel p++; 968888fea18SAndreas Jaekel 969888fea18SAndreas Jaekel errno = 0; 970add9520fSAndreas Jaekel guid = strtoll(arg, (char **)NULL, 10); 971888fea18SAndreas Jaekel if (errno) { 972888fea18SAndreas Jaekel fprintf(stderr, "guid must be a number.\n"); 973888fea18SAndreas Jaekel exit (EXIT_FAILURE); 974888fea18SAndreas Jaekel } 975888fea18SAndreas Jaekel 976888fea18SAndreas Jaekel len = strlen(p); 977888fea18SAndreas Jaekel 978888fea18SAndreas Jaekel mark = malloc(sizeof(*mark) + len + 1); 979888fea18SAndreas Jaekel if (!mark) { 980888fea18SAndreas Jaekel fprintf(stderr, "can't allocate mark structure: %s\n", 981888fea18SAndreas Jaekel strerror(errno)); 982888fea18SAndreas Jaekel exit (EXIT_FAILURE); 983888fea18SAndreas Jaekel } 984888fea18SAndreas Jaekel mark->zev_guid = guid; 985888fea18SAndreas Jaekel mark->zev_mark_id = 0; 986888fea18SAndreas Jaekel mark->zev_payload_len = len; 987888fea18SAndreas Jaekel strcpy(ZEV_PAYLOAD(mark), p); 988888fea18SAndreas Jaekel 989888fea18SAndreas Jaekel if (ioctl(fd, ZEV_IOC_MARK, mark)) { 990888fea18SAndreas Jaekel perror("queueing mark failed"); 991888fea18SAndreas Jaekel return (EXIT_FAILURE); 992888fea18SAndreas Jaekel } 993888fea18SAndreas Jaekel 994888fea18SAndreas Jaekel printf("mark id: %lu\n", mark->zev_mark_id); 995888fea18SAndreas Jaekel return (0); 996888fea18SAndreas Jaekel } 997888fea18SAndreas Jaekel 998add9520fSAndreas Jaekel static int 999add9520fSAndreas Jaekel zev_queue_blocking(int fd, char *arg, int block) 1000add9520fSAndreas Jaekel { 1001add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 1002add9520fSAndreas Jaekel 10036a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 10046a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 1005add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 1006add9520fSAndreas Jaekel return EXIT_FAILURE; 1007add9520fSAndreas Jaekel } 10086a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 1009add9520fSAndreas Jaekel 1010add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 1011add9520fSAndreas Jaekel perror("getting queue properties failed"); 1012add9520fSAndreas Jaekel return (EXIT_FAILURE); 1013add9520fSAndreas Jaekel } 1014add9520fSAndreas Jaekel if (block) { 1015add9520fSAndreas Jaekel gqp.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 1016add9520fSAndreas Jaekel } else { 1017add9520fSAndreas Jaekel gqp.zev_flags &= ~ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 1018add9520fSAndreas Jaekel } 1019add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 1020add9520fSAndreas Jaekel perror("setting queue properties failed"); 1021add9520fSAndreas Jaekel return (EXIT_FAILURE); 1022add9520fSAndreas Jaekel } 1023add9520fSAndreas Jaekel return (0); 1024add9520fSAndreas Jaekel } 1025add9520fSAndreas Jaekel 1026add9520fSAndreas Jaekel static int 1027add9520fSAndreas Jaekel zev_set_max_queue_len(int fd, char *arg, char *len) 1028add9520fSAndreas Jaekel { 1029add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 1030add9520fSAndreas Jaekel 1031add9520fSAndreas Jaekel if (!len) { 1032add9520fSAndreas Jaekel fprintf(stderr, "queue size parameter missing.\n"); 1033add9520fSAndreas Jaekel return EXIT_FAILURE; 1034add9520fSAndreas Jaekel } 1035add9520fSAndreas Jaekel 10366a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 10376a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 1038add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 1039add9520fSAndreas Jaekel return EXIT_FAILURE; 1040add9520fSAndreas Jaekel } 10416a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 1042add9520fSAndreas Jaekel 1043add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 1044add9520fSAndreas Jaekel perror("getting queue properties failed"); 1045add9520fSAndreas Jaekel return (EXIT_FAILURE); 1046add9520fSAndreas Jaekel } 1047add9520fSAndreas Jaekel gqp.zev_max_queue_len = atol(len); 1048add9520fSAndreas Jaekel if (gqp.zev_max_queue_len == 0 && strcmp("0", len)) { 1049add9520fSAndreas Jaekel fprintf(stderr, "queue size parameter garbled.\n"); 1050add9520fSAndreas Jaekel return (EXIT_FAILURE); 1051add9520fSAndreas Jaekel } 1052add9520fSAndreas Jaekel if (gqp.zev_max_queue_len > ZEV_MAX_QUEUE_LEN) { 1053add9520fSAndreas Jaekel fprintf(stderr, "queue size parameter out of bounds.\n"); 1054add9520fSAndreas Jaekel return (EXIT_FAILURE); 1055add9520fSAndreas Jaekel } 1056add9520fSAndreas Jaekel 1057add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 1058add9520fSAndreas Jaekel perror("setting queue properties failed"); 1059add9520fSAndreas Jaekel return (EXIT_FAILURE); 1060add9520fSAndreas Jaekel } 1061add9520fSAndreas Jaekel return (0); 1062add9520fSAndreas Jaekel } 1063add9520fSAndreas Jaekel 1064add9520fSAndreas Jaekel static int 1065add9520fSAndreas Jaekel zev_set_poll_wakeup_queue_len(int fd, char *arg, char *len) 1066add9520fSAndreas Jaekel { 1067add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 1068add9520fSAndreas Jaekel 1069add9520fSAndreas Jaekel if (!len) { 1070add9520fSAndreas Jaekel fprintf(stderr, "poll throttle parameter missing.\n"); 1071add9520fSAndreas Jaekel return EXIT_FAILURE; 1072add9520fSAndreas Jaekel } 1073add9520fSAndreas Jaekel 10746a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 10756a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 1076add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 1077add9520fSAndreas Jaekel return EXIT_FAILURE; 1078add9520fSAndreas Jaekel } 10796a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 1080add9520fSAndreas Jaekel 1081add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 1082add9520fSAndreas Jaekel perror("getting queue properties failed"); 1083add9520fSAndreas Jaekel return (EXIT_FAILURE); 1084add9520fSAndreas Jaekel } 1085add9520fSAndreas Jaekel gqp.zev_poll_wakeup_threshold = atol(len); 1086add9520fSAndreas Jaekel if (gqp.zev_poll_wakeup_threshold == 0 && strcmp("0", len)) { 1087add9520fSAndreas Jaekel fprintf(stderr, "poll throttle parameter garbled.\n"); 1088add9520fSAndreas Jaekel return (EXIT_FAILURE); 1089add9520fSAndreas Jaekel } 10906a6a51eeSAndreas Jaekel if (gqp.zev_poll_wakeup_threshold > ZEV_MAX_POLL_WAKEUP_QUEUE_LEN) { 1091add9520fSAndreas Jaekel fprintf(stderr, "poll throttle parameter out of bounds.\n"); 1092add9520fSAndreas Jaekel return (EXIT_FAILURE); 1093add9520fSAndreas Jaekel } 1094add9520fSAndreas Jaekel 1095add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 1096add9520fSAndreas Jaekel perror("setting queue properties failed"); 1097add9520fSAndreas Jaekel return (EXIT_FAILURE); 1098add9520fSAndreas Jaekel } 1099add9520fSAndreas Jaekel return (0); 1100add9520fSAndreas Jaekel } 1101add9520fSAndreas Jaekel 1102add9520fSAndreas Jaekel static int 1103add9520fSAndreas Jaekel zev_queue_properties(int fd, char *arg) 1104add9520fSAndreas Jaekel { 1105add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 1106add9520fSAndreas Jaekel 11076a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 11086a6a51eeSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 1109add9520fSAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 1110add9520fSAndreas Jaekel return EXIT_FAILURE; 1111add9520fSAndreas Jaekel } 11126a6a51eeSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 1113add9520fSAndreas Jaekel 1114add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 1115add9520fSAndreas Jaekel perror("getting queue properties failed"); 1116add9520fSAndreas Jaekel return (EXIT_FAILURE); 1117add9520fSAndreas Jaekel } 1118add9520fSAndreas Jaekel 1119add9520fSAndreas Jaekel printf("queue : %s\n", arg); 1120add9520fSAndreas Jaekel printf("max size : %" PRIu64 "\n", gqp.zev_max_queue_len); 1121add9520fSAndreas Jaekel printf("poll throttle: %" PRIu64 "\n", gqp.zev_poll_wakeup_threshold); 1122add9520fSAndreas Jaekel printf("persistent : %s\n", 1123add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no"); 1124add9520fSAndreas Jaekel printf("blocking : %s\n", 1125add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? "yes" : "no"); 1126add9520fSAndreas Jaekel 1127add9520fSAndreas Jaekel return (0); 1128add9520fSAndreas Jaekel } 1129add9520fSAndreas Jaekel 1130add9520fSAndreas Jaekel static int 1131add9520fSAndreas Jaekel zev_list_queues(int fd) 1132add9520fSAndreas Jaekel { 1133add9520fSAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 1134add9520fSAndreas Jaekel zev_ioctl_get_queue_list_t gql; 1135add9520fSAndreas Jaekel zev_ioctl_get_queue_statistics_t gs; 1136add9520fSAndreas Jaekel uint64_t i; 1137add9520fSAndreas Jaekel char name[ZEV_MAX_QUEUE_NAME_LEN+1]; 1138add9520fSAndreas Jaekel 1139add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_LIST, &gql)) { 1140add9520fSAndreas Jaekel perror("getting queue list failed"); 1141add9520fSAndreas Jaekel return (EXIT_FAILURE); 1142add9520fSAndreas Jaekel } 1143add9520fSAndreas Jaekel 1144add9520fSAndreas Jaekel printf("Name Size " 1145add9520fSAndreas Jaekel "Max Size Wakeup Per Block\n"); 1146add9520fSAndreas Jaekel 1147add9520fSAndreas Jaekel for (i=0; i<gql.zev_n_queues; i++) { 1148add9520fSAndreas Jaekel strncpy(name, gql.zev_queue_name[i].zev_name, 1149add9520fSAndreas Jaekel ZEV_MAX_QUEUE_NAME_LEN); 1150add9520fSAndreas Jaekel name[gql.zev_queue_name[i].zev_namelen] = '\0'; 1151add9520fSAndreas Jaekel 11526a6a51eeSAndreas Jaekel memcpy(gqp.zev_queue_name.zev_name, 11536a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN); 11546a6a51eeSAndreas Jaekel gqp.zev_queue_name.zev_namelen = 11556a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_namelen; 1156add9520fSAndreas Jaekel 1157add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 1158add9520fSAndreas Jaekel if (errno == ENOENT) 1159add9520fSAndreas Jaekel continue; 1160add9520fSAndreas Jaekel perror("getting queue properties failed"); 1161add9520fSAndreas Jaekel return (EXIT_FAILURE); 1162add9520fSAndreas Jaekel } 1163add9520fSAndreas Jaekel 11646a6a51eeSAndreas Jaekel memcpy(gs.zev_queue_name.zev_name, 11656a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN); 11666a6a51eeSAndreas Jaekel gs.zev_queue_name.zev_namelen = 11676a6a51eeSAndreas Jaekel gql.zev_queue_name[i].zev_namelen; 1168add9520fSAndreas Jaekel 1169add9520fSAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_STATISTICS, &gs)) { 1170add9520fSAndreas Jaekel if (errno == ENOENT) 1171add9520fSAndreas Jaekel continue; 1172add9520fSAndreas Jaekel perror("getting statistics data failed"); 1173add9520fSAndreas Jaekel return (EXIT_FAILURE); 1174add9520fSAndreas Jaekel } 1175add9520fSAndreas Jaekel 1176add9520fSAndreas Jaekel printf("%-40s %-10" PRIu64 " %-10" PRIu64 " %-6" PRIu64 1177add9520fSAndreas Jaekel " %-3s %-3s\n", 1178add9520fSAndreas Jaekel name, 1179add9520fSAndreas Jaekel gs.zev_statistics.zev_queue_len, 1180add9520fSAndreas Jaekel gqp.zev_max_queue_len, 1181add9520fSAndreas Jaekel gqp.zev_poll_wakeup_threshold, 1182add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no", 1183add9520fSAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? 1184add9520fSAndreas Jaekel "yes" : "no"); 1185add9520fSAndreas Jaekel } 1186add9520fSAndreas Jaekel 1187add9520fSAndreas Jaekel return (0); 1188add9520fSAndreas Jaekel } 1189add9520fSAndreas Jaekel 119042110aacSAndreas Jaekel static int 119142110aacSAndreas Jaekel zev_checksum(int dev_fd, char *filename) 119242110aacSAndreas Jaekel { 119342110aacSAndreas Jaekel int fd; 119442110aacSAndreas Jaekel offset_t off; 119542110aacSAndreas Jaekel offset_t data; 119642110aacSAndreas Jaekel zev_sig_t *sig; 119742110aacSAndreas Jaekel char *buf; 119842110aacSAndreas Jaekel zev_ioctl_get_signatures_t *gs; 119942110aacSAndreas Jaekel int i; 120042110aacSAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 120142110aacSAndreas Jaekel int buf_size; 120242110aacSAndreas Jaekel 120342110aacSAndreas Jaekel /* control struct, one lv1 signature and up to 256 lv0 signatures */ 120442110aacSAndreas Jaekel buf_size = (1 + 256) * sizeof(zev_sig_t); 120542110aacSAndreas Jaekel buf = malloc(sizeof(zev_ioctl_get_signatures_t) + buf_size); 120642110aacSAndreas Jaekel if (!buf) { 120742110aacSAndreas Jaekel perror("can't allocate checksum buffer"); 120842110aacSAndreas Jaekel return (EXIT_FAILURE); 120942110aacSAndreas Jaekel } 121042110aacSAndreas Jaekel 121142110aacSAndreas Jaekel fd = open(filename, O_RDONLY); 121242110aacSAndreas Jaekel if (fd < 0) { 121342110aacSAndreas Jaekel perror("can't open file"); 121442110aacSAndreas Jaekel return (EXIT_FAILURE); 121542110aacSAndreas Jaekel } 121642110aacSAndreas Jaekel 121742110aacSAndreas Jaekel gs = (zev_ioctl_get_signatures_t *)buf; 121842110aacSAndreas Jaekel gs->zev_fd = fd; 121942110aacSAndreas Jaekel gs->zev_bufsize = buf_size; 122042110aacSAndreas Jaekel 122142110aacSAndreas Jaekel off = 0; 122242110aacSAndreas Jaekel data = 0; 122342110aacSAndreas Jaekel while (1) { 122442110aacSAndreas Jaekel errno = 0; 122542110aacSAndreas Jaekel data = llseek(fd, off, SEEK_DATA); 122642110aacSAndreas Jaekel if (data < 0) { 122742110aacSAndreas Jaekel if (errno == ENXIO) /* no more data */ 122842110aacSAndreas Jaekel break; 122942110aacSAndreas Jaekel perror("llseek failed"); 123042110aacSAndreas Jaekel goto err; 123142110aacSAndreas Jaekel } 123242110aacSAndreas Jaekel data = P2ALIGN(data, ZEV_L1_SIZE); 123342110aacSAndreas Jaekel off = data + ZEV_L1_SIZE; 123442110aacSAndreas Jaekel 123542110aacSAndreas Jaekel gs->zev_offset = data; 123642110aacSAndreas Jaekel gs->zev_len = ZEV_L1_SIZE; 123742110aacSAndreas Jaekel 123842110aacSAndreas Jaekel if (ioctl(dev_fd, ZEV_IOC_GET_FILE_SIGNATURES, gs)) { 123942110aacSAndreas Jaekel perror("ioctl to get signatures failed"); 124042110aacSAndreas Jaekel goto err; 124142110aacSAndreas Jaekel } 124242110aacSAndreas Jaekel 124342110aacSAndreas Jaekel for (i=0; i<gs->zev_signature_cnt; i++) { 124442110aacSAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(gs); 124542110aacSAndreas Jaekel sig += i; 124642110aacSAndreas Jaekel sig2hex_direct(sig->value, sigval); 124742110aacSAndreas Jaekel printf("level %d, offset %llu, value %s\n", 124842110aacSAndreas Jaekel sig->level, sig->block_offset, sigval); 124942110aacSAndreas Jaekel } 125042110aacSAndreas Jaekel } 125142110aacSAndreas Jaekel 125242110aacSAndreas Jaekel free(buf); 125342110aacSAndreas Jaekel close(fd); 125442110aacSAndreas Jaekel return 0; 125542110aacSAndreas Jaekel err: 125642110aacSAndreas Jaekel free(buf); 125742110aacSAndreas Jaekel close(fd); 125842110aacSAndreas Jaekel return (EXIT_FAILURE); 125942110aacSAndreas Jaekel } 126042110aacSAndreas Jaekel 1261b690436dSAndreas Jaekel typedef struct zevstat { 1262b690436dSAndreas Jaekel uint64_t ns_start; 1263b690436dSAndreas Jaekel uint64_t events[ZEV_OP_MIN + ZEV_OP_MAX]; 1264b690436dSAndreas Jaekel uint64_t guids; 1265b690436dSAndreas Jaekel uint64_t total_events; 1266b690436dSAndreas Jaekel uint64_t total_guids; 1267b690436dSAndreas Jaekel avl_tree_t guids_interval; 1268b690436dSAndreas Jaekel avl_tree_t guids_runtime; 1269b690436dSAndreas Jaekel } zevstat_t; 1270b690436dSAndreas Jaekel 1271b690436dSAndreas Jaekel typedef struct zev_guidtrack_t { 1272b690436dSAndreas Jaekel uint64_t guid; 1273b690436dSAndreas Jaekel avl_node_t avl_interval; 1274b690436dSAndreas Jaekel avl_node_t avl_runtime; 1275b690436dSAndreas Jaekel } zev_guidtrack_t; 1276b690436dSAndreas Jaekel 1277b690436dSAndreas Jaekel zevstat_t zevstat; 1278b690436dSAndreas Jaekel 1279b690436dSAndreas Jaekel static void 1280b690436dSAndreas Jaekel zev_eventstat(char *buf, int len) 1281b690436dSAndreas Jaekel { 1282b690436dSAndreas Jaekel zev_header_t *rec = (zev_header_t *)buf; 1283b690436dSAndreas Jaekel zev_guidtrack_t *gt; 1284b690436dSAndreas Jaekel zev_guidtrack_t *gt_int; 1285b690436dSAndreas Jaekel zev_guidtrack_t to_find; 1286b690436dSAndreas Jaekel avl_index_t where; 1287b690436dSAndreas Jaekel 1288b690436dSAndreas Jaekel zevstat.total_events++; 1289b690436dSAndreas Jaekel zevstat.events[rec->op]++; 1290b690436dSAndreas Jaekel 1291b690436dSAndreas Jaekel to_find.guid = rec->guid; 1292b690436dSAndreas Jaekel gt = avl_find(&zevstat.guids_runtime, &to_find, &where); 1293b690436dSAndreas Jaekel if (!gt) { 1294b690436dSAndreas Jaekel gt = malloc(sizeof(*gt)); 1295b690436dSAndreas Jaekel if (!gt) { 1296b690436dSAndreas Jaekel perror("can't get guid tracking record"); 1297b690436dSAndreas Jaekel exit (EXIT_FAILURE); 1298b690436dSAndreas Jaekel } 1299b690436dSAndreas Jaekel gt->guid = rec->guid; 1300b690436dSAndreas Jaekel avl_insert(&zevstat.guids_runtime, gt, where); 1301b690436dSAndreas Jaekel } 1302b690436dSAndreas Jaekel gt_int = avl_find(&zevstat.guids_interval, &to_find, &where); 1303b690436dSAndreas Jaekel if (!gt_int) 1304b690436dSAndreas Jaekel avl_insert(&zevstat.guids_interval, gt, where); 1305b690436dSAndreas Jaekel } 1306b690436dSAndreas Jaekel 1307b690436dSAndreas Jaekel static void 1308f432e238SAndreas Jaekel zev_eventstat_interval(FILE *out) 1309b690436dSAndreas Jaekel { 1310b690436dSAndreas Jaekel uint64_t events; 1311b690436dSAndreas Jaekel int i; 1312b690436dSAndreas Jaekel zev_guidtrack_t *gt; 1313b690436dSAndreas Jaekel 1314b690436dSAndreas Jaekel events = 0; 1315b690436dSAndreas Jaekel for (i = ZEV_OP_MIN; i <= ZEV_OP_MAX; i++) { 1316b690436dSAndreas Jaekel events += zevstat.events[i]; 1317b690436dSAndreas Jaekel } 1318b690436dSAndreas Jaekel 1319b690436dSAndreas Jaekel if (verbose) { 1320f432e238SAndreas Jaekel fprintf(out, "%u %6llu %6llu %6llu %6llu ", 1321b690436dSAndreas Jaekel time(NULL), 1322b690436dSAndreas Jaekel events, 1323b690436dSAndreas Jaekel zevstat.total_events, 1324b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_interval), 1325b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_runtime)); 1326b690436dSAndreas Jaekel for (i = ZEV_OP_MIN; i <= ZEV_OP_MAX; i++) 1327f432e238SAndreas Jaekel fprintf(out, "%6llu ", zevstat.events[i]); 1328f432e238SAndreas Jaekel fprintf(out, "\n"); 1329b690436dSAndreas Jaekel } else { 1330f432e238SAndreas Jaekel fprintf(out, "%u %6llu %6llu %6llu %6llu\n", 1331b690436dSAndreas Jaekel time(NULL), 1332b690436dSAndreas Jaekel events, 1333b690436dSAndreas Jaekel zevstat.total_events, 1334b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_interval), 1335b690436dSAndreas Jaekel avl_numnodes(&zevstat.guids_runtime)); 1336b690436dSAndreas Jaekel } 1337b690436dSAndreas Jaekel memset(&zevstat.events, 0, sizeof(zevstat.events)); 1338b690436dSAndreas Jaekel zevstat.guids = 0; 1339b690436dSAndreas Jaekel while (gt = avl_first(&zevstat.guids_interval)) 1340b690436dSAndreas Jaekel avl_remove(&zevstat.guids_interval, gt); 1341f432e238SAndreas Jaekel fflush(out); 1342b690436dSAndreas Jaekel } 1343b690436dSAndreas Jaekel 1344b690436dSAndreas Jaekel static int 1345b690436dSAndreas Jaekel zev_evcompar(const void *a, const void *b) 1346b690436dSAndreas Jaekel { 1347b690436dSAndreas Jaekel const zev_guidtrack_t *ga = a; 1348b690436dSAndreas Jaekel const zev_guidtrack_t *gb = b; 1349b690436dSAndreas Jaekel 1350b690436dSAndreas Jaekel if (ga->guid > gb->guid) 1351b690436dSAndreas Jaekel return 1; 1352b690436dSAndreas Jaekel if (ga->guid < gb->guid) 1353b690436dSAndreas Jaekel return -1; 1354b690436dSAndreas Jaekel return 0; 1355b690436dSAndreas Jaekel } 1356b690436dSAndreas Jaekel 1357b690436dSAndreas Jaekel static int 1358f432e238SAndreas Jaekel zev_zevstat(int fd, char *s_interval, char *s_count, char *outfile) 1359b690436dSAndreas Jaekel { 1360b690436dSAndreas Jaekel uint64_t interval = 1000; 1361b690436dSAndreas Jaekel uint64_t ms; 1362b690436dSAndreas Jaekel uint64_t t_until; 1363b690436dSAndreas Jaekel uint64_t t_now; 1364b690436dSAndreas Jaekel int cnt = -1; 1365b690436dSAndreas Jaekel struct pollfd pfd[1]; 1366b690436dSAndreas Jaekel int ret; 1367b690436dSAndreas Jaekel char buf[4096]; 1368b690436dSAndreas Jaekel zev_event_t *ev; 1369b690436dSAndreas Jaekel int off = 0; 1370b690436dSAndreas Jaekel zev_ioctl_add_queue_t aq; 1371b690436dSAndreas Jaekel int q_fd; 1372b690436dSAndreas Jaekel zev_guidtrack_t *gt; 1373f432e238SAndreas Jaekel FILE *out = stdout; 1374f432e238SAndreas Jaekel struct stat st; 1375f432e238SAndreas Jaekel char filename[MAXPATHLEN]; 1376f432e238SAndreas Jaekel int retry; 1377f432e238SAndreas Jaekel 1378f432e238SAndreas Jaekel if (outfile) { 1379f432e238SAndreas Jaekel retry = 0; 1380f432e238SAndreas Jaekel strncpy(filename, outfile, sizeof(filename)); 1381f432e238SAndreas Jaekel while (stat(filename, &st) == 0) { 1382f432e238SAndreas Jaekel /* file exists */ 1383f432e238SAndreas Jaekel snprintf(filename, sizeof(filename), 1384f432e238SAndreas Jaekel "%s.%d", outfile, retry); 1385f432e238SAndreas Jaekel retry++; 1386f432e238SAndreas Jaekel } 1387f432e238SAndreas Jaekel out = fopen(filename, "wb+"); 1388f432e238SAndreas Jaekel if (!out) { 1389f432e238SAndreas Jaekel perror("opening output file failed"); 1390f432e238SAndreas Jaekel return (EXIT_FAILURE); 1391f432e238SAndreas Jaekel } 1392f432e238SAndreas Jaekel } 1393b690436dSAndreas Jaekel 1394b690436dSAndreas Jaekel memset(&zevstat, 0, sizeof(zevstat)); 1395b690436dSAndreas Jaekel avl_create(&zevstat.guids_runtime, zev_evcompar, 1396b690436dSAndreas Jaekel sizeof(zev_guidtrack_t), 1397b690436dSAndreas Jaekel offsetof(zev_guidtrack_t, avl_runtime)); 1398b690436dSAndreas Jaekel avl_create(&zevstat.guids_interval, zev_evcompar, 1399b690436dSAndreas Jaekel sizeof(zev_guidtrack_t), 1400b690436dSAndreas Jaekel offsetof(zev_guidtrack_t, avl_interval)); 1401b690436dSAndreas Jaekel 140219695134SAndreas Jaekel if (s_interval) { 1403b690436dSAndreas Jaekel interval = atol(s_interval); 1404b690436dSAndreas Jaekel if (interval == 0) { 1405b690436dSAndreas Jaekel fprintf(stderr, "invalid interval.\n"); 1406b690436dSAndreas Jaekel return (EXIT_FAILURE); 1407b690436dSAndreas Jaekel } 1408b690436dSAndreas Jaekel interval *= 1000; 140919695134SAndreas Jaekel } 1410b690436dSAndreas Jaekel if (s_count) { 1411b690436dSAndreas Jaekel cnt = atol(s_count); 1412b690436dSAndreas Jaekel if (interval == 0) { 1413b690436dSAndreas Jaekel fprintf(stderr, "invalid count.\n"); 1414b690436dSAndreas Jaekel return (EXIT_FAILURE); 1415b690436dSAndreas Jaekel } 1416b690436dSAndreas Jaekel } 1417b690436dSAndreas Jaekel 1418b690436dSAndreas Jaekel aq.zev_max_queue_len = 1024 * 1024; 1419c99a1a25SAndreas Jaekel aq.zev_flags = ZEV_FL_INITIALLY_EMPTY; 1420b690436dSAndreas Jaekel snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN, 1421b690436dSAndreas Jaekel "zevstat.%ld.%ld", time(NULL), getpid()); 1422b690436dSAndreas Jaekel aq.zev_namelen = strlen(aq.zev_name); 1423b690436dSAndreas Jaekel 1424b690436dSAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) { 1425b690436dSAndreas Jaekel perror("adding temporary queue failed"); 1426b690436dSAndreas Jaekel return (EXIT_FAILURE); 1427b690436dSAndreas Jaekel } 1428b690436dSAndreas Jaekel 1429b690436dSAndreas Jaekel snprintf(buf, sizeof(buf), 1430b690436dSAndreas Jaekel "/devices/pseudo/zev@0:%s", aq.zev_name); 1431b690436dSAndreas Jaekel q_fd = open(buf, O_RDONLY); 1432b690436dSAndreas Jaekel if (q_fd < 0) { 1433b690436dSAndreas Jaekel perror("opening queue device failed"); 1434b690436dSAndreas Jaekel return (EXIT_FAILURE); 1435b690436dSAndreas Jaekel } 1436b690436dSAndreas Jaekel 1437b690436dSAndreas Jaekel pfd[0].fd = q_fd; 1438b690436dSAndreas Jaekel pfd[0].events = POLLIN; 1439b690436dSAndreas Jaekel 1440b690436dSAndreas Jaekel /* drain queue */ 144119695134SAndreas Jaekel while ((ret = poll(pfd, 1, 0)) > 0) { 1442b690436dSAndreas Jaekel if (read(q_fd, buf, sizeof(buf)) < 0) { 1443b690436dSAndreas Jaekel perror("read failed"); 1444b690436dSAndreas Jaekel close(q_fd); 1445b690436dSAndreas Jaekel return(EXIT_FAILURE); 1446b690436dSAndreas Jaekel } 1447b690436dSAndreas Jaekel } 1448b690436dSAndreas Jaekel if (ret < 0) { 1449b690436dSAndreas Jaekel perror("poll failed"); 1450b690436dSAndreas Jaekel close(q_fd); 1451b690436dSAndreas Jaekel return(EXIT_FAILURE); 1452b690436dSAndreas Jaekel } 1453b690436dSAndreas Jaekel 1454f432e238SAndreas Jaekel fprintf(out, "timestamp events tevents guids tguids"); 1455b690436dSAndreas Jaekel if (verbose) { 1456f432e238SAndreas Jaekel fprintf(out, " error mark mount umount zvol_w "); 1457f432e238SAndreas Jaekel fprintf(out, "zvol_t close create mkdir mxattr "); 1458f432e238SAndreas Jaekel fprintf(out, "remove rmdir link symlnk rename "); 1459f432e238SAndreas Jaekel fprintf(out, "write trunc setatt acl"); 1460b690436dSAndreas Jaekel } 1461f432e238SAndreas Jaekel fprintf(out, "\n"); 1462b690436dSAndreas Jaekel while (cnt) { 1463b690436dSAndreas Jaekel t_until = gethrtime() + (interval * 1000000); 1464b690436dSAndreas Jaekel ms = interval; 1465b690436dSAndreas Jaekel do { 1466b690436dSAndreas Jaekel ret = poll(pfd, 1, ms); 1467b690436dSAndreas Jaekel t_now = gethrtime(); 1468b690436dSAndreas Jaekel if (t_now < t_until) { 1469b690436dSAndreas Jaekel ms = t_until - t_now; 1470b690436dSAndreas Jaekel ms /= 1000000ull; 1471b690436dSAndreas Jaekel } 1472b690436dSAndreas Jaekel if (ret < 0) { 1473b690436dSAndreas Jaekel perror("poll failed"); 1474b690436dSAndreas Jaekel close(q_fd); 1475b690436dSAndreas Jaekel return(EXIT_FAILURE); 1476b690436dSAndreas Jaekel } 1477b690436dSAndreas Jaekel if (!(pfd[0].revents & POLLIN)) 1478b690436dSAndreas Jaekel continue; 1479b690436dSAndreas Jaekel /* data available */ 1480b690436dSAndreas Jaekel ret = read(q_fd, buf, sizeof(buf)); 1481b690436dSAndreas Jaekel if (ret < 0) { 1482b690436dSAndreas Jaekel perror("read failed"); 1483b690436dSAndreas Jaekel close(q_fd); 1484b690436dSAndreas Jaekel return(EXIT_FAILURE); 1485b690436dSAndreas Jaekel } 1486b690436dSAndreas Jaekel if (ret == 0) 1487b690436dSAndreas Jaekel continue; 1488b690436dSAndreas Jaekel while (ret > off) { 1489b690436dSAndreas Jaekel ev = (zev_event_t *)(buf + off); 1490b690436dSAndreas Jaekel zev_eventstat(buf + off, ev->header.record_len); 1491b690436dSAndreas Jaekel off += ev->header.record_len; 1492b690436dSAndreas Jaekel } 1493b690436dSAndreas Jaekel off = 0; 1494b690436dSAndreas Jaekel } while ((t_now) < t_until && (ms > 0)); 1495f432e238SAndreas Jaekel zev_eventstat_interval(out); 1496b690436dSAndreas Jaekel if (cnt > 0) 1497b690436dSAndreas Jaekel cnt--; 1498b690436dSAndreas Jaekel } 1499b690436dSAndreas Jaekel close(q_fd); 1500f432e238SAndreas Jaekel if (outfile) 1501f432e238SAndreas Jaekel fclose(out); 1502b690436dSAndreas Jaekel while (gt = avl_first(&zevstat.guids_interval)) 1503b690436dSAndreas Jaekel avl_remove(&zevstat.guids_interval, gt); 1504b690436dSAndreas Jaekel while (gt = avl_first(&zevstat.guids_runtime)) { 1505b690436dSAndreas Jaekel avl_remove(&zevstat.guids_runtime, gt); 1506b690436dSAndreas Jaekel free(gt); 1507b690436dSAndreas Jaekel } 1508b690436dSAndreas Jaekel return EXIT_SUCCESS; 1509b690436dSAndreas Jaekel } 1510b690436dSAndreas Jaekel 1511f432e238SAndreas Jaekel static int 1512f432e238SAndreas Jaekel zev_report(int fd, char *basename) 1513f432e238SAndreas Jaekel { 1514f432e238SAndreas Jaekel char filename[MAXPATHLEN]; 1515f432e238SAndreas Jaekel char count[10]; 1516f432e238SAndreas Jaekel time_t now; 1517f432e238SAndreas Jaekel time_t midnight; 1518f432e238SAndreas Jaekel struct tm tm; 1519f432e238SAndreas Jaekel int minutes; 1520f432e238SAndreas Jaekel int ret; 1521f432e238SAndreas Jaekel 1522f432e238SAndreas Jaekel verbose++; 1523f432e238SAndreas Jaekel while (1) { 1524f432e238SAndreas Jaekel now = time(NULL); 1525f432e238SAndreas Jaekel localtime_r(&now, &tm); 1526f432e238SAndreas Jaekel snprintf(filename, sizeof(filename), "%s.%04d-%02d-%02d", 1527f432e238SAndreas Jaekel basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); 1528f432e238SAndreas Jaekel tm.tm_sec = 0; 1529f432e238SAndreas Jaekel tm.tm_min = 0; 1530f432e238SAndreas Jaekel tm.tm_hour = 0; 1531f432e238SAndreas Jaekel tm.tm_mday++; /* works for Jan 32nd, Feb 30th, etc. */ 1532f432e238SAndreas Jaekel midnight = mktime(&tm); 1533f432e238SAndreas Jaekel if (now % 60) 1534f432e238SAndreas Jaekel sleep(60 - (now % 60)); 1535f432e238SAndreas Jaekel minutes = (midnight - time(NULL)) / 60; 1536f432e238SAndreas Jaekel snprintf(count, sizeof(count), "%d", minutes); 1537f432e238SAndreas Jaekel ret = zev_zevstat(fd, "60", count, filename); 1538f432e238SAndreas Jaekel if (ret) 1539f432e238SAndreas Jaekel return EXIT_FAILURE; 1540f432e238SAndreas Jaekel } 1541f432e238SAndreas Jaekel return EXIT_SUCCESS; /* never reached */ 1542f432e238SAndreas Jaekel } 1543f432e238SAndreas Jaekel 1544a0d677d8SAndreas Jaekel static void 1545a0d677d8SAndreas Jaekel zev_sigint(int sig) 1546a0d677d8SAndreas Jaekel { 1547a0d677d8SAndreas Jaekel fflush(stdout); 1548a0d677d8SAndreas Jaekel } 1549a0d677d8SAndreas Jaekel 1550a18c35b9SAndreas Jaekel int 1551a18c35b9SAndreas Jaekel main(int argc, char **argv) 1552a18c35b9SAndreas Jaekel { 1553a18c35b9SAndreas Jaekel int fd; 1554a18c35b9SAndreas Jaekel int c; 1555a18c35b9SAndreas Jaekel extern char *optarg; 15566a6a51eeSAndreas Jaekel int create_tmp_queue = 1; 15576a6a51eeSAndreas Jaekel char buf[MAXPATHLEN]; 1558a5090b97SAndreas Jaekel int mode = 0; 1559a5090b97SAndreas Jaekel char *arg = NULL; 1560a5090b97SAndreas Jaekel char *arg2 = NULL; 1561b690436dSAndreas Jaekel char *p; 1562b690436dSAndreas Jaekel 1563a0d677d8SAndreas Jaekel sigset(SIGINT, zev_sigint); 1564a0d677d8SAndreas Jaekel 156550da9edeSAndreas Jaekel /* open device */ 156650da9edeSAndreas Jaekel fd = open(zev_device, O_RDONLY); 156750da9edeSAndreas Jaekel if (fd < 0) { 156850da9edeSAndreas Jaekel perror("opening zev device failed"); 156950da9edeSAndreas Jaekel return EXIT_FAILURE; 157050da9edeSAndreas Jaekel } 157150da9edeSAndreas Jaekel 1572b690436dSAndreas Jaekel p = strrchr(argv[0], '/'); 1573b690436dSAndreas Jaekel if (!p) { 1574b690436dSAndreas Jaekel p = argv[0]; 1575b690436dSAndreas Jaekel } else { 1576b690436dSAndreas Jaekel p++; 1577b690436dSAndreas Jaekel } 1578b690436dSAndreas Jaekel if (!strcmp(p, "zevstat")) { 1579b690436dSAndreas Jaekel mode = MD_ZEVSTAT; 158050da9edeSAndreas Jaekel if (argc < 2) 158150da9edeSAndreas Jaekel zevstat_usage(argv[0]); 158250da9edeSAndreas Jaekel if (!strcmp(argv[1], "-v")) { 158350da9edeSAndreas Jaekel if (argc < 3) 158450da9edeSAndreas Jaekel zevstat_usage(argv[0]); 158550da9edeSAndreas Jaekel verbose++; 158650da9edeSAndreas Jaekel arg = argv[2]; 158750da9edeSAndreas Jaekel arg2 = argv[3]; 158850da9edeSAndreas Jaekel } else { 158950da9edeSAndreas Jaekel arg = argv[1]; 159050da9edeSAndreas Jaekel arg2 = argv[2]; 159150da9edeSAndreas Jaekel } 1592f432e238SAndreas Jaekel return zev_zevstat(fd, arg, arg2, NULL); 1593f432e238SAndreas Jaekel } else if(!strcmp(p, "zevreport")) { 1594f432e238SAndreas Jaekel mode = MD_ZEV_REPORT; 1595f432e238SAndreas Jaekel if (argc != 2) 1596f432e238SAndreas Jaekel zevreport_usage(argv[0]); 1597f432e238SAndreas Jaekel return zev_report(fd, argv[1]); 1598b690436dSAndreas Jaekel } 1599a18c35b9SAndreas Jaekel 16006a6a51eeSAndreas Jaekel while ((c = getopt(argc, argv, 1601*35526fb3SArne Jansen "gvspc:d:Dlk:L:q:Q:t:m:M:a:A:r:P:b:B:T:R:f:h?")) != -1) { 1602a18c35b9SAndreas Jaekel switch(c) { 160316ff6b2fSAndreas Jaekel case 'g': 160416ff6b2fSAndreas Jaekel grep_friendly++; 160516ff6b2fSAndreas Jaekel verbose++; 160616ff6b2fSAndreas Jaekel break; 1607205ed6bfSAndreas Jaekel case 'v': 1608205ed6bfSAndreas Jaekel verbose++; 1609205ed6bfSAndreas Jaekel break; 1610a18c35b9SAndreas Jaekel case 's': 1611a5090b97SAndreas Jaekel mode = MD_STATISTICS; 1612a5090b97SAndreas Jaekel break; 1613a18c35b9SAndreas Jaekel case 'p': 1614a5090b97SAndreas Jaekel mode = MD_POLL_EVENTS; 1615a5090b97SAndreas Jaekel break; 161642110aacSAndreas Jaekel case 'c': 1617a5090b97SAndreas Jaekel mode = MD_CHECKSUMS; 1618a5090b97SAndreas Jaekel arg = optarg; 1619a5090b97SAndreas Jaekel break; 1620add9520fSAndreas Jaekel case 'D': 1621a5090b97SAndreas Jaekel mode = MD_DEBUG_INFO; 1622a5090b97SAndreas Jaekel break; 1623a18c35b9SAndreas Jaekel case 'd': 1624add9520fSAndreas Jaekel close(fd); 1625a18c35b9SAndreas Jaekel zev_device = optarg; 1626add9520fSAndreas Jaekel fd = open(zev_device, O_RDONLY); 1627add9520fSAndreas Jaekel if (fd < 0) { 1628add9520fSAndreas Jaekel perror("opening zev device failed"); 1629add9520fSAndreas Jaekel return EXIT_FAILURE; 1630add9520fSAndreas Jaekel } 16316a6a51eeSAndreas Jaekel create_tmp_queue = 0; 16326a6a51eeSAndreas Jaekel break; 16336a6a51eeSAndreas Jaekel case 'q': 16346a6a51eeSAndreas Jaekel snprintf(buf, sizeof(buf), 16356a6a51eeSAndreas Jaekel "/devices/pseudo/zev@0:%s", optarg); 16366a6a51eeSAndreas Jaekel close(fd); 16376a6a51eeSAndreas Jaekel zev_device = buf; 16386a6a51eeSAndreas Jaekel fd = open(zev_device, O_RDONLY); 16396a6a51eeSAndreas Jaekel if (fd < 0) { 16406a6a51eeSAndreas Jaekel perror("opening zev device failed"); 16416a6a51eeSAndreas Jaekel return EXIT_FAILURE; 16426a6a51eeSAndreas Jaekel } 16436a6a51eeSAndreas Jaekel create_tmp_queue = 0; 1644a18c35b9SAndreas Jaekel break; 1645*35526fb3SArne Jansen case 'f': 1646*35526fb3SArne Jansen fd = open(optarg, O_RDONLY); 1647*35526fb3SArne Jansen if (fd < 0) { 1648*35526fb3SArne Jansen perror("opening spool file failed"); 1649*35526fb3SArne Jansen return EXIT_FAILURE; 1650*35526fb3SArne Jansen } 1651*35526fb3SArne Jansen mode = MD_DUMP_SPOOL; 1652*35526fb3SArne Jansen break; 1653add9520fSAndreas Jaekel case 'l': 1654a5090b97SAndreas Jaekel mode = MD_LIST_QUEUES; 1655a5090b97SAndreas Jaekel break; 1656add9520fSAndreas Jaekel case 'Q': 1657a5090b97SAndreas Jaekel mode = MD_SET_GLOBAL_MAX_QUEUE_LEN; 1658a5090b97SAndreas Jaekel arg = optarg; 1659a5090b97SAndreas Jaekel break; 16606a6a51eeSAndreas Jaekel case 'L': 1661a5090b97SAndreas Jaekel mode = MD_SET_MAX_QUEUE_LEN; 1662a5090b97SAndreas Jaekel arg = optarg; 1663a5090b97SAndreas Jaekel arg2 = argv[optind]; 1664a5090b97SAndreas Jaekel break; 1665b690436dSAndreas Jaekel case 'T': 1666b690436dSAndreas Jaekel mode = MD_ZEVSTAT; 1667b690436dSAndreas Jaekel arg = optarg; 1668b690436dSAndreas Jaekel arg2 = argv[optind]; 1669b690436dSAndreas Jaekel break; 1670f432e238SAndreas Jaekel case 'R': 1671f432e238SAndreas Jaekel mode = MD_ZEV_REPORT; 1672f432e238SAndreas Jaekel arg = optarg; 1673f432e238SAndreas Jaekel break; 1674fec460f8SAndreas Jaekel case 't': 1675a5090b97SAndreas Jaekel mode = MD_SET_POLL_WAKEUP_QUEUE_LEN; 1676a5090b97SAndreas Jaekel arg = optarg; 1677a5090b97SAndreas Jaekel arg2 = argv[optind]; 1678a5090b97SAndreas Jaekel break; 1679a18c35b9SAndreas Jaekel case 'm': 1680a5090b97SAndreas Jaekel mode = MD_MUTE_POOL; 1681a5090b97SAndreas Jaekel arg = optarg; 1682a5090b97SAndreas Jaekel break; 1683a18c35b9SAndreas Jaekel case 'M': 1684a5090b97SAndreas Jaekel mode = MD_UNMUTE_POOL; 1685a5090b97SAndreas Jaekel arg = optarg; 1686a5090b97SAndreas Jaekel break; 1687888fea18SAndreas Jaekel case 'k': 1688a5090b97SAndreas Jaekel mode = MD_MARK; 1689a5090b97SAndreas Jaekel arg = optarg; 1690a5090b97SAndreas Jaekel break; 1691add9520fSAndreas Jaekel case 'a': 1692a5090b97SAndreas Jaekel mode = MD_ADD_QUEUE; 1693a5090b97SAndreas Jaekel arg = optarg; 1694a5090b97SAndreas Jaekel break; 16956a6a51eeSAndreas Jaekel case 'A': 1696a5090b97SAndreas Jaekel mode = MD_ADD_BLOCKING_QUEUE; 1697a5090b97SAndreas Jaekel arg = optarg; 1698a5090b97SAndreas Jaekel break; 1699add9520fSAndreas Jaekel case 'r': 1700a5090b97SAndreas Jaekel mode = MD_REMOVE_QUEUE; 1701a5090b97SAndreas Jaekel arg = optarg; 1702a5090b97SAndreas Jaekel break; 1703add9520fSAndreas Jaekel case 'b': 1704a5090b97SAndreas Jaekel mode = MD_QUEUE_BLOCKING; 1705a5090b97SAndreas Jaekel arg = optarg; 1706a5090b97SAndreas Jaekel break; 1707add9520fSAndreas Jaekel case 'B': 1708a5090b97SAndreas Jaekel mode = MD_QUEUE_NONBLOCKING; 1709a5090b97SAndreas Jaekel arg = optarg; 1710a5090b97SAndreas Jaekel break; 1711add9520fSAndreas Jaekel case 'P': 1712a5090b97SAndreas Jaekel mode = MD_QUEUE_PROPERTIES; 1713a5090b97SAndreas Jaekel arg = optarg; 1714a5090b97SAndreas Jaekel break; 1715a18c35b9SAndreas Jaekel case 'h': 1716a18c35b9SAndreas Jaekel case '?': 1717a18c35b9SAndreas Jaekel default: 1718a18c35b9SAndreas Jaekel usage(argv[0]); 1719a18c35b9SAndreas Jaekel } 1720a18c35b9SAndreas Jaekel } 1721a5090b97SAndreas Jaekel 1722a5090b97SAndreas Jaekel switch (mode) { 1723a5090b97SAndreas Jaekel case MD_STATISTICS: 1724a5090b97SAndreas Jaekel return zev_statistics(fd); 1725a5090b97SAndreas Jaekel case MD_POLL_EVENTS: 1726a5090b97SAndreas Jaekel return zev_poll_events(fd, create_tmp_queue); 1727*35526fb3SArne Jansen case MD_DUMP_SPOOL: 1728*35526fb3SArne Jansen return zev_dump_spool(fd); 1729a5090b97SAndreas Jaekel case MD_CHECKSUMS: 1730a5090b97SAndreas Jaekel return zev_checksum(fd, arg); 1731a5090b97SAndreas Jaekel case MD_DEBUG_INFO: 1732a5090b97SAndreas Jaekel return zev_debug_info(fd); 1733a5090b97SAndreas Jaekel case MD_LIST_QUEUES: 1734a5090b97SAndreas Jaekel return zev_list_queues(fd); 1735a5090b97SAndreas Jaekel case MD_SET_GLOBAL_MAX_QUEUE_LEN: 1736a5090b97SAndreas Jaekel return zev_set_global_max_queue_len(fd, arg); 1737a5090b97SAndreas Jaekel case MD_SET_MAX_QUEUE_LEN: 1738a5090b97SAndreas Jaekel return zev_set_max_queue_len(fd, arg, arg2); 1739a5090b97SAndreas Jaekel case MD_SET_POLL_WAKEUP_QUEUE_LEN: 1740a5090b97SAndreas Jaekel return zev_set_poll_wakeup_queue_len(fd, arg, arg2); 1741b690436dSAndreas Jaekel case MD_ZEVSTAT: 1742f432e238SAndreas Jaekel return zev_zevstat(fd, arg, arg2, NULL); 1743f432e238SAndreas Jaekel case MD_ZEV_REPORT: 1744f432e238SAndreas Jaekel return zev_report(fd, arg); 1745a5090b97SAndreas Jaekel case MD_MUTE_POOL: 1746a5090b97SAndreas Jaekel return zev_mute_pool(fd, arg); 1747a5090b97SAndreas Jaekel case MD_UNMUTE_POOL: 1748a5090b97SAndreas Jaekel return zev_unmute_pool(fd, arg); 1749a5090b97SAndreas Jaekel case MD_MARK: 1750a5090b97SAndreas Jaekel return zev_mark(fd, arg); 1751a5090b97SAndreas Jaekel case MD_ADD_QUEUE: 1752a5090b97SAndreas Jaekel return zev_add_queue(fd, arg, 0); 1753a5090b97SAndreas Jaekel case MD_ADD_BLOCKING_QUEUE: 1754a5090b97SAndreas Jaekel return zev_add_queue(fd, arg, 1); 1755a5090b97SAndreas Jaekel case MD_REMOVE_QUEUE: 1756a5090b97SAndreas Jaekel return zev_remove_queue(fd, arg); 1757a5090b97SAndreas Jaekel case MD_QUEUE_BLOCKING: 1758a5090b97SAndreas Jaekel return zev_queue_blocking(fd, arg, 0); 1759a5090b97SAndreas Jaekel case MD_QUEUE_NONBLOCKING: 1760a5090b97SAndreas Jaekel return zev_queue_blocking(fd, arg, 1); 1761a5090b97SAndreas Jaekel case MD_QUEUE_PROPERTIES: 1762a5090b97SAndreas Jaekel return zev_queue_properties(fd, arg); 1763a5090b97SAndreas Jaekel default: 1764a18c35b9SAndreas Jaekel close(fd); 1765a5090b97SAndreas Jaekel usage(argv[0]); 1766add9520fSAndreas Jaekel return EXIT_FAILURE; 1767a5090b97SAndreas Jaekel }; 1768a18c35b9SAndreas Jaekel } 1769a18c35b9SAndreas Jaekel 1770