2010-09-30 368 views
5

我试图修复git-svn中的间歇性错误。这个问题只发生在Windows XP中,Cygwin git(perl v5.10.1)和msysGit(perl v5.8.8)。sysopen权限被拒绝

随着涉及取回,我能够通过获得中途然后操作类似于

无法打开的.git/SVN /参/遥控器/主干消息去世的任何操作/.rev_map.cc05479a-e8ea-436f-8d71-e07493b7796c.lock:设备或资源忙

在/ usr/lib中/ git的核/ GIT中 - svn的线5240

然而,确切的锁文件和行号并不总是相同的。我已经跟踪到实际问题行3679

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

这是创建一个新的.lock文件,我试过相当于无济于事。

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

我检查了目录的权限,这是drwxr-XR-X,所以不应该有任何问题,或者如果他们成功了,他们就不会那么抵触。

难道这是因为脚本创建并重命名这个文件很多次快速连续,XP无法处理它?编辑:我怀疑是这种情况,因为当我使用perl调试器并手动启动每个sysopen的执行时,我获取的100个修订版本没有问题。

编辑:一些Git开发人员宁愿找出根本原因,而不愿意使用正常工作的黑客(我认为是正确的方法)。那么,谁能帮我找到否认我打开这些.lock文件的罪魁祸首?我有一些是理论上可以用于此目的的工具,但他们不太一路走:

  • 进程资源管理器 - 显示一个进程所拥有的所有手柄,并且还可以搜索所有进程拥有一个给定的句柄。然而,它不适用于短期流程或句柄(这是git svn clone/fetch的作用)
  • Unlocker - 检测何时出现通用“权限被拒绝”对话框并找到违规句柄和优惠来处理它们。但是,当非资源管理器程序遇到基于文件的错误时,它不会出现

简而言之,有没有什么方法可以在不成为Microsoft员工的情况下获得更多信息?

编辑2:这可能不是赛门铁克,而是我们在联网的计算机上运行的另一个程序。我有一些人正在研究它,他们应该至少能够在这里缩小事业的范围。

+0

这听起来似乎合理。 – Axeman 2010-09-30 16:06:15

+0

那么,如果添加一个循环来重试某个特定的次数,或者这样做太过分了,那么这会是一个很好的解决方案吗? – 2010-09-30 16:49:19

+0

不等于'O_RDWR | O_CREAT'打开(我的$ fh,“+ <”,$ db_lock)'? – mob 2010-09-30 17:30:39

回答

6

这种行为通常可以归因于防病毒组件保持打开文件并延迟删除。

+0

这也是我最好的猜测。我无法控制在机器上运行的防病毒程序,所以唯一的解决方案是更改Git,对吧?或者只是msysGit? – 2010-10-02 23:03:59

+0

你甚至可以暂时禁用它,看看问题是否消失?在你的问题中,你讨论如何找到并解决根本原因......如果杀毒软件有问题,那么你对git所做的任何改变都不过是一种解决方法。 – 2010-10-02 23:24:43

+0

这是赛门铁克,我不能杀或暂停它。我可以尝试与IT合作,但如果出现问题,我不能依靠赛门铁克解决它吗? – 2010-10-03 15:20:33

5

我目前的解决方案的黑客是更换的sysopen这个

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;' 

到目前为止,它的工作相当不错。大多数时候它不打印任何东西,偶尔会打印一张,而且我还没有看到它连续打印多个。这个解决方案太难懂了吗?

编辑:我的代码被ÆvarArnfjörðBjarmason的清理版本所取代。

+0

这是有道理的。很多代码缺乏强大的行为。 – Axeman 2010-09-30 17:23:11

+1

我建议在该循环中的Time :: HiRes :: sleep(.01)。另外,也许'最后如果$ fh || $! != Errno :: EBUSY' – ysth 2010-10-06 07:07:57

+0

还没有明确的原因,所以我给自己的赏金 – 2010-10-08 23:49:17

1

我会使用进程监视器,让它运行,直到失败再次发生。然后在Process Monitor中,当程序访问文件时(最可能是ACCESS_DENIED或SHARING_VIOLATION),应该会看到一个错误。然后你可以通过该文件名进行过滤,并查看其他进程(如果有)打开它。

+0

我想我得到的是“FAST IO DISALLOWED”。我应该在“路径”列上过滤,对吗? – 2010-10-07 21:21:51

+0

您可以忽略“FAST IO DISALLOWED”;这是正常的。发生错误时,应过滤“路径”列以仅包含导致错误的文件;这应该告诉你什么其他进程正在访问它。 – Luke 2010-10-07 23:27:48

1

如果您的程序在任何地方调用“fork()”或“system()”或“exec()”,这可能很可能是问题的根源。