Почему каталог может быть удален, когда моя оболочка использует этот каталог? - PullRequest
1 голос
/ 31 января 2020

Я не знаю, было ли то, с чем я столкнулся, было ошибкой или предполагаемым поведением, но, к счастью, я довольно быстро понял, что происходит.

Мой cd-файл оболочки находился в подкаталоге репозитория git, и я выполнил операцию git rebase -i squa sh, в которой задействованный коммит включал создание этого каталога.

После того, как эта операция завершилась без инцидентов, оболочка перешла в потерянное состояние, где git status (ни в RPROMPT помощника по теме zsh, ни при запуске) не указывало, что я даже больше не был в репозитории git ,

Как только я запустил cd .. все было хорошо, и все это имело смысл. В ходе операции перебазирования Git имел rm d каталога, в котором я находился (на первом шаге перебазировки), и впоследствии возвращал его обратно. С тех пор как его вернули, я мог бы за один шаг запустить cd $(pwd) до go.

Это немного запутанное поведение. Хотя, не ясно, что технически что-то было сделано неправильно git. У меня вопрос: может ли это быть ошибкой в ​​git или пользователи должны знать, как справиться с этой ситуацией?

Кроме того, более широкий актуальный вопрос root: почему разрешено удалять каталог, в котором находится моя оболочка, когда не разрешено извлекать диск, если у меня есть оболочка в смонтированном каталоге? Это кажется мне противоречивым.

Показательный пример: fuser <directory> показывает текущее использование каталога. Если программа находится в каталоге, она «использует» ее.

Ответы [ 2 ]

1 голос
/ 02 февраля 2020

Чтобы ответить на ваш первый вопрос:

Это не ошибка, это то, как Unix системы, в том числе Linux, всегда работали.

Есть даже хороший текст в POSIX spe c:

[EBUSY] Удаляемый каталог в настоящее время используется системой или каким-либо процессом, и реализация считает это ошибкой.

А именно, некоторые реализации (например, Windows ...) могут назвать это ошибкой, но большинство реализаций. а именно Unix вариантов, нет.

Способ, которым это реализовано в файловой системе, заключается в том, что процессы хранят ссылку на объект, который представляет каталог. Другая вещь, которая содержит такую ​​ссылку, является родительским каталогом. git rebase удалил последнюю ссылку, но первая остается. Даже если каталог создается заново, это новый объект файловой системы, в то время как ваша оболочка содержала ссылку на старый объект.

Именно поэтому cd .. и cd $(pwd) все еще работают - они повторно ищут каталог и захват новой ссылки, и освободите старую ссылку.

Официально старый объект не очищен, пока старая ссылка не выпущена. Это означает, что метаданные каталога не удаляются с диска до тех пор, пока процесс не освободит старый рабочий каталог.

Чтобы ответить на второй вопрос:

Чтобы извлечь диск, необходимо демонтируйте точку монтирования, и, как указано выше, процессы, которые вы обнаружите с помощью fuser, содержат ссылки на эту точку монтирования.

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

Единственное, что нужно сделать, это разрешить отсоединение файловой системы от дерева каталогов без фактической очистки. Вы по-прежнему не сможете извлечь диск, но, по крайней мере, вы можете использовать дерево каталогов так, как вы: sh.

Ну, это действительно возможно сделать с umount --lazy.

1 голос
/ 31 января 2020

Клемма 1:

$ cd tmp/
$ mkdir test
$ cd test

Клемма 2:

$ rmdir tmp/test 

Клемма 1:

$ ls 
sh: 0: getcwd() failed: No such file or directory

Несогласовано, да. Но разрешено.

PS. И это не имеет ничего общего с git.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...