Index: /trunk/Nebulous-Server/bin/neb-admin
===================================================================
--- /trunk/Nebulous-Server/bin/neb-admin	(revision 20175)
+++ /trunk/Nebulous-Server/bin/neb-admin	(revision 20176)
@@ -3,5 +3,5 @@
 # Copyright (C) 2005-2008  Joshua Hoblitt
 #
-# $Id: neb-admin,v 1.12 2008-10-11 02:13:23 jhoblitt Exp $
+# $Id: neb-admin,v 1.13 2008-10-15 20:58:02 jhoblitt Exp $
 
 use strict;
@@ -12,6 +12,4 @@
 
 use DBI;
-use Nebulous::Client;
-#use Nebulous::Server::SQL;
 use Net::Server::Daemonize qw( check_pid_file create_pid_file unlink_pid_file );
 use URI;
@@ -20,5 +18,14 @@
 use Pod::Usage qw( pod2usage );
 
-my ($db, $dbhost, $dbuser, $dbpass, $pending, $limit, $verbose);
+my (
+    $db,
+    $dbhost,
+    $dbpass,
+    $dbuser,
+    $limit,
+    $pending,
+    $removal,
+    $verbose,
+);
 
 $db     = $ENV{'NEB_DB'};
@@ -33,4 +40,5 @@
     'pass|p=s'              => \$dbpass,
     'pendingreplicate|r'    => \$pending,
+    'pendingremoval'        => \$removal,
     'limit|l=i'             => \$limit,
     'verbose|v'             => \$verbose,
@@ -44,5 +52,5 @@
     if defined $limit and not defined $pending;
 pod2usage( -msg => "no operation specified", -exitval => 2 )
-    unless defined $pending;
+    unless defined $pending or defined $removal;
 
 # set default limit to 5
@@ -67,107 +75,176 @@
 );
 
-#my $sql = Nebulous::Server::SQL->new();
-
+if ($pending) {
+    pending();
+} elsif ($removal) {
+    removal();
+} else {
+    die "THIS SHOULD NOT HAPPEN";
+}
+
+sub pending
+{
 # so_id, ext_id, instances, available_instances, need_recovery, recoverable
+    $dbh->do("CREATE TEMPORARY TABLE mymountedvol LIKE mountedvol");
+    $dbh->do("INSERT INTO mymountedvol SELECT * FROM mountedvol");
+    $dbh->do("CREATE TEMPORARY TABLE myvolume LIKE volume");
+    $dbh->do("INSERT INTO myvolume SELECT * FROM volume");
+
+    my $query = $dbh->prepare(
+    "        SELECT
+                storage_object.so_id,
+                ext_id,
+                count(ins_id) as instances,
+                myvolume.name as volume_name,
+                myvolume.host as volume_host,
+                count(mymountedvol.vol_id) as available_instances,
+                count(mymountedvol.vol_id) > 0 as recoverable,
+                storage_object_xattr.value as copies
+            FROM storage_object
+            JOIN instance
+                USING(so_id)
+            JOIN myvolume
+                USING(vol_id)
+            LEFT JOIN storage_object_xattr
+                ON storage_object.so_id = storage_object_xattr.so_id
+            JOIN mymountedvol
+                USING(vol_id)
+            WHERE mymountedvol.available = 1
+    --        WHERE storage_object_xattr.name = 'user.copies'
+            GROUP BY so_id
+            HAVING available_instances < instances OR instances < copies
+            LIMIT $limit"
+    );
+    $query->execute;
+
+    $dbh->do("DROP TABLE IF EXISTS mymountedvol");
+
+    my @rows;
+    while (my $row = $query->fetchrow_hashref) {
+        push @rows, $row;        
+    }
+    $query->finish;
+        
+    exit unless scalar @rows;
+
+    print "replicatePending MULTI\n\n";
+
+    foreach my $obj (@rows) {
+        if (defined $verbose) {
+            require Data::Dumper;
+            print Data::Dumper::Dumper($obj);
+        }
+
+        my $so_id = $obj->{so_id};
+        my $key = $obj->{ext_id};
+        my $has = $obj->{instances};
+        my $vol_name = $obj->{volume_name};
+        my $vol_host = $obj->{volume_host};
+        my $available = $obj->{available_instances} || 0;
+        my $need_recovery = $obj->{need_recovery};
+        my $recoverable = $obj->{recoverable};
+        # if the copies xattr is unset and the object has 2 or more instances, we
+        # will assume a target of 2 copies
+        my $copies = $obj->{copies} || 2;
+
+        # objects with only a single instance that are offline are unrecoverable so
+        # we don't need to handle that special case
+#    next unless $need_recovery;
+        unless ($recoverable) {
+            warn "so_id: $so_id key: \'$key\' ",
+                "can not be recovered - no available instances\n";
+            next;
+        }
+
+        my $need = $copies - $available;
+        $need = 0 if $need < 0;
+
+        next unless $need;
+
+        my %md = (
+            key         => $key,
+            need_copies => $need,
+            volume_name => $vol_name,
+            volume_host => $vol_host,
+        );
+
+        print_metadata("replicatePending", \%md);
+        print "\n";
+    }
+
+    return 1;
+}
+
+
+sub removal
 {
-    my $query = $dbh->prepare("CREATE TEMPORARY TABLE mymountedvol LIKE mountedvol");
+# so_id, ext_id, instances, available_instances, need_recovery, recoverable
+    $dbh->do("CREATE TEMPORARY TABLE mymountedvol LIKE mountedvol");
+    $dbh->do("INSERT INTO mymountedvol SELECT * FROM mountedvol");
+    $dbh->do("CREATE TEMPORARY TABLE myvolume LIKE volume");
+    $dbh->do("INSERT INTO myvolume SELECT * FROM volume");
+
+    my $query = $dbh->prepare(
+    );
     $query->execute;
+
+    $dbh->do("DROP TABLE IF EXISTS mymountedvol");
+
+    my @rows;
+    while (my $row = $query->fetchrow_hashref) {
+        push @rows, $row;        
+    }
+    $query->finish;
+        
+    exit unless scalar @rows;
+
+    print "replicatePending MULTI\n\n";
+
+    foreach my $obj (@rows) {
+        if (defined $verbose) {
+            require Data::Dumper;
+            print Data::Dumper::Dumper($obj);
+        }
+
+        my $so_id = $obj->{so_id};
+        my $key = $obj->{ext_id};
+        my $has = $obj->{instances};
+        my $vol_name = $obj->{volume_name};
+        my $vol_host = $obj->{volume_host};
+        my $available = $obj->{available_instances} || 0;
+        my $need_recovery = $obj->{need_recovery};
+        my $recoverable = $obj->{recoverable};
+        # if the copies xattr is unset and the object has 2 or more instances, we
+        # will assume a target of 2 copies
+        my $copies = $obj->{copies} || 2;
+
+        # objects with only a single instance that are offline are unrecoverable so
+        # we don't need to handle that special case
+#    next unless $need_recovery;
+        unless ($recoverable) {
+            warn "so_id: $so_id key: \'$key\' ",
+                "can not be recovered - no available instances\n";
+            next;
+        }
+
+        my $need = $copies - $available;
+        $need = 0 if $need < 0;
+
+        next unless $need;
+
+        my %md = (
+            key         => $key,
+            need_copies => $need,
+            volume_name => $vol_name,
+            volume_host => $vol_host,
+        );
+
+        print_metadata("replicatePending", \%md);
+        print "\n";
+    }
+
+    return 1;
 }
 
-{
-    my $query = $dbh->prepare("INSERT INTO mymountedvol SELECT * FROM mountedvol");
-    $query->execute;
-}
-
-{
-    my $query = $dbh->prepare("CREATE TEMPORARY TABLE myvolume LIKE volume");
-    $query->execute;
-}
-
-{
-    my $query = $dbh->prepare("INSERT INTO myvolume SELECT * FROM volume");
-    $query->execute;
-}
-
-my $query = $dbh->prepare(
-"        SELECT
-            storage_object.so_id,
-            ext_id,
-            count(ins_id) as instances,
-            myvolume.name as volume_name,
-            myvolume.host as volume_host,
-            count(mymountedvol.vol_id) as available_instances,
-            count(mymountedvol.vol_id) > 0 as recoverable,
-            storage_object_xattr.value as copies
-        FROM storage_object
-        JOIN instance
-            USING(so_id)
-        JOIN myvolume
-            USING(vol_id)
-        LEFT JOIN storage_object_xattr
-            ON storage_object.so_id = storage_object_xattr.so_id
-        JOIN mymountedvol
-            USING(vol_id)
-        WHERE mymountedvol.available = 1
---        WHERE storage_object_xattr.name = 'user.copies'
-        GROUP BY so_id
-        HAVING available_instances < instances OR instances < copies
-        LIMIT $limit" );
-$query->execute;
-
-$dbh->do("DROP TABLE IF EXISTS mymountedvol");
-
-my @rows;
-while (my $row = $query->fetchrow_hashref) {
-    push @rows, $row;        
-}
-$query->finish;
-    
-exit unless scalar @rows;
-
-print "replicatePending MULTI\n\n";
-
-foreach my $obj (@rows) {
-    if (defined $verbose) {
-        require Data::Dumper;
-        print Data::Dumper::Dumper($obj);
-    }
-
-    my $so_id = $obj->{so_id};
-    my $key = $obj->{ext_id};
-    my $has = $obj->{instances};
-    my $vol_name = $obj->{volume_name};
-    my $vol_host = $obj->{volume_host};
-    my $available = $obj->{available_instances} || 0;
-    my $need_recovery = $obj->{need_recovery};
-    my $recoverable = $obj->{recoverable};
-    # if the copies xattr is unset and the object has 2 or more instances, we
-    # will assume a target of 2 copies
-    my $copies = $obj->{copies} || 2;
-
-    # objects with only a single instance that are offline are unrecoverable so
-    # we don't need to handle that special case
-#    next unless $need_recovery;
-    unless ($recoverable) {
-        warn "so_id: $so_id key: \'$key\' ",
-            "can not be recovered - no available instances\n";
-        next;
-    }
-
-    my $need = $copies - $available;
-    $need = 0 if $need < 0;
-
-    next unless $need;
-
-    my %md = (
-        key         => $key,
-        need_copies => $need,
-        volume_name => $vol_name,
-        volume_host => $vol_host,
-    );
-
-    print_metadata("replicatePending", \%md);
-    print "\n";
-}
 
 sub print_metadata
