Вопрос или проблема
Изначально mv(1)
была операцией переименования; она обновляла имена в файловых системах и не копировала файлы. Недавно была добавлена функция удобства, при которой, если источник и цель находились на разных файловых системах, файлы копировались и удалялись. Также известна как “перемещение между устройствами”.
Теперь я пытался привести в порядок свои резервные копии. Я хотел переместить .../rest2/Public/Backups
в .../rest2/Backup/(Backups)
, так что:
root@ts412:/QNAP/mounts/rest2# mv Public/Backups Backup/
Где:
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
Так что тот же самый файл:
(К вашему сведению, rest2
это “оставшееся пространство на disk2
“)
Но перемещение начало вести себя как “перемещение между устройствами” (высокая загрузка процессора, диски заняты, различные ошибки о ненулевых каталогах и т. д.), поэтому я его отменил.
Проверка немного по-другому (обратите внимание на .
):
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
Потом я вспомнил, что у меня также была связанная точка монтирования (она делает имена, разделяемые через NFS, более понятными).
Так что я размонтировал дополнительную связанную точку монтирования:
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/
И mv(1)
была мгновенной, как я и ожидал.
Таким образом, несмотря на дополнительные mount(8)
, источник и цель всегда были в одной файловой системе, mount -o bind /QNAP/mounts/rest2/Backups /Backups
на это не влияет. Поэтому я задался вопросом, если mv(1)
получает точки монтирования /QNAP/mounts/rest2
для одного и /QNAP/mounts/rest2/Public
для другого, оно ошибочно решает, что два файла находятся на разных файловых системах?
Строго говоря, не mv
решает, что два файла находятся в разных файловых системах, а ядро. mv
должен вслепую пытаться выполнить базовую операцию rename
; только если это не удается с EXDEV
(указывая, что два операнда находятся в разных файловых системах), оно начинает вручную копировать и удалять файлы.
На Linux, однако, rename
только заботится о точках монтирования, он не учитывает основную файловую систему:
(Linux разрешает монтировать файловую систему в нескольких
точках, ноrename()
не работает между различными точками монтирования, даже если одна и та же файловая система монтирована оба раза.)
mv
мог бы обнаружить это, используя специфические для Linux функции, и это было предложено разработчикам coreutils (с концепцией), но в то время это было сочтено слишком сложным.
Смотрите также Mount –bind в той же файловой системе перемещает файлы как в той же файловой системе.
.
Ответ или решение
Ваша ситуация связана с особенностями работы команды mv
и поведения ядра Linux при обработке операции перемещения файлов. Как вы правильно заметили, исходное предназначение команды mv
заключалось в простом переименовании файлов в пределах одной файловой системы. Однако, для удобства пользователей была добавлена возможность так называемых «межустройства перемещений», при которой файлы копируются и затем удаляются, если исходный и целевой каталоги находятся на разных файловых системах.
Основным аспектом здесь является то, как ядро Linux обрабатывает сигналы о различных файловых системах. Напомним, что к ядру Linux могут применяться несколько различных монтировок одной и той же файловой системы, и такая ситуация нередко может привести к путанице, особенно в присутствии bind-монтирований.
Теория
Когда вы выполняете команду mv
, она пытается сначала выполнить системный вызов rename
, который обновляет путь файла без копирования его содержимого. Однако, rename
возвращает ошибку EXDEV
, если исходный и целевой пути располагаются на разных точках монтирования (mount points), даже если это одна и та же физическая файловая система. В таком случае, mv
переходит к копированию и удалению файлов, что задействует копирование данных и может быть значительно более ресурсоемким.
Пример
В вашем случае, вы имеете директории .../rest2/Public/Backups
и .../rest2/Backup/(Backups)
на одной и той же файловой системе /dev/sdb10
. Однако, в момент выполнения команды mv Public/Backups Backup/
у вас было активное bind-монтирование .../rest2/Public
, что могло привести к тому, что системный вызов rename
видел разные точки монтирования для источника и цели.
Даже несмотря на то что обе директории находятся на одной и той же физической файловой системе, различие в точках монтирования вводит систему в заблуждение, заставляя mv
подумать, что необходимо выполнить межустройство перемещение.
Применение
Для решения данной проблемы вы можете предпринять следующие шаги:
-
Проверка и управление монтировками: При работе с командой
mv
, особенно в контексте сложных монтирований, таких как bind-монтирования, убедитесь, что они не мешают корректной работеrename
. В вашем случае, отсоединение дополнительного bind-монтирования/QNAP/mounts/rest2/Public
позволило выполнить мгновенный и корректный перемещение без использования ресурсоемкого копирования и удаления. -
Проектирование монтирований: При планировании ресурсов системы и структуре файловых систем, учитывайте возможные запутывания из-за множества точек монтирования. Это поможет не только избежать проблем с командами, такими как
mv
, но и упростит обслуживание системы в будущем. -
Просмотр документации и использования инструментов: Иногда, для решения таких задач необходимо углубиться в документацию системных вызовов Linux и инструментов, таких как
mv
, чтобы понять, какое поведение ожидать при разных конфигурациях системы.
Хотя это может показаться незначительной деталью, корректная конфигурация монтирований и понимание системных вызовов позволяют значительно оптимизировать вашу работу с файловой системой и избегать неожиданных затрат ресурсов. Ваша ситуация – это хороший пример того, как знание внутреннего устройства операционной системы и её поведений на практике может помочь в решении технических задач.
Следует отметить, что предложенные изменения и обновления в утилите mv
обсуждались с разработчиками coreutils, но не были реализованы из-за сложности их внедрения. Поэтому, до каких-либо изменений в стандартных инструментах, системным администраторам приходится полагаться на свои знания и опыт в управлении операционными системами.