# HG changeset patch # User Heiko Schlittermann (JUMPER) # Date 1431522044 -7200 # Node ID 41872269ca6ffceb8bed617428dd2aad7c0b5773 # Parent 87081e9cf3ba9408419c709c59e86727ee942ef4# Parent 977e53d08eac0401e7953c27cb325054c025fd17 [merged] diff -r 87081e9cf3ba -r 41872269ca6f .hgtags --- a/.hgtags Wed May 13 14:58:27 2015 +0200 +++ b/.hgtags Wed May 13 15:00:44 2015 +0200 @@ -5,3 +5,5 @@ 19eeea04d29a6cf8b99baede5e7610a47ebb1598 imager_0.9 2a287457a78b22ce0c479a4d6b3caea7225a91e2 imager_0.10 46e6d2918f851257bec3d05fb01742eeef867db1 imager_0.11 +0efc1be1805b39a09d60c7f0dadf4a7c7aa37e96 imager_0.12 +affb4464dd8fe184eec477a8c61630fe802f04ed imager_0.13 diff -r 87081e9cf3ba -r 41872269ca6f LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Wed May 13 15:00:44 2015 +0200 @@ -0,0 +1,27 @@ +Copyright: + + Copyright (C) 2011,2012,2013 Heiko Schlittermann + +License: + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +On Debian systems, the complete text of the GNU General +Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". + +The Debian packaging is: + + Copyright (C) 2011 Heiko Schlittermann + +and is licensed under the GPL version 3, see above. diff -r 87081e9cf3ba -r 41872269ca6f README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Wed May 13 15:00:44 2015 +0200 @@ -0,0 +1,47 @@ +Guide to the impatient user +=========================== + +Install the package +------------------- + + # perl Build.PL + + (optional step) + # ./Build prereq_report + + ./Build install + +Create your first image +----------------------- + +NOTE: The device you're imaging must not be busy during +image creation. Other your image will be unusable! + +The preferred way to get an idle device is using LVM snapshots: + + # lvcreate -s -L 1G -n lvol00-snap vg00/lvol00 + + (optional - check the filesystem) + # fsck -y /dev/mapper/vg00/lvol00-snap + + # imager save /dev/mapper/vg00/lvol00-snap /path/to/backup + +Restore your image +------------------ + +For a full restore: + + # imager restore /path/to/backup/idx/HOST/DEVICE/IMAGE-name > image + +If you need just parts of your image: + + # imager fuse /path/to/backup/ /mnt + +Now you may browse the images below /mnt/. To select just some files - +loop mount such an image and restore the files you need: + + # mount -o loop /mnt/…/image /media/xxx + +Happy landings…. +-- +Heiko Schlittermann diff -r 87081e9cf3ba -r 41872269ca6f bin/imager.fuse --- a/bin/imager.fuse Wed May 13 14:58:27 2015 +0200 +++ b/bin/imager.fuse Wed May 13 15:00:44 2015 +0200 @@ -14,6 +14,7 @@ use DB_File; use File::Basename; use Imager; +use Smart::Comments; my %o = ( debug => undef, @@ -38,8 +39,11 @@ sub max { (sort { $a <=> $b } @_)[-1]; } -my $debug = sub { print STDERR @_ }; -$debug = sub { }; + +sub nop_debug { } +sub yes_debug { print STDERR @_ } + +*{main::debug} = \&nop_debug; #$SIG{INT} = sub { warn "Got ^C or INT signal\n"; exit 1; }; @@ -47,7 +51,7 @@ GetOptions( "d|debug!" => \$o{debug}, - "detach!" => \$o{detach}, + "detach!" => \$o{detach}, "tmp:s" => sub { $o{tmp} = length $_[1] ? $_[1] : $ENV{TMP} // "/tmp" }, "h|help" => sub { pod2usage(-verbose => 1, -exit => 0) }, "p|pass=s" => \$o{pass}, @@ -62,6 +66,11 @@ and @ARGV == 2 or pod2usage; + if ($o{debug}) { + undef &{main::debug}; + *{main::debug} = \&yes_debug; + } + my ($src, $mp) = @ARGV; $DATA = "$src/data"; @@ -82,13 +91,14 @@ Fuse::main( mountpoint => $mp, - debug => $o{debug} // 0, - getattr => \&getattr, - getdir => \&getdir, - open => \&openfile, - read => \&readbuffer, - write => \&writebuffer, - release => \&release, + + # debug => $o{debug} // 0, + getattr => \&getattr, + getdir => \&getdir, + open => \&openfile, + read => \&readbuffer, + write => \&writebuffer, + release => \&release, ); exit; @@ -154,7 +164,7 @@ sub release { my $path = $IDX . shift; return 0 if not exists $IMAGE{$path}; - $debug->("Currently we have " . keys(%DIRTY) . " dirty blocks\n"); + debug("Currently we have " . keys(%DIRTY) . " dirty blocks\n"); return 0; } @@ -164,11 +174,16 @@ my $finfo = $IMAGE{$path} or die "File $path is not opened!"; return "" if $offset >= $finfo->{meta}{devsize}; + debug("<<< REQUESTED: offset:$offset size:$size\n"); + my $buffer = ""; for (my $need = $size ; $need > 0 ; $need = $size - length($buffer)) { + debug("<<< offset:@{[$offset + length($buffer)]} size:$need\n"); $buffer .= _readblock($finfo, $need, $offset + length($buffer)); + debug("<<< missing: ", $size - length($buffer), "\n") if $size - length($buffer); } + debug("<<< SENDING " . length($buffer) . "\n\n"); return $buffer; } @@ -176,8 +191,9 @@ my ($finfo, $size, $offset) = @_; my ($block, $blockoffset, $length); - $debug->("<<< block offset:$offset size:$size\n"); - $debug->(" block @{[int($offset/BS)]} + @{[$offset % BS]}\n"); + debug("<<< requested: offset:$offset size:$size" + . "\tfrom $finfo->{meta}{filesystem}\n"); + debug(" mapped to: block:@{[int($offset/BS)]}+@{[$offset % BS]}\n"); # first check if it's an dirty block $block = int($offset / BS); @@ -185,7 +201,7 @@ $blockoffset = $offset % BS; $length = min(BS - $blockoffset, $size); - $debug->( + debug( "+++ dirty offset:$block*@{[BS]} + $blockoffset size:$length\n" ); return substr $DIRTY{ $finfo . $block }, $blockoffset, $length; @@ -207,18 +223,19 @@ } } - $debug->("=== $length\n"); - $debug->( -"+++ disk offset:$block*$finfo->{meta}{blocksize} + $blockoffset size:$length\n" - ); + debug("+++ disk offset:$block*$finfo->{meta}{blocksize}" + . " + $blockoffset size:$length\n"); + +# die if $blockoffset == 417792; my $fn = "$DATA/" . $finfo->{blocklist}{$block}; + debug(" fn:$fn\n"); state %cache; if (not defined $cache{fn} or ($cache{fn} ne $fn)) { - Imager::get_block("$fn*" => \$cache{data}); + Imager::get_block("$fn*" => \$cache{data}); $cache{fn} = $fn; } @@ -253,11 +270,11 @@ $blockoffset = $offset % BS; $length = min(BS - $blockoffset, $size); - $debug->(">>> offset:$offset size:$length of $size\n"); - $debug->(" block @{[int($offset/BS)]} + @{[$offset % BS]}\n"); + debug(">>> offset:$offset size:$length of $size\n"); + debug(" block @{[int($offset/BS)]} + @{[$offset % BS]}\n"); if (not exists $DIRTY{ $finfo . $block }) { - $debug->("+++ missing $block+$blockoffset\n"); + debug("+++ missing $block+$blockoffset\n"); $DIRTY{ $finfo . $block } = _readblock($finfo, BS, $block * BS); } @@ -274,11 +291,12 @@ while (<$fh>) { last if /^$/; /^(?\S+):\s+(?:(?\d+)|(?.*?))\s*$/ - and do { - # na sowas, die Zeitstempel dürfen nicht als Zeichenkette reinkommen! - $meta{ $+{k} } = defined $+{n} ? (0+$+{n}) : $+{v}; - next; - }; + and do { + + # na sowas, die Zeitstempel dürfen nicht als Zeichenkette reinkommen! + $meta{ $+{k} } = defined $+{n} ? (0 + $+{n}) : $+{v}; + next; + }; } return %meta; } diff -r 87081e9cf3ba -r 41872269ca6f bin/imager.save --- a/bin/imager.save Wed May 13 14:58:27 2015 +0200 +++ b/bin/imager.save Wed May 13 15:00:44 2015 +0200 @@ -17,18 +17,17 @@ use Imager 0.1; use if $^V >= v5.18 => (experimental => qw'lexical_topic smartmatch'); -use constant KiB => 1024; -use constant MiB => 1024 * KiB; -use constant GiB => 1024 * MiB; -use constant BS => 4 * MiB; -use constant DATEFMT => "%Y-%m-%dT%H:%M:%SZ"; -use constant CIPHER => "aes-128-cbc"; +use constant KiB => 1024; +use constant MiB => 1024 * KiB; +use constant GiB => 1024 * MiB; +use constant BS => 4 * MiB; +use constant DATEFMT => "%Y-%m-%dT%H:%M:%SZ"; +use constant CIPHER => "aes-128-cbc"; sub get_devsize; sub get_devname; sub save; - $SIG{INT} = sub { die "Got INT\n" }; my %o = ( @@ -54,7 +53,7 @@ "c|comment=s" => \$o{comment}, "z|compress:i" => sub { $o{compress} = $_[1] ? $_[1] : Z_BEST_SPEED }, "p|pass=s" => \$o{pass}, - "now=i" => \$o{now}, + "now=i" => \$o{now}, "b|blocksize=s" => sub { given ($_[1]) { when (/(\d+)G/i) { $o{blocksize} = $1 * GiB }; @@ -84,7 +83,7 @@ my $rc = 0; while (wait != -1) { - $rc = ($? >> 8) if ($? >> 8) > $rc; + $rc = ($? >> 8) if ($? >> 8) > $rc; } exit $rc; @@ -179,29 +178,28 @@ } binmode($out); - - my $bufref = \$buffer; - if ($o{compress}) { - my $zbuffer; - gzip( - \$buffer => \$zbuffer, - -Minimal => 1, - -Level => Z_BEST_SPEED, - -Strategy => Z_FILTERED - ) or die $GzipError; - if (length($zbuffer) / length($buffer) < 0.9) { - $bufref = \$zbuffer; - $ext = ".gz$ext"; - } + my $bufref = \$buffer; + if ($o{compress}) { + my $zbuffer; + gzip( + \$buffer => \$zbuffer, + -Minimal => 1, + -Level => Z_BEST_SPEED, + -Strategy => Z_FILTERED + ) or die $GzipError; + if (length($zbuffer) / length($buffer) < 0.9) { + $bufref = \$zbuffer; + $ext = ".gz$ext"; } + } - #for(my $todo = length $$bufref; - # $todo -= syswrite $out => $$bufref, $todo, -$todo; 1) - #{ - #} - syswrite $out => $$bufref; - - close($out) or die $!; + #for(my $todo = length $$bufref; + # $todo -= syswrite $out => $$bufref, $todo, -$todo; 1) + #{ + #} + syswrite $out => $$bufref or die "$0: write: $!\n"; + close($out) or die "$0: close output file: $!"; + rename($out => "$data/$file$ext"); $index{BLOCKS}[$blknr] .= " *"; $stats{written}++; diff -r 87081e9cf3ba -r 41872269ca6f debian/changelog --- a/debian/changelog Wed May 13 14:58:27 2015 +0200 +++ b/debian/changelog Wed May 13 15:00:44 2015 +0200 @@ -1,3 +1,17 @@ +imager (0.13) stable; urgency=low + + * perltidy, fixed debug output + + -- Heiko Schlittermann Mon, 27 Aug 2012 15:52:40 +0200 + +imager (0.12) stable; urgency=low + + * fixed Build.PL + * fixed attrs passed from getattr() + * The timestamps need to be numbers! + + -- Heiko Schlittermann Mon, 18 Jun 2012 16:54:46 +0200 + imager (0.11) stable; urgency=low * added the :name explanation