enter_chroot: introduce a sync process that synchronizes given files between chroot and host

Currently used for resolv.conf and hosts, because these files can
change during the lifetime of a chroot, for example on computers
with more dynamic network (laptops).

While this creates a persistent process in the background for the
sole purpose of syncing files, the performance impact is negligible.

BUG=12316
TEST=below
1) enter_chroot once+quit, many times + quit, verify correct exit
behaviour
2) enter_chroot, modify host resolv.conf, see chroot being updated

Change-Id: I26573570c027acc2c214a00838a6f982a7585b13

R=robotboy@chromium.org,dparker@chromium.org,sosa@chromium.org

Review URL: http://codereview.chromium.org/6720005
This commit is contained in:
Zdenek Behan 2011-04-07 00:37:20 +02:00
parent b3cf233d4c
commit e28239d294

View File

@ -129,6 +129,7 @@ SAVED_AUTOMOUNT_PREF_FILE="/tmp/.automount_pref"
sudo chmod 0777 "$FLAGS_chroot/var/lock" sudo chmod 0777 "$FLAGS_chroot/var/lock"
LOCKFILE="$FLAGS_chroot/var/lock/enter_chroot" LOCKFILE="$FLAGS_chroot/var/lock/enter_chroot"
SYNCERPIDFILE="${FLAGS_chroot}/var/tmp/enter_chroot_sync.pid"
function ensure_mounted { function ensure_mounted {
@ -153,12 +154,46 @@ function ensure_mounted {
fi fi
} }
function env_sync_proc {
# This function runs and performs periodic updates to the chroot env, if
# necessary.
local poll_interval=10
local sync_files="etc/resolv.conf etc/hosts"
# Make sure the synced files are writable by normal user, so that we
# don't have to sudo inside the loop.
for file in ${sync_files}; do
sudo chown ${USER} ${FLAGS_chroot}/${file} 1>&2
done
while true; do
# Sync files
for file in ${sync_files}; do
if ! cmp /${file} ${FLAGS_chroot}/${file} &> /dev/null; then
cp -f /${file} ${FLAGS_chroot}/${file}
fi
done
sleep ${poll_interval}
done
}
function setup_env { function setup_env {
# Validate sudo timestamp before entering the critical section so that we # Validate sudo timestamp before entering the critical section so that we
# don't stall for a password while we have the lockfile. # don't stall for a password while we have the lockfile.
# Don't use sudo -v since that has issues on machines w/ no password. # Don't use sudo -v since that has issues on machines w/ no password.
sudo echo "" > /dev/null 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 flock 200
echo $$ >> "$LOCKFILE" echo $$ >> "$LOCKFILE"
@ -283,6 +318,9 @@ function teardown_env {
debug "At least one other pid is running in the chroot, so not" debug "At least one other pid is running in the chroot, so not"
debug "tearing down env." debug "tearing down env."
else else
debug "Stopping syncer process"
kill $(cat "${SYNCERPIDFILE}")
MOUNTED_PATH=$(readlink -f "$FLAGS_chroot") MOUNTED_PATH=$(readlink -f "$FLAGS_chroot")
debug "Unmounting chroot environment." debug "Unmounting chroot environment."
# sort the list of mounts in reverse order, to ensure umount of # sort the list of mounts in reverse order, to ensure umount of