As the Raspberry PI uses an SD Card for it’s boot device there are times when you need either more space than is available on that device or a device that’s faster – writing to flash is slow and flash cards do have a limited number of writes that can be made to them.
Now there’s several ways to accomplish this:
- Use an external USB drive (the common route)
- Use a network shared drive
Using a USB drive is simple and is the faster option but it means it’s dedicated to the PI whilst it’s in use, hence this article on using a network drive – in this instance a directory on another Linux box in the network.
Also having it shared on the network means that multiple machines could use it at the same time. Imagine if you are a teacher with a collection of PI’s being used by your students. You could setup a central read-only directory with your class work which they can all access as if it’s installed locally.
Our aims
For this article I’m going to show how to setup a directory on a server and the raspberry pi as the client.
- tabitha – Ubuntu server that will host the directory
- lindesfarne – Raspberry PI client running the stock Debian SD Image
- kell – second Raspberry PI client also running Debian.
Although the examples will show tabitha and lindesfarne at the end I’ll also show how to copy files between two Raspberry PI’s via the share, kell being the second pi.
Also although I’m using a linux box in this setup if you wanted to use a PI as the server (sharing a usb drive for example) then it’s exactly the same.
Setting up the server
First I presume you are running a current Linux distribution. In this example I’m setting this up on a machine running Ubuntu but these instructions will work on Linux Mint or Debian as well.
First you need to pick a directory which you want to use as shared space. For the purpose of this article I’m going to use /srv/public
tabitha:~$ sudo mkdir -p /srv/public tabitha:~$ sudo chmod 777 /srv/public
Now first we have to use sudo as /srv is under the root directory so only root can create it. Most distributions have a /srv directory already but the -p attribute means that mkdir will create it as well if it doesn’t exist.
Also the chmod is a cheat for this article – it means that any user can not just read but write to that directory. Normally you would limit it to a specific user or group but that’s outside the scope of this article.
Next we need to install the NFS server.
tabitha:~$ sudo apt-get install nfs-kernel-server nfs-common portmap
Now you may already have a couple of these installed but usually nfs-kernel-server isn’t installed by default.
Next you need to configure nfs by adding the directory to /etc/exports
tabitha:~$ sudo vi /etc/exports
and add the following line to the end of the file:
/srv/public 192.168.2.0/24(rw,sync,no_subtree_check)
Now what this does is declare that the /srv/public directory is Read Write (rw) and it’s accessible by any machine within the local network – 192.168.2.x in my instance.
Now you could replace the nework definition with a * which means any machine but if it’s accessible from the public internet that’s not a good idea.
/srv/public *(rw,sync,no_subtree_check)
Alternatively you could specify a user name instead but this is a bit tricky to set unless your user’s are configured the same on both the server and the client.
/srv/public pi(rw,sync,no_subtree_check)
Now entries within ( ) are options specific to this share. common entries are:
- rw : Allow clients to read as well as write access
- ro : Read only access
- insecure : Tells the NFS server to use unpriveledged ports (ports > 1024).
- no_subtree_check : If the entire volume (/users) is exported, disabling this check will speed up transfers.
- async : async will speed up transfers.
Now you just need to restart nfs-server:
tabitha:~$ sudo service nfs-kernel-server restart
Now your NFS sever is sharing /srv/public
Mounting the directory on the PI
Now we are going to mount this share on the PI.
First you need to install NFS. If you are using the standard Debian image then you have enough to mount nfs. If in doubt then simply install it as we did for the server – if it’s already there it will just tell you it’s already installed.
Next decide where to mount it. Now you can mount it anywhere you want but I’m going to use the same /srv/public location – an alternative location for example is /mnt/public.
First make the directory as you did on the server.
pi@lindesfarne:~$ sudo mkdir -p /srv/public pi@lindesfarne:~$ sudo chmod 777 /srv/public
Next we’ll mount the share:
pi@lindesfarne:~$ sudo mount tabitha:/srv/public /srv/public
Here tabitha:/srv/public defines the server and the directory on the server whilst the /srv/public on the right is your local mount point. Now it should return almost immediately so next lets look at what we now have mounted:
pi@lindesfarne:~$ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 94M 0 94M 0% /lib/init/rw udev 10M 180K 9.9M 2% /dev mpfs 94M 0 94M 0% /dev/shm rootfs 1.6G 1.3G 257M 83% / /dev/mmcblk0p1 75M 28M 47M 38% /boot /dev/mmcblk0p4 2.0G 42M 1.8G 3% /home tabitha:/srv/public 141G 5.8G 128G 5% /srv/public
Now the machine has 128Gb of space available to it under /srv/public
Right lets test it. First we’ll create a file on the server and see if we can read it on the PI.
peter@tabitha:~$ uname -nmo tabitha i686 GNU/Linux peter@tabitha:~$ uname -nmo >/srv/public/tabitha
Now can we read it:
pi@lindesfarne:~$ cat /srv/public/tabitha tabitha i686 GNU/Linux
Now that one would always work as were reading so next we want to write from the client:
pi@lindesfarne:~$ uname -nmo lindesfarne armv6l GNU/Linux pi@lindesfarne:~$ uname -nmo >/srv/public/lindesfarne
And on the server?
peter@tabitha:~$ cat /srv/public/lindesfarne lindesfarne armv6l GNU/Linux
Using the drive on more than one PI
Ok now to bring in the second pi (kell) and we will copy a file from lindesfarne to it via the share.
First follow the instructions for mounting the drive above on the second pi – you should now have both attached to the server.
Next select a file to copy. For this article we’ll create a dummy file but if you have another locally you could use that instead:
pi@lindesfarne:~$ ( uname -a;df -h) > dummy pi@lindesfarne:~$ cat dummy Linux lindesfarne 3.1.9+ #90 Wed Apr 18 18:23:05 BST 2012 armv6l GNU/Linux Filesystem Size Used Avail Use% Mounted on tmpfs 94M 0 94M 0% /lib/init/rw udev 10M 180K 9.9M 2% /dev tmpfs 94M 0 94M 0% /dev/shm rootfs 1.6G 1.3G 256M 83% / /dev/mmcblk0p1 75M 28M 47M 38% /boot /dev/mmcblk0p4 2.0G 42M 1.8G 3% /home tabitha:/srv/public 141G 5.8G 128G 5% /srv/public
Next copy it to the drive & on the second pi copy it into the home directory
pi@lindesfarne:~$ cp dummy /srv/public/dummy pi@kell:~$ cp /srv/public/dummy
That’s it. View that file and you should see it’s exactly the same.
Unmounting the drive
If you want to unmount the drive then it’s simply a case of:
pi@lindesfarne:~$ sudo umount /srv/public
Mounting the drive on boot
Now this article shows how to mount the drive on the pi – but what if you want to mount it automatically every time you want to boot?
Well all you need to do is to add an entry to /etc/fstab
pi$lindesfarne:~$ sudo vi /etc/fstab
And add the following entry at the end of the file:
tabitha:/srv/public /srv/public nfs defaults 0 0
Thats it. The next time you reboot the pi it will automatically mount that drive.
Personally for the pi’s I leave that out and manually mount it – simply because I might be doing something else with the pi – possibly not connected to the network, but that’s how to do it.
I have two Pis and have one as a server for developing program’s for the second to use.
I tried to install the nfs server files and was successful except the Pi told me it would install rpcbind instead of portmap.
When I started the server it reported that it wouldn’t start because portmap permits not running.
I am running the “wheezy” kernel.. Apt-get needed me to update before it was ok..
Any thoughts ?
Patrick
I didn’t try installing the server on the PI but it might be something specific to wheezy – when I did it on the server it didn’t have a problem.
Later this evening I’ll give it a go using both wheezy & raspian to see if I can replicate it.
Reblogged this on gastarbeiten.
Thank you for this article, it’s well explained and can be understand by beginners, too!
I found a type in two places that you may fix: /src/public instead of /srv/public.
I have a server on my lan, placed the correct info in the /set/fstab and can manually mount the drive using “sudo mount -a”.
I cannot figure out why it will not automatically mount this on boot. Is it a timing issue? My PI is using DHCP and i have its mac address associated with 192.168.2.197 on my router and can reliably find it on that address. What is not set correctly that keeps it from mounting the nfs share at boot?
When I parse the dmesg, it mounts root before it loads the ethernet module then remounts these devices:
[ 14.895203] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[ 15.413996] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
There is no mention of the nfs during boot.
What am I missing?
Keith
Hmmm, interesting.
I’ve just setup mimas (my development PI) to mount a public mount on my NAS, rebooted and it’s worked.
All I did was:
apt-get install nfs-common
service rpcbind start
mkdir /mnt/discovery
Then added the following to /etc/fstab:
192.168.1.138:/mnt/discovery/nfs /mnt/discovery nfs rw,_netdev,auto 0 0
then mount -a and I saw the partition mounted:
root@mimas:~# df -H /mnt/discovery
Filesystem Size Used Avail Use% Mounted on
192.168.1.138:/mnt/discovery/nfs 2.0T 6.8G 1.8T 1% /mnt/discovery
Then I just did a reboot and once the pi came back then the partition was already there.
I have nfs-common installed, rpcbind is running, my mount point is /tmp/motion
My /etc/fstab line was this (based on a hint I found on the net):
192.168.2.198:/mnt/first_NAS/Motion /tmp/motion nfs rsize=8192,wsize=8192,timeo=14,intr 0 0
I tried yours:
192.168.2.198:/mnt/first_NAS/Motion /tmp/motion nfs rw,_netdev,auto 0 0
and get the same result. I can mount it with sudo mount -a, but it will not mount at boot.
after booting df returns this:
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
rootfs 7579104 4231088 2963168 59% /
/dev/root 7579104 4231088 2963168 59% /
devtmpfs 110544 0 110544 0% /dev
tmpfs 23764 560 23204 3% /run
tmpfs 5120 0 5120 0% /run/lock
tmpfs 47520 0 47520 0% /run/shm
/dev/mmcblk0p1 57288 18544 38744 33% /boot
$ sudo mount -a
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
rootfs 7579104 4231104 2963152 59% /
/dev/root 7579104 4231104 2963152 59% /
devtmpfs 110544 0 110544 0% /dev
tmpfs 23764 560 23204 3% /run
tmpfs 5120 0 5120 0% /run/lock
tmpfs 47520 0 47520 0% /run/shm
/dev/mmcblk0p1 57288 18544 38744 33% /boot
192.168.2.198:/mnt/first_NAS/Motion 3824382144 742773824 3081608320 20% /tmp/motion
Any ideas?
It does sound like a timing issue…
I’m wondering, is your dhcp responding fast enough or could that be delaying the network long enough?
Like you I’m using dhcp for IPv4 networking (IPv6 is different) and it’s fine here but then the firewall which also has dhcp etc on it is pretty powerful so it could be your dhcp server being slow.
One thing to try is to give your PI a static address & see if that helps. If it does then that’s a pointer, if not then I’m stumped.
From a service point of view everything is up and running as mount -a works once the pi finishes booting.
Still no joy with a static IP address. I need to figure out how to delay the nfs mount. THis is a v1 raspberry pi and I am using the ethernet interface.
I have this set up on 3 pi’s. One as the server and two clients. I am able to see the contents of the folder on the client side, but i dont have write access. The server pi can write to files though. I have the proper ‘rw’ in the /etc/exports on the server
/srv/public 10.0.0.0/24(rw,sync,no_subtree_check)
Somthing else i am missing?
It’s been a while (need to revisit this again soon myself though) but IIRC you have to add the rw mount option to the client as well, ether -o rw on the command line or add it to the column in /etc/fstab
Thanks for the quick reply! I un-mounted it from the command line and tried
sudo mount PiCL0:/srv/public /srv/public -o rw
It again mounted the drive, but did not allow me access to write.
Still missing somthing
Sorry for the late reply… Looking at the config of one instance I have:
sudo mount -t nfs -o rw,_netdev,auto server:/path /path
That said _netdev & auto shouldn’t affect this. The only other thing it could be is permissions, the uid’s don’t match on the server & client.
That said, I wrote this a couple of years ago so possibly something recent in Raspian has changed. I’ll be revisiting NFS on the PI again as I’m in the middle of setting up a PI based Docker cluster & I’ll need to have nfs working for that, so if it was a change I’ll soon find out.
Still no luck, I noticed that all the files in that new drive belong to root, (and i did try sudo when attemping to edit or create a new file) but is it a permissions thing? should i create a group with all three user accounts and assign that folder to that group?