#!/bin/bash # Work around OpenSims slow database corruption bug by using git to store all old backups. # Try to squeeze every last byte out of the tarballs. Seems to cut the total storage size down to one third the size of just the raw I/OAR files. # Saves even more if there's been no changes. # On the other hand, these backup files will grow indefinitely, the more changes, the faster it grows. I can live with that for more reliable backups that go back further. # Tries to avoid losing data if things go wrong. I think the main remaining problem would be running out of space, in which case you have bigger problems to deal with. # Strategy - unpack the last one, unpack and commit any old I/OARs, pack up the result, delete it's working directory, THEN run the save i/oar. # Avoids having to sync with OpenSim finishing the current I/OAR, and as a bonus, an easy to deliver latest I/OAR for people that want it. # Not really meant to be called by users, so don't bother validating the input and such. source common.sh getPrgDir type=$1 title=$2 date=$(date '+%F_%T') # Convert the type to uppercase. gar="_git$(echo -n ${type} | tr '[:lower:]' '[:upper:]')AR" name=$(sanitize "${title}") if [ -d ${PRGDIR}/../../backups/temp_backup${type}_${name} ]; then echo "WARNING - Mess left over from last backup, not gonna run!" mv ${PRGDIR}/../../backups/temp_backup${type}_${name}/*.oar ${PRGDIR}/../backups exit 1 fi mkdir -p ${PRGDIR}/../../backups/temp_backup${type}_${name} pushd ${PRGDIR}/../../backups/temp_backup${type}_${name} >/dev/null if [ -f ../${name}${gar}.tar.xz ]; then ionice -c3 nice -n 19 tar -xf ../${name}${gar}.tar.xz else mkdir -p ${name}${gar} git init ${name}${gar} >log fi pushd ${name}${gar} >/dev/null # Make sure stuff that's already compressed doesn't get compressed by git. # Also tries to protect binaries from mangling. cat >.gitattributes <<- zzzzEOFzzzz *.bvh -delta -diff -text *.jp2 -delta -diff -text *.jpg -delta -diff -text *.llmesh -delta -diff -text *.ogg -delta -diff -text *.png -delta -diff -text *.r32 -delta -diff -text *.tga -delta -diff -text zzzzEOFzzzz # Coz git insists. git config user.email "opensim@$(hostname -A | cut -d ' ' -f 1)" git config user.name "opensim" # Git is such a pedantic bitch, let's just fucking ignore any errors it gives due to lack of anything to do. # Even worse the OpenSim devs breaking logout tracking gives git plenty of nothing to do. lol # Looping through them in case there's a bunch of I/OARs from previous versions of this script. # Ignore files of zero size that OpenSim might create. find ../.. -maxdepth 1 -type f -name "${name}-*.${type}ar" -size '+0c' | sort | while read file; do # Deal with deletions in the inventory / sim, easy method, which becomes a nop for files that stay in the git add below. git rm -fr * &>>../log #|| echo "ERROR - Could not clean git for ${file} !" >>../errors if [ ! -f ../errors ]; then ionice -c3 nice -n 19 tar -xzf "${file}" || echo "ERROR - Could not unpack ${file} !" >>../errors fi if [ ! -f ../errors ]; then git add * &>>../log git add */\* &>>../log #|| echo "ERROR - Could not add ${file} to git!" >>../errors git add .gitattributes &>>../log # Magic needed to figure out if there's anything to commit. # After all the pain to get this to work, there's an ever changing timestamp in archive.xml that screws it up. # Like this system didn't have enough timestamps in it already. lol # TODO - I could sed out that timestamp, and put it back again based on the OAR file name when extracting. # IARs don't seem to have the timestamp. if t=$(git status --porcelain) && [ -z "${t}" ]; then true else # Note this commit message has to be just the file name, as the ungitAR script uses it. git commit -qm "$(basename ${file})" &>>../log || echo "ERROR - Could not commit ${file} !" >>../errors fi if [ ! -f ../errors ]; then mv ${file} .. fi fi if [ -f ../errors ]; then exit 1 # Seems to only exit from this loop, not the script. Makes me want to rewrite this in a real language. lol fi done #git gc --aggressive --prune=now # Takes a long time, doesn't gain much. Even worse, it increases the size of the resulting tarball. lol popd >/dev/null if [ ! -f errors ]; then XZ_OPT="-9e" ionice -c3 nice -n 19 tar -c --xz ${name}${gar} -f ../${name}${gar}.tar.xz || echo "ERROR - Could not pack gitAR!" >>errors fi popd >/dev/null if [ -f ${PRGDIR}/../../backups/temp_backup${type}_${name}/errors ]; then echo "NOT cleaning up coz - " cat ${PRGDIR}/../../backups/temp_backup${type}_${name}/errors else rm -fr ${PRGDIR}/../../backups/temp_backup${type}_${name} fi