Index: trunk/Nebulous-Server/bin/neb-admin
===================================================================
--- trunk/Nebulous-Server/bin/neb-admin	(revision 17771)
+++ trunk/Nebulous-Server/bin/neb-admin	(revision 17815)
@@ -3,5 +3,5 @@
 # Copyright (C) 2005-2008  Joshua Hoblitt
 #
-# $Id: neb-admin,v 1.1 2008-05-22 04:08:29 jhoblitt Exp $
+# $Id: neb-admin,v 1.2 2008-05-27 21:59:53 jhoblitt Exp $
 
 use strict;
@@ -19,5 +19,5 @@
 use Pod::Usage qw( pod2usage );
 
-my ($db, $dbuser, $dbpass, $server);
+my ($db, $dbuser, $dbpass, $server, $limit);
 
 $db     = $ENV{'NEB_DB'} unless $db;
@@ -31,4 +31,5 @@
     'pass=s'        => \$dbpass,
     'server|s=s'    => \$server,
+    'limit|l=i'     => \$limit,
 ) || pod2usage( 2 );
 
@@ -38,4 +39,7 @@
 pod2usage( -msg => "Required options: --db --user --pass", -exitval => 2 )
     unless $db && $dbuser && $dbpass;
+
+# set default limit to 5
+$limit ||= 5;
 
 my $neb = Nebulous::Client->new(
@@ -60,5 +64,6 @@
 
 # so_id, ext_id, instances, available_instances, need_recovery, recoverable
-my $query = $dbh->prepare( $sql->find_objects_with_unavailable_instances );
+my $query = $dbh->prepare( $sql->find_objects_with_unavailable_instances
+        . " LIMIT $limit" );
 $query->execute;
 
@@ -68,4 +73,6 @@
 }
 $query->finish;
+    
+print "replciate MULTI\n\n";
 
 foreach my $obj (@rows) {
@@ -75,4 +82,5 @@
     my $key = $obj->{ext_id};
     my $has = $obj->{instances};
+    my $vol_name = $obj->{volume_name};
     my $available = $obj->{available_instances} || 0;
     my $need_recovery = $obj->{need_recovery};
@@ -84,5 +92,5 @@
     # 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;
+#    next unless $need_recovery;
     unless ($recoverable) {
         warn "so_id: $so_id key: \'$key\' ",
@@ -96,11 +104,49 @@
     next unless $need;
 
-    for (; $need > 0; $need--) {
-        warn "so_id: $so_id key: \'$key\' ",
-            "has $available available instances, target $copies -- replicating"
-            or warn "so_id: $so_id key: \'$key\' replication failed";
-
-        $need++;
+    my %md = (
+        key         => $key,
+        need_copies => $need,
+        volume_name => $vol_name,
+    );
+
+    print_metadata("replicate", \%md);
+    print "\n";
+}
+
+sub print_metadata
+{
+    my ($name, $pairs) = @_;
+
+    print "$name METADATA\n";
+
+    # format from formatMetadataItem() in pzMetadataConfig.c
+    foreach my $key (keys %$pairs) {
+        my $value = $pairs->{$key};
+        if (looks_like_number($value)) {
+            printf("   " . "%-15s  %-8s  %-15s\n", $key, "S32", $value);
+        } else {
+            printf("   " . "%-15s  %-8s  %-15s\n", $key, "STR", $value);
+        }
     }
+    
+    print "END\n";
+}
+
+# looks_like_number() was stolen from Scalar::Util
+#
+# Copyright (c) 1997-2006 Graham Barr <gbarr@pobox.com>. All rights reserved.
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+sub looks_like_number {
+  local $_ = shift;
+
+  # checks from perlfaq4
+  return 0 if !defined($_) or ref($_);
+  return 1 if (/^[+-]?\d+$/); # is a +/- integer
+  return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # a C float
+  return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) or ($] >= 5.006001 and /^Inf$/i);
+
+  0;
 }
 
