#!/bin/bash # share fix # use this script to rebuild default configs for shares if the ._share becomes # broken for whatever reason. unset readynasd number x volume found iscsi shares invalid verbosity volumes found=0 shares=0 iscsi=0 migrated=0 mvcmd="mv" ################ ### commands ### ################ backupsnappershots() { echo "==== [Task] Backing up existing Snapper configs" tar -cf "/var/backups/backup_snapper_configs.$(date +%s).tar" /etc/snapper/configs 2>/dev/null if [[ $? ]]; then echo "===== [Info] Success at backing up snapper configs" echo "===== [Task] Removing Snapper Configs" rm /etc/snapper/configs/* 2>/dev/null else echo "===== [Fail] Couldn't backup configs. Please debug" fi } share_create() { found=$((found+1)) shares=$((shares+1)) path="/$volume/._share/$item" echo "=== [Info] Found share at /$volume/$item" echo "=== [Task] Recreating share configs." mkdir -p "$path" echo "share" > "$path"/datasettype.conf echo "0,25000" > "$path"/recycle.conf echo "#dashboard:available=0 \"/$volume/$item\" 127.0.0.1(insecure,insecure_locks,no_subtree_check,crossmnt,anonuid=99,anongid=99,root_squash,ro,async)" > "$path"/nfs.conf echo "" > "$path"/snapdir.conf echo "1 0 0 * * * 0" > "$path"/snapshot.conf cat > "$path"/afp.conf << EOF [$item] available = 1 path = /$volume/$item admin group = admin EOF cat > "$path"/custom_snapshot_management.conf << EOF enabled = no retention_rule = lifetime lifetime = 2592000 number = 30 nonempty_snapshots = yes prev_versions = no EOF cat > "$path"/custom_snapshot_schedule.conf << EOF ........................ ........................ ........................ ........................ ........................ ........................ ........................ EOF cat > "$path"/fs.conf << EOF compression = 0 bitrotprotection = 0 autodefrag = 0 refquota = 0 EOF cat > "$path"/ftp.conf << EOF available 0 default_access writeable mask fmask dmask user_rw group_rw host_rw user_ro group_ro host_ro EOF cat > "$path"/samba.conf << EOF [$item] path = /$volume/$item comment = "$item" spotlight = 0 guest ok = 1 force create mode = 0666 create mask = 0666 force directory mode = 1777 directory mask = 1777 admin users = +admin writeable = 1 follow symlinks = 1 EOF cat > /etc/snapper/configs/$((shares-1)) << EOF # subvolume to snapshot SUBVOLUME="/$volume/$item" # filesystem type FSTYPE="btrfs" # btrfs qgroup for space aware cleanup algorithms QGROUP="" # fraction of the filesystems space the snapshots may use SPACE_LIMIT="0.5" # users and groups allowed to work with config ALLOW_USERS="guest" ALLOW_GROUPS="admin" # sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots # directory SYNC_ACL="no" # start comparing pre- and post-snapshot in background after creating # post-snapshot BACKGROUND_COMPARISON="yes" # run daily number cleanup NUMBER_CLEANUP="yes" # limit for number cleanup NUMBER_MIN_AGE="1800" NUMBER_LIMIT="50" NUMBER_LIMIT_IMPORTANT="10" # create hourly snapshots TIMELINE_CREATE="yes" # cleanup hourly snapshots after some time TIMELINE_CLEANUP="yes" # limits for timeline cleanup TIMELINE_MIN_AGE="1800" TIMELINE_LIMIT_HOURLY="10" TIMELINE_LIMIT_DAILY="10" TIMELINE_LIMIT_WEEKLY="0" TIMELINE_LIMIT_MONTHLY="10" TIMELINE_LIMIT_YEARLY="10" # cleanup empty pre-post-pairs EMPTY_PRE_POST_CLEANUP="yes" # limits for empty pre-post-pair cleanup EMPTY_PRE_POST_MIN_AGE="1800" SNAPSHOT_HWM="13" EOF cd "$path" chown root.root datasettype.conf recycle.conf snapdir.conf snapshot.conf chown admin.admin afp.conf fs.conf ftp.conf nfs.conf samba.conf custom_snapshot_management.conf custom_snapshot_schedule.conf chmod 644 datasettype.conf recycle.conf snapdir.conf snapshot.conf afp.conf fs.conf ftp.conf nfs.conf samba.conf custom_snapshot_management.conf custom_snapshot_schedule.conf chmod 640 /etc/snapper/configs/$((shares-1)) echo "==== [Info] Done with Share /$volume/$item." } check_existing_backups() { if [ -d "/var/backups/shares/" ]; then echo "= [Info] Share config backups folder exist (/var/backups/shares)" echo "== [Task] Backing up existing share config backup folder" tar -cf "/var/backups/backup_share_configs.$(date +%s).tar" /var/backups/shares 2>/dev/null echo "=== [Info] Completed share config backup folder." sleep 1 echo "=== [Task] Listing backup folder for a quick analysis" stat -c "%y %s %n" /var/backups/shares/* echo "==== [Info] Review backup folder listing and decide to continue or restore." sleep 5 echo -n "==== [Decide] To cancel and manually restore from an above config, CTRL-C now... Otherwise, continuing in 5..."; sleep 1; echo -n " 4..."; sleep 1; echo -n " 3..."; sleep 1; echo -n " 2..."; sleep 1; echo -n " 1..."; sleep 1 ; echo " 0..."; sleep 1 fi } iscsi_create() { iscsi=$((iscsi+1)) found=$((found+1)) path="/$volume/._share/$item" echo "=== [Task] Recreating config for LUN at /$volume/$item.." mkdir -p "$path" cat > "$path"/iscsi.conf << EOF comment alert_threshold 80 EOF cat > "$path"/custom_snapshot_management.conf << EOF enabled = no retention_rule = lifetime lifetime = 2592000 number = 30 nonempty_snapshots = yes prev_versions = no EOF cat > "$path"/custom_snapshot_schedule.conf << EOF ........................ ........................ ........................ ........................ ........................ ........................ ........................ EOF echo "0 0 0 * 0 0 0" > "$path"/snapshot.conf echo "==== [Info] done with LUN /$volume/$item." } backup_configs() { cd "/$volume/._share/" tar -cf "/var/backups/$volume.sharelunconfig.$(date +%s).tar" ./* 2>/dev/null } checktype() { if ls -QdA /"$volume"/"$item"/.iscsi >/dev/null 2>&1; then iscsi_create else share_create fi } ################### ### end command ### ################### echo "===================================" echo "* Share and iSCSI Rebuild v6.10.0 *" echo "===================================" check_existing_backups echo "= [Task] Discovering volumes" volumes=$(rn_nml -g volumes 2>/dev/null) # find if readynasd is running if [[ $? -eq 0 ]]; then # if readynasd was successful volumes=$(echo "$volumes"| grep "resource-id" | sed 's/^.*id="//;s/".*//;') # then parse it readynasd=1 elif [[ $? -eq 1 ]] ; then # but if it wasn't echo "== [Info] readynasd not available; doing alternative lookup for shares" # inform intent volumes=$(find / -maxdepth 2 -name "._share" | sed 's/^\///g;s/\/.*//') # create new list fi number=$(echo "$volumes" | wc -w) if [[ ! $number ]]; then echo "== [Error] No volumes found." exit 1 else echo "== [Info] $number volume(s) found." backupsnappershots for volume in $volumes; do echo "== [Task] Investigating volume /$volume..." objects=$(cd /"$volume"; ls -dA ./*/ 2>/dev/null) if [[ $? == 2 ]]; then echo "=== [Error] No shares or LUNs found." else objects=$(echo "$objects" |egrep -v "^.apps\/$|^\.\/home\/$|^.purge\/$|^._share\/$|^.timemachine\/$|^.vault\/$|^.TemporaryItems\/$" | sed 's/\/$//;s/\.\///') echo "=== [Info] Number of items found : $(echo $objects | wc -w)" echo "=== [Info] Items found:" $objects backup_configs for item in $objects; do echo "=== [Task] Reviewing $item" if ! btrfs subv show /"$volume"/"$item" &>/dev/null; then echo "=== [Task] Adding /$volume/$item to subvolume migration list." invalid="$invalid $item" else checktype fi done fi if [[ $invalid ]]; then invalidnumber=$(echo "$invalid" | wc -w) echo "== [Task] Subvolume Migrations required: $invalidnumber" echo "== [Info] Subvolume Migrations list: $invalid" echo "=== [Warning] Do not interrupt this process. Doing so may result in an incomplete migration." sleep 3 echo -n "=== [Decide] If you want to terminate now, CTRL-C..." && echo -n "Continuing in 5..."; sleep 1; echo -n " 4..."; sleep 1; echo -n " 3..."; sleep 1; echo -n " 2..."; sleep 1; echo -n " 1..."; sleep 1 ; echo " 0..."; sleep 1 for item in $invalid; do echo "=== [Task] Subvolume Migrating /$volume/$item" $mvcmd /"$volume"/"$item" /"$volume"/"$item".fix if [[ ! $? ]]; then echo "==== [Fail] when renaming folder." elif [[ $? ]]; then echo "=== [Task] Creating replacement btrfs subvolume" btrfs subvolume create /"$volume"/"$item" &>/dev/null if [[ $? ]]; then echo "==== [Task] Migrating data to the new subvolume" $mvcmd /"$volume"/"$item".fix/* /"$volume"/"$item".fix/.* /"$volume"/"$item" &>/dev/null if [[ $? ]]; then echo "===== [Success] migrating /$volume/$item to a btrfs subvolume." rmdir /$volume/$item.fix migrated=$((migrated+1)) checktype else echo "===== [Error] Re-run in debug mode for more details." fi fi else echo "==== [Fail] when creating btrfs subvolume." fi done fi echo "= [Info] done with /$volume" unset invalid invalidnumber done if [[ $found -gt 0 ]] && [[ $readynasd ]] ; then echo "= [Task] Restarting readynasd to apply changes." systemctl restart readynasd else echo "= [Info] Not starting readynasd because it returned a bad message earlier; restart as needed." fi echo "[Stats] Rebuilt Share configs: $shares" echo "[Stats] Rebuilt LUN configs: $iscsi" echo "[Stats] Migrated folders to subvolumes: $migrated" fi