4

I have different disks with pictures

/media/drive1/pictures/
/media/drive2/pictures/
/media/drive3/pictures/
/media/drive4/pictures/
# ...

I have a folder called share which has symlinks for every subfolder of each pictures directory of each drive. I merge every subfolder with a script like this:

# I do this for every drive
for item in "/media/drive1/pictures/"*
do
    target=/media/share/pictures/`basename "$item"`
    if [ ! -d "$target" ]; then
        ln -s "$item" "$target"
        chown -h lsc:lsc "$target"
    fi
done

I've been sharing this successfully with Samba for a whlle now.

[global]
# ...
follow symlinks = yes

Since this is a pure private network and the share is READONLY, security isn't a big deal.

### /etc/exports
/media/share *(ro,async)

When I mount my share mount 1.2.3.4:/ foo the symlinks try to follow on the local host.

My question: How can I share a folder that follows symlinks on the host that's sharing the mount?

NOTE: The bind bind solution in /etc/fstab won't work here, since every subfolder of /media/share/ points to different locations/disks.

  • Why would be bind mount not work? Did you try to add crossmnt to your /etc/exports and restart the NFS server, then remount. – Thomas Aug 27 '16 at 12:19
4

This approach will not work with NFS mounted shares. Symbolic links only contain a path to another file or directory on the originating system where they're being shared from. Unless you take care to make the links relative or to duplicate the same directory structures on remote systems as the originator of the share, they simply will not work.

I cannot think of any method that will allow the directory structure as you've described through NFS, and give you the functionality that you're looking for.

You might want to take a look at the advanced features of automounting, specifically this page titled: Setting advanced automount map options.

References

  • You could use bind mount instead of symlinks! Look at my anser – F. Hauri Dec 22 '17 at 10:44
1

You can do a bind type mount, that is better than links in many situations, in fstab file you can put:

/source    /dest    none defaults,bind   0   0   
1

Why can't you make all the symlinks relative? That would do the trick.

Assuming that on the NFS server (1.2.3.4), you have the following mounted (different physical drives possible)

/media/drive1/pictures/
/media/drive2/pictures/
/media/drive3/pictures/
/media/drive4/pictures/
# ...

In the script change your ln line from

 ln -s "$item" "$target"

to read

 ln -s "../${item#/media/}" "$target"

This would create your symlinks in the format of

../drive1/pictures/...

Since you mention it's a private network and security isn't a concern, you can set the exports to

### /etc/exports
/media *(ro,async)

Then on the client boxes that mount the NFS

mkdir -p foo; mount 1.2.3.4:/media foo

In foo you will now see share, drive1, drive2, drive3, drive4, ...

So in effect you've mounted the whole media directory on your client, and the symlinks are relative so they would work fine. The amount of change needed is pretty minimal, the ${item#/media/} syntax may or may not be supported by your version of bash, any equivalent would do (you can use sed commands, awk, or anything you're familiar with to chop off the /media/).

The only problem left is unique names, if you have the following folder or file

/media/drive1/pictures/same_name1
/media/drive2/pictures/same_name1

The current code

if [ ! -d "$target" ]; then
    ln -s "$item" "$target"
    chown -h lsc:lsc "$target"
fi

Would skip creating a symlink after the first target is encountered. So you may have files that are missing symlinks purely because the name is already used in another drive.

You would need to modify your symlink name to append some kind of unique identifier for these cases.

if [ -d "$target" ]; then
    #extract out the "drive1" part from $item and prepend it to target 
    target="$(echo item | sed -e 's!/media/\([^/]*\)/pictures.*!\1!g')_${target}"
fi

if [ ! -d "$target" ]; then
    ln -s "$item" "$target"
    chown -h lsc:lsc "$target"
fi
0

It works with NFS export options 'nohide,crossmnt'

  1. /dev/sdc1 mounted on /shared
  2. /dev/sdd1 mounted on /shared/disk2
  3. /etc/exports has the mount option nohide and crossmnt
  4. Now reload exports with exportfs -ra

Ref: https://linux.die.net/man/5/exports

-1

Yes, but...

As correctly answered by slm, you could not dereference symlinks by nfs server, but as correctly pointed out by alejandro izquierdo, you could use bind mount to make the job:

  1. Ensure to mount your VFAT or NTFS with option uid=XXX to match correct user (lsc).

    mount -o uid=XXX,gid=YYY /dev/sdX1 /media/drive1
    
  2. Now you could replace your for item in... loop by something like:

    for item in /media/"drive1/pictures"/*
    do
        target="/media/share/pictures/$(basename "$item")"
        if [ ! -d "$target" ]; then
            mkdir "$target"
            mount --bind "$item" "$target"
        fi
    done
    

    Of course, this have to be done with root privileges! By using sudo or maybe from udev scripts...

  3. Care to umount the bind (umount "$target") before umounting the real source (/media/driveX) and don't forget to remove the mountpoint (rmdir "$target").

    Nota: you could rmdir /media/share/pictures/*, then will see some:

    rmdir: failed to remove '/media/share/pictures/drive1/': Device or resource busy
    

    which are not harmfull, then unused empty dirs will be removed.

  • This method didn't work etiher – Seff Jan 22 '18 at 2:20
  • @Seff If you follow correctly, this work! Where did this goes wrong? – F. Hauri Jan 22 '18 at 6:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.