1 #include <sys/zfs_znode.h> 2 #include <sys/fs/zfs.h> 3 #include <sys/fs/zev.h> 4 #include <sys/zfs_events.h> 5 6 #define ZEV_VERIFY(exp) \ 7 if (0 != (exp)) { \ 8 zev_queue_error(op, "operation failed: " \ 9 #exp " (line %d in %s)", \ 10 __LINE__, __FILE__); \ 11 if (nvl) { \ 12 nvlist_free(nvl); \ 13 } \ 14 return; \ 15 } 16 17 #define ZEV_ADD_INODE_INFO(znode, name) \ 18 do { \ 19 uint64_t mtime[2], ctime[2]; \ 20 sa_bulk_attr_t bulk[2]; \ 21 int count = 0; \ 22 timestruc_t mtime_s, ctime_s; \ 23 SA_ADD_BULK_ATTR(bulk, count, \ 24 SA_ZPL_MTIME(znode->z_zfsvfs), \ 25 NULL, &mtime, 16); \ 26 SA_ADD_BULK_ATTR(bulk, count, \ 27 SA_ZPL_CTIME(znode->z_zfsvfs), \ 28 NULL, &ctime, 16); \ 29 if ((sa_bulk_lookup(znode->z_sa_hdl, bulk, count)) != 0) { \ 30 zev_queue_error(op, "znode write: " \ 31 "mtime/ctime unavailable"); \ 32 /* continue anyway, use fake data */ \ 33 mtime_s.tv_sec = ctime_s.tv_sec = 0; \ 34 } \ 35 ZFS_TIME_DECODE(&mtime_s, mtime); \ 36 ZFS_TIME_DECODE(&ctime_s, ctime); \ 37 ZEV_VERIFY(nvlist_add_uint64(nvl, name ".ino", \ 38 znode->z_id)); \ 39 ZEV_VERIFY(nvlist_add_uint64(nvl, name ".gen", \ 40 znode->z_gen)); \ 41 ZEV_VERIFY(nvlist_add_uint64(nvl, name ".mtime", \ 42 mtime_s.tv_sec)); \ 43 ZEV_VERIFY(nvlist_add_uint64(nvl, name ".ctime", \ 44 ctime_s.tv_sec)); \ 45 ZEV_VERIFY(nvlist_add_uint64(nvl, name ".size", \ 46 znode->z_size)); \ 47 ZEV_VERIFY(nvlist_add_uint64(nvl, name ".mode", \ 48 znode->z_mode & MODEMASK)); \ 49 ZEV_VERIFY(nvlist_add_int32(nvl, name ".type", \ 50 znode->z_vnode->v_type)); \ 51 ZEV_VERIFY(nvlist_add_uint64(nvl, name ".links", \ 52 znode->z_links)); \ 53 } while(0); \ 54 55 void 56 zev_zfs_mount_cb(vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount) 57 { 58 nvlist_t *nvl = NULL; 59 int op = ZEV_OP_ZFS_MOUNT; 60 char mountpoint[MAXPATHLEN+1]; 61 62 zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data; 63 if (zev_skip_pool(zfsvfs->z_os)) 64 return; 65 /* expensive, but we don't have many mount ops. */ 66 if ((vnodetopath(NULL, mpt, mountpoint, sizeof(mountpoint), 67 kcred)) != 0) { 68 zev_queue_error(ZEV_OP_ZFS_MOUNT, 69 "unresolvable mountpoint, dataset=%s", dataset); 70 return; 71 } 72 73 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 74 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 75 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 76 zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 77 ZEV_VERIFY(nvlist_add_string(nvl, "dataset", dataset)); 78 ZEV_VERIFY(nvlist_add_string(nvl, "mountpoint", dataset)); 79 ZEV_VERIFY(nvlist_add_uint64(nvl, "root.ino", zfsvfs->z_root)); 80 ZEV_VERIFY(nvlist_add_boolean_value(nvl, "remount", remount)); 81 zev_queue_message(op, nvl); 82 nvlist_free(nvl); 83 } 84 85 void 86 zev_zfs_umount_cb(vfs_t *vfs) 87 { 88 nvlist_t *nvl = NULL; 89 int op = ZEV_OP_ZFS_UMOUNT; 90 91 zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data; 92 if (zev_skip_pool(zfsvfs->z_os)) 93 return; 94 95 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 96 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 97 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 98 zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 99 zev_queue_message(op, nvl); 100 nvlist_free(nvl); 101 } 102 103 void 104 zev_zvol_truncate_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len) 105 { 106 nvlist_t *nvl = NULL; 107 int op = ZEV_OP_ZVOL_TRUNCATE; 108 109 if (zev_skip_pool(os)) 110 return; 111 112 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 113 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 114 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 115 os->os_dsl_dataset->ds_phys->ds_guid)); 116 ZEV_VERIFY(nvlist_add_string(nvl, "dataset", dataset)); 117 ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off)); 118 ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len)); 119 zev_queue_message(op, nvl); 120 nvlist_free(nvl); 121 } 122 123 void 124 zev_zvol_write_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len) 125 { 126 nvlist_t *nvl = NULL; 127 int op = ZEV_OP_ZVOL_WRITE; 128 129 if (zev_skip_pool(os)) 130 return; 131 132 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 133 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 134 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 135 os->os_dsl_dataset->ds_phys->ds_guid)); 136 ZEV_VERIFY(nvlist_add_string(nvl, "dataset", dataset)); 137 ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off)); 138 ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len)); 139 zev_queue_message(op, nvl); 140 nvlist_free(nvl); 141 } 142 143 void 144 zev_znode_close_after_update_cb(znode_t *zp) 145 { 146 nvlist_t *nvl = NULL; 147 int op = ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE; 148 149 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 150 return; 151 152 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 153 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 154 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 155 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 156 ZEV_ADD_INODE_INFO(zp, "file"); 157 zev_queue_message(op, nvl); 158 nvlist_free(nvl); 159 } 160 161 void 162 zev_znode_create_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype) 163 { 164 nvlist_t *nvl = NULL; 165 int op = ZEV_OP_ZNODE_CREATE; 166 167 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 168 return; 169 170 int type = (int)txtype; 171 switch(type) { 172 case TX_CREATE: 173 case TX_CREATE_ACL: 174 case TX_CREATE_ATTR: 175 case TX_CREATE_ACL_ATTR: 176 op = ZEV_OP_ZNODE_CREATE; 177 break; 178 case TX_MKDIR: 179 case TX_MKDIR_ACL: 180 case TX_MKDIR_ATTR: 181 case TX_MKDIR_ACL_ATTR: 182 op = ZEV_OP_ZNODE_MKDIR; 183 break; 184 case TX_MKXATTR: 185 op = ZEV_OP_ZNODE_MAKE_XATTR_DIR; 186 break; 187 default: 188 zev_queue_error(ZEV_OP_ZNODE_CREATE, 189 "ERROR: ZNODE_CREATE: unknown txtype %d " 190 "(dir_inode=%d:%d inode=%d:%d name='%s')\n", 191 type, 192 dzp->z_gen, 193 dzp->z_id, 194 zp->z_gen, 195 zp->z_id, 196 name); 197 return; 198 } 199 200 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 201 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 202 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 203 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 204 ZEV_ADD_INODE_INFO(dzp, "parent"); 205 ZEV_ADD_INODE_INFO(zp, "file"); 206 ZEV_VERIFY(nvlist_add_string(nvl, "file.name", name)); 207 zev_queue_message(op, nvl); 208 nvlist_free(nvl); 209 } 210 211 void 212 zev_znode_remove_cb(znode_t *dzp, char *name, uint64_t txtype) 213 { 214 nvlist_t *nvl = NULL; 215 int op = ZEV_OP_ZNODE_REMOVE; 216 217 if (zev_skip_pool(dzp->z_zfsvfs->z_os)) 218 return; 219 220 int type = (int)txtype; 221 switch(type) { 222 case TX_REMOVE: 223 op = ZEV_OP_ZNODE_REMOVE; 224 break; 225 case TX_RMDIR: 226 op = ZEV_OP_ZNODE_RMDIR; 227 break; 228 default: 229 zev_queue_error(ZEV_OP_ZNODE_REMOVE, 230 "ERROR: ZNODE_REMOVE: unknown txtype %d " 231 "(dir_inode=%d:%d name='%s')\n", 232 type, 233 dzp->z_gen, 234 dzp->z_id, 235 name); 236 return; 237 } 238 239 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 240 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 241 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 242 dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 243 ZEV_ADD_INODE_INFO(dzp, "parent"); 244 ZEV_VERIFY(nvlist_add_string(nvl, "file.name", name)); 245 zev_queue_message(op, nvl); 246 nvlist_free(nvl); 247 } 248 249 void 250 zev_znode_link_cb(znode_t *dzp, znode_t *zp, char *name) 251 { 252 nvlist_t *nvl = NULL; 253 int op = ZEV_OP_ZNODE_LINK; 254 255 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 256 return; 257 258 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 259 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 260 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 261 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 262 ZEV_ADD_INODE_INFO(dzp, "parent"); 263 ZEV_ADD_INODE_INFO(zp, "file"); 264 ZEV_VERIFY(nvlist_add_string(nvl, "file.new_name", name)); 265 zev_queue_message(op, nvl); 266 nvlist_free(nvl); 267 } 268 269 void 270 zev_znode_symlink_cb(znode_t *dzp, znode_t *zp, char *name, char *link) 271 { 272 nvlist_t *nvl = NULL; 273 int op = ZEV_OP_ZNODE_SYMLINK; 274 275 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 276 return; 277 278 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 279 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 280 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 281 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 282 ZEV_ADD_INODE_INFO(dzp, "parent"); 283 ZEV_ADD_INODE_INFO(zp, "file"); 284 ZEV_VERIFY(nvlist_add_string(nvl, "file.name", name)); 285 ZEV_VERIFY(nvlist_add_string(nvl, "file.link", link)); 286 zev_queue_message(op, nvl); 287 nvlist_free(nvl); 288 } 289 290 void 291 zev_znode_rename_cb(znode_t *sdzp, char *sname, znode_t *tdzp, 292 char *tname, znode_t *szp) 293 { 294 nvlist_t *nvl = NULL; 295 int op = ZEV_OP_ZNODE_RENAME; 296 297 if (zev_skip_pool(szp->z_zfsvfs->z_os)) 298 return; 299 300 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 301 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 302 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 303 szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 304 ZEV_ADD_INODE_INFO(sdzp, "srcdir"); 305 ZEV_ADD_INODE_INFO(tdzp, "targetdir"); 306 ZEV_ADD_INODE_INFO(szp, "file"); 307 ZEV_VERIFY(nvlist_add_string(nvl, "file.src_name", sname)); 308 ZEV_VERIFY(nvlist_add_string(nvl, "file.target_name", tname)); 309 zev_queue_message(op, nvl); 310 } 311 312 void 313 zev_znode_write_cb(znode_t *zp, uint64_t off, uint64_t len) 314 { 315 nvlist_t *nvl = NULL; 316 int op = ZEV_OP_ZNODE_WRITE; 317 318 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 319 return; 320 321 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 322 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 323 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 324 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 325 ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off)); 326 ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len)); 327 ZEV_ADD_INODE_INFO(zp, "file"); 328 zev_queue_message(op, nvl); 329 nvlist_free(nvl); 330 } 331 332 void 333 zev_znode_truncate_cb(znode_t *zp, uint64_t off, uint64_t len) 334 { 335 nvlist_t *nvl = NULL; 336 int op = ZEV_OP_ZNODE_TRUNCATE; 337 338 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 339 return; 340 341 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 342 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 343 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 344 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 345 ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off)); 346 ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len)); 347 ZEV_ADD_INODE_INFO(zp, "file"); 348 zev_queue_message(op, nvl); 349 nvlist_free(nvl); 350 } 351 352 void 353 zev_znode_setattr_cb(znode_t *zp) 354 { 355 nvlist_t *nvl = NULL; 356 int op = ZEV_OP_ZNODE_SETATTR; 357 358 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 359 return; 360 361 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 362 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 363 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 364 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 365 ZEV_ADD_INODE_INFO(zp, "file"); 366 zev_queue_message(op, nvl); 367 nvlist_free(nvl); 368 } 369 370 void 371 zev_znode_acl_cb(znode_t *zp) 372 { 373 nvlist_t *nvl = NULL; 374 int op = ZEV_OP_ZNODE_ACL; 375 376 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 377 return; 378 379 ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)); 380 ZEV_VERIFY(nvlist_add_byte(nvl, "op", op)); 381 ZEV_VERIFY(nvlist_add_uint64(nvl, "guid", 382 zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid)); 383 ZEV_ADD_INODE_INFO(zp, "file"); 384 zev_queue_message(op, nvl); 385 nvlist_free(nvl); 386 } 387 388 rz_zev_callbacks_t zev_callbacks = { 389 /* zfsvfs events */ 390 .rz_zev_zfs_mount = zev_zfs_mount_cb, 391 .rz_zev_zfs_umount = zev_zfs_umount_cb, 392 393 /* zvol zil events */ 394 .rz_zev_zvol_truncate = zev_zvol_truncate_cb, 395 .rz_zev_zvol_write = zev_zvol_write_cb, 396 397 /* znode zil events */ 398 .rz_zev_znode_close_after_update = zev_znode_close_after_update_cb, 399 .rz_zev_znode_create = zev_znode_create_cb, 400 .rz_zev_znode_remove = zev_znode_remove_cb, 401 .rz_zev_znode_link = zev_znode_link_cb, 402 .rz_zev_znode_symlink = zev_znode_symlink_cb, 403 .rz_zev_znode_rename = zev_znode_rename_cb, 404 .rz_zev_znode_write = zev_znode_write_cb, 405 .rz_zev_znode_truncate = zev_znode_truncate_cb, 406 .rz_zev_znode_setattr = zev_znode_setattr_cb, 407 .rz_zev_znode_acl = zev_znode_acl_cb, 408 }; 409 410