Gnokiifs -------- Copyright (c) Edward Rosten 2005 er258 (at) cam (dot) ac (dot) uk This program talks gnokii on one and coda on the other, allowing you to mount the files on your Nokia phone (tested on the 7600 only). LICENSE ------- See the file LICENSE REQUIREMENTS ------------ Gnokii version 0.6.5 or greater. Linux 2.6 Coda (you only need the kernel side. This does not interact with the userland daemon). This comes as with the stock kernel. Some means of communication with your phone. Any means should work, but I have only used this with a DKU2 cable (since that's all I have). Check the gnokii documents for other means of communication. USAGE ----- GnokiiFS can automatically mount the filesystem (if required). To make this work, you will need the following line in /etc/fstab: /dev/cfs0 /mnt/phone coda defaults,user 0 0 This will allow a normal user to mount the phone (note the user must have read/write permissions on /dev/cfs0). Once this is setup, run: gnokiifs This will run gnokiifs and mount the phone. Use Ctrl+C to kill gnokiifs. This will automatically unmount the phone. Note that files are committed to the phone when they are closed, not when the system is unmounted, so any open, but unwritten files will be lost. By default, GnokiiFS will perform a lazy unmount, which means that the filesystem can be in use when an unmount happens. If you have special requirements and wish to (un)mount the phone yourself, you can run gnokiifs -n When files are opened non-destructively (i.e. not O_TRUNC), they are copied to the local disk first. This can make opening rather slow, especially if you use a program like xv for viewing images, which opens all of the images before displaying any of them. It's amazing what bits of bizzare behaviour you observe when you examine the debugging output from a filingsystem. Make sure you have the coda module loaded/compiled in. Make sure you have read+write access on your coda device (default is /dev/cfs0) Make sure /etc/fstab is setup correctly If you want to use USB, make sure you have nokia_dku2.ko loaded If the command: gnokii --listallfiles 'A:\*' produces an error, you need to configure gnokii properly. This program relies on a properly configured gnokii. Here is the output of gnokiifs -h: gnokiifs [-f X ] [-d X ] [-c X ] [-t X ] [-M X] [-U X] [-hnD] -f X = file permission bits (use 0nnn for octal) default is: 600 -d X = directory permission bits -c X = coda device file default is: 700 -t X = Time after which closed files are flushed from the cache in seconds. default is: 600 seconds -M X = Mountpoint to mount filesystem. default is: /mnt/phone -U X = Unmount flags. default is: -l -n Do NOT perform filesystem mounting and unmounting. -D print very verbose debug messages (only if compiled in) -h print this message INSTALL ------- To compile: ./configure && make then log on as root (if necessary) make install This generates an executable called gnokiifs. It should work, but if you have problems: 1 Make sure the path to the gnokii headers is correct (e.g. /usr/local/include) specify CPPFLAGS on the command line for ./configure 2 Make sure the path to the gnokii library is correct (e.g. /usr/local/lib) specify LDFLAGS on the command line for ./configure If you get lots of errors like "struct timespec redefined" then you have bad kernel headers in /usr/include/linux. The problem is that linux/time.h defines the same stuff as time.h without checking. This program needs both of these headers. If you get errors along the lines of: /usr/include/sys/time.h:95: parse error before numeric constant Then it is also a kernel headers problem. linux/time.h #defines the constants ITIMER_REAL, ITIMER_VIRTUAL and ITIMER_PROF, where as sys/time.h makes them in to an enum. There is a hack in gnokiifs.cpp to try to alleviate this problem, but if the hack is not functioning, then you have two options here: 1 Comment out all the definitions causing errors in 2 Get proper sanitized headers from your distro maker. BUGS / ISSUES ------------- So far it works on at least 2 computers. That's all the resources I have time to test it on. It doesn't compile or run on Linux 2.4. The Coda interface changed from 2.4 to 2.6. I no longer use any 2.4 machines so I'm not going to port and test it, but I will take patches. Many filesystem features are not implemented. Some because gnokii does not expose them, others because I have had no use for them yet. These will usually return EPERM (the message is "Operation not permitted"). If an error occurs internally, the error code seen by the program attempting the operation might not be too sensible. It doesn't work on Solaris. I believe Solaris supports CODA, but I don't have a Sun. Same with Win32. It doesn't work on FreeBSD either. I only have very limited access to a FreeBSD box, so I'm probably not going to do this either. TODO ---- Ioctl for reading the file ID. Add mount points, so the normal files (A:\*) appear in a/*. This allows for other file-systems, (B:\, etc) as well as virtual file-systems, e.g. messages, phone book. Add mappings, so that things like A:\predefgallery appear as A:\Gallery Internationalization of non debugging messages Add command queuing, so that the filesystem doesn't freeze when in use. Add more filesystem commands to gnokii HOW IT WORKS ------------ The Coda kernel module is a fairly generic module for serializing VFS operations. It turns the operations in to a packet of data containing the op-code (to identify the operation), a unique packet identifier (so that the kernel knows which packet you are responding to) and any extra data which it needs to communicate. Replies are structured in a similar fashion, you reply with a packet containing an error code (standard unix ones like ESUCCESS, EIO, etc), the opcode and identifier of the packet you're replying to and any extra data. This program deals with the commands in an entirely serial manner. Therefore an operation which takes a while to complete (such as committing a file to the phone) freezes the filesystem. Communication is done via a device file (usually /dev/cfs0). This works like a packet socket. A read will return a single packet of data, non necessarily a full buffer's worth of data. Writes work in a similar manner. Almost all incoming packets contain the VFid of a file. A VFid is a 128 bit block of data which is opaque to the kernel, but not to you. When Coda is interested in a new file, it performs a LOOKUP operation, giving you the directory and name of the file in which it is interested. You reply to this with a VFid. When the kernel wants to refer to that file in future, it does it by sending you the VFid of the file. Therefore, you need to keep track of which VFid belongs to which file. The VFid size changed from 96 bits to 128 bits during the transition from Linux 2.4 to Linux 2.6 Opening files is performed in a manner which seems rather odd at first glance. When Coda wishes to open a file, you open the file using the normal open() sys call, and respond with the file descriptor of that open file. The kernel module then removes that file from your process and places it in the calling process. All read() and write() operations on that file are dealt with by the kernel, since it is an "ordinary" "local" file. This means that you can't create purely virtual file-systems where read and write are dealt with by you, but it does mean that performance is good. ALTERNATIVE USERLAND FILE-SYSTEMS --------------------------------- There are several approaches to userland file-systems: 1 Shared library hacks. 2 Nonstandard kernel module / userland program pairs 3 Standard kernel module / userland program pairs AVFS ---- This overrides libc calls so that the open/read/write/etc calls can be diverted so that all programs using libc (i.e. all programs) will see a virtual filesystem. It therefore does not require any kernel functionality and can even be used without root being required to set it up. http://www.inf.bme.hu/~mszeredi/avfs/ FUSE ---- Provides a custom module and userspace library with callbacks for interfacing with the module. This has quite a lot of filesystems written for it, and is currently active. http://fuse.sourceforce.net SHFS Shell Filesystem --------------------- A custom module serializes commands and sends them to a userland program (usually ssh). The serialization of the commands is done in such a way that they can be deserialized at the other end by a standard shell. http://shfs.sourceforge.net/internals.html LUFS ---- This uses a kernel module to serialize all VFS operations and transmit them to a single userland daemon (using message passing, I believe). This userland daemon then deserializes the messages and invokes function calls from shared libraries (dynamically linking them in when new file-systems are mounted). This essentially replicates the kernel VFS system in userland and does all the communications for you. Much like the kernel, new file-systems can be added without restarting the daemon. http://lufs.sourceforge.net/lufs/ PerlFS ------ A system which serializes commands down a character device for use by a userland program (emphasis on Perl). This allows one to write file-systems in any suitable language. http://perlfs.sourceforge.net/ PODFUK ------ POrtable Dodgy Filesystems in Userland (hacK). The first version was a set of patches to an NFS server. The second version was a standalone program (a C and Makefile polyglot, in fact) which used coda. This version served as inspiration and a reference for the early versions of gnokiifs. Others ------ Pretty much any system which has userland file serving daemons, i.e. the real Coda, NFS, etc. Widespread adoption of these keeps well maintained modules in the standard kernel.