Long time lurker, first time poster…
This community has given a lot to me, and I wanted to contribute something that I hadn’t seen really discussed here much. My apologies in advance if this topic has been covered, answered, and addressed previously – I have not been able to find much on it in these forums and thought I would share my experiences.
I’ve been trying to get CrashPlan to work on my Drobo with watching the file system in real-time. There’s a lot that’s been written about it and it hasn’t historically worked on ARM-based Linux solutions like Drobo. For the past two weeks, I’ve been experimenting with getting it to work and it appears that watching the file system in real-time now works for CrashPlan, once you’ve tweaked a setting on your Drobo.
For those that care read on for the technical details – for those that don’t, skip to the end of this post for how to get things working. CrashPlan leverages Linux’s inotify API to monitor filesystem events. The way this API is used by CrashPlan is to register a notification of any filesystem event with each and every file and directory that you have selected for backup. That way, when anything happens (e.g. renaming a file, deleting a directory, etc.) CrashPlan is notified and it queues its own backup operations.
There have been two challenges historically with CrashPlan and inotify, from my reading. The first is that it seemed to just be plain broken for ARM-based systems. Somewhere in the recent past it seems CrashPlan has corrected this with their client and it WORKS correctly now. The second is that the sheer number of filesystem notifications (particularly for large sets of files and directories) can easily overwhelm the default Linux per-process limit for inotify notifications of 8192.
To correct the second issue, SSH into your Drobo and execute this command:
echo 1048576 > /proc/sys/fs/inotify/max_user_watches
This will increase the number of notifications that any single application can register to the maximum allowable. That should be all that is needed. To test this for yourself, execute the above command and then bring up the CrashPlan UI and ensure that ‘watch file system in real-time’ is UNCHECKED and save your settings. Then go back and check the option and re-save your settings. That should get CrashPlan to start watching your filesystem.
I’ve been running this without issues for two weeks.
Ricardo - if you are reading this…I modified the service.sh script for CrashPlan to increase the inotify limit automatically. I offer it for inclusion in the next update to the CrashPlan package if you would be interested in including it. For those that want to replace their CrashPlan service.sh with the one below, it should automate the task for you.
#!/bin/sh
#
# CrashPlan service
. /etc/service.subr
prog_dir=`dirname \`realpath $0\``
name="crashplan"
version="3.5.2"
depends="locale java7"
locale="/mnt/DroboFS/Shares/DroboApps/locale/bin/locale"
localedef="/mnt/DroboFS/Shares/DroboApps/locale/bin/localedef"
java="/mnt/DroboFS/Shares/DroboApps/java7/bin/java"
logfile="${prog_dir}/app/log/droboapp.log"
enginelog="${prog_dir}/app/log/engine_output.log"
errorlog="${prog_dir}/app/log/engine_error.log"
pidfile="${prog_dir}/var/run/crashplan.pid"
classpath="${prog_dir}/app/lib/com.backup42.desktop.jar:${prog_dir}/app/lang"
mainclass="com.backup42.service.CPService"
set_watch_files() {
echo 1048576 > /proc/sys/fs/inotify/max_user_watches
}
create_locale() {
local retcode
if [ ! -x "${locale}" -o ! -x "${localedef}" ]; then
echo "Locale support missing. Please install the locale DroboApp." >> "${logfile}"
exit 2
fi
"${locale}" -a | grep -q "^en_US.utf8" 1> /dev/null 2>&1
if [ $? -eq 0 ]; then return 0; fi
"${localedef}" -f UTF-8 -i en_US en_US.UTF-8 1>> "${logfile}" 2>&1
retcode=$?
if [ ${retcode} -ne 0 ]; then
echo "Local creation failed with error code ${retcode}" 1>> "${logfile}" 2>&1
exit ${retcode}
fi
}
start() {
local pid
set_watch_files
create_locale
# source for SRV_JAVA_OPTS
. "${prog_dir}/app/bin/run.conf"
SRV_JAVA_OPTS="${SRV_JAVA_OPTS} -Djava.io.tmpdir=${prog_dir}/tmp"
export LC_ALL="en_US.UTF-8"
export LANG="en_US.UTF-8"
export LD_LIBRARY_PATH="${prog_dir}/lib:${prog_dir}/app:$LD_LIBRARY_PATH"
cd ${prog_dir}/app
setsid ${java} ${SRV_JAVA_OPTS} -classpath "${classpath}" "${mainclass}" 1>> "${enginelog}" 2>> "${errorlog}" &
if [ $! -gt 0 ]; then
pid=$!
echo $pid > ${pidfile}
renice 19 ${pid} 1>> "${logfile}" 2>&1
fi
}
case "$1" in
start) start_service ;;
stop) stop_service ;;
restart) stop_service ; sleep 10 ; start_service ;;
status) status ;;
*) echo "Usage: $0 [start|stop|restart|status]" ; exit 1 ;;
esac