„Flock“ schlägt auf dem Desktop-PC zufällig fehl, aber nicht auf dem Notebook. Könnte es an der Hardware liegen?

„Flock“ schlägt auf dem Desktop-PC zufällig fehl, aber nicht auf dem Notebook. Könnte es an der Hardware liegen?

Ich verwende das folgende Skript, um den exklusiven Sperrvorgang mit einem Stresstest zu unterziehen flock.

Auf meinem Notebook funktioniert es immer einwandfrei.
Aber wenn ich es auf meinem Desktop-PC ausführe, kann es zufällig fehlschlagen, sodass zwei Instanzen gleichzeitig ausgeführt werden (und dieselbe Sperre erhalten!).
Beide laufen unter Ubuntu 20.04.

Ich vermute also ein Hardwareproblem auf meinem Desktop. Liegt es vielleicht am RAM?

Meine Frage ist also: Wie kann ich anhand des Hinweises, den Flock Missbehavior mir gibt, nachverfolgen/bestimmen, welches Hardwareteil defekt ist?
Ich meine, welcher Flock könnte darauf hinweisen, welche Hardware defekt ist (oder möglicherweise von schlechter Qualität ist)?

So bestätige ich das Problem:
Ich erhalte alle Flock-Prozesse, deren untergeordnete Befehle mit dem vollständigen Pfad des Skriptnamens übereinstimmen (das ist das, was Flock als untergeordneten Befehl ausführen sollte).
Außerdem protokolliere ich die von jedem Skript ausgeführte Arbeit und in diesem Protokoll ist die gleichzeitige Arbeit von zwei oder mehr seiner Instanzen aufgeführt. Die Arbeit wird nur protokolliert, wenn die Sperre erworben wurde.
Könnte es sein, dass ich Flock nicht richtig konfiguriert habe, um exklusive/eindeutige Sperren bereitzustellen?
Ich verwende dies jetzt auch auf einem anderen Terminal:
while true;do date;lslocks |grep flock;sleep 1;done

Das Skript: cat >flock.tst.sh;chmod +x flock.tst.sh

#!/bin/bash

LC_NUMERIC=en_US.UTF-8

# HELPERS:
#trash /tmp/flock.tst.log;for((i=0;i<20;i++));do flock.tst.sh&:;done #run this on shell
#pkill -fe flock.tst.sh #end all concurrent children trying to acquire the lock
#while true;do date;lslocks |grep flock;sleep 1;done #use this to check if there is more than one lock acquired, check also the log file to confirm it, and if there is two subsequent WORK on the terminal log, it means a problem happened too

: ${bDaemonizing:=false}
: ${bReport:=false} #help use this to show more log, but will be harder to read it.
: ${bCheck:=false} #help this will let the script check if there is more than one instance working, but it may be slow and make it more difficult to let the problem happen
if ! $bDaemonizing;then
  echo "this IS a daemon script, only one instace runnable"
  flSelf="`realpath $0`"
  
  #set -x 
  while ! bDaemonizing=true flock --timeout=$(bc <<< "0.2+0.0$RANDOM") "$flSelf" "$flSelf" "$@";do
    if $bCheck;then
      strParents="$(nice -n 19 pgrep -f "^flock --timeout=.* $flSelf $flSelf" |tr '\n' ',' |sed -r 's"(.*),"\1"')"
      if [[ -n "$strParents" ]];then
        anDaemonPid=( $(nice -n 19 pgrep --parent "$strParents" -f "$flSelf") )
        if((${#anDaemonPid[*]}>1));then echo "ERROR: more than one daemon, flock failed!? :(";ps --no-headers -o ppid,pid,cmd -p "${anDaemonPid[@]}";fi
        if $bReport && ((${#anDaemonPid[*]}==1));then echo "$$:Wait daemon stop running or 'kill ${anDaemonPid[0]}'";fi #could be: "already running, exiting.", but the new instance may have updated parameters that work as intended now.
      fi
    fi
  done
  
  exit #returns w/e flock does
fi

echo "$$:Work:`date`"
for((i=0;i<60;i++));do
  echo "`\
    echo $i;\
    date;\
    ps --no-headers -o ppid,pid,stat,state,pcpu,rss,cmd -p "$PPID";\
    ps --no-headers -o ppid,pid,stat,state,pcpu,rss,cmd -p "$$";\
  `" >>/tmp/flock.tst.log
  
  sleep 1
done
echo "$$:Done:`date`"


Einige Ergebnisse:
Wie Sie sehen können, wurde die exklusive Sperre gleichzeitig von den Prozessen 1458428(flock:1458427) und 1438949(flock:1438941) erworben :(

Die (vom Skript erstellte) Protokolldatei zeigt dieses Problem (bei Sekunde 50 trat ein Protokoll der zweiten Sekunde der anderen Instanz auf, die die Sperre nicht hätte erhalten sollen):

2
Fri 22 Jan 17:03:16 -03 2021
1438953 1458427 S    S  0.0   784 flock --timeout=.22377 /home/myUser/bin/flock.tst.sh /home/myUser/bin/flock.tst.sh
1458427 1458428 S    S  0.0  3852 /bin/bash /home/myUser/bin/flock.tst.sh
50
Fri 22 Jan 17:03:16 -03 2021
1438925 1438941 S    S  0.0   788 flock --timeout=.229687 /home/myUser/bin/flock.tst.sh /home/myUser/bin/flock.tst.sh
1438941 1438949 S    S  0.0  3900 /bin/bash /home/myUser/bin/flock.tst.sh

lslockzeigt dies (das while-Symbol datesteht im Skript als Hinweis):

Fri 22 Jan 17:03:16 -03 2021
flock           1459088 FLOCK  1.8K WRITE* 0          0          0 /home/myUser/bin/flock.tst.sh
flock           1458427 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh
flock           1438941 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh (deleted)
Fri 22 Jan 17:03:17 -03 2021
flock           1459616 FLOCK  1.8K WRITE* 0          0          0 /home/myUser/bin/flock.tst.sh
flock           1458427 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh
flock           1438941 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh (deleted)

Das Terminalprotokoll (das die vielen gleichzeitigen Instanzen hervorgebracht hat) zeigt Folgendes:

1438949:Work:Fri 22 Jan 17:02:23 -03 2021
1458428:Work:Fri 22 Jan 17:03:14 -03 2021
1438949:Done:Fri 22 Jan 17:03:26 -03 2021
1476209:Work:Fri 22 Jan 17:04:02 -03 2021
1458428:Done:Fri 22 Jan 17:04:17 -03 2021

Antwort1

Hypothese: Kurz bevor es passierte, haben Sie das Skript gespeichert. Ihr Editor hat eine Kopie davon gespeichert und diese dann an den ursprünglichen Pfad verschoben. Siehewie Vim das machtUndWarum.

Tatsächlich wurde die alte Sperre immer noch auf der alten Datei (Inode) gehalten. Dies zeigte sich wie …/flock.tst.sh (deleted)in der Ausgabe von lslocks. Aber flockIhr Skript (eine andere Instanz davon?) erzeugte weiterhin den Pfad „use the path“. Als der Pfad anfing, auf einen anderen Inode zu zeigen, flockdurfte ein neuer eine neue Sperre erwerben. Dies zeigte sich wie …/flock.tst.shin der Ausgabe von lslocks.

Die beiden Schlösser waren unabhängig voneinander, sie konnten sich nicht gegenseitig blockieren, da sieandersDateien. Flock funktionierte wie vorgesehen.

Ich kann Ihr Ergebnis tatsächlich reproduzieren, indem ich zwei Instanzen des Skripts ausführe (eine erhält die Sperre und eine andere versucht weiter, sie zu erhalten) und es dann mit öffne und sofort vim( ) schreibe . Alternativ::w

cp flock.tst.sh foo
mv foo flock.tst.sh

verwandte Informationen