Library Versioning

I have been discovering all about library versioning. What I found came as a surprise to me and others especially those from a sysadmin background.

Basically it all comes down to the fact that the numbers on the end of a library name may not be what you expect and it is even more complex on OS X.

Libtool on Linux

For example consider the following libraries on a recent CentOS 6.2 install:

  • /lib64/libparted-2.1.so.0.0.0
  • /lib64/libproc-3.2.8.so
  • /lib64/libgcrypt.so.11.5.3

These show the three different ways in which a library may be versioned. Chapter 7 of the libtool manual discuses this subject. Libtool library versions are purely concerned with the supported API or interface that the library supports. It determines what the linker will allow to be linked.

libtool library versions are described by three integers:

  • current
    • The most recent interface number that this library implements.
  • revision
    • The implementation number of the current interface.
  • age
    • The difference between the newest and oldest interfaces that this library imple- ments. In other words, the library implements all the interface numbers in the range from number current – age to current.

If two libraries have identical current and age numbers, then the dynamic linker chooses the library with the greater revision number.

This is (or should be) what you see for libgcrypt.so.11.5.3. Running gpg –version shows that the version of libgcrypt is in fact

# gpg --version
gpg (GnuPG) 2.0.14
libgcrypt 1.4.5

The version of libgcrypt is 1.4.5 but its API is 11.5.3.

In order to set the Libtool library version you set the  -version-info 11:5:3 flag using libmylib_la_LDFLAGS in your Makefile.am (See the automate manual).

By contrast /lib64/libproc-3.2.8.so has no numbers after the .so. They all appear before it. This reflects the fact that the developers, for whatever reason decided to use the version number of the application in the library. Running free gives

# free -V
procps version 3.2.8

This is achieved by using the flag  -release in place of -version-info in Makefile.am.

libparted-2.1.so.0.0.0 shows both. Running parted gives

# parted -v
parted (GNU parted) 2.1

OS X

According to Fink the situation on OS X is slightly different. There is a “strict distinction between shared libraries and dynamically loadable modules”. On linux any “shared code can be used as a library and for dynamic loading”. On OS X there are two types of library MH_DYLIB (a shared library) and MH_BUNDLE (a module). MH_DYLIB carry the extension .dylib and can be linked against in the familiar -lmylib at compile/link time. They can not be loaded as a module using dlopen(). MH_BUNDLE on the other hand can be dlopened. Apple suggest naming these .bundle however, much ported software uses .so instead. It is not directly possible to link against bundles as if they were shared libraries.

Selecting an interval from a integer column in PostgreSQL

I needed to create a select that combined a timestamp in one column with an interval specified in minutes from another column. After much manual reading and searching I found the answer on stackoverflow. My SQL looked something like:

SELECT d.time AT TIME ZONE 'UTC' + interval '1 minute' * d.minute as time FROM my data d ...

Much faster than using Perl’s DateTime::Format::Pg and DateTime::Duration modules to do the addition.

Upgrading the Subversion plugin on Jenkins

Since upgrading our subversion server to 1.7 I have tried several times to upgrade the subversion plugin on Jenkins (v1.457) from 1.34 to 1.39. Using the plugin manager it downloads the plugin and asks you to restart. However, when you restart the jenkins.war expands and overwrites the newly downloaded plugin with the 1.34 version that I guess is shipped in the war.

The solution is easy. Use the plugin manager to download the plugin and change the ownership of the subversion.jpi file so that the jenkins user can not overwrite it. Then restart. (This will make future upgrades more difficult as you will have to revert the ownership).

Cutting down the noise of automake

Adding AM_SILENT_RULES([yes]) to your configure.ac will greatly reduce the output of make. It will look very similar to the linux kernel build:

Making all in common
  CC     strlcat.o
  CC     strlcpy.o
  AR     libcompat.a
Making all in netconf/src/ncx
  CC     libncx_a-b64.o
  CC     libncx_a-blob.o
  CC     libncx_a-bobhash.o
  CC     libncx_a-cap.o

This line must go after your AM_INIT_AUTOMAKE initialization. You need to be using automake >= 1.11. There is a good explanation here.

 

freebsd-update

I have always liked FreeBSD. IMHO it has the best and most up-to-date software collection in the form of ports (much more current than Gentoo last time I looked). I was always irritated by how hard it was to upgrade the kernel and core OS. Talking to several friends I found that the new(ish) freebsd-update utility seems to have passed a lot of people by.

It allows binary updates to the FreeBSD OS (not ports or packages) it also supports major and minor release upgrades. Along with portsnap and portupgrade FreeBSD is now as easy to manage as any other OS.

One minor gotcha is that it only updates the version number reported by uname if the kernel has been upgraded.

Fun and games with OS X Lion Server

With the recent release of Lion I decided to upgrade my desktop from Snow Leopard client to Lion Server and at the same time migrate the Snow Leopard mac mini server over to it.

According to the combination of a knowledge base article and the migration instructions Chapter 3 page 24 this should be easy. It was not.

The knowledge base instructions say in step 2-7

Open “Install Mac OS X Lion”. Note: In order to install Lion Server, the Server app must be in the same folder as the Install Mac OS X app. If you just purchased Lion Server, these items should be in the Applications folder on the startup disk.

Click continue and agree to the software license agreement if you agree.

Click the “Show All Disks…” button.

Select a blank disk on which to install.

Click the Customize button.

Select the Server Software package.

Unfortunately that isn’t true. It only works if you are already running Lion Server!!! Here is what you need to do.

Assuming you have a disposable Snow Leopard client on volume A and have a blank volume B.

  1. Boot into Snow Leopard client.
  2. Use disk utility to erase volume B
  3. Download both the Lion Client app and the Lion Server app from the app store.
  4. They will be place in you /Applications folder
  5. Run the Lion Client app, when asked press “Show all disks” then select install on Volume B.
  6. Unlike what Apple say the customise button will stay greyed out and it will ignore the Server app.
  7. During the install ignore the option to migrate (This is a client only migration).
  8. Once Lion Client is installed run the Server App to install the server component
  9. Copy the Lion Client app and the Lion Server app from the volume A /Applications to the new Lion Server /Applications directory.
  10. Use disk utility to erase volume A
  11. Run the Lion Client app, when asked press “Show all disks” then select install on Volume A.
  12. This time what Apple say will be true. The customise button will be enabled and you will be able to select the Server component to install.
  13. Connect the mac mini in target disk mode and during the install you will be invited to migrate from another server.

This guide to hosting Lion software updates on a Snow Leopard Server is correct and useful.

Installing grub2 on GNU/Linux Software Raid

I have been setting up a two machines with software raid to use as Xen virtual environments. The two machines have 5 and 4 500GB disks. I decided to run Gentoo as the Dom0  OS because there is lots of good documentation for it and it has always been my favorite GNU/Linux distribution. The install of the OS and xen is easy. I opted for the latest Xen 4.0.1rc3-pre code. Just emerge xen and xen-tools to get all the prerequisites and the unmerge them and build the latest source. Creating the RAID arrays was also easy. I did the following.