So, apt has some support for doing updates on servers that mount /usr
read-only, in particular you can do:
DPkg {
// Auto re-mounting of a readonly /usr
Pre-Invoke {"mount -o remount,rw /usr";};
Post-Invoke {"mount -o remount,ro /usr";};
}
However this doesn't work quite frequently, since the umount fails
if there's any file in /usr that's been deleted (ie, was in a package
which has been updated), but is still being used (a /usr/lib/lib* that's
referenced by a long running program, or a /usr/bin/* program that's still
running, like apt-get or dselect). This is because the filesystem will
be modified when the file is closed, because the inode will be freed,
so it's obviously not read-only.
That's the theory AIUI, anyway.
To avoid this, we want to ensure that files aren't ever deleted after the
apt-get has finished. One way to do this is to keep a filename pointing
at all the inodes that can't be deleted. Unfortunately dpkg doesn't have
any hooks to do this. Fortunately, dpkg does. Two scripts are attached
which do this.
Basically, one script is called after apt finishes downloading which
makes hard links for *all* files under /usr that'll be replaced over the
upcoming upgrade (keeping a note of all of them), and the other script
is called after every dpkg run, and, theoretically on reboot or similar,
which goes through that list and unlinks any files that it reasonably can.
You can probably add something like this to your /etc/apt/apt.conf:
DPkg {
// Auto re-mounting of a readonly /usr
Pre-Install-Pkgs {"/home/aj/aptdpkgro.sh";};
Pre-Invoke {"mount -o remount,rw /usr";};
Post-Invoke {"/home/aj/aptdpkgclean.sh; mount -o remount,ro /usr";};
}
It's a long way from ideal, but it should probably work. It's not
particularly well tested.
Cheers,
aj
--
Anthony Towns <aj@humbug.org.au> <http://azure.humbug.org.au/~aj/>
I don't speak for anyone save myself. GPG signed mail preferred.
"Security here. Yes, maam. Yes. Groucho glasses. Yes, we're on it.
C'mon, guys. Somebody gave an aardvark a nose-cut: somebody who
can't deal with deconstructionist humor. Code Blue."
-- Mike Hoye,
see http://azure.humbug.org.au/~aj/armadillos.txt
#!/bin/sh
pathmatch="^/usr"
while read debname; do
pkg=$(dpkg --info $debname | sed -n 's/^ Package: *//p' | head -1)
(dpkg -L "$pkg" 2>/dev/null || true) | grep "$pathmatch" |
while read file; do
[ -f "$file" -a ! -L "$file" ] || continue
dir=`dirname "$file"`;
base=`basename "$file"`;
inode=`find "$file" -printf "%i\n"`
(cd "$dir" && ln "$base" ".${base}.dpkg-ro-used.$inode")
echo "$dir/.${base}.dpkg-ro-used.$inode"
done >>/var/lib/my_ro_hack.todel
done
#!/bin/sh
pathmatch="^/usr"
cat /var/lib/my_ro_hack.todel | while read file; do
[ -f "$file" ] || continue
N1=`find "$file" -printf "%i\n"`
b=`basename $file`; d=`dirname $file`
XF="${b#.}"; XF="$d/${XF%.dpkg-ro-used.*}"
N2=`find "$XF" -printf "%i\n"`
if [ "$N1" != "$N2" ] && ! fuser -s "$file"; then
rm -f "$file"
else
echo "$file"
fi
done >/var/lib/my_ro_hack.todel.new
mv /var/lib/my_ro_hack.todel.new /var/lib/my_ro_hack.todel
Attachment:
pgpHcVv7Ph4tu.pgp
Description: PGP signature