Tuesday, November 22, 2011

This tutorial uses unsupported features of the IOMEGA Storcenter ix4-200d and Crashplan does not support a client for ARM processors. The steps I described worked for me but use at your own risk!
Tutorial tested on IOMEGA Storcenter ix4-200d firmware 3.1.14.995
It should be fairly easy to adapt it to the Iomega ix2 NAS and with a little bit more work, even other devices using the ARM processor Marvell Kirkwood 6281 CPU (aka Feroceon).

First of all, it was much more complex than I anticipated. Crashplan is running on java, I was hoping for a quick java install and go! Actually it is much more complex because nothing is supported by either Iomega or Crashplan, some libraries are missing from the NAS and the custom linux (EMC Lifeline OS) does not behave as expected (read only file system and strange daemon startup mechanism)... This tutorial assumes some basic linux and vi knowledge...

2. Create a share where we will install our stuff
Create a share called NAS_Extension using the web interface
EDIT: now that I understand better the way the OS is organized, It would have been better to install everthing in /opt/ (/opt/ejre1.7.0 and /opt/crasplan3.0.3) the partition /opt/ is on is 15GB, so no risk to run out of space (type df to see the mount points and free space)

3. Install java
Because of oracle licensing, you can't download the file directly. Go there:http://www.oracle.com/technetwork/java/embedded/downloads/javase/index.html
and download the ejre corresponding to "ARMv5 Linux - Headless" under "Java SE for Embedded 7"
The file should be called ejre-7-fcs-b147-linux-arm-sflt-headless-27_jun_2011.tar.gz
Store it into the NAS_Extension partition you just created using your regular way of accessing the NAS.

TODO: Everything should work with openJDK as well. I'll try to update the tutorial when I get a chance.

Please note that it takes quite some time for crashplan to be available after a reboot. Because of the 'nice' level, the process basically waits for all the other boot processes (mostly twonkymediaserv) to finish before being available and sarting to listen on the socket. This takes a good 12 minutes for me.

Let me know if you manage to get the tutorial working for other NAS devices and what you had to change to do that. I'll try to compile your remarks into another post.
If this tutorial saved you 10 hours of messing around with your NAS, you can offer me a beer (a coffe or a tea would do as well)!

7. Faq:Q1: The Crashplan engine starts but fails after a few seconds/minutes
Chances are you libjtux is not properly updated.... retry to download it.
You should see the following stack trace when you do

cat /mnt/pools/A/A0/NAS_Extension/crashplan/log/engine_error.log
java.lang.UnsatisfiedLinkError: /mnt/pools/A/A0/NAS_Extension/crashplan/libjtux.so: /mnt/pools/A/A0/NAS_Extension/crashplan/libjtux.so: cannot open shared object file: No such file or directory (Possible cause: can't load IA 32-bit .so on a ARM-bit platform)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1928)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
at java.lang.Runtime.loadLibrary0(Runtime.java:845)
at java.lang.System.loadLibrary(System.java:1084)
at jtux.UUtil.init(UUtil.java:14)
at jtux.UProcess.(UProcess.java:30)
at com.code42.os.posix.PosixProcessCommands.getuid(PosixProcessCommands.java:57)
at com.backup42.service.CPService.logIds(CPService.java:1164)
at com.backup42.service.CPService.start(CPService.java:396)
at com.backup42.service.CPService.main(CPService.java:1552)

Q2: The Crashplan engine seems fine but it is never backing up anything
You should see the following stack trace when you do (it takes some time (like 5-10 minutes) before you get the stack trace, just be patient):

cat /mnt/pools/A/A0/NAS_Extension/crashplan/log/engine_error.log
Exception in thread "W10189988_ScanWrkr" java.lang.NoClassDefFoundError: Could not initialize class com.code42.jna.inotify.InotifyManager
at com.code42.jna.inotify.JNAInotifyFileWatcherDriver.(JNAInotifyFileWatcherDriver.java:21)
at com.code42.backup.path.BackupSetsManager.initFileWatcherDriver(BackupSetsManager.java:376)
at com.code42.backup.path.BackupSetsManager.startScheduledFileQueue(BackupSetsManager.java:314)
at com.code42.backup.path.BackupSetsManager.access$1600(BackupSetsManager.java:64)
at com.code42.backup.path.BackupSetsManager$ScanWorker.delay(BackupSetsManager.java:1007)
at com.code42.utils.AWorker.run(AWorker.java:158)
at java.lang.Thread.run(Thread.java:722)

In this case, it is likely jna-3.2.5.jar is not working. Try to install it again.
The same error can be caused by the fact that you miss libffi.so.5 or it is not found by ld. To make sure your problem is linked to libffi, you can try:

if ld tells you it can not find libffi.so.5, that's your problem and you should try to re install libffi.so.5 (don't forget to change /etc/ld.so.conf).

EDIT 28/10/2012
I am having this problem now:

root@IOMEGA_NAS:/mnt/pools/A/A0/NAS_Extension/crashplan/log# tail -40 engine_error.log
java.lang.UnsatisfiedLinkError: /mnt/pools/A/A0/NAS_Extension/crashplan/libmd5.so: /mnt/pools/A/A0/NAS_Extension/crashplan/libmd5.so: cannot open shared object file: No such file or directory (Possible cause: can't load IA 32-bit .so on a ARM-bit platform)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1928)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
at java.lang.Runtime.loadLibrary0(Runtime.java:845)
at java.lang.System.loadLibrary(System.java:1084)
at com.twmacinta.util.MD5._loadNativeLibrary(MD5.java:727)
at com.twmacinta.util.MD5._initNativeLibrary(MD5.java:703)
at com.twmacinta.util.MD5.(MD5.java:124)
at com.code42.utils.OsPatternList.getChecksum(OsPatternList.java:142)
at com.code42.utils.PatternList.equals(PatternList.java:350)
at com.code42.config.ConfigItem.setValue(ConfigItem.java:66)
at com.code42.config.ConfigXmlTransformer.fromXmlConfigItem(ConfigXmlTransformer.java:445)
at com.code42.config.ConfigXmlTransformer.fromXmlAConfigItem(ConfigXmlTransformer.java:405)
at com.code42.config.ConfigXmlTransformer.fromXml(ConfigXmlTransformer.java:306)
at com.code42.config.ConfigXmlTransformer.fromXmlConfigComponent(ConfigXmlTransformer.java:487)
at com.code42.config.ConfigXmlTransformer.fromXml(ConfigXmlTransformer.java:308)
at com.code42.config.ConfigXmlTransformer.fromXml(ConfigXmlTransformer.java:74)
at com.code42.xml.XmlTool.fromXml(XmlTool.java:176)
at com.code42.xml.XmlTool.fromXml(XmlTool.java:155)
at com.code42.config.AConfig.fromXml(AConfig.java:77)
at com.backup42.common.config.AppConfig.load(AppConfig.java:106)
at com.backup42.common.config.ServiceConfig.load(ServiceConfig.java:326)
at com.backup42.service.CPService.loadConfig(CPService.java:675)
at com.backup42.service.CPService.start(CPService.java:331)
at com.backup42.service.CPService.main(CPService.java:1622)