Blackbanded Sunfish, Enneacanthus chaetodon
A 30-60mm long fish with a very compressed, deep body, a thin pointed pectoral fin and round tail fin. Habitat: swamps, ponds and river pools.
Sunfish
An NFS client, implemented as an image filing system. Habitat: RISC OS.
Contents |
License |
Sunfish is copyright © 2003 Alex Waugh
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Requirements |
Sunfish requires a working network connection and an NFS server to connect to. The server should be running version 2 of the NFS protocol, version 1 of the Mount protocol, version 2 of the portmapper protocol, and optionally version 2 of the pcnfsd protocol. It has currently only been tested with the Linux kernel server present in Debian Woody, but it should work with other servers. Both UDP and TCP connections are supported.
Sunfish should run on any version of RISC OS from 3.11 onwards. It has been reported to work on RISC OS 3.7, RISC OS 4 (including under Virtual RPC), Select, and RISC OS 5. It is 26/32bit neutral.
Sunfish has been reported to work with the Linux 2.4 kernel server in various distibutions, a Solaris 7/8 server, the TrueGrid NFS server on Windows, and Netware 6.5SP1a. It partially works with Allegro NFSd 1.1.4 on Windows, but a bug in that version of the server can cause file not found errors when copying files onto the server.
The rest of this document assumes your server is correctly setup. You may wish to refer to Allan Curtis' notes on setting up a Linux NFS server, or the Drobe article on setting up the TrueGrid server for use with Sunfish.
Any updates will be available from http://www.alexwaugh.com/
Setting up a mount |
Sunfish is implemented as an image filing system. You can either write a mount file by hand, or use the frontend to create one.
To use the frontend, run !Sunfish which will put an icon on the lefthand side of the iconbar. Select New mount...
from the menu then fill in appropriate values for all the options. The options correspond with those described below, and the default values in the filenames, connection and ports sub-windows should not need altering for most simple connections. The mount leafname option is used to give a name to refer to the mount file. When you click on Create
then a mount file with the specified options will be created, and a new icon will be added to the iconbar for that mount.
To manually write a mount file, use your favorite text editor to create a file with the appropriate options as described below. Save this, then set it's filetype to Sunfish (&1b6). Then double click on the mount file you have just created and the server will be mounted and you can navigate the filesystem as normal.
Due to the way image filing systems work, you may not be able to edit the mount file once it has been mounted and while Sunfish is still running. There are two solutions - either set the filetype of the mount file to Text, edit it, then set it back to Sunfish, or *RMKill Sunfish before editing the file.
You may also have to ensure that the connection is not blocked by a firewall. The default configuration on some RedHat systems is known to block NFS traffic.
This is a very simple mount file. It will use pcnfsd to map the username and password onto a uid and gid.
Protocol: NFS2 Server: mint.cp15.org Export: /home/ajw498 Username: ajw498 Password: fiddlesticks
The same as above, but specifying the uid and gid explicitly. pcnfsd is not required in this case, and there is no need for the password to be stored in the file either.
Protocol: NFS2 Server: mint.cp15.org Export: /home/ajw498 UID: 1001 GID: 50
A more complex example.
Protocol: NFS2 Server: mint.cp15.org Transport: tcp Export: /tmp UID: 1002 GID: 51 GIDs: 52 53 105 umask: 066 MachineName: caramel ShowHidden: 0 Timeout: 5 DefaultFiletype: FFF AddExt: 2 MaxDataBuffer: 8192 Pipelining: 1
?xx
where xx is the hexadecimal value of the character. Spaces are mapped onto hard spaces, dots map to slashes and vice versa, and other characters are unchanged.
Unlike most other RISC OS filing systems, filenames may be case sensitive (depending on the casesensitive option). However, it is not recommended to use filenames that differ only in their case, as some programs or RISC OS may not distinguish between them correctly.
Options |
Any line beginning with a # is treated as a comment.
<Inet$Hostname>
which should be sufficient in most cases.
Generally, it doesn't matter what port is used, but some servers will only allow connections from ports less than 1024 unless the insecure option is used in /etc/exports on the server.
The RISC OS attributes are first converted to unix mode bits, with the private attributes mapping to user permissions, and the public attributes mapping to the group and others permissions (if a public attribute is set then both the corresponding group and others permission bit will be set). This value is then ORed with the unumask, and then ANDed with the inverse of the umask to give the final unix mode bits.
If case sensitivity is off, and you have two (or more) files in the same directory that differ only in case then trying to access one of them may result in the wrong file being altered.
Improving Performance |
There are three options that are likely to have an effect on performance: the transport, the MaxDataBuffer option and the Pipelining option.
Using TCP as the transport may give better results than UDP in some circumstances.
Normally, the bigger the data buffer the better (the maximum size is 8192), however some network cards (notably the Castle 100bT podule) cannot cope with large packet sizes when using UDP. I suggest you try setting it to 8192, and if you start getting timeout errors when transferring files then reduce it.
The pipelining option (which is disabled by default) allows file read and write requests to be pipelined which can give around a 20% increase in speed. However, with some servers or network setups it could make things slower. If, for example, your server is running on a 100bT segment while the client is the other side of a switch on a 10bT segment then it is likely to make things worse on a UDP connection, but if the server and client are of comparable speeds on the same segment then it may make things faster.
The server can also have a large influence on the speed. For example, if I read a 30MB file from the server it may take 14 seconds, but if I then read it a second time it take less than half that time because of the filesystem caching on the server.
The following table shows the maximum speeds I have obtained with various settings, and a comparison with LanManFS. If you are seeing significantly slower results then it may be worth experimenting with the above options. All the tests were copying a 68MB file using the filer with the faster option set. I think the server writing the file to disc is the limiting factor in the 100bT write tests.
LanManFS on Iyonix 100bT | Sunfish on SA RPC, Simtec 100bT | Sunfish on Iyonix, 100bT | |
---|---|---|---|
Read | 2.4MB/s | 0.98MB/s | 5.6MB/s |
Write | 1.8MB/s | 0.68MB/s | 1.8MB/s |
Reporting Bugs |
If you discover a bug, please report it to me, or better still fix it yourself and send me a patch. When reporting a bug, first load SysLog, then set the logging option in your mount file before doing the operation that triggers the bug. A log file should be generated in !SysLog.Logs.Sunfish. If you have access to a machine that can run a packet sniffer such as ethereal then it would be very useful to use that to save a dump of the network traffic along with the syslog file. Also, please provide a description of the problem and exactly what operation you were doing to trigger the bug, and details of what OS and NFS version the server is running would be helpful, and the version of the Sunfish module and RISC OS version.
Known Bugs |
The leafname returned from an OS_File 0 call will be in Unix format and may still have a ,xyz extension. This is only used for printing *opt 1 info so is not crucial. The PRMs state that *opt 1 may not work correctly on RISC OS 3 onwards anyway.
Wildcards in filenames are not supported. This would be a lot of hassle to implement for little benefit, and in any case I believe that it really should be fileswitch's job to sort out wildcards, not each and every filing system.
Devices and other non regular files are not supported, as they don't map to RISC OS functionality.
If ShowHidden == 0 and you try to delete a directory that contains hidden files then it will fail with a directory not empty error.
Sunfish does not support programs accessing files from callbacks, and will give an error if this causes reentrancy. This could be fixed if the internet stack didn't require callbacks to be triggered before it notices new data has arrived.
Some operations are not as fast as they could be. For the first release I have concentrated on getting a functional and stable program, and there are some places where performance could be improved in the future. In particular, file attributes and mappings between filenames and NFS file handles should be cached, as this would reduce network traffic and delay for directory listings and many other operations.
Recompiling |
Full source code is provided. To recompile the module, you will need Norcroft v5.53 or later, cmhg 5.42 or later, TCPIPLibs, and Perl. Earlier 26bit versions of Norcroft will not work because the code makes use of 64bit integers and some C99 functions.
For some unknown reason, if you use amu then it will give an error AMU: Don't know how to make 'o.pcnfsd-calls'
after generating pcnfsd-calls.c, but if you rerun amu then it will work. GNU make does not give this problem.