bin/imager.save
changeset 47 9a717ec183a2
parent 46 8b655cc9bd27
child 49 37e863785ccc
equal deleted inserted replaced
44:f1fea4381014 47:9a717ec183a2
    48                 -verbose   => 2,
    48                 -verbose   => 2,
    49                 exit       => 0,
    49                 exit       => 0,
    50                 -noperldoc => system("perldoc -V >/dev/null 2>&1")
    50                 -noperldoc => system("perldoc -V >/dev/null 2>&1")
    51             );
    51             );
    52         },
    52         },
    53         "c|comment=s"   => \$o{comment},
    53         "c|comment=s"  => \$o{comment},
    54         "z|compress:i"  => sub { $o{compress} = $_[1] ? $_[1] : Z_BEST_SPEED },
    54         "z|compress:i" => sub { $o{compress} = $_[1] ? $_[1] : Z_BEST_SPEED },
    55         "p|pass=s"      => \$o{pass},
    55         "p|pass=s"      => \$o{pass},
    56         "b|blocksize=s" => sub {
    56         "b|blocksize=s" => sub {
    57             given ($_[1]) {
    57             given ($_[1]) {
    58                 when (/(\d+)G/i) { $o{blocksize} = $1 * GiB };
    58                 when (/(\d+)G/i) { $o{blocksize} = $1 * GiB };
    59                 when (/(\d+)M/i) { $o{blocksize} = $1 * MiB };
    59                 when (/(\d+)M/i) { $o{blocksize} = $1 * MiB };
    99     $size = get_devsize($src);
    99     $size = get_devsize($src);
   100 
   100 
   101     -d $dst or die "$0: $dst: $!\n";
   101     -d $dst or die "$0: $dst: $!\n";
   102     mkpath([$data, $idx, $info]);
   102     mkpath([$data, $idx, $info]);
   103 
   103 
   104     my $index = File::Temp->new(DIR => $idx);
   104     my %index;
   105     print {$index} <<__EOT;
   105     $index{META} = {
   106 # imager
   106         format     => 1,
   107 format: 1
   107         host       => hostname,
   108 host: @{[hostname]}
   108         filesystem => $src,
   109 filesystem: $src
   109         blocksize  => $o{blocksize},
   110 blocksize: $o{blocksize}
   110         devsize    => $size,
   111 devsize: $size
   111         timestamp  => NOW,
   112 timestamp: @{[NOW]}
   112         datetime   => DATETIME,
   113 datetime: @{[DATETIME]}
   113         (defined $o{comment} ? (comment => $o{comment}) : ()),
   114 comment: @{[$o{comment}//"none"]}
   114         encryption => $o{pass} ? CIPHER : "none",
   115 encryption: @{[$o{pass} ? CIPHER : "none"]}
   115     };
   116 
       
   117 __EOT
       
   118 
   116 
   119     open(my $in => $src);
   117     open(my $in => $src);
   120     binmode($in);
   118     binmode($in);
   121     local $/ = \$o{blocksize};
   119     local $/ = \$o{blocksize};
   122     local $| = 1;
   120     local $| = 1;
   149         $ext = "";
   147         $ext = "";
   150         $ext .= $o{compress} ? ".gz" : "";
   148         $ext .= $o{compress} ? ".gz" : "";
   151         $ext .= $o{pass}     ? ".x"  : "";
   149         $ext .= $o{pass}     ? ".x"  : "";
   152 
   150 
   153         # the extension we do not put into the index
   151         # the extension we do not put into the index
   154         my $log = sprintf "%12d %s %s" => ($. - 1), $cs, $file;
   152         push @{ $index{BLOCKS} }, sprintf "%12d %s %s" => ($. - 1),
       
   153           $cs,                    $file;
   155 
   154 
   156         if (
   155         if (
   157             not(   -e "$data/$file"
   156             not(   -e "$data/$file"
   158                 or -e "$data/$file.gz"
   157                 or -e "$data/$file.gz"
   159                 or -e "$data/$file.x"
   158                 or -e "$data/$file.x"
   180                 ) or die $GzipError;
   179                 ) or die $GzipError;
   181             }
   180             }
   182             else { print {$out} $buffer }
   181             else { print {$out} $buffer }
   183             close($out);
   182             close($out);
   184             rename($out => "$data/$file$ext");
   183             rename($out => "$data/$file$ext");
   185             $log .= " *";
   184             $index{BLOCKS}[$. - 1] .= " *";
   186             $stats{written}++;
   185             $stats{written}++;
   187         }
   186         }
   188         else {
   187         else {
   189             $log .= "  ";
       
   190             $stats{skipped}++;
   188             $stats{skipped}++;
   191         }
   189         }
   192 
       
   193         say {$index} $log;
       
   194     }
   190     }
   195     $SIG{ALRM}->();
   191     $SIG{ALRM}->();
   196     alarm 0;
   192     alarm 0;
   197 
   193 
   198     say {$index} "# DONE (runtime " . (time() - $^T) . "s)";
   194     $index{META}{blocks}  = @{ $index{BLOCKS} };
       
   195     $index{META}{runtime} = time() - $^T . "s";
       
   196 
       
   197     my $index = File::Temp->new(DIR => $idx);
       
   198     say $index join "\n" => "# imager",
       
   199       (map { "$_: $index{META}{$_}" } sort(keys %{ $index{META} })),
       
   200       "",
       
   201       @{ $index{BLOCKS} };
       
   202     close($index);
       
   203     rename $index->filename => "$idx/" . DATETIME;
   199 
   204 
   200     say "# $src DONE (runtime " . (time() - $^T) . "s)";
   205     say "# $src DONE (runtime " . (time() - $^T) . "s)";
   201     say "# $src WRITTEN $stats{written}, SKIPPED $stats{skipped} blocks";
   206     say "# $src WRITTEN $stats{written}, SKIPPED $stats{skipped} blocks";
   202     say "# $src SAVINGS "
   207     say "# $src SAVINGS "
   203       . sprintf "%3d%%" => 100 *
   208       . sprintf "%3d%%" => 100 *
   204       ($stats{skipped} / ($stats{written} + $stats{skipped}));
   209       ($stats{skipped} / ($stats{written} + $stats{skipped}));
   205 
       
   206     rename $index->filename => "$idx/" . DATETIME;
       
   207     close $index;
       
   208 
   210 
   209 }
   211 }
   210 
   212 
   211 sub get_devsize {
   213 sub get_devsize {
   212     my ($devname) = @_;
   214     my ($devname) = @_;