1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 30 #pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.25 */ 31 32 #include <sys/types.h> 33 #include <sys/sysmacros.h> 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/vfs.h> 37 #include <sys/cred.h> 38 #include <sys/vnode.h> 39 #include <sys/file.h> 40 #include <sys/errno.h> 41 #include <sys/kmem.h> 42 #include <sys/user.h> 43 #include <sys/buf.h> 44 #include <sys/var.h> 45 #include <sys/conf.h> 46 #include <sys/debug.h> 47 #include <sys/proc.h> 48 #include <sys/signal.h> 49 #include <sys/siginfo.h> 50 #include <sys/acct.h> 51 #include <sys/procset.h> 52 #include <sys/cmn_err.h> 53 #include <sys/fault.h> 54 #include <sys/syscall.h> 55 #include <sys/ucontext.h> 56 #include <sys/procfs.h> 57 #include <sys/session.h> 58 #include <sys/task.h> 59 #include <sys/project.h> 60 #include <sys/pool.h> 61 #include <sys/zone.h> 62 #include <sys/contract/process_impl.h> 63 64 id_t getmyid(idtype_t); 65 int checkprocset(procset_t *); 66 static kthread_t *getlwpptr(id_t); 67 int procinset(proc_t *, procset_t *); 68 static int lwpinset(proc_t *, procset_t *, kthread_t *, int *); 69 70 /* 71 * The dotoprocs function locates the process(es) specified 72 * by the procset structure pointed to by psp. If funcp 73 * is non-NULL then it points to a function which dotoprocs 74 * will call for each process in the specified set. The 75 * arguments to this function will be a pointer to the 76 * current process from the set and arg. 77 * If the called function returns -1, it means that processing of the 78 * procset should stop and a normal (non-error) return should be made 79 * to the caller of dotoprocs. 80 * If the called function returns any other non-zero value the search 81 * is terminated and the function's return value is returned to 82 * the caller of dotoprocs. This will normally be an error code. 83 * Otherwise, dotoprocs will return zero after processing the entire 84 * process set unless no processes were found in which case ESRCH will 85 * be returned. 86 */ 87 int 88 dotoprocs(procset_t *psp, int (*funcp)(), char *arg) 89 { 90 proc_t *prp; /* A process from the set */ 91 int error; 92 int nfound; /* Nbr of processes found. */ 93 proc_t *lastprp; /* Last proc found. */ 94 95 /* 96 * Check that the procset_t is valid. 97 */ 98 error = checkprocset(psp); 99 if (error) { 100 return (error); 101 } 102 /* 103 * Check for the special value P_MYID in either operand 104 * and replace it with the correct value. We don't check 105 * for an error return from getmyid() because the idtypes 106 * have been validated by the checkprocset() call above. 107 */ 108 mutex_enter(&pidlock); 109 if (psp->p_lid == P_MYID) { 110 psp->p_lid = getmyid(psp->p_lidtype); 111 } 112 if (psp->p_rid == P_MYID) { 113 psp->p_rid = getmyid(psp->p_ridtype); 114 } 115 116 /* 117 * If psp only acts on a single proc, we can reduce pidlock hold time 118 * by avoiding a needless scan of the entire proc list. Although 119 * there are many procset_t combinations which might boil down to a 120 * single proc, the most common case is an AND operation where one 121 * side is a specific pid, and the other side is P_ALL, so that is 122 * the case for which we will provide a fast path. Other cases could 123 * be added in a similar fashion if they were to become significant 124 * pidlock bottlenecks. 125 * 126 * Perform the check symmetrically: either the left or right side may 127 * specify a pid, with the opposite side being 'all'. 128 */ 129 if (psp->p_op == POP_AND) { 130 if (((psp->p_lidtype == P_PID) && (psp->p_ridtype == P_ALL)) || 131 ((psp->p_ridtype == P_PID) && (psp->p_lidtype == P_ALL))) { 132 id_t pid; 133 134 pid = (psp->p_lidtype == P_PID) ? 135 psp->p_lid : psp->p_rid; 136 if ((prp = prfind((pid_t)pid)) == NULL) { 137 /* specified proc doesn't exist */ 138 mutex_exit(&pidlock); 139 return (ESRCH); 140 } 141 /* operate only on the specified proc */ 142 error = (*funcp)(prp, arg); 143 mutex_exit(&pidlock); 144 if (error == -1) 145 error = 0; 146 return (error); 147 } 148 } 149 150 nfound = 0; 151 error = 0; 152 153 for (prp = practive; prp != NULL; prp = prp->p_next) { 154 /* 155 * If caller is in a non-global zone, skip processes 156 * in other zones. 157 */ 158 if (!HASZONEACCESS(curproc, prp->p_zone->zone_id)) 159 continue; 160 if (prp->p_stat == SIDL || prp->p_stat == SZOMB || 161 prp->p_tlist == NULL || prp->p_flag & SSYS) 162 continue; 163 if (procinset(prp, psp)) { 164 nfound++; 165 lastprp = prp; 166 if (funcp != NULL && prp != proc_init) { 167 error = (*funcp)(prp, arg); 168 if (error == -1) { 169 mutex_exit(&pidlock); 170 return (0); 171 } else if (error) { 172 mutex_exit(&pidlock); 173 return (error); 174 } 175 } 176 } 177 } 178 if (nfound == 0) { 179 mutex_exit(&pidlock); 180 return (ESRCH); 181 } 182 if (nfound == 1 && lastprp == proc_init && funcp != NULL) 183 error = (*funcp)(lastprp, arg); 184 if (error == -1) 185 error = 0; 186 mutex_exit(&pidlock); 187 return (error); 188 } 189 190 /* 191 * Check if a procset_t is valid. Return zero or an errno. 192 */ 193 int 194 checkprocset(procset_t *psp) 195 { 196 switch (psp->p_lidtype) { 197 case P_LWPID: 198 case P_PID: 199 case P_PPID: 200 case P_PGID: 201 case P_SID: 202 case P_TASKID: 203 case P_CID: 204 case P_UID: 205 case P_GID: 206 case P_PROJID: 207 case P_POOLID: 208 case P_ZONEID: 209 case P_CTID: 210 case P_ALL: 211 break; 212 default: 213 return (EINVAL); 214 } 215 216 switch (psp->p_ridtype) { 217 case P_LWPID: 218 case P_PID: 219 case P_PPID: 220 case P_PGID: 221 case P_SID: 222 case P_TASKID: 223 case P_CID: 224 case P_UID: 225 case P_GID: 226 case P_PROJID: 227 case P_POOLID: 228 case P_ZONEID: 229 case P_CTID: 230 case P_ALL: 231 break; 232 default: 233 return (EINVAL); 234 } 235 236 switch (psp->p_op) { 237 case POP_DIFF: 238 case POP_AND: 239 case POP_OR: 240 case POP_XOR: 241 break; 242 default: 243 return (EINVAL); 244 } 245 246 return (0); 247 } 248 249 /* 250 * procinset returns 1 if the process pointed to 251 * by pp is in the process set specified by psp, otherwise 0 is returned. 252 * The caller should check that the process is not exiting and is not 253 * in the SYS scheduling class. 254 * 255 * This function expects to be called with a valid procset_t. 256 * The set should be checked using checkprocset() before calling 257 * this function. 258 */ 259 int 260 procinset(proc_t *pp, procset_t *psp) 261 { 262 int loperand = 0; 263 int roperand = 0; 264 int lwplinproc = 0; 265 int lwprinproc = 0; 266 kthread_t *tp = proctot(pp); 267 268 switch (psp->p_lidtype) { 269 270 case P_LWPID: 271 if (pp == ttoproc(curthread)) 272 if (getlwpptr(psp->p_lid) != NULL) 273 lwplinproc++; 274 break; 275 276 case P_PID: 277 if (pp->p_pid == psp->p_lid) 278 loperand++; 279 break; 280 281 case P_PPID: 282 if (pp->p_ppid == psp->p_lid) 283 loperand++; 284 break; 285 286 case P_PGID: 287 if (pp->p_pgrp == psp->p_lid) 288 loperand++; 289 break; 290 291 case P_SID: 292 mutex_enter(&pp->p_splock); 293 if (pp->p_sessp->s_sid == psp->p_lid) 294 loperand++; 295 mutex_exit(&pp->p_splock); 296 break; 297 298 case P_CID: 299 ASSERT(tp != NULL); 300 /* This case is broken for now. Need to be fixed XXX */ 301 if (tp->t_cid == psp->p_lid) 302 /* 303 * if (checkcid(psp->p_lid)) 304 */ 305 loperand++; 306 break; 307 308 case P_TASKID: 309 if (pp->p_task->tk_tkid == psp->p_lid) 310 loperand++; 311 break; 312 313 case P_UID: 314 mutex_enter(&pp->p_crlock); 315 if (crgetuid(pp->p_cred) == psp->p_lid) 316 loperand++; 317 mutex_exit(&pp->p_crlock); 318 break; 319 320 case P_GID: 321 mutex_enter(&pp->p_crlock); 322 if (crgetgid(pp->p_cred) == psp->p_lid) 323 loperand++; 324 mutex_exit(&pp->p_crlock); 325 break; 326 327 case P_PROJID: 328 if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 329 loperand++; 330 break; 331 332 case P_POOLID: 333 if (pp->p_pool->pool_id == psp->p_lid) 334 loperand++; 335 break; 336 337 case P_ZONEID: 338 if (pp->p_zone->zone_id == psp->p_lid) 339 loperand++; 340 break; 341 342 case P_CTID: 343 if (PRCTID(pp) == psp->p_lid) 344 loperand++; 345 break; 346 347 case P_ALL: 348 loperand++; 349 break; 350 351 default: 352 #ifdef DEBUG 353 cmn_err(CE_WARN, "procinset called with bad set"); 354 return (0); 355 #else 356 return (0); 357 #endif 358 } 359 360 switch (psp->p_ridtype) { 361 362 case P_LWPID: 363 if (pp == ttoproc(curthread)) 364 if (getlwpptr(psp->p_rid) != NULL) 365 lwprinproc++; 366 break; 367 368 case P_PID: 369 if (pp->p_pid == psp->p_rid) 370 roperand++; 371 break; 372 373 case P_PPID: 374 if (pp->p_ppid == psp->p_rid) 375 roperand++; 376 break; 377 378 case P_PGID: 379 if (pp->p_pgrp == psp->p_rid) 380 roperand++; 381 break; 382 383 case P_SID: 384 mutex_enter(&pp->p_splock); 385 if (pp->p_sessp->s_sid == psp->p_rid) 386 roperand++; 387 mutex_exit(&pp->p_splock); 388 break; 389 390 case P_TASKID: 391 if (pp->p_task->tk_tkid == psp->p_rid) 392 roperand++; 393 break; 394 395 case P_CID: 396 ASSERT(tp != NULL); 397 /* This case is broken for now. Need to be fixed XXX */ 398 if (tp->t_cid == psp->p_rid) 399 /* 400 * if (checkcid(psp->p_rid)) 401 */ 402 roperand++; 403 break; 404 405 case P_UID: 406 mutex_enter(&pp->p_crlock); 407 if (crgetuid(pp->p_cred) == psp->p_rid) 408 roperand++; 409 mutex_exit(&pp->p_crlock); 410 break; 411 412 case P_GID: 413 mutex_enter(&pp->p_crlock); 414 if (crgetgid(pp->p_cred) == psp->p_rid) 415 roperand++; 416 mutex_exit(&pp->p_crlock); 417 break; 418 419 case P_PROJID: 420 if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 421 roperand++; 422 break; 423 424 case P_POOLID: 425 if (pp->p_pool->pool_id == psp->p_rid) 426 roperand++; 427 break; 428 429 case P_ZONEID: 430 if (pp->p_zone->zone_id == psp->p_rid) 431 roperand++; 432 break; 433 434 case P_CTID: 435 if (PRCTID(pp) == psp->p_rid) 436 roperand++; 437 break; 438 439 case P_ALL: 440 roperand++; 441 break; 442 443 default: 444 #ifdef DEBUG 445 cmn_err(CE_WARN, "procinset called with bad set"); 446 return (0); 447 #else 448 return (0); 449 #endif 450 } 451 452 switch (psp->p_op) { 453 454 case POP_DIFF: 455 if (loperand && !lwprinproc && !roperand) 456 return (1); 457 else 458 return (0); 459 460 case POP_AND: 461 if (loperand && roperand) 462 return (1); 463 else 464 return (0); 465 466 case POP_OR: 467 if (loperand || roperand) 468 return (1); 469 else 470 return (0); 471 472 case POP_XOR: 473 if ((loperand && !lwprinproc && !roperand) || 474 (roperand && !lwplinproc && !loperand)) 475 return (1); 476 else 477 return (0); 478 479 default: 480 #ifdef DEBUG 481 cmn_err(CE_WARN, "procinset called with bad set"); 482 return (0); 483 #else 484 return (0); 485 #endif 486 } 487 /* NOTREACHED */ 488 } 489 490 /* 491 * lwpinset returns 1 if the thread pointed to 492 * by tp is in the process set specified by psp and is not in 493 * the sys scheduling class - otherwise 0 is returned. 494 * 495 * This function expects to be called with a valid procset_t. 496 * The set should be checked using checkprocset() before calling 497 * this function. 498 */ 499 int 500 lwpinset(proc_t *pp, procset_t *psp, kthread_t *tp, int *done) 501 { 502 int loperand = 0; 503 int roperand = 0; 504 int lwplinset = 0; 505 int lwprinset = 0; 506 507 ASSERT(ttoproc(tp) == pp); 508 509 /* 510 * If process is in the sys class return (0). 511 */ 512 if (proctot(pp)->t_cid == 0) { 513 return (0); 514 } 515 516 switch (psp->p_lidtype) { 517 518 case P_LWPID: 519 if (tp->t_tid == psp->p_lid) 520 lwplinset ++; 521 break; 522 523 case P_PID: 524 if (pp->p_pid == psp->p_lid) 525 loperand++; 526 break; 527 528 case P_PPID: 529 if (pp->p_ppid == psp->p_lid) 530 loperand++; 531 break; 532 533 case P_PGID: 534 if (pp->p_pgrp == psp->p_lid) 535 loperand++; 536 break; 537 538 case P_SID: 539 mutex_enter(&pp->p_splock); 540 if (pp->p_sessp->s_sid == psp->p_lid) 541 loperand++; 542 mutex_exit(&pp->p_splock); 543 break; 544 545 case P_TASKID: 546 if (pp->p_task->tk_tkid == psp->p_lid) 547 loperand++; 548 break; 549 550 case P_CID: 551 if (tp->t_cid == psp->p_lid) 552 loperand++; 553 break; 554 555 case P_UID: 556 mutex_enter(&pp->p_crlock); 557 if (crgetuid(pp->p_cred) == psp->p_lid) 558 loperand++; 559 mutex_exit(&pp->p_crlock); 560 break; 561 562 case P_GID: 563 mutex_enter(&pp->p_crlock); 564 if (crgetgid(pp->p_cred) == psp->p_lid) 565 loperand++; 566 mutex_exit(&pp->p_crlock); 567 break; 568 569 case P_PROJID: 570 if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 571 loperand++; 572 break; 573 574 case P_POOLID: 575 if (pp->p_pool->pool_id == psp->p_lid) 576 loperand++; 577 break; 578 579 case P_ZONEID: 580 if (pp->p_zone->zone_id == psp->p_lid) 581 loperand++; 582 break; 583 584 case P_CTID: 585 if (PRCTID(pp) == psp->p_lid) 586 loperand++; 587 break; 588 589 case P_ALL: 590 loperand++; 591 break; 592 593 default: 594 #ifdef DEBUG 595 cmn_err(CE_WARN, "lwpinset called with bad set"); 596 return (0); 597 #else 598 return (0); 599 #endif 600 } 601 602 switch (psp->p_ridtype) { 603 604 case P_LWPID: 605 if (tp->t_tid == psp->p_rid) 606 lwprinset ++; 607 break; 608 609 case P_PID: 610 if (pp->p_pid == psp->p_rid) 611 roperand++; 612 break; 613 614 case P_PPID: 615 if (pp->p_ppid == psp->p_rid) 616 roperand++; 617 break; 618 619 case P_PGID: 620 if (pp->p_pgrp == psp->p_rid) 621 roperand++; 622 break; 623 624 case P_SID: 625 mutex_enter(&pp->p_splock); 626 if (pp->p_sessp->s_sid == psp->p_rid) 627 roperand++; 628 mutex_exit(&pp->p_splock); 629 break; 630 631 case P_TASKID: 632 if (pp->p_task->tk_tkid == psp->p_rid) 633 roperand++; 634 break; 635 636 case P_CID: 637 if (tp->t_cid == psp->p_rid) 638 roperand++; 639 break; 640 641 case P_UID: 642 mutex_enter(&pp->p_crlock); 643 if (crgetuid(pp->p_cred) == psp->p_rid) 644 roperand++; 645 mutex_exit(&pp->p_crlock); 646 break; 647 648 case P_GID: 649 mutex_enter(&pp->p_crlock); 650 if (crgetgid(pp->p_cred) == psp->p_rid) 651 roperand++; 652 mutex_exit(&pp->p_crlock); 653 break; 654 655 case P_PROJID: 656 if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 657 roperand++; 658 break; 659 660 case P_POOLID: 661 if (pp->p_pool->pool_id == psp->p_rid) 662 roperand++; 663 break; 664 665 case P_ZONEID: 666 if (pp->p_zone->zone_id == psp->p_rid) 667 roperand++; 668 break; 669 670 case P_CTID: 671 if (PRCTID(pp) == psp->p_rid) 672 roperand++; 673 break; 674 675 case P_ALL: 676 roperand++; 677 break; 678 679 default: 680 #ifdef DEBUG 681 cmn_err(CE_WARN, "lwpinset called with bad set"); 682 return (0); 683 #else 684 return (0); 685 #endif 686 } 687 688 if (lwplinset && lwprinset) 689 *done = 1; 690 691 switch (psp->p_op) { 692 693 case POP_DIFF: 694 if ((loperand || lwplinset) && !(lwprinset || roperand)) 695 return (1); 696 else 697 return (0); 698 699 case POP_AND: 700 if ((loperand || lwplinset) && (roperand || lwprinset)) 701 return (1); 702 else 703 return (0); 704 705 case POP_OR: 706 if (loperand || roperand || lwplinset || lwprinset) 707 return (1); 708 else 709 return (0); 710 711 case POP_XOR: 712 if (((loperand || lwplinset) && 713 !(lwprinset || roperand)) || 714 ((roperand || lwprinset) && 715 !(lwplinset || loperand))) 716 return (1); 717 else 718 return (0); 719 720 default: 721 #ifdef DEBUG 722 cmn_err(CE_WARN, "lwpinset called with bad set"); 723 return (0); 724 #else 725 return (0); 726 #endif 727 } 728 /* NOTREACHED */ 729 } 730 /* 731 * Check for common cases of procsets which specify only the 732 * current process. cur_inset_only() returns B_TRUE when 733 * the current process is the only one in the set. B_FALSE 734 * is returned to indicate that this may not be the case. 735 */ 736 boolean_t 737 cur_inset_only(procset_t *psp) 738 { 739 if (((psp->p_lidtype == P_PID && 740 (psp->p_lid == P_MYID || 741 psp->p_lid == ttoproc(curthread)->p_pid)) || 742 ((psp->p_lidtype == P_LWPID) && 743 (psp->p_lid == P_MYID || 744 psp->p_lid == curthread->t_tid))) && 745 psp->p_op == POP_AND && psp->p_ridtype == P_ALL) 746 return (B_TRUE); 747 748 if (((psp->p_ridtype == P_PID && 749 (psp->p_rid == P_MYID || 750 psp->p_rid == ttoproc(curthread)->p_pid)) || 751 ((psp->p_ridtype == P_LWPID) && 752 (psp->p_rid == P_MYID || 753 psp->p_rid == curthread->t_tid))) && 754 psp->p_op == POP_AND && psp->p_lidtype == P_ALL) 755 return (B_TRUE); 756 757 return (B_FALSE); 758 } 759 760 id_t 761 getmyid(idtype_t idtype) 762 { 763 proc_t *pp; 764 uid_t uid; 765 gid_t gid; 766 pid_t sid; 767 768 pp = ttoproc(curthread); 769 770 switch (idtype) { 771 case P_LWPID: 772 return (curthread->t_tid); 773 774 case P_PID: 775 return (pp->p_pid); 776 777 case P_PPID: 778 return (pp->p_ppid); 779 780 case P_PGID: 781 return (pp->p_pgrp); 782 783 case P_SID: 784 mutex_enter(&pp->p_splock); 785 sid = pp->p_sessp->s_sid; 786 mutex_exit(&pp->p_splock); 787 return (sid); 788 789 case P_TASKID: 790 return (pp->p_task->tk_tkid); 791 792 case P_CID: 793 return (curthread->t_cid); 794 795 case P_UID: 796 mutex_enter(&pp->p_crlock); 797 uid = crgetuid(pp->p_cred); 798 mutex_exit(&pp->p_crlock); 799 return (uid); 800 801 case P_GID: 802 mutex_enter(&pp->p_crlock); 803 gid = crgetgid(pp->p_cred); 804 mutex_exit(&pp->p_crlock); 805 return (gid); 806 807 case P_PROJID: 808 return (pp->p_task->tk_proj->kpj_id); 809 810 case P_POOLID: 811 return (pp->p_pool->pool_id); 812 813 case P_ZONEID: 814 return (pp->p_zone->zone_id); 815 816 case P_CTID: 817 return (PRCTID(pp)); 818 819 case P_ALL: 820 /* 821 * The value doesn't matter for P_ALL. 822 */ 823 return (0); 824 825 default: 826 return (-1); 827 } 828 } 829 830 static kthread_t * 831 getlwpptr(id_t id) 832 { 833 proc_t *p; 834 kthread_t *t; 835 836 if (id == P_MYID) 837 t = curthread; 838 else { 839 p = ttoproc(curthread); 840 mutex_enter(&p->p_lock); 841 t = idtot(p, id); 842 mutex_exit(&p->p_lock); 843 } 844 845 return (t); 846 } 847 848 /* 849 * The dotolwp function locates the LWP(s) specified by the procset structure 850 * pointed to by psp. If funcp is non-NULL then it points to a function 851 * which dotolwp will call for each LWP in the specified set. 852 * LWPIDs specified in the procset structure always refer to lwps in curproc. 853 * The arguments for this function must be "char *arg", and "kthread_t *tp", 854 * where tp is a pointer to the current thread from the set. 855 * Note that these arguments are passed to the function in reversed order 856 * than the order of arguments passed by dotoprocs() to its callback function. 857 * Also note that there are two separate cases where this routine returns zero. 858 * In the first case no mutex is grabbed, in the second the p_lock mutex 859 * is NOT RELEASED. The priocntl code is expecting this behaviour. 860 */ 861 int 862 dotolwp(procset_t *psp, int (*funcp)(), char *arg) 863 { 864 int error = 0; 865 int nfound = 0; 866 kthread_t *tp; 867 proc_t *pp; 868 int done = 0; 869 870 /* 871 * Check that the procset_t is valid. 872 */ 873 error = checkprocset(psp); 874 if (error) { 875 return (error); 876 } 877 878 mutex_enter(&pidlock); 879 880 /* 881 * Check for the special value P_MYID in either operand 882 * and replace it with the correct value. We don't check 883 * for an error return from getmyid() because the idtypes 884 * have been validated by the checkprocset() call above. 885 */ 886 if (psp->p_lid == P_MYID) { 887 psp->p_lid = getmyid(psp->p_lidtype); 888 } 889 if (psp->p_rid == P_MYID) { 890 psp->p_rid = getmyid(psp->p_ridtype); 891 } 892 893 pp = ttoproc(curthread); 894 895 if (procinset(pp, psp)) { 896 mutex_exit(&pidlock); 897 return (0); 898 } 899 mutex_enter(&pp->p_lock); 900 if ((tp = pp->p_tlist) == NULL) { 901 mutex_exit(&pp->p_lock); 902 mutex_exit(&pidlock); 903 return (0); 904 } 905 do { 906 if (lwpinset(pp, psp, tp, &done)) { 907 nfound ++; 908 error = (*funcp)(arg, tp); 909 if (error) { 910 mutex_exit(&pp->p_lock); 911 mutex_exit(&pidlock); 912 return (error); 913 } 914 } 915 } while (((tp = tp->t_forw) != pp->p_tlist) && !done); 916 917 if (nfound == 0) { 918 mutex_exit(&pp->p_lock); 919 mutex_exit(&pidlock); 920 return (ESRCH); 921 } 922 923 mutex_exit(&pidlock); 924 return (error); 925 } 926