Download the Maemo .deb package here: mmc-unionfs.deb . (This package contains mmc-unionfs Version 0.3.3-1 with the unionfs-1.1.4 module, compiled for Kernel 2.6.12.3-omap1.)
Current state: to make long things short: first, there were some nasty bugs (which could be solved, but needed some patience), then I was very short of time for quite some time and now - my 770 didn't survive the usage patterns some furry animal applied to it. Although the Nokia 770 is a mouseless device, it caught that cat's attention. When that crazy cat was through with it, it's was not only mouseless, but also pretty useless. The cat's owner's liability insurance insists on paying nothing. And for the cat: That animal looked proud, goggle-eyed, and innocent after doing it's destructive work, and I can't help: I still like cats, even those who turn out as device destroying monsters.
I'll probably buy a 770 or an 800 next time, but for now, I'm focusing on other private projects until I decide it's time to buy a new one. Sorry, Folks. (And sorry for not updating this page - it took really long to get a clear decision from the insurance company.)
The bottom line for now is: Consider this project as hibernating for some undetermined time. I can't tell you right now when i'll resume working at it - I'll inform you here..
The command mmc-unionfs boot-disable caused an error message (but worked anyway).
Usage output (examples section on boot-enable and boot-disable) was outdated.
Kernel module and unionfs utilities updated to newest unionfs release (Version 1.1.4). Permissions to module and doc directory were too strict. Some minor user interface polishing.
Since there were no failure reports (except for one which looked serious but wasn't), mmc-unionfs has now moved into Maemo's application catalog (2006-05-24).
Nasty typo removed which caused trouble only in an unreleased version. Several smaller changes.
First public release.
unionfs merges several directories and directory trees into one.
You may look at it as looking from above into a stack of transparent layers, each representing a directory tree in a different place. Equally named files among the different layers stack in the same column, the topmost of them thus hiding those with the same name in lower layers.
In unionfs terminology, the whole stack is called a union, with the layers which make up the stack being called branches. You can add and remove branches on the fly, and give them read and write attributes. There's more about it - have a look at the project's homepage for details.
unionfs has reached a level of maturity good enough that it is included in various distributions. You can check a not-so-small list of projects using it at the above homepage address.
The Nokia770 implementation seems to do equally well. There's still some risk (as with any system software), that everything might happen, including bricking your Nokia770 or turning it into a flying saucer1, though I wouldn't exactly expect that. Anyway ... you've been warned.
For now, let's focus on our trusted Nokia770 and the (less trusted) set of utilities I've done that make up mmc-unionfs. They are meant to be simple enough to be used without much knowledge while not preventing you from any additional tweaks you might want to apply.
In our 770's hardware, we have two kinds of flash memory: the fixed one on the 770's mainboard and the one you're adding by inserting an MMC flash card.
Now if we stack MMC memory on top of, say. the /var/lib/install or even the entire /usr tree (having mounted the MMC branch read/write and the internal flash branch read-only), their capacity increases by that of the MMC and we can do whatever we want within those trees without actually having to touch anything in the built in flash at all.
Even deleting a file which resides in internal flash memory works this way: if you try to delete a file on a layer which lacks the 'writable' attribute, an entry is made into the topmost writable layer above it in a way which in every respect looks from above (the unified view) like an empty space, but isn't. If you remove the upper layer (the branch which carries the 'whiteout' in unionfs speak), the original file will reappear. Re-insert your upper branch and it will be gone again.
Modifying files on a read-only branch works as you'd expect: the data is read from the read-only branch but on the first write, the data is copied up and the modification is done to the read-write branch, thus shadowing from now on the read-only version. All subsequent accesses will be from and to the read-write branch. This is known as 'copyup'.
The default structure built up by mmc-unionfs does just that: It mounts the MMC read-write on top of freely selectable subtrees of the root fs on the internal flash, which are left read-only. You aren't constrained to stay with this setup, however.
I think you've got the basic idea. You can use your MMC space as if it were part of the internal memory without having to do nasty things like scattering symbolic links pointing to places on the MMC all over your root file system.
You can have several MMCs with several Nokia 'personalities', like one crammed full of utilities and E-Books for working, and one which leaves more space for your music, games, photos and other entertainment. Shut down, put in another MMC, switch on, and your Nokia770 might look very different from a user's perspective.
You may modify whatever parts of the root fs you like (but keep in mind that running programs may have a very distinct feeling about this topic if you change their files by starting a union while they're running - see below for a short discussion).
If you're checking a new program and the Nokia refuses to work with the modified set for whatever reason, simply switch it off, remove the MMC so you're back at your basic setup, and switch it on again. Re-insert the MMC, modify the erroneous file on the MMC , remount the branch on the fly with the mmc-unionfs utility, and you're ready to test the new setup again.
To run it, you have to prepare your MMC, install the mmc-union<whatever-version>.deb package and run (as root) the setup utility. But first take a glance at the CAVEATS section below.
Then let's start with -
You have to partition your MMC so it has at least 2 partitions. mmc-unionfs should use an ext2 partition (it could be done on VFAT, but that wouldn't be very useful due to its restrictions). The first partition (/dev/mmcblk0p1) cannot be used for mmc-unionfs as it is ignored (VFAT, and reserved for the 770's standard software).
So insert your MMC into a linux box to prepare it. For an example, I'm usually using three partitions as follows:
Use a program like fdisk on GNU/Linux to do the partitioning (don't forget to set the type code for the VFAT partition (6) - on the others (83 for swap and 82 for ext2) it won't hurt much if you forget it).
Then use mkfs.vfat for putting a file system onto the VFAT partition, mkswap to prepare the swap partition (if any), and mkfs.ext2 for initializing the ext2 file system.
All of the following steps may also be done on the Nokia 770 (the above of course too if you have the necessary software installed).
Now mount the ext2 partition. (If you have more than one of them, they will later be tried by mmc-unionfs in ascending order, starting at partition 2, until a successful mmc-unionfs mount can be made.) Put a directory named mmc-union it.
cd into it to define your branches there.
That's actually quite simple. Say we want to install two unions. The first one should extend /home/user, and the second one /var/lib/install. Then all you have to do is to create two empty directories within mmc-union with the names #home#user and #var#lib#install. They will later be filled with new content during normal use. I'm sure you've got the point in naming the directories: use the absolute path name of the tree you want to extend, then simply replace all slashes ('/') by hash marks ('#'). But take care of their rights: (#home#user should be owned by user:users (29999:29999) (chown 100:29999 will do the job), /var/lib/install belongs to install:users (100:29999)).
mkdir \#home#user \#var#lib#install
mkdir '#home#user' '#var#lib#install'
mkdir "#home#user" "#var#lib#install"
As a side note: the busybox sh (the Nokia's built-in shell) won't get TAB expansion right if you hit TAB immediately after a hash character which is preceded by a backslash.
If one of your original directories contains a hash mark, insert a literal backslash into the directory name just before the hash mark in question. You get it there by typing two backslash characters at the mkdir shell command line or by quoting as above.
Take some care about the unions you're creating. It won't do any good if you mount new branches on top of directories which carry crucial up-to-date information for processes already running. Let's take /var/run for an example. Many processes put some identification data like their PID there when they're running and remove it when done. Mounting the MMC over them will seem to work well at first - but while reading old data from internal flash, new and modified data will now be written onto the MMC. Next time the MMC branch gets inserted (either during booting or manually), the old data (including whiteouts) from the MMC will be there again, possibly masking new content, and thus indicating running conditions that don't exist any more.
As a rule of thumb: don't include anything below /var but above /var/lib/install. Be careful about /etc, and about including any other standard directory in / - and never ever include /lib except you definitely know what you're doing. Don't care about /var/lib/install and user's home directories - they should always work. /tmp is safe only when the union gets automatically mounted during boot. And finally, if things go wrong, shut down, remove the MMC and you are where you've been before.
Now we're done with the MMC. Partitioning and
putting a few directories onto it - that's all. Let's
move on to the
You must be able to gain root access later. (Have a look at the Maemo Wiki's HOWTO if you don't know about this. But keep in mind that mmc-unionfs is work in progress - and if you don't know how to get root access, it's probably better to wait for a while until things have settled more.)
First, install (as usual) the .deb package from the link on top of this page. This won't change much, it will just install some files into /var/lib/install/usr/share/mmc-unionfs, including a setup script.
Start a shell now, either from remote (ssh) or by running osso-xterm. Gain root access (by whatever means you've implemented: login, sudo sh, su, gainroot). Make sure the MMC we've prepared above is in place (it need not be mounted). Now cd to
/var/lib/install/usr/share/mmc-unionfs/setup
and run
./setup
This puts the files into your root file system, then does some cleanup.
If all seems well, type
mmc-unionfs setup
mmc-unionfs mount
If you get a 'command not found' message, you should either type in the full path (/sbin/mmc-unionfs) or make sure /sbin is in your $PATH by editing .profile in your home directory.
To see the result, run
df -h
and check for lines starting in 'union+'. You should now see the unions you've defined showing up with plenty of room in them. Play around, test.
When you're sure you want to have your unions always installed during the boot process, type:
mmc-unionfs boot-enable
That's it - you're done.
By the way, you should have a look at the following commands:
mmc-unionfs --help
mmc-unionfs status
and also at the more general unionfs utility commads, especially if you're looking for a way to do a more complex setup, delete and add branches on the fly, and so on:
unionctl --help
uniondbg --help
If you later decide to change what directory trees are included in your unions, just
(As a side note, the mmc-unionfs_init init script provides "stop" functionality to be used during system shutdown, and places a link into rc0.d, but this never gets called. I didn't investigate the reason until now as that most probably won't cause any ill effects at all.)
Always switch off your Nokia770 before removing or changing the MMC.
Dont' forget to run mmc-unionfs unload before installing an update. If there are programs using one of your unions, you might prefer rebooting without your MMC and re-inserting it after that. Plus, as a safety measure, run mmc-unionfs boot-disable and don't boot-enable it again before you've made sure all works as expected.
If you want to get rid of mmc-unionfs, the built-in app-installer won't suffice. Currently, there is no way of letting him know that he's not allowed to remove the files without having switched off running unions beforehand, so all mandatory files are moved out of its reach during setup. To safely remove all files, cd to /var/lib/install/usr/share/mmc-unionfs and run ./setup uninstall before uninstalling with the 770's built-in installer (which otherwise would remove the setup program).
If an application (like the shell) has its working directory in a place which later becomes part of a union, its working directory won't change magically but will be left where it was before. This means it still reads from and writes to the original directory (except when it uses full path names), though its actions are also visible in the union which this directory is part of. For a shell, simply run 'cd .' to avoid this.
In its default setup, mmc-unionfs arranges its branches so that it mounts the old directory tree read-only and the MMC data read/write. The result is then mounted in the same place as the old directory, thus extending it in a totally transparent way. This doesn't result in a recursive mount, though it might look like, since the union's member is still the old directory as it was before, not the resulting union (which carries the same name).
This also means you're using the original files as long as you don't do any change to them, like writing or deleting. If you do so, the orginal file or directory will stay untouched (even if you delete it) and all new data will be copied up and written to/read from the mmc.
You should not write to one of the branches directly while the union is mounted (i.e., don't write into the directories within your mmc-union directory on the mmc). This is due to buffering issues: The part you're writing to may already have been cached for the united view, which, from the kernel's perspective, is a totally different location.
/var/lib/install/var as part of a union might cause problems, but only if all of the following conditions are met:
Since you probably won't do much to the unions after you have set up and tested them, and there won't be problems during the boot process (as /var/lib/install applications aren't active then), /var/lib/install as a union can be considered safe for almost any real scenario.
If you're changing your kernel, you have to recompile unionfs (or wait until someone does it for you) to make mmc-unionfs work again. You won't loose any data, but you can't access them the usual way (through a union) until then.
Anybody can replace any file they like this way, including the system files. After all, that's what it is meant for. If you hand out your Nokia and don't want them to gain root access by inserting some prepared MMC, boot-disable mmc-unionfs and password-protect the sudo mmc-unionfs command in your /etc/sudores file. There may be more fine-grained security measures at some later time if needed.
For the time being, /bin/sh in the Nokia770 must not be bash (as of bash version 3.1.11). This is due to a bug in bash which doesn't allow to embed a case command within a $(..) command substitution. The bug has been reported. As mmc-unionfs explicitly requests /bin/sh, this shouldn't cause problems.
You can reach me by email at <mailto:hcz@hczim.de> . When reporting problems, make sure you include the package and busybox versions, what exactly needs to be done to reproduce the problem and what is printed out and/or what happens.
Make sure you're using the -v 3 (verbose) option to mmc-unionfs before you mail its output.
| /dev/mmcblk0p[1-9] | Partitions searched for (lowest number first) |
| /media/mmc[1-9] | Mount points. Created if needed. |
| $mmc/mmc-union | directory name (must be in the partition's top level) |
| /sbin/mmc-unionfs | unionfs management script |
| /usr/sbin/unionctl | unionfs utility |
| /usr/sbin/uniondbg | unionfs utility |
| /usr/sbin/unionimap | unionfs utility |
| /etc/init.d/mmc-unionfs_init | system init script |
| /etc/rcS.d/S00mmc-union | Startup link |
| /etc/rc0.d/K37mmc-union | Shutdown link |
| /etc/init.d/rcS | Startup link (appended to and removed from file as needed) |
| /lib/modules/$(uname-r)/unionfs.ko | unionfs module location |
You need:
To build:
This software consists of parts copyrighted by Stony Brook University (the huge part) and parts written and copyrighted by me (Heike C. Zimmerer <hcz@hczim.de>).
The software parts provided by me are licensed under the terms of the GNU General Public License (GPL), Version 2 (1991). See the file COPYING in the distributed package (use gunzip to uncompress it), which is also found at /var/lib/install/usr/share/doc/mmc-unionfs after installing but before running setup (reinstall to see it). If not, write the author or, if all fails, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
This software includes as its main and essential part a compiled version of unionfs and its utilities. Their sources were taken from a project at Stony Brook University (http://www.sunysb.edu), which is also licensed under the terms of the GNU General Public License (GPL). Make sure you've consulted the unionfs source code at ftp://ftp.fsl.cs.sunysb.edu/pub/unionfs and the project web page http://www.fsl.cs.sunysb.edu/project-unionfs.html for details. Many thanks to the folks there for creating such an amazing and useful piece of software.