Nfs – How to rearange a file tree and then export it over NFS

nfssymbolic-linksymlink

I've got a backup server that stores incremental backups in a tree like this:

/backups       
   hourly.0
      server 1
      server 2
   hourly.1
      server 1
      server 2
   hourly.2
      server 1
      server 2
   daily.0
      server 1
      server 2
   etc...

Without changing the source tree with the actual backups, I'd like to create a re-organized tree that looks like this:

/share
   server1/1 Hour Ago -> /backups/hourly.0/server1
   server1/2 Hours Ago -> /backups/hourly.1/server1
   server2/1 Hour Ago -> /backups/hourly.0/server2
   server2/2 Hours Ago -> /backups/hourly.1/server2
   ...

… and then export this tree as a single NFS mount.

The NFS client should see:

/backups       
   server 1
      1 Hour Ago
      2 Hours Ago
   server 2
      1 Hour Ago
      2 Hours Ago

Failed Attempt #1 – Use Symlinks

This doesn't work, because symlinks are relevant to the NFS client machine not the server. Trying to open "1 Hour Ago" on a client tries to access /backups/hourly.0/server1 on the client which does not exist.

Failed Attempt #2 – Use BIND in /etc/fstab

ie:

/backup/hourly.0/server1/ "/share/server1/1 Hour Ago" none ro,bind,defaults 0 0

This let me create the tree I wanted, which was visible on the NFS clients, but I couldn't see anything inside the folders. This is presumably because NFS does not span file systems, and NFS sees a bind mount point as a new file system.

Is there any way to accomplish this?

Best Answer

No, this is not possible with a single NFS export on kernel based nfs server.

As exports(5) manual says:

The file /etc/exports contains a table of local physical file systems on an NFS server that are accessible to NFS clients.

However you can export parts of the tree and reassemble them on the clients with bind.

Symbolic links

Another palliative is to use symlinks:

/server_1
  hourly.0 -> /backups/hourly.0/server\ 1
  hourly.1 -> /backups/hourly.1/server\ 1
  ...
/server_2
  hourly.0 -> /backups/hourly.0/server\ 2
  hourly.1 -> /backups/hourly.1/server\ 2
  ...

For this to work you would have to export the whole backups tree as well as the server directories. This means that with symlinks each server will see the backups of the other servers.

nohide option

There are nohide and crossmount options in the exports file. It only works for single server exports. I never used it because of the many warnings that accompany this option in the docs, such as the possibility of inode number clash.

Since you are exporting directory trees from the same physical file system you will never encounter this inode number clash or the deadlock caused by a dead intermediate server that can occur when exporting NFS-mounted subtree.

I do not think that Linux kernel NFS server would make filesystems mounted with bind option visible with nohide.

Doing it the other way around

I was thinking about the question and realized that probably the right way to approach this it to do it the other way around. That is to make directory trees for each server as you want them exported. Move the data to the appropriate locations and then reassemble the /backups tree with mount -o bind.

That is your filesystem would look like

/share/server1/1_Hour_Ago
               2_Hour_Ago
               ...
/share/server2/1_Hour_Ago
               2_Hour_Ago
               ...

Your fstab would be

/share/server1/1_Hour_Ago /backups/hourly.0/server_1 none rw,bind 0 0 
/share/server1/2_Hour_Ago /backups/hourly.1/server_1 none rw,bind 0 0
...
/share/server2/1_Hour_Ago /backups/hourly.0/server_2 none rw,bind 0 0 
/share/server2/2_Hour_Ago /backups/hourly.1/server_2 none rw,bind 0 0
...

Your exports would be just

/share/server1 server1(rw,no_subtree_check) 
/share/server2 server2(rw,no_subtree_check)