comparison 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
comparison
equal deleted inserted replaced
13874:cab67b95c26b 13875:f128a109e6d2
22 /* 22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms. 24 * Use is subject to license terms.
25 */ 25 */
26 26
27 #pragma ident "%Z%%M% %I% %E% SMI" 27 /*
28 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
29 */
28 30
29 #include <sys/types.h> 31 #include <sys/types.h>
30 #include <sys/param.h> 32 #include <sys/param.h>
31 #include <sys/thread.h> 33 #include <sys/thread.h>
32 #include <sys/sysmacros.h> 34 #include <sys/sysmacros.h>
33 #include <sys/signal.h> 35 #include <sys/signal.h>
34 #include <sys/cred.h> 36 #include <sys/cred.h>
35 #include <sys/priv.h> 37 #include <sys/priv.h>
36 #include <sys/user.h> 38 #include <sys/user.h>
39 #include <sys/file.h>
37 #include <sys/errno.h> 40 #include <sys/errno.h>
38 #include <sys/vnode.h> 41 #include <sys/vnode.h>
42 #include <sys/mode.h>
43 #include <sys/vfs.h>
39 #include <sys/mman.h> 44 #include <sys/mman.h>
40 #include <sys/kmem.h> 45 #include <sys/kmem.h>
41 #include <sys/proc.h> 46 #include <sys/proc.h>
42 #include <sys/pathname.h> 47 #include <sys/pathname.h>
43 #include <sys/cmn_err.h> 48 #include <sys/cmn_err.h>
55 #include <vm/as.h> 60 #include <vm/as.h>
56 #include <vm/rm.h> 61 #include <vm/rm.h>
57 #include <sys/modctl.h> 62 #include <sys/modctl.h>
58 #include <sys/systeminfo.h> 63 #include <sys/systeminfo.h>
59 #include <sys/machelf.h> 64 #include <sys/machelf.h>
65 #include <sys/sunddi.h>
60 #include "elf_impl.h" 66 #include "elf_impl.h"
61 #if defined(__i386) || defined(__i386_COMPAT) 67 #if defined(__i386) || defined(__i386_COMPAT)
62 #include <sys/sysi86.h> 68 #include <sys/sysi86.h>
63 #endif 69 #endif
64 70
65 void 71 void
66 setup_note_header(Phdr *v, proc_t *p) 72 setup_note_header(Phdr *v, proc_t *p)
67 { 73 {
68 int nlwp = p->p_lwpcnt; 74 int nlwp = p->p_lwpcnt;
69 int nzomb = p->p_zombcnt; 75 int nzomb = p->p_zombcnt;
76 int nfd;
70 size_t size; 77 size_t size;
71 prcred_t *pcrp; 78 prcred_t *pcrp;
79 uf_info_t *fip;
80 uf_entry_t *ufp;
81 int fd;
82
83 fip = P_FINFO(p);
84 nfd = 0;
85 mutex_enter(&fip->fi_lock);
86 for (fd = 0; fd < fip->fi_nfiles; fd++) {
87 UF_ENTER(ufp, fip, fd);
88 if ((ufp->uf_file != NULL) && (ufp->uf_file->f_count > 0))
89 nfd++;
90 UF_EXIT(ufp);
91 }
92 mutex_exit(&fip->fi_lock);
72 93
73 v[0].p_type = PT_NOTE; 94 v[0].p_type = PT_NOTE;
74 v[0].p_flags = PF_R; 95 v[0].p_flags = PF_R;
75 v[0].p_filesz = (sizeof (Note) * (9 + 2 * nlwp + nzomb)) 96 v[0].p_filesz = (sizeof (Note) * (9 + 2 * nlwp + nzomb + nfd))
76 + roundup(sizeof (psinfo_t), sizeof (Word)) 97 + roundup(sizeof (psinfo_t), sizeof (Word))
77 + roundup(sizeof (pstatus_t), sizeof (Word)) 98 + roundup(sizeof (pstatus_t), sizeof (Word))
78 + roundup(prgetprivsize(), sizeof (Word)) 99 + roundup(prgetprivsize(), sizeof (Word))
79 + roundup(priv_get_implinfo_size(), sizeof (Word)) 100 + roundup(priv_get_implinfo_size(), sizeof (Word))
80 + roundup(strlen(platform) + 1, sizeof (Word)) 101 + roundup(strlen(platform) + 1, sizeof (Word))
81 + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word)) 102 + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word))
82 + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word)) 103 + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word))
83 + roundup(sizeof (utsname), sizeof (Word)) 104 + roundup(sizeof (utsname), sizeof (Word))
84 + roundup(sizeof (core_content_t), sizeof (Word)) 105 + roundup(sizeof (core_content_t), sizeof (Word))
85 + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word)) 106 + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word))
86 + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word)); 107 + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word))
108 + nfd * roundup(sizeof (prfdinfo_t), sizeof (Word));
87 109
88 size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); 110 size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
89 pcrp = kmem_alloc(size, KM_SLEEP); 111 pcrp = kmem_alloc(size, KM_SLEEP);
90 prgetcred(p, pcrp); 112 prgetcred(p, pcrp);
91 if (pcrp->pr_ngroups != 0) { 113 if (pcrp->pr_ngroups != 0) {
94 } else { 116 } else {
95 v[0].p_filesz += sizeof (Note) + 117 v[0].p_filesz += sizeof (Note) +
96 roundup(sizeof (prcred_t), sizeof (Word)); 118 roundup(sizeof (prcred_t), sizeof (Word));
97 } 119 }
98 kmem_free(pcrp, size); 120 kmem_free(pcrp, size);
121
99 122
100 #if defined(__i386) || defined(__i386_COMPAT) 123 #if defined(__i386) || defined(__i386_COMPAT)
101 mutex_enter(&p->p_ldtlock); 124 mutex_enter(&p->p_ldtlock);
102 size = prnldt(p) * sizeof (struct ssd); 125 size = prnldt(p) * sizeof (struct ssd);
103 mutex_exit(&p->p_ldtlock); 126 mutex_exit(&p->p_ldtlock);
157 180
158 size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0; 181 size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0;
159 size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); 182 size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
160 size_t psize = prgetprivsize(); 183 size_t psize = prgetprivsize();
161 size_t bigsize = MAX(psize, MAX(sizeof (*bigwad), 184 size_t bigsize = MAX(psize, MAX(sizeof (*bigwad),
162 MAX(xregsize, crsize))); 185 MAX(xregsize, crsize)));
163 186
164 priv_impl_info_t *prii; 187 priv_impl_info_t *prii;
165 188
166 lwpdir_t *ldp; 189 lwpdir_t *ldp;
167 lwpent_t *lep; 190 lwpent_t *lep;
171 int i; 194 int i;
172 int nlwp; 195 int nlwp;
173 int nzomb; 196 int nzomb;
174 int error; 197 int error;
175 uchar_t oldsig; 198 uchar_t oldsig;
199 uf_info_t *fip;
200 int fd;
201 vnode_t *vroot;
202
176 #if defined(__i386) || defined(__i386_COMPAT) 203 #if defined(__i386) || defined(__i386_COMPAT)
177 struct ssd *ssd; 204 struct ssd *ssd;
178 size_t ssdsize; 205 size_t ssdsize;
179 #endif /* __i386 || __i386_COMPAT */ 206 #endif /* __i386 || __i386_COMPAT */
180 207
290 error = elfnote(vp, &offset, NT_ZONENAME, 317 error = elfnote(vp, &offset, NT_ZONENAME,
291 strlen(p->p_zone->zone_name) + 1, p->p_zone->zone_name, 318 strlen(p->p_zone->zone_name) + 1, p->p_zone->zone_name,
292 rlimit, credp); 319 rlimit, credp);
293 if (error) 320 if (error)
294 goto done; 321 goto done;
322
323
324 /* open file table */
325 vroot = PTOU(p)->u_rdir;
326 if (vroot == NULL)
327 vroot = rootdir;
328
329 VN_HOLD(vroot);
330
331 fip = P_FINFO(p);
332
333 for (fd = 0; fd < fip->fi_nfiles; fd++) {
334 uf_entry_t *ufp;
335 vnode_t *fvp;
336 struct file *fp;
337 vattr_t vattr;
338 prfdinfo_t fdinfo;
339
340 bzero(&fdinfo, sizeof (fdinfo));
341
342 mutex_enter(&fip->fi_lock);
343 UF_ENTER(ufp, fip, fd);
344 if (((fp = ufp->uf_file) == NULL) || (fp->f_count < 1)) {
345 UF_EXIT(ufp);
346 mutex_exit(&fip->fi_lock);
347 continue;
348 }
349
350 fdinfo.pr_fd = fd;
351 fdinfo.pr_fdflags = ufp->uf_flag;
352 fdinfo.pr_fileflags = fp->f_flag2;
353 fdinfo.pr_fileflags <<= 16;
354 fdinfo.pr_fileflags |= fp->f_flag;
355 if ((fdinfo.pr_fileflags & (FSEARCH | FEXEC)) == 0)
356 fdinfo.pr_fileflags += FOPEN;
357 fdinfo.pr_offset = fp->f_offset;
358
359
360 fvp = fp->f_vnode;
361 VN_HOLD(fvp);
362 UF_EXIT(ufp);
363 mutex_exit(&fip->fi_lock);
364
365 /*
366 * There are some vnodes that have no corresponding
367 * path. Its reasonable for this to fail, in which
368 * case the path will remain an empty string.
369 */
370 (void) vnodetopath(vroot, fvp, fdinfo.pr_path,
371 sizeof (fdinfo.pr_path), credp);
372
373 error = VOP_GETATTR(fvp, &vattr, 0, credp, NULL);
374 if (error != 0) {
375 VN_RELE(fvp);
376 VN_RELE(vroot);
377 goto done;
378 }
379
380 if (fvp->v_type == VSOCK)
381 fdinfo.pr_fileflags |= sock_getfasync(fvp);
382
383 VN_RELE(fvp);
384
385 /*
386 * This logic mirrors fstat(), which we cannot use
387 * directly, as it calls copyout().
388 */
389 fdinfo.pr_major = getmajor(vattr.va_fsid);
390 fdinfo.pr_minor = getminor(vattr.va_fsid);
391 fdinfo.pr_ino = (ino64_t)vattr.va_nodeid;
392 fdinfo.pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode;
393 fdinfo.pr_uid = vattr.va_uid;
394 fdinfo.pr_gid = vattr.va_gid;
395 fdinfo.pr_rmajor = getmajor(vattr.va_rdev);
396 fdinfo.pr_rminor = getminor(vattr.va_rdev);
397 fdinfo.pr_size = (off64_t)vattr.va_size;
398
399 error = elfnote(vp, &offset, NT_FDINFO,
400 sizeof (fdinfo), &fdinfo, rlimit, credp);
401 if (error) {
402 goto done;
403 }
404 }
295 405
296 #if defined(__i386) || defined(__i386_COMPAT) 406 #if defined(__i386) || defined(__i386_COMPAT)
297 mutex_enter(&p->p_ldtlock); 407 mutex_enter(&p->p_ldtlock);
298 ssdsize = prnldt(p) * sizeof (struct ssd); 408 ssdsize = prnldt(p) * sizeof (struct ssd);
299 if (ssdsize != 0) { 409 if (ssdsize != 0) {