Почему перенаправление файлов происходит успешно при сбое cp / mv? - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь перезаписать /etc/resolv.conf в Docker контейнере с Alpine Linux на EKS. Скопировать и переместить оба не удастся:

~ # cp /tmp/resolv.conf /etc/resolv.conf 
cp: can't create '/etc/resolv.conf': File exists
~ # mv /tmp/resolv.conf /etc/resolv.conf 
mv: can't rename '/tmp/resolv.conf': Resource busy

Но перенаправление оболочки завершается успешно и сохраняет индекс:

~ # ls -li /etc/resolv.conf 
1412461 -rw-r--r--    1 root     root           131 Feb 17 20:45 /etc/resolv.conf
~ # cat /tmp/resolv.conf.1386 > /etc/resolv.conf 
~ # ls -li /etc/resolv.conf 
1412461 -rw-r--r--    1 root     root            39 Feb 18 19:17 /etc/resolv.conf

Почему перенаправление успешно выполняется на занятом файле?

1 Ответ

0 голосов
/ 19 февраля 2020

Перенаправление не изменяет каталог, в котором находится файл , тогда как mv делает. Это очень важно, когда - как здесь - ваша «запись каталога» на самом деле является точкой монтирования, где ядро ​​переопределяет запись каталога и не позволяет отображать обычное содержимое.

То есть:


Что mv foo bar делает

mv foo bar

... на уровне операционной системы вызывает системный вызов rename("foo", "bar"), заменяя запись каталога bar с индексом, на который в данный момент указывает запись каталога foo. Он никогда не открывает и не изменяет существующий файл bar; только делает то, что он изменяет каталог, который ранее содержал этот файл, чтобы вместо него указывать на другой файл в записи с тем же именем.


Что echo hello > bar делает

В отличие от этого echo hello >bar вообще не меняет запись каталога ; это только изменение файла, на который указывает запись каталога. В частности, он запускает open("bar", O_TRUNC) и write(<fdno>, "hello\n") в файловом дескрипторе, который вернул open().


Итак, что делает cp?

... это хороший вопрос. Обычно , cp изменяет существующий файл на месте. Вы можете проверить это следующим образом:

echo ORIGINAL > file1
ln file1 file2
echo REPLACED > file3
cp file3 file1
cat file2

Если cp заменили file1 на совершенно новый файл, то индекс, с которым связан file2, не изменится (содержащий "ОРИГИНАЛЬНЫЙ") , Это не то, что происходит, хотя - file2 модифицируется cp, который только непосредственно идентифицирует file1 в качестве выходного файла, изменяя этот файл на REPLACED.

Мне нужно см. вывод strace cp /tmp/resolv.conf /etc/resolv.conf для диагностики описанного поведения.

...