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