Running BitTorrent Sync on your (rooted) Android device
BitTorrent, Inc came out with the beta of Sync - a peer to peer file sync tool this week. It came at the right time for me as I was looking for something to sync files across multiple machines, both across LAN and the internet, while using my own infrastructure.
The only issue I have with it is that there is no Android client yet. And I really want one - I use my Android tablet to write notes/annotate lecture slides and I want to ensure these are available on both my PCs and on my server.
Thankfully, while we wait for Sync to come to Android, there is a way to run Sync on your Android device right now, thanks to the fact that the BitTorrent folks have been awesome and released binaries for Linux on multiple architectures (including ARM, which is what 99% of the Android install base is running).
The way this is acheived is to use a chroot to run the Sync Linux binary. We do this by:
- Creating a minimal chroot environment, with only the libraries needed to run Sync
- Bundling this up into a filesystem image so we can run it off /sdcard on our Android device
- Using a small script to start Sync, and make the contents of /sdcard available to it under chroot
You will need a rooted Android device with loop filesystem mounts and busybox available. Most CyanogenMod ROMs should satisfy these requirements, if not, go out and recompile the kernel for your device so it does (horray for Open Source!)
Creating a minimal chroot environment
The first step is to create a small chroot environment with only the libraries needed to run Sync. Thankfully, Sync doesn't have many external dependencies:
$ ldd btsync librt.so.1 => /lib/librt.so.1 (0xf67c3000) libdl.so.2 => /lib/libdl.so.2 (0xf67b8000) libm.so.6 => /lib/libm.so.6 (0xf6748000) libpthread.so.0 => /lib/libpthread.so.0 (0xf6729000) libc.so.6 => /lib/libc.so.6 (0xf65f7000) /lib/ld-linux.so.3 (0xf67d7000)
To obtain the libraries we need, we'll start with a Gentoo Stage 3 tarball. I'm using a Tegra 2 device (Acer Iconia 501), so an ARM v7a stage3 is what we are after. If you have an older device, you may need a v6j archive.
Extract the stage3 to a temporary directory (the stage3 is designed to extract to /, so make sure you extract it into a new directory).
Create a new directory tree to house the chroot. Copy the following over from the stage3 lib/:
lib/libnss_compat-2.15.so lib/librt.so.1 lib/libresolv-2.15.so lib/libnss_hesiod-2.15.so lib/libdl.so.2 lib/libnss_hesiod.so.2 lib/libnss_compat.so.2 lib/libm.so.6 lib/libnss_nis-2.15.so lib/ld-linux.so.3 (rename from ld-linux-armhf.so.3 in the v7a stage3) lib/libnss_files.so.2 lib/libc.so.6 lib/libnss_nis.so.2 lib/libpthread.so.0 lib/libnss_dns-2.15.so lib/libnss_nisplus.so.2 lib/libnss_nisplus-2.15.so lib/libnss_db.so.2 lib/libnss_dns.so.2 lib/libnss_files-2.15.so lib/libnss_db-2.15.so
Now create the rest of the folders you'll typically see in a Linux system (plus a folder to bind the Android sdcard to):
mkdir btsync bin dev etc proc root sdcard sys tmp usr var
I'd suggest copying busybox over from the stage3 bin/ into chroot bin/, and making symlinks to some useful utilities (du, ps, sh) to it. These will come in handy if you need to debug inside the chroot
In /etc, it would be a good idea to create resolv.conf and hosts (but Sync doesn't seem to need them)
Next, download the binary for Sync (remember to download the ARM binary, unless you are one of the lucky people on an x86 device) and place it into btsync/
Handy tip: Being able to use QEMU chroots is very handy here; you can test the ARM chroot on your x86/x64 Linux machine.Build a filesystem image
Now, we need to build a filesystem image. The reason why we do this is that most devices have /sdcard formatted as FAT32 (or similar), and there are no execute permissions on these filesystems, nor are there symlinks and other things. So we use an ext2/3 filesystem image which does have all these features.
Create a 50MB image (trust me, this is far more than you should need:
dd if=/dev/zero of=btsync-img.img bs=1M count=50
Now format it:
(You will probably be warned that the image file is not a block device. Ignore the warning)
Now create a mount point and mount the image:
mkdir btsync-img mount -o loop btsync-img.img btsync-img
Copy all the files from the chroot into the image directory:
cd btsync-img cp -r ../btsync-chroot/* .
Now we are done, unmount the image:
umount btsync-imgCreate a script to start Sync from Android:
Next step is to create a small script that runs on the device that mounts the image and runs btsync. Here is the one I wrote:
#!/bin/sh cd /sdcard busybox mount -o loop btsync-img.img btsync-root busybox mount --bind /dev btsync-root/dev busybox mount --bind /sys btsync-root/sys busybox mount --bind /proc btsync-root/proc busybox mount --bind /sdcard btsync-root/sdcard chroot btsync-root /btsync/btsync
Transfer both btsync-img.img and the script (I called mine runbtsync.sh) over to /sdcard on your Android device. You can run
to start Sync. As with sync on normal Linux, you will need to go to http://<your_device_ip>:8888/ in a browser to get started (or just http://localhost:8888 if you are using the browser on the same device)
(Don't forget to get root (run "su") if you are running it from a terminal on your device)
And here's an image I prepared earlier:
btsync-img.img.bz2 for ARM v7 (i.e Tegra 2 and above)
p.s I also wrote an SELinux policy for running BitTorrent Sync under SELinux environments