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