IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 7, 2009, 12:45:24 PM (17 years ago)
Author:
eugene
Message:

update from mainline

Location:
branches/eam_branches/20090715
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715

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

    r24637 r25022  
    696696    $log->debug("entered - @_");
    697697
    698     my ($key, $vol_name) = validate_pos(@_,
     698    my ($key, $dest_vol_name) = validate_pos(@_,
    699699        {
    700700            type        => SCALAR,
     
    726726    # instance on it.  If all avilable volume already have an instance on them
    727727    # then we should throw an error
    728 
    729     # vol_name overrides the key implied volume
    730     eval {
    731         $key = parse_neb_key($key, $vol_name);
     728    # volume names implied as part of the key are *IGNORED* as the source and
     729    # *SHOULD NOT* be used as the destination either
     730
     731    eval {
     732        $key = parse_neb_key($key);
    732733    };
    733734    $log->logdie("$@") if $@;
    734     $vol_name = $key->volume;
    735735
    736736    my $db  = $self->db($key);
    737737
    738     if (defined $vol_name
     738    # puke if the source volume is bogus, we may want to actually use this as
     739    # the instance to be copied later
     740    if (defined $key->volume
    739741        and not $self->_is_valid_volume_name($key, $key->volume)) {
    740742        unless ($key->hard_volume) {
    741             $log->warn( "$vol_name is not a known volume name" );
    742             $vol_name = undef;
     743            $log->warn($key->volume . " not a known volume name");
    743744        } else {
    744            $log->logdie("$vol_name is not a valid volume name");
    745         }
     745           $log->logdie("$key is not a valid volume name");
     746        }
     747    }
     748    # puke if the source volume is bogus, we may want to actually use this as
     749    # the instance to be copied later
     750    if (defined $dest_vol_name
     751        and not $self->_is_valid_volume_name($key, $dest_vol_name)) {
     752           $log->logdie($key->volume . " is not a valid volume name");
    746753    }
    747754       
    748755    my ($vol_id, $vol_host, $vol_path, $vol_xattr);
    749     if (defined $vol_name) {
     756    if (defined $dest_vol_name) {
    750757        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    751             = $self->_get_storage_volume($key, $vol_name);
     758            = $self->_get_storage_volume($key, $dest_vol_name);
    752759    } else {
    753760        ($vol_id, $vol_host, $vol_path, $vol_xattr)
     
    810817            $db->rollback;
    811818            # handle soft volumes
    812             if (defined $vol_name and not defined $key->hard_volume) {
     819            if (defined $dest_vol_name and not defined $key->hard_volume) {
    813820                $log->debug("retrying with 'any' volume");
    814821                return $self->replicate_object($key->path, 'any');
     
    841848
    842849    return "$uri";
     850}
     851
     852
     853sub prune_object
     854{
     855    my $self = shift;
     856
     857    my $log = $self->log;
     858    $log->debug("entered - @_");
     859
     860    my ($key) = validate_pos(@_,
     861        {
     862            type        => SCALAR,
     863            callbacks   => {
     864                'is valid object key'
     865                    => sub { $self->_is_valid_object_key($_[0]) },
     866            },
     867        },
     868    );
     869
     870    my $sql = $self->sql;
     871
     872    eval {
     873        $key = parse_neb_key($key);
     874    };
     875    $log->logdie("$@") if $@;
     876
     877    my $db  = $self->db($key);
     878
     879    my $rows_removed = 0;
     880TRANS: while (1) {
     881        eval {
     882            # remove key from cache
     883            $self->cache->delete($key->path) if defined $self->cache;
     884
     885            my $so_id;
     886            {
     887                my $query = $db->prepare_cached( $sql->find_object_by_ext_id );
     888                $query->execute( $key->path );
     889                $so_id = $query->fetchrow_hashref->{'so_id'};
     890                $query->finish;
     891            }
     892
     893            # record the path of the innaccesible files for deferred
     894            # deletion
     895            my $rows_copied;
     896            {
     897                my $query = $db->prepare_cached( $sql->copy_dead_instances_to_deleted );
     898                $rows_copied = $query->execute( $so_id );
     899            }
     900
     901            # check to see if there is anything to be done
     902            unless ($rows_copied > 0) {
     903                $db->rollback;
     904                return;
     905            }
     906
     907            # In MySQL you can't select from a table your deleting rows from so
     908            # we first have to get a list of instances to be removed, and then
     909            # removed them.
     910            my $rows_found;
     911            {
     912                my $query = $db->prepare_cached( $sql->find_dead_instances_by_so_id );
     913                $rows_found = $query->execute( $so_id );
     914                foreach my $row ($query->fetchrow_hashref) {
     915                    # remove dead instances
     916                    my $query = $db->prepare_cached( $sql->delete_instance_by_ins_id);
     917                    $rows_removed += $query->execute( $row->{ins_id} );
     918                }
     919                $query->finish;
     920            }
     921
     922            # sanity check
     923            die("instances inaccessible ($rows_copied) != instances removed ($rows_removed)")
     924                unless $rows_copied == $rows_removed;
     925           
     926            $db->commit;
     927            $log->debug("commit");
     928        };
     929        if ($@) {
     930            $db->rollback;
     931            $log->debug("rollback");
     932            if ($@ =~ $trans_regex) {
     933                $log->warn("database error, retrying transaction: $@");
     934                sleep TRANS_RETRY_WAIT;
     935                redo TRANS;
     936            }
     937            $log->logdie("error: $@");
     938        }
     939        last;
     940    }
     941
     942    $log->debug("leaving");
     943
     944    return $rows_removed;
    843945}
    844946
     
    16741776                # remove key from cache
    16751777                $self->cache->delete($key->path) if defined $self->cache;
    1676 
    1677                 # record the path of the innaccesible files for deferred
    1678                 # deletion
    1679                 {
    1680                     my $query = $db->prepare_cached( $sql->copy_instances_to_deleted );
    1681                     $query->execute( $so_id );
    1682                 }
    1683                 # remove all instances... not strictly nessicary as the delete
    1684                 # from storage_object should cascade but the fkey was specified
    1685                 # without the cascade
    1686                 {
    1687                     my $query = $db->prepare_cached( $sql->delete_instance_by_so_id );
    1688                     $query->execute( $so_id );
     1778               
     1779                if ($total > $available) {
     1780                    $self->prune_object("$key");
    16891781                }
    16901782               
Note: See TracChangeset for help on using the changeset viewer.