`flock` falla aleatoriamente en una PC de escritorio pero no en una computadora portátil, ¿podría ser hardware defectuoso?

`flock` falla aleatoriamente en una PC de escritorio pero no en una computadora portátil, ¿podría ser hardware defectuoso?

Estoy usando el siguiente script para realizar una prueba de estrés del bloqueo exclusivo con flock.

En mi notebook siempre funciona bien.
Pero cuando lo ejecuto en mi PC de escritorio, puede fallar aleatoriamente, permitiendo que dos instancias se ejecuten al mismo tiempo (¡adquiriendo el mismo bloqueo!).
Ambos ejecutan ubuntu 20.04.

Entonces sospecho que hay un problema de hardware en mi escritorio, ¿puede ser la RAM?

Entonces, mi pregunta es, según la información que me está dando el mal comportamiento de la bandada, ¿cómo puedo rastrear/determinar qué pieza de hardware está defectuosa?
Quiero decir, ¿qué bandada podría indicar qué hardware está defectuoso (o puede que sea de baja calidad)?

Cómo confirmo el problema:
obtengo todos los procesos de Flock que tienen el comando secundario que coincide con el nombre del script de ruta completa (eso es lo que Flock debería ejecutar como comando secundario).
Además, registro el trabajo realizado por cada script y en ese registro tengo el trabajo simultáneo de dos o más de sus instancias. El trabajo se registra sólo si se adquiere el bloqueo.
¿Es posible que no esté configurando Flock correctamente para proporcionar bloqueos exclusivos/únicos?
Ahora también estoy usando esto en otra terminal:
while true;do date;lslocks |grep flock;sleep 1;done

La secuencia de comandos: 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`"


Algunos resultados:
Como puede ver, el bloqueo exclusivo fue adquirido por los procesos 1458428(flock:1458427) y 1438949(flock:1438941) simultáneamente :(

El archivo de registro (creado por el script) muestra este problema (en el segundo 50, ocurrió un segundo registro 2 de la otra instancia que no debería haber adquirido el bloqueo):

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

lslockmuestra esto (el tiempo con dateestá en el guión como consejo):

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)

el registro del terminal (que generó muchas instancias simultáneas) muestra esto:

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

Respuesta1

Hipótesis: justo antes de que sucediera guardaste el guión. Su editor guardó una copia y luego la movió a la ruta original. Ver¿Cómo Vim hace esto?ypor qué.

De hecho, el antiguo bloqueo todavía se mantenía en el archivo antiguo (inodo). Esto se mostró como …/flock.tst.sh (deleted)en la salida de lslocks. Pero flocksu script (¿otra instancia del mismo?) siguió generando el uso de la ruta. Cuando la ruta comenzó a apuntar a otro inodo, flockse permitió que algunos nuevos adquirieran un nuevo bloqueo. Esto se mostró como …/flock.tst.shen la salida de lslocks.

Las dos cerraduras eran independientes, no podían bloquearse entre sí porque usabandiferentearchivos. Flock funcionó según lo diseñado.

De hecho, puedo recrear el resultado ejecutando dos instancias del script (de modo que una obtenga el bloqueo y la otra siga intentando obtenerlo) y luego abriéndolo vimy escribiendo ( :w) de inmediato. Alternativamente:

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

información relacionada