Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section


   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  29  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/param.h>
  34 #include <sys/thread.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/signal.h>
  37 #include <sys/cred.h>
  38 #include <sys/priv.h>
  39 #include <sys/user.h>
  40 #include <sys/file.h>
  41 #include <sys/errno.h>
  42 #include <sys/vnode.h>
  43 #include <sys/mode.h>
  44 #include <sys/vfs.h>
  45 #include <sys/mman.h>
  46 #include <sys/kmem.h>
  47 #include <sys/proc.h>
  48 #include <sys/pathname.h>
  49 #include <sys/cmn_err.h>


  77         int nfd;
  78         size_t size;
  79         prcred_t *pcrp;
  80         uf_info_t *fip;
  81         uf_entry_t *ufp;
  82         int fd;
  83 
  84         fip = P_FINFO(p);
  85         nfd = 0;
  86         mutex_enter(&fip->fi_lock);
  87         for (fd = 0; fd < fip->fi_nfiles; fd++) {
  88                 UF_ENTER(ufp, fip, fd);
  89                 if ((ufp->uf_file != NULL) && (ufp->uf_file->f_count > 0))
  90                         nfd++;
  91                 UF_EXIT(ufp);
  92         }
  93         mutex_exit(&fip->fi_lock);
  94 
  95         v[0].p_type = PT_NOTE;
  96         v[0].p_flags = PF_R;
  97         v[0].p_filesz = (sizeof (Note) * (10 + 2 * nlwp + nzomb + nfd))
  98             + roundup(sizeof (psinfo_t), sizeof (Word))
  99             + roundup(sizeof (pstatus_t), sizeof (Word))
 100             + roundup(prgetprivsize(), sizeof (Word))
 101             + roundup(priv_get_implinfo_size(), sizeof (Word))
 102             + roundup(strlen(platform) + 1, sizeof (Word))
 103             + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word))
 104             + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word))
 105             + roundup(sizeof (utsname), sizeof (Word))
 106             + roundup(sizeof (core_content_t), sizeof (Word))
 107             + roundup(sizeof (prsecflags_t), sizeof (Word))
 108             + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word))
 109             + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word))

 110             + nfd * roundup(sizeof (prfdinfo_t), sizeof (Word));
 111 
 112         if (curproc->p_agenttp != NULL) {
 113                 v[0].p_filesz += sizeof (Note) +
 114                     roundup(sizeof (psinfo_t), sizeof (Word));
 115         }
 116 
 117         size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 118         pcrp = kmem_alloc(size, KM_SLEEP);
 119         prgetcred(p, pcrp);
 120         if (pcrp->pr_ngroups != 0) {
 121                 v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) +
 122                     sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word));
 123         } else {
 124                 v[0].p_filesz += sizeof (Note) +
 125                     roundup(sizeof (prcred_t), sizeof (Word));
 126         }
 127         kmem_free(pcrp, size);
 128 
 129 


 439 
 440 #if defined(__i386) || defined(__i386_COMPAT)
 441         mutex_enter(&p->p_ldtlock);
 442         ssdsize = prnldt(p) * sizeof (struct ssd);
 443         if (ssdsize != 0) {
 444                 ssd = kmem_alloc(ssdsize, KM_SLEEP);
 445                 prgetldt(p, ssd);
 446                 error = elfnote(vp, &offset, NT_LDT, ssdsize,
 447                     (caddr_t)ssd, rlimit, credp);
 448                 kmem_free(ssd, ssdsize);
 449         }
 450         mutex_exit(&p->p_ldtlock);
 451         if (error)
 452                 goto done;
 453 #endif  /* __i386 || defined(__i386_COMPAT) */
 454 
 455         nlwp = p->p_lwpcnt;
 456         nzomb = p->p_zombcnt;
 457         /* for each entry in the lwp directory ... */
 458         for (ldp = p->p_lwpdir; nlwp + nzomb != 0; ldp++) {

 459 
 460                 if ((lep = ldp->ld_entry) == NULL)   /* empty slot */
 461                         continue;
 462 
 463                 if ((t = lep->le_thread) != NULL) {  /* active lwp */
 464                         ASSERT(nlwp != 0);
 465                         nlwp--;
 466                         lwp = ttolwp(t);
 467                         mutex_enter(&p->p_lock);
 468                         prgetlwpsinfo(t, &bigwad->lwpsinfo);




 469                         mutex_exit(&p->p_lock);
 470                 } else {                                /* zombie lwp */
 471                         ASSERT(nzomb != 0);
 472                         nzomb--;
 473                         bzero(&bigwad->lwpsinfo, sizeof (bigwad->lwpsinfo));
 474                         bigwad->lwpsinfo.pr_lwpid = lep->le_lwpid;
 475                         bigwad->lwpsinfo.pr_state = SZOMB;
 476                         bigwad->lwpsinfo.pr_sname = 'Z';
 477                         bigwad->lwpsinfo.pr_start.tv_sec = lep->le_start;
 478                 }



 479                 error = elfnote(vp, &offset, NT_LWPSINFO,
 480                     sizeof (bigwad->lwpsinfo), (caddr_t)&bigwad->lwpsinfo,
 481                     rlimit, credp);
 482                 if (error)
 483                         goto done;

 484                 if (t == NULL)          /* nothing more to do for a zombie */
 485                         continue;
 486 
 487                 mutex_enter(&p->p_lock);
 488                 if (t == curthread) {
 489                         /*
 490                          * Modify t_whystop and lwp_cursig so it appears that
 491                          * the current LWP is stopped after faulting on the
 492                          * signal that caused the core dump.  As a result,
 493                          * prgetlwpstatus() will record that signal, the saved
 494                          * lwp_siginfo, and its signal handler in the core file
 495                          * status.  We restore lwp_cursig in case a subsequent
 496                          * signal was received while dumping core.
 497                          */
 498                         oldsig = lwp->lwp_cursig;
 499                         lwp->lwp_cursig = (uchar_t)sig;
 500                         t->t_whystop = PR_FAULTED;
 501 
 502                         prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 503                         bigwad->lwpstatus.pr_why = 0;
 504 
 505                         t->t_whystop = 0;
 506                         lwp->lwp_cursig = oldsig;
 507                 } else {
 508                         prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 509                 }
 510                 mutex_exit(&p->p_lock);
 511                 error = elfnote(vp, &offset, NT_LWPSTATUS,
 512                     sizeof (bigwad->lwpstatus), (caddr_t)&bigwad->lwpstatus,
 513                     rlimit, credp);
 514                 if (error)
 515                         goto done;
 516 





 517 #if defined(__sparc)
 518                 /*
 519                  * Unspilled SPARC register windows.
 520                  */
 521                 {
 522                         size_t size = prnwindows(lwp);
 523 
 524                         if (size != 0) {
 525                                 size = sizeof (gwindows_t) -
 526                                     (SPARC_MAXREGWINDOW - size) *
 527                                     sizeof (struct rwindow);
 528                                 prgetwindows(lwp, &bigwad->gwindows);
 529                                 error = elfnote(vp, &offset, NT_GWINDOWS,
 530                                     size, (caddr_t)&bigwad->gwindows,
 531                                     rlimit, credp);
 532                                 if (error)
 533                                         goto done;
 534                         }
 535                 }
 536                 /*




   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  29  * Copyright 2018 Joyent, Inc.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/param.h>
  34 #include <sys/thread.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/signal.h>
  37 #include <sys/cred.h>
  38 #include <sys/priv.h>
  39 #include <sys/user.h>
  40 #include <sys/file.h>
  41 #include <sys/errno.h>
  42 #include <sys/vnode.h>
  43 #include <sys/mode.h>
  44 #include <sys/vfs.h>
  45 #include <sys/mman.h>
  46 #include <sys/kmem.h>
  47 #include <sys/proc.h>
  48 #include <sys/pathname.h>
  49 #include <sys/cmn_err.h>


  77         int nfd;
  78         size_t size;
  79         prcred_t *pcrp;
  80         uf_info_t *fip;
  81         uf_entry_t *ufp;
  82         int fd;
  83 
  84         fip = P_FINFO(p);
  85         nfd = 0;
  86         mutex_enter(&fip->fi_lock);
  87         for (fd = 0; fd < fip->fi_nfiles; fd++) {
  88                 UF_ENTER(ufp, fip, fd);
  89                 if ((ufp->uf_file != NULL) && (ufp->uf_file->f_count > 0))
  90                         nfd++;
  91                 UF_EXIT(ufp);
  92         }
  93         mutex_exit(&fip->fi_lock);
  94 
  95         v[0].p_type = PT_NOTE;
  96         v[0].p_flags = PF_R;
  97         v[0].p_filesz = (sizeof (Note) * (10 + 3 * nlwp + nzomb + nfd))
  98             + roundup(sizeof (psinfo_t), sizeof (Word))
  99             + roundup(sizeof (pstatus_t), sizeof (Word))
 100             + roundup(prgetprivsize(), sizeof (Word))
 101             + roundup(priv_get_implinfo_size(), sizeof (Word))
 102             + roundup(strlen(platform) + 1, sizeof (Word))
 103             + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word))
 104             + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word))
 105             + roundup(sizeof (utsname), sizeof (Word))
 106             + roundup(sizeof (core_content_t), sizeof (Word))
 107             + roundup(sizeof (prsecflags_t), sizeof (Word))
 108             + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word))
 109             + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word))
 110             + nlwp * roundup(sizeof (prlwpname_t), sizeof (Word))
 111             + nfd * roundup(sizeof (prfdinfo_t), sizeof (Word));
 112 
 113         if (curproc->p_agenttp != NULL) {
 114                 v[0].p_filesz += sizeof (Note) +
 115                     roundup(sizeof (psinfo_t), sizeof (Word));
 116         }
 117 
 118         size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 119         pcrp = kmem_alloc(size, KM_SLEEP);
 120         prgetcred(p, pcrp);
 121         if (pcrp->pr_ngroups != 0) {
 122                 v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) +
 123                     sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word));
 124         } else {
 125                 v[0].p_filesz += sizeof (Note) +
 126                     roundup(sizeof (prcred_t), sizeof (Word));
 127         }
 128         kmem_free(pcrp, size);
 129 
 130 


 440 
 441 #if defined(__i386) || defined(__i386_COMPAT)
 442         mutex_enter(&p->p_ldtlock);
 443         ssdsize = prnldt(p) * sizeof (struct ssd);
 444         if (ssdsize != 0) {
 445                 ssd = kmem_alloc(ssdsize, KM_SLEEP);
 446                 prgetldt(p, ssd);
 447                 error = elfnote(vp, &offset, NT_LDT, ssdsize,
 448                     (caddr_t)ssd, rlimit, credp);
 449                 kmem_free(ssd, ssdsize);
 450         }
 451         mutex_exit(&p->p_ldtlock);
 452         if (error)
 453                 goto done;
 454 #endif  /* __i386 || defined(__i386_COMPAT) */
 455 
 456         nlwp = p->p_lwpcnt;
 457         nzomb = p->p_zombcnt;
 458         /* for each entry in the lwp directory ... */
 459         for (ldp = p->p_lwpdir; nlwp + nzomb != 0; ldp++) {
 460                 prlwpname_t name = { 0, };
 461 
 462                 if ((lep = ldp->ld_entry) == NULL)   /* empty slot */
 463                         continue;
 464 
 465                 if ((t = lep->le_thread) != NULL) {  /* active lwp */
 466                         ASSERT(nlwp != 0);
 467                         nlwp--;
 468                         lwp = ttolwp(t);
 469                         mutex_enter(&p->p_lock);
 470                         prgetlwpsinfo(t, &bigwad->lwpsinfo);
 471                         if (t->t_name != NULL) {
 472                                 (void) strlcpy(name.pr_lwpname, t->t_name,
 473                                     sizeof (name.pr_lwpname));
 474                         }
 475                         mutex_exit(&p->p_lock);
 476                 } else {                                /* zombie lwp */
 477                         ASSERT(nzomb != 0);
 478                         nzomb--;
 479                         bzero(&bigwad->lwpsinfo, sizeof (bigwad->lwpsinfo));
 480                         bigwad->lwpsinfo.pr_lwpid = lep->le_lwpid;
 481                         bigwad->lwpsinfo.pr_state = SZOMB;
 482                         bigwad->lwpsinfo.pr_sname = 'Z';
 483                         bigwad->lwpsinfo.pr_start.tv_sec = lep->le_start;
 484                 }
 485 
 486                 name.pr_lwpid = bigwad->lwpsinfo.pr_lwpid;
 487 
 488                 error = elfnote(vp, &offset, NT_LWPSINFO,
 489                     sizeof (bigwad->lwpsinfo), (caddr_t)&bigwad->lwpsinfo,
 490                     rlimit, credp);
 491                 if (error)
 492                         goto done;
 493 
 494                 if (t == NULL)          /* nothing more to do for a zombie */
 495                         continue;
 496 
 497                 mutex_enter(&p->p_lock);
 498                 if (t == curthread) {
 499                         /*
 500                          * Modify t_whystop and lwp_cursig so it appears that
 501                          * the current LWP is stopped after faulting on the
 502                          * signal that caused the core dump.  As a result,
 503                          * prgetlwpstatus() will record that signal, the saved
 504                          * lwp_siginfo, and its signal handler in the core file
 505                          * status.  We restore lwp_cursig in case a subsequent
 506                          * signal was received while dumping core.
 507                          */
 508                         oldsig = lwp->lwp_cursig;
 509                         lwp->lwp_cursig = (uchar_t)sig;
 510                         t->t_whystop = PR_FAULTED;
 511 
 512                         prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 513                         bigwad->lwpstatus.pr_why = 0;
 514 
 515                         t->t_whystop = 0;
 516                         lwp->lwp_cursig = oldsig;
 517                 } else {
 518                         prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 519                 }
 520                 mutex_exit(&p->p_lock);
 521                 error = elfnote(vp, &offset, NT_LWPSTATUS,
 522                     sizeof (bigwad->lwpstatus), (caddr_t)&bigwad->lwpstatus,
 523                     rlimit, credp);
 524                 if (error)
 525                         goto done;
 526 
 527                 if ((error = elfnote(vp, &offset, NT_LWPNAME, sizeof (name),
 528                     (caddr_t)&name, rlimit, credp)) != 0)
 529                         goto done;
 530 
 531 
 532 #if defined(__sparc)
 533                 /*
 534                  * Unspilled SPARC register windows.
 535                  */
 536                 {
 537                         size_t size = prnwindows(lwp);
 538 
 539                         if (size != 0) {
 540                                 size = sizeof (gwindows_t) -
 541                                     (SPARC_MAXREGWINDOW - size) *
 542                                     sizeof (struct rwindow);
 543                                 prgetwindows(lwp, &bigwad->gwindows);
 544                                 error = elfnote(vp, &offset, NT_GWINDOWS,
 545                                     size, (caddr_t)&bigwad->gwindows,
 546                                     rlimit, credp);
 547                                 if (error)
 548                                         goto done;
 549                         }
 550                 }
 551                 /*