On Sat, Oct 14, 2023 at 09:02:41PM +0200, Marc Espie wrote:
> On Sat, Oct 14, 2023 at 11:24:08AM -0700, Andrew Hewus Fresh wrote:
> > While testing another patch, I noticed that fw_update will lock the
> > package database even if it's just downloading and not touching the
> > installed packages.
> > 
> > Currently we do _read_ the existing firmware as part of detecting what
> > we might need to download or upgrade without locking.  I'm unsure if
> > that is an issue.
> > 
> > Comments, OK?
> > 
> > 
> > 
> > Index: fw_update.sh
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/fw_update/fw_update.sh,v
> > retrieving revision 1.51
> > diff -u -p -r1.51 fw_update.sh
> > --- fw_update.sh    14 Oct 2023 18:10:47 -0000      1.51
> > +++ fw_update.sh    14 Oct 2023 18:12:08 -0000
> > @@ -593,7 +593,7 @@ kept=''
> >  unregister=''
> >  
> >  if [ "${devices[*]:-}" ]; then
> > -   lock_db
> > +   "$INSTALL" && lock_db
> >     for f in "${devices[@]}"; do
> >             d="$( firmware_devicename "$f" )"
> >  
> > 
> > 
> the package tools have two lock modes: read-only and read-write.
> If you want to match them, you want lock read-only for this.

Everywhere but during detection "installed_firmware" is called with the
read-write lock.

I think using that read-only lock during detection would look like this.

Index: fw_update.sh
===================================================================
RCS file: /cvs/src/usr.sbin/fw_update/fw_update.sh,v
retrieving revision 1.51
diff -u -p -r1.51 fw_update.sh
--- fw_update.sh        14 Oct 2023 18:10:47 -0000      1.51
+++ fw_update.sh        14 Oct 2023 19:39:25 -0000
@@ -69,7 +69,7 @@ cleanup() {
        fi
 
        [ "${FTPPID:-}" ] && kill -TERM -"$FTPPID" 2>/dev/null
-       [ "${LOCKPID:-}" ] && kill -TERM -"$LOCKPID" 2>/dev/null
+       unlock_db
        [ "${FWPKGTMP:-}" ] && rm -rf "$FWPKGTMP"
        "$REMOVE_LOCALSRC" && rm -rf "$LOCALSRC"
        [ -e "$CFILE" ] && [ ! -s "$CFILE" ] && rm -f "$CFILE"
@@ -259,7 +259,7 @@ lock_db() {
        [ -e /usr/bin/perl ] || return 0
 
        set -o monitor
-       perl <<-'EOL' |&
+       _shared=${1:-0} perl <<-'EOL' |&
                no lib ('/usr/local/libdata/perl5/site_perl');
                use v5.36;
                use OpenBSD::PackageInfo qw< lock_db >;
@@ -267,7 +267,7 @@ lock_db() {
                $|=1;
 
                $0 = "fw_update: lock_db";
-               lock_db(0);
+               lock_db($ENV{_shared});
 
                say $$;
 
@@ -284,6 +284,20 @@ EOL
        return 0
 }
 
+unlock_db() {
+       [ "${LOCKPID:-}" ] || return 0
+       local _seconds=0
+
+       kill -TERM -"$LOCKPID"
+
+       while kill -0 -"$LOCKPID" 2>/dev/null; do
+               sleep 1
+               ((_seconds++ > 5)) && kill -KILL -"$LOCKPID"
+       done
+
+       unset LOCKPID
+}
+
 installed_firmware() {
        local _pre="$1" _match="$2" _post="$3" _firmware _fw
        set -sA _firmware -- $(
@@ -581,7 +595,9 @@ if [ "${devices[*]:-}" ]; then
        "$ALL" && warn "Cannot use -a and devices/files" && usage
 else
        ((VERBOSE > 1)) && echo -n "Detect firmware ..."
+       lock_db 1
        set -sA devices -- $( detect_firmware )
+       unlock_db
        ((VERBOSE > 1)) &&
            { [ "${devices[*]:-}" ] && echo " found." || echo " done." ; }
 fi
@@ -593,7 +609,7 @@ kept=''
 unregister=''
 
 if [ "${devices[*]:-}" ]; then
-       lock_db
+       "$INSTALL" && lock_db
        for f in "${devices[@]}"; do
                d="$( firmware_devicename "$f" )"
 

Reply via email to