Raspberry Pi runs Linux in a small package.

Network-Attached Storage On the Raspberry Pi

Network-Attached Storage

The Raspberry Pi is an extremely low-cost yet highly capable Linux platform. It can be a very nice platform for a small network appliance. Network-Attached Storage or NAS is a data storage appliance. One possible applications includes backup. Simply copy the files to the network drive. Another application is file sharing. Several hosts could share the one collection of data. This could be a media server, a small Linux-powered box hosting your music and movies.

It is easy to confuse NAS with SAN, but a Storage Area Network is an entirely different approach to networked data storage. A SAN includes a high-speed switch fabric or interconnected mesh, with multiple hosts sharing storage distributed across multiple storage devices. Unless all hosts access the data in read-only mode, their operating systems need to do file locking and access arbitration.

While my examples and screen shots are from a Raspberry Pi, this page explains how to build and use NAS on any Linux platform.

Attach the Disk

Use a disk drive with adequate storage capacity. If you're starting with a bare drive, get the appropriate PATA-to-USB or SATA-to-USB adaptor.

If you are using a small external drive that came in its own enclosure, the USB interface will be built in. You will not be able to power the drive through the Raspberry Pi USB interface. Either use a powered USB hub, or attach a self-powered drive.

The below kernel messages are captured by Syslog on the Raspberry Pi when I attach my drive. We see that Super Top manufactured the PATA-to-USB interface, and assigned it a serial number in some non-ASCII character set. The disk itself is a Maxtor TM3500630A, a 500 GB (or 465 GiB) PATA drive.

The Raspberry Pi's file system is on a "disk" that isn't really a disk, it's a flash RAM card that appears as device /dev/mmcblk0 with partitions mmcblk0p1 and mmcblk0p2. This new disk is the first truly disk-like device seen by the kernel, so it is named /dev/sda.

Apr 25 10:27:12 raspberrypi kernel: [172811.187377] usb 1-1.2: new high-speed USB device number 5 using dwc_otg
Apr 25 10:27:12 raspberrypi kernel: [172811.288965] usb 1-1.2: New USB device found, idVendor=14cd, idProduct=6600
Apr 25 10:27:12 raspberrypi kernel: [172811.288997] usb 1-1.2: New USB device strings: Mfr=1, Product=3, SerialNumber=2
Apr 25 10:27:12 raspberrypi kernel: [172811.289013] usb 1-1.2: Product: USB 2.0  IDE DEVICE
Apr 25 10:27:12 raspberrypi kernel: [172811.289027] usb 1-1.2: Manufacturer: Super Top
Apr 25 10:27:12 raspberrypi kernel: [172811.289040] usb 1-1.2: SerialNumber: å|å|å|å|å|å|å²ȁȁºμä
Apr 25 10:27:12 raspberrypi kernel: [172811.293605] usb-storage 1-1.2:1.0: Quirks match for vid 14cd pid 6600: 20
Apr 25 10:27:12 raspberrypi kernel: [172811.293874] scsi0 : usb-storage 1-1.2:1.0
Apr 25 10:27:13 raspberrypi kernel: [172812.288673] scsi 0:0:0:0: Direct-Access     MAXTOR S TM3500630A            PQ: 0 ANSI: 0
Apr 25 10:27:13 raspberrypi kernel: [172812.292318] sd 0:0:0:0: [sda] 976773168 512-byte logical blocks: (500 GB/465 GiB)
Apr 25 10:27:13 raspberrypi kernel: [172812.292971] sd 0:0:0:0: [sda] Write Protect is off
Apr 25 10:27:13 raspberrypi kernel: [172812.293551] sd 0:0:0:0: [sda] No Caching mode page present
Apr 25 10:27:13 raspberrypi kernel: [172812.293578] sd 0:0:0:0: [sda] Assuming drive cache: write through
Apr 25 10:27:13 raspberrypi kernel: [172812.296434] sd 0:0:0:0: [sda] No Caching mode page present
Apr 25 10:27:13 raspberrypi kernel: [172812.296467] sd 0:0:0:0: [sda] Assuming drive cache: write through
Apr 25 10:27:13 raspberrypi kernel: [172812.317674]  sda: sda1
Apr 25 10:27:13 raspberrypi kernel: [172812.322688] sd 0:0:0:0: [sda] No Caching mode page present
Apr 25 10:27:13 raspberrypi kernel: [172812.322722] sd 0:0:0:0: [sda] Assuming drive cache: write through
Apr 25 10:27:13 raspberrypi kernel: [172812.322742] sd 0:0:0:0: [sda] Attached SCSI disk
Raspberry Pi Ethernet and USB connectors.

Let's see what the Raspberry Pi has on its USB bus. ("On its USB"? "On its US Bus"? Whatever.)

root@raspberrypi:~# lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 005: ID 14cd:6600 Super Top USB 2.0 IDE DEVICE
Bus 001 Device 004: ID 0b05:1786 ASUSTek Computer, Inc. USB-N10 802.11n Network Adapter [Realtek RTL8188SU]

root@raspberrypi:~# lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/3p, 480M
            |__ Port 1: Dev 3, If 0, Class=vend., Driver=smsc95xx, 480M
	    |__ Port 2: Dev 5, If 0, Class=stor., Driver=usb-storage, 480M
	    |__ Port 3: Dev 4, If 0, Class=vend., Driver=r8712u, 480M

IC3, located just behind the USB connector, is the SMSC95xx / LAN9512 combined USB and Ethernet controller. So, the SMSC (or Standard MicroSystems Corporation) device at position #2 is the USB hub, while the one at position #3 is the 802.3 Ethernet interface. I have an ASUSTek 802.11n wireless LAN device plugged in at position #4. Finally, there is the USB-IDE interface at position #5.

Partition the Disk and Create a File System

Let's see what disk devices appear, and what's left over from its previous use.

root@raspberrypi:~# ls -l /dev/sd*
brw-rw---T 1 root floppy 8, 0 Apr 25 10:27 /dev/sda
brw-rw---T 1 root floppy 8, 1 Apr 25 10:27 /dev/sda1

root@raspberrypi:~# file -s /dev/sda
/dev/sda:  sticky x86 boot sector; partition 1: ID=0xb,
	starthead 1, startsector 63, 976768002 sectors,
	extended partition table (last)\011, code offset 0x0

root@raspberrypi:~# fdisk -l /dev/sda

Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x80c58b56

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1              63   976768064   488384001    b  W95 FAT32

OK, it had a FAT32 file system. Let's write zeros onto its boot block and wipe out the old partition table:

root@raspberrypi:~# dd if=/dev/zero of=/dev/sda bs=1k count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB) copied, 0.00793873 s, 129 kB/s

Now let's use parted to create a GUID disk label and set up a modern partition layout. The GUID disk label is sometimes called a GUID partition table, hence "gpt" here. The partition will start at cylinder 1 to leave cylinder 0 for the disk label itself, and it will continue through "-0" which means "all the way to the end".

root@raspberrypi:~# parted /dev/sda
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel
New disk label type? gpt
Warning: The existing disk label on /dev/sda will be destroyed and all data on
this disk will be lost. Do you want to continue?
Yes/No? yes
(parted) mkpart
Partition name?  []?
File system type?  [ext2]? ext4
Start? 1
End? -0
(parted) print
Model: MAXTOR S TM3500630A (scsi)
Disk /dev/sda: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End    Size   File system  Name  Flags
 1      1049kB  500GB  500GB

(parted) quit
Information: You may need to update /etc/fstab.

Now let's create an Ext4 file system in that partition. I will go ahead and label it as /export1 so the mount can be specified by label instead of device name.

Let's say I later set up a second disk to use at the same time as /export2. The Raspberry Pi has just two USB ports, so I would have to remove either the wireless LAN device or the first disk and attach a USB hub. Once I get things reconnected, who knows which of the two disks the kernel will think is the first one. I don't have to worry about this at all as long as I put labels in the file systems and they are mounted by label rather than device name.

root@raspberrypi:~# mkfs.ext4 -L /export1 /dev/sda1 
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=/export1
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
30531584 inodes, 122096384 blocks
6104819 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
3727 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 
	102400000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done     

You might prefer to use a UUID or Universally Unique Identifier instead of a label. You could have generated and applied a UUID when creating the file system in the above step. But you can always go back later and add or change the label or UUID, as in this example of setting a fresh UUID. It's a little easier to create the file system without a UUID and then add one, as tune2fs can generate a random one for you, but you have to come up with one and then specify it to the mkfs.ext4 command:

root@raspberrypi:~# tune2fs -U random /dev/sda1 

Now that we have added a UUID, let's see the alternatives we have for specifying disk devices:

root@raspberrypi:~# ls -lR /dev/disk 
/dev/disk/:
total 0
drwxr-xr-x 2 root root 140 Apr 26 15:58 by-id
drwxr-xr-x 2 root root  60 Apr 26 15:58 by-label
drwxr-xr-x 2 root root  80 Apr 26 15:58 by-path
drwxr-xr-x 2 root root 100 Apr 26 15:58 by-uuid

/dev/disk/by-id:
total 0
lrwxrwxrwx 1 root root 13 Dec 31  1969 memstick-SU08G_0x1e7f2fb5 -> ../../mmcblk0
lrwxrwxrwx 1 root root 15 Dec 31  1969 memstick-SU08G_0x1e7f2fb5-part1 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 15 Apr 23 10:27 memstick-SU08G_0x1e7f2fb5-part2 -> ../../mmcblk0p2
lrwxrwxrwx 1 root root  9 Apr 26 15:58 usb-MAXTOR_S_TM3500630A_??????????-0:0 -> ../../sda
lrwxrwxrwx 1 root root 10 Apr 26 15:58 usb-MAXTOR_S_TM3500630A_??????????-0:0-part1 -> ../../sda1

/dev/disk/by-label:
total 0
lrwxrwxrwx 1 root root 10 Apr 26 15:58 /export1 -> ../../sda1

/dev/disk/by-path:
total 0
lrwxrwxrwx 1 root root  9 Apr 26 15:58 platform-bcm2708_usb-usb-0:1.2:1.0-scsi-0:0:0:0 -> ../../sda
lrwxrwxrwx 1 root root 10 Apr 26 15:58 platform-bcm2708_usb-usb-0:1.2:1.0-scsi-0:0:0:0-part1 -> ../../sda1

/dev/disk/by-uuid:
total 0
lrwxrwxrwx 1 root root 15 Apr 23 10:27 62ba9ec9-47d9-4421-aaee-71dd6c0f3707 -> ../../mmcblk0p2
lrwxrwxrwx 1 root root 10 Apr 26 15:58 9cd3f34d-e323-b124-982f-8f6f4ebc0491 -> ../../sda1
lrwxrwxrwx 1 root root 15 Dec 31  1969 C522-EA52 -> ../../mmcblk0p1

These are four collections of symbolic links, all of them pointing to the /dev/sd* and /dev/mmcblk* devices.

The by-id directory has some form of manufacturer, model and serial number. The non-ASCII serial number of the Super Top interface give it an awkward and vague string instead of a unique number. There is an alternative by-id name for everything: the entire memory card and its two partitions, and the entire disk and its one partition.

The by-label directory has just one entry. I put a label in the file system I created but the Raspbian distribution doesn't label its root file system.

The by-path directory is where you would see the full PCI bus — controller — disk chain on a typical system. Here we see the USB bus — port — device chain.

Finally, there are UUIDs in the by-uuid directory.

You will see that some of the devices seem to have been detected in the second just before the Unix epoch began at 00:00:00 01 January 1970. There is no hardware clock on the Raspberry Pi, so its system clock always starts back at the beginning of the epoch. Once it gets up and can contact a time reference over the NTP protocol, it jumps the system clock to the real time.

Mount and Export the File System

Let's tell the system where it should find and connect this new file system. We do this in /etc/fstab. The "0" needs to be there, some number needs to be there, but you surely aren't still using dump and restore so the 5th column will be ignored. The "2" means "Run fsck on this file system, but it's not the root file system so do it later."

root@raspberrypi:~# cat /etc/fstab 
proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
LABEL=/export1  /export1        ext4    defaults          0       2

Let's create the mount point, mount all the file systems including this new one, and see what happens:

root@raspberrypi:~# mkdir /export1 
root@raspberrypi:~# mount -a 
root@raspberrypi:~# df -h 
Filesystem      Size  Used Avail Use% Mounted on
rootfs          7.3G  2.6G  4.4G  37% /
/dev/root       7.3G  2.6G  4.4G  37% /
devtmpfs        212M     0  212M   0% /dev
tmpfs            44M  252K   44M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            88M     0   88M   0% /run/shm
/dev/mmcblk0p1   56M   19M   38M  34% /boot
/dev/sda1       459G  198M  435G   1% /export1

We need to add the NFS server software.

root@raspberrypi:~# apt-get install nfs-kernel-server
[...]
Creating config file /etc/exports with new version
Creating config file /etc/default/nfs-kernel-server with new version
[...]

The rpcbind service needs to be started before the NFS server is started. By default, it doesn't run at all. Let's try to add rpcbind as a running service, started when its authors say it should be started. Raspbian and Ubuntu are derived from Debian, and so we use update-rc.d instead of chkconfig as we would for most other distributions.

root@raspberrypi:~# update-rc.d rpcbind defaults
update-rc.d: using dependency based boot sequencing
update-rc.d: warning: default start runlevel arguments (2 3 4 5) do not match
				rpcbind Default-Start values (S 2 3 4 5)
insserv: warning: current start runlevel(s) (empty) of script `rpcbind'
				overrides LSB defaults (2 3 4 5 S).
insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6 S) of script
				`rpcbind' overrides LSB defaults (0 1 6).

root@raspberrypi:~# ls -F /etc/rc*/*rpcbind
/etc/rc0.d/K05rpcbind@  /etc/rc3.d/K05rpcbind@  /etc/rc6.d/K05rpcbind@
/etc/rc1.d/K05rpcbind@  /etc/rc4.d/K05rpcbind@  /etc/rcS.d/K12rpcbind@
/etc/rc2.d/K05rpcbind@  /etc/rc5.d/K05rpcbind@

That didn't work. I'm not sure why, but it's easy to fix. Let's remove those K??rpcbind links and re-run the update-rc.d command:

root@raspberrypi:~# rm /etc/rc*/*rpcbind
root@raspberrypi:~# update-rc.d rpcbind defaults
update-rc.d: using dependency based boot sequencing
update-rc.d: warning: default start runlevel arguments (2 3 4 5) do not match
				rpcbind Default-Start values (S 2 3 4 5)

root@raspberrypi:~# ls -F /etc/rc*/*rpcbind
/etc/rc0.d/K05rpcbind@  /etc/rc3.d/S12rpcbind@  /etc/rc6.d/K05rpcbind@
/etc/rc1.d/K05rpcbind@  /etc/rc4.d/S12rpcbind@  /etc/rcS.d/S12rpcbind@
/etc/rc2.d/S12rpcbind@  /etc/rc5.d/S12rpcbind@

It worked that time! Now let's add nfs-kernel-server. Notice that the ordering is handled, the RPC port mapper starts as S12, and then the NFS server can start as S14. It's the reverse at shutdown or reboot, with NFS service stopping as K01 and the RPC port mapper stopping later as K05.

root@raspberrypi:~# update-rc.d nfs-kernel-server defaults
update-rc.d: using dependency based boot sequencing

root@raspberrypi:~# ls -F /etc/rc*/*nfs-kernel-server
/etc/rc0.d/K01nfs-kernel-server@  /etc/rc4.d/S14nfs-kernel-server@
/etc/rc1.d/K01nfs-kernel-server@  /etc/rc5.d/S14nfs-kernel-server@
/etc/rc2.d/S14nfs-kernel-server@  /etc/rc6.d/K01nfs-kernel-server@
/etc/rc3.d/S14nfs-kernel-server@

root@raspberrypi:~# ls -F /etc/rc2.d/
K01lightdm@     S12rpcbind@            S15cron@            S17plymouth@
K05nfs-common@  S14ifplugd@            S15dbus@            S17rc.local@
README          S14nfs-kernel-server@  S15dphys-swapfile@  S17rmnologin@
S01bootlogs@    S14rsyslog@            S15ntp@
S01motd@        S14sudo@               S15rsync@
S01sysfsutils@  S14triggerhappy@       S15ssh@

We define what we want to share, with which hosts or lists or blocks of IP addresses, in what modes, in /etc/exports.

root@raspberrypi:~# cat /etc/exports
/exports    10.0.0.0/8(rw)

Let's manually start the port mapper and the NFS server in the proper order.

root@raspberrypi:~# /etc/init.d/rpcbind start
[ ok ] Starting rpcbind daemon....
root@raspberrypi:~# /etc/init.d/nfs-kernel-server start
[ ok ] Exporting directories for NFS kernel daemon....
[....] Starting NFS kernel daemon: nfsdrpc.nfsd: address family inet6 not supported by protocol TCP
 mountdrpc.mountd: svc_tli_create: could not open connection for udp6
rpc.mountd: svc_tli_create: could not open connection for tcp6
rpc.mountd: svc_tli_create: could not open connection for udp6
rpc.mountd: svc_tli_create: could not open connection for tcp6
rpc.mountd: svc_tli_create: could not open connection for udp6
rpc.mountd: svc_tli_create: could not open connection for tcp6
. ok 

Those error messages are troubling. But they happen only because the NFS server was expecting both IPv4 and IPv6 networking to be configured, while the Raspberry Pi runs only IPv4 by default. It's easy to configure IPv6, see the networking page for all the details. If we just load the IPv6 module, the kernel will automatically configure a link-local IPv6 address for each interface.

root@raspberrypi:~# /etc/init.d/nfs-kernel-server stop
[ ok ] Stopping NFS kernel daemon: mountd nfsd.
[ ok ] Unexporting directories for NFS kernel daemon....

root@raspberrypi:~# modprobe ipv6
root@raspberrypi:~# /etc/init.d/nfs-kernel-server start
[ ok ] Exporting directories for NFS kernel daemon....
[ ok ] Starting NFS kernel daemon: nfsd mountd.

Let's go to another machine and test a number of things with one command — can we contact the RPC port mapper, does the port mapper know about the NFS server, and is the NFS server ready to serve something? Then with a second command, has anything mounted any of the shared file systems?

cromwell@desktop:~% showmount -e raspberrypi
Export list for raspberrypi:
/export1 *

cromwell@desktop:~% showmount -a raspberrypi
All mount points on raspberrypi:

Configure NFS Automounting on the Clients

Now let's set up automounting on the clients! The following is all done on a client, not on the Raspberry Pi itself but on a client that will use the Raspberry Pi as a network storage appliance.

You can do this in a variety of ways. I am going to set this up so that /backup will magically appear and be connected to the network storage whenever anyone references that part of the file system. If the NFS volume isn't currently mounted, there will be no /backup. But as soon as it is referenced, the client will automatically mount it and keep it mounted as long as it is used at least every so often.

To accomplish my goal, I just add one line to /etc/autofs/auto.master and then I create a small file defining that automatically mounted NFS file system.

[root@desktop~]# tail -1 /etc/autofs/auto.master 
/-    auto.backup

[root@desktop~]# cat /etc/autofs/auto.backup 
/backup    -tcp    raspberrypi:/home

Now let's (re)start the automounter service and see what we get. If it wasn't already running, it fails to stop the non-existent service but that's nothing to worry about. I have already copied a hierarchy of directories and files over to the Raspberry Pi's disk.

[root@desktop~]# /etc/init.d/autofs restart
Stopping NFS automounter                                         [FAIL]
Starting NFS automounter                                         [ OK ]

[root@desktop~]# ls -F /backup
Desktop/  Documents/  Pictures/   Videos/

[root@desktop~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
rootfs                909G   20G  843G   3% /
devtmpfs              3.8G     0  3.8G   0% /dev
tmpfs                 3.8G  772K  3.8G   1% /dev/shm
tmpfs                 3.8G  1.1M  3.8G   1% /run
/dev/sda6             909G   20G  843G   3% /
tmpfs                 3.8G     0  3.8G   0% /sys/fs/cgroup
/dev/sda1             190M  161M   20M  90% /boot
/dev/sdc1             1.8T  1.5T  397G  79% /home
/dev/sdb1             917G  860G   58G  94% /home2
/dev/sdd1             459G  201G  258G  44% /home3
raspberrypi:/export1  459G   42G  435G   9% /backup

The mount command can show us further details.

[root@desktop~]# mount
rootfs on / type rootfs (rw)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,relatime,size=3923584k,nr_inodes=980896,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,relatime)
tmpfs on /run type tmpfs (rw,nosuid,nodev,relatime,mode=755)
/dev/sda6 on / type ext4 (rw,relatime,data=ordered)
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct)
systemd-1 on /proc/bus/usb type autofs (rw,relatime,fd=19,pgrp=1,timeout=300,minproto=5,maxproto=5,direct)
mqueue on /dev/mqueue type mqueue (rw,relatime)
securityfs on /sys/kernel/security type securityfs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime)
/dev/sda1 on /boot type ext4 (rw,relatime,data=ordered)
/dev/sdc1 on /home type ext4 (rw,relatime,data=ordered)
/dev/sdb1 on /home2 type ext4 (rw,relatime,data=ordered)
/dev/sdd1 on /home3 type ext4 (rw,relatime,data=ordered)
usbfs on /proc/bus/usb type usbfs (rw,relatime,devgid=43,devmode=664)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
nfsd on /proc/fs/nfsd type nfsd (rw,relatime)
auto.backup on /backup type autofs (rw,relatime,fd=6,pgrp=6200,timeout=300,minproto=5,maxproto=5,direct)
raspberry:/export1 on /backup type nfs4 (rw, relatime, vers=4.0, rsize=65536, wsize=65536, namlen=255, hard, proto=tcp, port=0, timeo=600, retrans=2, sec=sys, clientaddr=10.1.1.100, local_lock=none, addr=10.1.1.232)

We could tune the automounter by setting variables in /etc/sysconfig/autofs or by specifying options for individual file systems in the automount map file(s), but the defaults are probably fine. I specified -tcp for this mount, but that would not have to be explicitly set on some clients.

All that would remain now would be setting the ownership, group and permissions on the file system on the server. Of course, the numerical user and group ids must be synchronized between the NFS server and its clients!

Select a Raspberry Pi topic:

Which model and how much memory?

$ cat /sys/firmware/devicetree/base/model
$ grep MemTotal /proc/meminfo
Raspberry Pi starter kit with aluminum case
Amazon B07XTRFD3Z
Back to the Linux / Unix page Radio Topics