bin/imager.save
changeset 32 02ef2d1b190a
parent 30 7067c6844088
parent 26 496ee9b0f488
child 35 bbdb8ea3079a
equal deleted inserted replaced
29:4a1820d504c4 32:02ef2d1b190a
    13 use IO::Compress::Gzip qw(gzip $GzipError :level :strategy);
    13 use IO::Compress::Gzip qw(gzip $GzipError :level :strategy);
    14 use Hash::Util qw(lock_keys);
    14 use Hash::Util qw(lock_keys);
    15 use Getopt::Long;
    15 use Getopt::Long;
    16 use Pod::Usage;
    16 use Pod::Usage;
    17 
    17 
       
    18 
    18 use constant KiB      => 1024;
    19 use constant KiB      => 1024;
    19 use constant MiB      => 1024 * KiB;
    20 use constant MiB      => 1024 * KiB;
    20 use constant GiB      => 1024 * MiB;
    21 use constant GiB      => 1024 * MiB;
    21 use constant NOW      => time();
    22 use constant NOW      => time();
    22 use constant DATETIME => strftime("%Y-%m-%dT%H:%M:%SZ" => gmtime(NOW));
    23 use constant DATETIME => strftime("%Y-%m-%dT%H:%M:%SZ" => gmtime(NOW));
    23 
    24 
    24 sub get_devsize;
    25 sub get_devsize;
    25 sub get_devname;
    26 sub get_devname;
       
    27 sub save;
    26 
    28 
    27 $SIG{INT} = sub { die "Got INT\n" };
    29 $SIG{INT} = sub { die "Got INT\n" };
    28 
    30 
    29 my %o = (
    31 my %o = (
    30     compress  => undef,
    32     compress  => undef,
    31     verbose   => undef,
    33     verbose   => undef,
    32     blocksize => 2 * MiB,
    34     blocksize => 4 * MiB,
    33 );
    35 );
    34 lock_keys(%o);
    36 lock_keys(%o);
    35 
    37 
    36 my $NOW = time();
    38 my $NOW = time();
    37 
    39 
    38 MAIN: {
    40 MAIN: {
    39     my ($src, $dst);
       
    40 
       
    41     my $idx  = "{DIR}/idx/{HOSTNAME}/{DEVICE}/";
       
    42     my $data = "{DIR}/data";
       
    43     my $size;
       
    44 
       
    45     GetOptions(
    41     GetOptions(
    46         "h|help" => sub { pod2usage(-verbose => 1, exit => 0) },
    42         "h|help" => sub { pod2usage(-verbose => 1, exit => 0) },
    47         "m|man"  => sub {
    43         "m|man"  => sub {
    48             pod2usage(
    44             pod2usage(
    49                 -verbose   => 2,
    45                 -verbose   => 2,
    62                     die "Blocksize $_[1] is incorrect!\n"
    58                     die "Blocksize $_[1] is incorrect!\n"
    63                 };
    59                 };
    64             }
    60             }
    65         },
    61         },
    66       )
    62       )
    67       and @ARGV == 2
    63       and @ARGV >= 2 or pod2usage;
    68       or pod2usage;
    64 
    69     ($src, $dst) = @ARGV;
    65     my $dst = pop @ARGV;
       
    66     foreach my $src (@ARGV) {
       
    67 	if (my $pid = fork()) {
       
    68 	    next;
       
    69 	}
       
    70 	elsif (not defined $pid) {
       
    71 	    die "Can't fork: $!\n"
       
    72 	}
       
    73 	save($src, $dst);
       
    74 	exit;
       
    75     }
       
    76 
       
    77     do 1 while wait != -1;
       
    78 
       
    79 }
       
    80 
       
    81 sub save {
       
    82     my ($src, $dst) = @_;
       
    83     my $idx  = "{DIR}/idx/{HOSTNAME}/{DEVICE}/";
       
    84     my $data = "{DIR}/data";
       
    85     my $size;
    70 
    86 
    71     foreach ($idx, $data) {
    87     foreach ($idx, $data) {
    72         s/{DIR}/$dst/g;
    88         s/{DIR}/$dst/g;
    73         s/{HOSTNAME}/hostname/eg;
    89         s/{HOSTNAME}/hostname/eg;
    74         s/{DEVICE}/get_devname($src)/eg;
    90         s/{DEVICE}/get_devname($src)/eg;
   103     );
   119     );
   104 
   120 
   105     local $SIG{ALRM} = sub {
   121     local $SIG{ALRM} = sub {
   106         my $speed = ($stats{written} + $stats{skipped}) / (time - $^T + 1);
   122         my $speed = ($stats{written} + $stats{skipped}) / (time - $^T + 1);
   107         say sprintf
   123         say sprintf
   108 "# done %5.1f%% | %24s (%*d of $stats{todo}, written %*d, skipped %*d)",
   124 "# %*s done %5.1f%% | %24s (%*d of $stats{todo}, written %*d, skipped %*d)",
       
   125 	  (sort {$a<=>$b} map { length basename $_ } @ARGV)[-1] => basename($src),
   109           100 * (($stats{written} + $stats{skipped}) / $stats{todo}),
   126           100 * (($stats{written} + $stats{skipped}) / $stats{todo}),
   110           ($speed ? (scalar localtime($^T + $stats{todo} / $speed)) : ""),
   127           ($speed ? (scalar localtime($^T + $stats{todo} / $speed)) : ""),
   111           length($stats{todo}) => $stats{written} + $stats{skipped},
   128           length($stats{todo}) => $stats{written} + $stats{skipped},
   112           length($stats{todo}) => $stats{written},
   129           length($stats{todo}) => $stats{written},
   113           length($stats{todo}) => $stats{skipped};
   130           length($stats{todo}) => $stats{skipped};
   155     $SIG{ALRM}->();
   172     $SIG{ALRM}->();
   156     alarm 0;
   173     alarm 0;
   157 
   174 
   158     say {$index} "# DONE (runtime " . (time() - $^T) . "s)";
   175     say {$index} "# DONE (runtime " . (time() - $^T) . "s)";
   159 
   176 
   160     say "# DONE (runtime " . (time() - $^T) . "s)";
   177     say "# $src DONE (runtime " . (time() - $^T) . "s)";
   161     say "# WRITTEN $stats{written}, SKIPPED $stats{skipped} blocks";
   178     say "# $src WRITTEN $stats{written}, SKIPPED $stats{skipped} blocks";
   162     say "# SAVINGS "
   179     say "# $src SAVINGS "
   163       . sprintf "%3d%%" => 100 *
   180       . sprintf "%3d%%" => 100 *
   164       ($stats{skipped} / ($stats{written} + $stats{skipped}));
   181       ($stats{skipped} / ($stats{written} + $stats{skipped}));
   165 
   182 
   166     rename $index->filename => "$idx/" . DATETIME;
   183     rename $index->filename => "$idx/" . DATETIME;
   167     close $index;
   184     close $index;
   213 
   230 
   214 Use compression when writing the blocks to disk. (default: off)
   231 Use compression when writing the blocks to disk. (default: off)
   215 
   232 
   216 =item B<-b> I<blocksize>|B<--blocksize>=I<blocksize>
   233 =item B<-b> I<blocksize>|B<--blocksize>=I<blocksize>
   217 
   234 
   218 The blocksize used. (may be suffixed with K, M, G). (default: 2MiB)
   235 The blocksize used. (may be suffixed with K, M, G). (default: 4 MiB)
   219 
   236 
   220 =item B<-h>|B<--help>
   237 =item B<-h>|B<--help>
   221 
   238 
   222 =item B<-m>|B<--man>
   239 =item B<-m>|B<--man>
   223 
   240