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_create_checksum(rec, zp); 268 zev_queue_message(op, msg); 269 } 270 271 void 272 zev_znode_remove_cb(znode_t *dzp, 273 znode_t *zp, 274 dmu_tx_t *tx, 275 char *name, 276 uint64_t txtype) 277 { 278 int op = ZEV_OP_ZNODE_REMOVE; 279 zev_znode_remove_t *rec; 280 zev_msg_t *msg = NULL; 281 int msg_size; 282 int name_len; 283 284 if (zev_skip_pool(dzp->z_zfsvfs->z_os)) 285 return; 286 287 int type = (int)txtype; 288 switch(type) { 289 case TX_REMOVE: 290 op = ZEV_OP_ZNODE_REMOVE; 291 break; 292 case TX_RMDIR: 293 op = ZEV_OP_ZNODE_RMDIR; 294 break; 295 default: 296 zev_queue_error(ZEV_OP_ZNODE_REMOVE, 297 "ERROR: ZNODE_REMOVE: unknown txtype %d " 298 "(dir_inode=%d:%d name='%s')\n", 299 type, 300 dzp->z_gen, 301 dzp->z_id, 302 name); 303 return; 304 } 305 306 /* both types use the same struct, so this works for all types: */ 307 name_len = strlen(name); 308 msg_size = sizeof(*rec) + name_len + 1; 309 msg = zev_alloc(sizeof(*msg) + msg_size); 310 msg->size = msg_size; 311 rec = (zev_znode_remove_t *)(msg + 1); 312 rec->record_len = msg_size; 313 rec->op = op; 314 rec->op_time = ddi_get_time(); 315 rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 316 rec->txg = tx->tx_txg; 317 ZEV_FILL_INODE_INFO(file, zp); 318 ZEV_FILL_INODE_INFO(parent, dzp); 319 rec->name_len = name_len; 320 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 321 zev_queue_message(op, msg); 322 } 323 324 void 325 zev_znode_link_cb(znode_t *dzp, znode_t *zp, dmu_tx_t *tx, char *name) 326 { 327 int op = ZEV_OP_ZNODE_LINK; 328 zev_znode_link_t *rec; 329 zev_msg_t *msg = NULL; 330 int msg_size; 331 int name_len; 332 333 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 334 return; 335 336 name_len = strlen(name); 337 msg_size = sizeof(*rec) + name_len + 1; 338 msg = zev_alloc(sizeof(*msg) + msg_size); 339 msg->size = msg_size; 340 rec = (zev_znode_link_t *)(msg + 1); 341 rec->record_len = msg_size; 342 rec->op = op; 343 rec->op_time = ddi_get_time(); 344 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 345 rec->txg = tx->tx_txg; 346 ZEV_FILL_INODE_INFO(parent, dzp); 347 ZEV_FILL_INODE_INFO(file, zp); 348 rec->name_len = name_len; 349 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 350 zev_queue_message(op, msg); 351 } 352 353 void 354 zev_znode_symlink_cb(znode_t *dzp, 355 znode_t *zp, 356 dmu_tx_t *tx, 357 char *name, 358 char *link) 359 { 360 int op = ZEV_OP_ZNODE_SYMLINK; 361 zev_znode_symlink_t *rec; 362 zev_msg_t *msg = NULL; 363 int msg_size; 364 int name_len; 365 int link_len; 366 367 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 368 return; 369 370 name_len = strlen(name); 371 link_len = strlen(link); 372 msg_size = sizeof(*rec) + name_len + 1 + link_len + 1; 373 msg = zev_alloc(sizeof(*msg) + msg_size); 374 msg->size = msg_size; 375 rec = (zev_znode_symlink_t *)(msg + 1); 376 rec->record_len = msg_size; 377 rec->op = op; 378 rec->op_time = ddi_get_time(); 379 rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 380 rec->txg = tx->tx_txg; 381 ZEV_FILL_INODE_INFO(parent, dzp); 382 ZEV_FILL_INODE_INFO(file, zp); 383 rec->name_len = name_len; 384 rec->link_len = link_len; 385 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 386 (void) memcpy(ZEV_LINK(rec), link, link_len + 1); 387 zev_symlink_checksum(rec, link); 388 zev_queue_message(op, msg); 389 } 390 391 void 392 zev_znode_rename_cb(znode_t *sdzp, 393 char *sname, 394 znode_t *tdzp, 395 char *tname, 396 znode_t *szp, 397 dmu_tx_t *tx) 398 { 399 int op = ZEV_OP_ZNODE_RENAME; 400 zev_znode_rename_t *rec; 401 zev_msg_t *msg = NULL; 402 int msg_size; 403 int srcname_len; 404 int dstname_len; 405 406 if (zev_skip_pool(szp->z_zfsvfs->z_os)) 407 return; 408 409 srcname_len = strlen(sname); 410 dstname_len = strlen(tname); 411 msg_size = sizeof(*rec) + srcname_len + 1 + dstname_len + 1; 412 msg = zev_alloc(sizeof(*msg) + msg_size); 413 msg->size = msg_size; 414 rec = (zev_znode_rename_t *)(msg + 1); 415 rec->record_len = msg_size; 416 rec->op = op; 417 rec->op_time = ddi_get_time(); 418 rec->guid = szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 419 rec->txg = tx->tx_txg; 420 ZEV_FILL_INODE_INFO(srcdir, sdzp); 421 ZEV_FILL_INODE_INFO(dstdir, tdzp); 422 ZEV_FILL_INODE_INFO(file, szp); 423 rec->srcname_len = srcname_len; 424 rec->dstname_len = dstname_len; 425 (void) memcpy(ZEV_SRCNAME(rec), sname, srcname_len + 1); 426 (void) memcpy(ZEV_DSTNAME(rec), tname, dstname_len + 1); 427 zev_queue_message(op, msg); 428 } 429 430 void 431 zev_znode_write_cb(znode_t *zp, dmu_tx_t *tx, uint64_t off, uint64_t len) 432 { 433 int op = ZEV_OP_ZNODE_WRITE; 434 zev_znode_write_t *rec; 435 zev_msg_t *msg = NULL; 436 int msg_size; 437 zev_sig_t *sig_buf; 438 uint64_t sig_buf_len; 439 uint64_t sig_len; 440 uint64_t sig_cnt; 441 int ret; 442 443 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 444 return; 445 446 ret = zev_get_checksums(&sig_buf, &sig_buf_len, &sig_cnt, 0, 447 zp, off, len, zev_write); 448 if (ret) { 449 zev_queue_error(op, 450 "ERROR: ZNODE_WRITE: can't get checksum (inode=%d:%d)\n", 451 zp->z_gen, 452 zp->z_id); 453 return; 454 } 455 sig_len = sig_cnt * sizeof(zev_sig_t); 456 457 msg_size = sizeof(*rec) + sig_len; 458 msg = zev_alloc(sizeof(*msg) + msg_size); 459 msg->size = msg_size; 460 rec = (zev_znode_write_t *)(msg + 1); 461 rec->record_len = msg_size; 462 rec->op = op; 463 rec->op_time = ddi_get_time(); 464 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 465 rec->txg = tx->tx_txg; 466 ZEV_FILL_INODE_INFO(file, zp); 467 rec->offset = off; 468 rec->length = len; 469 rec->signature_cnt = sig_cnt; 470 if (sig_cnt && sig_buf) 471 memcpy(ZEV_SIGNATURES(rec), sig_buf, sig_len); 472 if (sig_buf) 473 zev_free(sig_buf, sig_buf_len); 474 zev_queue_message(op, msg); 475 } 476 477 void 478 zev_znode_truncate_cb(znode_t *zp, dmu_tx_t *tx, uint64_t off, uint64_t len) 479 { 480 int op = ZEV_OP_ZNODE_TRUNCATE; 481 zev_znode_truncate_t *rec; 482 zev_msg_t *msg = NULL; 483 int msg_size; 484 zev_sig_t *sig_buf; 485 uint64_t sig_buf_len; 486 uint64_t sig_len; 487 uint64_t sig_cnt; 488 int ret; 489 490 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 491 return; 492 493 ret = zev_get_checksums(&sig_buf, &sig_buf_len, &sig_cnt, 0, 494 zp, off, len, zev_truncate); 495 if (ret) { 496 zev_queue_error(op, 497 "ERROR: ZNODE_TRUNCATE: can't get checksum (inode=%d:%d)\n", 498 zp->z_gen, 499 zp->z_id); 500 return; 501 } 502 sig_len = sig_cnt * sizeof(zev_sig_t); 503 504 msg_size = sizeof(*rec) + sig_len; 505 msg = zev_alloc(sizeof(*msg) + msg_size); 506 msg->size = msg_size; 507 rec = (zev_znode_truncate_t *)(msg + 1); 508 rec->record_len = msg_size; 509 rec->op = op; 510 rec->op_time = ddi_get_time(); 511 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 512 rec->txg = tx->tx_txg; 513 ZEV_FILL_INODE_INFO(file, zp); 514 rec->offset = off; 515 rec->length = len; 516 rec->signature_cnt = sig_cnt; 517 if (sig_cnt && sig_buf) 518 memcpy(ZEV_SIGNATURES(rec), sig_buf, sig_len); 519 if (sig_buf) 520 zev_free(sig_buf, sig_buf_len); 521 zev_queue_message(op, msg); 522 } 523 524 void 525 zev_znode_setattr_cb(znode_t *zp, dmu_tx_t *tx) 526 { 527 int op = ZEV_OP_ZNODE_SETATTR; 528 zev_znode_setattr_t *rec; 529 zev_msg_t *msg = NULL; 530 int msg_size; 531 532 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 533 return; 534 535 msg_size = sizeof(*rec); 536 msg = zev_alloc(sizeof(*msg) + msg_size); 537 msg->size = msg_size; 538 rec = (zev_znode_setattr_t *)(msg + 1); 539 rec->record_len = msg_size; 540 rec->op = op; 541 rec->op_time = ddi_get_time(); 542 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 543 rec->txg = tx->tx_txg; 544 ZEV_FILL_INODE_INFO(file, zp); 545 zev_queue_message(op, msg); 546 } 547 548 void 549 zev_znode_acl_cb(znode_t *zp, dmu_tx_t *tx) 550 { 551 int op = ZEV_OP_ZNODE_ACL; 552 zev_znode_acl_t *rec; 553 zev_msg_t *msg = NULL; 554 int msg_size; 555 556 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 557 return; 558 559 msg_size = sizeof(*rec); 560 msg = zev_alloc(sizeof(*msg) + msg_size); 561 msg->size = msg_size; 562 rec = (zev_znode_acl_t *)(msg + 1); 563 rec->record_len = msg_size; 564 rec->op = op; 565 rec->op_time = ddi_get_time(); 566 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 567 rec->txg = tx->tx_txg; 568 ZEV_FILL_INODE_INFO(file, zp); 569 zev_queue_message(op, msg); 570 } 571 572 rz_zev_callbacks_t zev_callbacks = { 573 /* zfsvfs events */ 574 .rz_zev_zfs_mount = zev_zfs_mount_cb, 575 .rz_zev_zfs_umount = zev_zfs_umount_cb, 576 577 /* zvol zil events */ 578 .rz_zev_zvol_truncate = zev_zvol_truncate_cb, 579 .rz_zev_zvol_write = zev_zvol_write_cb, 580 581 /* znode zil events */ 582 .rz_zev_znode_close_after_update = zev_znode_close_after_update_cb, 583 .rz_zev_znode_create = zev_znode_create_cb, 584 .rz_zev_znode_remove = zev_znode_remove_cb, 585 .rz_zev_znode_link = zev_znode_link_cb, 586 .rz_zev_znode_symlink = zev_znode_symlink_cb, 587 .rz_zev_znode_rename = zev_znode_rename_cb, 588 .rz_zev_znode_write = zev_znode_write_cb, 589 .rz_zev_znode_truncate = zev_znode_truncate_cb, 590 .rz_zev_znode_setattr = zev_znode_setattr_cb, 591 .rz_zev_znode_acl = zev_znode_acl_cb, 592 }; 593 594