Mercurial > illumos > illumos-gate
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) { |