2015-10-21 20 views
5

Làm cách nào để thực hiện cuộc gọi hệ thống mount từ perl? Sau đây:Thực hiện cuộc gọi hệ thống gắn kết từ perl

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

kết quả trong:

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

tôi không thể gọi chương trình mount sử dụng system vì tôi cần phải thực hiện một cuộc gọi mount() hệ thống mà chương trình mount dường như không có khả năng. Cụ thể hơn, tôi cần phải gọi:

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

Nhưng nếu tôi cố gắng chạy sau đây với một không chia sẻ không gian tên núi linux không có đặc quyền:

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

Sau đó, tôi nhận được thông báo lỗi sau:

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. 

Sử dụng strace cho biết chương trình mount thực sự là gọi:

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

Nhưng việc tách tùy chọn này không hoạt động. Tôi cần MS_BINDMS_REC|MS_PRIVATE trong một cuộc gọi đến cuộc gọi hệ thống mount để cuộc gọi hệ thống hoạt động trong không gian tên gắn kết không được chia sẻ không được chia sẻ.

Vậy làm cách nào để thực hiện cuộc gọi hệ thống ban đầu của mình trong perl mà không có thông báo lỗi về nỗ lực sửa đổi giá trị chỉ đọc?

chỉnh sửa:

Rất may Ikegami đã nhanh chóng chỉ ra những gì tôi đã làm sai khi cố gắng sử dụng chức năng perl của syscall nhưng trong trường hợp ai đó tìm thấy này khi tìm kiếm cách để ràng buộc gắn kết một thư mục từ bên trong một núi không có đặc quyền namespace chỉ với tiện ích dòng lệnh mount, đây là cách:

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

này sẽ lần lượt gọi syscall sau nội bộ:

mount("proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND|MS_REC, 0); 

Cờ MS_MGC_VAL dường như có khả năng tương thích ngược với phiên bản hạt nhân trước phiên bản 2.4. Các bit quan trọng là MS_BIND (để thực hiện việc gắn kết chính nó) và MS_REC (để thực hiện đệ quy sao cho các thư mục có nội dung ẩn bởi các gắn kết khác đang được thực hiện vào chúng không được hiển thị nội dung của chúng trong không gian tên gắn kết).

Vì vậy, bây giờ tôi phải quyết định xem tôi đi với một perl system gọi hàm hoặc chỉ làm mount systemcall vì cả hai công việc chỉ là tốt :)

Trả lời

8

syscall từ chối để vượt qua một con trỏ đến bộ đệm chuỗi của một hằng số vì nó không có ý kiến ​​nếu đối số là char * hoặc 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

Giải pháp rất đơn giản. Chỉ cần sao chép hằng số vào một biến đầu tiên.

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

Test:

$ 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

Bạn sir/madam vừa làm cho ngày của tôi! Bây giờ tôi thấy rằng các tài liệu của 'syscall' nói" Bạn không thể sử dụng một chuỗi chữ (hoặc chuỗi chỉ đọc) như một đối số "... ngớ ngẩn tôi, tôi nên đã RTFM ... Tuy nhiên, kể từ khi bạn chỉ cần cứu tôi nhiều đau đầu Tôi muốn bạn nhiều upvotes :) – josch

+0

Doh! Đã không đọc được điều đó! Cải thiện câu trả lời của tôi một chút. – ikegami

Các vấn đề liên quan