Originalmente, mv(1)
era uma operação de renomeação; atualizava nomes em sistemas de arquivos e não copiava arquivos. Mais recentemente, um recurso de conveniência foi adicionado, pelo qual se a origem e o destino estivessem em sistemas de arquivos diferentes, ele copiaria e excluiria os arquivos. Também conhecido como "inter-device move".
Agora eu estava tentando arrumar meus backups. Eu queria mudar .../rest2/Public/Backups
para .../rest2/Backup/(Backups)
, então:
root@ts412:/QNAP/mounts/rest2# mv Public/Backups Backup/
Onde:
root@ts412:/QNAP/mounts/rest2# df -h /QNAP/mounts/rest2/Public/
Filesystem Size Used Avail Use% Mounted on
/dev/sdb10 831G 715G 75G 91% /QNAP/mounts/rest2
root@ts412:/QNAP/mounts/rest2# df -h /QNAP/mounts/rest2/Backup/
Filesystem Size Used Avail Use% Mounted on
/dev/sdb10 831G 715G 75G 91% /QNAP/mounts/rest2
Então, o mesmo sistema de arquivos:
(Para sua informação, rest2
é "o resto do espaço em disk2
")
Mas a mudança começou a se comportar como uma "mudança entre dispositivos" (alta CPU, discos ocupados, vários erros sobre diretórios não vazios etc.), então eu a eliminei.
Verificando de uma forma ligeiramente diferente (observe o .
):
root@ts412:/QNAP/mounts/rest2# df -h Backup/.
Filesystem Size Used Avail Use% Mounted on
/dev/sdb10 831G 715G 75G 91% /QNAP/mounts/rest2
root@ts412:/QNAP/mounts/rest2# df -h Public/Backups/.
Filesystem Size Used Avail Use% Mounted on
/dev/sdb10 831G 715G 75G 91% /QNAP/mounts/rest2/Public
Então eu lembro que EU TAMBÉM tinha um bind mount (ele torna os nomes compartilhados via NFS mais amigáveis). Então eu desmontei o bind mount extra:
root@ts412:/QNAP/mounts/rest2# umount /QNAP/mounts/rest2/Public
root@ts412:/QNAP/mounts/rest2# df -h Public/Backups/.
Filesystem Size Used Avail Use% Mounted on
/dev/sdb10 831G 715G 75G 91% /QNAP/mounts/rest2
root@ts412:/QNAP/mounts/rest2# mv Public/Backups Backup/
E mv(1)
foi instantâneo, como eu esperava.
Então, apesar dos s extras mount(8)
, a fonte e o alvo sempre estavam no mesmo sistema de arquivos , o que mount -o bind /QNAP/mounts/rest2/Backups /Backups
não afeta isso. Então, estou pensando se mv(1)
obtém pontos de montagem de volta /QNAP/mounts/rest2
para um e /QNAP/mounts/rest2/Public
para o outro, ele decide incorretamente que os dois arquivos estão em sistemas de arquivos diferentes?
A rigor, não é ele
mv
quem decide que os dois arquivos estão em sistemas de arquivos diferentes, é o kernel.mv
Ele deve tentar cegamente uma operação básicarename
; somente se isso falharEXDEV
(indicando que os dois operandos estão em sistemas de arquivos diferentes) ele copia e remove os arquivos manualmente.No Linux, no entanto, ele
rename
só se preocupa com pontos de montagem , não considerando o sistema de arquivos subjacente:mv
poderia detectar isso usando recursos específicos do Linux, e isso foi sugerido aos desenvolvedores do coreutils (com uma prova de conceito), mas foi considerado muito complexo na época.Veja também Mount --bind no mesmo sistema de arquivos move arquivos como se estivessem no mesmo sistema de arquivos .
Preciso acrescentar mais algumas informações porque acho que fui ambíguo e tropecei em uma questão relacionada (e muito interessante).
A VERDADEIRA montaria é:
Tenho 2 montagens de ligação significativas:
(Para sua informação, isso é SOMENTE para que eu possa fazer: exportfs -o rw *:/Public, caso contrário, não uso /Public etc)
Se eu tivesse feito:
Então percebi que cairia nos problemas com movimentações entre dispositivos discutidos nos comentários.
Mas, se eu converter meus exemplos de nomes de caminho relativos para nomes de caminho completos, o que eu estava tentando fazer era:
O que se comportou como uma movimentação entre dispositivos até que eu fiz:
(este é o nome usado na montagem de ligação acima)
então:
Foi instantâneo (sem movimentação entre dispositivos)
Agora, neste ponto, estou começando a duvidar da minha memória, então voltei e fiz:
(ou seja, movendo-o para trás)
e novamente funcionou como um movimento entre dispositivos!
NO ENTANTO, ao verificar, descobri
root@ts412:/QNAP/mounts/rest2# mount | grep Público
/dev/sdb10 em /Público tipo ext4 (rw,relatime)
/dev/sdb10 em /Público tipo ext4 (rw,relatime)
/dev/sdb10 em /Público tipo ext4 (rw,relatime)
/dev/sdb10 em /QNAP/mounts/rest2/Público tipo ext4 (rw,relatime)
root@ts412:/QNAP/mounts/rest2# mount | grep Backup
/dev/sdb10 em /Backup tipo ext4 (rw,relatime)
Os valores para "/Backup" são o que eu espero/pretendo, as múltiplas entradas para /Public não são nada do que eu esperava.
Que /QNAP/mounts/rest2/Public não deveria estar lá... e como o caminho corresponde ao mv(1) acima, É POR ISSO que parece ser interdispositivo (sujeito à explicação de Stephen Kitt )
...então como ele chega lá? Na raiz está um script (fragmento):
Que pode ser chamado (neste exemplo) de
Deve causar:
/dev/disk/by-label/rest2 para ser montado em /QNAP/mounts/rest2 Então: /share/Backup para (sym) link para /QNAP/mounts/rest2/Backup /share/Public para (sym) link para /QNAP/mounts/rest2/Public ... E também uma exportação NFS de /Public /Backup ...
Entretanto, o código originalmente não tinha essas 2 linhas sob o comentário "Estranhamente..."
Essa função acaba sendo invocada pelo udev (por exemplo, quando um disco é conectado), então pode ser executada diversas vezes.
Estou começando a perder o fio da meada, mas acho que a montagem de ligação emitida repetidamente fez com que a montagem extra espúria existisse [empilhada?] e, portanto, levou ao problema original! ...ufa.
Então, minha surpresa inicial foi que, embora eu não estivesse usando a montagem bind, sua mera existência fez com que um mv(1) normal "estragasse tudo"... mas descobri que EU ESTAVA usando uma montagem bind, mas não percebi.