📜 ⬆️ ⬇️

Shared directory on a Linux machine, v2

In a situation where there is a shared directory on a server with several users (for example, on a file storage facility on a local network), you may face a problem when you need to give read-write permissions to all registered users. The situation has already been discussed in Habré, so let me literally quote the article by the user karapuz :

What can be done here? Several decisions immediately come to mind:

1. Set the corresponding umask for the shared directory;
2. Set the appropriate default acl;
3. Set the SGID bit.
')
Well, they applied one of the solutions, or all at once. It seems everything works. Both users have full access to the entire contents of the shared directory, the new files in this directory inherit its rights, but you have dropped photos from the camera into this directory. Your wife enters the system under her own user and decides to change these photographs a little, only when you save, a message about insufficient rights appears. It turns out that the files you copied did not inherit the rights of the shared directory. Why? Yes, because the cp utility doesn't care about your umasks and acl's. It copies files with preserving the original rights, or the rights are reduced, it all depends on the rights to the directory where we copy.


As a solution to the problem, karapuz suggested using one of the two existing daemons for monitoring the file system fam or gamin and the utility fileschanged .

But, as practice has shown, both of these daemons significantly load the server, especially when users are actively working with files in a controlled directory. On the network, you can find complaints from users that gamin eats up to 30% of processor time. I can say that I received the same disappointing results. In order to ease the load on the piece of iron, I decided to use the inotifywait utility from the inotify-tools package instead of the utilities mentioned above:

sudo apt-get install inotify-tools

inotifywait cleverly tracks changes to directories and files using the inotify interface.

And so, we have a program for tracking state changes, now we need to feed her the necessary directory and force it to do it after a reboot.

Here is an approximate solution on my server. Suppose you need to monitor the rights in the directory / home / sharez /

Create a trigger /usr/local/bin/inotifywait.sh

sudo nano /usr/local/bin/inotifywait.sh

#!/bin/sh
#
inotifywait -mrq -e close_write -e moved_to -e create --format "%w%f" "$1" | while read "FILE"
do
if [ -d "$FILE" ]; then
chown -R nobody:nogroup "$FILE"
chmod -R a+rwX "$FILE"
elif [ -f "$FILE" ]; then
chown nobody:nogroup "$FILE"
chmod a+rw-x "$FILE"
fi
done
:


A close look will notice that the rights and ownership of directories are set recursively. What is this for, because any recursive actions are additional significant overhead costs? The fact is that inotifywait only monitors the inode of a file or directory. And if when creating a directory, the create event affects all files and subdirectories, when moved within the same physical section, the moved_to event affects only the directory being moved (knows about the operation with a directory inode, but the inodes inside it remain intact) and and files in it. As a result, when we perform a move operation, we may lose the most important thing, because of which we started all this - the inheritance of rights. Therefore, I decided to sacrifice performance, especially since the operation of moving a large number of files at the same time is rarely performed.
Now you need to create a script for init.d

I didn’t like the launch options from rc.local , so the inotifywait.sh script in init.d will look something like this:

sudo nano /etc/init.d/inotifywait.sh

#! /bin/sh
case "$1" in
start|"")
rm -f /tmp/inotifywait.log
/usr/local/bin/inotifywait.sh /home/sharez/ >/tmp/inotifywait.log 2>&1 &
;;
restart|reload|force-reload)
echo "Error: argument '$1' not supported" >&2
exit 3
;;
stop)
# , inotifywait
;;
*)
echo "Usage: inotifywait.sh [start|stop]" >&2
exit 3
;;
esac
:


Making our scripts executable:
sudo chmod a+x /usr/local/bin/
sudo chmod a+x /etc/init.d/inotifywait.sh


Add the boot script to the runwords and run:
sudo update-rc.d inotifywait.sh defaults
sudo service inotifywait.sh start


It seems that everything, the wild sagging performance that I occasionally caught when a lot of people worked with their files on the server disappeared.

At the same time, I also solved one side task: as you can see, in addition to the access rights in the script, I also assign an owner and a group. In reality, several such scripts manage document flow in the office on the same binary rights, without resorting to acl. The document passes a certain path department by department, and at each moment of time only one department has the right to edit (or even read).

UPD: changed the name a bit, now it is less in line with the original karapuz article, but rather as a matter of fact.

Source: https://habr.com/ru/post/132614/


All Articles