Tuesday, September 25, 2007

Fun with Debian Source Packages II

On my last post I promised to present a use case for a Debian source package which doesn't have to do with debugging or patching a bad binary package. So here goes.

As part of my preparations for a rainy day - namely, the day on which my PC will suddenly die on me - I wanted to make sure that I could access the files on my USB backup disk, without Bacula. The files are stored in a set of large compressed archive files, so it may seem hopeless, but luckily Bacula comes with a file extraction utility bextract. The following command can extract the files from a given storage device, using a bootstrap file and the configuration file of the Bacula storage daemon:

bextract -b <bsr-file> -c <bacula-sd.conf> FileStorage <destination-directory>

So all I need to do is run a script at the end of each backup job, that copies the bootstrap file that Bacula generates to the backup disk. Furthermore, I need to make sure that up to date versions of both the storage daemon configuration file, and of the bextract executable are also stored on the backup disk.

But the bextract executable depends on a number of external shared libraries, as can be determined with ldd:

# ldd /usr/sbin/bextract
linux-gate.so.1 => (0xffffe000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f67000)
libz.so.1 => /usr/lib/libz.so.1 (0xb7f52000)
libpython2.4.so.1.0 => /usr/lib/libpython2.4.so.1.0 (0xb7e41000)
libutil.so.1 => /lib/i686/cmov/libutil.so.1 (0xb7e3d000)
librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7e34000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7e1d000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7e18000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7d2d000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7d08000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7cfd000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7bb5000)
libattr.so.1 => /lib/libattr.so.1 (0xb7bb1000)
/lib/ld-linux.so.2 (0xb7f85000)

In order to avoid these dependencies, bextract has to be statically linked. The need for static linking has been anticipated by Bacula's authors and is supported as an option in the upstream build procedure.

But it's not enabled in the regular Debian build procedure, and getting this done entails some modification of the source package...

Looking at the package's debian/rules file I realized that it actually runs the upstream package's configure script with a set of options. I executed ./configure --help and got a list of all the available options - the relevant option in this case is --enable-static-tools.

So, in order to enable static linking of the Bacula tools, I added the option --enable-static-tools to the configuration options provided to the configure script (by modifying CONF_ALL in debian/rules). Instead of building the whole package with dpkg-buildpackage I launched the build of the sqlite3 version of the storage daemon (which is the version I have installed), like this:

fakeroot -- debian/rules build-stamp-sqlite3

This generated a statically linked bextract at debian/tmp-build-sqlite3/src/stored/bextract, as can verified with ldd:

# ldd debian/tmp-build-sqlite3/src/stored/bextract
not a dynamic executable

While useful at times, mutilation of source packages has some obvious downsides:
  • it may require quite a bit of experimentation before you get it right
  • you're basically on your own, pretty much the same situation that you face when downloading any non-Debian source package
  • maintenance can be quite a nightmare because source packages are not tracked by the Debian package management tools
Have fun.

No comments:

Post a Comment