IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 27, 2019, 12:04:14 PM (7 years ago)
Author:
eugene
Message:

merging updates to Nebulous from EAM dev branch ipp-20191011

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Nebulous-Server/lib/Nebulous/Server.pm

    r39926 r41172  
    1313use base qw( Class::Accessor::Fast );
    1414
     15use Carp;
     16
    1517use Cache::Memcached;
    1618use DBI;
     19
     20## for gentoo:
    1721use Digest::SHA1 qw( sha1_hex );
     22
     23## for ubuntu:
     24# use Digest::SHA qw( sha1_hex );
     25
    1826use Fcntl ':mode';
    1927use File::Basename qw( basename dirname fileparse );
     
    7785        Cache::Memcached->new({
    7886            servers => $config->memcached_servers,
    79        })
    80     );
     87                              })
     88        );
    8189#    $self->cache->set("foo", "bar") or die "set failed";
    8290#    $self->cache->get("foo") or die "get failed";
     
    215223}
    216224
     225my $get_storage_volume_calls = 0;
     226
    217227sub create_object
    218228{
     
    252262    # the key's volume can't be validiated on input for this method so we have
    253263    # to check it after parsing the key
    254     if (defined $vol_name
    255         and not $self->_is_valid_volume_name($key, $key->volume)) {
     264    if (defined $vol_name and not $self->_is_valid_volume_name($key, $key->volume)) {
    256265        unless ($key->hard_volume) {
    257266            $log->warn( "$vol_name is not a known volume name" );
     
    262271    }
    263272       
     273    $get_storage_volume_calls = 0;
     274
    264275    my ($vol_id, $vol_host, $vol_path, $vol_xattr)
    265276        = $self->_get_storage_volume($key, $vol_name, $key->hard_volume);
     
    273284                # create storage_object
    274285                my $query = $db->prepare_cached( $sql->new_object );
    275                 $query->execute('NULL', $key->path, basename($key->path), $parent_id);
     286# bad syntax    $query->execute('NULL', $key->path, basename($key->path), $parent_id);
     287                $query->execute(0, $key->path, basename($key->path), $parent_id);
     288                $query->finish;
    276289            }
    277290
     
    292305                my $query = $db->prepare_cached( $sql->new_object_attr );
    293306                $query->execute($so_id);
     307                $query->finish;
    294308            }
    295309
     
    300314                my $query = $db->prepare_cached( $sql->new_object_instance );
    301315                $query->execute($vol_id);
     316                $query->finish;
    302317            }
    303318
     
    327342                # vol_id, uri, ins_id
    328343                $query->execute($vol_id, "$uri", $ins_id);
     344                $query->finish;
    329345            }
    330346
     
    421437                    }
    422438                    $query->finish;
     439                    $db->commit;
    423440                }
    424441
     
    441458                    my $query = $db->prepare_cached($sql->new_directory);
    442459                    $query->execute($dir, $parent_id);
     460                    $query->finish;
     461                    $db->commit;
    443462                }
    444463
     
    452471                    ($parent_id) = $query->fetchrow_array;
    453472                    $query->finish;
     473                    $db->commit;
    454474                }
    455475                die("failed to get LAST_INSERT_ID()")
    456476                    unless $parent_id;
    457 
    458                 $db->commit;
    459477            }
    460478        };
     
    712730        {
    713731            type        => SCALAR|UNDEF,
    714 #            callbacks   => {
    715 #                # check that the volume name requested is valid
    716 #                'is valid volume name' => sub {
    717 #                    return 1 if not defined $_[0];
    718 #                    $self->_is_valid_volume_name($_[0])
    719 #                },
    720 #            },
    721732            optional    => 1,
    722733        },
     
    726737
    727738    # if a volume name is explicity specified then we should make the
    728     # replication onto that volume (even if there is alread an instance on that
     739    # replication onto that volume (even if there is already an instance on that
    729740    # volume) if at all possible and throw an error if we can not.
     741
    730742    # if a volume name IS NOT specified then we should make the replication
    731743    # onto any (hopefully the best) volume that DOES NOT already have an
    732     # instance on it.  If all avilable volume already have an instance on them
     744    # instance on it.  If all available volumes already have an instance on them
    733745    # then we should throw an error
     746
    734747    # volume names implied as part of the key are *IGNORED* as the source and
    735748    # *SHOULD NOT* be used as the destination either
    736749
    737750    eval {
    738         $key = parse_neb_key($key);
     751        # EAM 2019.10.31 : if I supply dest_vol_name here, then
     752        # $key->volume will point at that volume and the section below
     753        # will correctly be testing the validity of dest_vol_name
     754        $key = parse_neb_key($key, $dest_vol_name);
    739755    };
    740756    $log->logdie("$@") if $@;
     
    742758    my $db  = $self->db($key);
    743759
     760    ## Old comment:
    744761    # puke if the source volume is bogus, we may want to actually use this as
    745762    # the instance to be copied later
    746     if (defined $key->volume
    747         and not $self->_is_valid_volume_name($key, $key->volume)) {
     763
     764    # EAM 2019.10.31 : in the past, the key-implied volume was
     765    # supplied here, which was inconsistent since above it says the
     766    # key-implied volume is ignored. By supplying $dest_vol_name to
     767    # parse_neb_key above, the key->volume now refers to the
     768    # dest_volume
     769    if (defined $key->volume and not $self->_is_valid_volume_name($key, $key->volume)) {
    748770        unless ($key->hard_volume) {
    749771            $log->warn($key->volume . " not a known volume name");
     
    752774        }
    753775    }
    754     # puke if the source volume is bogus, we may want to actually use this as
    755     # the instance to be copied later
    756     if (defined $dest_vol_name
    757         and not $self->_is_valid_volume_name($key, $dest_vol_name)) {
    758            $log->logdie($key->volume . " is not a valid volume name");
    759     }
    760        
     776
     777    # puke if the destination volume is bogus
     778    ## XXX if I supply dest_vol_name to parse_neb_key above, this section below is redundant with the above
     779    ## if (defined $dest_vol_name
     780    ##     and not $self->_is_valid_volume_name($key, $dest_vol_name)) {
     781    ##        $log->logdie($key->volume . " is not a valid volume name");
     782    ## }
     783
     784    $get_storage_volume_calls = 0;
     785
    761786    my ($vol_id, $vol_host, $vol_path, $vol_xattr);
    762787    if (defined $dest_vol_name) {
     788        # if we supplied dest_vol_name, then the call to parse_neb_key above
     789        # will have set $key->volume to that value and hard_volume to match
    763790        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    764             = $self->_get_storage_volume($key, $dest_vol_name);
     791            = $self->_get_storage_volume($key, $key->volume, $key->hard_volume);
    765792    } else {
    766793        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    767794            = $self->_get_replication_volume($key);
    768795    }
     796
     797    # print "selected target: $vol_id, $vol_host\n";
    769798
    770799    my $uri;
     
    784813                $so_id = $query->fetchrow_hashref->{ 'so_id' };
    785814                $query->finish;
     815                $db->commit;
    786816            }
    787817
     
    800830                # time LAST_INSERT_ID() is invoked
    801831                $query->finish;
     832                $db->commit;
    802833            }
    803834
     
    841872    eval {
    842873        my $mode = $self->getxattr_object("$key", 'user.mode');
    843         if (defined $mode) {
    844             $self->chmod_object("$key", $mode);
     874        if (defined $mode && $mode ne "") {
     875            $self->chmod_object("$key", $mode);
    845876        }
    846877    };
     
    852883
    853884    $log->debug("leaving");
    854 
    855885    return "$uri";
    856886}
     
    13231353            die( "xattr $key:$name does not exist" );
    13241354        }
     1355
    13251356        # if we go more then one row bad something very bad has happened.
    13261357        unless ($rows == 1) {
     
    13351366        $value = $row->{ 'value' };
    13361367    };
     1368    $db->commit;
     1369
    13371370    if ($@) {
    13381371        if ($@ =~ /user\..*? does not exist/) {
    13391372            # do not log xattr does not exist messages
     1373            # NOTE: the client is using the reported message to interpret the errors
    13401374            die $@;
    13411375        }
     
    13861420    };
    13871421    $log->logdie("database error: $@") if $@;
     1422    $db->commit;
    13881423
    13891424    $log->debug("leaving");
     
    14421477                die( "affected row count is $rows instead of 1" );
    14431478            }
    1444 
    14451479            $db->commit;
    14461480            $log->debug("commit");
     
    15451579        $work_dir = $pattern;
    15461580        $file_pattern = '%';
    1547     }
    1548     else {
     1581    } else {
    15491582        my $dir_plain = dirname($pattern);
    15501583        if ($dir_plain eq 'neb:') {
     
    15751608        my $query = $db->prepare_cached( $sql->find_dir_by_parent_id . " AND dirname LIKE ? ");
    15761609        $query->execute( $dir_id, $file_pattern );
     1610        $db->commit;
    15771611
    15781612        while ( my $row = $query->fetchrow_hashref ) {
     
    15951629        my $query = $db->prepare_cached( $sql->find_object_by_dir_id . " AND ext_id_basename LIKE ? ");
    15961630        $query->execute( $dir_id , $file_pattern);
     1631        $db->commit;
    15971632
    15981633        while ( my $row = $query->fetchrow_hashref ) {
     
    16241659    my $sql = $self->sql;
    16251660    my $db  = $self->_db_for_index($index);
    1626 
    16271661
    16281662    # first check to see if the key is an exact match
     
    16451679        $log->logdie("database error: $@");
    16461680    }
     1681    $db->commit;
    16471682
    16481683    if (scalar @keys) {
     
    16781713    };
    16791714    $log->logdie("database error: $@") if $@;
     1715    $db->commit;
    16801716
    16811717    # find files under dir
     
    16921728    };
    16931729    $log->logdie("database error: $@") if $@;
     1730    $db->commit;
    16941731
    16951732    $log->debug( "leaving" );
     
    17531790}
    17541791
     1792# sub find_instances
    17551793sub find_instances_old
    17561794{
     
    17691807        {
    17701808            type        => SCALAR|UNDEF,
    1771 #            callbacks   => {
    1772 #                # check that the volume name requested is valid
    1773 #                'is valid volume name' => sub {
    1774 #                    return 1 if not defined $_[0];
    1775 #                    $self->_is_valid_volume_name($_[0])
    1776 #                },
    1777 #            },
    17781809            optional    => 1,
    17791810        },
     
    17871818    my $sql = $self->sql;
    17881819
    1789 #    unless ($key) {
    1790 #        $log->warn("key was undefined after validate_pos(), trying again...");
    1791 #        return $self->find_instances(@_);
    1792 #    }
     1820    # default value for find_invalid is false
     1821    if (not defined $find_invalid) { $find_invalid = 0; }
    17931822
    17941823    # vol_name overrides the key implied volume
     
    18281857            my $rows;
    18291858            # ext_id, available
    1830             if (defined($find_invalid)) {
     1859            if (defined($find_invalid) and $find_invalid) {
     1860                # XXX returns instances which are NOT available
    18311861                $rows = $query->execute($key->path, 0);
    18321862            }
     
    18651895}
    18661896
    1867 #sub find_instances_by_proximity
     1897# sub find_instances_by_proximity
    18681898sub find_instances
    18691899{
     
    18821912        {
    18831913            type        => SCALAR|UNDEF,
    1884 #            callbacks   => {
    1885 #                # check that the volume name requested is valid
    1886 #                'is valid volume name' => sub {
    1887 #                    return 1 if not defined $_[0];
    1888 #                    $self->_is_valid_volume_name($_[0])
    1889 #                },
    1890 #            },
    18911914            optional    => 1,
    18921915        },
     
    18971920        },
    18981921    );
    1899 
    19001922    my $sql = $self->sql;
    19011923
    1902 #    unless ($key) {
    1903 #        $log->warn("key was undefined after validate_pos(), trying again...");
    1904 #        return $self->find_instances(@_);
    1905 #    }
     1924    if (not defined $find_invalid) { $find_invalid = 0; }
     1925
     1926    if ($find_invalid eq "find them all") {
     1927        $log->logdie("old neb-cull --one_only, neb-rm --invalid both disabled by new Server.pm");
     1928    }
    19061929
    19071930    # vol_name overrides the key implied volume
     
    19321955            }
    19331956        }
    1934 
    1935 
    19361957    }
    19371958
     
    19721993            # ext_id, name, available
    19731994            # host_vol_id host_cab_id host_site_id ext_id available
    1974             my $rows = $query->execute($h_vol_id, $h_cab_id, $h_site_id, $key->path, 1);
     1995
     1996            my $rows;
     1997            if (defined($find_invalid) and $find_invalid) {
     1998                # returns instances which are NOT available (volume not available)
     1999                $rows = $query->execute($h_vol_id, $h_cab_id, $h_site_id, $key->path, 0);
     2000            } else {
     2001                $rows = $query->execute($h_vol_id, $h_cab_id, $h_site_id, $key->path, 1);
     2002            }           
    19752003            unless ($rows > 0) {
    19762004                $query->finish;
    1977                 die("no instances on storage volume or volume is not avaiable for key: $key volume: $vol_name");
     2005                die("no instances on storage volume or volume is not available for key: $key volume: $vol_name");
    19782006            }
    19792007        } else {
    19802008            $query = $db->prepare_cached( $sql->get_object_instances );
     2009            # ext_id, available
     2010
    19812011            my $rows;
    1982             # ext_id, available
    1983             if (defined($find_invalid)) {
     2012            if (defined($find_invalid) and $find_invalid) {
     2013                # returns instances which are NOT available (volume not available)
    19842014                $rows = $query->execute($key->path, 0);
    1985             }
    1986             else {
     2015            } else {
    19872016                $rows = $query->execute($key->path, 1);
    19882017            }
     
    19922021            }
    19932022        }
     2023        $db->commit;
     2024        ## if we do not call commit here, the transaction stays
     2025        ## open blocking some operations below.
    19942026
    19952027        while (my $row = $query->fetchrow_hashref) {
    19962028            my $instance = $row->{ 'uri' };
    19972029            push @locations, $instance if $instance;
     2030
     2031            # Carp::carp ("instance 2: $row->{ 'uri' }, $row->{ 'vol_id' }, $row->{ 'cab_id' }, $row->{ 'vol_idx' }\n");
    19982032        }
    19992033    };
     
    20032037        if (defined $vol_name and not defined $key->hard_volume) {
    20042038            $log->debug("retrying with 'any' volume");
    2005             return $self->find_instances($key->path, 'any');
     2039            return $self->find_instances($key->path, 'any', $find_invalid);
    20062040        }
    20072041        $log->logdie("database error: $@");
     
    20182052}
    20192053
     2054# this method returns instances on the specified volume
     2055# or a list of all available instances
     2056# it does NOT choose instances based on proximity
     2057# and it does NOT return invalid instances
    20202058sub find_instances_for_cull
    20212059{
     
    20612099    my $db  = $self->db($key);
    20622100
     2101    ## XXX this method is missing the alias deference section (see find_instances)
     2102    ## if aliases are intended to be compute nodes in the same cabinet / site as
     2103    ## the storage nodes, then this is not needed.
     2104
    20632105    # the key's volume can't be validiated on input for this method so we have
    20642106    # to check it after parsing the key
     
    20822124            unless ($rows > 0) {
    20832125                $query->finish;
    2084                 die("no instances on storage volume or volume is not avaiable for key: $key volume: $vol_name");
     2126                die("no instances on storage volume or volume is not available for key: $key volume: $vol_name");
    20852127            }
    20862128        } else {
     
    21052147        $db->rollback;
    21062148        # handle soft volumes
    2107         if (defined $vol_name and not defined $key->hard_volume) {
     2149        # we need to call find_intances_for_cull here so the returned structure
     2150        # is the same (find_instances just returns an array of strings)
     2151        if (defined $vol_name and not defined $key->hard_volume and ($vol_name ne "any")) {
    21082152            $log->debug("retrying with 'any' volume");
    2109             return $self->find_instances($key->path, 'any');
     2153            return $self->find_instances_for_cull($key->path, 'any');
    21102154        }
    21112155        $log->logdie("database error: $@");
    21122156    }
     2157    $db->commit;
    21132158
    21142159    # XXX remove this?
     
    22222267                }
    22232268            }
    2224 
    22252269            $db->commit;
    22262270            $log->debug("commit");
     
    22822326        $stat = $query->fetchrow_arrayref;
    22832327        $query->finish;
     2328        $db->commit;
    22842329    };
    22852330    $log->logdie("database error: $@") if $@;
     
    23182363    };
    23192364    $log->logdie("database error: $@") if $@;
     2365    $db->commit;
    23202366
    23212367    $log->logdie("no mounted volumes found") unless (scalar @$stats);
     
    24152461    my ($key, $name, $hard_volume) = @_;
    24162462   
    2417 #    $log->warn("_g_s_v: key:>$key< name:>$name< hard_vol:>$hard_volume<");
     2463    # track the number of calls to this function and
     2464    # give up after 10 attempts
     2465    $get_storage_volume_calls ++;
     2466
     2467#   $log->warn("_g_s_v: key:>$key< name:>$name< hard_vol:>$hard_volume<");
    24182468    my $sql = $self->sql;
    24192469    my $db  = $self->db($key);
     
    24272477            # %free, name, avaiable, allocate
    24282478            $rows = $query->execute($max_used_space, $name, 1, 1);
    2429             # XXX destinguish between non-existant and unavailable
     2479            # XXX distinguish between non-existant and unavailable
    24302480            unless ($rows > 0) {
    24312481                $query->finish;
     2482                $db->commit;
    24322483
    24332484                # if a volume name was specified, and is soft, and we failed to
     
    24422493            if ($rows > 1) {
    24432494                $query->finish;
     2495                $db->commit;
    24442496                die("affected row count is $rows instead of 1");
    24452497            }
     
    24492501            $rows = $query->execute($max_used_space, 1, 1, $topfew_count);
    24502502#           $log->warn("Storage_volume: $rows $topfew_count");
    2451             # there has to be atleast one storage volume
     2503            # there has to be at least one storage volume
    24522504            unless ($rows > 0) {
    24532505                $query->finish;
    2454                 die("no storage volume is available for key: $key volume: $name hard_volume: $hard_volume");
     2506                $db->commit;
     2507                # prevent failure in the die due to undefined variables
     2508                my $hard_volume_str = defined $hard_volume ? $hard_volume : "undefined";
     2509                my $name_str = defined $name ? $name : "undefined";
     2510                die("no storage volume is available for key: $key volume: $name_str hard_volume: $hard_volume_str");
    24552511            }
    24562512        }
     
    24652521            $log->error($@);
    24662522            $log->debug("retrying...");
    2467             return $self->_get_storage_volume(@_);
     2523            if ($get_storage_volume_calls < 10) {
     2524                return $self->_get_storage_volume(@_);
     2525            }
     2526            # else
     2527            $log->logdie("no available storage volume: $@");
    24682528        }
    24692529        # else
     
    25022562        unless ($rows > 0) {
    25032563            $query->finish;
    2504             die("Requested key $key does not exist");
     2564            die("Requested key $key does not exist (or cabinet is undefined)");
    25052565        }
    25062566        if ($rows == 1) {
     
    25132573            }
    25142574            $query->finish;
    2515         }
    2516         else {
     2575        } else {
     2576            # if instances are spread across multiple cabinets, allow the next instance to go anywhere
     2577            # NOTE: this does not prevent the new instance from going to the same volume as one of the existing instances
    25172578            $forbidden_cabinet = 0;
    25182579            $forbidden_site    = 0;
    25192580            $query->finish;
    25202581        }
    2521            
     2582        $db->commit;
    25222583
    25232584        $query = $db->prepare_cached( $sql->get_replication_volume_for_ext_id );
    2524         # ext_id, %free, avaiable, allocate
     2585        # ext_id, %free, available, allocate
     2586
    25252587        $rows = $query->execute($key->path, $max_used_space, 1, 1, $forbidden_cabinet, $forbidden_site, $topfew_count);
    2526         # XXX destinguish between non-existant and unaviable
     2588        # XXX distinguish between non-existant and unavailable
    25272589        unless ($rows > 0) {
    25282590            $query->finish;
     
    25442606        ($vol_id, $vol_host, $vol_path, $xattr, $free) = $query->fetchrow_array;
    25452607        $query->finish;
     2608        $db->commit;
    25462609    };
    25472610    $log->logdie("database error: $@") if $@;
     
    25902653        ($ext_id) = $query->fetchrow_array;
    25912654        $query->finish;
     2655        $db->commit;
     2656        ## if we do not call commit here, the transaction stays open blocking some operations below
    25922657    };
    25932658    if ($@) {
     
    26122677}
    26132678
    2614 
     2679# in the past, _is_valid_volume_name returned 'undef'. 
     2680# now it either returns 1 (success) or 0 (failure)
    26152681sub _is_valid_volume_name
    26162682{
     
    26502716        ($vol_id, $vol_path, $free) = $query->fetchrow_array;
    26512717        $query->finish;
     2718        $db->commit;
    26522719    };
    26532720    $log->logdie("database error: $@") if $@;
Note: See TracChangeset for help on using the changeset viewer.