pnfs執行truncate失敗的BUG解析

2021-05-31 23:24:23 字數 2099 閱讀 5605

bug 名稱

truncate操作失敗

bug 描述

使用fstest工具,先執行create再執行truncate後,伺服器會返回eio,而不是期望的0,過一段時間之後,重複執行truncate則成功。

這是導致truncate測試用例所有失敗的唯一原因。具體測試指令碼在fstest/tests/truncate目錄下。

bug 重現過程

1.       在客戶端掛載目錄下,使用fstest建立乙個檔案

命令:./fstest create aaa 0644

2.       執行truncate操作

命令:./fstest truncate aaa 1234567

3.       會顯示eio

出現bug的系統日誌

客戶端日誌:

伺服器端日誌:

bug 分析

現象分析    

根據操作不成功的返回值eio,很難分析出具體原因,因為eio是經過err_map操作之後的對映值,具體錯誤的返回值需要在log中定位。

log分析

1.       根據客戶端和伺服器的錯誤返回值10038,得出對應的巨集定義是err_openmode;

2.       通過在伺服器端日誌的3903行(見上圖)分析,定位出錯的具體**函式。

經過判斷,當前stateid是存在 對應的delegation的,然後進入check_delemode()函式,該函式**如下:

在2295行,經過打printk,斷定dp->dl_type的值為nfs4_open_deleagate_read。

4.       經過閱讀pnfs協議,發現在setattr()操作之前進行的open()操作,伺服器會嘗試授予delegation.

5.       閱讀伺服器端open()操作**,發現呼叫nfs4_open_delegation(current_fh, open, stp)後,入口引數open,中含有op_share_access變數,經過列印輸入,其值為nfs4_share_access_read。在隨後進行的分配delegation操作中,會把分配給它的delegation設定為nfs4_share_access_read。當客戶端下次持有這個delegation來執行setattr操作時,由於設定了修改size的標誌位,導致delegation的型別判斷失敗,操作失敗。

6.       若在shell中執行touch命令建立檔案,然後在執行truncate系統呼叫,則不會出現同樣錯誤,是因為touch觸發的系統呼叫是:open("cc", o_wronly|o_creat|o_noctty|o_nonblock, 0666);而測試指令碼中的建立命令是open(str(0), o_creat | o_excl, num(1));兩者相比,建立時候的標誌位設定不同,導致伺服器接收到的open操作,入口引數的op_share_access不同,從而測試指令碼的命令可以獲得讀許可權的delegation,而touch命令則無法獲取delegation。

7.       對於使用測試指令碼建立檔案,過一段時間後在執行truncate操作可以成功。

是由於客戶端會每60秒執行nfs4_renew_state(struct work_struct *work)操作,此操作會檢查是否存在「unreferenced」的delegation,若有則將其釋放。

而truncate操作之後,會執行檔案的close操作,刪除對應dentry,使得open操作得到的delegation變成「unreferenced」,在nfs4_renew_state()操作中被刪除。也就是說,檔案被建立之後,只要客戶端執行了nfs4_renew_state操作,再執行truncate操作,就可以成功。

8.由於nfs4_renew_state()操作是定期執行的,而truncate操作是隨機發生的,導致之前的第一次操作失敗後,間隔「不確定的時間」,再次成功。

bug定位

執行修改檔案大小的操作時候,客戶端持有的delegation型別為nfs4_share_access_read。

解決方案

在客戶端傳送setattr()請求之前,檢查修改size的標誌位是否設定,若設定,則釋放delegation。

在函式nfs_setattr()中,新增如下**:

驗證驗證通過。

**以及文件的提交路徑

PHP 執行多條 truncate

相同點 1.truncate和不帶where子句的delete 以及drop都會刪除表內的資料。2.drop truncate都是ddl語句 資料定義語言 執行後會自動提交。不同點 1.truncate 和 delete 只刪除資料不刪除表的結構 定義 drop 語句將刪除表的結構被依賴的約束 co...

誤操作經歷,truncate導致閃回查詢失敗

開發人員向我反映由於誤操作刪除了表裡的一些資料,要求我恢復。諮詢了誤操作的時間點後,我用閃回查詢試了一下,被誤刪的資料還在回滾段,可以挽救回來。我先備份了現在表裡的資料。create table a as select from 業務表。然後我做了一件愚蠢的事 truncate table 業務表 ...

解決erl sname gandalf 執行失敗

輸入erl sname gandalf後如圖 通過很多周折 包括使用crashdump viewer start 檢視崩潰記錄,網上查閱資料等等,都是竹籃打水一場空 總歸在反覆看報錯資訊之後,終於將目光注意到了這串英文,原來系統早就非常明確的告訴我,問題出在 cookie!接著我在 erlang程式...