Filesystem Snapshots on Android

Friday, May 8, 2009

A recent trick floating around the xda-developers forums involves using UnionFS to layer the microSD storage on top of the existing data partition, effectively allowing the microSD storage to be used for data. This technique originated from MarcusMaximus04 and has made its way into the firmware builds of TheDudeOfLife and JesusFreke.

While most users were playing around with the easy “apps2SD” feature, I decided to explore a different aspect of UnionFS — stackable snapshots. The goal was to be able to make snapshots of the filesystem that could be rolled back at any time, undoing any changes. While this may sound like server-oriented technology, it could be useful on a mobile platform that is collecting a sizable hacker community.

Here’s how I did it. I started with TheDudeOfLife’s latest build, which includes the new apps2SD trick from MarcusMaximus04. My microSD card has three partitions — the first is the usual FAT32 volume for documents, the second is an EXT2 volume for apps2SD, and the third is an additional EXT2 volume that I’m using to store my snapshots. If you follow the commands, you would see that I effectively bypass apps2SD for this experiment; but it is possible to use this method with apps2SD. Warning: the blogging software pretty-prints the quotation marks; be sure to make them regular double-quotes before copy+pasting.

1. Prepare a Mount Point

To mount the second EXT2 partition, we’ll need yet another mount point. Using ADB, remount the system partition in read-write mode:

adb remount

Next, get a shell session on the phone (through the terminal app or ADB) and type:

mkdir /system/sd2

2. Prepare the Snapshot Directories

We’ll be making three snapshots in this experiment, so let’s mount the second EXT2 partition and create some directories:

mount -t ext2 /dev/block/mmcblk0p3 /system/sd2
mkdir /system/sd2/snapshot0 /system/sd2/snapshot1 /system/sd2/snapshot2

3. Create a Snapshot

To create a snapshot, we overlay one of the snapshot directories over the existing data mount. But first, we must undo the original apps2SD overlay or this would not work:

mount -t yaffs2 -o rw,nosuid,nodev /dev/block/mtdblock5 /data
mount -t unionfs -o dirs=”/system/sd2/snapshot0=rw:/data=ro” none /data

As a test, let’s create a file:

touch /data/test0

4. Repeat

Now let’s create another snapshot and a new file:

mount -t yaffs2 -o rw,nosuid,nodev /dev/block/mtdblock5 /data
mount -t unionfs -o dirs=”/system/sd2/snapshot1=rw:/system/sd2/snapshot0=ro:/data=ro” none /data
touch /data/test1

5. Repeat

… and again:

mount -t yaffs2 -o rw,nosuid,nodev /dev/block/mtdblock5 /data
mount -t unionfs -o dirs=”/system/sd2/snapshot2=rw:/system/sd2/snapshot1=ro:/system/sd2/snapshot0=ro:/data=ro” none /data
touch /data/test2

6. Did it Work?

Let’s see. We have created three files, and we could check by listing them:

ls /data/test*

/data/test0
/data/test1
/data/test2

We could delete a file that we created in an earlier snapshot:

rm /data/test0
ls /data/test*

/data/test1
/data/test2

But when we switch to an earlier snapshot… not only was the most recently created file gone, but the deleted file came back:

mount -t yaffs2 -o rw,nosuid,nodev /dev/block/mtdblock5 /data
mount -t unionfs -o dirs=”/system/sd2/snapshot1=rw:/system/sd2/snapshot0=ro:/data=ro” none /data
ls /data/test*

/data/test0
/data/test1

As you can see, the last file we created just vanished. Now let’s roll back to the first snapshot:

mount -t yaffs2 -o rw,nosuid,nodev /dev/block/mtdblock5 /data
mount -t unionfs -o dirs=”/system/sd2/snapshot0=rw:/data=ro” none /data
ls /data/test*

/data/test0

There is just one test file now. And finally, let’s see what happens when we restore to the original mount:

mount -t yaffs2 -o rw,nosuid,nodev /dev/block/mtdblock5 /data
ls /data/test*

… the test files are all gone. But where have they gone? Why, they’re all on the snapshot partition, of course:

ls /system/sd2/snapshot*/

test0
test1
test2

7. Getting apps2SD Back

If you’re missing your apps2SD by now, you could do the following to get it back:

mount -t unionfs -o dirs=/system/sd:/data none /data

Or you could just reboot.

So…

Snapshots do work, though the procedure is a bit cumbersome. However, it should be trivial to write up a shell script to automate most of this. There are a couple of things that remain to be tested, however:

  1. Performance: UnionFS is supposed to be very efficient, but I have not done any actual performance testing.
  2. Efficiency: We created many overlay mounts back there while experimenting; I need to do some more reading to determine any impact this may have on efficiency.

6 Comments

  1. anwar says:

    Hi

    very nice I am working on the same thing I will try it. My supervisor asked my to take a snapshot of the file system so that we can later restore to that point if some goes wrong….
    What partition is exactly the file system….?

    One thing more is it possible to take a snapshot of the runing file system including all the runing process and save it and later reply it again?

    Best regards.

  2. Jiang Yio says:

    AuFS seems to be all the rage these days, and it’s cyanogen preferred Apps2SD technique. Running processes are not filesystem features so what you ask is not possible. It seems that you want to implement a hibernation feature, and I suppose you’d look around in the kernel for it. You’d have to pause everything while you snapshot the CPU and RAM, though.

  3. anwar says:

    hi

    can I do this process with emulator if yes how? I am trying to it but am not able to do so. The first two command aren’t working with the phone however I am supposed to do it with the emulator that we will run on the server. Please guide my on the process on emulator…

    I am trying very hard but still stuck in the following command

    mount -t ext2 /dev/block/mmcblk0p3 /system/sd2

    First of all I don’t have mmcblk0p3 instead I have only mmcblk0p and mmcblk0p1. I have changed them but still it give me the following error…
    mount: Device or resource busy

    Please if you have time I need your help.

    Best regards

  4. Jiang Yio says:

    You need an EXT2/3/4 partition on your SD card. This partition is where all the snapshots go. This experiment was basically built on top of the Apps2SD mechanism.

    Furthermore, you need an Android build that supports UnionFS or AuFS. I’d suggest using AuFS since it’s supposedly better, but you’d have to modify the procedure somewhat.

Pingbacks & Trackbacks

  1. in /system/ schreiben ohne Root-Rechte mittels squashfs/unionfs - Android-Hilfe.de - Pingback on 2010/06/04
  2. Is it possible to expand your internal memory storage using UnionFS? - Pingback on 2010/08/27