Bug#649174: update-inetd: make robust against being run when perl-base and perl-modules are out of sync

Colin Watson cjwatson at ubuntu.com
Fri Nov 18 14:14:05 UTC 2011


Package: update-inetd
Version: 4.40
Severity: normal
Tags: patch
User: ubuntu-devel at lists.ubuntu.com
Usertags: origin-ubuntu ubuntu-patch precise

There are a few situations where it's possible for update-inetd to be
called in the middle of an upgrade from one Perl major version to the
next: for example, https://bugs.launchpad.net/bugs/862129 turned out to
be a case where the samba postrm was called in such a situation.  If
that happens, then any modules provided by the perl-modules package will
be unavailable.  This includes File::Temp and File::Copy, both of which
are used by update-inetd.

It would be very helpful for update-inetd to work even when only
perl-base is available.  I appreciate that this requires slightly more
complex code, but it would make the whole system more robust during
upgrades.

Here's a suggested patch to implement this.  It implements fallback
versions of the 'tempfile' and 'move' functions if the module versions
are unavailable.  These will be a bit slower since they involve calling
external programs, but at least the complexity is all kept up in the
part of the code that imports modules rather than polluting the main
body of DebianNet.pm.

I've tested this by performing an upgrade from Ubuntu oneiric to precise
(which involves an upgrade from perl 5.12 to 5.14), pausing it
immediately after perl-base is configured, and then running update-inetd
--add and --remove.  Without this patch, it fails with "Can't locate
File/Temp.pm in @INC"; with this patch, it behaves as expected (and
strace output looks sensible as well).

Making this truly robust will probably also involve having perl-base
declare Breaks on versions of update-inetd prior to this patch being
applied.  I've CCed perl at packages.debian.org in case they'd like to
comment on this.

  * Fall back to external 'tempfile' and 'mv' commands in case perl-base and
    perl-modules are out of sync during an upgrade (LP: #862129).

=== modified file 'DebianNet.pm'
--- DebianNet.pm	2011-09-11 19:03:14 +0000
+++ DebianNet.pm	2011-11-18 14:06:39 +0000
@@ -15,8 +15,44 @@ package DebianNet;
 require 5.6.1;
 
 use Debconf::Client::ConfModule ':all';
-use File::Temp qw/ tempfile /;
-use File::Copy qw/ move /;
+
+BEGIN {
+    eval 'use File::Temp qw/ tempfile /';
+    if ($@) {
+        # If perl-base and perl-modules are out of sync, fall back to the
+        # external 'tempfile' command.  In this case we don't bother trying
+        # to mangle the template we're given into something that tempfile
+        # can understand.
+        sub tempfile {
+            open my $tempfile_fh, '-|', 'tempfile'
+                or die "Error running tempfile: $!";
+            chomp (my $tempfile_name = <$tempfile_fh>);
+            unless (length $tempfile_name) {
+                die "tempfile did not return a temporary file name";
+            }
+            unless (close $tempfile_fh) {
+                if ($!) {
+                    die "Error closing tempfile pipe: $!";
+                } else {
+                    die "tempfile returned exit status $?";
+                }
+            }
+            open my $fh, '+<', $tempfile_name
+                or die "Error opening temporary file $tempfile_name: $!";
+            return ($fh, $tempfile_name);
+        }
+    }
+
+    eval 'use File::Copy qw/ move /';
+    if ($@) {
+        # If perl-base and perl-modules are out of sync, fall back to the
+        # external 'mv' command.
+        sub move {
+            my ($from, $to) = @_;
+            return system('mv', $from, $to) == 0;
+        }
+    }
+}
 
 $inetdcf="/etc/inetd.conf";
 $sep = "#<off># ";

Thanks,

-- 
Colin Watson                                       [cjwatson at ubuntu.com]






More information about the Perl-maintainers mailing list