Author: arkurth
Date: Fri Feb 13 21:11:59 2015
New Revision: 1659685

URL: http://svn.apache.org/r1659685
Log:
VCL-817
(pgrep command arguments have changed with RHEL/CentOS 7.x)

Updated utils.pm::is_management_node_process_running to not use pgrep. The ps 
and grep commands are used instead.

Added utils.pm::get_reservation_vcld_process_name_regex. It returns a regex 
formatted to match the name generated by rename_vcld_process. This is called by 
utils.pm::reservation_being_processed and passed to 
is_management_node_process_running.

Removed utils.pm::kill_reservation_process. The code was old and buggy. Added 
Linux.pm::kill_process. This is called from new.pm::computer_not_being_used.


VCL-174
(NAT Support)
Moved the calls to populate_reservation_natport and update_reservation_natlog 
back to utils.pm::get_request_info. Removed calls from State.pm::initialize. 
They were being called too late and the connect method info contained in the 
DataStructure object didn't have the natport info. Added check to where they 
are called so that they are only called for the reservation currently being 
processed -- not all reservations in a cluster.

Changed name of iptables chain added to NAT host to include the vcld process 
name.

Udated iptables.pm::get_table_info to parse the iptables rule specifications 
and construct a hash.


Other
Changed the email subject generated in utils.pm::notify to include the VM 
host's short computer name rather than the full name. The subject can be quite 
long and truncated in some email clients.

Changed the vcld process name generated in utils.pm::rename_vcld_process to 
also use the shorter VM host name.

Added utils.pm::character_to_ascii_value - This returns the decimal, hex, or 
octal value of a single character. It may be used to include special characters 
in a regex passed to a subroutine such as is_management_node_process_running. 
This isn't currently being called.

Updated image.pm::setup_capture_base_image to call 
get_reservation_vcld_process_name_regex to determine the pattern to filter the 
vcld.log output displayed after the image capture begins.

Modified:
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    vcl/trunk/managementnode/lib/VCL/Module/State.pm
    vcl/trunk/managementnode/lib/VCL/image.pm
    vcl/trunk/managementnode/lib/VCL/new.pm
    vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1659685&r1=1659684&r2=1659685&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Fri Feb 13 21:11:59 2015
@@ -514,8 +514,8 @@ sub post_load {
 
 =head2 post_reserve
 
- Parameters  :
- Returns     :
+ Parameters  : none
+ Returns     : boolean
  Description :
 
 =cut
@@ -527,7 +527,7 @@ sub post_reserve {
                return 0;
        }
        
-       my $image_name          = $self->data->get_image_name();
+       my $image_name = $self->data->get_image_name();
        my $computer_short_name = $self->data->get_computer_short_name();
        my @post_reserve_script_paths = ('/usr/local/vcl/vcl_post_reserve', 
'/etc/init.d/vcl_post_reserve');
        
@@ -542,7 +542,6 @@ sub post_reserve {
        # write contents to local temp file 
/tmp/resrvationid_post_reserve_userdata
        # scp tmpfile to ‘/root/.vclcontrol/post_reserve_userdata’
        # assumes the image has the call in vcl_post_reserve to import/read the 
user data file
-       #
        
        my $reservation_id = $self->data->get_reservation_id();
        my $variable_name = "userdata|$reservation_id"; 
@@ -567,7 +566,7 @@ sub post_reserve {
                }
                #Clean variable from variable table
                if (delete_variable($variable_name)) {
-                       notify($ERRORS{'DEBUG'}, 0, "Deleted variable_name 
$variable_name from variable table");
+                       notify($ERRORS{'DEBUG'}, 0, "deleted variable_name 
$variable_name from variable table");
                }
        }
        
@@ -3762,7 +3761,7 @@ sub enable_firewall_port {
                        }
                }
        }
-
+       
        my @new_scope_list = split(/,/,$new_scope);
        
        for my $scope_string (@new_scope_list) {
@@ -5046,6 +5045,10 @@ sub command_exists {
                return;
        }
        
+       if ($self->{command_exists}{$shell_command}) {
+               return 1;
+       }
+       
        my $computer_node_name = $self->data->get_computer_node_name();
        
        my ($exit_status, $output) = $self->execute("which $shell_command", 0);
@@ -5055,10 +5058,12 @@ sub command_exists {
        }
        elsif (my ($command_line) = grep(/\/$shell_command$/, @$output)) {
                notify($ERRORS{'DEBUG'}, 0, "verified '$shell_command' command 
exists on $computer_node_name: $command_line");
+               $self->{command_exists}{$shell_command} = 1;
                return 1;
        }
        else {
                notify($ERRORS{'DEBUG'}, 0, "'$shell_command' command does NOT 
exist on $computer_node_name");
+               $self->{command_exists}{$shell_command} = 0;
                return 0;
        }
 }
@@ -5407,7 +5412,6 @@ sub should_set_user_password {
        }
 }
 
-
 #/////////////////////////////////////////////////////////////////////////////
 
 =head2 grant_connect_method_access
@@ -5497,13 +5501,66 @@ sub grant_connect_method_access {
                notify($ERRORS{'WARNING'}, 0, "failed to add line to 
$external_sshd_config_file_path: '$allow_users_line'");
                return;
        }
-
+       
        $self->restart_service('ext_sshd') || return;
 
        # If ssh_public_keys add to authorized_keys
 
        return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 kill_process
+
+ Parameters  : $pid, $signal (optional)
+ Returns     : boolean
+ Description : Kills a process on the computer.
+
+=cut
 
+sub kill_process {
+       my $self = shift;
+       if (ref($self) !~ /linux/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my ($pid_argument, $signal) = @_;
+       if (!defined($pid_argument)) {
+               notify($ERRORS{'WARNING'}, 0, "PID argument was not specified");
+               return;
+       }
+       
+       my $computer_node_name = $self->data->get_computer_node_name();
+       
+       # Suicide prevention
+       if ($pid_argument eq $PID) {
+               notify($ERRORS{'WARNING'}, 0, "process $pid_argument not 
killed, it is the currently running process");
+               return;
+       }
+       
+       $signal = '9' unless defined $signal;
+       $signal =~ s/^-+//g;
+       
+       my $command = "kill -$signal $pid_argument";
+       my ($exit_status, $output) = $self->execute($command);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
kill process $pid_argument on $computer_node_name");
+               return;
+       }
+       elsif ($exit_status == 1 || grep(/no such process/i, @$output)) {
+               notify($ERRORS{'DEBUG'}, 0, "process $pid_argument not running 
on $computer_node_name");
+               return 1;
+       }
+       elsif ($exit_status != 0 || grep(/^kill:/i, @$output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to kill process 
$pid_argument with signal $signal on $computer_node_name, command: '$command', 
exit status: $exit_status, output:\n" . join("\n", @$output));
+               return 0;
+       }
+       else {
+               notify($ERRORS{'DEBUG'}, 0, "killed process $pid_argument with 
signal $signal on $computer_node_name");
+               return 1;
+       }
 }
 
 ##/////////////////////////////////////////////////////////////////////////////

Modified: vcl/trunk/managementnode/lib/VCL/Module/State.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/State.pm?rev=1659685&r1=1659684&r2=1659685&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/State.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/State.pm Fri Feb 13 21:11:59 2015
@@ -114,16 +114,6 @@ sub initialize {
                
$self->data->set_reservation_lastcheck_time($reservation_lastcheck);
        }
        
-       # Populate natport table for reservation
-       if ($nathost_id && $request_state_name =~ 
/(new|reserved|modified|test)/) {
-               if (!populate_reservation_natport($reservation_id)) {
-                       $self->reservation_failed("failed to populate natport 
table for reservation");
-               }
-               if (!update_reservation_natlog($reservation_id)) {
-                       notify($ERRORS{'CRITICAL'}, 0, "failed to populate 
natlog table for reservation");
-               }
-       }
-       
        # If this is a cluster request, wait for all reservations to begin 
before proceeding
        if ($reservation_count > 1) {
                if (!$self->wait_for_all_reservations_to_begin('begin', 300, 
30)) {

Modified: vcl/trunk/managementnode/lib/VCL/image.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/image.pm?rev=1659685&r1=1659684&r2=1659685&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/image.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/image.pm Fri Feb 13 21:11:59 2015
@@ -983,6 +983,9 @@ EOF
                return;
        }
        
+       my $process_regex = 
get_reservation_vcld_process_name_regex($reservation_id) || $reservation_id;
+       $process_regex =~ s/^\w+\s//;
+       
        my $message = <<EOF;
 Inserted imaging request to the database:
 request ID: $request_id
@@ -992,7 +995,7 @@ This process will now display the conten
 daemon is running. If you do not see many lines of additional output, exit this
 process, start the vcld daemon, and monitor the image capture process by 
running
 the command:
-tail -f $LOGFILE | grep '$request_id:$reservation_id'
+tail -f $LOGFILE | grep -P '$process_regex'
 
 EOF
        

Modified: vcl/trunk/managementnode/lib/VCL/new.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/new.pm?rev=1659685&r1=1659684&r2=1659685&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/new.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/new.pm Fri Feb 13 21:11:59 2015
@@ -850,8 +850,8 @@ sub computer_not_being_used {
                                        
                                        # Kill competing process and update 
request state to complete
                                        notify($ERRORS{'OK'}, 0, "attempting to 
kill process of competing reservation $competing_reservation_id assigned to 
$computer_short_name");
-                                       if 
(kill_reservation_process($competing_reservation_id)) {
-                                               notify($ERRORS{'OK'}, 0, 
"killed process for competing reservation $competing_reservation_id");
+                                       for my $competing_reservation_pid 
(@competing_reservation_pids) {
+                                               
$self->mn_os->kill_process($competing_reservation_pid);
                                        }
                                        
                                        # Wait for competing process to end 
before verifying that it was successfully killed

Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1659685&r1=1659684&r2=1659685&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Fri Feb 13 21:11:59 2015
@@ -93,6 +93,7 @@ our @EXPORT = qw(
        _pingnode
        add_imageid_to_newimages
        add_reservation_account
+       character_to_ascii_value
        check_blockrequest_time
        check_endtimenotice_interval
        check_ssh
@@ -178,6 +179,7 @@ our @EXPORT = qw(
        get_reservation_computerloadlog_entries
        get_reservation_computerloadlog_time
        get_reservation_management_node_hostname
+       get_reservation_vcld_process_name_regex
        get_request_loadstate_names
        get_resource_groups
        get_user_group_member_info
@@ -207,7 +209,6 @@ our @EXPORT = qw(
        is_valid_ip_address
        is_variable_set
        kill_child_processes
-       kill_reservation_process
        known_hosts
        mail
        makedatestring
@@ -741,7 +742,7 @@ END
                                my $computer_name = 
$ENV{data}->get_computer_short_name(0);
                                $subject .= "|$computer_name" if (defined 
$computer_name);
                                
-                               my $vmhost_hostname = 
$ENV{data}->get_vmhost_hostname(0);
+                               my $vmhost_hostname = 
$ENV{data}->get_vmhost_short_name(0);
                                $subject .= ">$vmhost_hostname" if (defined 
$vmhost_hostname);
                                
                                my $image_name = $ENV{data}->get_image_name(0);
@@ -2772,59 +2773,6 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 kill_reservation_process
-
- Parameters  : $request_state_name, $reservation_id
- Returns     : 0 or 1
- Description :
-
-=cut
-
-sub kill_reservation_process {
-       my ($reservation_id) = @_;
-       
-       # Sanity check, make sure reservation id is valid
-       if (!$reservation_id) {
-               notify($ERRORS{'WARNING'}, 0, "reservation id is not defined");
-               return;
-       }
-       if ($reservation_id !~ /^\d+$/) {
-               notify($ERRORS{'WARNING'}, 0, "reservation id is not valid: 
$reservation_id");
-               return;
-       }
-       
-       notify($ERRORS{'OK'}, 0, "attempting to kill process for reservation 
$reservation_id");
-       
-       # Use the pkill utility to find processes matching the reservation ID
-       # Do not use -9 or else DESTROY won't run
-       my $pkill_command = "pkill -f ':$reservation_id ' 2>&1";
-       notify($ERRORS{'DEBUG'}, 0, "executing pkill command: $pkill_command");
-       
-       my $pkill_output = `$pkill_command`;
-       my $pkill_exit_status = $? >> 8;
-       
-       # Check the pgrep exit status
-       if ($pkill_exit_status == 0) {
-               notify($ERRORS{'OK'}, 0, "reservation $reservation_id process 
was killed, returning 1");
-               return 1;
-       }
-       elsif ($? == -1) {
-               notify($ERRORS{'OK'}, 0, "\$? is set to -1, Perl bug likely 
encountered, assuming reservation $reservation_id process was killed, returning 
1");
-               return 1;
-       }
-       elsif ($pkill_exit_status == 1) {
-               notify($ERRORS{'OK'}, 0, "process was not found for reservation 
$reservation_id, returning 1");
-               return 1;
-       }
-       else {
-               notify($ERRORS{'WARNING'}, 0, "pkill error occurred, returning 
undefined, output:\n$pkill_output");
-               return;
-       }
-       
-} ## end sub kill_reservation_process
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 database_select
 
  Parameters  : SQL select statement
@@ -3087,6 +3035,23 @@ EOF
                my $computer_info = get_computer_info($computer_id, $no_cache);
                $request_info->{reservation}{$reservation_id}{computer} = 
$computer_info;
                
+               # Populate natport table for reservation
+               # Make sure this wasn't called from 
populate_reservation_natport or else recursive loop will occur
+               if (defined $ENV{reservation_id} && $ENV{reservation_id} eq 
$reservation_id) {
+                       my $caller_trace = get_caller_trace(5);
+                       if ($caller_trace !~ /populate_reservation_natport/) {
+                               my $request_state_name = 
$request_info->{state}{name};
+                               if ($request_state_name =~ 
/(new|reserved|modified|test)/) {
+                                       if 
(!populate_reservation_natport($reservation_id)) {
+                                               notify($ERRORS{'CRITICAL'}, 0, 
"failed to populate natport table for reservation");
+                                       }
+                                       if 
(!update_reservation_natlog($reservation_id)) {
+                                               notify($ERRORS{'CRITICAL'}, 0, 
"failed to populate natlog table for reservation");
+                                       }
+                               }
+                       }
+               }
+               
                # Add the connect method info to the hash
                my $connect_method_info = 
get_connect_method_info($imagerevision_id, 0);
                $request_info->{reservation}{$reservation_id}{connect_methods} 
= $connect_method_info;
@@ -5979,9 +5944,9 @@ sub set_hash_process_id {
 =head2 rename_vcld_process
 
  Parameters  : hash - Reference to hash containing request data
- Returns     : 0 or 1
- Description : Renames running process based on request information.  Appends 
the state
-               name, request ID, and reservation ID to the process name.
+ Returns     : boolean
+ Description : Renames running process based on request information. Appends 
the
+               state name, request ID, and reservation ID to the process name.
                Sets PARENTIMAGE and SUBIMAGE in the hash depending on whether 
or
                reservation ID is the lowest for a request.
 
@@ -6028,13 +5993,16 @@ sub rename_vcld_process {
                        my $reservation_id        = 
$data_structure->get_reservation_id();
                        my $request_state_name    = 
$data_structure->get_request_state_name();
                        my $computer_short_name   = 
$data_structure->get_computer_short_name();
-                       my $vmhost_hostname       = 
$data_structure->get_vmhost_hostname(0);
+                       my $vmhost_hostname       = 
$data_structure->get_vmhost_short_name(0);
                        my $image_name            = 
$data_structure->get_image_name();
                        my $user_login_id         = 
$data_structure->get_user_login_id();
                        my $request_forimaging    = 
$data_structure->get_request_forimaging();
                        my $reservation_count     = 
$data_structure->get_reservation_count();
                        my $reservation_is_parent = 
$data_structure->is_parent_reservation();
                        
+                       # !!! IMPORTANT !!!
+                       # If the reservation naming scheme is changed, always 
check get_reservation_vcld_process_name_regex to make sure it matches the new 
name pattern
+                       
                        # Append the request and reservation IDs if they are set
                        $new_process_name .= " 
'|$PID|$request_id|$reservation_id|";
                        $new_process_name .= "$request_state_name|" if 
($request_state_name);
@@ -7020,23 +6988,23 @@ computer
 LEFT JOIN (state) ON (state.id = computer.stateid)
 LEFT JOIN (platform) ON (platform.id = computer.platformid)
 LEFT JOIN (
-       provisioning,
-       module
+   provisioning,
+   module
 )
 ON (
-       provisioning.id = computer.provisioningid
-       AND module.id = provisioning.moduleid
+   provisioning.id = computer.provisioningid
+   AND module.id = provisioning.moduleid
 )
 LEFT JOIN (schedule) ON (schedule.id = computer.scheduleid)
 LEFT JOIN (module AS predictivemodule) ON (predictivemodule.id = 
computer.predictivemoduleid)
 LEFT JOIN (
    resource,
-       resourcetype
+   resourcetype
 )
 ON (
    resource.subid = computer.id
-       AND resource.resourcetypeid = resourcetype.id
-       AND resourcetype.name = 'computer'
+   AND resource.resourcetypeid = resourcetype.id
+   AND resourcetype.name = 'computer'
 )
 LEFT JOIN (nathostcomputermap) ON (nathostcomputermap.computerid = computer.id)
 
@@ -7095,7 +7063,7 @@ EOF
                        $computer_info->{resource}{$table}{$column} = $value;
                }
                elsif ($table eq 'nathostcomputermap') {
-                       # Do not add, will retrieve later on
+                       $computer_info->{nathost}{$table}{$column} = $value;
                }
                else {
                        $computer_info->{$table}{$column} = $value;
@@ -7163,7 +7131,7 @@ EOF
        }
        
        # Check if the computer associated with this reservation is assigned a 
NAT host
-       if (my $nathost_id = $computer_info->{'nathostcomputermap-nathostid'}) {
+       if (my $nathost_id = 
$computer_info->{nathost}{nathostcomputermap}{nathostid}) {
                my $nathost_info = get_computer_nathost_info($computer_id, 
$no_cache);
                if ($nathost_info) {
                        $computer_info->{nathost} = $nathost_info;
@@ -8815,11 +8783,10 @@ EOF
        # Call the database select subroutine
        # This will return an array of one or more rows based on the select 
statement
        my @computerloadlog_rows = database_select($select_statement);
-
+       
        # Check if at least 1 row was returned
        my $computerloadlog_exists = 0;
-       
-       my $parent_reservation_id;
+       my $parent_reservation_id = '<unknown>';
        my $parent_computerloadlog_exists = 0;
        
        
@@ -8838,7 +8805,8 @@ EOF
        }
        
        # Check if a vcld process is running matching for this reservation
-       my @processes_running = 
is_management_node_process_running("$PROCESSNAME 
.\\|[0-9]+\\|[0-9]+\\|$reservation_id\\|");
+       my $reservation_process_name_regex = 
get_reservation_vcld_process_name_regex($reservation_id);
+       my @processes_running = 
is_management_node_process_running($reservation_process_name_regex);
        
        my $info_string = "reservation ID: $reservation_id\n";
        $info_string .= "parent reservation ID: $parent_reservation_id\n";
@@ -8849,32 +8817,32 @@ EOF
        # Check the results and return
        if ($computerloadlog_exists && @processes_running) {
                #notify($ERRORS{'DEBUG'}, 0, "reservation $reservation_id is 
currently being processed, computerloadlog 'begin' entry exists and running 
process was found:\n$info_string");
-               return 1;
+               return (wantarray ? @processes_running : 1);
        }
        elsif (!$computerloadlog_exists && @processes_running) {
                notify($ERRORS{'DEBUG'}, 0, "computerloadlog 'begin' entry does 
NOT exist but running process was found: @processes_running, assuming 
reservation $reservation_id is currently being processed\n$info_string");
-               return 1;
+               return (wantarray ? @processes_running : 1);
        }
        elsif ($computerloadlog_exists && !@processes_running) {
                if ($reservation_id eq $parent_reservation_id) {
                        #notify($ERRORS{'WARNING'}, 0, "$reservation_id is the 
parent reservation, computerloadlog 'begin' entry exists but running process 
was NOT found, assuming reservation $reservation_id is NOT currently being 
processed\n$info_string");
-                       return 0;
+                       return (wantarray ? () : 0);
                }
                else {
                        # This is a child reservation, computerloadlog exists, 
no process running for this reservation
                        if ($parent_computerloadlog_exists) {
                                notify($ERRORS{'DEBUG'}, 0, "child reservation: 
$reservation_id, computerloadlog 'begin' entry exists but running process was 
NOT found, parent reservation $parent_reservation_id computerloadlog entry 
exists, assuming a process for this reservation already ran and parent 
reservation process is still running, returning true\n$info_string");
-                               return 1;
+                               return (wantarray ? () : 1);
                        }
                        else {
                                notify($ERRORS{'DEBUG'}, 0, "child reservation: 
$reservation_id, computerloadlog 'begin' entry exists but running process was 
NOT found, parent reservation $parent_reservation_id computerloadlog entry does 
not exist, assuming this reservation is NOT currently being processed and has 
not been processed yet, returning false\n$info_string");
-                               return 0;
+                               return (wantarray ? () : 0);
                        }
                }
        }
        else {
                notify($ERRORS{'DEBUG'}, 0, "reservation $reservation_id is NOT 
currently being processed\n$info_string");
-               return 0;
+               return (wantarray ? () : 0);
        }
 }
 
@@ -8915,7 +8883,7 @@ sub run_command {
        my @output = split(/[\r\n]+/, $output_string);
        
        if (!$no_output) {
-               notify($ERRORS{'DEBUG'}, 0, "executed command: $command, exit 
status: $exit_status, output:\n@output");
+               notify($ERRORS{'DEBUG'}, 0, "executed command: $command, exit 
status: $exit_status, output:\n" . join("\n", @output));
        }
        return ($exit_status, \@output);
 }
@@ -9014,6 +8982,75 @@ sub string_to_ascii {
        }
 }
 
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 character_to_ascii_value
+
+ Parameters  : $character, $numeral_system (optional)
+ Returns     : hex number 
+ Description : Determines the ASCII value of a given character. A numeral 
system
+               argument may be specified. Valid values are 'decimal', 'hex', or
+               'oct'. By default, the decimal value is returned.
+
+=cut
+
+sub character_to_ascii_value {
+       my ($character, $numeral_system) = @_;
+       if (!defined($character)) {
+               notify($ERRORS{'WARNING'}, 0, "character argument was not 
supplied");
+               return;
+       }
+       elsif (length($character) != 1) {
+               notify($ERRORS{'WARNING'}, 0, "length of character argument is 
not 1: " . length($character));
+               return;
+       }
+       if (defined($numeral_system)) {
+               if ($numeral_system =~ /hex/i) {
+                       $numeral_system = 'hexadecimal';
+               }
+               elsif ($numeral_system =~ /dec/i) {
+                       $numeral_system = 'decimal';
+               }
+               elsif ($numeral_system =~ /oct/i) {
+                       $numeral_system = 'octal';
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "numeral system specified 
by the argument is not supported: $numeral_system");
+                       return;
+               }
+       }
+       else {
+               $numeral_system = 'decimal';
+       }
+       
+       if (defined($ENV{ascii_value}{$character}{$numeral_system})) {
+               return $ENV{ascii_value}{$character}{$numeral_system};
+       }
+       
+       my $decimal_value = unpack("C*", $character);
+       my $values = {
+               'decimal' => $decimal_value,
+               'hexadecimal' => sprintf("%X", $decimal_value),
+               'octal' => sprintf("%o", $decimal_value),
+       };
+       
+       # Store the results in %ENV to avoid repetitive messages in vcld.log
+       $ENV{ascii_value}{$character} = $values;
+       
+       my $string = "ASCII $numeral_system value of '$character': 
$values->{$numeral_system}";
+       if ($numeral_system ne 'decimal') {
+               $string .= " (decimal: $values->{decimal})";
+       }
+       if ($numeral_system ne 'hexadecimal') {
+               $string .= " (hexadecimal: $values->{hexadecimal})";
+       }
+       if ($numeral_system ne 'octal') {
+               $string .= " (octal: $values->{octal})";
+       }
+       
+       notify($ERRORS{'DEBUG'}, 0, $string);
+       return $values->{$numeral_system};
+}
 
 #/////////////////////////////////////////////////////////////////////////////
 
@@ -9161,33 +9198,57 @@ sub xmlrpc_call {
 
 =head2 is_management_node_process_running
 
- Parameters  : $process_identifier
+ Parameters  : $process_regex
  Returns     : array or hash reference
- Description : Determines if any processes matching the $process_identifier
-               argument are running on the management node. The
-               $process_identifier must be a regular expression understood by
-               pgrep. The return value differs based on how this subroutine is
-               called.
+ Description : Determines if any processes matching the $process_regex
+               argument are running on the management node. The $process_regex
+               must be a valid Perl regular expression.
+               
+               The following command is used to determine if a process is
+               running:
+               ps -e -o pid,args | grep -P "$process_regex"
+               
+               The behavior is different than if the -P argument is not used.
+               The following characters must be escaped with a backslash in
+               order for a literal match to be found:
+               | ( ) [ ] . +
+               
+               If these are not escaped, grep will interpret them as the
+               corresponing regular expression operational character. For
+               example:
                
-               If called in scalar context, a hash reference is
-               returned. The hash keys are PIDs and the values are the full 
name
-               of the process.
+               To match this literal string:
+               |(foo)|
+               Pass this:
+               \|\(foo\)\|
                
-               If called in list context, an array is returned containing the
-               PIDs.
+               To match 'foo' or 'bar, pass this:
+               (foo|bar)
+               
+               To match a pipe character ('|'), followed by either 'foo' or
+               'bar, followed by another pipe character:
+               |foo|
+               Pass this:
+               \|(foo|bar)\|
+               
+               The return value differs based on how this subroutine is called.
+               If called in scalar context, a hash reference is returned. The
+               hash keys are PIDs and the values are the full name of the
+               process. If called in list context, an array is returned
+               containing the PIDs.
 
 =cut
 
 sub is_management_node_process_running {
-       my ($process_identifier) = @_;
+       my ($process_regex) = @_;
        
        # Check the arguments
-       unless ($process_identifier) {
-               notify($ERRORS{'WARNING'}, 0, "process PID or name argument was 
not specified");
+       unless ($process_regex) {
+               notify($ERRORS{'WARNING'}, 0, "process regex pattern argument 
was not specified");
                return;
        }
        
-       my $command = "pgrep -fl '$process_identifier'";
+       my $command = "ps -e -o pid,args | grep -P \"$process_regex\"";
        my ($exit_status, $output) = run_command($command, 0);
        if (!defined($output)) {
                notify($ERRORS{'WARNING'}, 0, "failed to run command to 
determine if process is running: $command");
@@ -9196,23 +9257,23 @@ sub is_management_node_process_running {
        
        my $processes_running = {};
        for my $line (@$output) {
-               my ($pid, $process_name) = $line =~ /^(\d+)\s*(.*)/;
+               my ($pid, $process_name) = $line =~ /^\s*(\d+)\s*(.*)/g;
                
                if (!defined($pid)) {
-                       notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output 
line, it does not begin with a number: $line");
+                       notify($ERRORS{'DEBUG'}, 0, "ignoring line, it does not 
begin with a number: '$line'");
                        next;
                }
                elsif ($pid eq $PID) {
-                       notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output line 
for the currently running process: $line");
+                       notify($ERRORS{'DEBUG'}, 0, "ignoring line for the 
currently running process: $line");
                        next;
                }
-               elsif ($line =~ /pgrep -fl/) {
-                       notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output line 
containing for pgrep command: $line");
+               elsif ($line =~ /grep -P/) {
+                       notify($ERRORS{'DEBUG'}, 0, "ignoring line containing 
for this command: $line");
                        next;
                }
                elsif ($line =~ /sh -c/) {
                        # Ignore lines containing 'sh -c', probably indicating 
a duplicate process of a command run remotely
-                       notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output line 
containing 'sh -c': $line");
+                       notify($ERRORS{'DEBUG'}, 0, "ignoring containing 'sh 
-c': $line");
                        next;
                }
                else {
@@ -9225,18 +9286,40 @@ sub is_management_node_process_running {
        if ($process_count) {
                if (wantarray) {
                        my @process_ids = sort keys %$processes_running;
-                       notify($ERRORS{'DEBUG'}, 0, "process is running, 
identifier: '$process_identifier', returning array containing PIDs: 
@process_ids");
+                       notify($ERRORS{'DEBUG'}, 0, "process is running, 
identifier: '$process_regex', returning array containing PIDs: @process_ids");
                        return @process_ids;
                }
                else {
-                       notify($ERRORS{'DEBUG'}, 0, "process is running, 
identifier: '$process_identifier', returning hash reference:\n" . 
format_data($processes_running));
+                       notify($ERRORS{'DEBUG'}, 0, "process is running, 
identifier: '$process_regex', returning hash reference:\n" . 
format_data($processes_running));
                        return $processes_running;
                }
        }
        else {
-               notify($ERRORS{'DEBUG'}, 0, "process is NOT running, 
identifier: '$process_identifier'");
+               notify($ERRORS{'DEBUG'}, 0, "process is NOT running, 
identifier: '$process_regex'");
+               return;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_vcld_process_name_regex
+
+ Parameters  : $reservation_id
+ Returns     : string
+ Description : Returns a string containing a regular expression which should
+               match a single reservation process. This regex is passed to
+               is_management_node_process_running.
+
+=cut
+
+sub get_reservation_vcld_process_name_regex {
+       my ($reservation_id) = @_;
+       if (!defined($reservation_id)) {
+               notify($ERRORS{'WARNING'}, 0, "reservation ID argument was not 
specified");
                return;
        }
+       
+       return "$PROCESSNAME .\\|[0-9]+\\|[0-9]+\\|$reservation_id\\|";
 }
 
 #/////////////////////////////////////////////////////////////////////////////


Reply via email to