You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/01/14 21:50:30 UTC

svn commit: r899404 - in /incubator/vcl/trunk/managementnode/lib/VCL: Module/OS.pm Module/OS/Linux/UnixLab.pm Module/OS/Windows.pm Module/Provisioning/Lab.pm reclaim.pm

Author: arkurth
Date: Thu Jan 14 20:50:29 2010
New Revision: 899404

URL: http://svn.apache.org/viewvc?rev=899404&view=rev
Log:
VCL-185
Removed obsolete code from reclaim.pm which was no longer being called because the Linux modules now implement a sanitize() subroutine.  Moved call to sanitize() out of reclaim.pm::process and into a new sub called call_os_sanitize() so that the code can be reused.

Moved get_currentimage_txt_contents() and get_current_image_name() out of Windows.pm and into OS.pm so that they can be used by the Linux OS modules. Created get_current_image_name() sub in UnixLab.pm that overrides the one in OS.pm. Lab machines don't contain a currentimage.txt file and the image name should be correct for lab reservations, so it just returns the reservation image name.

Renamed the initialize() sub in Lab.pm to load(). It will get called at the same time when a reservation is processed.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm
    incubator/vcl/trunk/managementnode/lib/VCL/reclaim.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=899404&r1=899403&r2=899404&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Thu Jan 14 20:50:29 2010
@@ -169,6 +169,96 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_currentimage_txt_contents
+
+ Parameters  : None
+ Returns     : If successful: array
+               If failed: false
+ Description : Reads the currentimage.txt file on a computer and returns its
+               contents as an array. Each array element represents a line in
+               the file.
+
+=cut
+
+sub get_currentimage_txt_contents {
+	my $self = shift;
+	if (ref($self) !~ /VCL::Module/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+
+	# Attempt to retrieve the contents of currentimage.txt
+	my $cat_command = "cat ~/currentimage.txt";
+	my ($cat_exit_status, $cat_output) = run_ssh_command($computer_node_name, $management_node_keys, $cat_command, '', '', 0);
+	if (defined($cat_exit_status) && $cat_exit_status == 0) {
+		notify($ERRORS{'DEBUG'}, 0, "retrieved currentimage.txt contents from $computer_node_name");
+	}
+	elsif (defined($cat_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve currentimage.txt from $computer_node_name, exit status: $cat_exit_status, output:\n@{$cat_output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to failed to retrieve currentimage.txt from $computer_node_name");
+		return;
+	}
+
+	notify($ERRORS{'DEBUG'}, 0, "found " . @{$cat_output} . " lines in currentimage.txt on $computer_node_name");
+
+	return @{$cat_output};
+} ## end sub get_currentimage_txt_contents
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_current_image_name
+
+ Parameters  : None
+ Returns     : If successful: string
+               If failed: false
+ Description : Reads the currentimage.txt file on a computer and returns a
+               string containing the name of the loaded image.
+
+=cut
+
+sub get_current_image_name {
+	my $self = shift;
+	if (ref($self) !~ /VCL::Module/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $computer_node_name = $self->data->get_computer_node_name();
+
+	# Get the contents of the currentimage.txt file
+	my @current_image_txt_contents;
+	if (@current_image_txt_contents = $self->get_currentimage_txt_contents()) {
+		notify($ERRORS{'DEBUG'}, 0, "retrieved currentimage.txt contents from $computer_node_name");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve currentimage.txt contents from $computer_node_name");
+		return;
+	}
+
+	# Make sure an empty array wasn't returned
+	if (defined $current_image_txt_contents[0]) {
+		my $current_image_name = $current_image_txt_contents[0];
+
+		# Remove any line break characters
+		$current_image_name =~ s/[\r\n]*//g;
+
+		notify($ERRORS{'DEBUG'}, 0, "name of image currently loaded on $computer_node_name: $current_image_name");
+		return $current_image_name;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "empty array was returned when currentimage.txt contents were retrieved from $computer_node_name");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm?rev=899404&r1=899403&r2=899404&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm Thu Jan 14 20:50:29 2010
@@ -287,6 +287,38 @@
 	notify($ERRORS{'OK'}, 0, "$computer_node_name has been sanitized");
 	return 1;
 } ## end sub sanitize
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_current_image_name
+
+ Parameters  : None
+ Returns     : If successful: string
+               If failed: 0
+ Description : Returns the name of the reservation image. This is used in
+               reclaim.pm to determine if a computer needs to be reloaded or
+					sanitized. Lab machines should always be sanitized.
+
+=cut
+
+sub get_current_image_name {
+	my $self = shift;
+	if (ref($self) !~ /VCL::Module/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $image_name = $self->data->get_image_name();
+	if ($image_name) {
+		notify($ERRORS{'DEBUG'}, 0, "returning reservation image name: $image_name");
+		return $image_name;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve reservation image name");
+		return 0;
+	}
+}
+
 #/////////////////////////////////////////////////////////////////////////////
 
 1;

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=899404&r1=899403&r2=899404&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Thu Jan 14 20:50:29 2010
@@ -3980,91 +3980,6 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 get_currentimage_txt_contents
-
- Parameters  : 
- Returns     : array containing lines in currentimage.txt
- Description : 
-
-=cut
-
-sub get_currentimage_txt_contents {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-
-	my $management_node_keys = $self->data->get_management_node_keys();
-	my $computer_node_name   = $self->data->get_computer_node_name();
-
-	# Attempt to retrieve the contents of currentimage.txt
-	my $cat_command = "cat ~/currentimage.txt";
-	my ($cat_exit_status, $cat_output) = run_ssh_command($computer_node_name, $management_node_keys, $cat_command);
-	if (defined($cat_exit_status) && $cat_exit_status == 0) {
-		notify($ERRORS{'DEBUG'}, 0, "retrieved currentimage.txt from $computer_node_name");
-	}
-	elsif (defined($cat_exit_status)) {
-		notify($ERRORS{'WARNING'}, 0, "failed to retrieve currentimage.txt from $computer_node_name, exit status: $cat_exit_status, output:\n@{$cat_output}");
-		return ();
-	}
-	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to failed to retrieve currentimage.txt from $computer_node_name");
-		return;
-	}
-
-	notify($ERRORS{'DEBUG'}, 0, "found " . @{$cat_output} . " lines in currentimage.txt on $computer_node_name");
-
-	return @{$cat_output};
-} ## end sub get_currentimage_txt_contents
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_current_image_name
-
- Parameters  : 
- Returns     : string containing image name loaded on computer
- Description : 
-
-=cut
-
-sub get_current_image_name {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-
-	my $computer_node_name = $self->data->get_computer_node_name();
-
-	# Get the contents of the currentimage.txt file
-	my @current_image_txt_contents;
-	if (@current_image_txt_contents = $self->get_currentimage_txt_contents()) {
-		notify($ERRORS{'DEBUG'}, 0, "retrieved currentimage.txt contents from $computer_node_name");
-	}
-	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to retrieve currentimage.txt contents from $computer_node_name");
-		return;
-	}
-
-	# Make sure an empty array wasn't returned
-	if (defined $current_image_txt_contents[0]) {
-		my $current_image_name = $current_image_txt_contents[0];
-
-		# Remove any line break characters
-		$current_image_name =~ s/[\r\n]*//g;
-
-		notify($ERRORS{'DEBUG'}, 0, "returning name of image currently loaded on $computer_node_name: $current_image_name");
-		return $current_image_name;
-	}
-	else {
-		notify($ERRORS{'WARNING'}, 0, "empty array was returned when currentimage.txt contents were retrieved from $computer_node_name");
-		return;
-	}
-} ## end sub get_current_image_name
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 firewall_enable_ping
 
  Parameters  : 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm?rev=899404&r1=899403&r2=899404&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm Thu Jan 14 20:50:29 2010
@@ -63,7 +63,7 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 initialize
+=head2 load
 
  Parameters  :
  Returns     :
@@ -71,7 +71,7 @@
 
 =cut
 
-sub initialize {
+sub load {
 	my $self                  = shift;
 	my $request_id            = $self->data->get_request_id();
 	my $reservation_id        = $self->data->get_reservation_id();
@@ -79,7 +79,7 @@
 	my $request_check_time    = $self->data->get_request_check_time();
 	my $computer_id           = $self->data->get_computer_id();
 
-	notify($ERRORS{'OK'}, 0, "initializing Lab module, computer id: $computer_id, is parent reservation: $reservation_is_parent");
+	notify($ERRORS{'OK'}, 0, "computer id: $computer_id, is parent reservation: $reservation_is_parent");
 
 	# Check if this is a preload request
 	# Nothing needs to be done for lab preloads
@@ -109,7 +109,7 @@
 	else {
 		notify($ERRORS{'OK'}, 0, "check_time result is $request_check_time, reservation will be processed");
 	}
-} ## end sub initialize
+}
 
 #/////////////////////////////////////////////////////////////////////////////
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/reclaim.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/reclaim.pm?rev=899404&r1=899403&r2=899404&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/reclaim.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/reclaim.pm Thu Jan 14 20:50:29 2010
@@ -78,189 +78,79 @@
 
 =head2 process
 
- Parameters  : $request_data_hash_reference
- Returns     : 1 if successful, 0 otherwise
- Description : Processes a reservation in the reclaim state. You must pass this
-               method a reference to a hash containing request data.
+ Parameters  : Reference to state object
+ Returns     : Nothing, process always exits
+ Description : Processes a reservation in the timeout and deleted states.
 
 =cut
 
 sub process {
 	my $self = shift;
 	
-	# Store hash variables into local variables
-	my $request_data = $self->data->get_request_data;
-
-	my $request_id                 = $self->data->get_request_data();
-	my $request_state_name         = $self->data->get_request_state_name();
-	my $request_laststate_name     = $self->data->get_request_laststate_name();
-	my $reservation_id             = $self->data->get_reservation_id();
-	my $reservation_remoteip       = $self->data->get_reservation_remote_ip();
-	my $computer_type              = $self->data->get_computer_type();
-	my $computer_id                = $self->data->get_computer_id();
-	my $computer_shortname         = $self->data->get_computer_short_name();
-	my $computer_hostname          = $self->data->get_computer_host_name();
-	my $computer_ipaddress         = $self->data->get_computer_ip_address();
-	my $computer_state_name        = $self->data->get_computer_state_name();
-	my $image_os_name              = $self->data->get_image_os_name();
-	my $image_os_type              = $self->data->get_image_os_type();
-	my $imagerevision_imagename    = $self->data->get_image_name();
-	my $user_unityid               = $self->data->get_user_login_id();
-	my $computer_currentimage_name = $self->data->get_computer_currentimage_name();
-
+	# Get required data
+	my $request_data                        = $self->data->get_request_data();
+	my $reservation_id                      = $self->data->get_reservation_id();
+	my $request_state_name                  = $self->data->get_request_state_name();
+	my $request_laststate_name              = $self->data->get_request_laststate_name();
+	my $computer_id                         = $self->data->get_computer_id();
+	my $computer_type                       = $self->data->get_computer_type();
+	my $computer_shortname                  = $self->data->get_computer_short_name();
+	my $computer_state_name                 = $self->data->get_computer_state_name();
+	my $computer_currentimage_name          = $self->data->get_computer_currentimage_name();
+	my $os_current_image_name               = $self->os->get_current_image_name();
+	
 	# Insert into computerloadlog if request state = timeout
 	if ($request_state_name =~ /timeout|deleted/) {
 		insertloadlog($reservation_id, $computer_id, $request_state_name, "reclaim: starting $request_state_name process");
 	}
-	insertloadlog($reservation_id, $computer_id, "info", "reclaim: request state is $request_state_name");
-	insertloadlog($reservation_id, $computer_id, "info", "reclaim: request laststate is $request_laststate_name");
-	insertloadlog($reservation_id, $computer_id, "info", "reclaim: computer type is $computer_type");
-	insertloadlog($reservation_id, $computer_id, "info", "reclaim: computer OS is $image_os_name");
-
-	# If request laststate = new, nothing needs to be done
-	if ($request_laststate_name =~ /new/) {
-		notify($ERRORS{'OK'}, 0, "request laststate is $request_laststate_name, nothing needs to be done to the computer");
-		# Proceed to set request to complete and computer to available
+	
+	# Make sure computer current image name was retrieved from the database
+	if (!$computer_currentimage_name) {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve computer current image name from the database, computer will be reloaded");
+		$self->insert_reload_and_exit();
 	}
-
+	
+	# Reload the computer if unable to retrieve the current image name
+	if (!$os_current_image_name) {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve name of image currently loaded on $computer_shortname, computer will be reloaded");
+		$self->insert_reload_and_exit();
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "beginning to reclaim $computer_shortname:\nrequest state: $request_state_name\nrequest laststate: $request_laststate_name\ncomputer state: $computer_state_name\ncomputer type: $computer_type\ncomputer current image name in database: $computer_currentimage_name\nimage loaded on computer: $os_current_image_name");
+	
 	# Don't attempt to do anything to machines that are currently reloading
-	elsif ($computer_state_name =~ /maintenance|reloading/) {
+	if ($computer_state_name =~ /maintenance|reloading/) {
 		notify($ERRORS{'OK'}, 0, "computer in $computer_state_name state, nothing needs to be done to the computer");
-		# Proceed to set request to complete
 	}
-
-	# Check the computer type
-	# Treat blades and virtual machines the same
-	# Either a reload request will be inserted or the node will be sanitized
-	# Lab computers only need to have sshd disabled.
-	
-	elsif ($computer_type =~ /blade|virtualmachine/) {
-		notify($ERRORS{'DEBUG'}, 0, "computer type is $computer_type");
-
-		# Check if request laststate is reserved - computer should be sanitized and not reloaded because user did not log on
-		if ($request_laststate_name =~ /reserved/) {
-			notify($ERRORS{'OK'}, 0, "request laststate is $request_laststate_name, attempting to sanitize computer");
-
-			# Attempt to get the name of the image currently loaded on the computer
-			# This should match the computer table's current image
-			if ($self->os->can("get_current_image_name")) {
-				notify($ERRORS{'OK'}, 0, "calling " . ref($self->os) . "::get_current_image_name() subroutine");
-				my $current_image_name;
-				if ($current_image_name = $self->os->get_current_image_name()) {
-					notify($ERRORS{'OK'}, 0, "retrieved name of image currently loaded on $computer_shortname: $current_image_name");
-				}
-				else {
-					# OS module's get_current_image_name() subroutine returned false, reload is necessary
-					notify($ERRORS{'WARNING'}, 0, "failed to retrieve name of image currently loaded on $computer_shortname, computer will be reloaded");
-					$self->insert_reload_and_exit();
-				}
-				
-				# Make sure the computer table's current image name matches what's on the computer
-				if ($current_image_name eq $computer_currentimage_name) {
-					notify($ERRORS{'OK'}, 0, "computer table current image name ($computer_currentimage_name) matches OS's current image name ($current_image_name)");
-				}
-				else {
-					# Computer table current image name does not match current image, reload is necessary
-					notify($ERRORS{'WARNING'}, 0, "computer table current image name (" . string_to_ascii($computer_currentimage_name) . ") does not match OS's current image name (" . string_to_ascii($current_image_name) . "), computer will be reloaded");
-					$self->insert_reload_and_exit();
-				}
-			}
-			
-			# Attempt to call OS module's sanitize() subroutine
-			# This subroutine should perform all the tasks necessary to sanitize the OS if it was reserved and not logged in to
-			if ($self->os->can("sanitize")) {
-				notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->os) . "::sanitize() subroutine");
-				if ($self->os->sanitize()) {
-					notify($ERRORS{'OK'}, 0, "$computer_shortname has been sanitized");
-				}
-				else {
-					# OS module's sanitize() subroutine returned false, meaning reload is necessary
-					notify($ERRORS{'WARNING'}, 0, "failed to sanitize $computer_shortname, computer will be reloaded");
-					$self->insert_reload_and_exit();
-				}
-			}
-			
-			# TODO: The following section should be removed once sanitize() is implemented by Linux.pm
-			elsif ($image_os_type =~ /linux/){
-				# Loaded Linux image needs to be cleaned up
-				notify($ERRORS{'OK'}, 0, "attempting steps to clean up loaded $image_os_name image");
-
-				# Make sure user is not connected
-				if (isconnected($computer_shortname, $computer_type, $reservation_remoteip, $image_os_name, $computer_ipaddress, $image_os_type)) {
-					notify($ERRORS{'WARNING'}, 0, "user $user_unityid is connected to $computer_shortname, computer will be reloaded");
-					$self->insert_reload_and_exit();
-				} ## end if (isconnected($computer_shortname, $computer_type...
-
-				# User is not connected, delete the user
-				if (del_user($computer_shortname, $user_unityid, $computer_type, $image_os_name)) {
-					notify($ERRORS{'OK'}, 0, "user $user_unityid removed from $computer_shortname");
-					insertloadlog($reservation_id, $computer_id, "info", "reclaim: removed user");
-				}
-				else {
-					notify($ERRORS{'OK'}, 0, "user $user_unityid could not be removed from $computer_shortname, computer will be reloaded");
-					$self->insert_reload_and_exit();
-				}
-			}
-
-			else {
-				# Unknown image type
-				notify($ERRORS{'WARNING'}, 0, "unsupported image OS detected: $image_os_name, computer will be reloaded");
-				$self->insert_reload_and_exit();
-			}
-		}
-
-		else {
-			# Either blade or vm and request laststate is not reserved
-			# Computer should be reloaded
-			notify($ERRORS{'OK'}, 0, "request laststate is $request_laststate_name, computer will be reloaded");
-			$self->insert_reload_and_exit();
-		}
+	# If request laststate = new, nothing needs to be done
+	elsif ($request_laststate_name =~ /new/) {
+		notify($ERRORS{'OK'}, 0, "request laststate is $request_laststate_name, nothing needs to be done to the computer");
 	}
-
+	# Lab computers only need to be sanitized (have sshd disabled)
 	elsif ($computer_type =~ /lab/) {
-		notify($ERRORS{'OK'}, 0, "computer type is $computer_type");
-
-		# Display a warning if laststate is not inuse or reserved
-		#    but still try to clean up computer
-		if ($request_laststate_name =~ /inuse|reserved/) {
-			notify($ERRORS{'OK'}, 0, "request laststate is $request_laststate_name");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "laststate for request is $request_laststate_name, this shouldn't happen");
-		}
-
-		# Disable sshd
-		if (disablesshd($computer_ipaddress, $user_unityid, $reservation_remoteip, "timeout", $image_os_name)) {
-			notify($ERRORS{'OK'}, 0, "sshd on $computer_shortname $computer_ipaddress has been disabled");
-			insertloadlog($reservation_id, $computer_id, "info", "reclaim: disabled sshd");
+		notify($ERRORS{'OK'}, 0, "computer type is $computer_type, computer will be sanitized");
+		$self->call_os_sanitize();
+	}
+	# If request laststate = reserved, user did not log in
+	# Make sure image loaded on computer (currentimage.txt) matches what's set in computer.currentimageid
+	elsif ($request_laststate_name =~ /reserved/) {
+		notify($ERRORS{'DEBUG'}, 0, "request laststate is $request_laststate_name, checking if computer table current image matches image currently loaded on $computer_shortname");
+		if ($computer_currentimage_name eq $os_current_image_name) {
+			notify($ERRORS{'OK'}, 0, "computer table current image name ($computer_currentimage_name) matches image name on computer ($os_current_image_name), computer will be sanitized");
+			$self->call_os_sanitize();
 		}
 		else {
-			notify($ERRORS{'CRITICAL'}, 0, "unable to disable sshd on $computer_shortname $computer_ipaddress");
-			insertloadlog($reservation_id, $computer_id, "info", "reclaim: unable to disable sshd");
-
-			# Attempt to put lab computer in failed state if not already in maintenance
-			if ($computer_state_name =~ /maintenance/) {
-				notify($ERRORS{'OK'}, 0, "$computer_shortname in $computer_state_name state, skipping state update to failed");
-			}
-			else {
-				if (update_computer_state($computer_id, "failed")) {
-					notify($ERRORS{'OK'}, 0, "$computer_shortname put into failed state");
-					insertloadlog($reservation_id, $computer_id, "info", "reclaim: set computer state to failed");
-				}
-				else {
-					notify($ERRORS{'CRITICAL'}, 0, "unable to put $computer_shortname into failed state");
-					insertloadlog($reservation_id, $computer_id, "info", "reclaim: unable to set computer state to failed");
-				}
-			}
+			notify($ERRORS{'OK'}, 0, "computer table current image name ($computer_currentimage_name) does NOT match image name on computer ($os_current_image_name), computer will be reloaded");
+			$self->insert_reload_and_exit();
 		}
 	}
-
-	# Unknown computer type, this shouldn't happen
+	# Request laststate is not reserved, user logged in
 	else {
-		notify($ERRORS{'CRITICAL'}, 0, "unsupported computer type: $computer_type, not blade, virtualmachine, or lab");
-		insertloadlog($reservation_id, $computer_id, "info", "reclaim: unsupported computer type: $computer_type");
+		notify($ERRORS{'OK'}, 0, "request laststate is $request_laststate_name, computer will be reloaded");
+		$self->insert_reload_and_exit();
 	}
 
+
 	# Update the request state to complete and exit
 	# Set the computer state to available if it isn't in the maintenance or reloading state
 	if ($computer_state_name =~ /maintenance|reloading/) {
@@ -270,6 +160,9 @@
 	else {
 		switch_state($request_data, 'complete', 'available', '', '1');
 	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "exiting");
+	exit;
 
 } ## end sub process
 
@@ -279,10 +172,11 @@
 
  Parameters  : Reference to state object
  Returns     : Nothing, process always exits
- Description : -Retrieves the next image to be loaded on the computer based on a predictive loading algorithm
-					-Inserts a new reload request for the predicted image on the computer
-					-Sets the state of the request being processed to complete
-					-Sets the state of the computer to reload
+ Description : -Retrieves the next image to be loaded on the computer based on
+                a predictive loading algorithm
+               -Inserts a new reload request
+               -Sets the state of the request being processed to complete
+               -Sets the state of the computer to reload
 
 =cut
 
@@ -307,7 +201,7 @@
 
 	notify($ERRORS{'OK'}, 0, "next image: $next_image_name, image id=$next_image_id, imagerevision id=$next_imagerevision_id");
 	
-	# Insert reload request data into the datbase
+	# Insert reload request data into the database
 	if (insert_reload_request($request_data)) {
 		notify($ERRORS{'OK'}, 0, "inserted reload request into database for computer id=$computer_id, image=$next_image_name");
 
@@ -321,12 +215,51 @@
 		switch_state($request_data, 'failed', 'failed', '', '1');
 	}
 	
-	# Make sure this VCL state process exits
+	notify($ERRORS{'DEBUG'}, 0, "exiting");
 	exit;
 }
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 call_os_sanitize
+
+ Parameters  : Reference to state object
+ Returns     : If successful: true
+               If failed: exits
+ Description : Calls the OS module's sanitize subroutine. If sanitize() fails,
+               a reload request will be inserted into the database and this
+               process will exit.
+
+=cut
+
+sub call_os_sanitize {
+	my $self = shift;
+	
+	# Make sure sanitize() has been implemented by the OS module
+	if (!$self->os->can("sanitize")) {
+		notify($ERRORS{'WARNING'}, 0, "sanitize subroutine has not been implemented by the " . ref($self->os) . " OS module, computer will be reloaded");
+		$self->insert_reload_and_exit();
+	}
+	
+	my $computer_shortname = $self->data->get_computer_short_name();
+	
+	# Attempt to call OS module's sanitize() subroutine
+	# This subroutine should perform all the tasks necessary to sanitize the OS if it was reserved and not logged in to
+	notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->os) . "::sanitize() subroutine");
+	if ($self->os->sanitize()) {
+		notify($ERRORS{'OK'}, 0, "$computer_shortname has been sanitized");
+	}
+	else {
+		# OS module's sanitize() subroutine returned false, meaning reload is necessary
+		notify($ERRORS{'WARNING'}, 0, "failed to sanitize $computer_shortname, computer will be reloaded");
+		$self->insert_reload_and_exit();
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__