dpkg db ro and rw layers synchronized
I posted about sync'ing PKGget with APT earlier today:
- Improve PKGget sync with APT — August 20, 2025
...but that sync code is far from complete.
When easyOS is updated to a new version, there will be a mismatch of the dpkg database information in /var/lib/dpkg/info and /var/lib/dpkg/status, on the read-write and read-only aufs levels.
That is, the above-mentioned folders and files get saved in /mnt/wkg/.session at power-off, reloaded at next bootup. You install a .deb, fine, it gets added into the dpkg database, and also saved in .session.
However, when you bootup a new version of Easy, the dpkg database information in /var/lib/dpkg in easy.sfs will no longer match what is in .session. There may be a package that was in easy.sfs, but no longer. Or, the latest easy.sfs may have a new package. Or, a package in easy.sfs may be a new version.
All of this information at the easy.sfs level is hidden, because the .session folder is on top, in the aufs layers. When you run various tests, there will be mismatches reported, for example:
# dpkg --audit
# /usr/bin/apt list --upgradable
I have written a script that handles all of these situations and sync's the dpkg database at the top layer with the easy.sfs layer. There is a new script, /var/local/petget/alias/sync-dpkg-layers:
#!/bin/bash
#bootup new version of easyos, there will be discrepancies between /var/lib/dpkg
#in /mnt/wkg/.session (and in containers .session) and in easy.sfs
#--new or removed pkgs in easy.sfs, version changes.
export LANG=C
mkdir -p /tmp/petget
#mismatch could be the 'status' files...
RWstatus="$(grep '^Package: ' /var/lib/dpkg/status | cut -f 2 -d ' ' | sort)"
ROstatus="$(grep '^Package: ' /mnt/.easy_ro/easy_sfs/var/lib/dpkg/status | cut -f 2 -d ' ' | sort)"
echo -n "$RWstatus" > /tmp/petget/dpkg-RWstatus
echo -n "$ROstatus" > /tmp/petget/dpkg-ROstatus
#find pkgs in rw layer, not in ro...
NEWstatus="$(grep -v -F -x -f /tmp/petget/dpkg-ROstatus /tmp/petget/dpkg-RWstatus)"
#ex:
#attr
#debootstrap
#gir1.2-ayatanaappindicator3-0.1
#grub-common
#libayatana-appindicator3-1
#libayatana-ido3-0.4-0
#libayatana-indicator3-7
#libdbusmenu-glib4
#libdbusmenu-gtk3-4
#memtest86+
#...some of these are user-installed, some no longer in easy.sfs
MISSstatus="$(grep -v -F -x -f /tmp/petget/dpkg-RWstatus /tmp/petget/dpkg-ROstatus)"
#ex:
#ccrypt
#firmware-intel-sound
#geany
#geany-common
#libaudio2
#libdaemon0
#libgif7
#libglu1-mesa
#libglut3.12
#libimobiledevice-glue-1.0-0
#libmtp9t64
#libmtp-common
#libnma0
#libnma-common
#libnma-headers
#libnotify-bin
#libplist-2.0-4
#libturbojpeg0
#libusbmuxd-2.0-7
#mobile-broadband-provider-info
#network-manager-applet
#network-manager-gnome
#nm-connection-editor
#...these are new in easy.sfs
##############
#handle NEWstatus...
for aNEW in ${NEWstatus}
do
[ -z "$aNEW" ] && continue
grep -q -F "|${aNEW}|" /root/.packages/user-installed-packages
[ $? -eq 0 ] && continue
#want to purge it from db, as no longer exists...
sed -i "/^Package: ${aNEW}$/,/^$/d" /var/lib/dpkg/status
rm -f /var/lib/dpkg/info/${aNEW}:* 2>/dev/null
rm -f /var/lib/dpkg/info/${aNEW}.* 2>/dev/null
done
##############
#handle MISSstatus...
for aMISS in ${MISSstatus}
do
[ -z "$aMISS" ] && continue
#extract paragraph from ro-layer, append on rw-layer...
P1="$(sed -n "/^Package: ${aMISS}$/,/^$/p" /mnt/.easy_ro/easy_sfs/var/lib/dpkg/status)"
echo "${P1}
" >> /var/lib/dpkg/status
done
####################################
#handle pkg version change...
ROpkgs="$(grep -E '^Package: |^Version: |^$' /mnt/.easy_ro/easy_sfs/var/lib/dpkg/status | cut -f 2 -d ' ' | sed -e 's%^$%ZZZZZ%' | tr '\n' '|' | sed -e 's%|ZZZZZ|%\n%g')"
#...ex: xserver-xorg-video-vmware|1:13.4.0-1
for aP in ${ROpkgs}
do
[ -z "$aP" ] && continue
Pn="${aP%|*}"
Pv="${aP#*|}"
RWpara="$(sed -n "/^Package: ${Pn}$/,/^$/p" /var/lib/dpkg/status)"
grep -q "^Version: ${Pv}$" <<<"$RWpara"
if [ $? -ne 0 ];then
#top-level status file has wrong version...
sed -i "/^Package: ${Pn}$/,/^$/d" /var/lib/dpkg/status
ROpara="$(sed -n "/^Package: ${Pn}$/,/^$/p" /mnt/.easy_ro/easy_sfs/var/lib/dpkg/status)"
echo "${ROpara}
" >> /var/lib/dpkg/status
#also the info files...
rm -f /var/lib/dpkg/info/${Pn}:* 2>/dev/null
rm -f /var/lib/dpkg/info/${Pn}.* 2>/dev/null
cp -a -f /mnt/.easy_ro/easy_sfs/var/lib/dpkg/info/${Pn}:* /var/lib/dpkg/info/ 2>/dev/null
cp -a -f /mnt/.easy_ro/easy_sfs/var/lib/dpkg/info/${Pn}.* /var/lib/dpkg/info/ 2>/dev/null
fi
done
sync
###end###
It only gets called when there is an update of EasyOS version. Called from apt and apt-get alias scripts, and when PKGget starts, so will also work in containers.
The above code is the first version, to show the idea. I will
work on it a bit more, for example to handle more .sfs files in
the layers, such as the devx .sfs
Tags: easy