mylvmbackup-discuss team mailing list archive
-
mylvmbackup-discuss team
-
Mailing list archive
-
Message #00068
patches for backuptype=none and error handling
hi, I'd like to suggest the attached patch for inclusion in mylvmbackup.
it is relative to 0.13. it does the following (from top to bottom):
* make sure $PATH includes sbin
* make sure $HOME is set (not always the case when launched
(indirectly) from init, in my case, from Bacula)
* count error messages logged, and never exit with status 0 if
non-zero
* move around cleanup for backuptype=none. this means you can do
"mylvmbackup --backuptype=none --keep_mount" to take a snapshot,
and "mylvmbackup --backuptype=none" to release it. the
shuffling is necessary to handle the case where mylvmbackup dies
suddenly.
* simple typo for $pidfile -- probably fixed in trunk, I didn't
check...
* cleanup handles the case where the snapshot was created and
mounted in a different run
* fix a potential endless loop if the logerr hook contains errors.
--
thanks,
Kjetil T. Homme
Redpill Linpro - Changing the game
--- mylvmbackup.pl.in 2009-09-05 15:44:09.000000000 +0200
+++ /srv/nfs/ms/home/kjetilho/svn/puppet/modules/mysql/files/mylvmbackup/mylvmbackup.pl 2010-12-14 17:12:44.979678793 +0100
@@ -37,6 +37,9 @@
my $configfile = "/etc/mylvmbackup.conf";
my $configfile2 = "";
+$ENV{PATH} .= ":/usr/sbin:/usr/bin:/sbin:/bin";
+$ENV{HOME} ||= (getpwuid($<))[7];
+
my $TMP= ($ENV{TMPDIR} || "/tmp");
my $backupdir;
@@ -87,6 +90,7 @@
my $syslog_socktype;
my $syslog_facility;
my $syslog_remotehost;
+my $errors=0;
# Load defaults into variables
load_defaults();
@@ -140,7 +144,7 @@
# No .tar.gz on the end!
my $archivename = $backupdir.'/'.$fullprefix;
-my $mounted = 0;
+my $mounted;
my $snapshot_created = 0;
# Check for the backupdir, it must exist, and it must be readable/writable
@@ -160,6 +164,22 @@
my $posmountdir = $mountdir;
$posmountdir .= '-pos'; # Notice that we do not add a slash.
+if ($backuptype eq 'none' && !$keep_mount && !$keep_snapshot)
+{
+ cleanup();
+ exit ($errors ? 1 : 0);
+}
+
+# Make sure mountdir doesn't already exist
+if (glob "$mountdir/*") {
+ # First try to cleanup after a failed previous run
+ cleanup();
+ if (glob "$mountdir/*") {
+ log_msg ("Please make sure Temp dir ($mountdir) is empty.", LOG_ERR);
+ exit(1);
+ }
+}
+
my $pos_filename = $posmountdir.'/'.$fullprefix.'.pos';
my $pos_tempfile_fh;
my $pos_tempfile;
@@ -176,14 +196,6 @@
# Check it again for existence and read/write.
check_dir($mountdir, 'mountdir');
-# Now make sure it's empty
-my @mountdir_content = glob "$mountdir/*" ;
-unless ( scalar(@mountdir_content) eq 0)
-{
- log_msg ("Please make sure Temp dir ($mountdir) is empty.", LOG_ERR);
- exit(1);
-};
-
# Figure out our DSN string
my $dsn = "DBI:mysql:database=mysql;mysql_read_default_group=client";
@@ -253,13 +265,10 @@
run_hook("backupfailure");
}
}
-} else {
- cleanup();
- exit 1;
}
cleanup();
-exit 0;
+exit ($errors ? 1 : 0);
# Please keep all 3 functions in the same order: load_config, load_args, load_defaults
sub load_config
@@ -420,7 +429,7 @@
$suffix='_mysql';
$datefmt='%Y%m%d_%H%M%S';
$innodb_recover=0;
- $pidfile = '$TMP/mylvmbackup_recoverserver.pid';
+ $pidfile = "$TMP/mylvmbackup_recoverserver.pid";
$skip_flush_tables=0;
$extra_flush_tables=0;
$skip_mycnf=0;
@@ -637,6 +646,9 @@
my $msg = shift;
my $syslog_level = shift;
+ # Make sure we never exit successfully if LOG_ERR occurs
+ ++$errors if $syslog_level eq LOG_ERR;
+
# Only log errors and warnings if quiet option is set
return if ($quiet) and ($syslog_level eq LOG_INFO);
@@ -695,15 +707,32 @@
{
run_hook("precleanup");
log_msg ("Cleaning up...", LOG_INFO);
+
+ unless (defined $mounted) {
+ my $mapper_name = "$vgname/$backuplv";
+ $mapper_name =~ s:-:--:g;
+ $mapper_name =~ s:/:-:g;
+ $mapper_name = "mapper/$mapper_name";
+ if (open(my $mountfd, "$mount|")) {
+ while (<$mountfd>) {
+ if (m:^/dev/($vgname/$backuplv|$mapper_name)\s:) {
+ log_msg ("found mounted LV", LOG_INFO);
+ $mounted = 1;
+ }
+ }
+ close($mountfd);
+ }
+ }
+
unless ($keep_mount) {
run_command("Unmounting $mountdir","$umount $mountdir") if ($mounted);
- unlink $pos_filename if (-f $pos_filename);
- unlink $mycnf_filename if (-f $mycnf_filename);
+ unlink $pos_filename if defined $pos_filename && -f $pos_filename;
+ unlink $mycnf_filename if defined $mycnf_filename && -f $mycnf_filename;
if ($posmountdir) {
rmdir $mountdir;
rmdir $posmountdir;
}
- unlink $pos_tempfile if (-f $pos_tempfile);
+ unlink $pos_tempfile if defined $pos_tempfile && -f $pos_tempfile;
} else {
log_msg("Not removing mount as requested by configuration", LOG_INFO);
}
@@ -714,9 +743,6 @@
foreach my $lvs_info (@lvs_info) {
log_msg ($lvs_info, LOG_INFO);
}
- }
- if ($snapshot_created)
- {
unless ($keep_snapshot || $keep_mount) {
run_command("Removing snapshot", "$lvremove -f /dev/$vgname/$backuplv");
} else {
@@ -888,6 +914,9 @@
my $hookfile = $hooksdir."/".$hookname;
$hookarg="" unless ($hookarg);
+ # Avoid loops
+ my $log_err = ($hookname eq "precleanup" || $hookname eq "logerr") ?
+ LOG_WARNING : LOG_ERR;
eval "use $hookname";
if($@)
{
@@ -901,7 +930,7 @@
if ( $? >> 8 != 0)
{
log_msg (sprintf("Hook $hookname failed with nonzero exit value %d", $? >> 8),
- $hookname eq "precleanup" ? LOG_WARNING : LOG_ERR);
+ $log_err);
}
}
} else {
@@ -909,7 +938,7 @@
my $ret = $hookname->execute(($dbh ? $dbh->clone() : undef), $hookarg);
if(!$ret)
{
- log_msg ("Perl module '$hookname' did not return a true result: " . $hookname->errmsg(), LOG_ERR);
+ log_msg ("Perl module '$hookname' did not return a true result: " . $hookname->errmsg(), $log_err);
}
}
}
Follow ups