Package: backupninja
Version: 1.2.2-1
Severity: normal

Package: backupninja
Version: 1.2.2-1
Severity: important
Tags: patch

--- Problem description

The rsync handler's rotate_long (and rotate_long_remote) functions contain
three bugs that together cause long-format backup rotation to stall silently
after a few cycles.

--- Bug 1 -- cuttoff_time calculation wrong for weekly/monthly

rotate_long currently reads:

    cutoff_time=$(( now - (seconds*(i-1)) ))

For daily rotations this is correct (base_age = 0), but for weekly and monthly
it does not account for the time needed to fill all preceding tiers.

Example with keepdaily=5, keepweekly=3:

  weekly.1: cutoff = now - 0  (immediately eligible for promotion)
  monthly.1: cutoff = now - 0 (immediately eligible)

Instead they should take, respectively, 5 days and 26 days before being
rotated.

Fix: add base_age so that weekly/monthly only rotate after lower
tiers have been filled:

    if [ "$rottype" == "daily" ]; then
        base_age=0
    elif [ "$rottype" == "weekly" ]; then
        base_age=$((keepdaily * 86400))
    elif [ "$rottype" == "monthly" ]; then
        base_age=$(((keepdaily * 86400) + (keepweekly * 604800)))
    fi
    cutoff_time=$(( now - (base_age + (i * seconds)) ))

--- Bug 2 -- created file lost on daily/weekly promotion

When daily.MAX is promoted to weekly.1 (or weekly.MAX to monthly.1), the
original handler discards the "created" metadata file from the source directory
and writes only a new "rotated" file:

    date +%c%n%s > metadata/rotated
    #if [ -f metadata/daily.$max/created ]; then
    #    mv ...  (commented out)
    #fi

Over successive cycles every backup in a tier ends up with the same promotion
timestamp instead of the original backup creation time. The age calculation
sees all of them as equally new, which produces infinite "skipping rotation"
messages.

Fix: restore the mv of created into the promoted directory:

    if [ -f $backuproot/metadata/daily.$max/created ]; then
        $nice mv $backuproot/metadata/daily.$max/created \
               $backuproot/metadata/weekly.1/
    fi

(Same change needed on the weekly->monthly promotion and in
rotate_long_remote.)

--- Bug 3 -- no fallback when only "rotated" exists

rotate_long currently reads:

    if [ -f $metadata.$i/created ]; then
        $nice mv $metadata.$i/created $metadata.$next
    fi

If a backup directory only has a "rotated" file (common after Bug 2  has
corrupted the metadata), the timestamp is silently lost during the shift. The
next iteration reads "created=0", triggers "Invalid metadata", and aborts the
rotation loop.

Fix:

    if [ -f $metadata.$i/created ]; then
        $nice mv $metadata.$i/created $metadata.$next
    elif [ -f $metadata.$i/rotated ]; then
        $nice mv $metadata.$i/rotated $metadata.$next/created
    fi

--- Repairing existing corrupted timestamps

Backup sets already affected (all monthly.* metadata showing the
same date) can be repaired with:

    for d in /path/to/backup/section/weekly.*
/path/to/backup/section/monthly.*; do
        mtime=$(stat -c '%Y' "$d")
        printf '%(%c)T\n%s\n' "$mtime" "$mtime" > "$(dirname
$d)/metadata/$(basename $d)/created"
    done

--- Affected versions

The bugs affect both local (rotate_long) and remote (rotate_long_remote) code
paths.


-- System Information:
Debian Release: forky/sid
  APT prefers testing
  APT policy: (501, 'testing'), (500, 'stable-updates'), (500, 
'stable-security'), (500, 'stable'), (50, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 7.0.10+deb14-amd64 (SMP w/12 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, 
TAINT_UNSIGNED_MODULE
Locale: LANG=it_IT.UTF-8, LC_CTYPE=it_IT.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages backupninja depends on:
ii  bash    5.3-3
ii  dialog  1.3-20260107-2
ii  gawk    1:5.3.2-1
ii  mawk    1.3.4.20260302-1

Versions of packages backupninja recommends:
ii  bsd-mailx [mailx]  8.1.2-0.20220412cvs-1.1

Versions of packages backupninja suggests:
pn  borgbackup     <none>
ii  bzip2          1.0.8-6+b2
pn  debconf-utils  <none>
pn  duplicity      <none>
ii  fdisk          2.42.1-2
pn  genisoimage    <none>
pn  hwinfo         <none>
pn  mdadm          <none>
pn  rdiff-backup   <none>
pn  restic         <none>
ii  rsync          3.4.3+ds1-2
pn  subversion     <none>
pn  trickle        <none>
ii  util-linux     2.42.1-2
pn  wodim          <none>

-- Configuration Files:
/etc/backupninja.conf changed [not included]

-- no debconf information

Reply via email to