Getting rdiff-backup working on UNFS3

Introduction

When rdiff-backup writes to storage provided over UNFS3 then it encounters the following error:

Exception '[Errno 116] Stale NFS file handle: '/staging/backups/ditalini_root.rdiffbackup/bin/rdiff-backup.tmp.39'' raised of class 'exceptions.OSError':
  File "/var/lib/python-support/python2.4/rdiff_backup/Main.py", line 302, in error_check_Main
    try: Main(arglist)
  File "/var/lib/python-support/python2.4/rdiff_backup/Main.py", line 322, in Main
    take_action(rps)
  File "/var/lib/python-support/python2.4/rdiff_backup/Main.py", line 278, in take_action
    elif action == "backup": Backup(rps[0], rps[1])
  File "/var/lib/python-support/python2.4/rdiff_backup/Main.py", line 344, in Backup
    backup.Mirror(rpin, rpout)
  File "/var/lib/python-support/python2.4/rdiff_backup/backup.py", line 38, in Mirror
    DestS.patch(dest_rpath, source_diffiter)
  File "/var/lib/python-support/python2.4/rdiff_backup/backup.py", line 218, in patch
    ITR(diff.index, diff)
  File "/var/lib/python-support/python2.4/rdiff_backup/rorpiter.py", line 281, in __call__
    last_branch.fast_process(*args)
  File "/var/lib/python-support/python2.4/rdiff_backup/backup.py", line 515, in fast_process
    if self.patch_to_temp(mirror_rp, diff_rorp, tf):
  File "/var/lib/python-support/python2.4/rdiff_backup/backup.py", line 536, in patch_to_temp
    result = self.patch_snapshot_to_temp(diff_rorp, new)
  File "/var/lib/python-support/python2.4/rdiff_backup/backup.py", line 561, in patch_snapshot_to_temp
    rpath.copy_attribs(diff_rorp, new)
  File "/var/lib/python-support/python2.4/rdiff_backup/rpath.py", line 166, in copy_attribs
    rpout.chown(*rpout.conn.user_group.map_rpath(rpin))
  File "/var/lib/python-support/python2.4/rdiff_backup/rpath.py", line 874, in chown
    try: self.conn.C.lchown(self.path, uid, gid)

This problem stems from that UNFS3 does not implement lchown().

This page describes how Alexis Huxley got rdiff-backup working with UNFS3.

Procedure

  1. Create lchown.c containing:
    #include <sys/types.h>
    
    int lchown(
    const char *path,
    uid_t owner,
    gid_t group)
    {
        return(0);
    }
  2. Convert this to a shared library with the commands:
    PUBLIBNAME=librdiffhack.so.1
    PRVLIBNAME=$PUBLIBNAME.0.1
    LIBDIR=/usr/local/lib
    gcc -fPIC -g -c -Wall lchown.c
    gcc -shared -Wl,-soname,$PUBLIBNAME -o $PRVLIBNAME lchown.o -lc
    mkdir -p $LIBDIR
    cp $PRVLIBNAME $LIBDIR
    ln -s $PRVLIBNAME $LIBDIR/$PUBLIBNAME
  3. Trick rdiff-backup into using this version of lchown() either by invoking it as follows:
    LD_PRELOAD=/usr/local/lib/librdiffhack.so.1 rdiff-backup ...

    or by creating a wrapper script like this one:

    #!/bin/sh
    
    LD_PRELOAD=/usr/local/lib/librdiffhack.so.1 exec rdiff-backup "$@"

 

See also