Understand dpkg and don’t get stuck with a maintainer script failure

Continuing my series of articles on dpkg’s errors, this time I’ll cover a pretty common one which has several variations:

Setting up acpid (1:2.0.12-1) ...
rm: cannot remove `/etc/rc1.d/K20acpid': No such file or directory
dpkg: error processing acpid (--configure):
 subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
 acpid

Even if dpkg is failing and outputting the error message, the real problem is not in dpkg but in the installed package (acpid in the example above). As we already learned, a package contains not only files but also “maintainer scripts” that are executed at various points of the installation process (see some useful graphics to understand how they are called, thanks to Margarita Manterola).

Maintainer scripts in a package upgrade

In the introductory example it was acpid’s “post-installation script” that failed, and dpkg is only forwarding that failure back to the caller. The maintainer scripts are stored in /var/lib/dpkg/info/. You can thus inspect them and even modify them if you hit a bug and want to work around it (do this only if you understand what you do!).

One common modification is to add “set -x” at the start of the script and to retry the failing operation. That way you can see what’s executed exactly. Here’s what the output could look like after the addition of “set -x” to /var/lib/dpkg/info/acpid.postinst:

$ sudo dpkg --configure acpid
Setting up acpid (1:2.0.12-1) ...
+ dpkg --compare-versions 1:2.0.11-1 lt-nl 1.0.10-3
+ dpkg --compare-versions 1:2.0.11-1 lt-nl 1.0.6-16
+ dpkg --compare-versions 1:2.0.11-1 lt 1.0.6-6
+ rm /etc/rc1.d/K20acpid
rm: cannot remove `/etc/rc1.d/K20acpid': No such file or directory
dpkg: error processing acpid (--configure):
 subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
 acpid

This output helps you locate the command that is actually failing. Here’s it’s relatively easy since we have an error message from “rm”. And the fix is trivial too, we replace “rm” with “rm -f” so that it doesn’t fail when the file doesn’t exist (this is a fake bug I made up for this article—I just added a failing rm call—but it’s inspired by real bugs I experienced).

Maintainer scripts are supposed to be idempotent: we should be able to execute them several times in a row without bad consequences. It happens from time to time that the maintainer gets this wrong… on the first try it works, so he uploads his package and we discover the problem only later once someone ended up executing the same code twice for some reason.

Follow me on Identi.ca, Twitter, Facebook and Google+. Or subscribe to this blog by RSS or by email.

Additional Resources

Get the Debian Administrator's Handbook

After a successful liberation campaign, the Debian Administrator's Handbook is now freely available. If you appreciate my articles and what I do for Debian, check out the book and grab a copy.

Comments

  1. FYI the +1 button doesn’t appear to work on your website. Keeps going ‘red’ on me. :( Great resource btw!

  2. Also your website doesn’t even work with goo.gl keeps error-ing out. Something funky is going on and yours is the only website I’ve ever experienced this with.

  3. dj_palindrome says:

    I’m not going to complain about your website ;-)
    Instead, I’m going to thank you for a great article.
    I have a weird problem updating libc6 on a flash-based installation of Knoppix and it’s obvious the package maintainer’s script doesn’t quite know what it’s doing:

    # dpkg -i –force-all /var/cache/apt/archives/libc6_2.13-20_i386.deb

    (Reading database … 348874 files and directories currently installed.)
    Preparing to replace libc6 2.13-7 (using …/libc6_2.13-20_i386.deb) …
    A copy of the C library was found in an unexpected directory:
    ‘/UNIONFS/lib/i386-linux-gnu/libc-2.13.so’
    It is not safe to upgrade the C library in this situation;
    please remove that copy of the C library or get it out of
    ‘/UNIONFS/lib/i386-linux-gnu’ and try again.

    dpkg: error processing /var/cache/apt/archives/libc6_2.13-20_i386.deb (–install):
    subprocess new pre-installation script returned error exit status 1
    Errors were encountered while processing:
    /var/cache/apt/archives/libc6_2.13-20_i386.deb

  4. dj_palindrome says:

    Thanks I will; unfortunately not everybody who gets bug reports is as friendly as you, esepecially if they are just from end-users, or worse, they can smell a newbie coming.

    Since this is only a virtualized environment, maybe I will educate myself my investigating the behavior of the script in a bit more detail so I’ll know what I’m talking about.

    • dj_palindrome says:

      Someone on the Knoppix user forum suggested using a quick-and-dirty chroot to break the update deadlock, and this worked. Whether this was really the fault of the package script, or merely the weird ways Knoppix maintains a persistent disk image, is unknown (or at least beyond me).

      So thanks for the tip.

  5. Hi all,
    I have the following error when i try to install one package called LUDataManager i built myself :
    # dpkg -i LUDataManager_V01.01.27.deb
    Preparing to replace LUDataManager 01.01.27 (using LUDataManager_V01.01.27.deb)…
    Setting up LUDataManager (01.01.27)…
    sh: /var/lib/dpkg/info/LUDataManager.postinst: not found
    dpkg: postinst failed, exit code 32512
    I don’t understand what happened because I see the script postinst in the package and even in the directory /var/lib/dpkg/info.
    Does anyone has an idea ? Thanks for help.

    • One more detail : the installation is made on an embedded busybox system v1.13.2.

    • Debian packages are usually entirely lower-case. I bet the problem is related to this…

      • Hi,
        I don’t think so because I already installed packages named with upper case letters on my embedded device and there is no problem !!
        Can you tell me more about the ‘set up’ stage of a package installation and why sh doesn’t find the postinst script that I see in /var/lib/dpkg/info ..
        Thanks.

        • Feel free to use “strace” to find out what’s happening. If you believe it’s a bug please report it and provide the package so that we can duplicate the problem (and tell use what filesystem you’re using for /var/lib/dpkg/). If you want to learn more, you can always dig in the sources… in any case, this is not the proper place to have this discussion.

          BTW, the filename can have upper cases, what matters is what you see after “Package:” in the output of dpkg -I LUDataManager_V01.01.27.deb.

          • Thanks for your reply.
            I found that the problem was caused by the postinst file in my package: its format was Windows and not Unix/Linux, that is each line ends with ^M.