如何从perl完成mount
系统调用?以下内容:
$ret = syscall(&SYS_mount, "/proc", "/path/to/my/mount/point", 0, 0, 0);
结果:
Modification of a read-only value attempted at ...
我无法使用mount
来调用system
程序,因为我需要进行mount()
系统调用mount
程序似乎不具备。更具体地说,我需要致电:
mount("/proc", "/path/to/my/mpoint/point", NULL, MS_REC|MS_PRIVATE|MS_BIND, NULL);
但是如果我尝试使用非特权的非共享mount linux命名空间运行以下命令:
mount --make-rprivate --bind /proc /path/to/my/mountpoint
然后我收到以下错误:
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.
使用strace
显示mount
程序实际执行的操作是:
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_BIND
和MS_REC|MS_PRIVATE
一次调用mount
系统调用才能在非特权非共享安装命名空间中工作。
那么如何在没有关于尝试修改只读值的错误消息的情况下在perl中进行初始系统调用?
修改:
值得庆幸的是,ikegami很快指出我在尝试使用perl的syscall
函数时做错了什么,但是有人在搜索如何绑定从无特权的mount命名空间中挂载目录时发现了这一点只使用mount
命令行实用程序,方法如下:
mount --rbind /proc /path/to/my/mountpoint
这反过来会在内部调用以下系统调用:
mount("proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND|MS_REC, 0);
MS_MGC_VAL
标志似乎是为了向后兼容2.4之前的内核版本。重要的位是MS_BIND
(用于执行绑定安装本身)和MS_REC
(用于递归执行,以便将其内容隐藏的目录放入其中的目录不会暴露其内容mount命名空间)。
所以现在我必须决定是使用perl system
函数调用还是只执行mount
系统调用,因为两者都可以正常工作:)
答案 0 :(得分:8)
syscall
拒绝传递指向常量字符串缓冲区的指针,因为它不知道参数是char *
还是const char *
。
你不能使用字符串文字(或其他只读字符串)作为syscall的参数,因为Perl必须假设任何字符串指针都可以通过
写入
解决方案很简单。只需将常量复制到变量中即可。
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)
答案 1 :(得分:1)
您可以在此处找到Perl中的完整实现:https://github.com/i-MSCP/imscp/blob/1.5.x/engine/PerlLib/iMSCP/Mount.pm