12bb8e5e2SAndreas Jaekel #include <stdio.h> 22bb8e5e2SAndreas Jaekel #include <unistd.h> 32bb8e5e2SAndreas Jaekel #include <stdlib.h> 42bb8e5e2SAndreas Jaekel #include <fcntl.h> 52bb8e5e2SAndreas Jaekel #include <stropts.h> 62bb8e5e2SAndreas Jaekel #include <poll.h> 72bb8e5e2SAndreas Jaekel #include <string.h> 82bb8e5e2SAndreas Jaekel #include <sys/fs/zev.h> 92bb8e5e2SAndreas Jaekel #include <errno.h> 10b9710123SAndreas Jaekel #include <sys/sysmacros.h> 11*d65b2fffSAndreas Jaekel #include <stdarg.h> 122bb8e5e2SAndreas Jaekel 13e9a5e479SAndreas Jaekel #define ZEV_DEVICE "/devices/pseudo/zev@0:ctrl" 142bb8e5e2SAndreas Jaekel 152bb8e5e2SAndreas Jaekel static char *zev_device = ZEV_DEVICE; 162bb8e5e2SAndreas Jaekel 179193e9c2SAndreas Jaekel static char *zev_op_name[] = { 18*d65b2fffSAndreas Jaekel "ERROR", 19*d65b2fffSAndreas Jaekel "MARK", 20*d65b2fffSAndreas Jaekel "ZFS_MOUNT", 21*d65b2fffSAndreas Jaekel "ZFS_UMOUNT", 22*d65b2fffSAndreas Jaekel "ZVOL_WRITE", 23*d65b2fffSAndreas Jaekel "ZVOL_TRUNCATE", 24*d65b2fffSAndreas Jaekel "ZNODE_CLOSE_AFTER_UPDATE", 25*d65b2fffSAndreas Jaekel "ZNODE_CREATE", 26*d65b2fffSAndreas Jaekel "ZNODE_MKDIR", 27*d65b2fffSAndreas Jaekel "ZNODE_MAKE_XATTR_DIR", 28*d65b2fffSAndreas Jaekel "ZNODE_REMOVE", 29*d65b2fffSAndreas Jaekel "ZNODE_RMDIR", 30*d65b2fffSAndreas Jaekel "ZNODE_LINK", 31*d65b2fffSAndreas Jaekel "ZNODE_SYMLINK", 32*d65b2fffSAndreas Jaekel "ZNODE_RENAME", 33*d65b2fffSAndreas Jaekel "ZNODE_WRITE", 34*d65b2fffSAndreas Jaekel "ZNODE_TRUNCATE", 35*d65b2fffSAndreas Jaekel "ZNODE_SETATTR", 36*d65b2fffSAndreas Jaekel "ZNODE_ACL", 379193e9c2SAndreas Jaekel NULL 389193e9c2SAndreas Jaekel }; 399193e9c2SAndreas Jaekel 405e286361SAndreas Jaekel static int verbose = 0; 41*d65b2fffSAndreas Jaekel static int grep_friendly = 0; 42*d65b2fffSAndreas Jaekel 43*d65b2fffSAndreas Jaekel static void 44*d65b2fffSAndreas Jaekel zpf(char *fmt, ...) 45*d65b2fffSAndreas Jaekel { 46*d65b2fffSAndreas Jaekel va_list ap; 47*d65b2fffSAndreas Jaekel 48*d65b2fffSAndreas Jaekel va_start(ap, fmt); 49*d65b2fffSAndreas Jaekel vprintf(fmt, ap); 50*d65b2fffSAndreas Jaekel va_end(ap); 51*d65b2fffSAndreas Jaekel if (grep_friendly) { 52*d65b2fffSAndreas Jaekel printf(" "); 53*d65b2fffSAndreas Jaekel } else { 54*d65b2fffSAndreas Jaekel printf("\n"); 55*d65b2fffSAndreas Jaekel } 56*d65b2fffSAndreas Jaekel } 57*d65b2fffSAndreas Jaekel 58*d65b2fffSAndreas Jaekel static void 59*d65b2fffSAndreas Jaekel znl(void) 60*d65b2fffSAndreas Jaekel { 61*d65b2fffSAndreas Jaekel if (grep_friendly) 62*d65b2fffSAndreas Jaekel printf("\n"); 63*d65b2fffSAndreas Jaekel } 645e286361SAndreas Jaekel 65e9a5e479SAndreas Jaekel static int 662bb8e5e2SAndreas Jaekel zev_statistics(int fd) 672bb8e5e2SAndreas Jaekel { 682bb8e5e2SAndreas Jaekel zev_statistics_t zs; 69e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_GLOBAL_STATISTICS, &zs)) { 702bb8e5e2SAndreas Jaekel perror("getting statistics data failed"); 71e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 722bb8e5e2SAndreas Jaekel } 732bb8e5e2SAndreas Jaekel printf("ZEV module state:\n"); 742bb8e5e2SAndreas Jaekel 752bb8e5e2SAndreas Jaekel printf(" queue length in bytes : %lu\n", zs.zev_queue_len); 762bb8e5e2SAndreas Jaekel printf(" queue length limit : %lu\n", zs.zev_max_queue_len); 772bb8e5e2SAndreas Jaekel printf(" bytes read from device : %lu\n", zs.zev_bytes_read); 782bb8e5e2SAndreas Jaekel printf(" module internal errors : %lu\n\n", zs.zev_cnt_errors); 792bb8e5e2SAndreas Jaekel 80e9a5e479SAndreas Jaekel printf(" discarded events : %lu\n", 81e9a5e479SAndreas Jaekel zs.zev_cnt_discarded_events); 82e9a5e479SAndreas Jaekel printf(" discarded bytes : %lu\n\n", zs.zev_bytes_discarded); 83e9a5e479SAndreas Jaekel 842bb8e5e2SAndreas Jaekel printf("ZFS event statistics:\n"); 852bb8e5e2SAndreas Jaekel 862bb8e5e2SAndreas Jaekel printf(" total ZFS events : %lu\n", zs.zev_cnt_total_events); 872bb8e5e2SAndreas Jaekel printf(" ZFS mount : %lu\n", zs.zev_cnt_zfs_mount); 882bb8e5e2SAndreas Jaekel printf(" ZFS umount : %lu\n", zs.zev_cnt_zfs_umount); 892bb8e5e2SAndreas Jaekel printf(" ZVOL write : %lu\n", zs.zev_cnt_zvol_write); 902bb8e5e2SAndreas Jaekel printf(" ZVOL truncate : %lu\n", zs.zev_cnt_zvol_truncate); 912bb8e5e2SAndreas Jaekel printf(" ZNODE close after update: %lu\n", 922bb8e5e2SAndreas Jaekel zs.zev_cnt_znode_close_after_update); 932bb8e5e2SAndreas Jaekel printf(" ZNODE create : %lu\n", zs.zev_cnt_znode_create); 942bb8e5e2SAndreas Jaekel printf(" ZNODE remove : %lu\n", zs.zev_cnt_znode_remove); 952bb8e5e2SAndreas Jaekel printf(" ZNODE link : %lu\n", zs.zev_cnt_znode_link); 962bb8e5e2SAndreas Jaekel printf(" ZNODE symlink : %lu\n", zs.zev_cnt_znode_symlink); 972bb8e5e2SAndreas Jaekel printf(" ZNODE rename : %lu\n", zs.zev_cnt_znode_rename); 982bb8e5e2SAndreas Jaekel printf(" ZNODE write : %lu\n", zs.zev_cnt_znode_write); 992bb8e5e2SAndreas Jaekel printf(" ZNODE truncate : %lu\n", 1002bb8e5e2SAndreas Jaekel zs.zev_cnt_znode_truncate); 1012bb8e5e2SAndreas Jaekel printf(" ZNODE setattr : %lu\n", zs.zev_cnt_znode_setattr); 1022bb8e5e2SAndreas Jaekel printf(" ZNODE acl : %lu\n", zs.zev_cnt_znode_acl); 103e9a5e479SAndreas Jaekel return EXIT_SUCCESS; 1042bb8e5e2SAndreas Jaekel } 1052bb8e5e2SAndreas Jaekel 1062bb8e5e2SAndreas Jaekel static void 107*d65b2fffSAndreas Jaekel zev_print_inode_info(char *name, zev_inode_info_t *info) 108*d65b2fffSAndreas Jaekel { 109*d65b2fffSAndreas Jaekel zpf(" %s.inode: %llu", name, info->ino); 110*d65b2fffSAndreas Jaekel zpf(" %s.gen: %llu", name, info->gen); 111*d65b2fffSAndreas Jaekel zpf(" %s.mtime: %llu", name, info->mtime); 112*d65b2fffSAndreas Jaekel zpf(" %s.ctime: %llu", name, info->ctime); 113*d65b2fffSAndreas Jaekel zpf(" %s.size: %llu", name, info->size); 114*d65b2fffSAndreas Jaekel zpf(" %s.mode: %llo", name, info->mode); 115*d65b2fffSAndreas Jaekel zpf(" %s.links: %llu", name, info->links); 116*d65b2fffSAndreas Jaekel zpf(" %s.type: %lu", name, info->type); 117*d65b2fffSAndreas Jaekel zpf(" %s.flags: %lu", name, info->flags); 118*d65b2fffSAndreas Jaekel } 119*d65b2fffSAndreas Jaekel 120*d65b2fffSAndreas Jaekel static void 121*d65b2fffSAndreas Jaekel zev_print_mark_payload(zev_mark_t *rec) 122*d65b2fffSAndreas Jaekel { 123*d65b2fffSAndreas Jaekel int i; 124*d65b2fffSAndreas Jaekel int j; 125*d65b2fffSAndreas Jaekel uint8_t *p; 126*d65b2fffSAndreas Jaekel char c; 127*d65b2fffSAndreas Jaekel 128*d65b2fffSAndreas Jaekel zpf(" payload:"); 129*d65b2fffSAndreas Jaekel p = (uint8_t *)ZEV_PAYLOAD(rec); 130*d65b2fffSAndreas Jaekel for (i=0; i<rec->payload_len; i+=16) { 131*d65b2fffSAndreas Jaekel printf(" "); 132*d65b2fffSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) { 133*d65b2fffSAndreas Jaekel printf("%02x ", p[j]); 134*d65b2fffSAndreas Jaekel if (j == i + 7) 135*d65b2fffSAndreas Jaekel printf(" "); 136*d65b2fffSAndreas Jaekel } 137*d65b2fffSAndreas Jaekel if (grep_friendly) 138*d65b2fffSAndreas Jaekel continue; 139*d65b2fffSAndreas Jaekel for (; j<i+16; j++) { 140*d65b2fffSAndreas Jaekel printf(" "); 141*d65b2fffSAndreas Jaekel if (j == i + 7) 142*d65b2fffSAndreas Jaekel printf(" "); 143*d65b2fffSAndreas Jaekel } 144*d65b2fffSAndreas Jaekel printf(" "); 145*d65b2fffSAndreas Jaekel for (j=i; j<rec->payload_len && j<i+16; j++) { 146*d65b2fffSAndreas Jaekel c = '.'; 147*d65b2fffSAndreas Jaekel if (p[j] >= ' ' && p[j] <= '~') 148*d65b2fffSAndreas Jaekel c = p[j]; 149*d65b2fffSAndreas Jaekel printf("%c", c); 150*d65b2fffSAndreas Jaekel if (j == i + 7) 151*d65b2fffSAndreas Jaekel printf(" "); 152*d65b2fffSAndreas Jaekel } 153*d65b2fffSAndreas Jaekel printf("\n"); 154*d65b2fffSAndreas Jaekel } 155*d65b2fffSAndreas Jaekel } 156*d65b2fffSAndreas Jaekel 157*d65b2fffSAndreas Jaekel static void 15863aba447SAndreas Jaekel zev_print_error(char *buf) 15963aba447SAndreas Jaekel { 16063aba447SAndreas Jaekel zev_error_t *rec = (zev_error_t *)buf; 16163aba447SAndreas Jaekel time_t op_time = rec->op_time; 16263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 16363aba447SAndreas Jaekel 164*d65b2fffSAndreas Jaekel if (verbose) { 165*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 166*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 167*d65b2fffSAndreas Jaekel zpf(" failed.op: %s", 168*d65b2fffSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN]); 169*d65b2fffSAndreas Jaekel zpf(" message: %s", ZEV_ERRSTR(rec)); 170*d65b2fffSAndreas Jaekel znl(); 171*d65b2fffSAndreas Jaekel } else { 17263aba447SAndreas Jaekel printf("%s %s: failed_op=%s msg=%s\n", 17363aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 174*d65b2fffSAndreas Jaekel zev_op_name[rec->failed_op - ZEV_OP_MIN], 175*d65b2fffSAndreas Jaekel ZEV_ERRSTR(rec)); 176*d65b2fffSAndreas Jaekel } 17763aba447SAndreas Jaekel } 17863aba447SAndreas Jaekel 17963aba447SAndreas Jaekel static void 18001c2c787SAndreas Jaekel zev_print_mark(char *buf) 18101c2c787SAndreas Jaekel { 18201c2c787SAndreas Jaekel zev_mark_t *rec = (zev_mark_t *)buf; 18301c2c787SAndreas Jaekel time_t op_time = rec->op_time; 18401c2c787SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 18501c2c787SAndreas Jaekel 186*d65b2fffSAndreas Jaekel if (verbose) { 187*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 188*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 189*d65b2fffSAndreas Jaekel zpf(" mark.id: %llu", rec->mark_id); 190*d65b2fffSAndreas Jaekel zpf(" payload.len: %llu", rec->payload_len); 191*d65b2fffSAndreas Jaekel if (rec->payload_len) 192*d65b2fffSAndreas Jaekel zev_print_mark_payload(rec); 193*d65b2fffSAndreas Jaekel znl(); 194*d65b2fffSAndreas Jaekel } else { 19501c2c787SAndreas Jaekel printf("%s %s: guid=%llu mark_id=%lld payload_len=%ld\n", 196*d65b2fffSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], rec->guid, 197*d65b2fffSAndreas Jaekel rec->mark_id, rec->payload_len); 198*d65b2fffSAndreas Jaekel } 19901c2c787SAndreas Jaekel } 20001c2c787SAndreas Jaekel 20101c2c787SAndreas Jaekel static void 20263aba447SAndreas Jaekel zev_print_zfs_mount(char *buf) 20363aba447SAndreas Jaekel { 20463aba447SAndreas Jaekel zev_zfs_mount_t *rec = (zev_zfs_mount_t *)buf; 20563aba447SAndreas Jaekel time_t op_time = rec->op_time; 20663aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 20763aba447SAndreas Jaekel 208*d65b2fffSAndreas Jaekel if (verbose) { 209*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 210*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 211*d65b2fffSAndreas Jaekel zpf(" dataset: %s", ZEV_DATASET(rec)); 212*d65b2fffSAndreas Jaekel zpf(" mountpoint: %s", ZEV_MOUNTPOINT(rec)); 213*d65b2fffSAndreas Jaekel zpf(" remount: %s", rec->remount ? "true" : "false"); 214*d65b2fffSAndreas Jaekel zev_print_inode_info("root", &rec->root); 215*d65b2fffSAndreas Jaekel znl(); 216*d65b2fffSAndreas Jaekel } else { 217*d65b2fffSAndreas Jaekel printf("%s %s: guid=%llu remount=%s dataset='%s' " 218*d65b2fffSAndreas Jaekel "mountpoint='%s'\n", 21963aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 22063aba447SAndreas Jaekel rec->guid, 22163aba447SAndreas Jaekel rec->remount ? "true" : "false", 22263aba447SAndreas Jaekel ZEV_DATASET(rec), 22363aba447SAndreas Jaekel ZEV_MOUNTPOINT(rec)); 22463aba447SAndreas Jaekel } 225*d65b2fffSAndreas Jaekel } 22663aba447SAndreas Jaekel 22763aba447SAndreas Jaekel static void 22863aba447SAndreas Jaekel zev_print_zfs_umount(char *buf) 22963aba447SAndreas Jaekel { 23063aba447SAndreas Jaekel zev_zfs_umount_t *rec = (zev_zfs_umount_t *)buf; 23163aba447SAndreas Jaekel time_t op_time = rec->op_time; 23263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 23363aba447SAndreas Jaekel 234*d65b2fffSAndreas Jaekel if (verbose) { 235*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 236*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 237*d65b2fffSAndreas Jaekel znl(); 238*d65b2fffSAndreas Jaekel } else { 23963aba447SAndreas Jaekel printf("%s %s: guid=%llu\n", 24063aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 24163aba447SAndreas Jaekel rec->guid); 24263aba447SAndreas Jaekel } 243*d65b2fffSAndreas Jaekel } 24463aba447SAndreas Jaekel 24563aba447SAndreas Jaekel static void 24663aba447SAndreas Jaekel zev_print_zvol_truncate(char *buf) 24763aba447SAndreas Jaekel { 24863aba447SAndreas Jaekel zev_zvol_truncate_t *rec = (zev_zvol_truncate_t *)buf; 24963aba447SAndreas Jaekel time_t op_time = rec->op_time; 25063aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 25163aba447SAndreas Jaekel 252*d65b2fffSAndreas Jaekel if (verbose) { 253*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 254*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 255*d65b2fffSAndreas Jaekel zpf(" offset: %llu", rec->offset); 256*d65b2fffSAndreas Jaekel zpf(" length: %llu", rec->length); 257*d65b2fffSAndreas Jaekel znl(); 258*d65b2fffSAndreas Jaekel } else { 25963aba447SAndreas Jaekel printf("%s %s: guid=%llu offset=%llu length=%llu\n", 26063aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 26163aba447SAndreas Jaekel rec->guid, 26263aba447SAndreas Jaekel rec->offset, 26363aba447SAndreas Jaekel rec->length); 26463aba447SAndreas Jaekel } 265*d65b2fffSAndreas Jaekel } 26663aba447SAndreas Jaekel 26763aba447SAndreas Jaekel static void 26863aba447SAndreas Jaekel zev_print_zvol_write(char *buf) 26963aba447SAndreas Jaekel { 27063aba447SAndreas Jaekel zev_print_zvol_truncate(buf); 27163aba447SAndreas Jaekel } 27263aba447SAndreas Jaekel 27363aba447SAndreas Jaekel static void 27463aba447SAndreas Jaekel zev_print_znode_close_after_update(char *buf) 27563aba447SAndreas Jaekel { 27663aba447SAndreas Jaekel zev_znode_close_after_update_t *rec = 27763aba447SAndreas Jaekel (zev_znode_close_after_update_t *)buf; 27863aba447SAndreas Jaekel time_t op_time = rec->op_time; 27963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 28063aba447SAndreas Jaekel 281*d65b2fffSAndreas Jaekel if (verbose) { 282*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 283*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 284*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 285*d65b2fffSAndreas Jaekel znl(); 286*d65b2fffSAndreas Jaekel } else { 28763aba447SAndreas Jaekel printf("%s %s: guid=%llu file=%llu.%llu\n", 28863aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 28963aba447SAndreas Jaekel rec->guid, 29063aba447SAndreas Jaekel rec->file.ino, rec->file.gen); 29163aba447SAndreas Jaekel } 292*d65b2fffSAndreas Jaekel } 29363aba447SAndreas Jaekel 29463aba447SAndreas Jaekel static void 29563aba447SAndreas Jaekel zev_print_znode_create(char *buf) 29663aba447SAndreas Jaekel { 29763aba447SAndreas Jaekel zev_znode_create_t *rec = (zev_znode_create_t *)buf; 29863aba447SAndreas Jaekel time_t op_time = rec->op_time; 29963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 30063aba447SAndreas Jaekel 301*d65b2fffSAndreas Jaekel if (verbose) { 302*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 303*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 304*d65b2fffSAndreas Jaekel zpf(" name: '%s'", ZEV_NAME(rec)); 305*d65b2fffSAndreas Jaekel zev_print_inode_info("parent", &rec->file); 306*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 307*d65b2fffSAndreas Jaekel znl(); 308*d65b2fffSAndreas Jaekel } else { 309c035b1e8SAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu file=%llu.%llu " 310c035b1e8SAndreas Jaekel "file.mtime=%llu, parent.mtime=%llu, name='%s'\n", 31163aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 31263aba447SAndreas Jaekel rec->guid, 31363aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 31463aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 315c035b1e8SAndreas Jaekel rec->file.mtime, rec->parent.mtime, 31663aba447SAndreas Jaekel ZEV_NAME(rec)); 31763aba447SAndreas Jaekel } 318*d65b2fffSAndreas Jaekel } 31963aba447SAndreas Jaekel 32063aba447SAndreas Jaekel static void 32163aba447SAndreas Jaekel zev_print_znode_mkdir(char *buf) 32263aba447SAndreas Jaekel { 32363aba447SAndreas Jaekel zev_print_znode_create(buf); 32463aba447SAndreas Jaekel } 32563aba447SAndreas Jaekel 32663aba447SAndreas Jaekel static void 32763aba447SAndreas Jaekel zev_print_znode_make_xattr_dir(char *buf) 32863aba447SAndreas Jaekel { 32963aba447SAndreas Jaekel zev_print_znode_create(buf); 33063aba447SAndreas Jaekel } 33163aba447SAndreas Jaekel 33263aba447SAndreas Jaekel static void 33363aba447SAndreas Jaekel zev_print_znode_remove(char *buf) 33463aba447SAndreas Jaekel { 33563aba447SAndreas Jaekel zev_znode_remove_t *rec = (zev_znode_remove_t *)buf; 33663aba447SAndreas Jaekel time_t op_time = rec->op_time; 33763aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 33863aba447SAndreas Jaekel 339*d65b2fffSAndreas Jaekel if (verbose) { 340*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 341*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 342*d65b2fffSAndreas Jaekel zpf(" file.name: '%s'", ZEV_NAME(rec)); 343*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 344*d65b2fffSAndreas Jaekel zev_print_inode_info("parent", &rec->file); 345*d65b2fffSAndreas Jaekel znl(); 346*d65b2fffSAndreas Jaekel } else { 347*d65b2fffSAndreas Jaekel printf("%s %s: guid=%llu parent=%llu.%llu " 348*d65b2fffSAndreas Jaekel "file.mtime=%llu name='%s'\n", 34963aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 35063aba447SAndreas Jaekel rec->guid, 35163aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 3526db5d4ecSAndreas Jaekel rec->file.mtime, 35363aba447SAndreas Jaekel ZEV_NAME(rec)); 35463aba447SAndreas Jaekel } 355*d65b2fffSAndreas Jaekel } 35663aba447SAndreas Jaekel 35763aba447SAndreas Jaekel static void 35863aba447SAndreas Jaekel zev_print_znode_rmdir(char *buf) 35963aba447SAndreas Jaekel { 36063aba447SAndreas Jaekel zev_print_znode_remove(buf); 36163aba447SAndreas Jaekel } 36263aba447SAndreas Jaekel 36363aba447SAndreas Jaekel static void 36463aba447SAndreas Jaekel zev_print_znode_link(char *buf) 36563aba447SAndreas Jaekel { 36663aba447SAndreas Jaekel zev_znode_link_t *rec = (zev_znode_link_t *)buf; 36763aba447SAndreas Jaekel time_t op_time = rec->op_time; 36863aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 36963aba447SAndreas Jaekel 370*d65b2fffSAndreas Jaekel if (verbose) { 371*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 372*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 373*d65b2fffSAndreas Jaekel zpf(" link.name: '%s'", ZEV_NAME(rec)); 374*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 375*d65b2fffSAndreas Jaekel zev_print_inode_info("parent", &rec->file); 376*d65b2fffSAndreas Jaekel znl(); 377*d65b2fffSAndreas Jaekel } else { 37803101f54SAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu " 37903101f54SAndreas Jaekel "file.ctime=%llu parent.ctime=%llu name='%s'\n", 38063aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 38163aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 38263aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 38303101f54SAndreas Jaekel rec->file.ctime, rec->parent.ctime, 38463aba447SAndreas Jaekel ZEV_NAME(rec)); 385*d65b2fffSAndreas Jaekel } 38663aba447SAndreas Jaekel } 38763aba447SAndreas Jaekel 38863aba447SAndreas Jaekel static void 38963aba447SAndreas Jaekel zev_print_znode_symlink(char *buf) 39063aba447SAndreas Jaekel { 39163aba447SAndreas Jaekel zev_znode_symlink_t *rec = (zev_znode_symlink_t *)buf; 39263aba447SAndreas Jaekel time_t op_time = rec->op_time; 39363aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 39463aba447SAndreas Jaekel 395*d65b2fffSAndreas Jaekel if (verbose) { 396*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 397*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 398*d65b2fffSAndreas Jaekel zpf(" symlink.name: '%s'", ZEV_NAME(rec)); 399*d65b2fffSAndreas Jaekel zpf(" symlink.link: '%s'", ZEV_LINK(rec)); 400*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 401*d65b2fffSAndreas Jaekel zev_print_inode_info("parent", &rec->file); 402*d65b2fffSAndreas Jaekel znl(); 403*d65b2fffSAndreas Jaekel } else { 404*d65b2fffSAndreas Jaekel printf("%s %s: parent=%llu.%llu file=%llu.%llu " 405*d65b2fffSAndreas Jaekel "name='%s' link='%s'\n", 40663aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 40763aba447SAndreas Jaekel rec->parent.ino, rec->parent.gen, 40863aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 40963aba447SAndreas Jaekel ZEV_NAME(rec), 41063aba447SAndreas Jaekel ZEV_LINK(rec)); 41163aba447SAndreas Jaekel } 412*d65b2fffSAndreas Jaekel } 41363aba447SAndreas Jaekel 41463aba447SAndreas Jaekel static void 41563aba447SAndreas Jaekel zev_print_znode_rename(char *buf) 41663aba447SAndreas Jaekel { 41763aba447SAndreas Jaekel zev_znode_rename_t *rec = (zev_znode_rename_t *)buf; 41863aba447SAndreas Jaekel time_t op_time = rec->op_time; 41963aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 42063aba447SAndreas Jaekel 421*d65b2fffSAndreas Jaekel if (verbose) { 422*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 423*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 424*d65b2fffSAndreas Jaekel zpf(" file.srcname: '%s'", ZEV_SRCNAME(rec)); 425*d65b2fffSAndreas Jaekel zpf(" file.dstname: '%s'", ZEV_DSTNAME(rec)); 426*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 427*d65b2fffSAndreas Jaekel zev_print_inode_info("srcdir", &rec->srcdir); 428*d65b2fffSAndreas Jaekel zev_print_inode_info("dstdir", &rec->dstdir); 429*d65b2fffSAndreas Jaekel znl(); 430*d65b2fffSAndreas Jaekel } else { 431*d65b2fffSAndreas Jaekel printf("%s %s: srcdir=%llu.%llu dstdir=%llu.%llu " 432*d65b2fffSAndreas Jaekel "file=%llu.%llu file.mtime=%llu, file.ctime=%llu, " 433*d65b2fffSAndreas Jaekel "srcdir.mtime=%llu, srcdir.ctime=%llu, " 434*d65b2fffSAndreas Jaekel "dstdir.mtime=%llu, dstdir.ctime=%llu, " 43563aba447SAndreas Jaekel "srcname='%s' dstname='%s'\n", 43663aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 43763aba447SAndreas Jaekel rec->srcdir.ino, rec->srcdir.gen, 43863aba447SAndreas Jaekel rec->dstdir.ino, rec->dstdir.gen, 43963aba447SAndreas Jaekel rec->file.ino, rec->file.gen, 440c035b1e8SAndreas Jaekel rec->file.mtime, rec->file.ctime, 441c035b1e8SAndreas Jaekel rec->srcdir.mtime, rec->srcdir.ctime, 442c035b1e8SAndreas Jaekel rec->dstdir.mtime, rec->dstdir.ctime, 44363aba447SAndreas Jaekel ZEV_SRCNAME(rec), 44463aba447SAndreas Jaekel ZEV_DSTNAME(rec)); 44563aba447SAndreas Jaekel } 446*d65b2fffSAndreas Jaekel } 44763aba447SAndreas Jaekel 44863aba447SAndreas Jaekel static void 4495e286361SAndreas Jaekel sig2hex_direct(const uint8_t *sig, char *hex) 4505e286361SAndreas Jaekel { 4515e286361SAndreas Jaekel int i; 4525e286361SAndreas Jaekel 4535e286361SAndreas Jaekel for (i = 0; i < SHA1_DIGEST_LENGTH; ++i) { 4545e286361SAndreas Jaekel sprintf(hex + 2 * i, "%02x", sig[i]); 4555e286361SAndreas Jaekel } 4565e286361SAndreas Jaekel hex[SHA1_DIGEST_LENGTH * 2] = '\0'; 4575e286361SAndreas Jaekel } 4585e286361SAndreas Jaekel 4595e286361SAndreas Jaekel static void 46063aba447SAndreas Jaekel zev_print_znode_write(char *buf) 46163aba447SAndreas Jaekel { 46263aba447SAndreas Jaekel zev_znode_write_t *rec = (zev_znode_write_t *)buf; 46363aba447SAndreas Jaekel time_t op_time = rec->op_time; 46463aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 4655e286361SAndreas Jaekel zev_sig_t *sig; 4665e286361SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 4675e286361SAndreas Jaekel int i; 46863aba447SAndreas Jaekel 4695e286361SAndreas Jaekel if (verbose) { 470*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 471*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 472*d65b2fffSAndreas Jaekel zpf(" offset: %llu", rec->offset); 473*d65b2fffSAndreas Jaekel zpf(" length: %llu", rec->length); 474*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 475*d65b2fffSAndreas Jaekel znl(); 4765e286361SAndreas Jaekel for (i=0; i<rec->signature_cnt; i++) { 4775e286361SAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(rec); 4785e286361SAndreas Jaekel sig += i; 4795e286361SAndreas Jaekel sig2hex_direct(sig->value, sigval); 4805e286361SAndreas Jaekel printf(" sig: level %d, offset %llu, value %s\n", 4815e286361SAndreas Jaekel sig->level, sig->block_offset, sigval); 4825e286361SAndreas Jaekel } 483*d65b2fffSAndreas Jaekel } else { 484*d65b2fffSAndreas Jaekel printf("%s %s: file=%llu.%llu offset=%llu length=%llu\n", 485*d65b2fffSAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 486*d65b2fffSAndreas Jaekel rec->file.ino, rec->file.gen, 487*d65b2fffSAndreas Jaekel rec->offset, rec->length); 4885e286361SAndreas Jaekel } 48963aba447SAndreas Jaekel } 49063aba447SAndreas Jaekel 49163aba447SAndreas Jaekel static void 49263aba447SAndreas Jaekel zev_print_znode_truncate(char *buf) 49363aba447SAndreas Jaekel { 49463aba447SAndreas Jaekel zev_print_znode_write(buf); 49563aba447SAndreas Jaekel } 49663aba447SAndreas Jaekel 49763aba447SAndreas Jaekel static void 49863aba447SAndreas Jaekel zev_print_znode_setattr(char *buf) 49963aba447SAndreas Jaekel { 50063aba447SAndreas Jaekel zev_znode_setattr_t *rec = (zev_znode_setattr_t *)buf; 50163aba447SAndreas Jaekel time_t op_time = rec->op_time; 50263aba447SAndreas Jaekel char *ct = ctime(&op_time); ct[24] = '\0'; 50363aba447SAndreas Jaekel 504*d65b2fffSAndreas Jaekel if (verbose) { 505*d65b2fffSAndreas Jaekel zpf("%s %s", ct, zev_op_name[rec->op - ZEV_OP_MIN]); 506*d65b2fffSAndreas Jaekel zpf(" guid: %llu", rec->guid); 507*d65b2fffSAndreas Jaekel zev_print_inode_info("file", &rec->file); 508*d65b2fffSAndreas Jaekel znl(); 509*d65b2fffSAndreas Jaekel } else { 510c035b1e8SAndreas Jaekel printf("%s %s: file=%llu.%llu mtime=%llu\n", 51163aba447SAndreas Jaekel ct, zev_op_name[rec->op - ZEV_OP_MIN], 512c035b1e8SAndreas Jaekel rec->file.ino, rec->file.gen, rec->file.mtime); 51363aba447SAndreas Jaekel } 514*d65b2fffSAndreas Jaekel } 51563aba447SAndreas Jaekel 51663aba447SAndreas Jaekel static void 51763aba447SAndreas Jaekel zev_print_znode_acl(char *buf) 51863aba447SAndreas Jaekel { 51963aba447SAndreas Jaekel zev_print_znode_setattr(buf); 52063aba447SAndreas Jaekel } 52163aba447SAndreas Jaekel 52263aba447SAndreas Jaekel static void 5239193e9c2SAndreas Jaekel zev_print_event(char *buf, int len) 5249193e9c2SAndreas Jaekel { 52563aba447SAndreas Jaekel int record_len; 52663aba447SAndreas Jaekel int op; 5279193e9c2SAndreas Jaekel 52863aba447SAndreas Jaekel record_len = *(uint32_t *)buf; 52963aba447SAndreas Jaekel if (record_len != len) { 53063aba447SAndreas Jaekel fprintf(stderr, "record length mismatch: got %d, expected %d\n", 53163aba447SAndreas Jaekel record_len, len); 5329193e9c2SAndreas Jaekel exit(1); 5339193e9c2SAndreas Jaekel } 53463aba447SAndreas Jaekel op = *((uint32_t *)buf + 1); 5359193e9c2SAndreas Jaekel if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) { 53663aba447SAndreas Jaekel fprintf(stderr, "unknown op code: %d\n", op); 5379193e9c2SAndreas Jaekel exit(1); 5389193e9c2SAndreas Jaekel } 53963aba447SAndreas Jaekel switch (op) { 54063aba447SAndreas Jaekel case ZEV_OP_ERROR: 54163aba447SAndreas Jaekel zev_print_error(buf); 5429193e9c2SAndreas Jaekel break; 54301c2c787SAndreas Jaekel case ZEV_OP_MARK: 54401c2c787SAndreas Jaekel zev_print_mark(buf); 54501c2c787SAndreas Jaekel break; 54663aba447SAndreas Jaekel case ZEV_OP_ZFS_MOUNT: 54763aba447SAndreas Jaekel zev_print_zfs_mount(buf); 5489193e9c2SAndreas Jaekel break; 54963aba447SAndreas Jaekel case ZEV_OP_ZFS_UMOUNT: 55063aba447SAndreas Jaekel zev_print_zfs_umount(buf); 5519193e9c2SAndreas Jaekel break; 55263aba447SAndreas Jaekel case ZEV_OP_ZVOL_TRUNCATE: 55363aba447SAndreas Jaekel zev_print_zvol_truncate(buf); 5549193e9c2SAndreas Jaekel break; 55563aba447SAndreas Jaekel case ZEV_OP_ZVOL_WRITE: 55663aba447SAndreas Jaekel zev_print_zvol_write(buf); 55763aba447SAndreas Jaekel break; 55863aba447SAndreas Jaekel case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE: 55963aba447SAndreas Jaekel zev_print_znode_close_after_update(buf); 56063aba447SAndreas Jaekel break; 56163aba447SAndreas Jaekel case ZEV_OP_ZNODE_CREATE: 56263aba447SAndreas Jaekel zev_print_znode_create(buf); 56363aba447SAndreas Jaekel break; 56463aba447SAndreas Jaekel case ZEV_OP_ZNODE_MKDIR: 56563aba447SAndreas Jaekel zev_print_znode_mkdir(buf); 56663aba447SAndreas Jaekel break; 56763aba447SAndreas Jaekel case ZEV_OP_ZNODE_MAKE_XATTR_DIR: 56863aba447SAndreas Jaekel zev_print_znode_make_xattr_dir(buf); 56963aba447SAndreas Jaekel break; 57063aba447SAndreas Jaekel case ZEV_OP_ZNODE_REMOVE: 57163aba447SAndreas Jaekel zev_print_znode_remove(buf); 57263aba447SAndreas Jaekel break; 57363aba447SAndreas Jaekel case ZEV_OP_ZNODE_RMDIR: 57463aba447SAndreas Jaekel zev_print_znode_rmdir(buf); 57563aba447SAndreas Jaekel break; 57663aba447SAndreas Jaekel case ZEV_OP_ZNODE_LINK: 57763aba447SAndreas Jaekel zev_print_znode_link(buf); 57863aba447SAndreas Jaekel break; 57963aba447SAndreas Jaekel case ZEV_OP_ZNODE_SYMLINK: 58063aba447SAndreas Jaekel zev_print_znode_symlink(buf); 58163aba447SAndreas Jaekel break; 58263aba447SAndreas Jaekel case ZEV_OP_ZNODE_RENAME: 58363aba447SAndreas Jaekel zev_print_znode_rename(buf); 58463aba447SAndreas Jaekel break; 58563aba447SAndreas Jaekel case ZEV_OP_ZNODE_WRITE: 58663aba447SAndreas Jaekel zev_print_znode_write(buf); 58763aba447SAndreas Jaekel break; 58863aba447SAndreas Jaekel case ZEV_OP_ZNODE_TRUNCATE: 58963aba447SAndreas Jaekel zev_print_znode_truncate(buf); 59063aba447SAndreas Jaekel break; 59163aba447SAndreas Jaekel case ZEV_OP_ZNODE_SETATTR: 59263aba447SAndreas Jaekel zev_print_znode_setattr(buf); 59363aba447SAndreas Jaekel break; 59463aba447SAndreas Jaekel case ZEV_OP_ZNODE_ACL: 59563aba447SAndreas Jaekel zev_print_znode_acl(buf); 5969193e9c2SAndreas Jaekel break; 5979193e9c2SAndreas Jaekel default: 59863aba447SAndreas Jaekel fprintf(stderr, "unhandled op code: %d\n", op); 5999193e9c2SAndreas Jaekel exit(1); 6009193e9c2SAndreas Jaekel } 6019193e9c2SAndreas Jaekel } 6029193e9c2SAndreas Jaekel 603e9a5e479SAndreas Jaekel static int 6044ca7dd5eSAndreas Jaekel zev_poll_events(int fd, int create_tmp_queue) 6052bb8e5e2SAndreas Jaekel { 6062bb8e5e2SAndreas Jaekel struct pollfd pfd[1]; 6072bb8e5e2SAndreas Jaekel int ret; 6089193e9c2SAndreas Jaekel char buf[4096]; 60968a46c64SAndreas Jaekel zev_event_t *ev; 61068a46c64SAndreas Jaekel int off = 0; 611e9a5e479SAndreas Jaekel zev_ioctl_add_queue_t aq; 612e9a5e479SAndreas Jaekel int q_fd; 613e9a5e479SAndreas Jaekel 6144ca7dd5eSAndreas Jaekel if (create_tmp_queue) { 615e9a5e479SAndreas Jaekel aq.zev_max_queue_len = 0; 616e9a5e479SAndreas Jaekel aq.zev_flags = ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 617e9a5e479SAndreas Jaekel snprintf(aq.zev_name, ZEV_MAX_QUEUE_NAME_LEN, 618e9a5e479SAndreas Jaekel "zevadm.%ld.%ld", time(NULL), getpid()); 619e9a5e479SAndreas Jaekel aq.zev_namelen = strlen(aq.zev_name); 620e9a5e479SAndreas Jaekel 621e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) { 622e9a5e479SAndreas Jaekel perror("adding temporary queue failed"); 623e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 624e9a5e479SAndreas Jaekel } 625e9a5e479SAndreas Jaekel 6264ca7dd5eSAndreas Jaekel snprintf(buf, sizeof(buf), 6274ca7dd5eSAndreas Jaekel "/devices/pseudo/zev@0:%s", aq.zev_name); 628e9a5e479SAndreas Jaekel q_fd = open(buf, O_RDONLY); 629e9a5e479SAndreas Jaekel if (q_fd < 0) { 630e9a5e479SAndreas Jaekel perror("opening queue device failed"); 631e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 632e9a5e479SAndreas Jaekel } 6334ca7dd5eSAndreas Jaekel } else { 6344ca7dd5eSAndreas Jaekel q_fd = fd; 6354ca7dd5eSAndreas Jaekel } 636e9a5e479SAndreas Jaekel 6372bb8e5e2SAndreas Jaekel while (1) { 638e9a5e479SAndreas Jaekel pfd[0].fd = q_fd; 6392bb8e5e2SAndreas Jaekel pfd[0].events = POLLIN; 6402bb8e5e2SAndreas Jaekel ret = poll(pfd, 1, 1000); 6412bb8e5e2SAndreas Jaekel if (ret < 0) { 6422bb8e5e2SAndreas Jaekel perror("poll failed"); 6434ca7dd5eSAndreas Jaekel close(q_fd); 644e9a5e479SAndreas Jaekel return(EXIT_FAILURE); 6452bb8e5e2SAndreas Jaekel } 6462bb8e5e2SAndreas Jaekel if (!(pfd[0].revents & POLLIN)) 6472bb8e5e2SAndreas Jaekel continue; 6482bb8e5e2SAndreas Jaekel /* data available */ 649e9a5e479SAndreas Jaekel ret = read(q_fd, buf, sizeof(buf)); 6502bb8e5e2SAndreas Jaekel if (ret < 0) { 6512bb8e5e2SAndreas Jaekel perror("read failed"); 6524ca7dd5eSAndreas Jaekel close(q_fd); 653e9a5e479SAndreas Jaekel return(EXIT_FAILURE); 6542bb8e5e2SAndreas Jaekel } 6552bb8e5e2SAndreas Jaekel if (ret == 0) 6562bb8e5e2SAndreas Jaekel continue; 65768a46c64SAndreas Jaekel while (ret > off) { 65868a46c64SAndreas Jaekel ev = (zev_event_t *)(buf + off); 65968a46c64SAndreas Jaekel zev_print_event(buf + off, ev->header.record_len); 66068a46c64SAndreas Jaekel off += ev->header.record_len; 66168a46c64SAndreas Jaekel } 662108668daSAndreas Jaekel off = 0; 6632bb8e5e2SAndreas Jaekel } 6644ca7dd5eSAndreas Jaekel if (create_tmp_queue) 665e9a5e479SAndreas Jaekel close(q_fd); 666e9a5e479SAndreas Jaekel return EXIT_SUCCESS; 6672bb8e5e2SAndreas Jaekel } 6682bb8e5e2SAndreas Jaekel 6692bb8e5e2SAndreas Jaekel static void 6702bb8e5e2SAndreas Jaekel usage(char *progname) 6712bb8e5e2SAndreas Jaekel { 672e9a5e479SAndreas Jaekel fprintf(stderr, "usage: %s [-d <dev>] [options]\n", progname); 673e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 674e9a5e479SAndreas Jaekel fprintf(stderr, " Status information:\n"); 6752bb8e5e2SAndreas Jaekel fprintf(stderr, " -s show zev statistics\n"); 6762bb8e5e2SAndreas Jaekel fprintf(stderr, " -p poll for ZFS events\n"); 677e9a5e479SAndreas Jaekel fprintf(stderr, " -D print zev module debug " 678e9a5e479SAndreas Jaekel "information\n"); 679e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 680e9a5e479SAndreas Jaekel fprintf(stderr, " Tune zev module settings:\n"); 681e9a5e479SAndreas Jaekel fprintf(stderr, " -Q <bytes> set maximum event queue " 682e9a5e479SAndreas Jaekel "length\n"); 683e9a5e479SAndreas Jaekel fprintf(stderr, " -m <pool> mute pool, no events for " 684e9a5e479SAndreas Jaekel "this pool\n"); 6852bb8e5e2SAndreas Jaekel fprintf(stderr, " -M <pool> unmute pool\n"); 686e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 687e9a5e479SAndreas Jaekel fprintf(stderr, " Queue management:\n"); 688e9a5e479SAndreas Jaekel fprintf(stderr, " -l list queues\n"); 6894ca7dd5eSAndreas Jaekel fprintf(stderr, " -a <name> add non-blocking queue\n"); 6904ca7dd5eSAndreas Jaekel fprintf(stderr, " -A <name> add blocking queue\n"); 691e9a5e479SAndreas Jaekel fprintf(stderr, " -r <name> remove queue\n"); 692e9a5e479SAndreas Jaekel fprintf(stderr, " -b <name> make queue non-blocking " 693e9a5e479SAndreas Jaekel "(default)\n"); 694e9a5e479SAndreas Jaekel fprintf(stderr, " -B <name> make queue block when full\n"); 695e9a5e479SAndreas Jaekel fprintf(stderr, " -P <name> display queue properties\n"); 6964ca7dd5eSAndreas Jaekel fprintf(stderr, " -L <name> <bytes> set maximum event queue " 697e9a5e479SAndreas Jaekel "length\n"); 698e9a5e479SAndreas Jaekel fprintf(stderr, " -t <name> <bytes> set queue length poll " 699e9a5e479SAndreas Jaekel "throttle\n"); 700e9a5e479SAndreas Jaekel fprintf(stderr, "\n"); 701e9a5e479SAndreas Jaekel fprintf(stderr, " Other options:\n"); 702e9a5e479SAndreas Jaekel fprintf(stderr, " -d <dev> non-default device file. " 703e9a5e479SAndreas Jaekel "('%s')\n", ZEV_DEVICE); 7044ca7dd5eSAndreas Jaekel fprintf(stderr, " -q <name> use device file for this " 7054ca7dd5eSAndreas Jaekel "queue name\n"); 70601c2c787SAndreas Jaekel fprintf(stderr, " -k <guid>:<payload> queue mark event\n"); 707b9710123SAndreas Jaekel fprintf(stderr, " -c <filename> list file's content " 708b9710123SAndreas Jaekel "checksums\n"); 709*d65b2fffSAndreas Jaekel fprintf(stderr, " -v verbose: additional output " 7105e286361SAndreas Jaekel "for some operations\n"); 711*d65b2fffSAndreas Jaekel fprintf(stderr, " -g grep-friendly event output, " 712*d65b2fffSAndreas Jaekel "one event per line\n"); 7132bb8e5e2SAndreas Jaekel exit (EXIT_FAILURE); 7142bb8e5e2SAndreas Jaekel } 7152bb8e5e2SAndreas Jaekel 7162bb8e5e2SAndreas Jaekel static int 7174ca7dd5eSAndreas Jaekel zev_add_queue(int fd, char *arg, int blocking) 7182bb8e5e2SAndreas Jaekel { 719e9a5e479SAndreas Jaekel zev_ioctl_add_queue_t aq; 720e9a5e479SAndreas Jaekel int namelen; 7212bb8e5e2SAndreas Jaekel 722e9a5e479SAndreas Jaekel namelen = strlen(arg); 723e9a5e479SAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) { 724e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg); 7252bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 7262bb8e5e2SAndreas Jaekel } 727e9a5e479SAndreas Jaekel 728e9a5e479SAndreas Jaekel aq.zev_namelen = namelen; 729e9a5e479SAndreas Jaekel strcpy(aq.zev_name, arg); 7304ca7dd5eSAndreas Jaekel aq.zev_flags = ZEV_FL_PERSISTENT; 7314ca7dd5eSAndreas Jaekel if (blocking) { 7324ca7dd5eSAndreas Jaekel aq.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 7334ca7dd5eSAndreas Jaekel aq.zev_max_queue_len = ZEV_MAX_QUEUE_LEN; 7344ca7dd5eSAndreas Jaekel } else { 735e9a5e479SAndreas Jaekel aq.zev_max_queue_len = (1024 * 1024); 7364ca7dd5eSAndreas Jaekel } 737e9a5e479SAndreas Jaekel 738e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_ADD_QUEUE, &aq)) { 739e9a5e479SAndreas Jaekel perror("adding queue failed"); 7402bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 7412bb8e5e2SAndreas Jaekel } 7422bb8e5e2SAndreas Jaekel return (0); 7432bb8e5e2SAndreas Jaekel } 7442bb8e5e2SAndreas Jaekel 7452bb8e5e2SAndreas Jaekel static int 746e9a5e479SAndreas Jaekel zev_remove_queue(int fd, char *arg) 747205a9bc9SAndreas Jaekel { 748e9a5e479SAndreas Jaekel zev_ioctl_remove_queue_t aq; 749e9a5e479SAndreas Jaekel int namelen; 750205a9bc9SAndreas Jaekel 751e9a5e479SAndreas Jaekel namelen = strlen(arg); 752e9a5e479SAndreas Jaekel if (namelen > ZEV_MAX_QUEUE_NAME_LEN) { 753e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long: %s\n", arg); 754205a9bc9SAndreas Jaekel return (EXIT_FAILURE); 755205a9bc9SAndreas Jaekel } 756e9a5e479SAndreas Jaekel 7574ca7dd5eSAndreas Jaekel aq.zev_queue_name.zev_namelen = namelen; 7584ca7dd5eSAndreas Jaekel strcpy(aq.zev_queue_name.zev_name, arg); 759e9a5e479SAndreas Jaekel 760e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_REMOVE_QUEUE, &aq)) { 761e9a5e479SAndreas Jaekel perror("removing queue failed"); 762e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 763e9a5e479SAndreas Jaekel } 764e9a5e479SAndreas Jaekel return (0); 765e9a5e479SAndreas Jaekel } 766e9a5e479SAndreas Jaekel 767e9a5e479SAndreas Jaekel static int 768e9a5e479SAndreas Jaekel zev_set_global_max_queue_len(int fd, char *arg) 769e9a5e479SAndreas Jaekel { 770e9a5e479SAndreas Jaekel uint64_t maxqueuelen; 771e9a5e479SAndreas Jaekel 772e9a5e479SAndreas Jaekel errno = 0; 773e9a5e479SAndreas Jaekel maxqueuelen = strtol(arg, (char **)NULL, 10); 774e9a5e479SAndreas Jaekel if (errno) { 775e9a5e479SAndreas Jaekel fprintf(stderr, "invalid queue length parameter: %s\n", arg); 776e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 777e9a5e479SAndreas Jaekel } 778e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_MAX_QUEUE_LEN, &maxqueuelen)) { 779e9a5e479SAndreas Jaekel perror("setting max queue length failed"); 780205a9bc9SAndreas Jaekel return (EXIT_FAILURE); 781205a9bc9SAndreas Jaekel } 782205a9bc9SAndreas Jaekel return (0); 783205a9bc9SAndreas Jaekel } 784205a9bc9SAndreas Jaekel 785205a9bc9SAndreas Jaekel static int 7862bb8e5e2SAndreas Jaekel zev_mute_unmute_impl(int fd, char *poolname, int mute) 7872bb8e5e2SAndreas Jaekel { 7882bb8e5e2SAndreas Jaekel zev_ioctl_poolarg_t pa; 7892bb8e5e2SAndreas Jaekel int len; 7902bb8e5e2SAndreas Jaekel int op = mute ? ZEV_IOC_MUTE_POOL : ZEV_IOC_UNMUTE_POOL; 7912bb8e5e2SAndreas Jaekel len = strlen(poolname); 7922bb8e5e2SAndreas Jaekel if (len <= 0 || len >= sizeof(pa.zev_poolname)) { 7932bb8e5e2SAndreas Jaekel fprintf(stderr, "invalid poolname: %s\n", poolname); 7942bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 7952bb8e5e2SAndreas Jaekel } 7962bb8e5e2SAndreas Jaekel strcpy(pa.zev_poolname, poolname); 7972bb8e5e2SAndreas Jaekel pa.zev_poolname_len = len; 7982bb8e5e2SAndreas Jaekel if (ioctl(fd, op, &pa)) { 7992bb8e5e2SAndreas Jaekel perror("muting pool data failed"); 8002bb8e5e2SAndreas Jaekel return (EXIT_FAILURE); 8012bb8e5e2SAndreas Jaekel } 8022bb8e5e2SAndreas Jaekel return (0); 8032bb8e5e2SAndreas Jaekel } 8042bb8e5e2SAndreas Jaekel 8052bb8e5e2SAndreas Jaekel int 8062bb8e5e2SAndreas Jaekel zev_mute_pool(int fd, char *poolname) 8072bb8e5e2SAndreas Jaekel { 8082bb8e5e2SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 1); 8092bb8e5e2SAndreas Jaekel } 8102bb8e5e2SAndreas Jaekel 8112bb8e5e2SAndreas Jaekel int 8122bb8e5e2SAndreas Jaekel zev_unmute_pool(int fd, char *poolname) 8132bb8e5e2SAndreas Jaekel { 8142bb8e5e2SAndreas Jaekel return zev_mute_unmute_impl(fd, poolname, 0); 8152bb8e5e2SAndreas Jaekel } 8162bb8e5e2SAndreas Jaekel 81701c2c787SAndreas Jaekel static int 818e9a5e479SAndreas Jaekel zev_debug_info(int fd) 819e9a5e479SAndreas Jaekel { 820e9a5e479SAndreas Jaekel zev_ioctl_debug_info_t di; 821e9a5e479SAndreas Jaekel 822e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_DEBUG_INFO, &di)) { 823e9a5e479SAndreas Jaekel perror("getting zev debug info failed"); 824e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 825e9a5e479SAndreas Jaekel } 826e9a5e479SAndreas Jaekel 827e9a5e479SAndreas Jaekel printf("memory allocated: %llu bytes\n", di.zev_memory_allocated); 8285e286361SAndreas Jaekel printf("checksum cache size: %llu\n", di.zev_chksum_cache_size); 8295e286361SAndreas Jaekel printf("checksum cache hits: %llu\n", di.zev_chksum_cache_hits); 8305e286361SAndreas Jaekel printf("checksum cache misses: %llu\n", di.zev_chksum_cache_misses); 831e9a5e479SAndreas Jaekel return 0; 832e9a5e479SAndreas Jaekel } 833e9a5e479SAndreas Jaekel 834e9a5e479SAndreas Jaekel static int 83501c2c787SAndreas Jaekel zev_mark(int fd, char *arg) 83601c2c787SAndreas Jaekel { 83701c2c787SAndreas Jaekel zev_ioctl_mark_t *mark; 83801c2c787SAndreas Jaekel uint64_t guid; 83901c2c787SAndreas Jaekel int len; 84001c2c787SAndreas Jaekel char *p; 84101c2c787SAndreas Jaekel 84201c2c787SAndreas Jaekel p = strchr(arg, ':'); 84301c2c787SAndreas Jaekel if (!p) { 84401c2c787SAndreas Jaekel fprintf(stderr, "expected value is <guid>:<payload>, " 84501c2c787SAndreas Jaekel "e.g. '123:hello'\n"); 84601c2c787SAndreas Jaekel exit (EXIT_FAILURE); 84701c2c787SAndreas Jaekel } 84801c2c787SAndreas Jaekel *p = '\n'; 84901c2c787SAndreas Jaekel p++; 85001c2c787SAndreas Jaekel 85101c2c787SAndreas Jaekel errno = 0; 852e9a5e479SAndreas Jaekel guid = strtoll(arg, (char **)NULL, 10); 85301c2c787SAndreas Jaekel if (errno) { 85401c2c787SAndreas Jaekel fprintf(stderr, "guid must be a number.\n"); 85501c2c787SAndreas Jaekel exit (EXIT_FAILURE); 85601c2c787SAndreas Jaekel } 85701c2c787SAndreas Jaekel 85801c2c787SAndreas Jaekel len = strlen(p); 85901c2c787SAndreas Jaekel 86001c2c787SAndreas Jaekel mark = malloc(sizeof(*mark) + len + 1); 86101c2c787SAndreas Jaekel if (!mark) { 86201c2c787SAndreas Jaekel fprintf(stderr, "can't allocate mark structure: %s\n", 86301c2c787SAndreas Jaekel strerror(errno)); 86401c2c787SAndreas Jaekel exit (EXIT_FAILURE); 86501c2c787SAndreas Jaekel } 86601c2c787SAndreas Jaekel mark->zev_guid = guid; 86701c2c787SAndreas Jaekel mark->zev_mark_id = 0; 86801c2c787SAndreas Jaekel mark->zev_payload_len = len; 86901c2c787SAndreas Jaekel strcpy(ZEV_PAYLOAD(mark), p); 87001c2c787SAndreas Jaekel 87101c2c787SAndreas Jaekel if (ioctl(fd, ZEV_IOC_MARK, mark)) { 87201c2c787SAndreas Jaekel perror("queueing mark failed"); 87301c2c787SAndreas Jaekel return (EXIT_FAILURE); 87401c2c787SAndreas Jaekel } 87501c2c787SAndreas Jaekel 87601c2c787SAndreas Jaekel printf("mark id: %lu\n", mark->zev_mark_id); 87701c2c787SAndreas Jaekel return (0); 87801c2c787SAndreas Jaekel } 87901c2c787SAndreas Jaekel 880e9a5e479SAndreas Jaekel static int 881e9a5e479SAndreas Jaekel zev_queue_blocking(int fd, char *arg, int block) 882e9a5e479SAndreas Jaekel { 883e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 884e9a5e479SAndreas Jaekel 8854ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 8864ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 887e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 888e9a5e479SAndreas Jaekel return EXIT_FAILURE; 889e9a5e479SAndreas Jaekel } 8904ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 891e9a5e479SAndreas Jaekel 892e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 893e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 894e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 895e9a5e479SAndreas Jaekel } 896e9a5e479SAndreas Jaekel if (block) { 897e9a5e479SAndreas Jaekel gqp.zev_flags |= ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 898e9a5e479SAndreas Jaekel } else { 899e9a5e479SAndreas Jaekel gqp.zev_flags &= ~ZEV_FL_BLOCK_WHILE_QUEUE_FULL; 900e9a5e479SAndreas Jaekel } 901e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 902e9a5e479SAndreas Jaekel perror("setting queue properties failed"); 903e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 904e9a5e479SAndreas Jaekel } 905e9a5e479SAndreas Jaekel return (0); 906e9a5e479SAndreas Jaekel } 907e9a5e479SAndreas Jaekel 908e9a5e479SAndreas Jaekel static int 909e9a5e479SAndreas Jaekel zev_set_max_queue_len(int fd, char *arg, char *len) 910e9a5e479SAndreas Jaekel { 911e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 912e9a5e479SAndreas Jaekel 913e9a5e479SAndreas Jaekel if (!len) { 914e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter missing.\n"); 915e9a5e479SAndreas Jaekel return EXIT_FAILURE; 916e9a5e479SAndreas Jaekel } 917e9a5e479SAndreas Jaekel 9184ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 9194ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 920e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 921e9a5e479SAndreas Jaekel return EXIT_FAILURE; 922e9a5e479SAndreas Jaekel } 9234ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 924e9a5e479SAndreas Jaekel 925e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 926e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 927e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 928e9a5e479SAndreas Jaekel } 929e9a5e479SAndreas Jaekel gqp.zev_max_queue_len = atol(len); 930e9a5e479SAndreas Jaekel if (gqp.zev_max_queue_len == 0 && strcmp("0", len)) { 931e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter garbled.\n"); 932e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 933e9a5e479SAndreas Jaekel } 934e9a5e479SAndreas Jaekel if (gqp.zev_max_queue_len > ZEV_MAX_QUEUE_LEN) { 935e9a5e479SAndreas Jaekel fprintf(stderr, "queue size parameter out of bounds.\n"); 936e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 937e9a5e479SAndreas Jaekel } 938e9a5e479SAndreas Jaekel 939e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 940e9a5e479SAndreas Jaekel perror("setting queue properties failed"); 941e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 942e9a5e479SAndreas Jaekel } 943e9a5e479SAndreas Jaekel return (0); 944e9a5e479SAndreas Jaekel } 945e9a5e479SAndreas Jaekel 946e9a5e479SAndreas Jaekel static int 947e9a5e479SAndreas Jaekel zev_set_poll_wakeup_queue_len(int fd, char *arg, char *len) 948e9a5e479SAndreas Jaekel { 949e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 950e9a5e479SAndreas Jaekel 951e9a5e479SAndreas Jaekel if (!len) { 952e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter missing.\n"); 953e9a5e479SAndreas Jaekel return EXIT_FAILURE; 954e9a5e479SAndreas Jaekel } 955e9a5e479SAndreas Jaekel 9564ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 9574ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 958e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 959e9a5e479SAndreas Jaekel return EXIT_FAILURE; 960e9a5e479SAndreas Jaekel } 9614ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 962e9a5e479SAndreas Jaekel 963e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 964e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 965e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 966e9a5e479SAndreas Jaekel } 967e9a5e479SAndreas Jaekel gqp.zev_poll_wakeup_threshold = atol(len); 968e9a5e479SAndreas Jaekel if (gqp.zev_poll_wakeup_threshold == 0 && strcmp("0", len)) { 969e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter garbled.\n"); 970e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 971e9a5e479SAndreas Jaekel } 9724ca7dd5eSAndreas Jaekel if (gqp.zev_poll_wakeup_threshold > ZEV_MAX_POLL_WAKEUP_QUEUE_LEN) { 973e9a5e479SAndreas Jaekel fprintf(stderr, "poll throttle parameter out of bounds.\n"); 974e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 975e9a5e479SAndreas Jaekel } 976e9a5e479SAndreas Jaekel 977e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_SET_QUEUE_PROPERTIES, &gqp)) { 978e9a5e479SAndreas Jaekel perror("setting queue properties failed"); 979e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 980e9a5e479SAndreas Jaekel } 981e9a5e479SAndreas Jaekel return (0); 982e9a5e479SAndreas Jaekel } 983e9a5e479SAndreas Jaekel 984e9a5e479SAndreas Jaekel static int 985e9a5e479SAndreas Jaekel zev_queue_properties(int fd, char *arg) 986e9a5e479SAndreas Jaekel { 987e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 988e9a5e479SAndreas Jaekel 9894ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = strlen(arg); 9904ca7dd5eSAndreas Jaekel if (gqp.zev_queue_name.zev_namelen > ZEV_MAX_QUEUE_NAME_LEN) { 991e9a5e479SAndreas Jaekel fprintf(stderr, "queue name too long.\n"); 992e9a5e479SAndreas Jaekel return EXIT_FAILURE; 993e9a5e479SAndreas Jaekel } 9944ca7dd5eSAndreas Jaekel strcpy(gqp.zev_queue_name.zev_name, arg); 995e9a5e479SAndreas Jaekel 996e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 997e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 998e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 999e9a5e479SAndreas Jaekel } 1000e9a5e479SAndreas Jaekel 1001e9a5e479SAndreas Jaekel printf("queue : %s\n", arg); 1002e9a5e479SAndreas Jaekel printf("max size : %" PRIu64 "\n", gqp.zev_max_queue_len); 1003e9a5e479SAndreas Jaekel printf("poll throttle: %" PRIu64 "\n", gqp.zev_poll_wakeup_threshold); 1004e9a5e479SAndreas Jaekel printf("persistent : %s\n", 1005e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no"); 1006e9a5e479SAndreas Jaekel printf("blocking : %s\n", 1007e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? "yes" : "no"); 1008e9a5e479SAndreas Jaekel 1009e9a5e479SAndreas Jaekel return (0); 1010e9a5e479SAndreas Jaekel } 1011e9a5e479SAndreas Jaekel 1012e9a5e479SAndreas Jaekel static int 1013e9a5e479SAndreas Jaekel zev_list_queues(int fd) 1014e9a5e479SAndreas Jaekel { 1015e9a5e479SAndreas Jaekel zev_ioctl_get_queue_properties_t gqp; 1016e9a5e479SAndreas Jaekel zev_ioctl_get_queue_list_t gql; 1017e9a5e479SAndreas Jaekel zev_ioctl_get_queue_statistics_t gs; 1018e9a5e479SAndreas Jaekel uint64_t i; 1019e9a5e479SAndreas Jaekel char name[ZEV_MAX_QUEUE_NAME_LEN+1]; 1020e9a5e479SAndreas Jaekel 1021e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_LIST, &gql)) { 1022e9a5e479SAndreas Jaekel perror("getting queue list failed"); 1023e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 1024e9a5e479SAndreas Jaekel } 1025e9a5e479SAndreas Jaekel 1026e9a5e479SAndreas Jaekel printf("Name Size " 1027e9a5e479SAndreas Jaekel "Max Size Wakeup Per Block\n"); 1028e9a5e479SAndreas Jaekel 1029e9a5e479SAndreas Jaekel for (i=0; i<gql.zev_n_queues; i++) { 1030e9a5e479SAndreas Jaekel strncpy(name, gql.zev_queue_name[i].zev_name, 1031e9a5e479SAndreas Jaekel ZEV_MAX_QUEUE_NAME_LEN); 1032e9a5e479SAndreas Jaekel name[gql.zev_queue_name[i].zev_namelen] = '\0'; 1033e9a5e479SAndreas Jaekel 10344ca7dd5eSAndreas Jaekel memcpy(gqp.zev_queue_name.zev_name, 10354ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN); 10364ca7dd5eSAndreas Jaekel gqp.zev_queue_name.zev_namelen = 10374ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_namelen; 1038e9a5e479SAndreas Jaekel 1039e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_PROPERTIES, &gqp)) { 1040e9a5e479SAndreas Jaekel if (errno == ENOENT) 1041e9a5e479SAndreas Jaekel continue; 1042e9a5e479SAndreas Jaekel perror("getting queue properties failed"); 1043e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 1044e9a5e479SAndreas Jaekel } 1045e9a5e479SAndreas Jaekel 10464ca7dd5eSAndreas Jaekel memcpy(gs.zev_queue_name.zev_name, 10474ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_name, ZEV_MAX_QUEUE_NAME_LEN); 10484ca7dd5eSAndreas Jaekel gs.zev_queue_name.zev_namelen = 10494ca7dd5eSAndreas Jaekel gql.zev_queue_name[i].zev_namelen; 1050e9a5e479SAndreas Jaekel 1051e9a5e479SAndreas Jaekel if (ioctl(fd, ZEV_IOC_GET_QUEUE_STATISTICS, &gs)) { 1052e9a5e479SAndreas Jaekel if (errno == ENOENT) 1053e9a5e479SAndreas Jaekel continue; 1054e9a5e479SAndreas Jaekel perror("getting statistics data failed"); 1055e9a5e479SAndreas Jaekel return (EXIT_FAILURE); 1056e9a5e479SAndreas Jaekel } 1057e9a5e479SAndreas Jaekel 1058e9a5e479SAndreas Jaekel printf("%-40s %-10" PRIu64 " %-10" PRIu64 " %-6" PRIu64 1059e9a5e479SAndreas Jaekel " %-3s %-3s\n", 1060e9a5e479SAndreas Jaekel name, 1061e9a5e479SAndreas Jaekel gs.zev_statistics.zev_queue_len, 1062e9a5e479SAndreas Jaekel gqp.zev_max_queue_len, 1063e9a5e479SAndreas Jaekel gqp.zev_poll_wakeup_threshold, 1064e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_PERSISTENT ? "yes" : "no", 1065e9a5e479SAndreas Jaekel gqp.zev_flags & ZEV_FL_BLOCK_WHILE_QUEUE_FULL ? 1066e9a5e479SAndreas Jaekel "yes" : "no"); 1067e9a5e479SAndreas Jaekel } 1068e9a5e479SAndreas Jaekel 1069e9a5e479SAndreas Jaekel return (0); 1070e9a5e479SAndreas Jaekel } 1071e9a5e479SAndreas Jaekel 1072b9710123SAndreas Jaekel static int 1073b9710123SAndreas Jaekel zev_checksum(int dev_fd, char *filename) 1074b9710123SAndreas Jaekel { 1075b9710123SAndreas Jaekel int fd; 1076b9710123SAndreas Jaekel offset_t off; 1077b9710123SAndreas Jaekel offset_t data; 1078b9710123SAndreas Jaekel zev_sig_t *sig; 1079b9710123SAndreas Jaekel char *buf; 1080b9710123SAndreas Jaekel zev_ioctl_get_signatures_t *gs; 1081b9710123SAndreas Jaekel int i; 1082b9710123SAndreas Jaekel char sigval[(SHA1_DIGEST_LENGTH * 2) + 1]; 1083b9710123SAndreas Jaekel int buf_size; 1084b9710123SAndreas Jaekel 1085b9710123SAndreas Jaekel /* control struct, one lv1 signature and up to 256 lv0 signatures */ 1086b9710123SAndreas Jaekel buf_size = (1 + 256) * sizeof(zev_sig_t); 1087b9710123SAndreas Jaekel buf = malloc(sizeof(zev_ioctl_get_signatures_t) + buf_size); 1088b9710123SAndreas Jaekel if (!buf) { 1089b9710123SAndreas Jaekel perror("can't allocate checksum buffer"); 1090b9710123SAndreas Jaekel return (EXIT_FAILURE); 1091b9710123SAndreas Jaekel } 1092b9710123SAndreas Jaekel 1093b9710123SAndreas Jaekel fd = open(filename, O_RDONLY); 1094b9710123SAndreas Jaekel if (fd < 0) { 1095b9710123SAndreas Jaekel perror("can't open file"); 1096b9710123SAndreas Jaekel return (EXIT_FAILURE); 1097b9710123SAndreas Jaekel } 1098b9710123SAndreas Jaekel 1099b9710123SAndreas Jaekel gs = (zev_ioctl_get_signatures_t *)buf; 1100b9710123SAndreas Jaekel gs->zev_fd = fd; 1101b9710123SAndreas Jaekel gs->zev_bufsize = buf_size; 1102b9710123SAndreas Jaekel 1103b9710123SAndreas Jaekel off = 0; 1104b9710123SAndreas Jaekel data = 0; 1105b9710123SAndreas Jaekel while (1) { 1106b9710123SAndreas Jaekel errno = 0; 1107b9710123SAndreas Jaekel data = llseek(fd, off, SEEK_DATA); 1108b9710123SAndreas Jaekel if (data < 0) { 1109b9710123SAndreas Jaekel if (errno == ENXIO) /* no more data */ 1110b9710123SAndreas Jaekel break; 1111b9710123SAndreas Jaekel perror("llseek failed"); 1112b9710123SAndreas Jaekel goto err; 1113b9710123SAndreas Jaekel } 1114b9710123SAndreas Jaekel data = P2ALIGN(data, ZEV_L1_SIZE); 1115b9710123SAndreas Jaekel off = data + ZEV_L1_SIZE; 1116b9710123SAndreas Jaekel 1117b9710123SAndreas Jaekel gs->zev_offset = data; 1118b9710123SAndreas Jaekel gs->zev_len = ZEV_L1_SIZE; 1119b9710123SAndreas Jaekel 1120b9710123SAndreas Jaekel if (ioctl(dev_fd, ZEV_IOC_GET_FILE_SIGNATURES, gs)) { 1121b9710123SAndreas Jaekel perror("ioctl to get signatures failed"); 1122b9710123SAndreas Jaekel goto err; 1123b9710123SAndreas Jaekel } 1124b9710123SAndreas Jaekel 1125b9710123SAndreas Jaekel for (i=0; i<gs->zev_signature_cnt; i++) { 1126b9710123SAndreas Jaekel sig = (zev_sig_t *)ZEV_SIGNATURES(gs); 1127b9710123SAndreas Jaekel sig += i; 1128b9710123SAndreas Jaekel sig2hex_direct(sig->value, sigval); 1129b9710123SAndreas Jaekel printf("level %d, offset %llu, value %s\n", 1130b9710123SAndreas Jaekel sig->level, sig->block_offset, sigval); 1131b9710123SAndreas Jaekel } 1132b9710123SAndreas Jaekel } 1133b9710123SAndreas Jaekel 1134b9710123SAndreas Jaekel free(buf); 1135b9710123SAndreas Jaekel close(fd); 1136b9710123SAndreas Jaekel return 0; 1137b9710123SAndreas Jaekel err: 1138b9710123SAndreas Jaekel free(buf); 1139b9710123SAndreas Jaekel close(fd); 1140b9710123SAndreas Jaekel return (EXIT_FAILURE); 1141b9710123SAndreas Jaekel } 1142b9710123SAndreas Jaekel 11432bb8e5e2SAndreas Jaekel int 11442bb8e5e2SAndreas Jaekel main(int argc, char **argv) 11452bb8e5e2SAndreas Jaekel { 11462bb8e5e2SAndreas Jaekel int fd; 11472bb8e5e2SAndreas Jaekel int c; 11482bb8e5e2SAndreas Jaekel extern char *optarg; 11494ca7dd5eSAndreas Jaekel int create_tmp_queue = 1; 11504ca7dd5eSAndreas Jaekel char buf[MAXPATHLEN]; 11512bb8e5e2SAndreas Jaekel 11522bb8e5e2SAndreas Jaekel /* open device */ 11532bb8e5e2SAndreas Jaekel fd = open(zev_device, O_RDONLY); 11542bb8e5e2SAndreas Jaekel if (fd < 0) { 11552bb8e5e2SAndreas Jaekel perror("opening zev device failed"); 11562bb8e5e2SAndreas Jaekel return EXIT_FAILURE; 11572bb8e5e2SAndreas Jaekel } 11584ca7dd5eSAndreas Jaekel while ((c = getopt(argc, argv, 1159*d65b2fffSAndreas Jaekel "gvspc:d:Dlk:L:q:Qt:m:M:a:A:r:P:b:B:h?")) != -1){ 11602bb8e5e2SAndreas Jaekel switch(c) { 1161*d65b2fffSAndreas Jaekel case 'g': 1162*d65b2fffSAndreas Jaekel grep_friendly++; 1163*d65b2fffSAndreas Jaekel verbose++; 1164*d65b2fffSAndreas Jaekel break; 11655e286361SAndreas Jaekel case 'v': 11665e286361SAndreas Jaekel verbose++; 11675e286361SAndreas Jaekel break; 11682bb8e5e2SAndreas Jaekel case 's': 1169e9a5e479SAndreas Jaekel return zev_statistics(fd); 11702bb8e5e2SAndreas Jaekel case 'p': 11714ca7dd5eSAndreas Jaekel return zev_poll_events(fd, create_tmp_queue); 1172b9710123SAndreas Jaekel case 'c': 1173b9710123SAndreas Jaekel return zev_checksum(fd, optarg); 1174e9a5e479SAndreas Jaekel case 'D': 1175e9a5e479SAndreas Jaekel return zev_debug_info(fd); 11762bb8e5e2SAndreas Jaekel case 'd': 1177e9a5e479SAndreas Jaekel close(fd); 11782bb8e5e2SAndreas Jaekel zev_device = optarg; 1179e9a5e479SAndreas Jaekel fd = open(zev_device, O_RDONLY); 1180e9a5e479SAndreas Jaekel if (fd < 0) { 1181e9a5e479SAndreas Jaekel perror("opening zev device failed"); 1182e9a5e479SAndreas Jaekel return EXIT_FAILURE; 1183e9a5e479SAndreas Jaekel } 11844ca7dd5eSAndreas Jaekel create_tmp_queue = 0; 11854ca7dd5eSAndreas Jaekel break; 11864ca7dd5eSAndreas Jaekel case 'q': 11874ca7dd5eSAndreas Jaekel snprintf(buf, sizeof(buf), 11884ca7dd5eSAndreas Jaekel "/devices/pseudo/zev@0:%s", optarg); 11894ca7dd5eSAndreas Jaekel close(fd); 11904ca7dd5eSAndreas Jaekel zev_device = buf; 11914ca7dd5eSAndreas Jaekel fd = open(zev_device, O_RDONLY); 11924ca7dd5eSAndreas Jaekel if (fd < 0) { 11934ca7dd5eSAndreas Jaekel perror("opening zev device failed"); 11944ca7dd5eSAndreas Jaekel return EXIT_FAILURE; 11954ca7dd5eSAndreas Jaekel } 11964ca7dd5eSAndreas Jaekel create_tmp_queue = 0; 11972bb8e5e2SAndreas Jaekel break; 1198e9a5e479SAndreas Jaekel case 'l': 1199e9a5e479SAndreas Jaekel return zev_list_queues(fd); 1200e9a5e479SAndreas Jaekel case 'Q': 1201e9a5e479SAndreas Jaekel return zev_set_global_max_queue_len(fd, optarg); 12024ca7dd5eSAndreas Jaekel case 'L': 1203e9a5e479SAndreas Jaekel return zev_set_max_queue_len(fd, optarg, argv[optind]); 1204205a9bc9SAndreas Jaekel case 't': 1205e9a5e479SAndreas Jaekel return zev_set_poll_wakeup_queue_len(fd, optarg, 1206e9a5e479SAndreas Jaekel argv[optind]); 12072bb8e5e2SAndreas Jaekel case 'm': 12082bb8e5e2SAndreas Jaekel return zev_mute_pool(fd, optarg); 12092bb8e5e2SAndreas Jaekel case 'M': 12102bb8e5e2SAndreas Jaekel return zev_unmute_pool(fd, optarg); 121101c2c787SAndreas Jaekel case 'k': 121201c2c787SAndreas Jaekel return zev_mark(fd, optarg); 1213e9a5e479SAndreas Jaekel case 'a': 12144ca7dd5eSAndreas Jaekel return zev_add_queue(fd, optarg, 0); 12154ca7dd5eSAndreas Jaekel case 'A': 12164ca7dd5eSAndreas Jaekel return zev_add_queue(fd, optarg, 1); 1217e9a5e479SAndreas Jaekel case 'r': 1218e9a5e479SAndreas Jaekel return zev_remove_queue(fd, optarg); 1219e9a5e479SAndreas Jaekel case 'b': 1220e9a5e479SAndreas Jaekel return zev_queue_blocking(fd, optarg, 0); 1221e9a5e479SAndreas Jaekel case 'B': 1222e9a5e479SAndreas Jaekel return zev_queue_blocking(fd, optarg, 1); 1223e9a5e479SAndreas Jaekel case 'P': 1224e9a5e479SAndreas Jaekel return zev_queue_properties(fd, optarg); 12252bb8e5e2SAndreas Jaekel case 'h': 12262bb8e5e2SAndreas Jaekel case '?': 12272bb8e5e2SAndreas Jaekel default: 12282bb8e5e2SAndreas Jaekel usage(argv[0]); 12292bb8e5e2SAndreas Jaekel } 12302bb8e5e2SAndreas Jaekel } 12312bb8e5e2SAndreas Jaekel usage(argv[0]); 12322bb8e5e2SAndreas Jaekel close(fd); 1233e9a5e479SAndreas Jaekel return EXIT_FAILURE; 12342bb8e5e2SAndreas Jaekel } 12352bb8e5e2SAndreas Jaekel 1236