Гарантированно ли два подкаталога с одинаковым корнем находятся в одной смонтированной файловой системе?

Есть две проблемы;

Первая заключается в том, что внутри каждой команды bash -ic (которая, кстати, не порождает интерактивную оболочку, потому что -c переопределяет -i , поэтому -i безопасно быть отброшенным) вы вызываете bash disown вместо bash , что ничего не значит и немедленно завершает работу при ошибке; поэтому нет интерактивной оболочки, которая бы открывала gnome-terminal в конце внешней команды bash -c ;

(Также помните, что вы можете использовать exec bash вместо bash в конце команды, чтобы сохранить некоторые процессы.)

Второй - это Ctrl + C SIGINT. все процессы в одной группе убитого процесса, включая родительский экземпляр bash , который должен порождать интерактивную оболочку в конце команды;

Чтобы исправить это, вы можете использовать ] bash ловушка , встроенная для установки bash для создания другого интерактивного экземпляра bash при приеме сигнала SIGINT.

Короче говоря, это должно работать:

gnome-terminal \
  --tab-with-profile=Default --title=PROG1 -e "bash -c \"trap 'bash' 2; clear;ls;./prog1; exec bash\"" \
  --tab-with-profile=Default --title=SIMULATOR -e "bash -c \"trap 'bash' 2; clear;ls;./simulator; exec bash\"" \
  --tab-with-profile=Default --title=PROG2 -e "bash -c \"trap 'bash' 2; clear;ls;./prog2; exec bash\"" \
  --tab-with-profile=Default --title=DATA -e "bash -c \"trap 'bash' 2; ./data -f \"/home/user/NetBeansProjects/data3.txt\" -p \"6785\"; exec bash\"" \
  --tab-with-profile=Default --title=PROG3 -e "bash -c \"trap 'bash' 2; cd /home/user/NetBeansProjects/simulator;./prog3; exec bash\"" \
&
5
08.05.2018, 21:49
3 ответа

Им это не гарантируется. Возможно, /foo/oldPathявляется точкой монтирования.

Однако это можно легко проверить, запустив mount | grep 'on /foo/oldPath'Ни один вывод не должен указывать на то, что каталог oldPathне является точкой монтирования.

Вам нужно быть более осторожным, если вы используете вложенные каталоги, так как вы можете иметь точку монтирования где угодно.

Я не уверен, что это автоматизировано, но стоит отметить, что третье поле из mount (, разделенное пробелом -), является точкой монтирования для каждой строки, поэтому использование cut -d ' ' -f 3может быть используется для извлечения пути (, если вам нужно убедиться, что это не просто подстрока другой точки монтирования, например/foo/oldPath/nested/mountPoint)

Если вы хотите перевести это в код C/C++, вы можете использовать system("mount | grep 'on /foo/oldPath'"), но я не буду на этом клянусь. Возможно, вам повезет больше на StackOverflow, где вы найдете более подробную информацию о реализации, если вам это нужно.

14
27.01.2020, 20:31

Обратите внимание, что при работе с overlayfs нельзя полагаться на rename()из существующих до -каталогов.

Я думаю, что вы обычно можете игнорировать эту возможность, если вы не пишете инструмент управления файлами общего назначения... Например, менеджер пакетов ... в этом случае вы, по-видимому, можете не рассматривать это поправимо (по причинам атомарности )и вы хотите полагаться на новый redirect_dirформат оверлеев.

Так что это скорее педантичная заметка, чтобы вы знали, что это Linux, мы не соблюдаем POSIX, если не хотим, и "гарантировано" - это очень сильно сказано :).


https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt

Unless "redirect_dir" feature is enabled, rename(2) on a lower or merged directory will fail with EXDEV.

Overlayfs уже не соответствует обычным ожиданиям файловой системы unix в других деталях:

Objects that are not directories (files, symlinks, device-special files etc.) are presented either from the upper or lower filesystem as appropriate. When a file in the lower filesystem is accessed in a way the requires write-access, such as opening for write access, changing some metadata etc., the file is first copied from the lower filesystem to the upper filesystem (copy_up)...

The copy_up operation essentially creates a new, identical file and moves it over to the old name. Any open files referring to this inode will access the old data.

4
27.01.2020, 20:31

Вы не должны пытаться это сделать, по ряду причин (, подробно описанных в других ответах ):/foo/oldPath, может быть точкой монтирования, или может присутствовать оверлейная файловая система, препятствующая перемещению файлов. Вы даже можете столкнуться с монтированием привязки для отдельных файлов, что также вызовет проблемы при переименовании файлов.

Вместо того, чтобы пытаться заранее определить, можно ли переименовать файлы, следует попытаться переименовать их и устранить ошибки.renameвернет -1, если произойдет ошибка, а errnoбудет установлено на EXDEV, если переименование невозможно из-за проблем с перекрестным -монтированием. Затем вы можете действовать другим способом (скопировать и удалить ).

В общем случае, чтобы определить, находятся ли два объекта файловой системы в одной и той же файловой системе, следует запустить для нихstatи посмотреть идентификатор устройства (в поле st_devвstruct stat). Два объекта файловой системы в одной и той же файловой системе будут иметь одинаковый идентификатор устройства.

5
27.01.2020, 20:31

Теги

Похожие вопросы