2015-10-21 28 views
5

Come può essere effettuata la chiamata di sistema mount da perl? I seguenti:Esecuzione della chiamata di sistema di montaggio da perl

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

risultati in:

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

non posso chiamare il programma mount utilizzando system perché ho bisogno di fare una chiamata di sistema mount() che il programma mount non sembra essere in grado di. Più in particolare, ho bisogno di chiamare:

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

Ma se provo a eseguire il seguente con una senza privilegi non condiviso namespace monte linux:

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

Poi ho il seguente errore:

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. 

L'utilizzo di strace rivela che il programma mount deve effettivamente chiamare:

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

Ma questa divisione di opzioni non funziona. Ho bisogno di MS_BIND e MS_REC|MS_PRIVATE in una singola chiamata alla chiamata di sistema mount affinché funzioni in uno spazio dei nomi non condiviso con supporto non condiviso.

Così come posso fare la mia chiamata iniziale del sistema in perl senza il messaggio di errore circa un tentativo di modifica di un valore di sola lettura?

modificare:

fortuna Ikegami è affrettato a sottolineare che cosa ho fatto di sbagliato quando si cerca di utilizzare la funzione di perl syscall ma nel caso in cui qualcuno trova questo durante la ricerca di come associare montare una directory all'interno di un monte senza privilegi spazio dei nomi con solo l'utilità della riga di comando mount, ecco come:

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

questo a sua volta chiamare il seguente syscall internamente:

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

Il MS_MGC_VAL bandiera sembra che sia per la compatibilità con le versioni di kernel precedenti alla 2.4. I bit importanti sono MS_BIND (per fare il montaggio del binding stesso) e MS_REC (per farlo in modo ricorsivo in modo che le directory che hanno il loro contenuto nascosto da altri montaggi in corso su di esse non abbiano il loro contenuto esposto nello spazio dei nomi di mount).

Così ora devo decidere se vado con una funzione di chiamata di Perl system o semplicemente fare la chiamata di sistema mount perché entrambi lavorano altrettanto bene :)

risposta

8

syscall rifiuta di passare un puntatore al buffer di stringa di una costante dal momento che non ha idea se l'argomento è char * o 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

La soluzione è semplice. È sufficiente copiare prima la costante in una variabile.

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

prova:

$ 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

È signore/a solo fatto il mio giorno! Ora vedo che i documenti di 'syscall' dicono" Non puoi usare una stringa letterale (o altra stringa di sola lettura) come argomento "... sciocco me, dovrei avere RTFM ... Tuttavia, dato che tu mi hai appena risparmiato molti mal di testa ti auguro molti voti positivi :) – josch

+0

Doh! Non avevo letto neanche quello! Migliorata la mia risposta un po '. – ikegami