IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 25, 2009, 2:00:56 PM (17 years ago)
Author:
eugene
Message:

merging changes from head

Location:
branches/eam_branches/20090522
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090522

  • branches/eam_branches/20090522/Nebulous-Server

  • branches/eam_branches/20090522/Nebulous-Server/lib/Nebulous/Server.pm

    r23932 r24557  
    1313use base qw( Class::Accessor::Fast );
    1414
     15use Cache::Memcached;
    1516use DBI;
    1617use Digest::SHA1 qw( sha1_hex );
     18use Fcntl ':mode';
    1719use File::Basename qw( basename dirname fileparse );
    1820use File::ExtAttr qw( setfattr );
     
    2729use URI::file;
    2830
    29 __PACKAGE__->mk_accessors(qw( log sql config ));
    30 
    31 use constant SUBPATH_DEPTH  => 2;
    32 use constant NFS_RETRIES    => 100;
     31__PACKAGE__->mk_accessors(qw( log sql config cache ));
     32
     33use constant SUBPATH_DEPTH      => 2;
     34use constant NFS_RETRIES        => 100;
     35use constant NFS_RETRY_WAIT     => 1;
     36use constant TRANS_RETRY_WAIT   => 1;
     37
     38# transaction restart/retry regex
     39my $trans_regex = qr/Deadlock Found|Lock wait timeout exceeded|try restarting transaction|Can't connect to MySQL server/i;
    3340
    3441sub new
     
    4552sub new_from_config
    4653{
    47     my ($class, $config) = @_;
     54    my $class = shift;
     55
     56    my ($config) = @_;
    4857
    4958    # log4perl is not avaliable until we call init()
     
    5160    my $log = Log::Log4perl::get_logger( "Nebulous::Server" );
    5261    $log->level($config->trace);
     62    $log->debug( "entered - @_" );
    5363
    5464    my $sql = Nebulous::Server::SQL->new;
    55 
    56     $log->debug( "entered - @_" );
    5765
    5866    my $self = bless {}, ref $class || $class;
     
    6068    $self->sql($sql);
    6169    $self->config($config);
     70    $self->cache(
     71        Cache::Memcached->new({
     72            servers => $config->memcached_servers,
     73       })
     74    );
     75#    $self->cache->set("foo", "bar") or die "set failed";
     76#    $self->cache->get("foo") or die "get failed";
     77    $log->logdie("at least one database must be defined") unless $config->n_db;
     78
     79    # cause a db session to be started
     80    $self->_db_for_index(0);
    6281
    6382    $log->debug( "leaving" );
     
    7089sub _db_index_for_key
    7190{
    72     my ($self, $key) = @_;
     91    my $self = shift;
     92
     93    my $log     = $self->log;
     94    $log->debug( "entered - @_" );
     95
     96    my ($key) = @_;
    7397
    7498    my $config  = $self->config;
    7599
    76100    my $db_index = 0;
    77     die "key not defined" unless defined $key;
     101    $log->logdie("key not defined") unless defined $key;
    78102
    79103    # hash the key to select the correct database instance
     
    85109    $db_index = unpack("h8", sha1_hex($path)) % $config->n_db;
    86110
     111    $log->debug("index is $db_index");
     112    $log->debug("leaving");
     113
    87114    return $db_index;
    88115}
     
    90117sub _db_for_index
    91118{
    92     my ($self, $db_index) = @_;
     119    my $self = shift;
    93120
    94121    my $log     = $self->log;
     122    $log->debug( "entered - @_" );
     123
     124    my ($db_index) = @_;
     125
    95126    my $sql     = $self->sql;
    96127    my $config  = $self->config;
     
    108139    # lookup database info
    109140    my $db_config = $config->db($db_index);
    110     die "can't find database configuration info for database # $db_index"
     141    $log->logdie("can't find database configuration info for db # $db_index")
    111142        unless $db_config;
    112143
     
    116147    # processes and the database might have gone away on us.  Apache::DBI will
    117148    # take care of getting a valid dbh back.
    118     eval {
    119         $dbh = DBI->connect_cached(
    120             $db_config->dsn,
    121             $db_config->dbuser,
    122             $db_config->dbpasswd,
    123             {
    124                 RaiseError => 1,
    125                 PrintError => 0,
    126                 AutoCommit => 0,
    127             },
    128         );
    129 
    130         $dbh->do( $sql->set_transaction_model );
    131         $log->debug( "connected to database: ", sub { $dbh->data_sources; } );
    132         $dbh->commit;
    133         $log->debug("commit");
    134     };
    135     if ( $@ ) {
    136         $dbh->rollback if $dbh;
    137         $log->debug("rollback");
    138         $log->logdie( "database error: $@" );
     149    TRANS: while (1) {
     150        eval {
     151            $dbh = DBI->connect_cached(
     152                $db_config->dsn,
     153                $db_config->dbuser,
     154                $db_config->dbpasswd,
     155                {
     156                    RaiseError => 1,
     157                    PrintError => 0,
     158                    AutoCommit => 0,
     159                },
     160            );
     161
     162            $dbh->do( $sql->set_transaction_model );
     163            $log->debug( "connected to database: ", sub { $dbh->data_sources; } );
     164            $dbh->commit;
     165            $log->debug("commit");
     166        };
     167        if ($@) {
     168            $dbh->rollback if $dbh;
     169            $log->debug("rollback") if $dbh;
     170            if ($@ =~ qr/Can't connect to MySQL server/) {
     171                $log->warn("database error, retrying transaction: $@");
     172                sleep TRANS_RETRY_WAIT;
     173                redo TRANS;
     174            }
     175            $log->logdie( "database error: $@" );
     176        }
     177        last;
    139178    }
    140179
    141180    $self->{dbs}[$db_index] = $dbh;
    142181
     182    $log->debug("leaving");
     183
    143184    return $dbh;
    144185}
     
    148189    my $self = shift;
    149190
     191    my $log     = $self->log;
     192    $log->debug( "entered - @_" );
     193
    150194    my ($key) = validate_pos(@_,
    151195        {
     
    154198    );
    155199
    156     my $log     = $self->log;
    157200    my $sql     = $self->sql;
    158201    my $config  = $self->config;
    159202
    160     die "key not defined" unless defined $key;
     203    $log->logdie("key not defined") unless defined $key;
    161204    my $db_index = $self->_db_index_for_key($key);
    162205
    163206    my $dbh = $self->_db_for_index($db_index);
     207
    164208    return $dbh;
    165209}
     
    168212{
    169213    my $self = shift;
     214
     215    my $log = $self->log;
     216    $log->debug( "entered - @_" );
    170217
    171218    my ($key, $vol_name) = validate_pos(@_,
     
    186233    );
    187234
     235    my $sql = $self->sql;
     236
    188237    # vol_name overrides the key implied volume
    189     $key = parse_neb_key($key, $vol_name);
     238    eval {
     239        $key = parse_neb_key($key, $vol_name);
     240    };
     241    $log->logdie("$@") if $@;
    190242    $vol_name = $key->volume;
    191243
    192     my $log = $self->log;
    193     my $sql = $self->sql;
    194244    my $db  = $self->db($key);
    195 
    196     $log->debug( "entered - @_" );
    197245
    198246    # the key's volume can't be validiated on input for this method so we have
     
    200248    if (defined $vol_name
    201249        and not $self->_is_valid_volume_name($key, $key->volume)) {
    202         if ($key->soft_volume) {
     250        unless ($key->hard_volume) {
    203251            $log->warn( "$vol_name is not a known volume name" );
    204252            $vol_name = undef;
    205253        } else {
    206             die "$vol_name is not a valid volume name"
     254           $log->logdie("$vol_name is not a valid volume name");
    207255        }
    208256    }
    209257       
    210258    my ($vol_id, $vol_host, $vol_path, $vol_xattr)
    211         = $self->_get_storage_volume($key, $vol_name, $key->soft_volume);
     259        = $self->_get_storage_volume($key, $vol_name, $key->hard_volume);
    212260
    213261    my $parent_id = $self->_resolve_dir_parent_id(key => $key, create => 1);
     
    282330            $db->rollback;
    283331            $log->debug("rollback");
    284             if ($@ =~ /Deadlock found/) {
    285                 $log->warn("database deadlock retrying transaction: $@");
     332            if ($@ =~ $trans_regex) {
     333                $log->warn("database error, retrying transaction: $@");
     334                sleep TRANS_RETRY_WAIT;
    286335                redo TRANS;
    287336            }
     
    291340    }
    292341
     342    # add new key to the cache
     343    $self->cache->set($key->path, 1) if defined $self->cache;
     344    $log->debug( "key added to cache" );
     345
    293346    $log->debug("leaving");
    294347
     
    300353{
    301354    my $self = shift;
     355
     356    my $log = $self->log;
     357    $log->debug( "entered - @_" );
    302358
    303359    my %p = validate(@_,
     
    322378    my $key = $p{key};
    323379
    324     my $log = $self->log;
    325380    my $sql = $self->sql;
    326381    my $db  = $self->db($key);
    327 
    328     $log->debug( "entered - @_" );
    329382
    330383    # no path means '/', which has a dir_id & parent_id of 1
     
    394447                    $query->finish;
    395448                }
    396                 $log->logdie("failed to get LAST_INSERT_ID()")
     449                die("failed to get LAST_INSERT_ID()")
    397450                    unless $parent_id;
    398451
    399                 $db->commit;
     452#                $db->commit;
    400453            }
    401454        };
     
    403456            $db->rollback;
    404457            $log->debug("rollback");
    405             if ($@ =~ /Deadlock found/) {
    406                 $log->warn("database deadlock retrying transaction: $@");
     458            if ($@ =~ $trans_regex) {
     459                $log->warn("database error, retrying transaction: $@");
     460                $parent_id = 1;
     461                sleep TRANS_RETRY_WAIT;
    407462                redo TRANS;
    408463            }
     464            if ($@ =~ qr/Duplicate entry/) {
     465                $log->warn("Duplicate database entry, retrying transaction: $@");
     466                $parent_id = 1;
     467                sleep TRANS_RETRY_WAIT;
     468                redo TRANS;
     469            }
    409470            $log->logdie("error: $@");
    410471        }
     
    421482{
    422483    my $self = shift;
     484
     485    my $log = $self->log;
     486    $log->debug("entered - @_");
    423487
    424488    my ($key, $newkey) = validate_pos(@_,
     
    438502    );
    439503
     504    my $sql = $self->sql;
     505
    440506    # ignore volumes
    441     $key    = parse_neb_key($key);
    442     $newkey = parse_neb_key($newkey);
    443 
    444     my $log = $self->log;
    445     my $sql = $self->sql;
     507    eval {
     508        $key = parse_neb_key($key);
     509    };
     510    $log->logdie("$@") if $@;
     511    eval {
     512        $newkey = parse_neb_key($newkey);
     513    };
     514    $log->logdie("$@") if $@;
     515
    446516    my $db  = $self->db($key);
    447 
    448     $log->debug("entered - @_");
    449517
    450518    # XXX this may require database migration in the future
     
    464532            unless ($rows == 1) {
    465533                $query->finish;
    466                 $log->logdie("affected row count is $rows instead of 1");
    467             }
     534                die("affected row count is $rows instead of 1");
     535            }
     536
     537            $self->cache->delete($key->path) if defined $self->cache;
     538            $self->cache->set($newkey->path, 1) if defined $self->cache;
    468539
    469540            $db->commit;
     
    473544            $db->rollback;
    474545            $log->debug("rollback");
    475             if ($@ =~ /Deadlock found/) {
    476                 $log->warn("database deadlock retrying transaction: $@");
     546            if ($@ =~ $trans_regex) {
     547                $log->warn("database error, retrying transaction: $@");
     548                sleep TRANS_RETRY_WAIT;
    477549                redo TRANS;
    478550            }
     
    491563    my $self = shift;
    492564
     565    my $log = $self->log;
     566    $log->debug("entered - @_");
     567
    493568    my ($key1, $key2) = validate_pos(@_,
    494569        {
     
    506581    );
    507582
     583    my $sql = $self->sql;
     584
    508585    # ignore volumes
    509     $key1 = parse_neb_key($key1);
    510     $key2 = parse_neb_key($key2);
    511 
    512     my $log = $self->log;
    513     my $sql = $self->sql;
     586    eval {
     587        $key1 = parse_neb_key($key1);
     588    };
     589    $log->logdie("$@") if $@;
     590    eval {
     591        $key2 = parse_neb_key($key2);
     592    };
     593    $log->logdie("$@") if $@;
    514594
    515595    my $dbidx1 = $self->_db_index_for_key($key1);
    516596    my $dbidx2 = $self->_db_index_for_key($key2);
    517     die "cannot swap keys not stored on the same database" unless ($dbidx1 == $dbidx2);
     597    $log->logdie("cannot swap keys not stored on the same database")
     598        unless ($dbidx1 == $dbidx2);
    518599
    519600    my $dbh1 = $self->_db_for_index($dbidx1);
    520601    my $dbh2 = $self->_db_for_index($dbidx2);
    521     die "different db handles for the same db?" unless ($dbh1 == $dbh2);
    522 
    523     $log->debug("entered - @_");
     602    $log->logdie("different db handles for the same db?")
     603        unless ($dbh1 == $dbh2);
    524604
    525605    # order of operations for the swap with a single db is:
     
    543623              unless ($rows == 1) {
    544624                  $query->finish;
    545                   $log->logdie("affected row count is $rows instead of 1");
     625                  die("affected row count is $rows instead of 1");
    546626              }
    547627          }
     
    556636              unless ($rows == 1) {
    557637                  $query->finish;
    558                   $log->logdie("affected row count is $rows instead of 1");
     638                  die("affected row count is $rows instead of 1");
    559639              }
    560640          }
     
    569649              unless ($rows == 1) {
    570650                  $query->finish;
    571                   $log->logdie("affected row count is $rows instead of 1");
     651                  die("affected row count is $rows instead of 1");
    572652              }
    573653          }
     
    579659            $db->rollback;
    580660            $log->debug("rollback");
    581             if ($@ =~ /Deadlock found/) {
    582                 $log->warn("database deadlock retrying transaction: $@");
     661            if ($@ =~ $trans_regex) {
     662                $log->warn("database error, retrying transaction: $@");
     663                sleep TRANS_RETRY_WAIT;
    583664                redo TRANS;
    584665            }
     
    612693    my $self = shift;
    613694
     695    my $log = $self->log;
     696    $log->debug("entered - @_");
     697
    614698    my ($key, $vol_name) = validate_pos(@_,
    615699        {
     
    633717    );
    634718
     719    my $sql = $self->sql;
     720
    635721    # if a volume name is explicity specified then we should make the
    636722    # replication onto that volume (even if there is alread an instance on that
     
    642728
    643729    # vol_name overrides the key implied volume
    644     $key = parse_neb_key($key, $vol_name);
     730    eval {
     731        $key = parse_neb_key($key, $vol_name);
     732    };
     733    $log->logdie("$@") if $@;
    645734    $vol_name = $key->volume;
    646735
    647     my $log = $self->log;
    648     my $sql = $self->sql;
    649736    my $db  = $self->db($key);
    650 
    651     $log->debug("entered - @_");
    652737
    653738    if (defined $vol_name
    654739        and not $self->_is_valid_volume_name($key, $key->volume)) {
    655         if ($key->soft_volume) {
     740        unless ($key->hard_volume) {
    656741            $log->warn( "$vol_name is not a known volume name" );
    657742            $vol_name = undef;
    658743        } else {
    659             die "$vol_name is not a valid volume name"
     744           $log->logdie("$vol_name is not a valid volume name");
    660745        }
    661746    }
     
    681766                unless ( $rows > 0 ) {
    682767                    $query->finish;
    683                     $log->logdie( "storage object does not exist" );
     768                    die( "storage object does not exist" );
    684769                }
    685770
     
    725810            $db->rollback;
    726811            # handle soft volumes
    727             if (defined $vol_name and defined $key->soft_volume) {
     812            if (defined $vol_name and not defined $key->hard_volume) {
    728813                $log->debug("retrying with 'any' volume");
    729814                return $self->replicate_object($key->path, 'any');
    730815            }
    731816            $log->debug("rollback");
    732             if ($@ =~ /Deadlock found/) {
    733                 $log->warn("database deadlock retrying transaction: $@");
     817            if ($@ =~ $trans_regex) {
     818                $log->warn("database error, retrying transaction: $@");
     819                sleep TRANS_RETRY_WAIT;
    734820                redo TRANS;
    735821            }
     
    739825    }
    740826
     827    # check to see if the user.mode xattr exists
     828    eval {
     829        my $mode = $self->getxattr_object("$key", 'user.mode');
     830        if (defined $mode) {
     831            $self->chmod_object("$key", $mode);
     832        }
     833    };
     834    if ($@) {
     835        unless ($@ =~ qr/user.mode does not exist/) {
     836            $log->logdie("error: $@");
     837        }
     838    }
     839
    741840    $log->debug("leaving");
    742841
     
    748847{
    749848    my $self = shift;
     849
     850    my $log = $self->log;
     851    $log->debug( "entered - @_" );
    750852
    751853    my ( $key, $type ) = validate_pos( @_,
     
    764866    );
    765867
     868    my $sql = $self->sql;
     869
    766870    # ignore volume
    767     $key = parse_neb_key($key);
    768 
    769     my $log = $self->log;
    770     my $sql = $self->sql;
     871    eval {
     872        $key = parse_neb_key($key);
     873    };
     874    $log->logdie("$@") if $@;
     875
    771876    my $db  = $self->db($key);
    772 
    773     $log->debug( "entered - @_" );
    774877
    775878    my $so_id;
     
    785888                unless ( $rows == 1 ) {
    786889                    $query->finish;
    787                     $log->logdie( "storage object does not exist" );
     890                    die( "storage object does not exist" );
    788891                }
    789892
     
    800903                # can't set a write lock if there are read locks
    801904                if ($write_lock) {
    802                     $log->logdie("can not write lock twice -- retry");
     905                    die("can not write lock twice -- retry");
    803906                }
    804907               
    805908                if ($read_lock > 0) {
    806                     $log->logdie("can not write lock after read lock -- retry");
     909                    die("can not write lock after read lock -- retry");
    807910                }
    808911
     
    813916                    # if we affected more then one row something very bad has happened.
    814917                    unless ($rows == 1) {
    815                         $log->logdie("affected row count is $rows instead of 1");
     918                        die("affected row count is $rows instead of 1");
    816919                    }
    817920
     
    820923                # can't set a read lock if there's a write lock
    821924                if ($write_lock) {
    822                     $log->logdie("can not read lock after write lock -- retry");
     925                    die("can not read lock after write lock -- retry");
    823926                }
    824927
     
    829932                    # if we affected more then one row something very bad has happened.
    830933                    unless ($rows == 1) {
    831                         $log->logdie("affected row count is $rows instead of 1");
     934                        die("affected row count is $rows instead of 1");
    832935                    }
    833936                }
     
    840943            $db->rollback;
    841944            $log->debug("rollback");
    842             if ($@ =~ /Deadlock found/) {
    843                 $log->warn("database deadlock retrying transaction: $@");
     945            if ($@ =~ $trans_regex) {
     946                $log->warn("database error, retrying transaction: $@");
     947                sleep TRANS_RETRY_WAIT;
    844948                redo TRANS;
    845949            }
     
    858962{
    859963    my $self = shift;
     964
     965    my $log = $self->log;
     966    $log->debug( "entered - @_" );
    860967
    861968    my ( $key, $type ) = validate_pos( @_,
     
    874981    );
    875982
     983    my $sql = $self->sql;
     984
    876985    # ignore volume
    877     $key = parse_neb_key($key);
    878 
    879     my $log = $self->log;
    880     my $sql = $self->sql;
     986    eval {
     987        $key = parse_neb_key($key);
     988    };
     989    $log->logdie("$@") if $@;
     990
    881991    my $db  = $self->db($key);
    882 
    883     $log->debug( "entered - @_" );
    884992
    885993    my $so_id;
     
    8951003                unless ($rows == 1) {
    8961004                    $query->finish;
    897                     $log->logdie("storage object does not exist");
     1005                    die("storage object does not exist");
    8981006                }
    8991007
     
    9091017                # can't remove a write lock if it doesn't exist
    9101018                if ($read_lock) {
    911                     $log->logdie("can not have a write lock under a read lock");
     1019                    die("can not have a write lock under a read lock");
    9121020                }
    9131021
    9141022                unless ($write_lock) {
    915                     $log->logdie("can not remove non-existant write lock");
     1023                    die("can not remove non-existant write lock");
    9161024                }
    9171025
     
    9221030                    # if we affected more then one row something very bad has happened.
    9231031                    unless ($rows == 1) {
    924                         $log->logdie("affected row count is $rows instead of 1");
     1032                        die("affected row count is $rows instead of 1");
    9251033                    }
    9261034                }
     
    9291037                # can't remove a read lock if there aren't any
    9301038                if ($write_lock) {
    931                     $log->logdie("can not have a read lock under a write lock");
     1039                    die("can not have a read lock under a write lock");
    9321040                }
    9331041                   
    9341042                if ($read_lock == 0) {
    935                     $log->logdie("can not remove non-existant read lock");
     1043                    die("can not remove non-existant read lock");
    9361044                }
    9371045
     
    9421050                    # if we affected more then one row something very bad has happened.
    9431051                    unless ($rows == 1) {
    944                         $log->logdie("affected row count is $rows instead of 1");
     1052                        die("affected row count is $rows instead of 1");
    9451053                    }
    9461054
     
    9531061            $db->rollback;
    9541062            $log->debug("rollback");
    955             if ($@ =~ /Deadlock found/) {
    956                 $log->warn("database deadlock retrying transaction: $@");
     1063            if ($@ =~ $trans_regex) {
     1064                $log->warn("database error, retrying transaction: $@");
     1065                sleep TRANS_RETRY_WAIT;
    9571066                redo TRANS;
    9581067            }
     
    9711080{
    9721081    my $self = shift;
     1082
     1083    my $log = $self->log;
     1084    $log->debug("entered - @_");
    9731085
    9741086    my ($key, $name, $value, $flags) = validate_pos(@_,
     
    9811093        {
    9821094            type        => SCALAR,
     1095            callbacks   => {
     1096                'xattr is in user. namespace'
     1097                    => sub { ($_[0]) =~ qr/^user\./ },
     1098            },
    9831099        },
    9841100        {
     
    9931109    );
    9941110
     1111    my $sql = $self->sql;
     1112
    9951113    # ignore volume
    996     $key = parse_neb_key($key);
    997 
    998     my $log = $self->log;
    999     my $sql = $self->sql;
     1114    eval {
     1115        $key = parse_neb_key($key);
     1116    };
     1117    $log->logdie("$@") if $@;
     1118
    10001119    my $db  = $self->db($key);
    1001 
    1002     $log->debug("entered - @_");
    10031120
    10041121TRANS: while (1) {
     
    10201137            if ($flags eq 'create') {
    10211138                unless ($rows == 1) {
    1022                     $log->logdie( "affected row count is $rows instead of 1" );
     1139                    die( "affected row count is $rows instead of 1" );
    10231140                }
    10241141            } else {
     
    10261143                # the case of a replace and 1 if the xattr didn't already exist.
    10271144                unless ($rows == 1 or $rows == 2) {
    1028                     $log->logdie( "affected row count is $rows instead of 2" );
     1145                    die( "affected row count is $rows instead of 2" );
    10291146                }
    10301147            }
     
    10361153            $db->rollback;
    10371154            $log->debug("rollback");
    1038             if ($@ =~ /Deadlock found/) {
    1039                 $log->warn("database deadlock retrying transaction: $@");
     1155            if ($@ =~ $trans_regex) {
     1156                $log->warn("database error, retrying transaction: $@");
     1157                sleep TRANS_RETRY_WAIT;
    10401158                redo TRANS;
    10411159            }
     
    10541172{
    10551173    my $self = shift;
     1174
     1175    my $log = $self->log;
     1176    $log->debug("entered - @_");
    10561177
    10571178    my ($key, $name) = validate_pos(@_,
     
    10641185        {
    10651186            type        => SCALAR,
     1187            callbacks   => {
     1188                'xattr is in user. namespace'
     1189                    => sub { ($_[0]) =~ qr/^user\./ },
     1190            },
    10661191        },
    10671192    );
    10681193
     1194    my $sql = $self->sql;
     1195
    10691196    # ignore volume
    1070     $key = parse_neb_key($key);
    1071 
    1072     my $log = $self->log;
    1073     my $sql = $self->sql;
     1197    eval {
     1198        $key = parse_neb_key($key);
     1199    };
     1200    $log->logdie("$@") if $@;
     1201
    10741202    my $db  = $self->db($key);
    1075 
    1076     $log->debug("entered - @_");
    10771203
    10781204    my $value;
     
    10851211        if ($rows == 0) {
    10861212            $query->finish;
    1087             $log->logdie( "xattr $key:$name does not exist" );
     1213            die( "xattr $key:$name does not exist" );
    10881214        }
    10891215        # if we go more then one row bad something very bad has happened.
    10901216        unless ($rows == 1) {
    10911217            $query->finish;
    1092             $log->logdie( "affected row count is $rows instead of 1" );
     1218            die( "affected row count is $rows instead of 1" );
    10931219        }
    10941220
     
    10991225        $value = $row->{ 'value' };
    11001226    };
    1101     $log->logdie("database error: $@") if $@;
     1227    if ($@) {
     1228        if ($@ =~ /user\..*? does not exist/) {
     1229            # do not log xattr does not exist messages
     1230            die $@;
     1231        }
     1232        $log->logdie("database error: $@") if $@;
     1233    }
    11021234
    11031235    $log->debug("leaving");
     
    11101242{
    11111243    my $self = shift;
     1244
     1245    my $log = $self->log;
     1246    $log->debug("entered - @_");
    11121247
    11131248    my ($key) = validate_pos(@_,
     
    11201255    );
    11211256
     1257    my $sql = $self->sql;
     1258
    11221259    # ignore volume
    1123     $key = parse_neb_key($key);
    1124 
    1125     my $log = $self->log;
    1126     my $sql = $self->sql;
     1260    eval {
     1261        $key = parse_neb_key($key);
     1262    };
     1263    $log->logdie("$@") if $@;
     1264
    11271265    my $db  = $self->db($key);
    1128 
    1129     $log->debug("entered - @_");
    11301266
    11311267    my @xattrs;
     
    11511287    my $self = shift;
    11521288
     1289    my $log = $self->log;
     1290    $log->debug("entered - @_");
     1291
    11531292    my ($key, $name) = validate_pos(@_,
    11541293        {
     
    11601299        {
    11611300            type        => SCALAR,
     1301            callbacks   => {
     1302                'xattr is in user. namespace'
     1303                    => sub { ($_[0]) =~ qr/^user\./ },
     1304            },
    11621305        },
    11631306    );
    11641307
     1308    my $sql = $self->sql;
     1309
    11651310    # ignore volume
    1166     $key = parse_neb_key($key);
    1167 
    1168     my $log = $self->log;
    1169     my $sql = $self->sql;
     1311    eval {
     1312        $key = parse_neb_key($key);
     1313    };
     1314    $log->logdie("$@") if $@;
     1315
    11701316    my $db  = $self->db($key);
    1171 
    1172     $log->debug("entered - @_");
    11731317
    11741318TRANS: while (1) {
     
    11791323            $query->finish;
    11801324
     1325            # no rows affected means the xattr did not exist
     1326            if ($rows == 0) {
     1327                die( "xattr $key:$name does not exist" );
     1328            }
     1329
    11811330            # if we affected more then one row something very bad has happened.
    1182             unless ($rows == 1) {
    1183                 $log->logdie( "affected row count is $rows instead of 1" );
     1331            if ($rows > 1) {
     1332                die( "affected row count is $rows instead of 1" );
    11841333            }
    11851334
     
    11901339            $db->rollback;
    11911340            $log->debug("rollback");
    1192             if ($@ =~ /Deadlock found/) {
    1193                 $log->warn("database deadlock retrying transaction: $@");
     1341            if ($@ =~ $trans_regex) {
     1342                $log->warn("database error, retrying transaction: $@");
     1343                sleep TRANS_RETRY_WAIT;
    11941344                redo TRANS;
    11951345            }
     
    12091359    my $self = shift;
    12101360
     1361    my $log = $self->log;
     1362    $log->debug( "entered - @_" );
     1363
    12111364    my ($pattern) = validate_pos( @_,
    12121365        {
     
    12161369    );
    12171370
    1218     $pattern = parse_neb_key($pattern);
    1219 
    1220     my $log = $self->log;
    1221 
    1222     $log->debug( "entered - @_" );
     1371
     1372    eval {
     1373        $pattern = parse_neb_key($pattern) if defined $pattern;
     1374    };
     1375    $log->logdie("$@") if $@;
    12231376
    12241377    unless (defined $pattern) {
     
    12351388    $log->logdie("no keys found") unless ( scalar @keys );
    12361389
     1390    if (defined $self->cache) {
     1391        foreach my $path (@keys) {
     1392            $self->cache->set($path, 1);
     1393                $log->debug("key added to cache as: $path");
     1394        }
     1395    }
     1396
    12371397    $log->debug( "leaving" );
    12381398
     
    12451405
    12461406    my $self    = shift;
     1407
     1408    my $log = $self->log;
     1409    $log->debug( "entered - @_" );
     1410
    12471411    my $index   = shift;
    12481412    my $key     = shift;
    12491413
    1250     my $log = $self->log;
    12511414    my $sql = $self->sql;
    12521415    my $db  = $self->_db_for_index($index);
    12531416
    1254     $log->debug( "entered - @_" );
    12551417
    12561418    # first check to see if the key is an exact match
     
    13101472    my $self = shift;
    13111473
     1474    my $log = $self->log;
     1475    $log->debug("entered - @_");
     1476
    13121477    my ($key, $vol_name) = validate_pos(@_,
    13131478        {
     
    13301495    );
    13311496
     1497    my $sql = $self->sql;
     1498
     1499#    unless ($key) {
     1500#        $log->warn("key was undefined after validate_pos(), trying again...");
     1501#        return $self->find_instances(@_);
     1502#    }
     1503
    13321504    # vol_name overrides the key implied volume
    1333     $key = parse_neb_key($key, $vol_name);
     1505    eval {
     1506        $key = parse_neb_key($key, $vol_name);
     1507    };
     1508    $log->logdie("$@") if $@;
    13341509    $vol_name = $key->volume;
    13351510
    1336     my $log = $self->log;
    1337     my $sql = $self->sql;
    13381511    my $db  = $self->db($key);
    1339 
    1340     $log->debug("entered - @_");
    13411512
    13421513    # the key's volume can't be validiated on input for this method so we have
     
    13441515    if (defined $vol_name
    13451516        and not $self->_is_valid_volume_name($key, $key->volume)) {
    1346         if ($key->soft_volume) {
     1517        if ($key->hard_volume) {
     1518            $log->logdie("$vol_name is not a valid volume name");
     1519        } else {
    13471520            $log->warn( "$vol_name is not a known volume name" );
    13481521            $vol_name = undef;
    1349         } else {
    1350             die "$vol_name is not a valid volume name"
    13511522        }
    13521523    }
     
    13611532            unless ($rows > 0) {
    13621533                $query->finish;
    1363                 $log->logdie("no instances on storage volume or volume is not avaiable for key: $key volume: $vol_name");
     1534                die("no instances on storage volume or volume is not avaiable for key: $key volume: $vol_name");
    13641535            }
    13651536        } else {
     
    13691540            unless ($rows > 0) {
    13701541                $query->finish;
    1371                 $log->logdie("no instances available for key: $key");
     1542                die("no instances available for key: $key");
    13721543            }
    13731544        }
     
    13811552        $db->rollback;
    13821553        # handle soft volumes
    1383         if (defined $vol_name and defined $key->soft_volume) {
     1554        if (defined $vol_name and not defined $key->hard_volume) {
    13841555            $log->debug("retrying with 'any' volume");
    13851556            return $self->find_instances($key->path, 'any');
     
    14031574    my $self = shift;
    14041575
     1576    my $log = $self->log;
     1577    $log->debug( "entered - @_" );
     1578
    14051579    my ($key, $uri) = validate_pos( @_,
    14061580        {
     
    14151589    );
    14161590
     1591    my $sql = $self->sql;
     1592
    14171593    # ignore volume
    1418     $key = parse_neb_key($key);
    1419 
    1420     my $log = $self->log;
    1421     my $sql = $self->sql;
     1594    eval {
     1595        $key = parse_neb_key($key);
     1596    };
     1597    $log->logdie("$@") if $@;
     1598
    14221599    my $db  = $self->db($key);
    1423 
    1424     $log->debug( "entered - @_" );
    14251600
    14261601TRANS: while (1) {
    14271602        eval {
     1603            my $instances;
    14281604            my $so_id;
    1429             my $instances;
    1430             # get so_id
     1605            my $ins_id;
     1606            # find so_id for key and get count of instances
    14311607            {
    1432                 my $query = $db->prepare_cached( $sql->get_object_from_uri );
    1433                 my $rows = $query->execute( $uri );
    1434 
     1608                my $query = $db->prepare_cached( $sql->get_instance_count_by_ext_id );
     1609                my $rows = $query->execute($key->path);
    14351610                unless ( $rows > 0 ) {
    14361611                    $query->finish;
    1437                     $log->logdie( "no instance is associated with uri" );
    1438                 }
    1439 
    1440                 $so_id = $query->fetchrow_hashref->{ 'so_id' };
     1612                    die( "$key has no associated instances - this should not happen" );
     1613                }
     1614
     1615                my $record = $query->fetchrow_hashref;
     1616                $so_id      = $record->{ 'so_id' };
     1617                $instances  = $record->{ 'count(ins_id)' };
    14411618                $query->finish;
    1442 
    1443             }
    1444 
     1619            }
     1620
     1621            # find ins_id for uri
    14451622            {
    1446                 my $query = $db->prepare_cached( $sql->get_instance_count );
    1447                 $query->execute( $so_id );
    1448 
    1449                 $instances = $query->fetchrow_hashref->{ 'count(ins_id)' };
     1623                my $query = $db->prepare_cached( $sql->get_instance_by_uri );
     1624                my $rows = $query->execute($so_id, $uri);
     1625                unless ( $rows > 0) {
     1626                    $query->finish;
     1627                    die( "no instance is associated with uri" );
     1628                }
     1629
     1630                $ins_id = $query->fetchrow_hashref->{ 'ins_id' };
    14501631                $query->finish;
    14511632            }
     
    14531634            # remove instance
    14541635            {
    1455                 my $query = $db->prepare_cached( $sql->delete_instance );
    1456                 my $rows = $query->execute( $uri );
     1636                my $query = $db->prepare_cached( $sql->delete_instance_by_ins_id );
     1637                my $rows = $query->execute( $ins_id );
    14571638                $query->finish;
    14581639               
    1459                 # if we affected something other then two rows something very bad
    1460                 # has happened
     1640                # if we affected something other then one row something very
     1641                # bad has happened
    14611642                unless ( $rows == 1 ) {
    1462                     $log->logdie( "affected row count is $rows instead of 1" );
     1643                    die( "affected row count is $rows instead of 1" );
    14631644                }
    14641645            }
     
    14671648            # remove it too
    14681649            if ( $instances == 1 ) {
     1650                # remove key from cache
     1651                $self->cache->delete($key->path) if defined $self->cache;
     1652
    14691653                # we just removed the last instance
    14701654                my $query = $db->prepare_cached( $sql->delete_object );
     
    14741658                # TODO: this will have to be changed in order to support hardlinks
    14751659                unless ( $rows == 1 ) {
    1476                     $log->logdie( "affected row count is $rows instead of 2" );
     1660                    die( "affected row count is $rows instead of 2" );
    14771661                }
    14781662            }
     
    14841668            $db->rollback;
    14851669            $log->debug("rollback");
    1486             if ($@ =~ /Deadlock found/) {
    1487                 $log->warn("database deadlock retrying transaction: $@");
     1670            if ($@ =~ $trans_regex) {
     1671                $log->warn("database error, retrying transaction: $@");
     1672                sleep TRANS_RETRY_WAIT;
    14881673                redo TRANS;
    14891674            }
     
    15021687{
    15031688    my $self = shift;
     1689
     1690    my $log = $self->log;
     1691    $log->debug("entered - @_");
    15041692
    15051693    my ( $key ) = validate_pos( @_,
     
    15121700    );
    15131701
     1702    my $sql = $self->sql;
     1703
    15141704    # ignore volume
    1515     $key = parse_neb_key($key);
    1516 
    1517     my $log = $self->log;
    1518     my $sql = $self->sql;
     1705    eval {
     1706        $key = parse_neb_key($key);
     1707    };
     1708    $log->logdie("$@") if $@;
     1709
    15191710    my $db  = $self->db($key);
    1520 
    1521     $log->debug("entered - @_");
    15221711
    15231712    my $stat;
     
    15271716
    15281717        unless ($rows == 1) {
    1529             $log->logdie("no storage object found");
     1718            die("no storage object found");
    15301719        }
    15311720
     
    15481737    my $self = shift;
    15491738
     1739    my $log = $self->log;
     1740    $log->debug("entered - @_");
     1741
    15501742    validate_pos(@_);
    15511743
    1552     my $log = $self->log;
    15531744    my $sql = $self->sql;
    15541745    my $db  = $self->_db_for_index(0); # XXX fix as above
    15551746
    1556     $log->debug("entered - @_");
    1557 
    15581747    my $stats;
    15591748    my $query;
     
    15761765}
    15771766
     1767sub chmod_object
     1768{
     1769    my $self = shift;
     1770
     1771    my $log = $self->log;
     1772    $log->debug("entered - @_");
     1773
     1774    my ($key, $mode) = validate_pos( @_,
     1775        {
     1776            type        => SCALAR,
     1777            callbacks   => {
     1778                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
     1779            },
     1780        },
     1781        {
     1782            type        => SCALAR,
     1783            regex       => qr/\d{3,4}/,
     1784            callbacks   => {
     1785                'is allowable mode' => sub {
     1786                    $_[0] == (S_IRUSR | S_IRGRP)
     1787                },
     1788            },
     1789        },
     1790    );
     1791
     1792    my $sql = $self->sql;
     1793
     1794    # ignore volume
     1795    eval {
     1796        $key = parse_neb_key($key);
     1797    };
     1798    $log->logdie("$@") if $@;
     1799
     1800    my $db  = $self->db($key);
     1801
     1802    # find all instances of this object
     1803    my $locations;
     1804    eval {
     1805        $locations = $self->find_instances("$key");
     1806    };
     1807    $log->logdie("error: $@") if $@;
     1808
     1809    # update each instances
     1810    foreach my $inst (@$locations) {
     1811        my $path = URI->new($inst)->path;
     1812
     1813        $self->_retry(sub { chmod($mode, $path) })
     1814            or $log->logdie("can not chmod() $path: $!");
     1815
     1816        # XXX I'm assuming that it's OK to fsync() a filehandle that's only
     1817        # open for reading?  Opening as w/rw here can fail if the chmod removes
     1818        # write permissions.
     1819        my $fh;
     1820        $self->_retry(sub { open($fh, '<', $path) })
     1821            or $log->logdie("can not open() $path: $!");
     1822
     1823        # fsync(3c)
     1824        $self->_retry(sub { $fh->sync() })
     1825            or $log->logdie("can not sync() $path: $!");
     1826
     1827        $self->_retry(sub { close($fh) })
     1828            or $log->logdie("can not close() $path: $!");
     1829    }
     1830
     1831    # stick an xattr on this object with the mode
     1832    # XXX this would probably be better as a field in the storage_object_attr
     1833    # table but since we're not planning to use this for very many objects (as
     1834    # a %) it may not be worth adding the extra field at this time.
     1835    eval {
     1836        $self->setxattr_object("$key", 'user.mode', $mode, 'replace');
     1837    };
     1838    $log->logdie("error: $@") if $@;
     1839
     1840    $log->debug("leaving");
     1841
     1842    return $mode;
     1843}
    15781844
    15791845sub _get_storage_volume
     
    15811847    my $self = shift;
    15821848
    1583     my ($key, $name, $soft_volume) = @_;
    1584 
    1585     my $log = $self->log;
    1586     my $sql = $self->sql;
    1587     my $db  = $self->db($key);
    1588 
     1849    my $log = $self->log;
    15891850    no warnings qw( uninitialized );
    15901851    $log->debug( "entered - @_" );
    15911852    use warnings;
     1853
     1854    my ($key, $name, $hard_volume) = @_;
     1855
     1856    my $sql = $self->sql;
     1857    my $db  = $self->db($key);
    15921858
    15931859    my ($vol_id, $vol_host, $vol_path, $xattr);
     
    16051871                # if a volume name was specified, and is soft, and we failed to
    16061872                # find it, fall back to any volume
    1607                 if ($soft_volume) {
     1873                unless ($hard_volume) {
    16081874                    ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume($key);
    16091875                    return; # this just returns out of the eval not from the subroutine
    16101876                }
    1611                 $log->logdie("storage volume: $name is not available");
     1877                die("storage volume: $name is not available");
    16121878            }
    16131879            # when matching by name we shouldn't ever match more than once
    16141880            if ($rows > 1) {
    16151881                $query->finish;
    1616                 $log->logdie("affected row count is $rows instead of 1");
     1882                die("affected row count is $rows instead of 1");
    16171883            }
    16181884        } else {
     
    16231889            unless ($rows > 0) {
    16241890                $query->finish;
    1625                 $log->logdie("no storage volume is available");
     1891                die("no storage volume is available for key: $key volume: $name hard_volume: $hard_volume");
    16261892            }
    16271893        }
     
    16311897        $query->finish;
    16321898    };
    1633     $log->logdie("database error: $@") if $@;
     1899    if ($@) {
     1900        if ($@ =~ qr/no storage volume is available/) {
     1901            # this should not happen unless all volumes are full
     1902            $log->error($@);
     1903            $log->debug("retrying...");
     1904            return $self->_get_storage_volume(@_);
     1905        }
     1906        # else
     1907        $log->logdie("database error: $@");
     1908    }
    16341909
    16351910    $log->logdie("failed to find a suitable volume" )
     
    16461921    my $self = shift;
    16471922
    1648     my $key = shift;
    1649 
    1650     my $log = $self->log;
    1651     my $sql = $self->sql;
    1652     my $db  = $self->db($key);
    1653 
     1923    my $log = $self->log;
    16541924    no warnings qw( uninitialized );
    16551925    $log->debug( "entered - @_" );
    16561926    use warnings;
     1927
     1928    my $key = shift;
     1929
     1930    my $sql = $self->sql;
     1931    my $db  = $self->db($key);
    16571932
    16581933    my ($vol_id, $vol_host, $vol_path, $xattr);
     
    16651940        unless ($rows > 0) {
    16661941            $query->finish;
    1667             $log->logdie("can't find a suitable storage volume to replicate $key to");
     1942            die("can't find a suitable storage volume to replicate $key to");
    16681943        }
    16691944        # when matching by name we shouldn't ever match more than once
    16701945        if ($rows > 1) {
    16711946            $query->finish;
    1672             $log->logdie("affected row count is $rows instead of 1");
     1947            die("affected row count is $rows instead of 1");
    16731948        }
    16741949
     
    16901965sub _is_valid_object_key
    16911966{
    1692     my ($self, $key) = @_;
    1693 
    1694     $key = parse_neb_key($key);
    1695 
    1696     my $log = $self->log;
     1967    my $self = shift;
     1968
     1969    my $log = $self->log;
     1970    $log->debug( "entered - @_" );
     1971
     1972    my ($key) = @_;
     1973
    16971974    my $sql = $self->sql;
     1975
     1976    eval {
     1977        $key = parse_neb_key($key);
     1978    };
     1979    $log->logdie("$@") if $@;
     1980
     1981    # check cache first
     1982    my $cached = $self->cache->get($key->path) if defined $self->cache;
     1983    if (defined $cached) {
     1984        $log->debug( "key $key found in cache as ", $key->path );
     1985        $log->debug( "leaving" );
     1986        return 1;
     1987    } else {
     1988        $log->debug( "key $key not found in cache" );
     1989    }
     1990
    16981991    my $db  = $self->db($key);
    16991992
     
    17122005
    17132006    if (defined $ext_id) {
     2007        $log->debug( "key found in db" );
     2008        # add key to cache
     2009        $self->cache->set($key->path, 1) if defined $self->cache;
     2010        $log->debug( "key added to cache as ", $key->path );
     2011        $log->debug( "leaving" );
    17142012        return 1;
    17152013    }
    17162014
     2015    $log->debug( "key not found in db" );
     2016    $log->debug( "leaving" );
     2017
    17172018    return;
    17182019}
     
    17212022sub _is_valid_volume_name
    17222023{
    1723     my ($self, $key, $vol_name) = @_;
    1724 
    1725     $key = parse_neb_key($key);
     2024    my $self = shift;
     2025
     2026    my $log = $self->log;
     2027    $log->debug( "entered - @_" );
     2028
     2029    my ($key, $vol_name) = @_;
     2030
     2031    my $sql = $self->sql;
     2032
     2033    # the volume name implied by the key is ignored.  $key is only needed to
     2034    # select a database connection
     2035    eval {
     2036        $key = parse_neb_key($key);
     2037    };
     2038    $log->logdie("$@") if $@;
    17262039    my $volume_info = parse_neb_volume($vol_name);
    17272040
    1728     my $log = $self->log;
    1729     my $sql = $self->sql;
    17302041    my $db  = $self->db($key);
    17312042
     
    17342045    # handle "any" volume
    17352046    if ($vol_name eq 'any') {
     2047        $log->debug( "found volume name $vol_name" );
     2048        $log->debug( "leaving" );
    17362049        return 1;
    17372050    }
     
    17482061
    17492062    if (defined $vol_id and defined $vol_path) {
     2063        $log->debug( "found volume name $vol_name" );
     2064        $log->debug( "leaving" );
    17502065        return 1;
    17512066    }
    17522067
     2068    $log->debug( "volume name $vol_name not found" );
     2069    $log->debug( "leaving" );
     2070
    17532071    return;
    17542072}
     
    17592077    my $self = shift;
    17602078
     2079    my $log = $self->log;
     2080    $log->debug( "entered - @_" );
     2081
    17612082    my ($key, $so_id, $ins_id, $vol_path, $xattr) =  @_;
    17622083
    1763     my $log = $self->log;
    17642084    my $sql = $self->sql;
    17652085    my $db  = $self->db($key);
     
    17702090        my $storage_filename = $self->_generate_storage_filename($key->path, $ins_id);
    17712091        unless (-d $storage_path) {
    1772             _retry(sub { mkpath(@_) }, $storage_path, 0, 0775)
    1773                 or die "can't create storage path: $storage_path";
     2092            $self->_retry(sub { mkpath([$storage_path], 0, 0775) })
     2093                or die("can't create storage path: $storage_path");
    17742094        }
    17752095        # check to make sure at least the parent directory has the proper
    17762096        # permissions
    1777         my $mode = [_retry(sub { stat($storage_path) } )]->[2] & 07777;
     2097        my $mode = [$self->_retry(sub { stat($storage_path) } )]->[2] & 07777;
    17782098        unless ($mode == 0775) {
    1779             $log->error("$storage_path has the wrong permissions of: %04x", $mode);
    1780             _retry(sub { chmod(0775, $storage_path) }) or die "can't chmod $storage_path: $!";
     2099            # XXX: this problem is so common that it's flooding the logs
     2100            $log->debug("$storage_path has the wrong permissions of: 0", sprintf("%o", $mode));
     2101            $self->_retry(sub { chmod(0775, $storage_path) })
     2102                or die("can not chmod() $storage_path: $!");
    17812103        }
    17822104
     
    17872109    };
    17882110    if ($@) {
     2111        if (defined $uri and -e $uri->file) {
     2112            unlink($uri->file)
     2113                or $log->error("failed to unlink() $uri: $!");
     2114        }
    17892115        $log->logdie($@);
    17902116    }
     
    17922118    if ($xattr) {
    17932119        my $path = $uri->file;
    1794         die "can not set xattr on $path: $!"
     2120        $log->logdie("can not set xattr on $path: $!")
    17952121            unless (setfattr($path, 'user.nebulous_key', $key->path));
    17962122    }
     
    18042130    my $self = shift;
    18052131
     2132    my $log = $self->log;
     2133    $log->debug( "entered - @_" );
     2134
    18062135    my ($path) = @_;
    18072136
    18082137    # perl's open() can't do an O_CREAT | O_EXCL
    1809     die "file $path already exists" if (-e $path);
     2138    # XXX is it possible to tell if this system call failed?
     2139    -e $path
     2140        and $log->logdie("file $path already exists");
    18102141
    18112142    my $fh;
    1812     die "can not open $path: $!"
    1813         unless (_retry(sub { open($fh, '>', $path) }));
     2143    $self->_retry(sub { open($fh, '>', $path) })
     2144        or $log->logdie("can not open() $path: $!");
    18142145
    18152146    # chmod before fsync() to make sure the changed perms hit the disk too
    1816     die "can not chmod $path: $!"
    1817         unless (_retry(sub { chmod(0664, $path) }));
    1818 
    1819     die "can not flush $path: $!"
    1820         unless ($fh->flush);
    1821 
    1822     die "can not sync $path: $!"
    1823         unless ($fh->sync);
    1824 
    1825     die "can not close $path: $!"
    1826         unless (_retry(sub { close($fh) }));
     2147    $self->_retry(sub { chmod(0664, $path) })
     2148        or $log->logdie("can not chmod() $path: $!");
     2149
     2150    $self->_retry(sub { $fh->sync() })
     2151        or $log->logdie("can not sync() $path: $!");
     2152
     2153    $self->_retry(sub { close($fh) })
     2154        or $log->logdie("can not close() $path: $!");
    18272155
    18282156    return $path;
     
    18612189sub _retry
    18622190{
     2191    my $self = shift;
     2192
     2193    my $log = $self->log;
     2194    $log->debug( "entered - @_" );
     2195
    18632196    my $func = shift;
    18642197
     
    18692202        };
    18702203        if ($@) {
    1871             die $@;
    1872             sleep 1;
     2204            $log->logdie($@);
     2205            sleep NFS_RETRY_WAIT;
    18732206            next;
    18742207        }
     
    18792212    # if the loop ended and $@ is set, rethrow the error
    18802213    if ($@) {
    1881         die $@;
     2214        $log->logdie($@);
    18822215    }
    18832216
Note: See TracChangeset for help on using the changeset viewer.