2012-08-06 01:44:11 +08:00
< html >
< head >
< title > NFS Client How-To< / title >
< / head >
< body background = "backgd.gif" >
< hr > < hr >
< table width = "100%" >
< tr align = "center" bgcolor = "#e4e4e4" >
< td >
< h1 > < big > < font color = "#3c34ec" > < i > NFS Client How-To< / i > < / font > < / big > < / h1 >
< p > Last Updated: June 18, 2012< / p >
< / td >
< / tr >
< / table >
< hr > < hr >
< table width = "100%" >
< tr bgcolor = "#e4e4e4" >
< td >
< h1 > Table of Contents< / h1 >
< / td >
< / tr >
< / table >
< center > < table width = "80%" >
< tr >
< td >
< table >
< tr >
< td valign = "top" width = "22" > < img height = "20" width = "20" src = "favicon.ico" > < / td >
< td >
< a href = "#nfsconfiguration" > Adding NFS to the NuttX Configuration< / a >
< / td >
< / tr >
< / table >
< table >
< tr >
< td valign = "top" width = "22" > < img height = "20" width = "20" src = "favicon.ico" > < / td >
< td >
< a href = "#mountinterface" > Mount Interface< / a >
< / td >
< / tr >
< / table >
< table >
< tr >
< td valign = "top" width = "22" > < img height = "20" width = "20" src = "favicon.ico" > < / td >
< td >
< a href = "#nfsmount" > NFS Mount Command< / a >
< / td >
< / tr >
< / table >
< table >
< tr >
< td valign = "top" width = "22" > < img height = "20" width = "20" src = "favicon.ico" > < / td >
< td >
< a href = "#serverconfig" > Configuring the NFS server (Ubuntu)< / a >
< / td >
< / tr >
< / table >
< / td >
< / tr >
< / table > < / center >
< table width = "100%" >
< tr bgcolor = "#e4e4e4" >
< td >
< a name = "nfsconfiguration" > < h1 > Adding NFS to the NuttX Configuration< / h1 > < / a >
< / td >
< / tr >
< / table >
< p >
The NFS client is easily added to your configuration:
You simply need to add < code > CONFIG_NFS< / code > to your < code > nuttx/.config< / code > file.
There are, however, a few dependencies on other system settings:
< / p >
< ol >
< li >
2019-02-12 02:09:26 +08:00
First, there are things that you must configure in order to be able to use any file system:
2012-08-06 01:44:11 +08:00
< / li >
< ul >
< li >
< code > CONFIG_DISABLE_MOUNTPOINT=n< / code > . You must include support for mount points in the pseudo-file system.
< / li >
< / ul >
< li >
And there are several dependencies on the networking configuration.
At a minimum, you need to have the following selections:
< / li >
< ul >
< li >
< code > CONFIG_NET=y< / code > . General networking support.
< / li >
< li >
< code > CONFIG_NET_UDP=y< / code > . Support for UDP.
< / li >
< / ul >
< / ol >
< table width = "100%" >
< tr bgcolor = "#e4e4e4" >
< td >
< a name = "mountinterface" > < h1 > Mount Interface< / h1 > < / a >
< / td >
< / tr >
< / table >
< p >
A low-level, C-callable interface is provided to mount a file system.
That interface is called < code > mount()< / code > and is mentioned in the < a href = "NuttxPortingGuide.html#NxFileSystem" > < code > porting guide< / code > < / a > and is prototyped in the header file < code > include/sys/mount.h< / code > :
< / p >
< ul > < pre >
int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data);
< / pre > < / ul >
< p >
< b > Synopsis< / b > :
< code > mount()< / code > attaches the filesystem specified by the < code > source< / code > block device name into the root file system at the path specified by < code > target< / code > .
< / p >
< p >
2019-07-31 06:08:19 +08:00
< b > Input Parameters< / b > :
2012-08-06 01:44:11 +08:00
< ul >
< li > < code > source< / code > . A null-terminated string providing the fill path to a block driver in the NuttX pseudo-file system.
< li > < code > target< / code > . The location in the NuttX pseudo-file system where the volume will be mounted.
< li > < code > filesystemtype< / code > . A string identifying the type of file system to use.
< li > < code > mountflags< / code > . Various flags that can be used to qualify how the file system is mounted.
< li > < code > data< / code > . Opaque data that is passed to the file system with the mount occurs.
< / ul >
< / p >
< p >
< b > Returned Values< / b >
Zero is returned on success; -1 is returned on an error and < code > errno< / code > is set appropriately:
< ul >
< li > < code > EACCES< / code > .
2019-07-31 06:08:19 +08:00
A component of a path was not searchable or mounting a read-only filesystem was attempted without giving the < code > MS_RDONLY< / code > flag.
2012-08-06 01:44:11 +08:00
< / li >
< li > < code > EBUSY< / code > .
< code > source< / code > is already mounted.
< / li >
< li > < code > EFAULT< / code > .
One of the pointer arguments points outside the user address space.
< / li >
< li > < code > EINVAL< / code > .
< code > source< / code > had an invalid superblock.
< / li >
< li > < code > ENODEV< / code > .
< code > filesystemtype< / code > not configured
< / li >
< li > < code > ENOENT< / code > .
A pathname was empty or had a nonexistent component.
< / li >
< li > < code > ENOMEM< / code > .
Could not allocate a memory to copy filenames or data into.
< / li >
< li > < code > ENOTBLK< / code > .
< code > source< / code > is not a block device
< / li >
< / ul >
< / p >
< p >
This same interface can be used to mount a remote, NFS file system using some special parameters.
The NFS mount differs from the < i > normal< / i > file system mount in that: (1) there is no block driver for the NFS file system, and (2) special parameters must be passed as < code > data< / code > to describe the remote NFS server.
Thus the following code snippet might represent how an NFS file system is mounted:
< / p >
< ul > < pre >
#include < sys/mount.h>
#include < nuttx/fs/nfs.h>
struct nfs_args data;
char *mountpoint;
ret = mount(NULL, mountpoint, string " nfs" , 0, (FAR void *)&data);
< / pre > < / ul >
< p >
2014-07-08 05:54:37 +08:00
NOTE that: (1) the block driver parameter is < code > NULL< / code > .
2012-08-06 01:44:11 +08:00
The < code > mount()< / code > is smart enough to know that no block driver is needed with the NFS file system.
(2) The NFS file system is identified with the simple string " nfs"
(3) A reference to < code > struct nfs_args< / code > is passed as an NFS-specific argument.
< / p >
< p >
The NFS-specific interface is described in the file < code > include/nuttx/fs/nfs.h< / code > .
There you can see that < code > struct nfs_args< / code > is defined as:
< / p >
< ul > < pre >
struct nfs_args
{
uint8_t addrlen; /* Length of address */
uint8_t sotype; /* Socket type */
uint8_t flags; /* Flags, determines if following are valid: */
uint8_t timeo; /* Time value in deciseconds (with NFSMNT_TIMEO) */
uint8_t retrans; /* Times to retry send (with NFSMNT_RETRANS) */
uint16_t wsize; /* Write size in bytes (with NFSMNT_WSIZE) */
uint16_t rsize; /* Read size in bytes (with NFSMNT_RSIZE) */
uint16_t readdirsize; /* readdir size in bytes (with NFSMNT_READDIRSIZE) */
char *path; /* Server's path of the directory being mount */
struct sockaddr_storage addr; /* File server address (requires 32-bit alignment) */
};
< / pre > < / ul >
< table width = "100%" >
< tr bgcolor = "#e4e4e4" >
< td >
< a name = "nfsmount" > < h1 > NFS Mount Command< / h1 > < / a >
< / td >
< / tr >
< / table >
< p >
The < a href = "NuttShell.html" > NuttShell (NSH)< / a > also supports a command called < code > nfsmount< / code >
that can be used to mount a remote file system via the NSH command line.
< / p >
< p >
< b > Command Syntax:< / b >
< / p >
< ul > < pre >
nfsmount < server-address> < mount-point> < remote-path>
< / pre > < / ul >
< p >
< b > Synopsis< / b > .
The < code > nfsmount< / code > command mounts a network file system in the NuttX pseudo filesystem.
The < code > nfsmount< / code > will use NFSv3 UDP protocol to mount the remote file system.
< / p >
< p >
< b > Command Line Arguments< / b > .
The < code > nfsmount< / code > takes three arguments:
< / p >
< ol >
< li >
The < code > < server-address> < / code > is the IP address of the server exporting the file system you wish to mount.
This implementation of NFS for the NuttX RTOS is only for a local area network, so the server and client must be in the same network.
< / li >
< li >
The < code > < mount-point > < / code > is the location in the NuttX pseudo filesystem where the mounted volume will appear.
This mount point can only reside in the NuttX pseudo filesystem.
By convention, this mount point is a subdirectory under < code > /mnt< / code > .
The mount command will create whatever pseudo directories that may be needed to complete the full path (but the full path must not already exist).
< / li >
< li >
The < code > < remote-path> < / code > is the file system < code > /< / code > directory being exported from server.
This < code > /< / code > directory must have been configured for exportation on the server before when the NFS server was set up.
< / li >
< / ol >
< p >
After the volume has been mounted in the NuttX pseudo filesystem, it may be access in the same way as other objects in the file system.
< / p >
< p >
< b > Example< / b > .
2013-08-27 23:40:19 +08:00
Suppose that the NFS server has been configured to export the directory < code > /export/shared< / code > .
2012-08-06 01:44:11 +08:00
The the following command would mount that file system (assuming that the target also has privileges to mount the file system).
< / p >
< ul > < pre >
NuttShell (NSH)
nsh> ls /mnt
/mnt:
nsh: ls: no such directory: /mnt
nsh> nfsmount 10.0.0.1 /mnt/nfs /export/shared
nsh> ls -l /mnt/nfs
/mnt/nfs:
drwxrwxrwx 4096 ..
drwxrwxrwx 4096 testdir/
-rw-rw-rw- 6 ctest.txt
-rw-r--r-- 15 btest.txt
drwxrwxrwx 4096 .
nsh> echo " This is a test" > /mnt/nfs/testdir/testfile.txt
nsh> ls -l /mnt/nfs/testdir
/mnt/nfs/testdir:
-rw-rw-rw- 21 another.txt
drwxrwxrwx 4096 ..
drwxrwxrwx 4096 .
-rw-rw-rw- 16 testfile.txt
nsh> cat /mnt/nfs/testdir/testfile.txt
This is a test
< / pre > < / ul >
< table width = "100%" >
< tr bgcolor = "#e4e4e4" >
< td >
< a name = "serverconfig" > < h1 > Configuring the NFS server (Ubuntu)< / h1 > < / a >
< / td >
< / tr >
< / table >
< p >
Setting up the server will be done in two steps:
First, setting up the configuration file for NFS, and then starting the NFS services.
2017-05-12 03:35:56 +08:00
But first, you need to install the nfs server on Ubuntu with these two commands:
2012-08-06 01:44:11 +08:00
< / p >
< ul > < pre >
# sudo apt-get install nfs-common< / FONT >
# sudo apt-get install nfs-kernel-server< / FONT >
< / pre > < / ul >
< p >
After that, we need to make or choose the directory we want to export from the NFS server.
In our case, we are going to make a new directory called < code > /export< / code > .
< / p >
< ul > < pre >
# sudo mkdir /export
< / pre > < / ul >
< p >
2014-02-21 08:14:02 +08:00
It is important that < code > /export< / code > directory allow access to everyone (777 permissions) as we will be accessing the NFS share from the client with no authentication.
2012-08-06 01:44:11 +08:00
< / p >
< ul > < pre >
# sudo chmod 777 /export
< / pre > < / ul >
< p >
When all this is done, we will need to edit the configuration file to set up an NFS server: < code > /etc/exports< / code > .
This file contains a list of entries;
each entry indicates a volume that is shared and how it is shared.
For more information for a complete description of all the setup options for this file you can check in the man pages (< code > man export< / code > ).< / p >
An entry in < code > /etc/exports< / code > will typically look like this:
< / p >
< ul > < pre >
directory machine1(option11,option12)
< / pre > < / ul >
< p >
2019-07-31 06:08:19 +08:00
So for our example we export < code > /export< / code > to the client 10.0.0.2 add the entry:
2012-08-06 01:44:11 +08:00
< / p >
< ul > < pre >
/export 10.0.0.2(rw)
< / pre > < / ul >
< p >
In our case we are using all the default options except for the < code > ro< / code > that we replaced with < code > rw< / code > so that our client will have read and write access to the directory that we are exporting.
< / p >
< / p >
2014-02-21 08:14:02 +08:00
After we do all the require configurations, we are ready to start the server with the next command:
2012-08-06 01:44:11 +08:00
< / p >
< ul > < pre >
# sudo /etc/init.d/nfs-kernel-server start
< / pre > < / ul >
< / p >
Note: If you later decide to add more NFS exports to the /etc/exports file, you will need to either restart NFS daemon
or run command exportfs.
< / p >
< ul > < pre >
2014-02-21 08:14:02 +08:00
# sudo /etc/init.d/nfs-kernel-server start
2012-08-06 01:44:11 +08:00
< / pre > < / ul >
< p > Or< / p >
< ul > < pre >
# exportfs -ra
< / pre > < / ul >
< p >
Now we can check if the export directory and our mount point is properly set up.
< / p >
< ul > < pre >
# sudo showmount -e
# sudo showmount -a
< / pre > < / ul >
< p >
And also we can verify if NFS is running in the system with:
< / p >
< P STYLE = "margin-left: 0.49in; margin-bottom: 0in; line-height: 100%" >
< ul > < pre >
# rpcinfo – p< / FONT >
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100011 1 udp 749 rquotad
100011 2 udp 749 rquotad
100005 1 udp 759 mountd
100005 1 tcp 761 mountd
100005 2 udp 764 mountd
100005 2 tcp 766 mountd
100005 3 udp 769 mountd
100005 3 tcp 771 mountd
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
300019 1 tcp 830 amd
300019 1 udp 831 amd
100024 1 udp 944 status
100024 1 tcp 946 status
100021 1 udp 1042 nlockmgr
100021 3 udp 1042 nlockmgr
100021 4 udp 1042 nlockmgr
100021 1 tcp 1629 nlockmgr
100021 3 tcp 1629 nlockmgr
100021 4 tcp 1629 nlockmgr
< / pre > < / ul >
< p >
Now your NFS sever is sharing < code > /export< / code > directory to be accessed.
< / p >
< / body >
< / html >