Nautilusはファイルを貼り付けても書き込みシステムコールを呼び出しません。

Nautilusはファイルを貼り付けても書き込みシステムコールを呼び出しません。

Ubuntu 14.04デスクトップ版では、Linuxカーネルモジュールを使用していくつかのシステムコールを接続しようとしています。

ところでフックwrite(unsigned int fd, const char __user *buf, size_t count)してfilenameに戻してみると、ノーチラスにコピーして貼り付けるfdときにこのフォルダにwriteが呼び出されないことがわかりました。しかし、使用すると呼び出され、ファイル名が正確に 。/home/user/1.txt/home/user/folder/cp /home/user/1.txt /home/user/folderwrite/home/user/folder/1.txt

フックも試しましたが、pwriteノーチラスを使用してファイルを貼り付けても呼び出しは検出されません。

writeもしそうなら、ターゲットがシステムコールを呼び出さないとき、Nutilusはどのようにファイルを特定のフォルダにコピーして貼り付けますか?

ベストアンサー1

Nautilusは、最適化の目的で他のアプローチを使用しているようです。

/ntest/testfile内部に45バイトのテストファイルがあるとしましょう。

Lorem ipsum dolor sit amet
Leroooy Jeeenkins

ディレクトリに移動したいです/ntest2。 Nautilusが正確に何をしているのかを追跡するには、次のように始めることができます(実際にはあまり厳格な制限で何度も実行しましたが、良いスタートです)。

strace -f -P '/ntest/testfile' -P '/ntest2/testfile' -qq nautilus

デフォルトでは、次の抜粋は何が起こっているかを説明します(上記のpipe2()コマンドは呼び出しをキャプチャしません。他のトレースセッションに基づいて挿入しました)。

openat(AT_FDCWD, "/ntest/testfile", O_RDONLY) = 35
openat(AT_FDCWD, "/ntest2/testfile", O_WRONLY|O_CREAT|O_EXCL, 0644) = 36
pipe2([37, 38], O_CLOEXEC)  = 0
stat("/ntest2/testfile", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
splice(35, [0], 38, NULL, 1048576, SPLICE_F_MORE) = 45
splice(37, NULL, 36, [0], 45, SPLICE_F_MORE) = 45
close(35)                   = 0
close(36)                   = 0

カーネルとユーザースペースの間でデータをコピーすることなく、s間でデータを転送できるようにsplice(2)Nautilusによって使用されます。一端にパイプが必要なfdため、Nautilusは入力ファイル記述子と出力ファイル記述子を持つパイプを作成します。ソースファイルとターゲットファイルを開いてパイプを作成した後、Nautilusはソースファイルのデータをパイプの入力として読み取るために使用され、2番目はパイプのデータを出力ファイルに書き込むために使用されます。この方法には、通常の方法と同様に、カーネルからユーザーへ、ユーザーからカーネルへのデータ変換は含まれません。man 2 splice3837splice()splice()read()write()

この動作はNautilusに固有のものではなく、Nautilusが使用するライブラリ(glib)に固有のものです。のように見えるこれは splice() 呼び出しです。Nautilusがglibの使用を観察しました。g_file_copy()これは順番に呼び出されます。file_copy_fallback()->splice_stream_with_progress()->do_splice()

おすすめ記事