From a55933e19f2f2e67eebba5b63eb7cd6dd671c2ec Mon Sep 17 00:00:00 2001
From: Mark Harrison <mark@omniti.com>
Date: Wed, 21 May 2008 21:29:29 +0000
Subject: [PATCH] Merging reloading code from markdevel to trunk.

git-svn-id: https://labs.omniti.com/resmon/trunk@106 8c0face9-b7db-6ec6-c4b3-d5f7145c7d55
---
 lib/Resmon/Module.pm | 22 ++++++++++++++++++++++
 resmon               | 24 ++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/lib/Resmon/Module.pm b/lib/Resmon/Module.pm
index 90bcab0..fe83afb 100755
--- a/lib/Resmon/Module.pm
+++ b/lib/Resmon/Module.pm
@@ -2,6 +2,7 @@ package Resmon::Module;
 
 use strict;
 use Data::Dumper;
+use FileHandle;
 use UNIVERSAL qw/isa/;
 my %coderefs;
 
@@ -74,5 +75,26 @@ sub config_as_hash {
   return $conf;
 }
 
+sub reload_module {
+    my $self = shift;
+    my $class = ref($self) || $self;
+    $class =~ s/::/\//g;
+    my $file = $INC{"$class.pm"};
+    print STDERR "Reloading module: $class\n";
+    my $fh = FileHandle->new($file);
+    local($/);
+    my $redef = 0;
+    local($SIG{__WARN__}) = sub {
+        if($_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) {
+            $redef++;
+            return;
+        }
+        warn @_;
+    };
+    eval <$fh>;
+    return $@ if $@;
+    return $redef;
+}
+
 $rmloading = "Demand loading";
 1;
diff --git a/resmon b/resmon
index c8f9244..194a3de 100755
--- a/resmon
+++ b/resmon
@@ -37,13 +37,33 @@ sub configure {
 }
 
 sub reconfigure {
-    print STDERR "Reloading...\n";
+    my $modstatus = "";
+    print STDERR "Reloading modules...\n";
+    my $modules = $config->{Module};
+    while ( my ($key, $value) = each(%$modules) ) {
+        my $mod = $value->[0]; # Only need the first of each module
+        my $errs = $mod->reload_module();
+        if ($errs) {
+            my $modname = ref($mod) || $mod;
+            $modname =~ s/Resmon::Module:://;
+            $modstatus .= "$modname ";
+            print STDERR " Failed to reload module $modname\n";
+            print STDERR $errs;
+            print STDERR " This module is no longer available.\n";
+        }
+    }
+    print STDERR "Reloading configuration...\n";
     eval { configure(); };
     if ($@) {
+        # The config object is recreated every time we reload, so we shouldn't
+        # need to reset this BAD value to empty on a successful load.
+        $config->{'configstatus'} = "BAD";
         print STDERR " Failed to reload: ";
         print STDERR $@;
         print STDERR " Continuing with old configuration\n";
     }
+
+    $config->{'modstatus'} = $modstatus;
 }
 
 $SIG{'HUP'} = \&reconfigure;
@@ -98,7 +118,7 @@ while(1) {
       };
       if($checkstat) {
         $results->{state} = 'BAD';
-        $results->{message} = $checkstat;
+        $results->{message} = "Bad module or problem running handler code.";
       } else {
         $results->{state} = $check_rv;
         $results->{message} = $check_mess;
-- 
GitLab