2015-10-21 32 views
5

Jak można wywołać wywołanie systemowe mount z Perla? Następujące:Wykonywanie wywołań systemowych mount z perl

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

skutkuje:

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

nie mogę nazwać program mount korzystając system bo muszę zrobić wywołanie systemowe mount() że program mount nie wydają się być zdolne. Dokładniej, muszę zadzwonić:

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

Ale jeśli próbuję uruchomić następujące z nieuprzywilejowany niewspółdzielone mocowanie linux nazw:

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

Następnie pojawia się następujący błąd:

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. 

Korzystanie z ujawnia, że ​​program faktycznie działa pod nazwą:

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

Ale to dzielenie opcji nie działa. Potrzebuję MS_BIND i MS_REC|MS_PRIVATE w jednym wywołaniu wywołania systemowego mount, aby działał w nieuprzywilejowanej wolnej przestrzeni nazw montowania.

Jak mogę wykonać moje pierwsze wywołanie systemowe w perlu bez komunikatu o próbie modyfikacji wartości tylko do odczytu?

edit:

szczęście Ikegami było szybkie podkreślić, co zrobiłem źle, gdy próbują wykorzystać syscall funkcji Perl, ale w przypadku ktoś znajdzie ten, szukając jak związać zamontować katalog z poziomu nieuprzywilejowany Górze nazw tylko z linii poleceń narzędzia mount, oto jak:

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

to z kolei wywoła następujące syscall wewnętrzne:

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

Wydaje się, że flaga MS_MGC_VAL jest kompatybilna z poprzednimi wersjami jądra przed wersją 2.4. Ważne bity to MS_BIND (za wykonanie samego bindowania) i MS_REC (za wykonanie tej operacji rekursywnie, aby katalogi, których zawartość została ukryta w innych mountach, nie zostały ujawnione w obszarze nazw mount).

Więc teraz muszę zdecydować, czy pójdę z Perl system wywołania funkcji lub po prostu zrobić mount wywołanie systemowe, ponieważ zarówno do pracy, jak dobrze :)

Odpowiedz

8

syscall odmawia przekazać wskaźnik do bufora string stałą ponieważ nie ma pojęcia, czy argument jest char * lub 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

Rozwiązanie jest proste. Wystarczy najpierw skopiować stałą do zmiennej.

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

panu/pani po prostu made my day! Teraz widzę, że dokumenty 'syscall' mówią" Nie możesz użyć ciągu literowego (lub innego ciągu tylko do odczytu) jako argumentu "... głupio mi, powinienem mieć RTFM ... Niemniej jednak, skoro ty właśnie uratowałeś mi wiele bólów głowy Życzę Ci wielu przebojów :) – josch

+0

Doh! Również tego nie przeczytałem! Poprawiłem trochę moją odpowiedź. – ikegami