Вопрос или проблема
Проблема:
Пытаюсь скопировать все содержимое одной директории в другую, включая скрытые файлы/директории и символические ссылки.
Это довольно просто cp -a ${src} ${dst}
Это работает как ожидалось на моей локальной виртуальной машине, но это работает неправильно на моем VPS (hostgator). Он не копирует символические ссылки, если целевой объект ссылки находится позже в списке директорий.
Учитывая, что оригинальные целевые ссылки работают, локальны для устройства, и я копирую на том же устройстве, какой лучший способ убедиться, что вся структура директорий скопирована точно?
Мне потребовалось довольно много времени, но я понял, что на самом деле мне нужно просто запустить команду копирования дважды, и второй проход добавляет недостающие ссылки. Есть ли лучший способ, чем это?
Работающее, но хакерское решение:
src=".default/.";
dst="tld.domain/";
cp -a ${src} ${dst};
cp -a ${src} ${dst};
Мне не нужно дублировать команду, чтобы убедиться, что все скопировано правильно.
Я также пробовал tar, та же проблема. Я не пробовал rsync, но оба, похоже, являются избыточным решением для того, что должно быть довольно тривиальной задачей.
Сценарий:
Для дополнительной перспективы на случай, если это имеет значение или я не был ясен.
Я создал шаблон структуры директорий для доменов веб-сайтов. После создания нового поддомена на моем веб-хосте я копирую шаблон в корневую директорию документа поддомена.
Это структура директорий моего поддомена и шаблона (.default/):
sites/
.default/
.htaccess
.www -> production/
production/
tld.domain.x/
tld.domain.y/
tld.domain.z/
Итак, я создаю новый поддомен и затем заполняю его корневую директорию содержимым шаблона. Проблема в том, что .www/
является символической ссылкой на production/
, но cp
и т.д. создают все в сортированном порядке, поэтому он пытается создать .www/
перед созданием production/
и, соответственно, терпит неудачу.
Мой веб-хост это HostGator VPS с CentOS6
Я могу сузить проблему до некоторых ограничений на создание символических ссылок. Мое предположение заключается в том, что VPS не позволяет создавать символические ссылки на внешние источники, которые обычно ведут себя так же, как недействительный целевой объект ссылки. То есть непонятный источник.
Где ни одно из имен не существует, вызывая на моем VPS:
ln -s foo bar
Выход:
ln: создание символической ссылки `bar': Доступ запрещён
Если я сначала создаю foo/, а затем ссылку, это работает как ожидалось.
df -T .
показывает, что тип файловой системы virtfs
.
Обычно символическая ссылка неактивна: она может хранить любую последовательность байтов (кроме нулевых байтов и только до определенной длины). При создании символической ссылки не имеет значения, указывает ли содержимое на существующий файл. Только при доступе к символической ссылке существует важность наличия целевого объекта. Таким образом, то, что вы видите на своем VPS, является ненормальным (и необычным, вдобавок).
Virtfs — это файловая система, разработанная для виртуальных машин KVM/QEMU, где как клиент, так и хост работают на Linux. Эта файловая система предоставляет часть файловой системы хоста в клиенте. Это позволяет легко и быстро делиться файлами между клиентом и хостом (быстрее, чем сетевой файловой системой). Это полезно на VPS, например, где все клиенты работают под одной и той же операционной системой, поэтому файлы ОС совместно используются (только для чтения, как надеются) между хостом и всеми клиентами. Она также может использоваться для специфичных для клиента файлов (которые не делятся с другими клиентами).
Virtfs предлагает два режима хранения: mapped и passthrough. Режим passthrough, как следует из названия, просто передает команды манипуляции с файлами от клиента к хосту; например, создание символической ссылки в клиенте создает символическую ссылку на хосте. Режим mapped использует расширенные атрибуты на хосте для хранения метаданных файлов и делает все файлы принадлежащими пользователю, запускающему QEMU. Режим mapped подходит для хранения файлов, специфичных для клиента, поскольку они затем принадлежат одному и тому же пользователю, запускающему QEMU, независимо от того, какому пользователю они принадлежат в клиенте. Ваш сайт, предположительно, хранится на экземпляре virtfs в режиме mapped.
В режиме mapped символические ссылки хранятся как обычный файл с расширенным атрибутом, указывающим на то, что это символическая ссылка. Это само по себе не объясняет вашу проблему. Однако это открывает окно возможностей для возникновения ошибки. Похоже, что что-то проверяет наличие целевых объектов символических ссылок и отказывает в их создании, если целевой объект не существует.
У меня нет опыта работы с virtfs, поэтому я не могу сказать, связано ли это с какой-либо опцией конфигурации. Я нашел проблему, которая похожа на вашу. Затронутый пользователь также был на VPS и также получил ошибки “доступ запрещён” при попытке создать висячую символическую ссылку. Его вывод был
Для справки: проблема не в RedHat 4.4 — команда
ln -s
была намеренно нарушена системным провайдером, чтобы предотвратить установку таких вещей, как RVM.
Вам может быть полезно связаться с вашим провайдером VPS, чтобы запросить объяснение и, надеюсь, решение.
Если вы не можете получить решение, временным обходным путем будет сначала скопировать директории и обычные файлы, а затем скопировать символические ссылки. Я не думаю, что какие-либо из обычных программ копирования (GNU cp
, rsync, cpio, tar, pax) имеют возможность скопировать все, но оставить символические ссылки на месте. Простой обходной путь – выполнить копирование дважды (с rsync, чтобы уже скопированные файлы не копировались снова), игнорируя ошибки в первом проходе:
rsync -a source/ destination/ 2>/dev/null
rsync -a source/ destination/
Ответ или решение
Проблема копирования символьных ссылок на virtfs
Копирование файловых структур, особенно когда включаются символические ссылки (symlinks), может представлять собой непростую задачу, особенно в условиях специфических файловых систем, таких как virtfs. Давайте разберемся подробнее с вашим запросом и условиями, в которых вы работаете.
Описание проблемы
Вы пытались выполнить команду cp -a ${src} ${dst}
для копирования содержимого каталога, включая скрытые файлы и символьные ссылки, и столкнулись с тем, что на вашем VPS (существующем в среде HostGator на базе CentOS 6) символьные ссылки не копируются должным образом. Причина этого кроется в порядке, в котором cp
обрабатывает файлы. Если целью символьной ссылки является файл или каталог, который еще не создан в момент копирования, это приведет к ошибке.
В вашем случае символьная ссылка ".www -> production/"
не может быть корректно скопирована, поскольку структура файловой системы virtfs
обрабатывает ссылки в заданном порядке.
Почему возникает ошибка
virtfs – это файловая система, созданная для виртуальных машин KVM/QEMU, обеспечивающая возможность совместного использования файлов между хостом и гостем. Она поддерживает два режима: mapped и passthrough. В режиме mapped символические ссылки хранятся как обычные файлы с расширенными атрибутами, что может привести к проблемам при попытке создать "виселицу" (dangling symlink) — ссылку на несуществующий файл.
Решение проблемы
-
Копирование в два этапа: Ваше текущее решение с повторным использованием команды копирования — это один из возможных подходов, хотя и выглядит неэффективным. Использование команды
cp
дважды может решать проблему, но это также приведет к ненужному дублированию операций. -
Использование rsync: Замена
cp
наrsync
может быть более оптимальным решением. Это команда, которая может копировать файлы и директории, а также игнорировать ошибки. Вы можете выполнить копирование в два этапа с помощьюrsync
, что позволит избежать проблем с символьными ссылками.rsync -a --ignore-errors ${src}/ ${dst}/ rsync -a ${src}/ ${dst}/
-
Обращение к Провайдеру VPS: Если проблема сохраняется, стоит обратиться в службу поддержки вашего хостинг-провайдера. Возможно, ограничения наложены на уровне конфигурации файловой системы или политики безопасности, которые можно исправить с их помощью.
Заключение
Работа с файловыми системами в виртуализированных средах может быть сложной из-за множества факторов, таких как структура каталогов, порядок доступа и настройки пользовы и прав. Ваша проблема с символьными ссылками на virtfs
может быть адекватно решена с помощью rsync
, что упростит процесс и обеспечит целостность копируемых данных. Сообщите вашему хостинг-провайдеру о проблеме, чтобы получить дополнительную помощь и, возможно, исправление конфигурации системы. Это обеспечит долгосрочное решение, если вы работаете с такими файлами регулярно.