Mercurial > illumos > illumos-gate
changeset 12621:67c30502d363
6942464 panic : vp->v_rdcnt > 0, file: ../../common/fs/vnode.c, line: 3177 while testing on s10 zones
author | <gerald.jelinek@sun.com> |
---|---|
date | Mon, 14 Jun 2010 12:34:59 -0600 |
parents | 12fcd99a642d |
children | e018bcda4475 |
files | usr/src/uts/common/os/brand.c |
diffstat | 1 files changed, 45 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/os/brand.c Mon Jun 14 10:04:10 2010 -0600 +++ b/usr/src/uts/common/os/brand.c Mon Jun 14 12:34:59 2010 -0600 @@ -580,6 +580,17 @@ child->p_brand_data = spd; } +static void +restoreexecenv(struct execenv *ep, stack_t *sp) +{ + klwp_t *lwp = ttolwp(curthread); + + setexecenv(ep); + lwp->lwp_sigaltstack.ss_sp = sp->ss_sp; + lwp->lwp_sigaltstack.ss_size = sp->ss_size; + lwp->lwp_sigaltstack.ss_flags = sp->ss_flags; +} + /*ARGSUSED*/ int brand_solaris_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, @@ -595,7 +606,11 @@ int interp; int i, err; struct execenv env; + struct execenv origenv; + stack_t orig_sigaltstack; struct user *up = PTOU(curproc); + proc_t *p = ttoproc(curthread); + klwp_t *lwp = ttolwp(curthread); brand_proc_data_t *spd; brand_elf_data_t sed, *sedp; char *linker; @@ -630,6 +645,26 @@ return (err); } + /* + * The following elf{32}exec call changes the execenv in the proc + * struct which includes changing the p_exec member to be the vnode + * for the brand library (e.g. /.SUNWnative/usr/lib/s10_brand.so.1). + * We will eventually set the p_exec member to be the vnode for the new + * executable when we call setexecenv(). However, if we get an error + * before that call we need to restore the execenv to its original + * values so that when we return to the caller fop_close() works + * properly while cleaning up from the failed exec(). Restoring the + * original value will also properly decrement the 2nd VN_RELE that we + * took on the brand library. + */ + origenv.ex_bssbase = p->p_bssbase; + origenv.ex_brkbase = p->p_brkbase; + origenv.ex_brksize = p->p_brksize; + origenv.ex_vp = p->p_exec; + orig_sigaltstack.ss_sp = lwp->lwp_sigaltstack.ss_sp; + orig_sigaltstack.ss_size = lwp->lwp_sigaltstack.ss_size; + orig_sigaltstack.ss_flags = lwp->lwp_sigaltstack.ss_flags; + if (args->to_model == DATAMODEL_NATIVE) { err = elfexec(nvp, uap, args, idatap, level + 1, execsz, setid, exec_file, cred, brand_action); @@ -641,8 +676,10 @@ } #endif /* _LP64 */ VN_RELE(nvp); - if (err != 0) + if (err != 0) { + restoreexecenv(&origenv, &orig_sigaltstack); return (err); + } /* * The u_auxv veCTors are set up by elfexec to point to the @@ -699,8 +736,10 @@ uphdr_vaddr = uphdr_vaddr32; } #endif /* _LP64 */ - if (err != 0) + if (err != 0) { + restoreexecenv(&origenv, &orig_sigaltstack); return (err); + } /* * Save off the important properties of the executable. The @@ -735,6 +774,7 @@ if ((err = lookupname(linker, UIO_SYSSPACE, FOLLOW, NULLVPP, &nvp)) != 0) { uprintf("%s: not found.", brandlinker); + restoreexecenv(&origenv, &orig_sigaltstack); return (err); } if (args->to_model == DATAMODEL_NATIVE) { @@ -758,8 +798,10 @@ } #endif /* _LP64 */ VN_RELE(nvp); - if (err != 0) + if (err != 0) { + restoreexecenv(&origenv, &orig_sigaltstack); return (err); + } /* * Now that we know the base address of the brand's