Filesystem Snapshots on Android
by Jiang Yio on May.08, 2009, under Android
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:
- Performance: UnionFS is supposed to be very efficient, but I have not done any actual performance testing.
- 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.
November 21st, 2009 on 7:37 am
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.
November 21st, 2009 on 12:51 pm
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.
November 22nd, 2009 on 2:02 pm
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
November 22nd, 2009 on 8:55 pm
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.