Index: branches/pap/Nebulous-Server/bin/nebdiskd
===================================================================
--- branches/pap/Nebulous-Server/bin/nebdiskd	(revision 23948)
+++ branches/pap/Nebulous-Server/bin/nebdiskd	(revision 25027)
@@ -1,7 +1,5 @@
 #!/usr/bin/env perl
 
-# Copyright (C) 2007  Joshua Hoblitt
-# 
-# $Id: nebdiskd,v 1.14 2008-10-16 22:51:34 jhoblitt Exp $
+# Copyright (C) 2007-2009  Joshua Hoblitt
 
 use strict;
@@ -35,8 +33,9 @@
     $user,
     $group,
+    $retry,
 );
 
 GetOptions(
-    'dbhost|h=s'    => \$dbhost,
+    'dbhost|H=s'    => \$dbhost,
     'dbpass|p=s'    => \$dbpass,
     'dbuser|u=s'    => \$dbuser,
@@ -46,6 +45,7 @@
     'pidfile=s'     => \$pidfile,
     'restart|r'     => \$restart,
+    'retry=i'       => \$retry,
     'stop|s'        => \$stop,
-    'user=s'        => \$user,
+    'user|U=s'      => \$user,
     'verbose|v'     => \$verbose,
 ) || pod2usage( 2 );
@@ -61,10 +61,11 @@
 $dbhost     ||= $c->get_dbhost  || $ENV{'NEB_DBHOST'} || 'localhost';
 $dbuser     ||= $c->get_dbuser  || $ENV{'NEB_USER'};
-$dbpass     ||= $c->get_dbpass  || $ENV{'NEB_PASS'};
+$dbpass     ||= $c->get_dbpass  || $ENV{'NEB_PASS'} || undef;
 $pidfile    ||= $c->get_pidfile || "/var/tmp/nebdiskd";
 $user       ||= $c->get_user    || $<; # user
 $group      ||= $c->get_group   || $); # group
-
-my $mounts = $c->get_mounts;
+$retry      ||= $c->get_retry   || 1;
+
+#my $mounts = $c->get_mounts;
 my $poll_interval = $c->get_poll_interval || 5;
 
@@ -80,9 +81,10 @@
 $c->set_pidfile($pidfile);
 $c->set_poll_interval($poll_interval);
+$c->set_retry($retry);
 $c->write;
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
-pod2usage( -msg => "Required options: --db --user --pass", -exitval => 2 )
-    unless $db && $dbuser && $dbpass;
+pod2usage( -msg => "Required options: --db --dbuser", -exitval => 2 )
+    unless $db && $dbuser;
 
 # start up logging
@@ -108,7 +110,12 @@
     log4perl.appender.Mailer.to      = ps-ipp-ops@ifa.hawaii.edu
     log4perl.appender.Mailer.subject = nebdiskd alert
-    log4perl.appender.AppError.Filter= MatchWarn
+    log4perl.appender.Mailer.buffered = 0
+    log4perl.appender.Mailer.Filter= MatchWarn
     log4perl.appender.Mailer.layout = Log::Log4perl::Layout::PatternLayout
     log4perl.appender.Mailer.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} | %H | %p | %M - %m%n
+
+    log4perl.appender.Limiter              = Log::Log4perl::Appender::Limit
+    log4perl.appender.Limiter.appender     = Mailer
+    log4perl.appender.Limiter.block_period = 300
 ';
 Log::Log4perl::init(\$conf);
@@ -136,4 +143,5 @@
                 poll_interval   => $poll_interval,
                 debug           => $debug,
+                retry           => $retry,
         );
     };
@@ -155,7 +163,8 @@
     my $dbhost          = $p{dbhost} or return;
     my $dbuser          = $p{dbuser} or return;
-    my $dbpass          = $p{dbpass} or return;
+#    my $dbpass          = $p{dbpass} or return;
     my $poll_interval   = $p{poll_interval} || 60;
     my $debug           = $p{debug} || 0;
+    my $retry           = $p{retry} || 1;
 
     # setup the db on every pass incase the database died on us
@@ -168,20 +177,41 @@
 
     eval {
-        my $r_query = $dbh->prepare_cached("REPLACE INTO mount VALUES(?, ?, ?)");
-        my $d_query = $dbh->prepare_cached("DELETE FROM mount WHERE mountpoint = ?");
-
+        my $r_query = $dbh->prepare_cached("REPLACE INTO mountedvol SELECT *, ?, ? FROM volume WHERE mountpoint = ?");
+        my $d_query = $dbh->prepare_cached("DELETE FROM mountedvol WHERE mountpoint = ?");
+
+        # get list of mount points
+        my $mounts = [];
+        {
+            # there may be multiple vol_ids per mountpoint but we only need to
+            # check each mointpont once
+            my $query = $dbh->prepare_cached("SELECT DISTINCT mountpoint FROM volume WHERE available = 1");
+            $query->execute;
+            while (my $row = $query->fetchrow_hashref) {
+                push @$mounts, $row;
+            }
+            $query->finish;
+        }
+        
         # determine valid mountpoints
         foreach my $mnt (@$mounts) {
-            $log->debug("checking $mnt");
+            my $mountpoint = $mnt->{'mountpoint'};
+            $log->debug("checking $mountpoint");
             # this /SHOULD/ fail if the mount point is handled by the
             # automounter and it fails to mount
-            eval {
-                unless (is_mountpoint($mnt)) {
+            my $tries = 0;
+            TEST: eval {
+                $tries++;
+                unless (is_mountpoint($mountpoint)) {
                     $log->warn("$mnt is not a valid mountpoint");
                 }
             };
             if ($@) {
+                # try is_mountpoint() again if $retry > 1
+                if ($tries < $retry) {
+                    $log->warn("retrying test of $mountpoint");
+                    goto TEST; 
+                }
                 $log->warn($@);
-                $d_query->execute($mnt);
+                $d_query->execute($mountpoint);
                 next;
             }
@@ -190,23 +220,24 @@
             # we determine if it's a valid mountpoint incase
             # is_mountpoint() invokes the automounter
-            my $dev_info = df($mnt, 1024);
+            my $dev_info = df($mountpoint, 1024);
             unless (defined $dev_info) {
-                $log->error("can't find device info for $mnt");
+                $log->error("can't find device info for $mountpoint");
                 next;
             }
 
-            $r_query->execute($mnt, @$dev_info{qw( blocks used )});
-            $log->debug("adding $mnt to db");
+            # find vol_id(s) for mountpoint
+            $r_query->execute(@$dev_info{qw( blocks used )}, $mountpoint);
+            $log->debug("adding $mountpoint to db");
 
         }
 
-        $dbh->do("call getmountedvol()");
-
-        $dbh->commit;
-        $log->debug("commited to database");
+#        $dbh->do("call getmountedvol()");
+
+#        $dbh->commit;
+#        $log->debug("commited to database");
     };
     if ($@) {
-        $dbh->rollback;
-        $log->debug("rolledback transaction");
+#        $dbh->rollback;
+#        $log->debug("rolledback transaction");
         $log->logdie($@);
     }
@@ -235,8 +266,9 @@
     my %p = @_;
 
+    # $p{dbpass} may be undef;
+
     return unless defined $p{db}
               and defined $p{dbhost}
-              and defined $p{dbuser}
-              and defined $p{dbpass};
+              and defined $p{dbuser};
 
     my $sql = Nebulous::Server::SQL->new;
@@ -249,5 +281,5 @@
             RaiseError => 1,
             PrintError => 1,
-            AutoCommit => 0,
+            AutoCommit => 1, # don't want this to be trasnactional
         },
     );
@@ -255,8 +287,8 @@
     eval {
         $dbh->do( $sql->set_transaction_model );
-        $dbh->commit;
+#        $dbh->commit;
     };
     if ($@) { 
-        $dbh->rollback;
+#        $dbh->rollback;
         $log->logdie($@);
     }
@@ -344,5 +376,8 @@
 =head1 SYNOPSIS
 
-    nebdiskd [--db <db name>] [--user <db username>] [--pass <db password>] [--debug] [--pidfile <filename>] [--stop] [--restart] [--verbose]
+    nebdiskd [--db|-D <db name>] [--dbhost|-H <db hostname>
+    [--dbuser|-u <db username>] [--dbpass|-p <db password>] [--debug|-d]
+    [--user|-U <username>] [--group|-g <groupname>] [--pidfile <filename>]
+    [--retry <n>] [--stop|-s] [--restart|-r] [--verbose|-v]
 
 =head1 DESCRIPTION
@@ -355,5 +390,5 @@
 =over 4
 
-=item * --db|-d <db name>
+=item * --db|-D <db name>
 
 Name of database (C<namespace>) to write too.
@@ -362,5 +397,5 @@
 variable is set.
 
-=item * --user|-u <db username>
+=item * --dbuser|-u <username>
 
 Username to authenticate with.
@@ -369,12 +404,19 @@
 variable is set.
 
-=item * --pass|-p <db password>
+=item * --dbpass|-p <password>
 
 Password to authenticate with.
+
+Optional if defined in the F<.nebdiskdrc> file or the appropriate environment
+variable is set or if the database does not require a password.
+
+=item * --dbhost|-H <hostname>
+
+Database host to connect to.
 
 Optional if defined in the F<.nebdiskdrc> file or the appropriate environment
 variable is set.
 
-=item * --debug
+=item * --debug|-d
 
 This flag prevents the program from "daemonizing" so output can be sent to
@@ -397,5 +439,10 @@
 instance.
 
-=item * --verbose|-r
+=item * --retry
+
+The number of times to test a mountpoint for "mountedness" before giving up on
+it.
+
+=item * --verbose|-v
 
 Turns on informational/debugging messages to be sent to the
@@ -403,4 +450,12 @@
 with C<--debug>.
 
+=item * --user|-U
+
+user account to run daemon as.
+
+=item * --group|-g
+
+group to run daemon as.
+
 =back
 
@@ -415,13 +470,13 @@
 =item * C<NEB_DB>
 
-Equivalent to --db|-d
+Equivalent to --db|-D
 
 =item * C<NEB_USER>
 
-Equivalent to --user|-u
+Equivalent to --dbuser|-u
 
 =item * C<NEB_PASS>
 
-Equivalent to --pass|-p 
+Equivalent to --dbpass|-p 
 
 =back
@@ -439,10 +494,7 @@
     dbpass: '@neb@'
     dbuser: nebulous
-    mounts:
-      - /mnt
-      - /tmp
-      - /usr
     pidfile: /var/tmp/nebdiskd
     poll_interval: 5
+    retry: 3
 
 The values C<db>, C<dbpass>, C<dbuser>, and C<pidfile> have the same semantics
@@ -451,10 +503,4 @@
 =over 4
 
-=item * C<mounts>
-
-A list of "paths" to C<stat(2)> before mounted volumes are polled.  The propose
-of this option is to attempt to keep "automounted" volumes mounted while this
-program is running.
-
 This value may be omitted or left blank.
 
@@ -465,4 +511,8 @@
 This value may be omitted or left blank.  The default value is C<60>s.
 
+=item * C<retry>
+
+Same as C<--retry>.
+
 =back
 
@@ -481,5 +531,5 @@
 =head1 COPYRIGHT
 
-Copyright (C) 2007  Joshua Hoblitt.  All rights reserved.
+Copyright (C) 2007-2009  Joshua Hoblitt.  All rights reserved.
 
 This program is free software; you can redistribute it and/or modify it under
