Genezzo::Contrib::Clustered::PrepUndo - Prepare undo file for Clustered Genezzo
Index
Code Index:
NAME

Genezzo::Contrib::Clustered::PrepUndo - Prepare undo file for Clustered Genezzo
SYNOPSIS

prepareUndo(gnz_home => "/dev/raw", undo_filename => "raw2");
DESCRIPTION

Creates or re-initializes undo file under GNZ_HOME. By default
file is named undo.und. File header contains basic information about
all other files in Genezzo installation. genprepundo.pl must
be run whenever a new file is added to the Genezzo installation.
Undo file format is documented in Clustered.pm.
FUNCTIONS

- prepareUndo(gnz_home => GNZ_HOME, undo_filename => UNDO_FILENAME,
number_of_processes => NUMBER_OF_PROCESSES,
undo_blocks_per_process => UNDO_BLOCKS_PER_PROCESS )
- gnz_home
-
Supply the location for the gnz_home installation. If
specified, it overrides the GNZ_HOME environment variable.
- undo_filename
-
Supply the name of the undo file. If not specified, it
defaults to undo.und for file system devices. It must
be specified for raw devices.
- number_of_processes
-
Specify the maximum number of processes supported by undo.
If not specified defaults to 256.
- undo_blocks_per_process
-
Specify the number of blocks (which list fileno-blockno pairs)
for a process. If not specified defaults to 220.
AUTHOR

Eric Rollins, rollins@acm.org
COPYRIGHT AND LICENSE

Copyright (c) 2005 Eric Rollins. All rights reserved.
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 2 of the License, or
any later version.
This program 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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Address bug reports and comments to rollins@acm.org
#!/usr/bin/perl
#
# PrepUndo.pm
#
# Initialize undo file for Clustered Genezzo
#
#
package Genezzo::Contrib::Clustered::PrepUndo;
use strict;
use warnings;
use Genezzo::GenDBI;
use Data::Dumper;
use Carp;
use Genezzo::Dict;
use Genezzo::Block::RDBlock;
use Genezzo::Block::Std;
use FreezeThaw;
use Genezzo::Util;
use Genezzo::Contrib::Clustered;
our $GZERR = sub {
my %args = (@_);
return
unless (exists($args{msg}));
my $warn = 0;
if (exists($args{severity}))
{
my $sev = uc($args{severity});
$sev = 'WARNING'
if ($sev =~ m/warn/i);
# don't print 'INFO' prefix
if ($args{severity} !~ m/info/i)
{
printf ("%s: ", $sev);
$warn = 1;
}
}
print $args{msg};
# add a newline if necessary
print "\n" unless $args{msg}=~/\n$/;
# carp $args{msg}
# if (warnings::enabled() && $warn);
};
sub MakeSQL
{
my $bigSQL;
($bigSQL = <<EOF_SQL) =~ s/^\#//gm;
#REM prepare database for Genezzo::Contrib::Clustered
#REM ATAThavok.sql and ATATsyshook.sql first
#insert into sys_hook (xid, pkg, hook, replace, xtype, xname, args, owner, creationdate, version) values (1000, 'Genezzo::BufCa::BCFile', '_filereadblock', 'ReadBlock_Hook', 'oo_require', 'Genezzo::Contrib::Clustered', 'ReadBlock', 'SYSTEM', TODAY, '1');
#insert into sys_hook (xid, pkg, hook, replace, xtype, xname, args, owner, creationdate, version) values (1001, 'Genezzo::BufCa::DirtyScalar', 'STORE', 'DirtyBlock_Hook', 'oo_require', 'Genezzo::Contrib::Clustered', 'DirtyBlock', 'SYSTEM', TODAY, '1');
#insert into sys_hook (xid, pkg, hook, replace, xtype, xname, args, owner, creationdate, version) values (1002, 'Genezzo::GenDBI', 'Kgnz_Commit', 'Commit_Hook', 'oo_require', 'Genezzo::Contrib::Clustered', 'Commit', 'SYSTEM', TODAY, '1');
#insert into sys_hook (xid, pkg, hook, replace, xtype, xname, args, owner, creationdate, version) values (1003, 'Genezzo::GenDBI', 'Kgnz_Rollback', 'Rollback_Hook', 'oo_require', 'Genezzo::Contrib::Clustered', 'Rollback', 'SYSTEM', TODAY, '1');
#insert into sys_hook (xid, pkg, hook, replace, xtype, xname, args, owner, creationdate, version) values (1003, 'Genezzo::GenDBI', 'Kgnz_Execute', 'Execute_Hook', 'oo_require', 'Genezzo::Contrib::Clustered', 'Execute', 'SYSTEM', TODAY, '1');
#insert into sys_hook (xid, pkg, hook, replace, xtype, xname, args, owner, creationdate, version) values (1004, 'Genezzo::BufCa::BCFile', '_init_filewriteblock', '_init_fwb_Hook', 'oo_require', 'Genezzo::Contrib::Clustered', '_init_filewriteblock', 'SYSTEM', TODAY, '1');
#commit;
#shutdown;
#REM restart gendba.pl from command line, so havok routines will be redefined
#quit;
EOF_SQL
my $now = Genezzo::Dict::time_iso8601();
$bigSQL =~ s/ATAT/\@/gm;
$bigSQL =~ s/TODAY/\'$now\'/gm;
my $pver = $Genezzo::Contrib::Clustered::VERSION;
$bigSQL =~ s/GPU_VERSION/$pver/gm;
$bigSQL = "REM Generated by " . __PACKAGE__ . " version " .
$pver . " on $now\nREM\n" . $bigSQL;
# print $bigSQL;
return $bigSQL;
}
my $glob_init;
my $glob_gnz_home;
my $glob_shutdown;
my $glob_id;
my $glob_defs;
sub prepareUndo
{
#my $self = shift;
my %optional = (
number_of_processes => 256,
undo_blocks_per_process => 220,
undo_filename => "undo.und"
);
my %required = (
);
my %args = (%optional,
@_);
return 0
unless (Validate(\%args, \%required));
my $glob_undo_filename = (exists($args{undo_filename}))
&& (defined($args{undo_filename}))
&& (length($args{undo_filename})) ? $args{undo_filename} : "";
my $glob_gnz_home = $args{gnz_home};
my $glob_procs = $args{number_of_processes}; # num of processes supported
# undo blocks per process
my $glob_blocks_per_proc = $args{undo_blocks_per_process};
my $dbh = Genezzo::GenDBI->connect($glob_gnz_home,
"NOUSER",
"NOPASSWORD",
{GZERR => $GZERR});
if(!defined($dbh)){
Carp::croak("failed connect");
}
$dbh->do("startup"); # start the database
#-----------------------------------------------------------------
# locate home
my $stmt = "select pref_value from _pref1 where pref_key='home'";
my $sth = $dbh->prepare($stmt);
if(!defined($sth)){
Carp::croak("failed prepare 2");
}
my $ret = $sth->execute();
if(!defined($ret)){
Carp::croak("failed execute 2");
}
my $ggg = $sth->fetchrow_hashref();
if(!defined($ggg)){
Carp::croak("zero rows 2");
}
my $pref_home = $ggg->{pref_value};
if ($glob_undo_filename eq ""){
if($pref_home eq "/dev/raw"){
print "ERROR: raw device -undo_filename required\n";
exit();
}else{
$glob_undo_filename = "undo.und";
}
}
#-----------------------------------------------------------------
# read per-file info
$stmt = "select fileidx,filename,blocksize,numblocks,tsid from _tsfiles";
$sth = $dbh->prepare($stmt);
if(!defined($sth)){
Carp::croak("failed prepare");
}
$ret = $sth->execute();
if(!defined($ret)){
Carp::croak("failed execute");
}
my $undoHeader = {
"procs" => $glob_procs,
"blocks_per_proc" => $glob_blocks_per_proc,
"files" => {}
};
while(1)
{
my $ggg = $sth->fetchrow_hashref();
last
unless(defined($ggg));
# look up header size in file FIXME
my $full_filename;
if($pref_home eq "/dev/raw"){
$full_filename = "$pref_home/$ggg->{filename}";
}else{
$full_filename = "$pref_home/ts/$ggg->{filename}";
}
$ggg->{full_filename} = $full_filename;
my $fh;
open($fh, "<$full_filename")
or die "open $full_filename failed: $!\n";
my ($hdrsize, $version, $blocksize, $h1) =
Genezzo::Util::FileGetHeaderInfo(filehandle => $fh,
filename => $full_filename);
$ggg->{hdrsize} = $hdrsize;
$undoHeader->{files}->{$ggg->{fileidx}} = $ggg;
}
#-----------------------------------------------------------------
my $dictobj = $dbh->{dictobj};
$dictobj->DictSetFileInfo(newkey => "undo_filename",
newval => $glob_undo_filename);
$dbh->do("commit");
my $full_filename;
if($pref_home eq "/dev/raw"){
$full_filename = "$pref_home/$glob_undo_filename";
}else{
$full_filename = "$pref_home/ts/$glob_undo_filename";
}
#-----------------------------------------------------------------
# store per-file info in file header block
my $frozen_undoHeader = FreezeThaw::freeze $undoHeader;
# construct an empty byte buffer
my $blocksize = $Genezzo::Block::Std::DEFBLOCKSIZE;
my $buff = "\0" x $blocksize;
my %tied_hash = ();
my $tie_val =
tie %tied_hash, 'Genezzo::Block::RDBlock', (refbufstr => \$buff,
blocksize =>
$blocksize);
my $newkey = $tie_val->HPush($frozen_undoHeader);
my $fh;
open($fh, ">$full_filename")
or die "open $full_filename failed: $!\n";
gnz_write ($fh, $buff, $blocksize)
== $blocksize
or die "bad write - file $full_filename : $! \n";
#-----------------------------------------------------------------
# mark process status block for each process as no outstanding transaction
my $i;
for($i = 0; $i < $glob_procs; $i++){
$buff = "-" x 10;
my $procstr = sprintf("%10d", $i);
$buff = $buff . $procstr;
$buff = $buff . ( "=" x ($blocksize - 20) );
gnz_write ($fh, $buff, $blocksize)
== $blocksize
or die "bad write - file $full_filename ($i): $! \n";
}
close $fh;
print "finished initialization of $full_filename.\n" ;
}
1;
__END__
# Below is stub documentation for your module. You better edit it!