2010-09-30 367 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()」,這可能很可能是問題的根源。