#ifndef __ZEV_H__ #define __ZEV_H__ #include #include #include #include #ifdef _KERNEL #include #include #include #include #include #endif #define ZEV_MAX_QUEUE_NAME_LEN 40 #define ZEV_MAX_QUEUES 63 #define ZEV_CONTROL_DEVICE_NAME "ctrl" /* global limit, no queue may grow larger than this. */ #define ZEV_MAX_QUEUE_LEN (1 * 1024 * 1024 * 1024) /* Don't wake up poll()ing processes for every single message. */ #define ZEV_DEFAULT_POLL_WAKEUP_QUEUE_LEN 8192 #define ZEV_MAX_POLL_WAKEUP_QUEUE_LEN 65536 #define ZEVIOC ('z' << 8) #define ZEV_IOC_GET_GLOBAL_STATISTICS (ZEVIOC | 1) /* get global stats */ #define ZEV_IOC_MUTE_POOL (ZEVIOC | 2) /* no events for pool */ #define ZEV_IOC_UNMUTE_POOL (ZEVIOC | 3) /* send pool events */ #define ZEV_IOC_SET_MAX_QUEUE_LEN (ZEVIOC | 4) /* when to block ops */ #define ZEV_IOC_SET_POLL_WAKEUP_QUEUE_LEN (ZEVIOC | 5) /* poll throttle */ #define ZEV_IOC_MARK (ZEVIOC | 6) /* add mark to queue */ #define ZEV_IOC_GET_GEN (ZEVIOC | 7) /* get generation no. */ #define ZEV_IOC_ADD_QUEUE (ZEVIOC | 8) /* create new queue */ #define ZEV_IOC_REMOVE_QUEUE (ZEVIOC | 9) /* delete queue */ #define ZEV_IOC_GET_QUEUE_PROPERTIES (ZEVIOC | 10) /* get properties */ #define ZEV_IOC_SET_QUEUE_PROPERTIES (ZEVIOC | 11) /* set properties */ #define ZEV_IOC_GET_QUEUE_STATISTICS (ZEVIOC | 12) /* get queue stats */ #define ZEV_IOC_GET_DEBUG_INFO (ZEVIOC | 13) /* get internal info */ #define ZEV_IOC_GET_QUEUE_LIST (ZEVIOC | 14) /* get queue list */ #define ZEV_IOC_GET_FILE_SIGNATURES (ZEVIOC | 15) /* get beaver sigs */ #define ZEV_OP_MIN 1 #define ZEV_OP_ERROR 1 #define ZEV_OP_MARK 2 #define ZEV_OP_ZFS_MOUNT 3 #define ZEV_OP_ZFS_UMOUNT 4 #define ZEV_OP_ZVOL_WRITE 5 #define ZEV_OP_ZVOL_TRUNCATE 6 #define ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE 7 #define ZEV_OP_ZNODE_CREATE 8 #define ZEV_OP_ZNODE_MKDIR 9 #define ZEV_OP_ZNODE_MAKE_XATTR_DIR 10 #define ZEV_OP_ZNODE_REMOVE 11 #define ZEV_OP_ZNODE_RMDIR 12 #define ZEV_OP_ZNODE_LINK 13 #define ZEV_OP_ZNODE_SYMLINK 14 #define ZEV_OP_ZNODE_RENAME 15 #define ZEV_OP_ZNODE_WRITE 16 #define ZEV_OP_ZNODE_TRUNCATE 17 #define ZEV_OP_ZNODE_SETATTR 18 #define ZEV_OP_ZNODE_ACL 19 #define ZEV_OP_MAX 19 /* zev event flags */ #define ZEV_FL_XATTR 0x0001 /* zev queue flags */ #define ZEV_FL_BLOCK_WHILE_QUEUE_FULL 0x0001 #define ZEV_FL_PERSISTENT 0x0002 #define ZEV_FL_INITIALLY_EMPTY 0x0004 /* checksum block sizes */ #define ZEV_L0_SIZE 4096 #define ZEV_L1_SIZE (256 * ZEV_L0_SIZE) /* zfs event records (as they are represented through the character device) */ #pragma pack(1) typedef struct zev_inode_info_t { uint64_t ino; uint64_t gen; uint64_t mtime; uint64_t ctime; uint64_t size; uint64_t mode; uint64_t links; uint32_t type; uint32_t flags; } zev_inode_info_t; #define ZEV_ERRSTR(rec) ((char *)(rec + 1)) #define ZEV_DATASET(rec) ((char *)(rec + 1)) #define ZEV_MOUNTPOINT(rec) (((char *)(rec + 1)) + rec->dataset_len + 1) #define ZEV_NAME(rec) ((char *)(rec + 1)) #define ZEV_SRCNAME(rec) ((char *)(rec + 1)) #define ZEV_DSTNAME(rec) (((char *)(rec + 1)) + rec->srcname_len + 1) #define ZEV_LINK(rec) (((char *)(rec + 1)) + rec->name_len + 1) #define ZEV_PAYLOAD(rec) ((char *)(rec + 1)) #define ZEV_SIGNATURES(rec) ((char *)(rec + 1)) #define ZEV_COMMON_FIELDS \ uint32_t record_len; \ uint32_t op; \ uint64_t op_time; \ uint64_t guid typedef struct zev_sig_t { uint16_t level; uint16_t padding1; uint32_t padding2; uint64_t block_offset; uint8_t value[SHA1_DIGEST_LENGTH]; /* 20 bytes -> no padding */ } zev_sig_t; typedef struct zev_header_t { ZEV_COMMON_FIELDS; } zev_header_t; typedef struct zev_error_t { ZEV_COMMON_FIELDS; uint32_t failed_op; uint32_t errstr_len; /* error string follows */ } zev_error_t; typedef struct zev_mark_t { ZEV_COMMON_FIELDS; uint64_t mark_id; uint32_t payload_len; uint32_t padding; /* payload follows */ } zev_mark_t; typedef struct zev_zfs_mount_t { ZEV_COMMON_FIELDS; zev_inode_info_t root; uint32_t remount; uint32_t dataset_len; uint32_t mountpoint_len; uint32_t padding; /* dataset follows */ /* mountpoint follows */ } zev_zfs_mount_t; typedef struct zev_zfs_umount_t { ZEV_COMMON_FIELDS; zev_inode_info_t covered; } zev_zfs_umount_t; typedef struct zev_zvol_truncate_t { ZEV_COMMON_FIELDS; uint64_t txg; uint64_t offset; uint64_t length; uint32_t dataset_len; uint32_t padding; /* dataset follows */ } zev_zvol_truncate_t; typedef struct zev_zvol_write_t { ZEV_COMMON_FIELDS; uint64_t txg; uint64_t offset; uint64_t length; uint32_t dataset_len; uint32_t padding; /* dataset follows */ } zev_zvol_write_t; typedef struct zev_znode_close_after_update_t { ZEV_COMMON_FIELDS; zev_inode_info_t file; } zev_znode_close_after_update_t; typedef struct zev_znode_create_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t file; zev_inode_info_t parent; zev_sig_t signature; uint32_t name_len; uint32_t padding; /* name follows */ } zev_znode_create_t; typedef struct zev_znode_create_t zev_znode_mkdir_t; typedef struct zev_znode_create_t zev_znode_make_xattr_dir_t; typedef struct zev_znode_remove_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t file; zev_inode_info_t parent; uint32_t name_len; uint32_t padding; /* name follows */ } zev_znode_remove_t; typedef struct zev_znode_remove_t zev_znode_rmdir_t; typedef struct zev_znode_link_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t parent; zev_inode_info_t file; uint32_t name_len; uint32_t padding; /* new_name follows */ } zev_znode_link_t; typedef struct zev_znode_symlink_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t parent; zev_inode_info_t file; zev_sig_t signature; uint32_t name_len; uint32_t link_len; /* name follows */ /* link follows */ } zev_znode_symlink_t; typedef struct zev_znode_rename_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t srcdir; zev_inode_info_t dstdir; zev_inode_info_t file; uint32_t srcname_len; uint32_t dstname_len; /* srcname follows */ /* dstname follows */ } zev_znode_rename_t; typedef struct zev_znode_write_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t file; uint64_t offset; uint64_t length; uint64_t signature_cnt; /* signatures follow */ } zev_znode_write_t; typedef struct zev_znode_truncate_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t file; uint64_t offset; uint64_t length; uint64_t signature_cnt; /* signatures follow */ } zev_znode_truncate_t; typedef struct zev_znode_setattr_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t file; } zev_znode_setattr_t; typedef struct zev_znode_acl_t { ZEV_COMMON_FIELDS; uint64_t txg; zev_inode_info_t file; } zev_znode_acl_t; /* convenience helper definition */ typedef union { zev_header_t header; zev_error_t error; zev_mark_t mark; union { zev_zfs_mount_t mount; zev_zfs_umount_t umount; } zfs; union { zev_zvol_truncate_t truncate; zev_zvol_write_t write; } zvol; union { zev_znode_close_after_update_t close; zev_znode_create_t create; zev_znode_mkdir_t mkdir; zev_znode_make_xattr_dir_t mkxattrdir; zev_znode_remove_t remove; zev_znode_rmdir_t rmdir; zev_znode_link_t link; zev_znode_symlink_t symlink; zev_znode_rename_t rename; zev_znode_write_t write; zev_znode_truncate_t truncate; zev_znode_setattr_t setattr; zev_znode_acl_t acl; } znode; } zev_event_t; typedef struct zev_statistics_t { uint64_t zev_queue_len; uint64_t zev_bytes_read; uint64_t zev_bytes_discarded; /* runtime settings */ uint64_t zev_max_queue_len; /* counters */ uint64_t zev_cnt_total_events; uint64_t zev_cnt_discarded_events; uint64_t zev_cnt_errors; uint64_t zev_cnt_marks; /* zfsvfs ops */ uint64_t zev_cnt_zfs_mount; uint64_t zev_cnt_zfs_umount; /* zvol ops */ uint64_t zev_cnt_zvol_write; uint64_t zev_cnt_zvol_truncate; /* znode ops */ uint64_t zev_cnt_znode_close_after_update; uint64_t zev_cnt_znode_create; uint64_t zev_cnt_znode_remove; uint64_t zev_cnt_znode_link; uint64_t zev_cnt_znode_symlink; uint64_t zev_cnt_znode_rename; uint64_t zev_cnt_znode_write; uint64_t zev_cnt_znode_truncate; uint64_t zev_cnt_znode_setattr; uint64_t zev_cnt_znode_acl; } zev_statistics_t; typedef struct zev_queue_name { uint64_t zev_namelen; char zev_name[ZEV_MAX_QUEUE_NAME_LEN]; } zev_queue_name_t; typedef struct zev_ioctl_poolarg { uint64_t zev_poolname_len; char zev_poolname[MAXPATHLEN]; } zev_ioctl_poolarg_t; typedef struct zev_ioctl_mark { uint64_t zev_mark_id; uint64_t zev_guid; uint32_t zev_payload_len; uint32_t padding; /* payload follows */ } zev_ioctl_mark_t; typedef struct zev_ioctl_get_gen { /* input */ uint64_t inode; uint32_t fd; /* open fd to any object on the same fs */ /* noput */ uint32_t padding; /* output */ uint64_t generation; uint64_t crtime; uint64_t guid; char dataset[MAXPATHLEN]; } zev_ioctl_get_gen_t; typedef struct zev_ioctl_set_queue_properties { uint64_t zev_max_queue_len; uint64_t zev_poll_wakeup_threshold; uint16_t zev_flags; uint16_t padding1; uint32_t padding2; zev_queue_name_t zev_queue_name; } zev_ioctl_set_queue_properties_t; typedef struct zev_ioctl_set_queue_properties zev_ioctl_get_queue_properties_t; typedef struct zev_ioctl_add_queue { uint64_t zev_max_queue_len; uint32_t padding; uint16_t zev_flags; uint16_t zev_namelen; char zev_name[ZEV_MAX_QUEUE_NAME_LEN]; } zev_ioctl_add_queue_t; typedef struct zev_ioctl_remove_queue { zev_queue_name_t zev_queue_name; } zev_ioctl_remove_queue_t; typedef struct zev_ioctl_get_queue_statistics { zev_queue_name_t zev_queue_name; zev_statistics_t zev_statistics; } zev_ioctl_get_queue_statistics_t; typedef struct zev_ioctl_debug_info { uint64_t zev_memory_allocated; uint64_t zev_chksum_cache_size; uint64_t zev_chksum_cache_hits; uint64_t zev_chksum_cache_misses; } zev_ioctl_debug_info_t; typedef struct zev_ioctl_get_queue_list { uint64_t zev_n_queues; zev_queue_name_t zev_queue_name[ZEV_MAX_QUEUES]; } zev_ioctl_get_queue_list_t; typedef struct zev_ioctl_get_signatures { /* in */ uint64_t zev_offset; uint64_t zev_len; uint32_t zev_fd; uint32_t zev_bufsize; /* out */ uint64_t zev_signature_cnt; /* up to zev_bufsize bytes of checksums will be written here */ } zev_ioctl_get_signatures_t; #pragma pack() #ifdef _KERNEL extern uint64_t zev_memory_allocated; extern uint64_t zev_memory_freed; #define ZEV_MEM_ADD(memsize) \ do { \ int64_t tmp_delta = (int64_t)(memsize); \ atomic_add_64(&zev_memory_allocated, tmp_delta); \ } while(0) #define ZEV_MEM_SUB(memsize) \ do { \ int64_t tmp_delta = (int64_t)(memsize); \ atomic_add_64(&zev_memory_freed, tmp_delta); \ } while(0) void *zev_alloc(ssize_t sz); void *zev_zalloc(ssize_t sz); void zev_free(void *ptr, ssize_t sz); typedef struct zev_msg_t { struct zev_msg_t *next; struct zev_msg_t *prev; uint64_t seq; uint16_t size; uint16_t read; /* data follows */ } zev_msg_t; void zev_queue_error(int op, char *fmt, ...); void zev_queue_message(int op, zev_msg_t *msg); void zev_queue_message_nvlist(int op, nvlist_t *nvl); int zev_skip_pool(objset_t *os); #endif #endif /* __ZEV_H__ */