"Fossies" - the Fresh Open Source Software Archive

Member "usr/bin/zrm-pre-scheduler" (26 Aug 2013, 8806 Bytes) of package /linux/privat/MySQL-zrm-3.0-release.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/usr/bin/perl -w
    2 #
    3 # Copyright (c) 2006 Zmanda Inc.  All Rights Reserved.
    4 #
    5 # This program is free software; you can redistribute it and/or modify it
    6 # under the terms of the GNU General Public License version 2 as published
    7 # by the Free Software Foundation.
    8 #
    9 # This program is distributed in the hope that it will be useful, but
   10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   11 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12 # for more details.
   13 #
   14 # You should have received a copy of the GNU General Public License along
   15 # with this program; if not, write to the Free Software Foundation, Inc.,
   16 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   17 #
   18 # Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
   19 # Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
   20 #
   21 #
   22 
   23 use warnings;
   24 use Getopt::Long;
   25 use Time::Local;
   26 use File::Copy;
   27 use File::Temp qw/ :mktemp  /;
   28 use Fcntl ':flock';
   29 use lib "/usr/lib/mysql-zrm";
   30 use ZRM::Common;
   31 
   32 
   33 
   34 my $oldPATH = $ENV{'PATH'};
   35 $ENV{'PATH'} = "/usr/local/bin:/opt/csw/bin:/usr/bin:/usr/sbin:/sbin:/bin:/usr/ucb";
   36 
   37 my $zrm_scheduler="/usr/bin/mysql-zrm-scheduler";
   38 my $prog="zrm-pre-scheduler";
   39 my $logdir="/var/log/mysql-zrm";
   40 my $logfile="$logdir/$prog.log";
   41 my $mycrontab_fh;
   42 my $mycrontab;
   43 
   44 
   45 my @PRESCHEDULEROPT = qw/html-report-directory=s
   46                          pre-scheduler=s
   47                          action=s
   48                          backup-level=i
   49                          interval=s/;
   50 
   51 my $MYSQL_ZRM_BASEDIR="/etc/mysql-zrm/";
   52 
   53 my $MYSQL_ZRM_CONFIG_FILE=$MYSQL_ZRM_BASEDIR . "mysql-zrm.conf";
   54 
   55 sub mprint {
   56     my $d=localtime();
   57     &lockLog();
   58     print LOG "$d: ";
   59     print LOG @_;
   60     &unlockLog();
   61 }
   62 
   63 sub log_and_die {
   64     my $d=localtime();
   65     &lockLog();
   66     print LOG "$d: ";
   67     print LOG  @_;
   68     &unlockLog();
   69     die @_;
   70 }
   71 
   72 # return tomorrow's day of month
   73 sub next_mday() {
   74     my $now = time;
   75     my $tomorrow = (localtime($now + 86400))[3];
   76     return ( $tomorrow );
   77 }
   78 
   79 
   80 # reschedule crontab, add --delay to differentiate from
   81 # the original crontab
   82 # check if delay > 24, if so
   83 #   skip if it's daily
   84 #   call mysql-zrm now anyway if it's weekly or monthly
   85 #   since we don't want to miss a weekly/monthly backup
   86 # else
   87 #   +n which ( n <= 11) to delay and install new crontab
   88 # when called with delete, just delete the crontab with --delay
   89 sub reschedule()
   90   {
   91     my $myaction  = $_[0]; # to edit or delete
   92     my $later   = $_[1];
   93     my $setname = $_[2];
   94     my $int     = $_[3]; #daily, weekly or monthly backup
   95     my $lev     = $_[4];
   96     my $found=0;
   97 
   98     ($mycrontab_fh, $mycrontab) = mkstemp( "/tmp/zrm-preschedulerXXXXX" );
   99     $mycrontab_fh=$mycrontab_fh; # quiet warnings
  100     system ("crontab -l > $mycrontab 2> /dev/null");
  101     $exit_value  = $? >> 8;
  102     if ( $exit_value > 1 ) {    # 0 is fine
  103       # suse crontab returns 1 for "no crontab found"
  104       &mprint ("ERROR: crontab -l failed.\n");
  105       &mprint ("Make sure you are allowed to run crontab on this machine\n");
  106       unlink $mycrontab;
  107       return 1;
  108     }
  109     open (INF, "$mycrontab") || &log_and_die ("ERROR: Cannot open $mycrontab : $!\n");
  110     open (OUTF, ">$mycrontab.tmp") || &log_and_die ("ERROR: Cannot create $mycrontab.tmp : $!\n");
  111     $pattern="\-\-action backup \-\-backup\-set $setname.*\-\-interval $int \-\-backup\-level $lev";
  112 
  113     if ( $myaction eq "edit" ) {
  114       while ( <INF> ) {
  115     # $1=min, $2=hr, $3=day_month, $4=month, $5=day_wk, $6=dontcare, $7=--delay, $8=delay_num
  116     if ( /^([^#].*)\s+([0-9]{1,2})\s+([0-9\*]{1,2})\s+([0-9\*]{1,2})\s+([0-9\*])\s+(.*$pattern\s+)(\-\-delay)\s+([0-9]{1,2})$/ ) {
  117       $new_delay = $8 + $later;
  118       $new_hr    = $2 + $later;
  119       if ( $new_hr > 23 ) {
  120         $new_hr -= 23;
  121         if ( $int eq "weekly") {
  122         $new_day_wk  = ($5 + 1)  % 7;
  123         $new_day_month = $3;
  124         }
  125         if ( $int eq "monthly" ) {
  126         $new_day_month = &next_mday();
  127         $new_day_wk = $5;
  128         }
  129       } else {
  130         $new_day_wk = $5;
  131         $new_day_month = $3;
  132       }
  133       $found++;
  134       print OUTF "$1 $new_hr $new_day_month $4 $new_day_wk $6 --delay $new_delay\n";
  135     } elsif ( ! (/^# DO NOT EDIT.*/ || /^# \(\/tmp\/.*crontab.*/ || /^# \(\/tmp\/zrm-prescheduler.*/ || /^# \(Cron version .*/) ) {
  136       print OUTF;
  137     }
  138       }             #end of while
  139       if ( $found == 0 ) {    #--delay crontab not found, add one here
  140     ($dontcare,$min,$hr,$mday,$dontcare,$dontcare,$wday,$dontcare) = localtime();
  141     $hr += $later;
  142     if ( $hr > 23 ) {
  143         $hr -= 23;
  144         if ($int eq "monthly") {
  145         $mday = &next_mday();
  146         } else {
  147         $mday = "*";
  148         }
  149         if ($int eq "weekly") {
  150         $wday++, $wday %= 7;
  151         } else {
  152         $wday = "*";
  153         }
  154     } else {
  155         if ( $int eq "weekly" ) {
  156         $mday = "*";
  157         } elsif ( $int eq "monthly" ) {
  158         $wday = "*";
  159         }
  160     }
  161     if ( $int eq "daily" ) {
  162         $mday = $wday = "*";
  163     }
  164     print OUTF "$min $hr $mday * $wday /usr/bin/$prog ";
  165     print OUTF "--action $myaction ";
  166         print OUTF "--interval $int " if ( $int );
  167     print OUTF "--backup-level $lev " if ( $lev );
  168     print OUTF "--delay $later\n";
  169       }
  170       &mprint("$setname crontab delayed by $later hour\n");
  171     }               #end of edit
  172     elsif ( $myaction eq "delete" ) {
  173       while ( <INF> ) {
  174     unless ( /^[^#].*$pattern.*\-\-delay\s+[0-9]{1,2}/ ||
  175          /^# DO NOT EDIT.*/ || /^# \(\/tmp\/.*crontab.*/ || /^# \(\/tmp\/zrm-prescheduler.*/ || /^# \(Cron version .*/) {
  176       print OUTF;
  177     }
  178       }
  179       &mprint("$setname crontab with delay deleted\n");
  180     }               #end of delete
  181     close OUTF;
  182     close INF;
  183     move ("$mycrontab.tmp", "$mycrontab") || &log_and_die ("ERROR: move failed: $!\n");
  184 
  185     # all is fine, install the new crontab
  186     system ("crontab $mycrontab");
  187     $exit_value  = $? >> 8;
  188     if ( $exit_value !=0 ) {
  189       &mprint ("ERROR: crontab -l failed.\n");
  190       &mprint ("Make sure you are allowed to run crontab on this machine\n");
  191       unlink $mycrontab;
  192       return 1;
  193     } else {
  194       unlink $mycrontab;
  195       &mprint ("$setname crontab updated successfully\n");
  196     }
  197     return 0;
  198   }
  199 
  200 
  201 sub call_reporter ()
  202   {
  203     my $name = $_[0];
  204     my $date=`date +%Y%m%d%H%M%S`;
  205     chomp($date);
  206     my $report_out="$name.$date.html";  # report name is $backupsetname.timestamp.html
  207     my $reporter="/usr/bin/mysql-zrm-reporter";
  208 
  209    # generate html output
  210     if ( $inputs{'html-report-directory'} && $inputs{'html-report-directory'} ne "" ) {
  211       system "$reporter", "--where", "backup-set=$name", "--latest", "--type", "html", "--output", "$report_out";
  212     }
  213   }
  214 
  215 
  216 
  217 #main
  218 
  219 if (-t STDIN && -t STDOUT) {
  220 die ("ERROR: cannot start $prog from command line\n");
  221 }
  222 
  223 $action = "pre-schedule";
  224 $USAGE_STRING = "";
  225 &initCommon(@PRESCHEDULEROPT);
  226 
  227 unless ( -d $logdir ) {
  228   mkdir ($logdir, 0750) ||
  229     die ("ERROR: mkdir $logdir failed: $!\n");
  230 }
  231 
  232 open (LOG, ">>$logfile") || &log_and_die ("ERROR: Cannot create/open logfile: $!\n");
  233 print STDOUT "Logging to $logfile\n";
  234 
  235 
  236 my $ret;
  237 my $now="--now";
  238 my $no_plugin=0;
  239 my $exit_value=0;
  240 my $skip=0;
  241 my $level=0;
  242 my $delay=0;
  243 
  244 
  245 my $interval    = $inputs{"interval"};
  246 my $myaction    = $inputs{"action"};
  247 
  248 if ( $inputs{"delay"} ) {
  249    $delay = $inputs{"delay"};
  250 }
  251 
  252 if ( $inputs{"backup-level"} ) {
  253    $level = $inputs{"backup-level"};
  254 }
  255 
  256 
  257 if ( $inputs{'pre-scheduler'} && $inputs{'pre-scheduler'} ne "" ) {
  258     $plugin_app=$inputs{'pre-scheduler'};
  259     &mprint("pre-scheduler plugin is $plugin_app\n");
  260 } else {
  261     $no_plugin=1;
  262     &mprint("no pre-scheduler plugin specified in $MYSQL_ZRM_CONFIG_FILE\n");
  263 }
  264 
  265 # call plugin which should return:
  266 #      0    = go ahead call mysql-zrm now
  267 #      1-11 = delay by N hour
  268 #      > 11   = skip this run
  269 if ( $no_plugin == 0 ) {
  270     system($plugin_app, "--backup-set", $backupset);
  271     $exit_value  = $? >> 8;
  272 }
  273 
  274 if ( $exit_value > 11 ) {
  275   $skip = 1;;
  276 }
  277 
  278 if ( $skip ||
  279      (($interval eq "daily") && ($delay + $exit_value) > 23 )) { # skip the run
  280   $ret = &reschedule("delete", 0, $backupset, $interval, $level);
  281   if ( $ret != 0 ) {
  282     &log_and_die("ERROR: delete crontab failed\n");
  283   }
  284   &mprint("$backupset $interval backup skipped\n");
  285   exit 0;
  286 }
  287 
  288 
  289 
  290 if ( $no_plugin == 1 || $exit_value == 0 ||
  291      (($interval ne "daily") &&  ($delay + $exit_value) > 23 )) {
  292     # call mysql-zrm-scheduler --now
  293     system($zrm_scheduler, $now, "--backup-set", $backupset, "--interval", $interval, "--backup-level", $level);
  294     &mprint("ERROR: $zrm_scheduler failed\n") if ( $? == 1 );
  295     &call_reporter($backupset);
  296 
  297     # remove the delay crontab
  298     $ret = &reschedule("delete", 0, $backupset, $interval, $level);
  299     if ( $ret != 0 ) {
  300     &mprint("ERROR: delete crontab failed\n");
  301     }
  302 } elsif ( $no_plugin == 0 ) {
  303     # reschedule crontab with N hrs delay
  304     $ret = &reschedule("edit", $exit_value, $backupset, $interval, $level);
  305     if ( $ret != 0 ) {
  306     &mprint("ERROR: edit crontab failed\n");
  307     }
  308 }