IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 20, 2009, 11:15:20 AM (17 years ago)
Author:
jhoblitt
Message:

merge neb_distrib_20081210

Location:
trunk/Nebulous-Server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Nebulous-Server

  • trunk/Nebulous-Server/lib/Nebulous/Server.pm

    r23698 r23932  
    99no warnings qw( uninitialized );
    1010
    11 our $VERSION = '0.15';
     11our $VERSION = '0.17';
    1212
    1313use base qw( Class::Accessor::Fast );
     
    1515use DBI;
    1616use Digest::SHA1 qw( sha1_hex );
    17 use File::Basename qw( dirname );
     17use File::Basename qw( basename dirname fileparse );
    1818use File::ExtAttr qw( setfattr );
    1919use File::Path;
    2020use File::Spec;
    21 use Log::Log4perl;
    22 use Nebulous::Keys qw( parse_neb_key parse_neb_volume );
     21use Log::Log4perl qw( :levels );
     22use Nebulous::Key qw( parse_neb_key parse_neb_volume );
    2323use Nebulous::Server::Config;
    2424use Nebulous::Server::Log;
    2525use Nebulous::Server::SQL;
    26 use Params::Validate qw( validate_pos SCALAR SCALARREF UNDEF );
     26use Params::Validate qw( validate validate_pos SCALAR SCALARREF UNDEF BOOLEAN );
    2727use URI::file;
    2828
     
    3737
    3838    # let Nebulous::Server::Config validate our params
    39     my $config = Nebulous::Server::Config->init( @_ );
     39    my $config = Nebulous::Server::Config->new( @_ );
     40
     41    return $class->new_from_config($config);
     42}
     43
     44
     45sub new_from_config
     46{
     47    my ($class, $config) = @_;
    4048
    4149    # log4perl is not avaliable until we call init()
    4250    Nebulous::Server::Log->init($config);
    4351    my $log = Log::Log4perl::get_logger( "Nebulous::Server" );
     52    $log->level($config->trace);
    4453
    4554    my $sql = Nebulous::Server::SQL->new;
     
    5261    $self->config($config);
    5362
    54     # ask for the db handle as a means of validating the database parameters
    55     $self->db;
    56 
    5763    $log->debug( "leaving" );
    58    
     64
    5965    return $self;
    6066}
    6167
    62 
    63 sub db
    64 {
    65     my $self = shift;
    66 
    67     if (@_) {
    68         $self->{db} = $_[0];
    69         return $self;
    70     }
     68# EAM : In the 'distributed' version of Nebulous, there is a collection of N databases
     69# the db_index uniquely defines the db used by a given key
     70sub _db_index_for_key
     71{
     72    my ($self, $key) = @_;
     73
     74    my $config  = $self->config;
     75
     76    my $db_index = 0;
     77    die "key not defined" unless defined $key;
     78
     79    # hash the key to select the correct database instance
     80    # only use the first 8 hex chars... have to be careful to avoid an int
     81    # overflow here
     82
     83    # hash only the directory component of the path and not the filename
     84    my $path = dirname($key->path);
     85    $db_index = unpack("h8", sha1_hex($path)) % $config->n_db;
     86
     87    return $db_index;
     88}
     89
     90sub _db_for_index
     91{
     92    my ($self, $db_index) = @_;
    7193
    7294    my $log     = $self->log;
     
    7496    my $config  = $self->config;
    7597
     98    # lookup to see if we have a stored dbh for this database
     99    my $dbh = $self->{dbs}[$db_index];
    76100    # if the dbh is still alive, return it
    77     if (defined $self->{db} and $self->{db}->ping) {
     101    if (defined $dbh and $dbh->ping) {
    78102        $log->debug("db handle is still alive");
    79         return $self->{db};
     103        return $dbh;
    80104    }
    81105    # otherwise create a new connection
    82106    $log->debug("db handle is dead/unopened");
     107
     108    # lookup database info
     109    my $db_config = $config->db($db_index);
     110    die "can't find database configuration info for database # $db_index"
     111        unless $db_config;
    83112
    84113    # if we're running under mod_perl & Apache::DBI is loaded we want to
     
    87116    # processes and the database might have gone away on us.  Apache::DBI will
    88117    # take care of getting a valid dbh back.
    89     my $db;
    90118    eval {
    91         $db = DBI->connect_cached(
    92             $config->dsn,
    93             $config->dbuser,
    94             $config->dbpasswd,
     119        $dbh = DBI->connect_cached(
     120            $db_config->dsn,
     121            $db_config->dbuser,
     122            $db_config->dbpasswd,
    95123            {
    96124                RaiseError => 1,
     
    100128        );
    101129
    102         $db->do( $sql->set_transaction_model );
    103         $log->debug( "connected to database: ", sub { $db->data_sources; } );
    104         $db->commit;
     130        $dbh->do( $sql->set_transaction_model );
     131        $log->debug( "connected to database: ", sub { $dbh->data_sources; } );
     132        $dbh->commit;
    105133        $log->debug("commit");
    106134    };
    107135    if ( $@ ) {
    108         $db->rollback if $db;
     136        $dbh->rollback if $dbh;
    109137        $log->debug("rollback");
    110138        $log->logdie( "database error: $@" );
    111139    }
    112140
    113     $self->{db} = $db;
    114 
    115     return $db;
    116 }
    117 
     141    $self->{dbs}[$db_index] = $dbh;
     142
     143    return $dbh;
     144}
     145
     146sub db
     147{
     148    my $self = shift;
     149
     150    my ($key) = validate_pos(@_,
     151        {
     152            isa => 'Nebulous::Key',
     153        },
     154    );
     155
     156    my $log     = $self->log;
     157    my $sql     = $self->sql;
     158    my $config  = $self->config;
     159
     160    die "key not defined" unless defined $key;
     161    my $db_index = $self->_db_index_for_key($key);
     162
     163    my $dbh = $self->_db_for_index($db_index);
     164    return $dbh;
     165}
    118166
    119167sub create_object
     
    138186    );
    139187
    140     my $log = $self->log;
    141     my $sql = $self->sql;
    142     my $db  =$self->db;
    143 
    144     $log->debug( "entered - @_" );
    145 
    146188    # vol_name overrides the key implied volume
    147189    $key = parse_neb_key($key, $vol_name);
    148190    $vol_name = $key->volume;
    149191
     192    my $log = $self->log;
     193    my $sql = $self->sql;
     194    my $db  = $self->db($key);
     195
     196    $log->debug( "entered - @_" );
     197
    150198    # the key's volume can't be validiated on input for this method so we have
    151199    # to check it after parsing the key
    152200    if (defined $vol_name
    153         and not $self->_is_valid_volume_name($key->volume)) {
     201        and not $self->_is_valid_volume_name($key, $key->volume)) {
    154202        if ($key->soft_volume) {
    155203            $log->warn( "$vol_name is not a known volume name" );
     
    161209       
    162210    my ($vol_id, $vol_host, $vol_path, $vol_xattr)
    163         = $self->_get_storage_volume($vol_name, $key->soft_volume);
     211        = $self->_get_storage_volume($key, $vol_name, $key->soft_volume);
     212
     213    my $parent_id = $self->_resolve_dir_parent_id(key => $key, create => 1);
    164214
    165215    my $uri;
     
    169219                # create storage_object
    170220                my $query = $db->prepare_cached( $sql->new_object );
    171                 $query->execute('NULL', $key->path);
     221                $query->execute('NULL', $key->path, basename($key->path), $parent_id);
    172222            }
    173223
     
    215265
    216266            # TODO add some stuff here to retry if unsucessful
    217             $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr);
     267            $uri = $self->_create_empty_instance_file($key, $so_id, $ins_id, $vol_path, $vol_xattr);
    218268            $log->debug("created $uri on volume ID: $vol_id");
    219269
     
    247297
    248298
     299sub _resolve_dir_parent_id
     300{
     301    my $self = shift;
     302
     303    my %p = validate(@_,
     304        {
     305            key     => {
     306                isa         => 'Nebulous::Key',
     307            },
     308            create  => {
     309                type        => BOOLEAN,
     310                optional    => 1,
     311                default     => undef,
     312            },
     313            # return dir_id instead of parent_id
     314            dir_id  => {
     315                type        => BOOLEAN,
     316                optional    => 1,
     317                default     => undef,
     318            },
     319        }
     320    );
     321
     322    my $key = $p{key};
     323
     324    my $log = $self->log;
     325    my $sql = $self->sql;
     326    my $db  = $self->db($key);
     327
     328    $log->debug( "entered - @_" );
     329
     330    # no path means '/', which has a dir_id & parent_id of 1
     331    return 1 if $key->path eq '';
     332
     333    # resolve parent directory
     334    my @dirs;
     335
     336    # File::Spec->splitpath was causing ->splitdir to always an extra dir
     337    # named "" because of a trailing /
     338    unless ($p{dir_id}) {
     339        @dirs = File::Spec->splitdir(dirname($key->path));
     340    } else {
     341        @dirs = File::Spec->splitdir($key->path);
     342    }
     343    # dirname returns "." if there is no dir component to the path, we have
     344    # to filter this out
     345    @dirs = grep(!/^\.$/, @dirs);
     346
     347    $log->debug("looking for dirs - ", join(" : ", @dirs), "\n");
     348
     349    # start at the root dir; '/' == 1
     350    my $parent_id = 1;
     351    my $dir_id;
     352TRANS: while (1) {
     353        eval {
     354            foreach my $dir (@dirs) {
     355                $dir_id = undef;
     356                {
     357                    my $query = $db->prepare_cached($sql->get_directory);
     358                    $query->execute($parent_id, $dir);
     359                    if ($query->rows) {
     360                        $dir_id = $query->fetchrow_hashref->{'dir_id'};
     361                        $log->debug("resolved $dir to dir_id: $dir_id");
     362                    }
     363                    $query->finish;
     364                }
     365
     366                # if we found a dir_id, a row for this directory already exists
     367                if (defined $dir_id) {
     368                    $parent_id = $dir_id;
     369                    # note that you can't exit an eval {} with next
     370                    next;
     371                }
     372
     373                # else dir doesn't exist
     374                unless ($p{create}) {
     375                    # resolution failed
     376                    $parent_id = undef;
     377                    last;
     378                }
     379
     380                {
     381                    # dir doesn't exist, create it
     382                    my $query = $db->prepare_cached($sql->new_directory);
     383                    $query->execute($dir, $parent_id);
     384                }
     385
     386                # get the dir_id of the new directory entry
     387                {
     388                    my $query = $db->prepare_cached($sql->last_insert_id);
     389                    $query->execute();
     390
     391                    # the new dir_id will be the parent_id of the next
     392                    # descendent directory
     393                    ($parent_id) = $query->fetchrow_array;
     394                    $query->finish;
     395                }
     396                $log->logdie("failed to get LAST_INSERT_ID()")
     397                    unless $parent_id;
     398
     399                $db->commit;
     400            }
     401        };
     402        if ($@) {
     403            $db->rollback;
     404            $log->debug("rollback");
     405            if ($@ =~ /Deadlock found/) {
     406                $log->warn("database deadlock retrying transaction: $@");
     407                redo TRANS;
     408            }
     409            $log->logdie("error: $@");
     410        }
     411        last;
     412    }
     413
     414    $log->debug("leaving");
     415
     416    return $p{dir_id} ? $dir_id : $parent_id;
     417}
     418
     419
    249420sub rename_object
    250421{
     
    266437        },
    267438    );
    268 
    269     my $log = $self->log;
    270     my $sql = $self->sql;
    271     my $db  =$self->db;
    272 
    273     $log->debug("entered - @_");
    274439
    275440    # ignore volumes
    276441    $key    = parse_neb_key($key);
    277442    $newkey = parse_neb_key($newkey);
     443
     444    my $log = $self->log;
     445    my $sql = $self->sql;
     446    my $db  = $self->db($key);
     447
     448    $log->debug("entered - @_");
     449
     450    # XXX this may require database migration in the future
     451    unless ($self->_db_index_for_key($key)
     452         == $self->_db_index_for_key($newkey)) {
     453        $log->logdie("can not rename objects across distributed database boundaries");
     454    }
    278455
    279456TRANS: while (1) {
     
    282459            my $query = $db->prepare_cached($sql->rename_object);
    283460            # this SQL statment takes the new key name as the first param
    284             my $rows = $query->execute($newkey->path, $key->path);
     461            my $rows = $query->execute($newkey->path, basename($newkey->path), $self->_resolve_dir_parent_id(key => $newkey, create => 1), $key->path);
    285462
    286463            # if we affected more then one row something very bad has happened.
     
    310487}
    311488
    312 
    313489sub swap_objects
    314490{
     
    329505        },
    330506    );
    331 
    332     my $log = $self->log;
    333     my $sql = $self->sql;
    334     my $db  =$self->db;
    335 
    336     $log->debug("entered - @_");
    337507
    338508    # ignore volumes
     
    340510    $key2 = parse_neb_key($key2);
    341511
    342     # order of operations for the swap:
     512    my $log = $self->log;
     513    my $sql = $self->sql;
     514
     515    my $dbidx1 = $self->_db_index_for_key($key1);
     516    my $dbidx2 = $self->_db_index_for_key($key2);
     517    die "cannot swap keys not stored on the same database" unless ($dbidx1 == $dbidx2);
     518
     519    my $dbh1 = $self->_db_for_index($dbidx1);
     520    my $dbh2 = $self->_db_for_index($dbidx2);
     521    die "different db handles for the same db?" unless ($dbh1 == $dbh2);
     522
     523    $log->debug("entered - @_");
     524
     525    # order of operations for the swap with a single db is:
    343526    # key1 -> key1.swap
    344527    # key2 -> key1
    345528    # key1.swap -> key2
    346529
    347 TRANS: while (1) {
     530    my $db = $dbh1;
     531  TRANS: while (1) {
    348532        eval {
    349533            {
    350                 # key1 -> key1.swap
    351                 my $query = $db->prepare_cached($sql->rename_object);
    352                 # this SQL statment takes the new key name as the first param
    353                 my $rows = $query->execute($key1->path . ".swap", $key1->path);
    354 
    355                 # if we affected more then one row something very bad has happened.
    356                 unless ($rows == 1) {
    357                     $query->finish;
    358                     $log->logdie("affected row count is $rows instead of 1");
    359                 }
    360             }
    361 
    362             {
    363                 # key2 -> key1
    364                 my $query = $db->prepare_cached($sql->rename_object);
    365                 # this SQL statment takes the new key name as the first param
    366                 my $rows = $query->execute($key1->path, $key2->path);
    367 
    368                 # if we affected more then one row something very bad has happened.
    369                 unless ($rows == 1) {
    370                     $query->finish;
    371                     $log->logdie("affected row count is $rows instead of 1");
    372                 }
    373             }
    374 
    375             {
    376                 # key1.swap -> key2
    377                 my $query = $db->prepare_cached($sql->rename_object);
    378                 # this SQL statment takes the new key name as the first param
    379                 my $rows = $query->execute($key2->path, $key1->path . ".swap");
    380 
    381                 # if we affected more then one row something very bad has happened.
    382                 unless ($rows == 1) {
    383                     $query->finish;
    384                     $log->logdie("affected row count is $rows instead of 1");
    385                 }
    386             }
     534              # key1 -> key1.swap
     535              my $query = $db->prepare_cached($sql->rename_object);
     536              # this SQL statment takes the new key name as the first param
     537              # XXX currently using a bogus dir_id -- this may cause a problem
     538              # someday but it's unlikley as it's contained entirely in the
     539              # transaction
     540              my $rows = $query->execute($key1->path . ".swap", basename($key1->path) . ".swap", 1, $key1->path);
     541
     542              # if we affected more then one row something very bad has happened.
     543              unless ($rows == 1) {
     544                  $query->finish;
     545                  $log->logdie("affected row count is $rows instead of 1");
     546              }
     547          }
     548
     549          {
     550              # key2 -> key1
     551              my $query = $db->prepare_cached($sql->rename_object);
     552              # this SQL statment takes the new key name as the first param
     553              my $rows = $query->execute($key1->path, basename($key1->path), $self->_resolve_dir_parent_id(key => $key1, create => 1), $key2->path);
     554
     555              # if we affected more then one row something very bad has happened.
     556              unless ($rows == 1) {
     557                  $query->finish;
     558                  $log->logdie("affected row count is $rows instead of 1");
     559              }
     560          }
     561
     562          {
     563              # key1.swap -> key2
     564              my $query = $db->prepare_cached($sql->rename_object);
     565              # this SQL statment takes the new key name as the first param
     566              my $rows = $query->execute($key2->path, basename($key2->path), $self->_resolve_dir_parent_id(key => $key2, create => 1), $key1->path . ".swap");
     567
     568              # if we affected more then one row something very bad has happened.
     569              unless ($rows == 1) {
     570                  $query->finish;
     571                  $log->logdie("affected row count is $rows instead of 1");
     572              }
     573          }
    387574
    388575            $db->commit;
     
    398585            $log->logdie("database error: $@");
    399586        }
    400         last;
    401     }
     587      last;
     588  }
    402589
    403590    $log->debug("leaving");
     
    406593}
    407594
     595# EAM : from JH, below is a possible option to swap instances across
     596# dbs.  I recommend that this action be disallowed, and instead such
     597# operations be implemented only as a combination of copy and delete
     598
     599# order of operations for the swap between two dbs is:
     600# key1 start transaction
     601# key1 -> read all instances
     602# key1 -> remove all instances
     603# key2 start transaction
     604# key2 -> read all instances
     605# key2 -> remove all instances
     606# key1 -> insert key 2 instances
     607# key2 -> insert key 1 instances
     608# key1,2 commit
    408609
    409610sub replicate_object
     
    440641    # then we should throw an error
    441642
    442     my $log = $self->log;
    443     my $sql = $self->sql;
    444     my $db  =$self->db;
    445 
    446     $log->debug("entered - @_");
    447 
    448643    # vol_name overrides the key implied volume
    449644    $key = parse_neb_key($key, $vol_name);
    450645    $vol_name = $key->volume;
    451646
     647    my $log = $self->log;
     648    my $sql = $self->sql;
     649    my $db  = $self->db($key);
     650
     651    $log->debug("entered - @_");
     652
    452653    if (defined $vol_name
    453         and not $self->_is_valid_volume_name($key->volume)) {
     654        and not $self->_is_valid_volume_name($key, $key->volume)) {
    454655        if ($key->soft_volume) {
    455656            $log->warn( "$vol_name is not a known volume name" );
     
    463664    if (defined $vol_name) {
    464665        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    465             = $self->_get_storage_volume($vol_name);
     666            = $self->_get_storage_volume($key, $vol_name);
    466667    } else {
    467668        ($vol_id, $vol_host, $vol_path, $vol_xattr)
     
    508709
    509710            # TODO add some stuff here to retry if unsucessful
    510             $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr);
     711            # XXX if this fails, it should try to generate the
     712            # instance on another volume (unless !$soft_volume)
     713            $uri = $self->_create_empty_instance_file($key, $so_id, $ins_id, $vol_path, $vol_xattr);
    511714
    512715            {
     
    561764    );
    562765
    563     my $log = $self->log;
    564     my $sql = $self->sql;
    565     my $db  =$self->db;
    566 
    567     $log->debug( "entered - @_" );
    568 
    569766    # ignore volume
    570767    $key = parse_neb_key($key);
     768
     769    my $log = $self->log;
     770    my $sql = $self->sql;
     771    my $db  = $self->db($key);
     772
     773    $log->debug( "entered - @_" );
    571774
    572775    my $so_id;
     
    671874    );
    672875
    673     my $log = $self->log;
    674     my $sql = $self->sql;
    675     my $db  =$self->db;
    676 
    677     $log->debug( "entered - @_" );
    678 
    679876    # ignore volume
    680877    $key = parse_neb_key($key);
     878
     879    my $log = $self->log;
     880    my $sql = $self->sql;
     881    my $db  = $self->db($key);
     882
     883    $log->debug( "entered - @_" );
    681884
    682885    my $so_id;
     
    790993    );
    791994
    792     my $log = $self->log;
    793     my $sql = $self->sql;
    794     my $db  =$self->db;
    795 
    796     $log->debug("entered - @_");
    797 
    798995    # ignore volume
    799996    $key = parse_neb_key($key);
     997
     998    my $log = $self->log;
     999    my $sql = $self->sql;
     1000    my $db  = $self->db($key);
     1001
     1002    $log->debug("entered - @_");
    8001003
    8011004TRANS: while (1) {
     
    8641067    );
    8651068
    866     my $log = $self->log;
    867     my $sql = $self->sql;
    868     my $db  =$self->db;
    869 
    870     $log->debug("entered - @_");
    871 
    8721069    # ignore volume
    8731070    $key = parse_neb_key($key);
     1071
     1072    my $log = $self->log;
     1073    my $sql = $self->sql;
     1074    my $db  = $self->db($key);
     1075
     1076    $log->debug("entered - @_");
    8741077
    8751078    my $value;
     
    9171120    );
    9181121
    919     my $log = $self->log;
    920     my $sql = $self->sql;
    921     my $db  =$self->db;
    922 
    923     $log->debug("entered - @_");
    924 
    9251122    # ignore volume
    9261123    $key = parse_neb_key($key);
     1124
     1125    my $log = $self->log;
     1126    my $sql = $self->sql;
     1127    my $db  = $self->db($key);
     1128
     1129    $log->debug("entered - @_");
    9271130
    9281131    my @xattrs;
     
    9601163    );
    9611164
    962     my $log = $self->log;
    963     my $sql = $self->sql;
    964     my $db  =$self->db;
    965 
    966     $log->debug("entered - @_");
    967 
    9681165    # ignore volume
    9691166    $key = parse_neb_key($key);
     1167
     1168    my $log = $self->log;
     1169    my $sql = $self->sql;
     1170    my $db  = $self->db($key);
     1171
     1172    $log->debug("entered - @_");
    9701173
    9711174TRANS: while (1) {
     
    10011204}
    10021205
    1003 
     1206# loop over all db_index values, passing db_index to each call
    10041207sub find_objects
    10051208{
    10061209    my $self = shift;
    10071210
    1008     my ( $pattern ) = validate_pos( @_,
     1211    my ($pattern) = validate_pos( @_,
    10091212        {
    10101213            type        => SCALAR,
     
    10131216    );
    10141217
    1015     my $log = $self->log;
    1016     my $sql = $self->sql;
    1017     my $db  =$self->db;
     1218    $pattern = parse_neb_key($pattern);
     1219
     1220    my $log = $self->log;
    10181221
    10191222    $log->debug( "entered - @_" );
    10201223
    1021     unless ($pattern) {
     1224    unless (defined $pattern) {
    10221225        $log->debug( "leaving" );
    10231226        $log->logdie("no keys found");
    10241227    }
    10251228
    1026     # attempt to strip off neb:// if it exists
    1027     $pattern =~ s|^neb:||;
    1028 
     1229    my @keys = ();
     1230    my $n_dbs = $self->config->n_db();
     1231    for (my $index = 0; $index < $n_dbs; $index ++) {
     1232        my $newkeys = $self->_find_objects_for_index($index, $pattern);
     1233        push @keys, @$newkeys;
     1234    }
     1235    $log->logdie("no keys found") unless ( scalar @keys );
     1236
     1237    $log->debug( "leaving" );
     1238
     1239    return \@keys;
     1240}
     1241
     1242# find matching objects from the given server
     1243sub _find_objects_for_index
     1244{
     1245
     1246    my $self    = shift;
     1247    my $index   = shift;
     1248    my $key     = shift;
     1249
     1250    my $log = $self->log;
     1251    my $sql = $self->sql;
     1252    my $db  = $self->_db_for_index($index);
     1253
     1254    $log->debug( "entered - @_" );
     1255
     1256    # first check to see if the key is an exact match
    10291257    my @keys;
    10301258    eval {
    1031         my $query = $db->prepare_cached( $sql->find_objects );
    1032         $query->execute( $pattern );
     1259        $log->debug("trying for an exact key match with $key");
     1260        my $query = $db->prepare_cached( $sql->find_object_by_ext_id );
     1261        $query->execute( $key->path );
     1262        if ($query->rows) {
     1263            my $ext_id = $query->fetchrow_hashref->{'ext_id'};
     1264            $log->debug( "pattern has an exact match" );
     1265            push @keys, $ext_id;
     1266        } else {
     1267            $log->debug("no exact match for key");
     1268        }
     1269        $query->finish;
     1270    };
     1271    if ($@) {
     1272        $db->rollback;
     1273        $log->logdie("database error: $@");
     1274    }
     1275
     1276    if (scalar @keys) {
     1277        # it was an exact match, so stop here
     1278        $log->debug("leaving");
     1279
     1280        return \@keys;
     1281    }
     1282
     1283    # else, assume it's a directory
     1284    my $dir_id = $self->_resolve_dir_parent_id(key => $key, dir_id => 1);
     1285    unless (defined $dir_id) {
     1286        $log->logdie("pattern $key does not match any key or directory");
     1287    }
     1288
     1289    eval {
     1290        $log->debug("trying for a directory match under dir: $dir_id");
     1291        my $query = $db->prepare_cached( $sql->find_object_by_dir_id );
     1292        $query->execute( $dir_id );
    10331293
    10341294        while ( my $row = $query->fetchrow_hashref ) {
    10351295            my $key = $row->{ 'ext_id' };
    10361296            push @keys, $key if $key;
     1297            $log->debug( "matched $key" ) if $key;
    10371298        }
    10381299    };
    10391300    $log->logdie("database error: $@") if $@;
    1040 
    1041     $log->logdie("no keys found") unless ( scalar @keys );
    10421301
    10431302    $log->debug( "leaving" );
     
    10711330    );
    10721331
    1073     my $log = $self->log;
    1074     my $sql = $self->sql;
    1075     my $db  =$self->db;
    1076 
    1077     $log->debug("entered - @_");
    1078 
    10791332    # vol_name overrides the key implied volume
    10801333    $key = parse_neb_key($key, $vol_name);
    10811334    $vol_name = $key->volume;
    10821335
     1336    my $log = $self->log;
     1337    my $sql = $self->sql;
     1338    my $db  = $self->db($key);
     1339
     1340    $log->debug("entered - @_");
     1341
    10831342    # the key's volume can't be validiated on input for this method so we have
    10841343    # to check it after parsing the key
    10851344    if (defined $vol_name
    1086         and not $self->_is_valid_volume_name($key->volume)) {
     1345        and not $self->_is_valid_volume_name($key, $key->volume)) {
    10871346        if ($key->soft_volume) {
    10881347            $log->warn( "$vol_name is not a known volume name" );
     
    11441403    my $self = shift;
    11451404
    1146     my ( $uri ) = validate_pos( @_,
     1405    my ($key, $uri) = validate_pos( @_,
     1406        {
     1407            type        => SCALAR,
     1408            callbacks   => {
     1409                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
     1410            },
     1411        },
    11471412        {
    11481413            type => SCALAR|SCALARREF,
     
    11501415    );
    11511416
    1152     my $log = $self->log;
    1153     my $sql = $self->sql;
    1154     my $db  =$self->db;
     1417    # ignore volume
     1418    $key = parse_neb_key($key);
     1419
     1420    my $log = $self->log;
     1421    my $sql = $self->sql;
     1422    my $db  = $self->db($key);
    11551423
    11561424    $log->debug( "entered - @_" );
     
    12441512    );
    12451513
    1246     my $log = $self->log;
    1247     my $sql = $self->sql;
    1248     my $db  =$self->db;
    1249 
    1250     $log->debug("entered - @_");
    1251 
    12521514    # ignore volume
    12531515    $key = parse_neb_key($key);
     1516
     1517    my $log = $self->log;
     1518    my $sql = $self->sql;
     1519    my $db  = $self->db($key);
     1520
     1521    $log->debug("entered - @_");
    12541522
    12551523    my $stat;
     
    12721540}
    12731541
    1274 
     1542# this should have a 'db_index' as an argument
    12751543sub mounts
    12761544{
     1545    # XXX: this will only pull the mounts from one db
     1546    # XXX: loop over db_index and generate a single unique list
     1547    # XXX: or report mount info for each db server
    12771548    my $self = shift;
    12781549
     
    12811552    my $log = $self->log;
    12821553    my $sql = $self->sql;
    1283     my $db  =$self->db;
     1554    my $db  = $self->_db_for_index(0); # XXX fix as above
    12841555
    12851556    $log->debug("entered - @_");
     
    13101581    my $self = shift;
    13111582
    1312     my $log = $self->log;
    1313     my $sql = $self->sql;
    1314     my $db  = $self->db;
     1583    my ($key, $name, $soft_volume) = @_;
     1584
     1585    my $log = $self->log;
     1586    my $sql = $self->sql;
     1587    my $db  = $self->db($key);
    13151588
    13161589    no warnings qw( uninitialized );
    13171590    $log->debug( "entered - @_" );
    13181591    use warnings;
    1319 
    1320     my ($name, $soft_volume) = @_;
    13211592
    13221593    my ($vol_id, $vol_host, $vol_path, $xattr);
     
    13351606                # find it, fall back to any volume
    13361607                if ($soft_volume) {
    1337                     ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume;
     1608                    ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume($key);
    13381609                    return; # this just returns out of the eval not from the subroutine
    13391610                }
     
    13751646    my $self = shift;
    13761647
    1377     my $log = $self->log;
    1378     my $sql = $self->sql;
    1379     my $db  =$self->db;
     1648    my $key = shift;
     1649
     1650    my $log = $self->log;
     1651    my $sql = $self->sql;
     1652    my $db  = $self->db($key);
    13801653
    13811654    no warnings qw( uninitialized );
    13821655    $log->debug( "entered - @_" );
    13831656    use warnings;
    1384 
    1385     my $key = shift;
    1386 
    1387     $key = parse_neb_key($key);
    13881657
    13891658    my ($vol_id, $vol_host, $vol_path, $xattr);
     
    14231692    my ($self, $key) = @_;
    14241693
    1425     my $log = $self->log;
    1426     my $sql = $self->sql;
    1427     my $db  =$self->db;
    1428 
    14291694    $key = parse_neb_key($key);
     1695
     1696    my $log = $self->log;
     1697    my $sql = $self->sql;
     1698    my $db  = $self->db($key);
    14301699
    14311700    my $ext_id;
     
    14521721sub _is_valid_volume_name
    14531722{
    1454     my ($self, $vol_name) = @_;
    1455 
    1456     my $log = $self->log;
    1457     my $sql = $self->sql;
    1458     my $db  =$self->db;
    1459 
     1723    my ($self, $key, $vol_name) = @_;
     1724
     1725    $key = parse_neb_key($key);
    14601726    my $volume_info = parse_neb_volume($vol_name);
     1727
     1728    my $log = $self->log;
     1729    my $sql = $self->sql;
     1730    my $db  = $self->db($key);
    14611731
    14621732    $vol_name = $volume_info->{volume};
     
    14931763    my $log = $self->log;
    14941764    my $sql = $self->sql;
    1495     my $db  = $self->db;
     1765    my $db  = $self->db($key);
    14961766
    14971767    my $uri;
    14981768    eval {
    1499         my $storage_path = $self->_generate_storage_path($key, $vol_path);
    1500         my $storage_filename = $self->_generate_storage_filename($key, $ins_id);
     1769        my $storage_path = $self->_generate_storage_path($key->path, $vol_path);
     1770        my $storage_filename = $self->_generate_storage_filename($key->path, $ins_id);
    15011771        unless (-d $storage_path) {
    15021772            _retry(sub { mkpath(@_) }, $storage_path, 0, 0775)
     
    15071777        my $mode = [_retry(sub { stat($storage_path) } )]->[2] & 07777;
    15081778        unless ($mode == 0775) {
    1509             $log->error("$storage_path has the wrong permissions of: %04o", $mode);
     1779            $log->error("$storage_path has the wrong permissions of: %04x", $mode);
    15101780            _retry(sub { chmod(0775, $storage_path) }) or die "can't chmod $storage_path: $!";
    15111781        }
     
    15231793        my $path = $uri->file;
    15241794        die "can not set xattr on $path: $!"
    1525             unless (setfattr($path, 'user.nebulous_key', $key));
     1795            unless (setfattr($path, 'user.nebulous_key', $key->path));
    15261796    }
    15271797
     
    15791849
    15801850    my ($key, $vol_path) = @_;
    1581 
    1582     # if the key has '/' in it, hash only the dirname() component
    1583     if ($key =~ m|/|) {
    1584         $key = dirname($key);
    1585     }
    15861851
    15871852    # taken and modified from Cache::File::cache_file_path()
     
    16271892    my $log = $self->log;
    16281893    my $sql = $self->sql;
    1629     my $db  =$self->db;
     1894#    my $db  = $self->db;
    16301895
    16311896    $log->debug( "entered" );
    16321897
    1633     $self->db->disconnect;       
    1634 
    1635     $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
     1898# XXX do we need to loop over db_index?
     1899#    $self->db->disconnect;       
     1900
     1901#    $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
    16361902
    16371903    $log->debug( "leaving" );
Note: See TracChangeset for help on using the changeset viewer.