Shared SAMBA hard drive

Configuration

Recently I found this page on the RetroPie documentation, it lists the benefits of sharing ROMS on a Network Share so files are not stored on the Raspberry Pi's SD. And frankly, for the setup I have at home with many of them connected to various devices, centralizing all the files on a central point makes all the sense. In terms of storage, each of the Pis has its own SD which is not convenient to store big or many files, and the whole network does not have a lot of storage capacity.

I started looking for a cheap NAS since it was the to-go answer for my problem, but it seems these are pretty pricey, plus all these devices come with their own operating system, media player capabilities, and a lot of features I won't think I would ever use, so I started looking for something more basic and in line of what I was looking for, just pure network storage

Then I got a cheap USB docking station and a 1TB hard drive from a second hand goods store. Then I attached the docking station to one of the network-connected Pi's and wrote an Ansible role to automatically mount it when the host boots, you just need to retrieve the hard drive uuid:

GitHub - namelivia/ansible-external-storage: Ansible role I use to mount an external drive
Ansible role I use to mount an external drive. Contribute to namelivia/ansible-external-storage development by creating an account on GitHub.

Next I configured the Raspberry Pi to be a SAMBA server, that way the rest of devices from the network will have access to the stored files, and to do so I also created another Ansible role:

GitHub - namelivia/ansible-samba: Ansible role to install and configure a shared samba volume
Ansible role to install and configure a shared samba volume - GitHub - namelivia/ansible-samba: Ansible role to install and configure a shared samba volume

The role will install required packages, create the configuration and start sharing the hard drive. The next piece of the puzzle is configuring clients to access the files on the shared hard drive, for that, I also created a new Ansible role to be run on every client machine, the role will configure /etc/fstab on the clients to automatically mount the network shared hard drive on boot:

GitHub - namelivia/ansible-samba-mounts: Ansible role I use to mount some samba directories
Ansible role I use to mount some samba directories - GitHub - namelivia/ansible-samba-mounts: Ansible role I use to mount some samba directories

Initial permission setup

The most confusing part of this setup was the permissions, the scenario here is a bit more complex than having a regular folder on your filesystem and there are more things to consider, to be fair, currently I have a working setup but I'm not entirely sure if its the optimal one.

On one hand, we have the usual UNIX permission configuration for every file and folder on the volume that includes:

  • owner
  • group
  • file mask
  • directory mask

But now, since this is a SAMBA shared volume we can set a lot more options on smb.conf like:

  • writeable
  • create mask
  • directory mask
  • valid_users
  • public

And on top of that, when mounting the volume on the client's /ect/fstab we can set:

  • file mode
  • dir mode
  • gid
  • uid

The initial configuration I went for was:

On the host:

  • owner: The regular home user
  • group: The regular home user
  • file mask: 644
  • directory mask: 755

On samba:

  • writeable: No
  • create mask: 644
  • directory mask: 755
  • valid_users: The samba user I just created
  • public: No

On the client:

  • file mode: 644
  • dir mode: 755
  • gid: 1000 (the regular user on the client machine)
  • uid: 1000 (the regular user on the client machine)

And it seemed to work ok, I had some programs writing data from the host machine using the regular user and then the data could be accessed and used by some other programs on my client machines... until it started to fail.

By debugging the errors I found out some of the programs on the client machines had to write data on the same folders in which the files that they were reading were placed, so that meant the clients should have writing rights on the SAMBA volume and they didn't, so I had to figure out a proper configuration to enable that.

Enabling writing rights for clients

The process to enable writing permissions for the clients didn't go as smoothly as I wanted to, and involved a lot of trial and error. I obviously skipped the 777 for all solution and did the following.

On the host machine, I created a UNIX group called samba-share, then I added both the samba user and the regular home user to the group. Then I changed the group (not the user) for the volume and update the folder permissions and the file permissions to 664 and 775 to all files and folders in the volume. Finally, I aligned the permission masks on all configuration files (on the client's and /etc/fstab on the server's smb.conf file). Finally, I had to set writeable to Yes on the samba configuration file. The final configuration then is:

On the host:

  • owner: The regular home user
  • group: The smb-share group
  • file mask: 664
  • directory mask: 775

On samba:

  • writeable: Yes
  • create mask: 664
  • directory mask: 775
  • valid_users: The samba user I just created
  • public: No

On the client:

  • file mode: 664
  • dir mode: 775
  • gid: 1000 (the regular user on the client machine)
  • uid: 1000 (the regular user on the client machine)

And with that, I checked that both software running on the host machine and software running on the client machines had the permissions they needed to work. I'm not super sure if there is some redundancy here on the configuration or if there is something misplaced but it worked! So I decided to write it down on this post to check it in the future.