mv и cp: чем отличается полученный файл?

mv и cp: чем отличается полученный файл?

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

В конце концов я сделал точную копию файла, но старая все равно не работала, а вот новая работала отлично.

Более того, если я использую mvкоманду для перемещения файла из того места, где он хранится, в то место, где он должен быть, это приводит к ошибкам. Если я использую команду cpдля копирования файла в то место, где он должен быть, ошибок не возникает.

Очевидно, что такие вещи, как diff, file, или ls -l, не показывают никаких различий между двумя файлами, поскольку один является копией другого,поскольку cpделает точную копию файла.

Я не могу поделиться слишком большой информацией о файле, потому что это рабочая вещь. Суть в том, что команды cp fileA fileBи mv fileA fileBсоздают "другой" файлB. Моя лучшая догадка - какой-то атрибут супернизкого уровня из файлаB остается позади во время cp(даже cp -pпроизводит то же самое поведение).

Чем mv отличается от cp в отношении точного содержимого результирующего файла?

ИЗМЕНИТЬ: С ls -l:

-rw-r--r--. 1 root root 3389 Aug  8 22:53 fileA
-rw-r--r--. 1 root root 3389 Aug  8 23:03 fileB

EDIT: Приложение — mysql, файл — файл .cnf, и элемент в этом файле конфигурации, который особенно интересен, — это имя двоичного журнала, используемого в репликации базы данных master-slave. «Ошибка» — «вы не используете двоичное ведение журнала», поскольку двоичного журнала нет, поскольку этот элемент никогда не «читался» mysql.

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

EDIT: К чему-то приближаемся... Наконец-то что-то новое в файлах.

ls -lZ

-rw-r--r--. root root unconfined_u:object_r:user_home_t:s0 server.cnf.bad
-rw-r--r--. root root unconfined_u:object_r:mysqld_etc_t:s0 server.cnf.good

решение1

TL;DR: в системе, гдеSELinuxиспользуется, файлы, используемые системой (например, демоны), следует копировать или перемещать с помощью cp -aZи mv -Zвместо cp -aи mv. Если это не было сделано, следует просто использовать restorecon -v -rили restorecon -v -F -rна месте назначения, чтобы попросить систему восстановить контексты SELinux по умолчанию. Всегда полезно использоватьrestoreconв конце скрипта, который работал с ключевыми файлами конфигурации.

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

Итак, чтобы решить вашу проблему, если ваша система основана на RHEL и использует mariadb-serverпакет, просто сделайте это на последнем шаге, когда файл находится вправильное место:

# restorecon -v -F /etc/my.cnf.d/server.cnf
Relabeled /etc/my.cnf.d/server.cnf from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:mysqld_etc_t:s0

(Обратите внимание, что без -Fэтого не произошло бы изменения unconfined_uв настроенном system_u. Это не имело бы значения для обычных систем. Мои знания о разнице и о том, почему это не имеет значения, не простираются так далеко).

Просто потребовалось бы больше работы, чтобы поместить правильный контекст в файлдругойместо.chconможно сделать это (либо указав это с помощью -u -tи т. д., либо проще скопировав контекст из другого файла с помощью --reference):

# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad
# chcon -v -u system_u -t mysqld_etc_t /home/test/server.cnf.bad 
changing security context of '/home/test/server.cnf.bad'
# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root system_u:object_r:mysqld_etc_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad

Если вы подозреваете проблемы с SELinux, проверьте /var/log/audit/audit.logзаписи со словом, deniedсвязанным с вашим процессом или файлом. Вы всегда можете временно попросить SELinux разрешить операции, а затем восстановить их, соответственно, setenforce Permissiveи setenforce Enforcingдля сравнения поведения. Не оставляйте его на, Permissiveособенно для производства.

Различные объяснения ниже...

Пример и что следует делать при работе с файлами конфигурации

Пример поведения с различными cpпараметрами и mvв системе с включенным SELinux:

$ id
uid=1034(test) gid=1034(test) groups=1034(test)
$ pwd
/home/test
test@glasswalker:~$ ls -lZ foo
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 foo
$ cp foo /tmp/foo1
$ cp --preserve=context foo /tmp/foo2
$ cp -a foo /tmp/foo3
$ cp -aZ foo /tmp/foo4
$ mv foo /tmp/foo5
$ ls -lZ /tmp/foo?
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo1
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo2
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo3
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo4
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo5
$ touch bar
$ ls -lZ bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:49 bar
$ mv -Z bar /tmp
$ ls -lZ /tmp/bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:49 /tmp/bar

Поэтому использование cp -aZor mv -Zработает нормально, когда контексты безопасности имеют значение, и при этом сохраняет другие атрибуты. Скрипт, перемещающий системные файлы, всегда должен использовать опцию -Zдля любой команды cpor mvили просто использовать restoreconна своем последнем шаге, чтобы избежать неожиданных проблем.

Почему такие различия?

Команда mvсохраняет согласованное поведение. Если бы это произошло в той же файловой системе, конечно, все, что прикреплено к файлу, включая его контекст безопасности, не было бы изменено, поскольку это просто «переименование». Таким образом, в двух файловых системах, где это фактически копирование с последующим удалением, она также копирует без изменений все, что прикреплено к файлу и о чем она знает, включая его контекст безопасности, для согласованности.

Команда cpпо умолчанию простосоздаетновый файл, поэтому этот файл наследует контекст selinux родителя, как обычно, если, конечно, не указано иное, с помощью --preserve=contextкоторого включен в -a. --preserve=contextможно вычесть из -aс помощью опции -Z, поэтому лучшим вариантом при копировании целых древовидных структур является использование -aZвместо , -aесли SELinux имеет значение.

По умолчанию при создании файла, что является обычным случаем, этот новый файл наследует контекст SELinux своего каталога, поэтому все работает нормально (не по теме: в редких случаях контекст файла должен отличаться от контекста его каталога просто из-за правила для его имени, ядру все равно, программы вроде демонаrestorecondпотребуется для его обработки).

Что такое SELinux

SELinux — это механизм обязательного контроля доступа (он жеМАК) используется в дополнение ко всем другим механизмам (разрешениям Unix, также известным какЦАП, Списки контроля доступа, также известные какACLи т. д.). Когда процесс выполняется в контексте безопасности процесса, существует «матрица правил», чтобы проверить, соответствует ли этопроцессконтекст может выполнить требуемую операцию (открыть, прочитать, записать, mmap,...) нафайлконтекст, в котором он пытается работать.

Пример для случая OP: если mysqldконтексту процесса разрешен доступ только к нескольким типам контекста файла, включая , mysqld_etc_tно не user_home_t, то запуск mysqldзавершится ошибкой, поскольку процесс не сможет прочитать свой файл конфигурации с неправильным user_home_tтипом.

В обычных системах это не имеет значения для интерактивного/вошедшего в систему пользователя, поскольку его обычный контекст процесса не ограничен, что означает, что никакое правило SELinux не будет применяться. Каждый запущенный демон systemdили другие подобные механизмыволяполучить контекст процесса, который можно проверить с помощью psпараметра -Z. Пример в системе Debian, работающей под управлением SELinux:

# ps -Z -p $$
LABEL                             PID TTY          TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 22498 pts/7 00:00:00 bash
# ps -Z -p $(pidof /sbin/getty)
LABEL                             PID TTY      STAT   TIME COMMAND
system_u:system_r:getty_t:s0     6158 tty1     Ss+    0:00 /sbin/getty 38400 tty1
system_u:system_r:getty_t:s0     6159 tty2     Ss+    0:00 /sbin/getty 38400 tty2
system_u:system_r:getty_t:s0     6160 tty3     Ss+    0:00 /sbin/getty 38400 tty3
system_u:system_r:getty_t:s0     6161 tty4     Ss+    0:00 /sbin/getty 38400 tty4
system_u:system_r:getty_t:s0     6162 tty5     Ss+    0:00 /sbin/getty 38400 tty5
system_u:system_r:getty_t:s0     6163 tty6     Ss+    0:00 /sbin/getty 38400 tty6

решение2

Да, есть принципиальная разница:

  • cp делает копию файла
  • mv (если вы остаетесь в пределах файловой системы) просто перемещает некоторые указатели на диске.

Попробуйте следующее:

touch a
ls -i a
cp a b
ls -i a b
mv a c
ls -i b c

Вы увидите, что b — это новый файл с новым номером инода, тогда как c — это тот же самый файл с номером инода старого a.

Однако это не объясняет вашего странного поведения.

решение3

Это то, чтоможет(Вы предоставили очень мало информации о приложении или этих ошибках, поэтому я могу только догадываться).

В Линуксеобязательная блокировка файлов встречается редко. Звонки типаflock(2)управлятьконсультативныйблокировки. Это означает, что ядро ​​отслеживает блокировки, но не применяет их, приложения должны сами их соблюдать.

Если что-то блокируется fileAи ваше приложение подчиняется блокировке, оно может отказать в обслуживании. Предположим, что это то, что происходит.

Блокировка влияет на inode, а не на путь или имя. Перемещение (переименование) заблокированного fileAв fileBпределах одной файловой системы ничего не делает с inode, файл по-прежнему заблокирован, приложение по-прежнему отказывается с ним работать. Копирование файла создает отдельный файл fileBс собственным inode, который не заблокирован, приложение работает.

(Примечание: перемещение файла в другую файловую систему фактически является копированием+удалением, поэтому оно должно снять блокировку, если таковая имеется).

Связанный контент