[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#591924: postgresql-common - insserv: script postgresql: service postgresql already provided!



Martin Pitt [2010-11-21 14:04 +0100]:
> For reference I attach a complete debdiff.

*cough*
-- 
Martin Pitt                        | http://www.piware.de
Ubuntu Developer (www.ubuntu.com)  | Debian Developer  (www.debian.org)
diff -Nru postgresql-common-111/debian/changelog postgresql-common-112/debian/changelog
--- postgresql-common-111/debian/changelog	2010-09-22 12:04:14.000000000 +0200
+++ postgresql-common-112/debian/changelog	2010-11-21 13:52:38.000000000 +0100
@@ -1,3 +1,27 @@
+postgresql-common (112) unstable; urgency=medium
+
+  * Urgency medium since this fixes an RC bug.
+  * debian/changelog: Fix changelog entry in version 111 for #597654: init
+    script priority was fixed to S19, not S29.
+  * pg_ctlcluster: Also pass additional pg_ctl arguments in "stop" and
+    "reload" mode.
+  * pg_ctlcluster: Pass correct exit code from pg_ctl in case of errors.
+  * PgCommon.pm, get_db_encoding(): Fix uninitialized variable if psql fails.
+  * t/040_upgrade.t: Check that pg_upgradecluster exits early and gracefully
+    if the old cluster does not stop (usually because there are still active
+    connections to it). This reproduces #509050.
+  * pg_upgradecluster: Move stopping of old cluster and disabling connections
+    to it much ealier, and properly fail without starting the upgrade.
+    (Closes: #509050)
+  * debian/postgresql-common.preinst: Remove obsolete init script from
+    postgresql-8.3 for upgrades from Lenny. It provides "postgresql" which is
+    also provided by our common init script, and insserv chokes on this. Our
+    common init script handles 8.3 as well and will just take over. Note that
+    this is a policy violation, but we can't clean up in -8.3 since that does
+    not exist any more in Squeeze. (Closes: #591924)
+
+ -- Martin Pitt <mpitt@debian.org>  Sun, 21 Nov 2010 13:52:25 +0100
+
 postgresql-common (111) unstable; urgency=high
 
   * Urgency high since this fixes two RC bugs.
@@ -15,7 +39,7 @@
     lsb_release is not working/existing. Derivatives have debian_version as
     well, and we don't actually evaluate it, so just print a meaningful error
     message and go with the default versions.
-  * debian/rules: Put init script priority back to S29/K21 to match the
+  * debian/rules: Put init script priority back to S19/K21 to match the
     previous postgresql-8.4 init script. Fix the priorities on upgrade in
     debian/postgresql-common.preinst. (Closes: #597654)
 
diff -Nru postgresql-common-111/debian/postgresql-common.preinst postgresql-common-112/debian/postgresql-common.preinst
--- postgresql-common-111/debian/postgresql-common.preinst	2010-09-22 12:01:14.000000000 +0200
+++ postgresql-common-112/debian/postgresql-common.preinst	2010-11-21 13:47:42.000000000 +0100
@@ -46,6 +46,13 @@
 		fi
 	    done
 	fi
+	# Remove obsolete init script from postgresql-8.3. It provides
+	# "postgresql" which is also provided by our common init script, and
+	# insserv chokes on this. Note that there is no reason to stop/restart
+	# postgresql-8.3, the new init script will just take over.
+	if dpkg --compare-versions "$2" lt-nl "112~"; then
+	    rm_conffile postgresql-8.3 /etc/init.d/postgresql-8.3
+	fi
         ;;
 
     abort-upgrade)
diff -Nru postgresql-common-111/PgCommon.pm postgresql-common-112/PgCommon.pm
--- postgresql-common-111/PgCommon.pm	2010-08-05 17:51:32.000000000 +0200
+++ postgresql-common-112/PgCommon.pm	2010-10-24 20:25:09.000000000 +0200
@@ -738,10 +738,10 @@
     close PSQL;
     $> = $orig_euid;
     restore_exec;
+    return undef if $?;
     chomp $out;
     ($out) = $out =~ /^([\w.-]+)$/; # untaint
-    return $out unless $?;
-    return undef;
+    return $out;
 }
 
 # Return locale of a particular database in a cluster. This requires access
diff -Nru postgresql-common-111/pg_ctlcluster postgresql-common-112/pg_ctlcluster
--- postgresql-common-111/pg_ctlcluster	2010-08-05 17:51:33.000000000 +0200
+++ postgresql-common-112/pg_ctlcluster	2010-10-24 20:22:49.000000000 +0200
@@ -252,23 +252,27 @@
         }
         exit 1;
     }
+
+    return 0;
 }
 
 sub stop {
     stop_check_pid_file;
+    my $result = 1;
 
     if ($force) {
         if (!fork()) {
             close STDOUT;
-            exec $pg_ctl, '-D', $info{'pgdata'}, '-s', '-w', '-m', 'fast', 'stop';
+            exec $pg_ctl, '-D', $info{'pgdata'}, '-s', '-w', '-m', 'fast', @pg_ctl_opts_from_cli, 'stop';
         } else {
             wait;
+	    $result = $? >> 8;
         }
 
         # try harder if "fast" mode does not work
         if (-f $info{'pgdata'}.'/postmaster.pid') {
-            print "(does not shutdown gracefully, now stopping immediately)";
-            system $pg_ctl, '-D', $info{'pgdata'}, '-s', '-w', '-m', 'immediate', 'stop';
+            print "(does not shutdown gracefully, now stopping immediately)\n";
+	    $result = system $pg_ctl, '-D', $info{'pgdata'}, '-s', '-w', '-m', 'immediate', @pg_ctl_opts_from_cli, 'stop';
         }
 
         # if that still not helps, use the big hammer
@@ -277,27 +281,38 @@
             $pid = get_running_pid $info{'pgdata'}.'/postmaster.pid';
             kill (9, $pid) if $pid;
             unlink $info{'pgdata'}.'/postmaster.pid';
+	    $result = 0;
         }
     } else {
         if (!fork()) {
             close STDOUT;
-            exec $pg_ctl, '-D', $info{'pgdata'}, '-s', '-w', 'stop';
+            exec $pg_ctl, '-D', $info{'pgdata'}, '-s', '-w', @pg_ctl_opts_from_cli, 'stop'; 
         } else {
             wait;
+	    $result = $? >> 8;
         }
     }
 
     # external_pid_file files are currently not removed by postmaster itself
-    unlink "/var/run/postgresql/$version-$cluster.pid";
+    if ($result == 0) {
+	unlink "/var/run/postgresql/$version-$cluster.pid";
+    }
+
+    return $result;
 }
 
 sub restart {
-    stop if $info{'running'};
-    start;
+    my $result;
+
+    if ($info{'running'}) {
+	$result = stop;
+	return $result if $result;
+    }
+    return start;
 }
 
 sub reload {
-    exec $pg_ctl, '-D', $info{'pgdata'}, '-s', 'reload';
+    exec $pg_ctl, '-D', $info{'pgdata'}, '-s', @pg_ctl_opts_from_cli, 'reload';
 }
 
 #
@@ -377,7 +392,7 @@
             'restart' => \&restart);
 
 if ($actions{$action}) {
-    $actions{$action}->();
+    exit $actions{$action}->();
 } else {
     error 'Error: invalid action (must be one of: '. 
         (join ', ', keys %actions);
diff -Nru postgresql-common-111/pg_upgradecluster postgresql-common-112/pg_upgradecluster
--- postgresql-common-111/pg_upgradecluster	2010-08-05 17:51:33.000000000 +0200
+++ postgresql-common-112/pg_upgradecluster	2010-10-24 20:43:15.000000000 +0200
@@ -188,14 +188,14 @@
 }
 
 # Save original pg_hba.conf, replace it with one that only allows local access
-# to the owner, and reload postmaster.
+# to the owner. Database must be reloaded manually if it is running.
 # Arguments: <version> <cluster> <owner> <owneruid>
 sub disable_connections {
     my $hba = "/etc/postgresql/$_[0]/$_[1]/pg_hba.conf";
 
-    rename $hba, "$hba.orig" or error 'could not rename pg_hba.conf';
+    rename $hba, "$hba.orig" or error "could not rename $hba: $!";
     unless (open F, ">$hba") {
-        rename "$hba.orig", $hba; 
+        rename "$hba.orig", $hba;
         error "could not create $hba";
     }
     chmod 0400, $hba;
@@ -206,11 +206,6 @@
 	print F "local all $_[2] ident sameuser";
     }
     close F;
-
-    if (system 'pg_ctlcluster', $_[0], $_[1], 'reload') {
-        rename "$hba.orig", $hba; 
-        error "could not reload cluster $_[0]/$_[1]";
-    }
 }
 
 # Restore original pg_hba.conf, but do not restart postmaster.
@@ -218,7 +213,7 @@
 sub enable_connections {
     my $hba = "/etc/postgresql/$_[0]/$_[1]/pg_hba.conf";
 
-    rename "$hba.orig", $hba or error 'could not rename pg_hba.conf';
+    rename "$hba.orig", $hba or error "could not rename $hba.orig: $!";
 }
 
 #
@@ -281,9 +276,25 @@
 
 my $oldpsql = get_program_path 'psql', $version;
 my $oldsocket = get_cluster_socketdir $version, $cluster;
+my $owner = getpwuid $info{'owneruid'};
+error 'could not get name of cluster owner' unless $owner;
+
+# stopping old cluster, so that we notice early when there are still
+# connections
+print "Stopping old cluster...\n";
+my @argv = ('pg_ctlcluster', $version, $cluster, 'stop', '--', '-t', '5');
+error "Could not stop old cluster" if system @argv;
+
+# Disable access to clusters during upgrade
+print "Disabling connections to the old cluster during upgrade...\n";
+disable_connections $version, $cluster, $owner, $info{'owneruid'};
+
+print "Restarting old cluster with restricted connections...\n";
+@argv = ('pg_ctlcluster', $version, $cluster, 'start');
+error "Could not restart old cluster" if system @argv;
 
 # create new cluster, preserving encoding and locales
-my @argv = ('pg_createcluster', '-u', $info{'owneruid'}, '-g', $info{'ownergid'},
+@argv = ('pg_createcluster', '-u', $info{'owneruid'}, '-g', $info{'ownergid'},
     '--socketdir', $info{'socketdir'}, $newversion,
     $cluster);
 
@@ -301,12 +312,16 @@
 delete $ENV{'LC_ALL'};
 error "Could not create target cluster" if system @argv;
 
+%newinfo = cluster_info($newversion, $cluster);
+
+print "Disabling connections to the new cluster during upgrade...\n";
+disable_connections $newversion, $cluster, $owner, $newinfo{'owneruid'};
+
 @argv = ('pg_ctlcluster', $newversion, $cluster, 'start');
 error "Could not start target cluster" if system @argv;
 
 sleep(4);
 
-%newinfo = cluster_info($newversion, $cluster);
 my $pg_restore = get_program_path 'pg_restore', $newversion;
 
 # check whether upgrade scripts exist; if so, verify that pg_restore supports
@@ -334,14 +349,6 @@
     wait;
 }
 
-# Disable access to clusters during upgrade
-my $owner = getpwuid $info{'owneruid'};
-error 'could not get name of cluster owner' unless $owner;
-print "Disabling connections to the old cluster during upgrade...\n";
-disable_connections $version, $cluster, $owner, $info{'owneruid'};
-print "Disabling connections to the new cluster during upgrade...\n";
-disable_connections $newversion, $cluster, $owner, $newinfo{'owneruid'};
-
 # dump cluster; drop to cluster owner privileges
 
 if (!fork) {
diff -Nru postgresql-common-111/t/040_upgrade.t postgresql-common-112/t/040_upgrade.t
--- postgresql-common-111/t/040_upgrade.t	2010-08-05 17:51:34.000000000 +0200
+++ postgresql-common-112/t/040_upgrade.t	2010-10-24 21:24:42.000000000 +0200
@@ -3,13 +3,15 @@
 
 use strict; 
 
+use POSIX qw/dup2/;
+
 use lib 't';
 use TestLib;
 
 use lib '/usr/share/postgresql-common';
 use PgCommon;
 
-use Test::More tests => ($#MAJORS == 0) ? 1 : 84;
+use Test::More tests => ($#MAJORS == 0) ? 1 : 91;
 
 if ($#MAJORS == 0) {
     pass 'only one major version installed, skipping upgrade tests';
@@ -90,6 +92,32 @@
 chmod 0100, '/tmp/pgtest/';
 chdir '/tmp/pgtest';
 
+# upgrade attempt fails cleanly if the server is busy
+my $psql = fork;
+if (!$psql) {
+    my @pw = getpwnam 'nobody';
+    change_ugid $pw[2], $pw[3];
+    dup2(POSIX::open('/dev/null', POSIX::O_WRONLY), 1);
+    exec 'psql', 'template1' or die "could not exec psql process: $!";
+}
+
+like_program_out 0, "pg_upgradecluster $MAJORS[0] upgr", 1, 
+    qr/Error: Could not stop old cluster/,
+    'pg_upgradecluster fails on busy cluster';
+like_program_out 'nobody', 'pg_lsclusters -h', 0,
+    qr/^$MAJORS[0]\s+upgr\s+5432 online postgres/;
+
+kill 9, $psql;
+waitpid $psql, 0;
+
+# now that the connection went away, postmaster shuts down; so restart it
+# properly
+system "pg_ctlcluster $MAJORS[0] upgr stop";
+sleep 5;
+like_program_out 'nobody', 'pg_lsclusters -h', 0,
+    qr/^$MAJORS[0]\s+upgr\s+5432 down\s+postgres/;
+is ((system "pg_ctlcluster $MAJORS[0] upgr start"), 0, 'Starting upgr cluster');
+
 # Upgrade to latest version
 my $outref;
 is ((exec_as 0, "(pg_upgradecluster $MAJORS[0] upgr | sed -e 's/^/STDOUT: /')", $outref, 0), 0, 'pg_upgradecluster succeeds');

Attachment: signature.asc
Description: Digital signature


Reply to: