Mercurial > illumos > illumos-gate
diff usr/src/uts/common/exec/elf/elf_notes.c @ 13875:f128a109e6d2
3294 pfiles postmortem support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Eric Schrock <eric.schrock@delphix.com>
author | Garrett D'Amore <garrett@damore.org> |
---|---|
date | Fri, 02 Nov 2012 09:48:42 -0700 |
parents | 68f95e015346 |
children | c1f1ea4feeb1 |
line wrap: on
line diff
--- a/usr/src/uts/common/exec/elf/elf_notes.c Tue Oct 23 12:58:35 2012 -0400 +++ b/usr/src/uts/common/exec/elf/elf_notes.c Fri Nov 02 09:48:42 2012 -0700 @@ -24,7 +24,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. + */ #include <sys/types.h> #include <sys/param.h> @@ -34,8 +36,11 @@ #include <sys/cred.h> #include <sys/priv.h> #include <sys/user.h> +#include <sys/file.h> #include <sys/errno.h> #include <sys/vnode.h> +#include <sys/mode.h> +#include <sys/vfs.h> #include <sys/mman.h> #include <sys/kmem.h> #include <sys/proc.h> @@ -57,6 +62,7 @@ #include <sys/modctl.h> #include <sys/systeminfo.h> #include <sys/machelf.h> +#include <sys/sunddi.h> #include "elf_impl.h" #if defined(__i386) || defined(__i386_COMPAT) #include <sys/sysi86.h> @@ -67,12 +73,27 @@ { int nlwp = p->p_lwpcnt; int nzomb = p->p_zombcnt; + int nfd; size_t size; prcred_t *pcrp; + uf_info_t *fip; + uf_entry_t *ufp; + int fd; + + fip = P_FINFO(p); + nfd = 0; + mutex_enter(&fip->fi_lock); + for (fd = 0; fd < fip->fi_nfiles; fd++) { + UF_ENTER(ufp, fip, fd); + if ((ufp->uf_file != NULL) && (ufp->uf_file->f_count > 0)) + nfd++; + UF_EXIT(ufp); + } + mutex_exit(&fip->fi_lock); v[0].p_type = PT_NOTE; v[0].p_flags = PF_R; - v[0].p_filesz = (sizeof (Note) * (9 + 2 * nlwp + nzomb)) + v[0].p_filesz = (sizeof (Note) * (9 + 2 * nlwp + nzomb + nfd)) + roundup(sizeof (psinfo_t), sizeof (Word)) + roundup(sizeof (pstatus_t), sizeof (Word)) + roundup(prgetprivsize(), sizeof (Word)) @@ -83,7 +104,8 @@ + roundup(sizeof (utsname), sizeof (Word)) + roundup(sizeof (core_content_t), sizeof (Word)) + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word)) - + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word)); + + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word)) + + nfd * roundup(sizeof (prfdinfo_t), sizeof (Word)); size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); pcrp = kmem_alloc(size, KM_SLEEP); @@ -97,6 +119,7 @@ } kmem_free(pcrp, size); + #if defined(__i386) || defined(__i386_COMPAT) mutex_enter(&p->p_ldtlock); size = prnldt(p) * sizeof (struct ssd); @@ -159,7 +182,7 @@ size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); size_t psize = prgetprivsize(); size_t bigsize = MAX(psize, MAX(sizeof (*bigwad), - MAX(xregsize, crsize))); + MAX(xregsize, crsize))); priv_impl_info_t *prii; @@ -173,6 +196,10 @@ int nzomb; int error; uchar_t oldsig; + uf_info_t *fip; + int fd; + vnode_t *vroot; + #if defined(__i386) || defined(__i386_COMPAT) struct ssd *ssd; size_t ssdsize; @@ -293,6 +320,89 @@ if (error) goto done; + + /* open file table */ + vroot = PTOU(p)->u_rdir; + if (vroot == NULL) + vroot = rootdir; + + VN_HOLD(vroot); + + fip = P_FINFO(p); + + for (fd = 0; fd < fip->fi_nfiles; fd++) { + uf_entry_t *ufp; + vnode_t *fvp; + struct file *fp; + vattr_t vattr; + prfdinfo_t fdinfo; + + bzero(&fdinfo, sizeof (fdinfo)); + + mutex_enter(&fip->fi_lock); + UF_ENTER(ufp, fip, fd); + if (((fp = ufp->uf_file) == NULL) || (fp->f_count < 1)) { + UF_EXIT(ufp); + mutex_exit(&fip->fi_lock); + continue; + } + + fdinfo.pr_fd = fd; + fdinfo.pr_fdflags = ufp->uf_flag; + fdinfo.pr_fileflags = fp->f_flag2; + fdinfo.pr_fileflags <<= 16; + fdinfo.pr_fileflags |= fp->f_flag; + if ((fdinfo.pr_fileflags & (FSEARCH | FEXEC)) == 0) + fdinfo.pr_fileflags += FOPEN; + fdinfo.pr_offset = fp->f_offset; + + + fvp = fp->f_vnode; + VN_HOLD(fvp); + UF_EXIT(ufp); + mutex_exit(&fip->fi_lock); + + /* + * There are some vnodes that have no corresponding + * path. Its reasonable for this to fail, in which + * case the path will remain an empty string. + */ + (void) vnodetopath(vroot, fvp, fdinfo.pr_path, + sizeof (fdinfo.pr_path), credp); + + error = VOP_GETATTR(fvp, &vattr, 0, credp, NULL); + if (error != 0) { + VN_RELE(fvp); + VN_RELE(vroot); + goto done; + } + + if (fvp->v_type == VSOCK) + fdinfo.pr_fileflags |= sock_getfasync(fvp); + + VN_RELE(fvp); + + /* + * This logic mirrors fstat(), which we cannot use + * directly, as it calls copyout(). + */ + fdinfo.pr_major = getmajor(vattr.va_fsid); + fdinfo.pr_minor = getminor(vattr.va_fsid); + fdinfo.pr_ino = (ino64_t)vattr.va_nodeid; + fdinfo.pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode; + fdinfo.pr_uid = vattr.va_uid; + fdinfo.pr_gid = vattr.va_gid; + fdinfo.pr_rmajor = getmajor(vattr.va_rdev); + fdinfo.pr_rminor = getminor(vattr.va_rdev); + fdinfo.pr_size = (off64_t)vattr.va_size; + + error = elfnote(vp, &offset, NT_FDINFO, + sizeof (fdinfo), &fdinfo, rlimit, credp); + if (error) { + goto done; + } + } + #if defined(__i386) || defined(__i386_COMPAT) mutex_enter(&p->p_ldtlock); ssdsize = prnldt(p) * sizeof (struct ssd);