Назад | Перейти на главную страницу

Linux и NFS: атомарное сравнение и обмен прав собственности на файлы

Мой ИТ-отдел сделал ошибку и отказался каждый файл в файловой системе, чтобы root:OurGroup. Затем их автоматическое резервное копирование (т.е. .snapshop) система создала снимок, поэтому у нас больше нет справки о том, какие разрешения были раньше.

Я пытаюсь работать с ними, чтобы создать сценарий, в котором будет установлен бит set-uid и который будет принадлежать пользователю root, который пользователи могут вызывать, чтобы при необходимости повторно загружать файлы / каталоги.

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

Однако, чтобы избежать состояния гонки, я хочу найти способ перехватить, если и только если файл принадлежит этим пользователям. Однако здесь есть состояние гонки: если я сделаю это двумя отдельными вызовами и два пользователя запустят этот скрипт в файле одновременно, это может вызвать коллизии. Вместо этого я хотел бы «сменить владельца, если владелец является пользователем» в одном вызове, вместо «если владелец является пользователем», за которым следует «сменить владельца»

Есть ли атомарный примитив сравнения и обмена для владения файлами?

В оболочке такого нет, но вы можете эмулировать это с помощью flock (видеть эта запись Stackoverflow)

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

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

Однако, чтобы избежать состояния гонки, я хочу найти способ перехватить, если и только если файл принадлежит этим пользователям. Однако здесь есть состояние гонки: если я сделаю это двумя отдельными вызовами и два пользователя запустят этот скрипт в файле одновременно, это может вызвать коллизии. Вместо этого я хотел бы «сменить владельца, если владелец является пользователем» в одном вызове, вместо «если владелец является пользователем», за которым следует «сменить владельца»

Вы, кажется, подразумеваете, что как только право собственности на файл изменилось с root:OurGroup к чему-то более разумному, например user1:department-name второй пользователь не сможет снова сменить владельца с user1:department-name к user2:some-team.

Но проблема не в этом ...

Проблема не в том, что два пользователя запускают скрипт одновременно или выполняют chown команды вскоре после другой или одновременно, проблема намного сложнее:
Как вы собираетесь разрешать конфликты, когда несколько пользователей заявляют о праве собственности на один и тот же файл или каталог?

Представьте, что первый пользователь, запускающий ваш скрипт, просто выбирает каждый файл и каталог ...

Решена ли ваша проблема, когда все файлы переходят с root:OurGroup как UID: GID для user1:department-name и будет ли право собственности восстановлено правильно?
И если последующий запуск от пользователя2, который хочет только владеть <path>/Department-Name/User1's files/* быть отказано?


Как упоминал @Lacek, лучше всего использовать старую резервную копию в качестве шаблона для владения любыми файлами, которые все еще существуют в текущей файловой системе, и сосредотачивать внимание только на вновь созданных файлах, которых нет в резервной копии. (Подход первого уровня дает этим файлам того же владельца, что и включающий каталог).

В chmod так же хорошо как chown командная поддержка --reference флаг. Вы можете указать на существующий файл из хранилища резервной копии и chown будет использовать владельца и группу этого справочного файла / каталога вместо того, чтобы указывать значения OWNER: GROUP напрямую, то есть что-то в строках:

cd /old-backup-of-nfs-share/
find . -exec chmod -v --reference='{}' /current-nfs-mount/'{}' \;