[merged]
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Wed, 13 May 2015 15:00:44 +0200
changeset 125 41872269ca6f
parent 124 87081e9cf3ba (current diff)
parent 122 977e53d08eac (diff)
child 126 97c56efb9cd8
[merged]
bin/imager.save
--- 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
--- /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 <http://www.gnu.org/licenses/>.
+
+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 <hs@schlittermann.de>
+
+and is licensed under the GPL version 3, see above.
--- /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 <hs@schlittermann.de>
--- 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 /^$/;
             /^(?<k>\S+):\s+(?:(?<n>\d+)|(?<v>.*?))\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;
     }
--- 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}++;
--- 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 <hs@schlittermann.de>  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 <hs@schlittermann.de>  Mon, 18 Jun 2012 16:54:46 +0200
+
 imager (0.11) stable; urgency=low
 
   * added the :name explanation