1 #include <sys/mode.h> 2 #include <sys/zfs_znode.h> 3 #include <sys/fs/zfs.h> 4 #include <sys/fs/zev.h> 5 #include <sys/zfs_events.h> 6 7 #define ZEV_FILL_INODE_INFO(name, znode) \ 8 do { \ 9 uint64_t mtime[2], ctime[2]; \ 10 sa_bulk_attr_t bulk[2]; \ 11 int count = 0; \ 12 timestruc_t mtime_s, ctime_s; \ 13 SA_ADD_BULK_ATTR(bulk, count, \ 14 SA_ZPL_MTIME(znode->z_zfsvfs), \ 15 NULL, &mtime, 16); \ 16 SA_ADD_BULK_ATTR(bulk, count, \ 17 SA_ZPL_CTIME(znode->z_zfsvfs), \ 18 NULL, &ctime, 16); \ 19 if ((sa_bulk_lookup(znode->z_sa_hdl, bulk, count)) != 0) { \ 20 zev_queue_error(op, "znode write: " \ 21 "mtime/ctime unavailable"); \ 22 /* continue anyway, use fake data */ \ 23 mtime_s.tv_sec = ctime_s.tv_sec = 0; \ 24 } \ 25 ZFS_TIME_DECODE(&mtime_s, mtime); \ 26 ZFS_TIME_DECODE(&ctime_s, ctime); \ 27 rec->name.ino = znode->z_id; \ 28 rec->name.gen = znode->z_gen; \ 29 rec->name.mtime = mtime_s.tv_sec; \ 30 rec->name.ctime = ctime_s.tv_sec; \ 31 rec->name.size = znode->z_size; \ 32 rec->name.type = znode->z_vnode->v_type; \ 33 rec->name.mode = \ 34 znode->z_mode | VTTOIF(znode->z_vnode->v_type); \ 35 rec->name.links = znode->z_links; \ 36 rec->name.flags = znode->z_pflags & ZFS_XATTR ? \ 37 ZEV_FL_XATTR : 0; \ 38 } while(0) 39 40 void 41 zev_zfs_mount_cb(vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount) 42 { 43 int op = ZEV_OP_ZFS_MOUNT; 44 char mountpoint[MAXPATHLEN+1]; 45 int mountpoint_len; 46 int dataset_len; 47 zev_zfs_mount_t *rec; 48 zev_msg_t *msg = NULL; 49 int msg_size; 50 znode_t *zp_root; 51 52 zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data; 53 if (dsl_dataset_is_snapshot(zfsvfs->z_os->os_dsl_dataset)) 54 return; 55 if (zev_skip_pool(zfsvfs->z_os)) 56 return; 57 /* expensive, but we don't have many mount ops. */ 58 if ((vnodetopath(NULL, mpt, mountpoint, sizeof(mountpoint), 59 kcred)) != 0) { 60 zev_queue_error(op, "unresolvable mountpoint, dataset=%s", 61 dataset); 62 return; 63 } 64 if (zfs_zget(zfsvfs, zfsvfs->z_root, &zp_root) != 0) { 65 zev_queue_error(op, "can't get root znode, dataset=%s", 66 dataset); 67 return; 68 } 69 70 dataset_len = strlen(dataset); 71 mountpoint_len = strlen(mountpoint); 72 msg_size = sizeof(*rec) + dataset_len + 1 + mountpoint_len + 1; 73 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 74 msg->size = msg_size; 75 rec = (zev_zfs_mount_t *)(msg + 1); 76 rec->record_len = msg_size; 77 rec->op = op; 78 rec->op_time = ddi_get_time(); 79 rec->guid = zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 80 rec->remount = remount; 81 rec->dataset_len = dataset_len; 82 rec->mountpoint_len = mountpoint_len; 83 ZEV_FILL_INODE_INFO(root, zp_root); 84 VN_RELE(ZTOV(zp_root)); 85 (void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1); 86 (void) memcpy(ZEV_MOUNTPOINT(rec), mountpoint, mountpoint_len + 1); 87 zev_queue_message(op, msg); 88 } 89 90 void 91 zev_zfs_umount_cb(vfs_t *vfs) 92 { 93 int op = ZEV_OP_ZFS_UMOUNT; 94 zev_zfs_umount_t *rec; 95 zev_msg_t *msg = NULL; 96 int msg_size; 97 98 zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data; 99 if (dsl_dataset_is_snapshot(zfsvfs->z_os->os_dsl_dataset)) 100 return; 101 if (zev_skip_pool(zfsvfs->z_os)) 102 return; 103 104 msg_size = sizeof(*rec); 105 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 106 msg->size = msg_size; 107 rec = (zev_zfs_umount_t *)(msg + 1); 108 rec->record_len = msg_size; 109 rec->op = op; 110 rec->op_time = ddi_get_time(); 111 rec->guid = zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 112 zev_queue_message(op, msg); 113 } 114 115 void 116 zev_zvol_truncate_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len) 117 { 118 int op = ZEV_OP_ZVOL_TRUNCATE; 119 zev_zvol_truncate_t *rec; 120 zev_msg_t *msg = NULL; 121 int msg_size; 122 int dataset_len; 123 124 if (zev_skip_pool(os)) 125 return; 126 127 dataset_len = strlen(dataset); 128 msg_size = sizeof(*rec) + dataset_len + 1; 129 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 130 msg->size = msg_size; 131 rec = (zev_zvol_truncate_t *)(msg + 1); 132 rec->record_len = msg_size; 133 rec->op = op; 134 rec->op_time = ddi_get_time(); 135 rec->guid = os->os_dsl_dataset->ds_phys->ds_guid; 136 rec->offset = off; 137 rec->length = len; 138 rec->dataset_len = dataset_len; 139 (void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1); 140 zev_queue_message(op, msg); 141 } 142 143 void 144 zev_zvol_write_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len) 145 { 146 int op = ZEV_OP_ZVOL_WRITE; 147 zev_zvol_write_t *rec; 148 zev_msg_t *msg = NULL; 149 int msg_size; 150 int dataset_len; 151 152 if (zev_skip_pool(os)) 153 return; 154 155 dataset_len = strlen(dataset); 156 msg_size = sizeof(*rec) + dataset_len + 1; 157 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 158 msg->size = msg_size; 159 rec = (zev_zvol_write_t *)(msg + 1); 160 rec->record_len = msg_size; 161 rec->op = op; 162 rec->op_time = ddi_get_time(); 163 rec->guid = os->os_dsl_dataset->ds_phys->ds_guid; 164 rec->offset = off; 165 rec->length = len; 166 rec->dataset_len = dataset_len; 167 (void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1); 168 zev_queue_message(op, msg); 169 } 170 171 void 172 zev_znode_close_after_update_cb(znode_t *zp) 173 { 174 int op = ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE; 175 zev_znode_close_after_update_t *rec; 176 zev_msg_t *msg = NULL; 177 int msg_size; 178 179 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 180 return; 181 182 msg_size = sizeof(*rec); 183 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 184 msg->size = msg_size; 185 rec = (zev_znode_close_after_update_t *)(msg + 1); 186 rec->record_len = msg_size; 187 rec->op = op; 188 rec->op_time = ddi_get_time(); 189 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 190 ZEV_FILL_INODE_INFO(file, zp); 191 zev_queue_message(op, msg); 192 } 193 194 void 195 zev_znode_create_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype) 196 { 197 int op = ZEV_OP_ZNODE_CREATE; 198 zev_znode_create_t *rec; 199 zev_msg_t *msg = NULL; 200 int msg_size; 201 int name_len; 202 203 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 204 return; 205 206 int type = (int)txtype; 207 switch(type) { 208 case TX_CREATE: 209 case TX_CREATE_ACL: 210 case TX_CREATE_ATTR: 211 case TX_CREATE_ACL_ATTR: 212 op = ZEV_OP_ZNODE_CREATE; 213 break; 214 case TX_MKDIR: 215 case TX_MKDIR_ACL: 216 case TX_MKDIR_ATTR: 217 case TX_MKDIR_ACL_ATTR: 218 op = ZEV_OP_ZNODE_MKDIR; 219 break; 220 case TX_MKXATTR: 221 op = ZEV_OP_ZNODE_MAKE_XATTR_DIR; 222 break; 223 default: 224 zev_queue_error(ZEV_OP_ZNODE_CREATE, 225 "ERROR: ZNODE_CREATE: unknown txtype %d " 226 "(dir_inode=%d:%d inode=%d:%d name='%s')\n", 227 type, 228 dzp->z_gen, 229 dzp->z_id, 230 zp->z_gen, 231 zp->z_id, 232 name); 233 return; 234 } 235 236 /* all three types use the same struct, so this works for all types: */ 237 name_len = strlen(name); 238 msg_size = sizeof(*rec) + name_len + 1; 239 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 240 msg->size = msg_size; 241 rec = (zev_znode_create_t *)(msg + 1); 242 rec->record_len = msg_size; 243 rec->op = op; 244 rec->op_time = ddi_get_time(); 245 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 246 ZEV_FILL_INODE_INFO(parent, dzp); 247 ZEV_FILL_INODE_INFO(file, zp); 248 rec->name_len = name_len; 249 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 250 zev_queue_message(op, msg); 251 } 252 253 void 254 zev_znode_remove_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype) 255 { 256 int op = ZEV_OP_ZNODE_REMOVE; 257 zev_znode_remove_t *rec; 258 zev_msg_t *msg = NULL; 259 int msg_size; 260 int name_len; 261 262 if (zev_skip_pool(dzp->z_zfsvfs->z_os)) 263 return; 264 265 int type = (int)txtype; 266 switch(type) { 267 case TX_REMOVE: 268 op = ZEV_OP_ZNODE_REMOVE; 269 break; 270 case TX_RMDIR: 271 op = ZEV_OP_ZNODE_RMDIR; 272 break; 273 default: 274 zev_queue_error(ZEV_OP_ZNODE_REMOVE, 275 "ERROR: ZNODE_REMOVE: unknown txtype %d " 276 "(dir_inode=%d:%d name='%s')\n", 277 type, 278 dzp->z_gen, 279 dzp->z_id, 280 name); 281 return; 282 } 283 284 /* both types use the same struct, so this works for all types: */ 285 name_len = strlen(name); 286 msg_size = sizeof(*rec) + name_len + 1; 287 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 288 msg->size = msg_size; 289 rec = (zev_znode_remove_t *)(msg + 1); 290 rec->record_len = msg_size; 291 rec->op = op; 292 rec->op_time = ddi_get_time(); 293 rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 294 ZEV_FILL_INODE_INFO(file, zp); 295 ZEV_FILL_INODE_INFO(parent, dzp); 296 rec->name_len = name_len; 297 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 298 zev_queue_message(op, msg); 299 } 300 301 void 302 zev_znode_link_cb(znode_t *dzp, znode_t *zp, char *name) 303 { 304 int op = ZEV_OP_ZNODE_LINK; 305 zev_znode_link_t *rec; 306 zev_msg_t *msg = NULL; 307 int msg_size; 308 int name_len; 309 310 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 311 return; 312 313 name_len = strlen(name); 314 msg_size = sizeof(*rec) + name_len + 1; 315 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 316 msg->size = msg_size; 317 rec = (zev_znode_link_t *)(msg + 1); 318 rec->record_len = msg_size; 319 rec->op = op; 320 rec->op_time = ddi_get_time(); 321 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 322 ZEV_FILL_INODE_INFO(parent, dzp); 323 ZEV_FILL_INODE_INFO(file, zp); 324 rec->name_len = name_len; 325 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 326 zev_queue_message(op, msg); 327 } 328 329 void 330 zev_znode_symlink_cb(znode_t *dzp, znode_t *zp, char *name, char *link) 331 { 332 int op = ZEV_OP_ZNODE_SYMLINK; 333 zev_znode_symlink_t *rec; 334 zev_msg_t *msg = NULL; 335 int msg_size; 336 int name_len; 337 int link_len; 338 339 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 340 return; 341 342 name_len = strlen(name); 343 link_len = strlen(link); 344 msg_size = sizeof(*rec) + name_len + 1 + link_len + 1; 345 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 346 msg->size = msg_size; 347 rec = (zev_znode_symlink_t *)(msg + 1); 348 rec->record_len = msg_size; 349 rec->op = op; 350 rec->op_time = ddi_get_time(); 351 rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 352 ZEV_FILL_INODE_INFO(parent, dzp); 353 ZEV_FILL_INODE_INFO(file, zp); 354 rec->name_len = name_len; 355 rec->link_len = link_len; 356 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 357 (void) memcpy(ZEV_LINK(rec), link, link_len + 1); 358 zev_queue_message(op, msg); 359 } 360 361 void 362 zev_znode_rename_cb(znode_t *sdzp, char *sname, znode_t *tdzp, 363 char *tname, znode_t *szp) 364 { 365 int op = ZEV_OP_ZNODE_RENAME; 366 zev_znode_rename_t *rec; 367 zev_msg_t *msg = NULL; 368 int msg_size; 369 int srcname_len; 370 int dstname_len; 371 372 if (zev_skip_pool(szp->z_zfsvfs->z_os)) 373 return; 374 375 srcname_len = strlen(sname); 376 dstname_len = strlen(tname); 377 msg_size = sizeof(*rec) + srcname_len + 1 + dstname_len + 1; 378 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 379 msg->size = msg_size; 380 rec = (zev_znode_rename_t *)(msg + 1); 381 rec->record_len = msg_size; 382 rec->op = op; 383 rec->op_time = ddi_get_time(); 384 rec->guid = szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 385 ZEV_FILL_INODE_INFO(srcdir, sdzp); 386 ZEV_FILL_INODE_INFO(dstdir, tdzp); 387 ZEV_FILL_INODE_INFO(file, szp); 388 rec->srcname_len = srcname_len; 389 rec->dstname_len = dstname_len; 390 (void) memcpy(ZEV_SRCNAME(rec), sname, srcname_len + 1); 391 (void) memcpy(ZEV_DSTNAME(rec), tname, dstname_len + 1); 392 zev_queue_message(op, msg); 393 } 394 395 void 396 zev_znode_write_cb(znode_t *zp, uint64_t off, uint64_t len) 397 { 398 int op = ZEV_OP_ZNODE_WRITE; 399 zev_znode_write_t *rec; 400 zev_msg_t *msg = NULL; 401 int msg_size; 402 403 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 404 return; 405 406 msg_size = sizeof(*rec); 407 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 408 msg->size = msg_size; 409 rec = (zev_znode_write_t *)(msg + 1); 410 rec->record_len = msg_size; 411 rec->op = op; 412 rec->op_time = ddi_get_time(); 413 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 414 ZEV_FILL_INODE_INFO(file, zp); 415 rec->offset = off; 416 rec->length = len; 417 zev_queue_message(op, msg); 418 } 419 420 void 421 zev_znode_truncate_cb(znode_t *zp, uint64_t off, uint64_t len) 422 { 423 int op = ZEV_OP_ZNODE_TRUNCATE; 424 zev_znode_truncate_t *rec; 425 zev_msg_t *msg = NULL; 426 int msg_size; 427 428 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 429 return; 430 431 msg_size = sizeof(*rec); 432 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 433 msg->size = msg_size; 434 rec = (zev_znode_truncate_t *)(msg + 1); 435 rec->record_len = msg_size; 436 rec->op = op; 437 rec->op_time = ddi_get_time(); 438 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 439 ZEV_FILL_INODE_INFO(file, zp); 440 rec->offset = off; 441 rec->length = len; 442 zev_queue_message(op, msg); 443 } 444 445 void 446 zev_znode_setattr_cb(znode_t *zp) 447 { 448 int op = ZEV_OP_ZNODE_SETATTR; 449 zev_znode_setattr_t *rec; 450 zev_msg_t *msg = NULL; 451 int msg_size; 452 453 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 454 return; 455 456 msg_size = sizeof(*rec); 457 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 458 msg->size = msg_size; 459 rec = (zev_znode_setattr_t *)(msg + 1); 460 rec->record_len = msg_size; 461 rec->op = op; 462 rec->op_time = ddi_get_time(); 463 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 464 ZEV_FILL_INODE_INFO(file, zp); 465 zev_queue_message(op, msg); 466 } 467 468 void 469 zev_znode_acl_cb(znode_t *zp) 470 { 471 int op = ZEV_OP_ZNODE_ACL; 472 zev_znode_acl_t *rec; 473 zev_msg_t *msg = NULL; 474 int msg_size; 475 476 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 477 return; 478 479 msg_size = sizeof(*rec); 480 msg = ZEV_ALLOC(sizeof(*msg) + msg_size); 481 msg->size = msg_size; 482 rec = (zev_znode_acl_t *)(msg + 1); 483 rec->record_len = msg_size; 484 rec->op = op; 485 rec->op_time = ddi_get_time(); 486 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 487 ZEV_FILL_INODE_INFO(file, zp); 488 zev_queue_message(op, msg); 489 } 490 491 rz_zev_callbacks_t zev_callbacks = { 492 /* zfsvfs events */ 493 .rz_zev_zfs_mount = zev_zfs_mount_cb, 494 .rz_zev_zfs_umount = zev_zfs_umount_cb, 495 496 /* zvol zil events */ 497 .rz_zev_zvol_truncate = zev_zvol_truncate_cb, 498 .rz_zev_zvol_write = zev_zvol_write_cb, 499 500 /* znode zil events */ 501 .rz_zev_znode_close_after_update = zev_znode_close_after_update_cb, 502 .rz_zev_znode_create = zev_znode_create_cb, 503 .rz_zev_znode_remove = zev_znode_remove_cb, 504 .rz_zev_znode_link = zev_znode_link_cb, 505 .rz_zev_znode_symlink = zev_znode_symlink_cb, 506 .rz_zev_znode_rename = zev_znode_rename_cb, 507 .rz_zev_znode_write = zev_znode_write_cb, 508 .rz_zev_znode_truncate = zev_znode_truncate_cb, 509 .rz_zev_znode_setattr = zev_znode_setattr_cb, 510 .rz_zev_znode_acl = zev_znode_acl_cb, 511 }; 512 513