mv, затронутый bind mounts (ощущается как ошибка)

Вопрос или проблема

Изначально 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 подумать, что необходимо выполнить межустройство перемещение.

Применение

Для решения данной проблемы вы можете предпринять следующие шаги:

  1. Проверка и управление монтировками: При работе с командой mv, особенно в контексте сложных монтирований, таких как bind-монтирования, убедитесь, что они не мешают корректной работе rename. В вашем случае, отсоединение дополнительного bind-монтирования /QNAP/mounts/rest2/Public позволило выполнить мгновенный и корректный перемещение без использования ресурсоемкого копирования и удаления.

  2. Проектирование монтирований: При планировании ресурсов системы и структуре файловых систем, учитывайте возможные запутывания из-за множества точек монтирования. Это поможет не только избежать проблем с командами, такими как mv, но и упростит обслуживание системы в будущем.

  3. Просмотр документации и использования инструментов: Иногда, для решения таких задач необходимо углубиться в документацию системных вызовов Linux и инструментов, таких как mv, чтобы понять, какое поведение ожидать при разных конфигурациях системы.

Хотя это может показаться незначительной деталью, корректная конфигурация монтирований и понимание системных вызовов позволяют значительно оптимизировать вашу работу с файловой системой и избегать неожиданных затрат ресурсов. Ваша ситуация – это хороший пример того, как знание внутреннего устройства операционной системы и её поведений на практике может помочь в решении технических задач.

Следует отметить, что предложенные изменения и обновления в утилите mv обсуждались с разработчиками coreutils, но не были реализованы из-за сложности их внедрения. Поэтому, до каких-либо изменений в стандартных инструментах, системным администраторам приходится полагаться на свои знания и опыт в управлении операционными системами.

Оцените материал
Добавить комментарий

Капча загружается...