2015-10-21 13 views
5

mountシステムコールはどのようにしてperlから実行できますか?次でperlからのマウントシステムコールの実行

$ret = syscall(&SYS_mount, "/proc", "/path/to/my/mount/point", 0, 0, 0); 

結果:

Modification of a read-only value attempted at ... 

は私がmountプログラムが可能なように思われないことをmount()システムコールを作成する必要があるためsystemを使用してmountプログラムを呼び出すことはできません。具体的には、私が呼び出す必要があります:

mount("/proc", "/path/to/my/mpoint/point", NULL, MS_REC|MS_PRIVATE|MS_BIND, NULL); 

をしかし、私はLinuxの名前空間マウント特権のない非共有で、以下を実行しようとした場合:

mount: wrong fs type, bad option, bad superblock on /proc, 
     missing codepage or helper program, or other error 

     In some cases useful info is found in syslog - try 
     dmesg | tail or so. 

mount --make-rprivate --bind /proc /path/to/my/mountpoint 

をそれから私は次のエラーを取得します

straceを使用すると、プログラムが実際に行うことは、

mount("/proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND, NULL); 
mount("none", "/path/to/my/mointpoint", NULL, MS_REC|MS_PRIVATE, NULL); 

ただし、このオプションの分割は機能しません。私はMS_BINDMS_REC|MS_PRIVATEを、特権のない共有されていないマウント名前空間で動作させるために、mountシステムコールへの一回の呼び出しで必要とします。

したがって、読み取り専用の値を変更しようとするとエラーメッセージが表示されずに、perlで初期システムコールを実行するにはどうすればよいですか?

編集

ありがたい池上はperlのsyscall機能を使用しようとすると、私は間違って何をしたかすぐに指摘したが、非特権マウント内からディレクトリをマウントバインドする方法を検索するときに場合には、誰かがこれを見つけました順番に

mount --rbind /proc /path/to/my/mountpoint 

これは内部で以下のシステムコールを呼び出します:

だけ mountコマンドラインユーティリティを使って名前空間に、ここではどのようにあります
mount("proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND|MS_REC, 0); 

フラグMS_MGC_VALは、2.4より前のカーネルバージョンとの下位互換性のためであるようです。重要なビットはMS_BIND(バインドマウントそのものを行うため)とMS_RECです(再帰的に行うことで、他のマウントによって隠されたコンテンツがマウントネームスペースに公開されないようにします)。

は、だから今、私はperlのsystem関数呼び出しで行くか、単に全く同じように仕事の両方のためmount SYSTEMCALLを行うかどうかを決定する必要があります:)

答えて

8

syscallは、一定の文字列バッファへのポインタを渡すことを拒否します引数がchar *const char *かどうかは分かりません。

You can't use a string literal (or other read-only string) as an argument to syscall because Perl has to assume that any string pointer might be written through

解決策は簡単です。最初に定数に変数をコピーするだけです。

my $ret = syscall(&SYS_mount, my $s="/proc", my $t="/path/to/my/mount/point", 0, 0, 0); 

テスト:

$ perl -E' 
    require "syscall.ph"; 
    my $ret = syscall(&SYS_mount, "/proc", "/path/to/my/mount/point", 0, 0, 0); 
    say $ret; 
' 
Modification of a read-only value attempted at -e line 3. 

$ perl -E' 
    require "syscall.ph"; 
    my $ret = syscall(&SYS_mount, my $s="/proc", my $t="/path/to/my/mount/point", 0, 0, 0); 
    say $ret; 
' 
-1 

$ strace perl -e' 
    require "syscall.ph"; 
    syscall(&SYS_mount, my $s="/proc", my $t="/path/to/my/mount/point", 0, 0, 0); 
' 2>&1 | grep mount 
mount("/proc", "/path/to/my/mount/point", NULL, 0, NULL) = -1 ENOENT (No such file or directory) 
+0

あなたサー/マダムは、ちょうど私の一日行わ!私は今、 'syscall'のドキュメントが"文字列リテラル(または他の読み取り専用文字列)を引数として使うことはできません "と言っているのを見ています... ...ばかげて私はRTFMを持っていたはずです...しかし、ちょうど私の多くの頭痛を救った私はあなたが多くのupvotesを望む:) – josch

+0

Doh!どちらかを読んでいなかった!私の答えは少し改善されました。 – ikegami

関連する問題