2010-09-30 1064 views
5

Estoy tratando de corregir un error intermitente en git-svn. El problema está sucediendo en Windows XP solamente, con Cygwin git (perl v5.10.1) y msysGit (perl v5.8.8).permiso sysopen denegado

Con cualquier operación que implica una zona de alcance, soy capaz de conseguir un punto intermedio y luego la operación muere con un mensaje similar a

No se pudo abrir .git/SVN/refs/mandos a distancia/tronco /.rev_map.cc05479a-e8ea-436f-8d71-e07493b7796c.lock: dispositivo o recurso ocupado

en/usr/lib/git-core línea/git-svn 5240

Sin embargo, la cerradura exacta archivo y número de línea no son siempre lo mismo. He rastreado el problema real a la línea 3679

sysopen(my $fh, $db_lock, O_RDWR | O_CREAT) 

Esto está creando un nuevo archivo .lock, y probé el equivalente en vano.

open(my $fh, ">", $db_lock) 

que comprueba los permisos del directorio, y es drwxr-xr-x, por lo que no debería haber ningún problema, o si lo fueran, no serían tan inconsistente.

¿Podría ser porque la secuencia de comandos está creando y renombrando este archivo tantas veces en rápida sucesión que XP no puede manejarlo? EDITAR: mi sospecha es que este es el caso, porque cuando usé el depurador de perl y comencé la ejecución de cada sysopen manualmente, no hubo problemas para las 100 revisiones que obtuve.

EDIT: Algunos desarrolladores de Git preferirían descubrir la causa principal que ir con un truco que funciona (el enfoque correcto, creo). Entonces, ¿alguien puede ayudarme a encontrar al culpable negando mi permiso para abrir estos archivos .lock? Tengo una serie de herramientas que teóricamente podrían ser utilizados para este propósito, pero no acabo de llegar hasta el final: Explorador

  • Proceso - muestra todos los mangos propiedad de un proceso, y también pueden buscar todos los procesos ser dueño de un mango determinado. Sin embargo, no funciona bien para procesos o manejadores efímeros (que es lo que hace git svn clone/fetch do)
  • Unlocker: detecta cuando aparece un cuadro de diálogo genérico de "denegación de permiso" y encuentra el (los) mango (s) ofensivo (s) y ofertas para tratar con ellos. Sin embargo, no aparece cuando los programas no exploradores encuentran errores basados ​​en archivos

En resumen, ¿hay alguna manera de obtener más información sin ser un empleado de Microsoft?

EDIT 2: Probablemente no sea Symantec, sino otro programa que tengamos funcionando en las computadoras en red. Tengo algunas personas investigándolo, y deberían poder al menos reducir la causa aquí.

+0

Eso suena plausible. – Axeman

+0

Entonces, ¿sería una buena solución agregar un bucle para reintentar hasta un cierto número de veces, o es demasiado pirateo? –

+0

No equivaldría a 'O_RDWR | O_CREAT' be 'open (mi $ fh," + <", $ db_lock)'? – mob

Respuesta

6

Este tipo de comportamiento generalmente se puede atribuir a un componente antivirus que mantiene el archivo abierto y retrasa la eliminación.

+0

Esa es mi mejor suposición, también. No tengo ningún control sobre el antivirus que se ejecuta en la máquina, por lo que la única solución es cambiar Git, ¿verdad? ¿O tal vez solo msysGit? –

+0

¿Puedes incluso desactivarlo temporalmente para ver si el problema desaparece? En su pregunta habla de encontrar y solucionar la causa raíz ... si el antivirus tiene errores, cualquier cambio que realice en git no será más que una solución. –

+0

Es Symantec, y no puedo matarlo ni detenerlo. Podría intentar trabajar con TI, pero si ese es el problema, ¿no tendría que depender de Symantec para solucionarlo? –

5

Mi corte de corriente de una solución es reemplazar el sysopen con este

my $fh; 
if ($^O eq 'MSWin32' or $^O eq 'cygwin') { 
    for my $try (1..10) { # Retry up to 10 times on problematic systems 
     sysopen($fh, $db_lock, O_RDWR | O_CREAT); 
     last if $fh; 
    } 
} else { 
    sysopen($fh, $db_lock, O_RDWR | O_CREAT); 
} 

croak "Couldnt open $db_lock: $!\n" unless $fh;' 

Y hasta ahora, está funcionando bastante bien. La mayoría de las veces no imprime ningún., Y ocasionalmente imprime uno, y no lo he visto imprimir más de uno en una fila. ¿Es esta solución demasiado hacky?

Editar: Mi código reemplazado por la versión limpiada de Ævar Arnfjörð Bjarmason.

+0

Eso tiene sentido. Una gran cantidad de código no tiene un comportamiento robusto. – Axeman

+1

Sugeriría un Time :: HiRes :: sleep (.01) en ese ciclo. Además, tal vez 'last if $ fh || ps ! = Errno :: EBUSY' – ysth

+0

Todavía no he identificado la causa, así que me doy la recompensa –

1

Usaría Process Monitor y lo dejaría funcionar hasta que vuelva a ocurrir la falla. Luego, en Process Monitor, verá un error mientras su programa accede al archivo (lo más probable es ACCESS_DENIED o SHARING_VIOLATION). Luego puede filtrar por ese nombre de archivo y ver qué otros procesos (si hay alguno) lo abrieron.

+0

Creo que lo que obtengo es "RÁPIDO IO EN DESALOJO". Debería filtrar en la columna 'Ruta', ¿verdad? –

+0

Puede ignorar "RÁPIDO IO DESACTIVADO"; es normal. Cuando se produce un error, debe filtrar la columna "Ruta" para incluir solo el archivo que causó el error; esto debería mostrarle qué otros procesos estaban accediendo a él. – Luke

1

Si su programa llama "fork()" o "system()" o "exec()" en cualquier lugar, este podría ser el origen del problema.