[sugj-tech:7008] ストレージ間のファイル移動処理で問題です
Kentaro Kataoka
kataoka @ silex.jp
2009年 1月 14日 (水) 19:49:28 JST
はじめまして片岡です。
このようなメーリングリストにメールを投げるのは初めてなので
作法が分からないので失礼があったらすみません。
以下のような症状がでたので対策を考えてみました(消しただけですが、、、)
●症状
WindowsXP(Home)からSamba(3.2.7 and 3.0.33)を操作中に以下のような症状がでました。
1. 1つの共有ディレクトリ内に複数のストレージデバイスをマウント
# mount -t vfat /dev/sda1 /mnt/shared/sda1 -o rw,fmask=000,dmask=000
# mount -t vfat /dev/sdb1 /mnt/shared/sdb1 -o rw,fmask=000,dmask=000
2. Windowsでsda1からsdb1にファイルの移動操作を行う
3. 移動先にファイルが作成される。
4. エラーメッセージが表示され移動元のファイルが削除されない
●原因
この問題で原因を調べた結果Windowsがrenameコマンドを投げたときにsamba内部で
rename関数が失敗しエラーコードSTATUS_ACCESS_DENIEDを返していることが分か
りました。
場所:source/modules/vfs_default.c の vfswrap_rename 関数
ここでrename関数はデバイスをまたいだ処理ができないため、デバイス間のrename
の場合応急処置としてcopy_regという関数が実行されています。
copy_regは移動操作をファイルのコピーや移動元ファイルの削除などのシステムコー
ルでこの問題をなんとかするためのものです。
場所:source/modules/vfs_default.c の copy_reg 関数
ext2などのファイルシステムを使用している場合この処理でも移動することが可能な
のですがFATやNTFSなどをつかうとcopy_reg内部で移動先ファイルのパーミッション
を移動元と同じにしようとしてchmod関数を実行して失敗してしまいエラーを返し、上
記の問題が発生してしまいます。
また、ext2などのファイルシステムを使用しても大きいサイズのファイルの場合samba
が内部で処理している間にWindows側がタイムアウトしてしまいファイルの移動処理が
失敗します。
●対策
vfswrap_rename関数ではcopy_regを呼ばないようにします。
変わりにvfswrap_rename関数を呼んだ場所でerrnoにEXDEVが入っていた場合
STATUS_NOT_SAME_DEVICEを返してやればWindows側が移動操作からコピー操作
に切り替えてファイル操作してくれるため、大きさやファイルシステムに関係なく
操作できるようになります。
具体的には以下のように変更を加えればよいと思われます。
( ※samba-3.2.7 の場合 )
source/modules/vfs_default.c の vfswrap_rename 関数 (463)
static int vfswrap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
{
int result;
START_PROFILE(syscall_rename);
result = rename(oldname, newname);
+ #if 0
if ((result == -1) && (errno == EXDEV)) {
/* Rename across filesystems needed. */
result = copy_reg(oldname, newname);
}
+ #endif
END_PROFILE(syscall_rename);
return result;
}
●この対策による問題点
クライアントがWindowsXPの場合はいいのですがMacOSX(10.4),MacOSX(10.5)
の場合STATUS_NOT_SAME_DEVICEを返されてもこのメッセージに対する動作
が定義されていないためエラーメッセージが表示されます。
Sambaのクライアントはまだ調査していません。
// --------------------------------
Kataoka Kentaro
E-mail: kataoka @ silex.jp
// --------------------------------
sugj-tech メーリングリストの案内