Non è garantito che. È possibile che /foo/oldPath
è un punto di montaggio.
Tuttavia, questo può essere facilmente controllato eseguendo mount | grep 'on /foo/oldPath'
Nessun output dovrebbe indicare che oldPath
la directory non è un punto di montaggio.
Dovrai fare più attenzione se utilizzi directory nidificate, poiché puoi avere un punto di montaggio ovunque.
Non sono sicuro che questo sia automatizzato, ma vale la pena notare che il terzo campo da mount (separato da spazi) è il punto di mount per ogni riga, quindi utilizzando un cut -d ' ' -f 3
potrebbe essere usato per estrarre il percorso (se hai bisogno di verificare che non sia solo una sottostringa di un altro punto di montaggio, come /foo/oldPath/nested/mountPoint
)
Se desideri tradurre questo in codice C/C++, potresti essere in grado di utilizzare system("mount | grep 'on /foo/oldPath'")
, ma non ci giurerò. Potresti avere più fortuna su StackOverflow per ulteriori dettagli sull'implementazione se ne hai bisogno.
Non dovresti tentare questo, per una serie di motivi (dettagliati nelle altre risposte):/foo/oldPath
potrebbe essere esso stesso un punto di montaggio o potrebbe essere presente un file system overlay che impedisce lo spostamento dei file. Puoi persino incontrare bind mount, su singoli file, che causeranno anche problemi durante la ridenominazione dei file.
Invece di provare a determinare in anticipo se i file possono essere rinominati, dovresti provare a rinominarli e gestire gli errori. rename
restituirà -1 se si verifica un errore e errno
sarà impostato su EXDEV
se la ridenominazione non è possibile a causa di problemi di montaggio incrociato. Puoi quindi procedere in un altro modo (copia ed elimina).
In generale, per determinare se due oggetti del file system si trovano sullo stesso file system, dovresti eseguire stat
su di essi e guarda l'identificatore del dispositivo (il st_dev
campo in struct stat
). Due oggetti file system sullo stesso file system avranno lo stesso identificatore di dispositivo.
Nota che quando esegui overlayfs, non puoi fare affidamento su rename()
di directory preesistenti.
Penso che di solito potresti ignorare questa possibilità, se non stai scrivendo uno strumento di gestione file generico ... Ad esempio, un gestore di pacchetti ... nel qual caso apparentemente potresti non considerarlo risolvibile (per motivi di atomicità) e vuoi affidarsi al nuovo redirect_dir
formato di overlayf.
Quindi questa è più una nota pedante per farti sapere che questo è Linux, non rispettiamo POSIX se non vogliamo, e "garantito" è una parola molto forte :).
https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt
A meno che la funzione "redirect_dir" non sia abilitata, rename(2) su una directory inferiore o unita fallirà con EXDEV.
Overlayfs già non corrisponde alle solite aspettative di un filesystem unix in altri dettagli:
Gli oggetti che non sono directory (file, collegamenti simbolici, file speciali del dispositivo ecc.) sono presentati dal filesystem superiore o inferiore a seconda dei casi. Quando si accede a un file nel filesystem inferiore in un modo che richiede l'accesso in scrittura, come l'apertura per l'accesso in scrittura, la modifica di alcuni metadati ecc., il file viene prima copiato dal filesystem inferiore al filesystem superiore (copy_up)...
L'operazione copy_up essenzialmente crea un nuovo file identico e lo sposta con il vecchio nome. Tutti i file aperti che fanno riferimento a questo inode accederanno ai vecchi dati.