Mercurial > illumos > illumos-gate
changeset 2949:5581081d0989
6481326 lx zone install sometimes hangs
author | nn35248 |
---|---|
date | Fri, 20 Oct 2006 07:07:59 -0700 |
parents | c89bd1dbe6d0 |
children | 449abdd74783 |
files | usr/src/lib/brand/lx/lx_brand/common/clone.c usr/src/lib/brand/lx/lx_brand/common/fork.c usr/src/lib/brand/lx/lx_brand/common/lx_brand.c usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h |
diffstat | 4 files changed, 32 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/brand/lx/lx_brand/common/clone.c Thu Oct 19 21:21:08 2006 -0700 +++ b/usr/src/lib/brand/lx/lx_brand/common/clone.c Fri Oct 20 07:07:59 2006 -0700 @@ -395,6 +395,8 @@ is_vforked--; } else { rval = fork1(); + if (rval == 0 && lx_is_rpm) + sleep(lx_rpm_delay); } if (rval > 0 && (flags & LX_CLONE_PARENT_SETTID))
--- a/usr/src/lib/brand/lx/lx_brand/common/fork.c Thu Oct 19 21:21:08 2006 -0700 +++ b/usr/src/lib/brand/lx/lx_brand/common/fork.c Fri Oct 20 07:07:59 2006 -0700 @@ -43,6 +43,9 @@ { int ret = fork1(); + if (ret == 0 && lx_is_rpm) + sleep(lx_rpm_delay); + return (ret == -1 ? -errno : ret); }
--- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c Thu Oct 19 21:21:08 2006 -0700 +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c Fri Oct 20 07:07:59 2006 -0700 @@ -51,6 +51,7 @@ #include <fcntl.h> #include <synch.h> #include <libelf.h> +#include <libgen.h> #include <pthread.h> #include <utime.h> #include <dirent.h> @@ -169,6 +170,8 @@ static uintptr_t stack_bottom; int lx_install = 0; /* install mode enabled if non-zero */ +boolean_t lx_is_rpm = B_FALSE; +int lx_rpm_delay = 1; int lx_strict = 0; /* "strict" mode enabled if non-zero */ int lx_verbose = 0; /* verbose mode enabled if non-zero */ int lx_debug_enabled = 0; /* debugging output enabled if non-zero */ @@ -693,6 +696,24 @@ lx_debug("branding myself and setting handler to 0x%p", (void *)lx_handler_table); + /* + * The version of rpm that ships with CentOS/RHEL 3.x has a race + * condition in it. If it creates a child process to run a + * post-install script, and that child process completes too + * quickly, it will disappear before the parent notices. This + * causes the parent to hang forever waiting for the already dead + * child to die. I'm sure there's a Lazarus joke buried in here + * somewhere. + * + * Anyway, as a workaround, we make every child of an 'rpm' process + * sleep for 1 second, giving the parent a chance to enter its + * wait-for-the-child-to-die loop. Thay may be the hackiest trick + * in all of our Linux emulation code - and that's saying + * something. + */ + if (strcmp("rpm", basename(argv[0])) == NULL) + lx_is_rpm = B_TRUE; + reg.lxbr_version = LX_VERSION; reg.lxbr_handler = (void *)&lx_handler_table; reg.lxbr_tracehandler = (void *)&lx_handler_trace_table;
--- a/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h Thu Oct 19 21:21:08 2006 -0700 +++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h Fri Oct 20 07:07:59 2006 -0700 @@ -45,6 +45,12 @@ extern pid_t zoneinit_pid; /* + * Support for the unfortunate RPM race condition workaround. + */ +extern int lx_rpm_delay; +extern boolean_t lx_is_rpm; + +/* * Values Linux expects for init */ #define LX_INIT_PGID 0