Fix race condition when starting env_syncer in enter_chroot.sh.

Sometimes, two processes might start the env_syncer at the same time.
If this occurs, then the pid file will get overwritten and one of the
processes won't be killed.

I've also fixed the env_syncer to properly daemonize, such that
cbuildbot won't wait on the env_syncer to be killed before exiting.
This requires closing stdin, stderr, and stdout.

BUG=chromium-os:17680
TEST=Reproduce hang, and verify that this fixes the hang. Verify that
     multiple chroots can be entered at the same time and that the
     env_syncer is killed when the last chroot exits. Verify that
     cbuildbot is not kept hanging even if the env_syncer doesn't
     exit.

Change-Id: I3cb9fbdf47a406e818e12cf91593b8e3481aa578
Reviewed-on: http://gerrit.chromium.org/gerrit/4232
Reviewed-by: Ryan Cui <rcui@chromium.org>
Tested-by: David James <davidjames@chromium.org>
This commit is contained in:
David James 2011-07-15 19:54:16 -07:00
parent 342f156c35
commit 412b902b0e

View File

@ -136,6 +136,10 @@ function env_sync_proc {
sudo chown ${USER} ${FLAGS_chroot}/${file} 1>&2
done
# Drop stdin, stderr, stdout, and chroot lock.
# This is needed for properly daemonizing the process.
exec 0>&- 1>&- 2>&- 200>&-
while true; do
# Sync files
for file in ${sync_files}; do
@ -186,19 +190,20 @@ function setup_env {
# Don't use sudo -v since that has issues on machines w/ no password.
sudo echo "" > /dev/null
# Syncer proc, but only the first time
if ! [ -f "${SYNCERPIDFILE}" ] || \
! [ -d /proc/$(cat "${SYNCERPIDFILE}") ]; then
debug "Starting sync process"
env_sync_proc &
echo $! > "${SYNCERPIDFILE}"
disown $!
fi
(
flock 200
echo $$ >> "$LOCKFILE"
# If there isn't a syncer daemon started already, start one. This daemon
# is killed by the enter_chroot that exits last.
if ! [ -f "${SYNCERPIDFILE}" ] || \
! [ -d /proc/$(cat "${SYNCERPIDFILE}") ]; then
debug "Starting sync process"
env_sync_proc &
echo $! > "${SYNCERPIDFILE}"
disown $!
fi
debug "Mounting chroot environment."
ensure_mounted none "-t proc" /proc
ensure_mounted none "-t sysfs" /sys