defined(&OBD_IOC_COPY);
eval 'sub OBD_IOC_MIGR () { &_IOC(3, ord(\'f\'), 23, 4);}' unless
defined(&OBD_IOC_MIGR);
+eval 'sub OBD_SNAP_SETTABLE () { &_IOC(3, ord(\'f\'), 40, 4);}' unless
+ defined(&OBD_SNAP_SETTABLE);
+eval 'sub OBD_SNAP_PRINTTABLE () { &_IOC(3, ord(\'f\'), 41, 4);}' unless
+ defined(&OBD_SNAP_PRINTTABLE);
+
+eval 'sub OBD_SNAP_RUNIT () { &_IOC(3, ord(\'f\'), 42, 4);}' unless
+ defined(&OBD_SNAP_RUNIT);
+eval 'sub OBD_EXT2_RUNIT () { &_IOC(3, ord(\'f\'), 61, 4);}' unless
+ defined(&OBD_EXT2_RUNIT);
eval 'sub ATTR_MODE () {1;}' unless defined(&ATTR_MODE);
eval 'sub ATTR_UID () {2;}' unless defined(&ATTR_UID);
'create' => {func => "Create", doc => "create: creates a new inode"},
'attach' => {func => "Attach", doc => "attach type [adapter bus tid lun]"},
'detach' => {func => "Detach", doc => "detach this device"},
- 'snapattach' => {func => "SnapAttach", doc => "snapattach snapno snapcount time1 index1 .... timek indexk"},
+ 'snapattach' => {func => "SnapAttach", doc => "snapattach snapno table"},
+ 'snapset' => {func => "SnapSetTable", doc => "snapset tableno file" },
+ 'snapprint' => {func => "SnapPrint", doc => "snapprint tableno"},
+
+ 'testext2iterator' => {func => "TestExt2Iterator", doc => ""},
+ 'testsnapiterator' => {func => "TestSnapIterator", doc => ""},
+
'snaptable' => {func => "SnapShotTable", doc => "snaptable: build a snapshot table (interactive)"},
'copy' => {func => "Copy", doc => "copy srcid tgtid"},
'migrate' => {func => "Migrate", doc => "migrate srcid tgtid"},
$datalen = 4 * 4;
}
- my $packed = pack("ipip", length($type), $type, $datalen, $data);
+ my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
my $rc = ioctl(DEV_OBD, &OBD_IOC_ATTACH, $packed);
}
-sub SnapAttach {
+sub TestExt2Iterator {
+ my $err = 0;
+ my $type = "ext2_obd";
+
+ $data = pack("i", 4711); # bogus data
+ $datalen = 4;
+
+ my $len = length($type);
+ my $cl = length($data);
+ my $add = pack("p", $data);
+ print "type $type (len $len), datalen $datalen ($cl)\n";
+ my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
+
+ my $rc = ioctl(DEV_OBD, &OBD_EXT2_RUNIT, $packed);
+
+ if (!defined $rc) {
+ print STDERR "ioctl failed: $!\n";
+ } elsif ($rc eq "0 but true") {
+ print "Finished (success)\n";
+ } else {
+ print "ioctl returned error code $rc.\n";
+ }
+}
+
+
+sub TestSnapIterator {
my $err = 0;
my $type = "snap_obd";
- my $snapdev = shift;
- my $snapno = shift;
+
+ $data = pack("i", 4711); # bogus data
+ $datalen = 4;
+
+ my $len = length($type);
+ my $cl = length($data);
+ my $add = pack("p", $data);
+ print "type $type (len $len), datalen $datalen ($cl)\n";
+ my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
+
+ my $rc = ioctl(DEV_OBD, &OBD_SNAP_RUNIT, $packed);
+
+ if (!defined $rc) {
+ print STDERR "ioctl failed: $!\n";
+ } elsif ($rc eq "0 but true") {
+ print "Finished (success)\n";
+ } else {
+ print "ioctl returned error code $rc.\n";
+ }
+}
+
+
+sub SnapPrint {
+ my $err = 0;
+ my $type = "snap_obd";
+ my $snaptableno = shift;
+
+ $data = pack("i", $snaptableno);
+ $datalen = 4;
+
+ my $len = length($type);
+ my $cl = length($data);
+ my $add = pack("p", $data);
+ print "type $type (len $len), datalen $datalen ($cl)\n";
+ my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
+
+ my $rc = ioctl(DEV_OBD, &OBD_SNAP_PRINTTABLE, $packed);
+
+ if (!defined $rc) {
+ print STDERR "ioctl failed: $!\n";
+ } elsif ($rc eq "0 but true") {
+ print "Finished (success)\n";
+ } else {
+ print "ioctl returned error code $rc.\n";
+ }
+}
+
+sub SnapSetTable {
+ my $err = 0;
+ my $type = "snap_obd";
+ my $snaptableno = shift;
my $file = shift;
my $snapcount;
my $table = {};
$snapcount = keys %{$table};
print "Snapcount $snapcount\n";
- $data = pack("iii", $snapdev, $snapno, $snapcount);
- $datalen = 3 * 4;
+
+ if ( ! defined $table->{0} ) {
+ print "No current snapshot in table! First make one\n";
+ return ;
+ }
+ $data = pack("ii", $snaptableno, $snapcount);
+ $datalen = 2 * 4;
foreach my $time (sort keys %{$table}) {
$data .= pack("Ii", $time, $table->{$time});
$datalen += 8;
my $cl = length($data);
my $add = pack("p", $data);
print "type $type (len $len), datalen $datalen ($cl)\n";
- printf "Addr of data %x\n", $add;
- my $packed = pack("ipip", length($type), $type, $datalen, $data);
+ my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
+
+ my $rc = ioctl(DEV_OBD, &OBD_SNAP_SETTABLE, $packed);
+
+ if (!defined $rc) {
+ print STDERR "ioctl failed: $!\n";
+ } elsif ($rc eq "0 but true") {
+ print "Finished (success)\n";
+ } else {
+ print "ioctl returned error code $rc.\n";
+ }
+}
+
+
+sub SnapAttach {
+ my $err = 0;
+ my $type = "snap_obd";
+ my $snapdev = shift;
+ my $snapno = shift;
+ my $tableno = shift;
+ my $snapcount;
+ my $data;
+ my $datalen = 0;
+
+ $data = pack("iii", $snapdev, $snapno, $tableno);
+ $datalen = 3 * 4;
+
+ my $len = length($type);
+ my $cl = length($data);
+ my $add = pack("p", $data);
+ print "type $type (len $len), datalen $datalen ($cl)\n";
+ my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
my $rc = ioctl(DEV_OBD, &OBD_IOC_ATTACH, $packed);
goto again;
add:
- my $idx = &readl("enter new index: ");
- my $time = &readl("enter time (hit RET for \"now\"): ");
+ my $idx = &readl("enter index where you want this snapshot: ");
+ my $time = &readl("enter time or 'now' or 'current': ");
my $oldtime = SnapFindTimeFromIdx($idx, $table);
- delete $table->{$oldtime} if defined $oldtime;
- $time = time unless $time;
+ if (defined $oldtime) {
+ print "This already exists, first clean up\n";
+ goto again;
+ }
+
+ if ( $time eq 'now' ) {
+ $time = time;
+ } elsif ( $time eq 'current' ) {
+ $time = 0;
+ }
$table->{$time} = $idx;
goto again;
foreach $time ( sort keys %{$table} ) {
my $stime = localtime($time);
+ if ( ! $time ) {
+ $stime = "current";
+ }
printf "Time: %s -- Index %d\n", $stime, $table->{$time};
}
}
$table->{$time} = $index;
}
close FH;
+
+ PrintSnapShotTable($table);
+
return $table;
}