sshfs is a great feature to map external directories onto a local Linux machine and work from the Linux machine as if you were working on the external machines. sshfs is a much better and modern replacement of NFS which gets outdated...
According to Wikipedia:
In computing, SSHFS (SSH Filesystem) is a filesystem client to mount and interact with directories and files located on a remote server or workstation over a normal ssh connection.[3] The client interacts with the remote file system via the SSH File Transfer Protocol (SFTP),[4] a network protocol providing file access, file transfer, and file management functionality over any reliable data stream that was designed as an extension of the Secure Shell protocol (SSH) version 2.0.
The current implementation of SSHFS using FUSE is a rewrite of an earlier version.
First and formost, you have to install sshfs. To do this, run the command sudo apt install sshfs.
If you get the message
geertvc@TL0355418:~/mystuff/bashfiles$ sudo apt install sshfs
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package sshfs is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'sshfs' has no installation candidate
you have to run the following command, since the package is apparently moved to another repository (see this link):
apt-add-repository universe
The apt-add-repository command is by default available in Linux 24.04 but not on the Raspberry Pi. To get it on the Raspberry Pi you have to run the command sudo apt install software-properties-common.
Once this is done a module has to be installed if needed: sudo modprobe fuse.
sshfs can be used to copy and use files over different computers. I myself use it as a convenient way to copy files between different Raspberry Pi's and even during compilation of applications where header files are stored on one Raspberry Pi and used during compilation on another Raspberry Pi.
One such use case is my current immediateC project I'm working on, together with John Wulff, the original author of immediateC.
For that particular project, I'm using 2 RPi's where one RPi is the "master" and the other one is the "slave". The master RPi contains header files that are needed during compilation by the slave RPi.
To take advantage of SSHFS, one RPi (local) must be able to connect to the other RPi (remote) without the need to enter a password. Therefore, the first thing to be done is to exchange public keys between the two RPi's. This works as follows:
Using OpenSSH (and the OpenSSL library), run the command ssh-keygen -t rsa -b 4096 on the local RPi. To make it more general, let's call this the local Linux machine and the other RPi the remote Linux machine.
The above command will generate a private/public key pair on the local Linux machine with the following properties:
encryption type is rsa (Rivest–Shamir–Adleman cryptographic method). This is a quite old, but still very much in use cryptographic method. The more up-to-date cryptographic method is ed25519 but this is not yet used very commonly, although it's also already 5+ years old. See further.
rsa is still the favourable encryption method.
bit size of the encryption is 4096 (the higher, the better)
default filenames are id_rsa (private key) and id_rsa.pub (public key)
filenames are stored in the directory ~/.ssh on the local Linux machine (directory is made, if it doesn't exist yet)
You can also use OpenSSH to install the more modern ed25519 encryption key.
There's a nice article written by Ben McDonald that can be found here.
To generate an ed25519 key, run the following command
ssh-keygen -t ed25519
-C (comment) and -f (file name) options are optional.
By default, the file is also stored in ~/.ssh and will have the name id_ed25519 and id_25519.pub unless specified otherwise with the -f option.
A possible good comment could be username@hostname-date. This indicates user, host and generation date for the key. This way, if there are multiple keys in the ~/.ssh directory it's more easy to know which key is applied where.
Note that ed25519 is fixed at 256 bytes, so the parameter -b is not relevant here unlike with an RSA key.
To get access from the local Linux machine to the remote Linux machine without having to give the password, the public key of the local Linux machine must be copied over to the remote Linux machine.
For this, the command ssh-copy-id can be run from the local Linux machine with the following parameters:
ssh-copy-id -i <location_of_public_key> <user>@<ip_address_of_remote_machine>
Example: ssh-copy-id -i ~/.ssh/id_rsa.pub pi@192.168.0.25
Once you submit the above command, the password of the remote machine will be asked.
Once the password is given, the public key of the local Linux machine will be copied into a file authorized_keys located in the ~/.ssh directory on the remote Linux machine. If needed, both the directory as well as the file will be created on the remote Linux machine with the correct permissions.
To test the connection on the local machine, you can immediately submit the command ssh <user>@<ip_addres_remote_machine> (it's suggested even to do this after the copy command was successful)
If all went well, you should be able to log in onto the remote Linux machine from the local Linux machine without having to give the password of the remote Linux machine.
If needed, do the same for the remote Linux machine so that you can also access the local Linux machine from the remote Linux machine:
Create a private/public key pair on the remote Linux machine
Copy over the public key from the remote Linux machine
Test the connection from the remote Linux machine to the local Linux machine
Once all this is done you have to create a mounting point on the local Linux machine from where you want to access the files on the remote Linux machine. Example: mkdir /home/pi/remote_machine.
Next, you have to "map" a directory on the remote Linux machine onto your mounting point on the local Linux machine.
Suppose we want to map the directory /home/pi/mystuff on the remote Linux machine onto the mounting point /home/pi/remote_machine on the local Linux machine we just created. This has to be done like so:
sshfs pi@<remote_ip_address>:<location_on_remote_rpi> <local_mounting_point>
Practical example:
sshfs pi@192.168.1.40:/home/pi/mystuff ~/remote_machine
Note: for the local RPi I didn't use the FQN, I used the shortcut name instead (~/remote_machine).
Once this is done, the content of the mounting point ~/remote_machine on the local Linux machine will show you all the files and directories within the ~/mystuff directory on the remote machine.
Now you can use files from the remote Linux machine in e.g. C files or .ic files like so:
.
.
%include "/home/pi/mystuff/remote_machine/immediatec/src/gevadomotics/single_item/mcp_iec_common.ih"
.
.
Where:
/home/pi/mystuff/remote_machine is the mounting point on the local Linux machine
/immediatec/src/gevadomotics/single_item/mcp_iec_common.ih is a file on the remote Linux machine located in the remote directory /home/pi/mystuff.
This is one example of how sshfs can be used.
Suppose we have the following setup:
A Raspberry Pi having the functionblocks.ih file located in /home/pi/mystuff/ff/functionblocks.ih
A Raspberry Pi having an application that needs that functionblocks.ih file in its application
To achieve this, we have to do the following:
Make sure both Raspberry Pi's can connect to each other using private/public key pairs (preferrably ED25519 key pairs)
On the Raspberry Pi that needs the functionblocks.ih file from the other Raspberry Pi, do the following:
If not done yet, create a mounting directory. Example: /home/pi/mystuff/rpi_mount
Run the command sshfs pi@192.168.1.40:/home/pi/mystuff /home/pi/mystuff/rpi_mount (FQN is used here, IP address is assumed)
This will mount the /home/pi/mystuff directory of the "provider" Raspberry Pi onto the mount directory rpi_mount
On the Raspberry Pi that needs the file, you can now go to the directory /home/pi/mystuff/rpi_mount and you will see the content of the "provider" Raspberry Pi's directory /home/pi/mystuff.
In the application .ic file on the Raspberry Pi that needs the file functionblocks.ih you can write an %include statement as if the functionblocks.ih file was located in its own RFS:
%include /home/pi/mystuff/rpi_mount/ff/functionblocks.ih
This will compile correctly and all function blocks defined in that file can now be freely used in the immediateC application, even if the file is physically located on the "provider" Raspberry Pi!
If you want to unmount a mounted point you have to use the command fusermount.
To unmount a mounted point:
fusermount -u <mounting_point>
Example:
fusermount -u ~/mystuff/rpi_mount_dir
Below is a shell script that checks if a given mounting point is existing or not. If not, create the mounting point using a call to a soft link which points to a shell script performing the real mounting command.
#!/bin/bash
if ! mountpoint -q /home/pi/mystuff/rpi_mount_dir;
then
sfs
fi
iCmake -Wno-all -slf -o piI2C_o2 piI2C_o2.ic
./setup_o2
This script does more than checking if a mount point exists, but the interesting part is given in bold blue.
If the mount point is not existing, run the command sfs which is a soft link to the following bash script:
#!/bin/bash
sshfs pi@192.168.1.40:/home/pi/mystuff ~/mystuff/rpi_mount_dir
The soft link has been created using the following command:
ln -s ~/mystuff/bashfiles/sfs.sh sfs
And then:
made sfs executable
made sure the PATH environment variable contained the path to ~/mystuff/bashfiles so that sfs can be called from anywhere.