1 #include <sys/modctl.h> 2 #include <sys/ddi.h> 3 #include <sys/sunddi.h> 4 #include <sys/conf.h> 5 #include <sys/devops.h> 6 #include <sys/stat.h> 7 #include <sys/fs/zev.h> 8 #include <sys/zev_callbacks.h> 9 10 typedef struct zev_state { 11 kmutex_t mutex; 12 dev_info_t *dip; 13 boolean_t busy; 14 } zev_state_t; 15 16 static void *statep; 17 struct pollhead zev_pollhead; 18 19 kmutex_t zev_mutex; 20 kcondvar_t zev_condvar; 21 krwlock_t zev_pool_list_rwlock; 22 static zev_statistics_t zev_statistics; 23 static ldi_handle_t zev_zfs_lh; 24 static ldi_ident_t zev_ldi_id; 25 static boolean_t zev_busy; 26 27 /* 28 * The longest potential message is from zev_zfs_mount() and 29 * contains the mountpoint, which might be close to MAXPATHLEN bytes long. 30 * 31 * Another candidate is zev_znode_rename_cb() and contains three inode 32 * numbers and two filenames of up to MAXNAMELEN bytes each. 33 */ 34 #define ZEV_MAX_MESSAGE_LEN 4096 35 36 /* If the queue size reaches 1GB, stop ZFS ops and block the threads. */ 37 #define ZEV_MAX_QUEUE_LEN (1 * 1024 * 1024 * 1024) 38 39 typedef struct zev_mq { 40 struct zev_mq *next; 41 int used; 42 int sent; 43 char buf[ZEV_MAX_MESSAGE_LEN]; 44 } zev_mq_t; 45 46 static zev_mq_t *zev_mq_head = NULL; 47 static zev_mq_t *zev_mq_tail = NULL; 48 static uint64_t zev_mq_len = 0; 49 50 typedef struct zev_pool_list_entry { 51 struct zev_pool_list_entry *next; 52 char name[MAXPATHLEN]; 53 } zev_pool_list_entry_t; 54 55 static zev_pool_list_entry_t *zev_muted_pools_head = NULL; 56 57 static int 58 zev_ioc_mute_pool(char *poolname) 59 { 60 zev_pool_list_entry_t *pe; 61 rw_enter(&zev_pool_list_rwlock, RW_WRITER); 62 /* pool already muted? */ 63 for (pe=zev_muted_pools_head; pe; pe=pe->next) { 64 if (!strcmp(pe->name, poolname)) { 65 rw_exit(&zev_pool_list_rwlock); 66 return EEXIST; 67 } 68 } 69 pe = kmem_zalloc(sizeof(*pe), KM_SLEEP); 70 if (!pe) { 71 rw_exit(&zev_pool_list_rwlock); 72 return ENOMEM; 73 } 74 strncpy(pe->name, poolname, sizeof(pe->name)); 75 pe->next = zev_muted_pools_head; 76 zev_muted_pools_head = pe; 77 rw_exit(&zev_pool_list_rwlock); 78 return (0); 79 } 80 81 static int 82 zev_ioc_unmute_pool(char *poolname) 83 { 84 zev_pool_list_entry_t *pe, *peprev; 85 rw_enter(&zev_pool_list_rwlock, RW_WRITER); 86 /* pool muted? */ 87 peprev = NULL; 88 for (pe=zev_muted_pools_head; pe; pe=pe->next) { 89 if (!strcmp(pe->name, poolname)) { 90 goto found; 91 } 92 peprev = pe; 93 } 94 rw_exit(&zev_pool_list_rwlock); 95 return ENOENT; 96 found: 97 if (peprev != NULL) { 98 peprev->next = pe->next; 99 } else { 100 zev_muted_pools_head = pe->next; 101 } 102 kmem_free(pe, sizeof(*pe)); 103 rw_exit(&zev_pool_list_rwlock); 104 return (0); 105 } 106 107 int 108 zev_skip_pool(objset_t *os) 109 { 110 zev_pool_list_entry_t *pe; 111 dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool; 112 rw_enter(&zev_pool_list_rwlock, RW_READER); 113 for (pe=zev_muted_pools_head; pe; pe=pe->next) { 114 if (!strcmp(pe->name, dp->dp_spa->spa_name)) { 115 rw_exit(&zev_pool_list_rwlock); 116 return 1; 117 } 118 } 119 rw_exit(&zev_pool_list_rwlock); 120 return 0; 121 } 122 123 void 124 zev_mq_printf(int op, int error, char *fmt, ...) 125 { 126 char buf[ZEV_MAX_MESSAGE_LEN]; 127 int len; 128 va_list ap; 129 zev_mq_t *mq; 130 131 /* render message */ 132 va_start(ap, fmt); 133 len = vsnprintf(buf, sizeof(buf), fmt, ap); 134 va_end(ap); 135 if (len >= sizeof(buf)) { 136 strcpy(buf, "ZEV_ERROR: message too long\n"); 137 len = strlen(buf); 138 error++; 139 } 140 141 /* op type ok? */ 142 if (op < ZEV_OP_MIN || op > ZEV_OP_MAX) { 143 len = snprintf(buf, sizeof(buf), 144 "ZEV_ERROR: unknown op %d\n", op); 145 error++; 146 } 147 148 mutex_enter(&zev_mutex); 149 while (zev_statistics.zev_max_queue_len && 150 zev_statistics.zev_queue_len >= zev_statistics.zev_max_queue_len) { 151 /* queue full. block until it's been shrunk. */ 152 cv_wait(&zev_condvar, &zev_mutex); 153 } 154 155 mq = zev_mq_tail; 156 /* make sure we have enough space in our queue */ 157 if (!mq || ((ZEV_MAX_MESSAGE_LEN - mq->used) < len)) { 158 /* need new mq */ 159 mq = kmem_zalloc(sizeof(*mq), KM_SLEEP); 160 if (zev_mq_tail) 161 zev_mq_tail->next = mq; 162 zev_mq_tail = mq; 163 zev_mq_len++; 164 if (!zev_mq_head) 165 zev_mq_head = mq; 166 } 167 168 /* copy message to queue */ 169 memcpy(mq->buf + mq->used, buf, len); 170 mq->used += len; 171 172 /* update statistics */ 173 zev_statistics.zev_cnt_total_events++; 174 zev_statistics.zev_queue_len += len; 175 if (error) 176 zev_statistics.zev_cnt_errors++; 177 178 switch (op) { 179 case ZEV_OP_ZFS_MOUNT: 180 zev_statistics.zev_cnt_zfs_mount++; 181 break; 182 case ZEV_OP_ZFS_UMOUNT: 183 zev_statistics.zev_cnt_zfs_umount++; 184 break; 185 case ZEV_OP_ZVOL_WRITE: 186 zev_statistics.zev_cnt_zvol_write++; 187 break; 188 case ZEV_OP_ZVOL_TRUNCATE: 189 zev_statistics.zev_cnt_zvol_truncate++; 190 break; 191 case ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE: 192 zev_statistics.zev_cnt_znode_close_after_update++; 193 break; 194 case ZEV_OP_ZNODE_CREATE: 195 zev_statistics.zev_cnt_znode_create++; 196 break; 197 case ZEV_OP_ZNODE_REMOVE: 198 zev_statistics.zev_cnt_znode_remove++; 199 break; 200 case ZEV_OP_ZNODE_LINK: 201 zev_statistics.zev_cnt_znode_link++; 202 break; 203 case ZEV_OP_ZNODE_SYMLINK: 204 zev_statistics.zev_cnt_znode_symlink++; 205 break; 206 case ZEV_OP_ZNODE_RENAME: 207 zev_statistics.zev_cnt_znode_rename++; 208 break; 209 case ZEV_OP_ZNODE_WRITE: 210 zev_statistics.zev_cnt_znode_write++; 211 break; 212 case ZEV_OP_ZNODE_TRUNCATE: 213 zev_statistics.zev_cnt_znode_truncate++; 214 break; 215 case ZEV_OP_ZNODE_SETATTR: 216 zev_statistics.zev_cnt_znode_setattr++; 217 break; 218 case ZEV_OP_ZNODE_ACL: 219 zev_statistics.zev_cnt_znode_acl++; 220 break; 221 } 222 223 mutex_exit(&zev_mutex); 224 225 /* chpoll event, if necessary */ 226 pollwakeup(&zev_pollhead, POLLIN); 227 } 228 229 static int 230 zev_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp) 231 { 232 int instance; 233 zev_state_t *sp; 234 zev_statistics_t zs; 235 zev_ioctl_poolarg_t pa; 236 uint64_t len; 237 238 instance = getminor(dev); 239 if ((sp = ddi_get_soft_state(statep, instance)) == NULL) 240 return (ENXIO); 241 if (ddi_model_convert_from(mode) != DDI_MODEL_NONE) { 242 /* userland has another data model. (most 243 likely 32-bit) -> not supported. */ 244 return (EINVAL); 245 } 246 /* Remember to do 32/64 bit mode adjustments if 247 necessary. See "Writing Device Drivers", 280pp */ 248 switch (cmd) { 249 case ZEV_IOC_GET_STATISTICS: 250 /* ddi_copyout() can take a long time. Better make 251 a copy to be able to release the mutex faster. */ 252 mutex_enter(&zev_mutex); 253 memcpy(&zs, &zev_statistics, sizeof(zs)); 254 mutex_exit(&zev_mutex); 255 if (ddi_copyout(&zs, (void *)arg, sizeof(zs), mode) != 0) 256 return EFAULT; 257 break; 258 case ZEV_IOC_MUTE_POOL: 259 case ZEV_IOC_UNMUTE_POOL: 260 if (ddi_copyin((void *)arg, &pa, sizeof(pa), mode) != 0) 261 return EFAULT; 262 if (pa.zev_poolname_len >=MAXPATHLEN) 263 return EINVAL; 264 pa.zev_poolname[pa.zev_poolname_len] = '\0'; 265 if (cmd == ZEV_IOC_MUTE_POOL) { 266 return zev_ioc_mute_pool(pa.zev_poolname); 267 } else { 268 return zev_ioc_unmute_pool(pa.zev_poolname); 269 } 270 break; 271 case ZEV_IOC_SET_MAX_QUEUE_LEN: 272 if (ddi_copyin((void *)arg, &len, sizeof(len), mode) != 0) 273 return EFAULT; 274 if (len > ZEV_MAX_QUEUE_LEN) 275 return EINVAL; 276 mutex_enter(&zev_mutex); 277 zev_statistics.zev_max_queue_len = len; 278 cv_broadcast(&zev_condvar); 279 mutex_exit(&zev_mutex); 280 break; 281 default: 282 /* generic "ioctl unknown" error */ 283 return (ENOTTY); 284 } 285 return (0); 286 } 287 288 static int 289 zev_chpoll(dev_t dev, short events, int anyyet, 290 short *reventsp, struct pollhead **phpp) 291 { 292 int instance; 293 zev_state_t *sp; 294 short revent = 0; 295 296 instance = getminor(dev); 297 if ((sp = ddi_get_soft_state(statep, instance)) == NULL) 298 return (ENXIO); 299 revent = 0; 300 if ((events & POLLIN)) { 301 mutex_enter(&zev_mutex); 302 if (zev_mq_head && zev_mq_head->used > zev_mq_head->sent) 303 revent |= POLLIN; 304 mutex_exit(&zev_mutex); 305 } 306 if (revent == 0) { 307 if (!anyyet) { 308 *phpp = &zev_pollhead; 309 } 310 } 311 *reventsp = revent; 312 return (0); 313 } 314 315 static int 316 zev_read(dev_t dev, struct uio *uio_p, cred_t *crep_p) 317 { 318 zev_state_t *sp; 319 int instance; 320 offset_t off; 321 int ret = 0; 322 int mq_bytes; 323 zev_mq_t *mq; 324 int len; 325 326 instance = getminor(dev); 327 if ((sp = ddi_get_soft_state(statep, instance)) == NULL) 328 return (ENXIO); 329 off = uio_p->uio_loffset; 330 mutex_enter(&zev_mutex); 331 while (zev_mq_head && uio_p->uio_resid) { 332 mq_bytes = zev_mq_head->used - zev_mq_head->sent; 333 if (mq_bytes <= 0) { 334 mq = zev_mq_head; 335 zev_mq_head = zev_mq_head->next; 336 if (!zev_mq_head) 337 zev_mq_tail = NULL; 338 kmem_free(mq, sizeof(*mq)); 339 continue; 340 } 341 len = min(uio_p->uio_resid, mq_bytes); 342 ret = uiomove(zev_mq_head->buf + zev_mq_head->sent, len, 343 UIO_READ, uio_p); 344 if (ret != 0) 345 break; 346 zev_statistics.zev_bytes_read += len; 347 zev_statistics.zev_queue_len -= len; 348 cv_broadcast(&zev_condvar); 349 zev_mq_head->sent += len; 350 } 351 mutex_exit(&zev_mutex); 352 uio_p->uio_loffset = off; 353 return (ret); 354 } 355 356 static int 357 zev_close(dev_t dev, int flag, int otyp, cred_t *crepd) 358 { 359 zev_state_t *sp; 360 int instance; 361 362 instance = getminor(dev); 363 if ((sp = ddi_get_soft_state(statep, instance)) == NULL) 364 return (ENXIO); 365 if (otyp != OTYP_CHR) 366 return (EINVAL); 367 mutex_enter(&sp->mutex); 368 if (sp->busy != B_TRUE) { 369 mutex_exit(&sp->mutex); 370 return (EINVAL); 371 } 372 sp->busy = B_FALSE; 373 mutex_exit(&sp->mutex); 374 return (0); 375 } 376 377 static int 378 zev_open(dev_t *devp, int flag, int otyp, cred_t *credp) 379 { 380 zev_state_t *sp; 381 int instance; 382 383 instance = getminor(*devp); 384 if ((sp = ddi_get_soft_state(statep, instance)) == NULL) 385 return (ENXIO); 386 if (otyp != OTYP_CHR) 387 return (EINVAL); 388 if (drv_priv(credp) != 0) 389 return (EPERM); 390 mutex_enter(&sp->mutex); 391 if (sp->busy == B_TRUE) { 392 /* XXX: wait for the instance to become available? */ 393 /* XXX: if we wait, the wait should be signal-interruptable. */ 394 mutex_exit(&sp->mutex); 395 return (EBUSY); 396 } 397 sp->busy = B_TRUE; /* can only be opened exclusively */ 398 mutex_exit(&sp->mutex); 399 return (0); 400 } 401 402 static struct cb_ops zev_cb_ops = { 403 zev_open, /* open */ 404 zev_close, /* close */ 405 nodev, /* strategy */ 406 nodev, /* print */ 407 nodev, /* dump */ 408 zev_read, /* read */ 409 nodev, /* write */ 410 zev_ioctl, /* ioctl */ 411 nodev, /* devmap */ 412 nodev, /* mmap */ 413 nodev, /* segmap */ 414 zev_chpoll, /* chpoll */ 415 ddi_prop_op, /* prop_op */ 416 NULL, /* streamtab */ 417 D_MP | D_64BIT, /* cb_flag */ 418 CB_REV, /* cb_rev */ 419 nodev, /* aread */ 420 nodev, /* awrite */ 421 }; 422 423 int 424 zev_install_callbacks(void) 425 { 426 int error = 0; 427 nvlist_t *nv; 428 zfs_cmd_t *zc; 429 char *packed = NULL; 430 size_t len; 431 int unused; 432 433 /* build parameter nvlist */ 434 if ((error = nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP)) != 0) 435 return (error); 436 if ((error = nvlist_add_uint64(nv, "callbacks", 437 (uint64_t)(uintptr_t)&zev_callbacks)) != 0) 438 goto out; 439 if ((error = nvlist_pack(nv, &packed, &len, NV_ENCODE_NATIVE, 440 KM_SLEEP)) != 0) 441 goto out; 442 /* create zfs_cmd_t and fill it in */ 443 zc = kmem_alloc(sizeof(zfs_cmd_t), KM_SLEEP); 444 if (zc == NULL) { 445 error = ENOMEM; 446 goto out; 447 } 448 strcpy(zc->zc_name, "zev"); 449 zc->zc_nvlist_src = (uint64_t)(uintptr_t)packed; 450 zc->zc_nvlist_src_size = len; 451 /* make ioctl() call */ 452 error = ldi_ioctl(zev_zfs_lh, ZFS_IOC_SET_ZEV_CALLBACKS, (uintptr_t)zc, 453 FKIOCTL, kcred, &unused); 454 kmem_free(zc, sizeof(zfs_cmd_t)); 455 out: 456 if (error != 0) 457 cmn_err(CE_WARN, "zev callback install failed (%d)", error); 458 if (packed) 459 kmem_free(packed, len); 460 (void) nvlist_free(nv); 461 return (error); 462 } 463 464 int 465 zev_uninstall_callbacks(void) 466 { 467 int error = 0; 468 zfs_cmd_t *zc; 469 int unused; 470 471 zc = kmem_zalloc(sizeof(zfs_cmd_t), KM_SLEEP); 472 if (zc == NULL) { 473 error = ENOMEM; 474 goto out; 475 } 476 strcpy(zc->zc_name, "zev"); 477 /* make ioctl() call */ 478 error = ldi_ioctl(zev_zfs_lh, ZFS_IOC_UNSET_ZEV_CALLBACKS, 479 (uintptr_t)zc, FKIOCTL, kcred, &unused); 480 kmem_free(zc, sizeof(zfs_cmd_t)); 481 out: 482 if (error != 0) 483 cmn_err(CE_WARN, "zev callback uninstall failed (%d)", error); 484 return (error); 485 } 486 487 static void 488 zev_free_instance(dev_info_t *dip) 489 { 490 int instance; 491 zev_state_t *sp; 492 instance = ddi_get_instance(dip); 493 ddi_remove_minor_node(dip, ddi_get_name(dip)); 494 sp = ddi_get_soft_state(statep, instance); 495 if (sp) { 496 mutex_destroy(&sp->mutex); 497 ddi_soft_state_free(statep, instance); 498 } 499 } 500 501 static int 502 zev_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 503 { 504 int instance; 505 zev_state_t *sp; 506 /* called once per instance with DDI_DETACH, 507 may be called to suspend */ 508 switch (cmd) { 509 case DDI_DETACH: 510 /* instance busy? */ 511 instance = ddi_get_instance(dip); 512 if ((sp = ddi_get_soft_state(statep, instance)) == NULL) 513 return (ENXIO); 514 mutex_enter(&sp->mutex); 515 if (sp->busy == B_TRUE) { 516 mutex_exit(&sp->mutex); 517 return (EBUSY); 518 } 519 mutex_exit(&sp->mutex); 520 /* free resources allocated for this instance */ 521 zev_free_instance(dip); 522 return (DDI_SUCCESS); 523 case DDI_SUSPEND: 524 /* kernel must not suspend zev devices while ZFS is running */ 525 return (DDI_FAILURE); 526 default: 527 return (DDI_FAILURE); 528 } 529 } 530 531 static int 532 zev_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 533 { 534 /* called once per instance with DDI_ATTACH, 535 may be called to resume */ 536 int instance; 537 zev_state_t *sp; 538 switch (cmd) { 539 case DDI_ATTACH: 540 instance = ddi_get_instance(dip); 541 if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS) { 542 return (DDI_FAILURE); 543 } 544 sp = ddi_get_soft_state(statep, instance); 545 ddi_set_driver_private(dip, sp); 546 sp->dip = dip; 547 sp->busy = B_FALSE; 548 mutex_init(&sp->mutex, NULL, MUTEX_DRIVER, NULL); 549 if (ddi_create_minor_node(dip, ddi_get_name(dip), 550 S_IFCHR, instance, DDI_PSEUDO, 0) == DDI_FAILURE) { 551 zev_free_instance(dip); 552 return (DDI_FAILURE); 553 } 554 ddi_report_dev(dip); 555 return (DDI_SUCCESS); 556 case DDI_RESUME: 557 /* suspendeding zev devices should never happen */ 558 return (DDI_SUCCESS); 559 default: 560 return (DDI_FAILURE); 561 } 562 } 563 564 static int 565 zev_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **resultp) 566 { 567 int instance; 568 zev_state_t *sp; 569 switch (infocmd) { 570 case DDI_INFO_DEVT2DEVINFO: 571 /* arg is dev_t */ 572 instance = getminor((dev_t)arg); 573 if ((sp = ddi_get_soft_state(statep, instance)) != NULL) { 574 *resultp = sp->dip; 575 return (DDI_SUCCESS); 576 } 577 *resultp = NULL; 578 return (DDI_FAILURE); 579 case DDI_INFO_DEVT2INSTANCE: 580 /* arg is dev_t */ 581 instance = getminor((dev_t)arg); 582 *resultp = (void *)(uintptr_t)instance; 583 return (DDI_FAILURE); 584 } 585 return (DDI_FAILURE); 586 } 587 588 static struct dev_ops zev_dev_ops = { 589 DEVO_REV, /* driver build revision */ 590 0, /* driver reference count */ 591 zev_getinfo, /* getinfo */ 592 nulldev, /* identify (obsolete) */ 593 nulldev, /* probe (search for devices) */ 594 zev_attach, /* attach */ 595 zev_detach, /* detach */ 596 nodev, /* reset (obsolete, use quiesce) */ 597 &zev_cb_ops, /* character and block device ops */ 598 NULL, /* bus driver ops */ 599 NULL, /* power management, not needed */ 600 ddi_quiesce_not_needed, /* quiesce */ 601 }; 602 603 static struct modldrv zev_modldrv = { 604 &mod_driverops, /* all loadable modules use this */ 605 "zev ZFS event provider, v1.0", /* driver name and version info */ 606 &zev_dev_ops /* ops method pointers */ 607 }; 608 609 static struct modlinkage zev_modlinkage = { 610 MODREV_1, /* fixed value */ 611 { 612 &zev_modldrv, /* driver linkage structure */ 613 NULL /* list terminator */ 614 } 615 }; 616 617 int 618 _init(void) 619 { 620 int error; 621 boolean_t have_ident = B_FALSE; 622 boolean_t have_ldi_id = B_FALSE; 623 boolean_t module_installed = B_FALSE; 624 625 if ((error = ddi_soft_state_init(&statep, sizeof(zev_state_t), 1)) != 0) 626 return (error); 627 zev_busy = B_FALSE; 628 629 mutex_init(&zev_mutex, NULL, MUTEX_DRIVER, NULL); 630 cv_init(&zev_condvar, NULL, CV_DRIVER, NULL); 631 rw_init(&zev_pool_list_rwlock, NULL, RW_DRIVER, NULL); 632 bzero(&zev_statistics, sizeof(zev_statistics)); 633 zev_statistics.zev_max_queue_len = ZEV_MAX_QUEUE_LEN; 634 if (zev_ioc_mute_pool("zg0")) { 635 cmn_err(CE_WARN, "zev: could not init mute list"); 636 goto FAIL; 637 } 638 639 if ((error = ldi_ident_from_mod(&zev_modlinkage, &zev_ldi_id)) != 0) { 640 cmn_err(CE_WARN, "zev: could not get ldi ident"); 641 goto FAIL; 642 } 643 have_ident = B_TRUE; 644 645 if ((error = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred, 646 &zev_zfs_lh, zev_ldi_id)) != 0) { 647 cmn_err(CE_WARN, "zev: could not open zfs device"); 648 goto FAIL; 649 } 650 have_ldi_id = B_TRUE; 651 652 if ((error = mod_install(&zev_modlinkage)) != 0) { 653 cmn_err(CE_WARN, "zev: could not install module"); 654 goto FAIL; 655 } 656 module_installed = B_TRUE; 657 if ((error = zev_install_callbacks()) != 0) { 658 cmn_err(CE_WARN, "zev: could not install callbacks"); 659 goto FAIL; 660 } 661 return (0); 662 FAIL: 663 /* free resources */ 664 if (module_installed == B_TRUE) 665 (void) mod_remove(&zev_modlinkage); 666 if (have_ldi_id == B_TRUE) 667 (void) ldi_close(zev_zfs_lh, FREAD | FWRITE, kcred); 668 if (have_ident == B_TRUE) 669 ldi_ident_release(zev_ldi_id); 670 mutex_destroy(&zev_mutex); 671 ddi_soft_state_fini(&statep); 672 return (error); 673 } 674 675 int 676 _info(struct modinfo *modinfop) 677 { 678 return (mod_info(&zev_modlinkage, modinfop)); 679 } 680 681 int 682 _fini(void) 683 { 684 int error = 0; 685 zev_mq_t *mq; 686 zev_pool_list_entry_t *pe, *npe; 687 688 mutex_enter(&zev_mutex); 689 if (zev_busy == B_TRUE) { 690 mutex_exit(&zev_mutex); 691 return (SET_ERROR(EBUSY)); 692 } 693 mutex_exit(&zev_mutex); 694 695 if ((error = zev_uninstall_callbacks()) != 0) 696 return (error); 697 /* no thread is inside of the callbacks anymore. Safe to remove. */ 698 if ((error = mod_remove(&zev_modlinkage)) != 0) { 699 cmn_err(CE_WARN, "mod_remove failed: %d", error); 700 return (error); 701 } 702 703 /* free resources */ 704 mutex_enter(&zev_mutex); 705 while (zev_mq_head) { 706 mq = zev_mq_head; 707 zev_mq_head = zev_mq_head->next; 708 if (mq) 709 kmem_free(mq, sizeof(*mq)); 710 } 711 mutex_exit(&zev_mutex); 712 rw_enter(&zev_pool_list_rwlock, RW_WRITER); 713 pe = zev_muted_pools_head; 714 while (pe) { 715 npe = pe; 716 pe = pe->next; 717 kmem_free(npe, sizeof(*npe)); 718 } 719 rw_exit(&zev_pool_list_rwlock); 720 ldi_close(zev_zfs_lh, FREAD | FWRITE, kcred); 721 ddi_soft_state_fini(&statep); 722 ldi_ident_release(zev_ldi_id); 723 rw_destroy(&zev_pool_list_rwlock); 724 cv_destroy(&zev_condvar); 725 mutex_destroy(&zev_mutex); 726 727 return (0); 728 } 729 730