On 03/14/2013 05:44 PM, Sergey Spiridonov wrote:
Привет Владимир
On 03/14/2013 05:59 AM, Владимир Скубриев wrote:
У тебя решение с использованием inotify-wait ?
Я написал демон на c++. В принципе уже работает, но хочу красоту навести.
Я вчера сделал при помощи inotifywait И скрипта в init.d
Но очень интересно было бы попробовать твоего демона и посмотреть что
получилось.
Как только наведешь красоту пиши в рассылку будем пробывать.
Кстати ты используешь inotifywait или напрямую с функцией ядра работаешь?
Ты продумывал демона с точки зрения работы с расширенными ACL, чтобы он
и группам расширенных acl тоже правам добавлял write ?
Я остановился на работе без acl, т.к. в моем случае они по сути не нужны.
Хотел еще уточнить кое что уточнить и спросить я прав вообще в своём
рассуждении?
Проблемы с созданием общего каталога в линукс связаны с:
1. Установкой прав по умолчанию в среде linux на вновь создаваемые и
копируемые файлы. Маска также действует на расширенные разрешения ACL в
том числе заданные по умолчанию (default acl).
Во первых ко всем создаваемым или копируемым файлам применяется маска
(0022), которая по умолчанию удаляет атрибуты записи и выполнения для
группы и остальных. Но нас больше интересуют права группы конечно.
Это связано в первую очередь с безопасностью.
Вновь создаваемым файлам как правило не необходимо иметь право
выполнения. А основной группе в которую входит пользователь не
обязательно сразу давать возможность записи в только что созданный
пользователем файл. И это де факто стандарт в мире линукс. Файл
создаётся с правами 644 а папка с правами 755.
При создании файла (в том числе при копировании в новый файл)
используется один и тот же системный вызов open(), но этот системный
вызов по разному используется при различных операциях.
В функции системного вызова open() есть параметр - mode. Значение этого
параметра влияет на результирующие права.
Это можно увидеть если запустить операции с файлами при помощи отладчика
strace:
Вызов метода open() при создании файла:
open("file-new", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
Вызов метода open() при копирование:
open("./file-copy", O_WRONLY|O_CREAT|O_EXCL, 0644) = 4
По умолчанию при создании нового файла системные утилиты и практически
все программы вызывают его с значением параметра mode = 666 для
файла и mode = 777 для папки (если создается папка). Новые объекты
создаются с полными правами. Но после создания нового объекта в ФС ядро
применяет к нему маску. Таким образом новые файлы и папки создаются с
правами 0644 и 0755 с маской установленной по умолчанию (0022).
Рассмотри применение маски. Это операция логического умножения.
Делаем инверсию бит системной маске: ~0022 -> 7755 (инверсия бит)
Далее выполняем побитовое логическое И: 7755 ? 0666 ->0644
Совет насчет вычитания в корне неверен! (0666-0202=0644) это случайное
совпадение!
А утилита копирования вызывает этот системный метод с значением
параметра равному правам исходного файла/папки. И они как правило могут
отличатся от значения используемого при создании объектов файловой системы.
Если учесть то, что при создании файла пользователем с значением
системной маски по умолчанию (0022) убирается право записи для основной
группы, то при копировании такого файла на общий ресурс пользователи
входящие в эту группу не смогут изменить данный файл пока владелец или
суперпользователь не установит для группы право на запись. Это
особенность работы системы по умолчанию.
В данном случае у нас есть два пути для решения данной проблемы:
1. Изменить на всех компьютерах в сети значение umask таким образом,
чтобы маска не отсекала право на запись для группы.
2. Сделать так, чтобы в система на сервере сама следила за новыми
файлами и правила их разрешения.
По сути не один из способов не является элегантным, так как в первом
случае нарушается безопасность пользователей а во втором мы "изобретаем
велосипед"
Но мы для решения задачи выберем второй вариант.
Для этого нам потребуется:
1. Установить пакет с специальной программой использующей API ядра ОС
для слежения за изменениями файлов.
aptitude install inotify-tools
2. Создать скрипт запускающий нужную нам утилиту в режиме демона(в фоне).
nano /usr/local/bin/inotifywait.sh:
#!/bin/sh
# Take the directory name as argument
# Source from:
#
http://en.positon.org/post/A-solution-to-the-umask-problem%3A-inotify-to-force-permissions
# Когда он запускается то есть почти 100 времени одного ядра,
# но в течении минуты все стабилизируется и нагрузка снижается до
минимального значения
inotifywait -mrq -e CREATE -e MODIFY -e CLOSE -e MOVE --format %w%f "$1"
| while read FILE
do
chmod g=u "$FILE"
done
3. Создать скрипт запуска init.d. Слово "common" - это название папки в
которой мы будем следить за новыми файлами.
/etc/init.d/inotifywait-common
#! /bin/sh
# PLease удостоверится, что папки и подпапки имеют бит GID (s)
# find /path/to/dir -type d -exec chmod g+s {} \;
# find $PATH_TO_FOLDER -type d -exec chmod g+s {} \;
# Укажите папку в которой следить за изменениями в файлах
PATH_TO_FOLDER=/storage/shares/common
case "$1" in
start|"")
rm -f /tmp/inotifywait.log
/usr/local/bin/inotifywait.sh $PATH_TO_FOLDER
>/tmp/inotifywait.log 2>&1 &
;;
restart|reload|force-reload)
echo "Error: argument '$1' not supported" >&2
exit 3
;;
stop)
# killall inotifywait ???
;;
*)
echo "Usage: inotifywait.sh [start|stop]" >&2
exit 3
;;
esac
:
4. Выполнить включение авто запуска данного скрипта при старте системы.
update-rc.d inotifywait-common defaults
5. Изменить значение параметра влияющего на работу API ядра inotify.
Сначала проверим сколько файлов и каталогов у нас используется сейчас:
ls -R /storage/shares/common | grep -c ''
665291
Соответственно значения 1000000 будет более чем достаточно для этой
папки на первое время.
Если планируется следить еще за одной папкой - рассчитываем это значение
исходя из большего из двух значений.
Вносим изменения в sysctl.conf
echo " ">> /etc/sysctl.conf
echo "# This specifies a limit on the number of watches that can be
associated with each inotify instance.">> /etc/sysctl.conf
echo "fs.inotify.max_user_watches=1000000" >> /etc/sysctl.conf
Также стоит отметить, что файлы создаваемые пользователями принадлежат
основной группе пользователя. При создании файла/папки на общем ресурсе
в нашем случае NFS нам необходимо помимо разрешений для группы изменять
также и саму группу объекта ФС.
Для решения данной задачи будем использовать GUID бит для нашего
родительского каталога. Данный бит также будет наследоваться всеми
дочерними каталогами и файлами
Установим его нашему сетевому каталогу:
chown g+s /storage/shares/common
Пару слов о расширенных списках контроля доступа в Линукс:
Они являются дополнением к обычной системе разрешений и задают именно
дополнительные права отличные от основного пользователя и группы.
На них распространяются те же правила что и на обычные права. Системная
маска к ним также применяется.
В ACL есть понятие прав по умолчанию.
Так вот если они заданы, то
1. Они наследуются дочерними каталогами
2. К ним также применяется системная маска, то есть если в системной
маске каких бит доступа нет, то и в расширенных acl этих бит доступа не
будет!
Если они не заданы, то
1. Новому объекту задаются права пользователя, группы и других при
помощи стандартного системного механизма.
2. К ним также применяется системная маска, то есть если в системной
маске каких бит доступа нет, то и в расширенных acl этих бит доступа не
будет!
По сути использовать их можно, если например необходимо разным группам
пользователей сделать разные права соответственно один право только на
чтение, другим на чтение и запись.
И вообще их можно использовать для задания дополнительных прав
пользователей.
А default acl нужно использовать для наследования прав дополнительных
пользователей и групп дочерними объектами, но при этом права для новых
файлов вне зависимости от того, как они создаются будут обрезаться
системной маской.
В итоге самое главное - это системная маска.
В связи с этим вопрос можно ли изменив значение системной маски изменить
поведение наследования расширенных и обычных прав ?
ОТВЕТ: ДА, но это повлияет на безопасность, так как файлы могут быть
доступны на запись не только его владельцу.
Пожалуйста! Поправите меня если я где то ошибаюсь?
--
С Уважением,
специалист по техническому и программному обеспечению,
системный администратор
Скубриев Владимир
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Россия, Ростовская область, г. Таганрог
тел. моб: +7 (918) 504 38 20
skype: v.skubriev
icq: 214-800-502
www: skubriev.ru