1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2015 Joyent, Inc. 14 */ 15 16 /* 17 * Support for the signalfd facility, a Linux-borne facility for 18 * file descriptor-based synchronous signal consumption. 19 * 20 * As described on the signalfd(3C) man page, the general idea behind these 21 * file descriptors is that they can be used to synchronously consume signals 22 * via the read(2) syscall. That capability already exists with the 23 * sigwaitinfo(3C) function but the key advantage of signalfd is that, because 24 * it is file descriptor based, poll(2) can be used to determine when signals 25 * are available to be consumed. 26 * 27 * The general implementation uses signalfd_state to hold both the signal set 28 * and poll head for an open file descriptor. Because a process can be using 29 * different sigfds with different signal sets, each signalfd_state poll head 30 * can be thought of as an independent signal stream and the thread(s) waiting 31 * on that stream will get poll notification when any signal in the 32 * corresponding set is received. 33 * 34 * The sigfd_proc_state_t struct lives on the proc_t and maintains per-proc 35 * state for function callbacks and data when the proc needs to do work during 36 * signal delivery for pollwakeup. 37 * 38 * The read side of the implementation is straightforward and mimics the 39 * kernel behavior for sigtimedwait(). Signals continue to live on either 40 * the proc's p_sig, or thread's t_sig, member. Read consumes the signal so 41 * that it is no longer pending. 42 * 43 * The poll side is more complex since all of the sigfds on the process need 44 * to be examined every time a signal is delivered to the process in order to 45 * pollwake any thread waiting in poll for that signal. 46 * 47 * Because it is likely that a process will only be using one, or a few, sigfds, 48 * but many total file descriptors, we maintain a list of sigfds which need 49 * pollwakeup. The list lives on the proc's p_sigfd struct. In this way only 50 * zero, or a few, of the state structs will need to be examined every time a 51 * signal is delivered to the process, instead of having to examine all of the 52 * file descriptors to find the state structs. When a state struct with a 53 * matching signal set is found then pollwakeup is called. 54 * 55 * The sigfd_list is self-cleaning; as signalfd_pollwake_cb is called, the list 56 * will clear out on its own. There is an exit helper (signalfd_exit_helper) 57 * which cleans up any remaining per-proc state when the process exits. 58 * 59 * The main complexity with signalfd is the interaction of forking and polling. 60 * This interaction is complex because now two processes have a fd that 61 * references the same dev_t (and its associated signalfd_state), but signals 62 * go to only one of those processes. Also, we don't know when one of the 63 * processes closes its fd because our 'close' entry point is only called when 64 * the last fd is closed (which could be by either process). 65 * 66 * Because the state struct is referenced by both file descriptors, and the 67 * state struct represents a signal stream needing a pollwakeup, if both 68 * processes were polling then both processes would get a pollwakeup when a 69 * signal arrives for either process (that is, the pollhead is associated with 70 * our dev_t so when a signal arrives the pollwakeup wakes up all waiters). 71 * 72 * Fortunately this is not a common problem in practice, but the implementation 73 * attempts to mitigate unexpected behavior. The typical behavior is that the 74 * parent has been polling the signalfd (which is why it was open in the first 75 * place) and the parent might have a pending signalfd_state (with the 76 * pollhead) on its per-process sigfd_list. After the fork the child will 77 * simply close that fd (among others) as part of the typical fork/close/exec 78 * pattern. Because the child will never poll that fd, it will never get any 79 * state onto its own sigfd_list (the child starts with a null list). The 80 * intention is that the child sees no pollwakeup activity for signals unless 81 * it explicitly reinvokes poll on the sigfd. 82 * 83 * As background, there are two primary polling cases to consider when the 84 * parent process forks: 85 * 1) If any thread is blocked in poll(2) then both the parent and child will 86 * return from the poll syscall with EINTR. This means that if either 87 * process wants to re-poll on a sigfd then it needs to re-run poll and 88 * would come back in to the signalfd_poll entry point. The parent would 89 * already have the dev_t's state on its sigfd_list and the child would not 90 * have anything there unless it called poll again on its fd. 91 * 2) If the process is using /dev/poll(7D) then the polling info is being 92 * cached by the poll device and the process might not currently be blocked 93 * on anything polling related. A subsequent DP_POLL ioctl will not invoke 94 * our signalfd_poll entry point again. Because the parent still has its 95 * sigfd_list setup, an incoming signal will hit our signalfd_pollwake_cb 96 * entry point, which in turn calls pollwake, and /dev/poll will do the 97 * right thing on DP_POLL. The child will not have a sigfd_list yet so the 98 * signal will not cause a pollwakeup. The dp code does its own handling for 99 * cleaning up its cache. 100 * 101 * This leaves only one odd corner case. If the parent and child both use 102 * the dup-ed sigfd to poll then when a signal is delivered to either process 103 * there is no way to determine which one should get the pollwakeup (since 104 * both processes will be queued on the same signal stream poll head). What 105 * happens in this case is that both processes will return from poll, but only 106 * one of them will actually have a signal to read. The other will return 107 * from read with EAGAIN, or block. This case is actually similar to the 108 * situation within a single process which got two different sigfd's with the 109 * same mask (or poll on two fd's that are dup-ed). Both would return from poll 110 * when a signal arrives but only one read would consume the signal and the 111 * other read would fail or block. Applications which poll on shared fd's 112 * cannot assume that a subsequent read will actually obtain data. 113 */ 114 115 #include <sys/ddi.h> 116 #include <sys/sunddi.h> 117 #include <sys/signalfd.h> 118 #include <sys/conf.h> 119 #include <sys/sysmacros.h> 120 #include <sys/filio.h> 121 #include <sys/stat.h> 122 #include <sys/file.h> 123 #include <sys/schedctl.h> 124 #include <sys/id_space.h> 125 #include <sys/sdt.h> 126 127 typedef struct signalfd_state signalfd_state_t; 128 129 struct signalfd_state { 130 kmutex_t sfd_lock; /* lock protecting state */ 131 pollhead_t sfd_pollhd; /* poll head */ 132 k_sigset_t sfd_set; /* signals for this fd */ 133 signalfd_state_t *sfd_next; /* next state on global list */ 134 }; 135 136 /* 137 * Internal global variables. 138 */ 139 static kmutex_t signalfd_lock; /* lock protecting state */ 140 static dev_info_t *signalfd_devi; /* device info */ 141 static id_space_t *signalfd_minor; /* minor number arena */ 142 static void *signalfd_softstate; /* softstate pointer */ 143 static signalfd_state_t *signalfd_state; /* global list of state */ 144 145 /* 146 * If we don't already have an entry in the proc's list for this state, add one. 147 */ 148 static void 149 signalfd_wake_list_add(signalfd_state_t *state) 150 { 151 proc_t *p = curproc; 152 list_t *lst; 153 sigfd_wake_list_t *wlp; 154 155 ASSERT(MUTEX_HELD(&p->p_lock)); 156 ASSERT(p->p_sigfd != NULL); 157 158 lst = &((sigfd_proc_state_t *)p->p_sigfd)->sigfd_list; 159 for (wlp = list_head(lst); wlp != NULL; wlp = list_next(lst, wlp)) { 160 if (wlp->sigfd_wl_state == state) 161 break; 162 } 163 164 if (wlp == NULL) { 165 wlp = kmem_zalloc(sizeof (sigfd_wake_list_t), KM_SLEEP); 166 wlp->sigfd_wl_state = state; 167 list_insert_head(lst, wlp); 168 } 169 } 170 171 static void 172 signalfd_wake_rm(list_t *lst, sigfd_wake_list_t *wlp) 173 { 174 list_remove(lst, wlp); 175 kmem_free(wlp, sizeof (sigfd_wake_list_t)); 176 } 177 178 static void 179 signalfd_wake_list_rm(proc_t *p, signalfd_state_t *state) 180 { 181 sigfd_wake_list_t *wlp; 182 list_t *lst; 183 184 ASSERT(MUTEX_HELD(&p->p_lock)); 185 186 if (p->p_sigfd == NULL) 187 return; 188 189 lst = &((sigfd_proc_state_t *)p->p_sigfd)->sigfd_list; 190 for (wlp = list_head(lst); wlp != NULL; wlp = list_next(lst, wlp)) { 191 if (wlp->sigfd_wl_state == state) { 192 signalfd_wake_rm(lst, wlp); 193 break; 194 } 195 } 196 197 if (list_is_empty(lst)) { 198 ((sigfd_proc_state_t *)p->p_sigfd)->sigfd_pollwake_cb = NULL; 199 list_destroy(lst); 200 kmem_free(p->p_sigfd, sizeof (sigfd_proc_state_t)); 201 p->p_sigfd = NULL; 202 } 203 } 204 205 static void 206 signalfd_wake_list_cleanup(proc_t *p) 207 { 208 sigfd_wake_list_t *wlp; 209 list_t *lst; 210 211 ASSERT(MUTEX_HELD(&p->p_lock)); 212 213 ((sigfd_proc_state_t *)p->p_sigfd)->sigfd_pollwake_cb = NULL; 214 215 lst = &((sigfd_proc_state_t *)p->p_sigfd)->sigfd_list; 216 while (!list_is_empty(lst)) { 217 wlp = (sigfd_wake_list_t *)list_remove_head(lst); 218 kmem_free(wlp, sizeof (sigfd_wake_list_t)); 219 } 220 } 221 222 static void 223 signalfd_exit_helper(void) 224 { 225 proc_t *p = curproc; 226 list_t *lst; 227 228 /* This being non-null is the only way we can get here */ 229 ASSERT(p->p_sigfd != NULL); 230 231 mutex_enter(&p->p_lock); 232 lst = &((sigfd_proc_state_t *)p->p_sigfd)->sigfd_list; 233 234 signalfd_wake_list_cleanup(p); 235 list_destroy(lst); 236 kmem_free(p->p_sigfd, sizeof (sigfd_proc_state_t)); 237 p->p_sigfd = NULL; 238 mutex_exit(&p->p_lock); 239 } 240 241 /* 242 * Called every time a signal is delivered to the process so that we can 243 * see if any signal stream needs a pollwakeup. We maintain a list of 244 * signal state elements so that we don't have to look at every file descriptor 245 * on the process. If necessary, a further optimization would be to maintain a 246 * signal set mask that is a union of all of the sets in the list so that 247 * we don't even traverse the list if the signal is not in one of the elements. 248 * However, since the list is likely to be very short, this is not currently 249 * being done. A more complex data structure might also be used, but it is 250 * unclear what that would be since each signal set needs to be checked for a 251 * match. 252 */ 253 static void 254 signalfd_pollwake_cb(void *arg0, int sig) 255 { 256 proc_t *p = (proc_t *)arg0; 257 list_t *lst; 258 sigfd_wake_list_t *wlp; 259 260 ASSERT(MUTEX_HELD(&p->p_lock)); 261 262 if (p->p_sigfd == NULL) 263 return; 264 265 lst = &((sigfd_proc_state_t *)p->p_sigfd)->sigfd_list; 266 wlp = list_head(lst); 267 while (wlp != NULL) { 268 signalfd_state_t *state = wlp->sigfd_wl_state; 269 270 mutex_enter(&state->sfd_lock); 271 272 if (sigismember(&state->sfd_set, sig) && 273 state->sfd_pollhd.ph_list != NULL) { 274 sigfd_wake_list_t *tmp = wlp; 275 276 /* remove it from the list */ 277 wlp = list_next(lst, wlp); 278 signalfd_wake_rm(lst, tmp); 279 280 mutex_exit(&state->sfd_lock); 281 pollwakeup(&state->sfd_pollhd, POLLRDNORM | POLLIN); 282 } else { 283 mutex_exit(&state->sfd_lock); 284 wlp = list_next(lst, wlp); 285 } 286 } 287 } 288 289 _NOTE(ARGSUSED(1)) 290 static int 291 signalfd_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) 292 { 293 signalfd_state_t *state; 294 major_t major = getemajor(*devp); 295 minor_t minor = getminor(*devp); 296 297 if (minor != SIGNALFDMNRN_SIGNALFD) 298 return (ENXIO); 299 300 mutex_enter(&signalfd_lock); 301 302 minor = (minor_t)id_allocff(signalfd_minor); 303 304 if (ddi_soft_state_zalloc(signalfd_softstate, minor) != DDI_SUCCESS) { 305 id_free(signalfd_minor, minor); 306 mutex_exit(&signalfd_lock); 307 return (ENODEV); 308 } 309 310 state = ddi_get_soft_state(signalfd_softstate, minor); 311 *devp = makedevice(major, minor); 312 313 state->sfd_next = signalfd_state; 314 signalfd_state = state; 315 316 mutex_exit(&signalfd_lock); 317 318 return (0); 319 } 320 321 /* 322 * Consume one signal from our set in a manner similar to sigtimedwait(). 323 * The block parameter is used to control whether we wait for a signal or 324 * return immediately if no signal is pending. We use the thread's t_sigwait 325 * member in the same way that it is used by sigtimedwait. 326 * 327 * Return 0 if we successfully consumed a signal or an errno if not. 328 */ 329 static int 330 consume_signal(k_sigset_t set, uio_t *uio, boolean_t block) 331 { 332 k_sigset_t oldmask; 333 kthread_t *t = curthread; 334 klwp_t *lwp = ttolwp(t); 335 proc_t *p = ttoproc(t); 336 timespec_t now; 337 timespec_t *rqtp = NULL; /* null means blocking */ 338 int timecheck = 0; 339 int ret = 0; 340 k_siginfo_t info, *infop; 341 signalfd_siginfo_t ssi, *ssp = &ssi; 342 343 if (block == B_FALSE) { 344 timecheck = timechanged; 345 gethrestime(&now); 346 rqtp = &now; /* non-blocking check for pending signals */ 347 } 348 349 t->t_sigwait = set; 350 351 mutex_enter(&p->p_lock); 352 /* 353 * set the thread's signal mask to unmask those signals in the 354 * specified set. 355 */ 356 schedctl_finish_sigblock(t); 357 oldmask = t->t_hold; 358 sigdiffset(&t->t_hold, &t->t_sigwait); 359 360 /* 361 * Based on rqtp, wait indefinitely until we take a signal in our set 362 * or return immediately if there are no signals pending from our set. 363 */ 364 while ((ret = cv_waituntil_sig(&t->t_delay_cv, &p->p_lock, rqtp, 365 timecheck)) > 0) 366 continue; 367 368 /* Restore thread's signal mask to its previous value. */ 369 t->t_hold = oldmask; 370 t->t_sig_check = 1; /* so post_syscall sees new t_hold mask */ 371 372 if (ret == -1) { 373 /* no signals pending */ 374 mutex_exit(&p->p_lock); 375 sigemptyset(&t->t_sigwait); 376 return (EAGAIN); /* no signals pending */ 377 } 378 379 /* Don't bother with signal if it is not in request set. */ 380 if (lwp->lwp_cursig == 0 || 381 !sigismember(&t->t_sigwait, lwp->lwp_cursig)) { 382 mutex_exit(&p->p_lock); 383 /* 384 * lwp_cursig is zero if pokelwps() awakened cv_wait_sig(). 385 * This happens if some other thread in this process called 386 * forkall() or exit(). 387 */ 388 sigemptyset(&t->t_sigwait); 389 return (EINTR); 390 } 391 392 if (lwp->lwp_curinfo) { 393 infop = &lwp->lwp_curinfo->sq_info; 394 } else { 395 infop = &info; 396 bzero(infop, sizeof (info)); 397 infop->si_signo = lwp->lwp_cursig; 398 infop->si_code = SI_NOINFO; 399 } 400 401 lwp->lwp_ru.nsignals++; 402 403 DTRACE_PROC2(signal__clear, int, ret, ksiginfo_t *, infop); 404 lwp->lwp_cursig = 0; 405 lwp->lwp_extsig = 0; 406 mutex_exit(&p->p_lock); 407 408 /* Convert k_siginfo into external, datamodel independent, struct. */ 409 bzero(ssp, sizeof (*ssp)); 410 ssp->ssi_signo = infop->si_signo; 411 ssp->ssi_errno = infop->si_errno; 412 ssp->ssi_code = infop->si_code; 413 ssp->ssi_pid = infop->si_pid; 414 ssp->ssi_uid = infop->si_uid; 415 ssp->ssi_fd = infop->si_fd; 416 ssp->ssi_band = infop->si_band; 417 ssp->ssi_trapno = infop->si_trapno; 418 ssp->ssi_status = infop->si_status; 419 ssp->ssi_utime = infop->si_utime; 420 ssp->ssi_stime = infop->si_stime; 421 ssp->ssi_addr = (uint64_t)(intptr_t)infop->si_addr; 422 423 ret = uiomove(ssp, sizeof (*ssp), UIO_READ, uio); 424 425 if (lwp->lwp_curinfo) { 426 siginfofree(lwp->lwp_curinfo); 427 lwp->lwp_curinfo = NULL; 428 } 429 sigemptyset(&t->t_sigwait); 430 return (ret); 431 } 432 433 /* 434 * This is similar to sigtimedwait. Based on the fd mode we may wait until a 435 * signal within our specified set is posted. We consume as many available 436 * signals within our set as we can. 437 */ 438 _NOTE(ARGSUSED(2)) 439 static int 440 signalfd_read(dev_t dev, uio_t *uio, cred_t *cr) 441 { 442 signalfd_state_t *state; 443 minor_t minor = getminor(dev); 444 boolean_t block = B_TRUE; 445 k_sigset_t set; 446 boolean_t got_one = B_FALSE; 447 int res; 448 449 if (uio->uio_resid < sizeof (signalfd_siginfo_t)) 450 return (EINVAL); 451 452 state = ddi_get_soft_state(signalfd_softstate, minor); 453 454 if (uio->uio_fmode & (FNDELAY|FNONBLOCK)) 455 block = B_FALSE; 456 457 mutex_enter(&state->sfd_lock); 458 set = state->sfd_set; 459 mutex_exit(&state->sfd_lock); 460 461 if (sigisempty(&set)) 462 return (set_errno(EINVAL)); 463 464 do { 465 res = consume_signal(state->sfd_set, uio, block); 466 if (res == 0) 467 got_one = B_TRUE; 468 469 /* 470 * After consuming one signal we won't block trying to consume 471 * further signals. 472 */ 473 block = B_FALSE; 474 } while (res == 0 && uio->uio_resid >= sizeof (signalfd_siginfo_t)); 475 476 if (got_one) 477 res = 0; 478 479 return (res); 480 } 481 482 /* 483 * If ksigset_t's were a single word, we would do: 484 * return (((p->p_sig | t->t_sig) & set) & fillset); 485 */ 486 static int 487 signalfd_sig_pending(proc_t *p, kthread_t *t, k_sigset_t set) 488 { 489 return (((p->p_sig.__sigbits[0] | t->t_sig.__sigbits[0]) & 490 set.__sigbits[0]) | 491 ((p->p_sig.__sigbits[1] | t->t_sig.__sigbits[1]) & 492 set.__sigbits[1]) | 493 (((p->p_sig.__sigbits[2] | t->t_sig.__sigbits[2]) & 494 set.__sigbits[2]) & FILLSET2)); 495 } 496 497 _NOTE(ARGSUSED(4)) 498 static int 499 signalfd_poll(dev_t dev, short events, int anyyet, short *reventsp, 500 struct pollhead **phpp) 501 { 502 signalfd_state_t *state; 503 minor_t minor = getminor(dev); 504 kthread_t *t = curthread; 505 proc_t *p = ttoproc(t); 506 short revents = 0; 507 508 state = ddi_get_soft_state(signalfd_softstate, minor); 509 510 mutex_enter(&state->sfd_lock); 511 512 if (signalfd_sig_pending(p, t, state->sfd_set) != 0) 513 revents |= POLLRDNORM | POLLIN; 514 515 mutex_exit(&state->sfd_lock); 516 517 if (!(*reventsp = revents & events) && !anyyet) { 518 *phpp = &state->sfd_pollhd; 519 520 /* 521 * Enable pollwakeup handling. 522 */ 523 if (p->p_sigfd == NULL) { 524 sigfd_proc_state_t *pstate; 525 526 pstate = kmem_zalloc(sizeof (sigfd_proc_state_t), 527 KM_SLEEP); 528 list_create(&pstate->sigfd_list, 529 sizeof (sigfd_wake_list_t), 530 offsetof(sigfd_wake_list_t, sigfd_wl_lst)); 531 532 mutex_enter(&p->p_lock); 533 /* check again now that we're locked */ 534 if (p->p_sigfd == NULL) { 535 p->p_sigfd = pstate; 536 } else { 537 /* someone beat us to it */ 538 list_destroy(&pstate->sigfd_list); 539 kmem_free(pstate, sizeof (sigfd_proc_state_t)); 540 } 541 mutex_exit(&p->p_lock); 542 } 543 544 mutex_enter(&p->p_lock); 545 if (((sigfd_proc_state_t *)p->p_sigfd)->sigfd_pollwake_cb == 546 NULL) { 547 ((sigfd_proc_state_t *)p->p_sigfd)->sigfd_pollwake_cb = 548 signalfd_pollwake_cb; 549 } 550 signalfd_wake_list_add(state); 551 mutex_exit(&p->p_lock); 552 } 553 554 return (0); 555 } 556 557 _NOTE(ARGSUSED(4)) 558 static int 559 signalfd_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) 560 { 561 signalfd_state_t *state; 562 minor_t minor = getminor(dev); 563 sigset_t mask; 564 565 state = ddi_get_soft_state(signalfd_softstate, minor); 566 567 switch (cmd) { 568 case SIGNALFDIOC_MASK: 569 if (ddi_copyin((caddr_t)arg, (caddr_t)&mask, sizeof (sigset_t), 570 md) != 0) 571 return (set_errno(EFAULT)); 572 573 mutex_enter(&state->sfd_lock); 574 sigutok(&mask, &state->sfd_set); 575 mutex_exit(&state->sfd_lock); 576 577 return (0); 578 579 default: 580 break; 581 } 582 583 return (ENOTTY); 584 } 585 586 _NOTE(ARGSUSED(1)) 587 static int 588 signalfd_close(dev_t dev, int flag, int otyp, cred_t *cred_p) 589 { 590 signalfd_state_t *state, **sp; 591 minor_t minor = getminor(dev); 592 proc_t *p = curproc; 593 594 state = ddi_get_soft_state(signalfd_softstate, minor); 595 596 if (state->sfd_pollhd.ph_list != NULL) { 597 pollwakeup(&state->sfd_pollhd, POLLERR); 598 pollhead_clean(&state->sfd_pollhd); 599 } 600 601 /* Make sure our state is removed from our proc's pollwake list. */ 602 mutex_enter(&p->p_lock); 603 signalfd_wake_list_rm(p, state); 604 mutex_exit(&p->p_lock); 605 606 mutex_enter(&signalfd_lock); 607 608 /* Remove our state from our global list. */ 609 for (sp = &signalfd_state; *sp != state; sp = &((*sp)->sfd_next)) 610 VERIFY(*sp != NULL); 611 612 *sp = (*sp)->sfd_next; 613 614 ddi_soft_state_free(signalfd_softstate, minor); 615 id_free(signalfd_minor, minor); 616 617 mutex_exit(&signalfd_lock); 618 619 return (0); 620 } 621 622 static int 623 signalfd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 624 { 625 if (cmd != DDI_ATTACH || signalfd_devi != NULL) 626 return (DDI_FAILURE); 627 628 mutex_enter(&signalfd_lock); 629 630 signalfd_minor = id_space_create("signalfd_minor", 1, L_MAXMIN32 + 1); 631 if (signalfd_minor == NULL) { 632 cmn_err(CE_WARN, "signalfd couldn't create id space"); 633 mutex_exit(&signalfd_lock); 634 return (DDI_FAILURE); 635 } 636 637 if (ddi_soft_state_init(&signalfd_softstate, 638 sizeof (signalfd_state_t), 0) != 0) { 639 cmn_err(CE_WARN, "signalfd failed to create soft state"); 640 id_space_destroy(signalfd_minor); 641 mutex_exit(&signalfd_lock); 642 return (DDI_FAILURE); 643 } 644 645 if (ddi_create_minor_node(devi, "signalfd", S_IFCHR, 646 SIGNALFDMNRN_SIGNALFD, DDI_PSEUDO, NULL) == DDI_FAILURE) { 647 cmn_err(CE_NOTE, "/dev/signalfd couldn't create minor node"); 648 ddi_soft_state_fini(&signalfd_softstate); 649 id_space_destroy(signalfd_minor); 650 mutex_exit(&signalfd_lock); 651 return (DDI_FAILURE); 652 } 653 654 ddi_report_dev(devi); 655 signalfd_devi = devi; 656 657 sigfd_exit_helper = signalfd_exit_helper; 658 659 mutex_exit(&signalfd_lock); 660 661 return (DDI_SUCCESS); 662 } 663 664 _NOTE(ARGSUSED(0)) 665 static int 666 signalfd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 667 { 668 switch (cmd) { 669 case DDI_DETACH: 670 break; 671 672 default: 673 return (DDI_FAILURE); 674 } 675 676 /* list should be empty */ 677 VERIFY(signalfd_state == NULL); 678 679 mutex_enter(&signalfd_lock); 680 id_space_destroy(signalfd_minor); 681 682 ddi_remove_minor_node(signalfd_devi, NULL); 683 signalfd_devi = NULL; 684 sigfd_exit_helper = NULL; 685 686 ddi_soft_state_fini(&signalfd_softstate); 687 mutex_exit(&signalfd_lock); 688 689 return (DDI_SUCCESS); 690 } 691 692 _NOTE(ARGSUSED(0)) 693 static int 694 signalfd_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 695 { 696 int error; 697 698 switch (infocmd) { 699 case DDI_INFO_DEVT2DEVINFO: 700 *result = (void *)signalfd_devi; 701 error = DDI_SUCCESS; 702 break; 703 case DDI_INFO_DEVT2INSTANCE: 704 *result = (void *)0; 705 error = DDI_SUCCESS; 706 break; 707 default: 708 error = DDI_FAILURE; 709 } 710 return (error); 711 } 712 713 static struct cb_ops signalfd_cb_ops = { 714 signalfd_open, /* open */ 715 signalfd_close, /* close */ 716 nulldev, /* strategy */ 717 nulldev, /* print */ 718 nodev, /* dump */ 719 signalfd_read, /* read */ 720 nodev, /* write */ 721 signalfd_ioctl, /* ioctl */ 722 nodev, /* devmap */ 723 nodev, /* mmap */ 724 nodev, /* segmap */ 725 signalfd_poll, /* poll */ 726 ddi_prop_op, /* cb_prop_op */ 727 0, /* streamtab */ 728 D_NEW | D_MP /* Driver compatibility flag */ 729 }; 730 731 static struct dev_ops signalfd_ops = { 732 DEVO_REV, /* devo_rev */ 733 0, /* refcnt */ 734 signalfd_info, /* get_dev_info */ 735 nulldev, /* identify */ 736 nulldev, /* probe */ 737 signalfd_attach, /* attach */ 738 signalfd_detach, /* detach */ 739 nodev, /* reset */ 740 &signalfd_cb_ops, /* driver operations */ 741 NULL, /* bus operations */ 742 nodev, /* dev power */ 743 ddi_quiesce_not_needed, /* quiesce */ 744 }; 745 746 static struct modldrv modldrv = { 747 &mod_driverops, /* module type (this is a pseudo driver) */ 748 "signalfd support", /* name of module */ 749 &signalfd_ops, /* driver ops */ 750 }; 751 752 static struct modlinkage modlinkage = { 753 MODREV_1, 754 (void *)&modldrv, 755 NULL 756 }; 757 758 int 759 _init(void) 760 { 761 return (mod_install(&modlinkage)); 762 } 763 764 int 765 _info(struct modinfo *modinfop) 766 { 767 return (mod_info(&modlinkage, modinfop)); 768 } 769 770 int 771 _fini(void) 772 { 773 return (mod_remove(&modlinkage)); 774 }