LKARMAFS 0.2.1 (c) 2006-2007 Enrique Vidal (evidal@iti.upv.es) A userspace filesystem for the Rio Karma player based on libkarma and FUSE. This program and all the files enclosed in this package are free software under the terms of the GNU General Public License (GPL). Please refer to the included file COPYING for the exact terms. ---------------------------------------------------------------------------- Table of Contents 1. Introduction 2. Features 3. Prerequisites 4. Instalation 5. Usage 6. Tips 7. Known bugs, workarouns and future developments ---------------------------------------------------------------------------- 1. Introduction Lkarmafs is a GNU-linux user-space filesystem for the Rio Karma (RK) player based on libkarma and FUSE. Starting with version 0.0.4, libkarma supports both the PEARL protocol over the RK TCPIP (Ethernet) interface and the new mounted-disk (USB/OMFS) interfaces. Therefore, lkarmafs provides transparent access to the RK disk contents through both interfaces. Lkarmafs implements a fixed directory structure based on the RK file properties, most of which are extracted from the id3 tags of the tune files. In this release, the directory hierarchy is as follows: mountDirectory/ |-- playlist/ | |-- PlayList1 | |-- PlayList2 | |... | |-- taxi/ | |-- file1 | |-- file2 | |... | `-- tune/ |-- Genre1/ | |-- Artist1/ | | |-- Source1/ (album) | | | |-- Title1 (track) | | | |-- Title2 | | | |... | | | | | |-- Source2/ | | |... | | | |-- Artist2/ | |... | |-- Genre2/ |... In addition, each tune file is shown with a suffix determined from its "codec" property (.flac, .mp3, .ogg, etc.). The Genre level under "tune" can be optionally disabled with a mount option. Missing property values needed for path formation are substitued by a dummy name. Future releases may implement a more flexible scheme, where the whole directory structure is decided by the user through a mount option specifying which properties are assigned to each level of the hierarchy. Starting with 0.1.9, the -T option (see below) enables a new, fake directory 'mountDirectory/upload' where tune files can be copied and they will automatically appear under tune/ with directory and file names derived fron the tune tags. Starting with 0.2.0, mountDirectory/playlist/* files can be expanded, and the corresponding tunes presented following the same hierarchy as that of tune/ In addition, a special control file "mountDirectory/options" is provided to allow changing some options at run time (see Sec. 5 below). ---------------------------------------------------------------------------- 2. Features Lkarmafs provides most usual filesystem calls, including statfs(), readdir(), getattr(), open(), read(), write(), unlink() (delete), etc. In particular, it provides full multiple-access READ support. Once the RK is lkarmafs-mounted you can, for instance, have your PC player (e.g., xmms) play some tunes and, simultaneously, have your favourite streamer stream (other) tunes through the LAN. And meanwhile, you can read some text files of the taxi/ subdir or copy arbritrary files from the RK to your PC. Moreover, if the RK is mounted through the TCPIP interface with the non-blocking-write option -L (see below), you may keep the RK itself playing other tunes through the earphones or the RCA lines. It also provides multiple simultaneous WRITE support. For the TCPIP interface, however, this is true only if the non-blocking-write option is NOT used (the RK is then blocked and you loose the possibility of playing with the RK while it is mounted). By default, write support is only provided for the taxi/ directory, but arbritrary (tune) files can be deleted, moved (renamed) or written to the adequate directories (or to uploading/ -- see above) with the "non-Taxi write" (-T) option. Using the TCPIP interface, write efficiency can be significantly improved by mounting `lkarmafs' with the fuse option `-o direct_io' and using a large I/O blocksize, e.g. by means of `dd bs=131072 if= of='. Example shell-scripts to upload MP3 and OGG tunes are included in this package. Based on FUSE, lkarmafs is mainly intended for single-user use. Nevertheless, using `chmod', taxi file permissions can be arbitrarily changed by the user who has mounted the filesystem. Read-only access can be allowed to other users, under the additional control of standard file access permissions (see fuse options `allow_other', `default_permissions'). Basic properties of the whole filesystem are provided through statfs(). Therefore `df' shows the total disk size and used space. File properties such as size, access permissions, modification and access times, are shown as regular file attributes. For all the other properties, extended attributes are used. Therefore, using the appropriate GNU-Linux tools (e.g., `getfattr', `setfattr') full access to all the RK metadata associated to each file is granted. ---------------------------------------------------------------------------- 3. Prerequisites Lkarmafs is based on the libkarma library and the FUSE kernel module and library. So far, it has been tested with libkarma-0.0.3 through 0.0.5 and fuse-2.4.1 through 2.6.0. The FUSE module comes with recent linux kernels. Its original site is http://fuse.sourceforge.net. Libkarma can be found at http://www.freakysoft.de/html/libkarma. A latest patched libkarma tree matching the latest lkarmafs version can be downloaded from http://sourceforge.net/projects/linux-karma/ Starting with version 0.0.4, libkarma supports the mounted-disk (USB/OMFS) interface. To use it, you need a kernel featuring a recent USB-STORAGE driver and KARMA-PARTITION support. As of Linux kernel version 2.6.16, both are included with vanilla kernels from kernel.org. Older kernels need to be patched, as explained in the web sites given below. In addition, an OMFS driver is needed, which can be found in the same addresses: http://linux-karma.sourceforge.net/rio-usb.html and http://bobcopeland.com/karma/ Beware that omfs-0.5.6 and earlier versions did not provide reliable write support. Starting with version 0.0.8 lkarmafs should be compiled with libkarma-0.0.5 (or later). For the USB interface, this provides very much faster Rio Database loading by reading the RK "smalldb" file and greatly simplifies the use by providing automatic discovery of the interface (and USB/OMFS mount point) where the RK is accessible. Starting with version 0.0.9 lkarmafs should be compiled with libkarma-0.0.5-hg118 (or later). This allows direct uploading of tune files with the correct properties. In particular, rid (to detect duplicates), length and duration are correctly set. ---------------------------------------------------------------------------- 4. Installation 1. Install the FUSE kernel module and library as explained in the fuse README file 2. Compile and install libkarma as explained in the libkarma INSTALL file. The resulting library files libkarma/lib/* should go to /usr/local/lib/ and the include file lkarma.h to /usr/local/include/libkarma/ 3. unpack lkarmafs and go to the lkarmafs main directory 4. make ---------------------------------------------------------------------------- 5. Usage 'lkarmafs -H' shows the available specific lkarmafs options and 'lkarmafs -h' shows the fuse and generic mount options. Use the -f option (non-daemon) to show possible error messages. * Other options: -B : Get properties from ??1 files rather than "smalldb" (USB/OMFS interface) -F : Force files to be written even if they are (different name) duplicates -G : Disable the "genre" level under "tune" in the filesystem hierarchy -L : Don't use permanent write-lock (simultaneous read-write may fail) -T : Allow moving/writing/deleting non-taxi files -U : Don't update play_last (access time) for tune files -V : Show currrent version -W : Don't write "smalldb" upon unmounting (USB/OMFS interface) -X : Don't use extended attributes (for tune properties such as play_count) -Y : Directory view of playlists -A || : RK interface; default: auto-discovery -C : your choice of local codeset; default: from locale -D : name for needed missing property values (def. "-UnKnown-") -E : tr-like pathname editing (man (1) tr) -P : password of your RK, if set In version 0.1.9 a -Z option is enabled to allow one-shot migrating from using MODE_PROPERTY=play_count_limit to MODE_PROPERTY=bpm. This option will be eliminated in future versions. Starting with 0.1.9, options can be read from optional config files. It attempts ~/lkarmafsrc first and, if it fails, /etc/lkarmafsrc. Starting with 0.2.0, a special control file ".../options" is provided to change some options at run time. It workas as follows: "cat .../options" shows the present values and "echo optionLetter > .../options" toggles the corresponding option. Allowed optionLetters are F, G, T, U, W, X, and Y. In addition, "echo E > .../options" terminates lkarmafs and umounts the RK filesystem. * Examples: lkarmafs myMusicDir Finds whether the RK is accessible: either USB/OMFS-mounted somewhere or connected through the Ethernet interface. If it is accessible, mounts the RK disk on myMusicDir/. It is mounted daemon-mode and with the default (FUSE) access permission control. It is assumed that no Ethernet password has been set and the codeset is taken from the locale. Any occurrence of the character "/" in property values needed for path formation (artist, title, etc.) is replaced with "|" and any occurrence of "|" is shown as "\|". If some path-formation property value is missing, it is assigned the default dummy name "-UnKnown-". lkarmafs -T myMusicDir The same as above, but with (limited) write permissions enabled for non-taxi files. A new directory myMusicDir/upload/ appears where tunes can be copied so they will appear under myMusicDir/tune/ with path names derived fron the tune tags. This option also enables tune renaming and deleting and other things such as `cat ~/myMusic/myArtist/myTune.mp3 > myMusicDir/A/B/C.mp3'. This sets the genre, artist, source, title and codec properties to 'A', 'B', 'C' and 'mp3', respectively. In this case, the RK will show this tune with these very same property names, ignoring the tune tags. lkarmafs -f -o allow_other,default_permissions \ -A 192.168.1.33 -P Karma1 -C ISO8859-15 -E "/ " "+_" /mnt/karma Mounts the RK disk trough a specific IP (Ethernet) address on /mnt/karma/. It is mounted non-daemon, with access to users different from the one executing lkarmafs and with basic permissions-control left to FUSE. The password is "Karma1" and the local codeset is set to "ISO8859-15" (latin-1 + Euro). The path-edit option substitutes all occurrences of two characters: "/" --> "+" and " " --> "_". Occurrences of "_" and "_" in properties needed for path formation are escaped with "\". The default name "-UnKnown-" is used for missing path-formation properties. lkarmafs -f -o default_permissions \ -A /mnt/karma2 -P Karma1 -D "=UnDefined=" -E "/" "+" ./karma Mounts the RK disk trough the mounted-disk (USB/OMFS) interface on the local dir karma/ It assumes the second partition of the RK disk has been previously USB/OMFS-mounted on /mnt/karma2 with adequate permissions. Lkarmafs is mounted non-daemon, single-user, with codeset taken from locale and with similar password and pathname edit options as in the previous example. The name for missing property values needed for path formation is set to "=UnDefined=". To unmount: fusermount -u * Auxiliary scripts: A number of simple shell-scripts are provided in the scripts/ directory, mainly as examples of advanced use of lkarmafs: mountLkfsEthernet mounts lkarmafs with useful options and Ethernet tricks umountLkfs umounts lkarmafs cpna: cp from the RK to the PC, ignoring the extended attributes getProps: get all the properties of a file (using ext. attributes) setProps: runs `setfattr' to set a property of a lkarmafs file treeLessColor: invoques "tree" and "less" with colorful options rkUsb: using karma_helper, logically (dis)connects and (un)mounts the RK from the USB/OMFS interface ---------------------------------------------------------------------------- 6. Tips - Taxi files (binaries or scripts) with exec permission can be executed. (this fails if lkarmafs is mounted with the `direct_io' fuse option). - GNOME (and perhaps KDE too) tends to abuse mounted filesystems; e.g., it keeps continuously issuing statfs() calls. You can try to avoid GNOME disturbances by preventing FUSE mounts apper in /etc/mtab. This can be achieved by compiling fusermount with -DIGNORE_MTAB - Use the -X option if you don't plan to do uploads or work with extended attributes (e.g., using scripts/getProps). This prevents warnings when copying from the RK and allows moving files outside the filesystem (e.g., `mv mntPoint/taxi/foo .') - The -T option permits uploading tune files using just `cp' or `dd'. Arbritary names can be given to [genre,] artist and tune directories and file names can be choosen at will too. These names are converted into the corresponding properties, therby overriding the traditional tag-based properties naming. The RK does recognize and play tunes copied or moved in this way. Such a very convenient flexibility, however, may lead to inconsistencies if not used properly. - To mount lkarmafs using "mount", enter a line in /etc/fstab such as: "lkarmafs[#] /mnt/lkfs/ fuse defaults,user,rw" where the optional is the RK mounted USB disk path, hostname or IP. Beware: for this to work lkarmafs must be accessible through executable path search ($PATH). Note also that, in some cases, the FUSE script "/sbin/mount.fuse" is broken (don't export $HOME). * Only for TCPIP (Ethernet) usage: - If not heavy write/delete work is to be done, use the -L option. Mounting and unmounting is much faster and the RK does not get blocked; so you can play with it as usual, as if it were not mounted. - Most players have buffering options. Use large buffers to prevent broken playing of tunes: ogg -b 512, mpg123 -b 512, mp3blaster -t 100, etc. - Modern kernels (>=2.6.13) and fuse drivers (>=2.5.0) use, by default, large I/O buffers (131072 bytes) for lkarmafs *read* calls (default write buffers are 4096 bytes, though). But, if lkarmafs is mounted with the `direct_io' fuse option, default I/O buffers are small both for read and write calls (4096 bytes). This can be overridden using, e.g., `dd bs=131072 if= of='. - The overall responsiveness of lkarmafs improves noticeably when it is kept moderately (and steadily) busy; e.g., playing some tunes. This seems to somehow speed up all the usual filesystem operations, including read, write and `ls'. - To circunvent the first "Known Bug" (below), copy a small "dummy" file to mntPoint/taxi/.dummy and mount lkarmafs as in the mountLkfs script: `DUMMY=mntPoint/taxi/.dummy while pgrep lkarmafs ; do sleep 60 ; cat $DUMMY >/dev/null ; done & lkarmafs ... mntPoint' ---------------------------------------------------------------------------- 7. Known bugs and future developments - lk_karma_write_dupes() sometimes allows writing files with identical rids (seems a libkarma issue) * Bugs using the USB/OMFS interface: - WARNING! OMFS unlink() was broken in omfs-0.6.0 and earlier versions. Use omfs-0.6.1 or later to avoid the danger of possible massive corruption of the RK disk. * Bugs using the TCPIP (Ethernet) interface and workarounds: - libkarma crashes if, after mounted, it remains unused for a while. Needs a libkarma fix. Workaround: keep lkarmafs busy ;) See "Tips" above and the mountLkfs script. - kfs_unlink() fails if it (the shell `rm') are used just after write or chmod. It might be a libkarma bug. Workaround: write/chmod -> umount -> mount -> rm - Occasional unexpected flush if direct_io and multiple + concurrent reads. Might be a fuse bug. Workaround: avoid concurrent reads and direct_io. * Additional future developments planned: - Provide a means to change -C and -E option values through mount-point/options - create playlists by copying (in -Y mode) files to mnt/playlists/... - create (write) and show (read) playlists in .m3u format - Suffix-number different tune files having identical pathnames - Add permission control for tunes (using bpm as for taxi files) - Implement subdirectories under taxi/ - Save smalldb from time to time or after each write/delete change. - Detect calls for unexisting directories and signal the error - Implement option similar to riocp "-u" to define the directory structure - Enable kfs_removxattr() (needs a new libkarma function) - Revise all the returned errors - Clear all the (debug) messages to sdtout/stderr, unless debug is enabled ----------------------------------------------------------------------------