Exemple #1
0
/*! \fn char *php_cmd(const char *php_command, int php_process)
 *  \brief calls the script server and executes a script command
 *  \param php_command the formatted php script server command
 *  \param php_process the php script server process to call
 *
 *  This function is called directly by the spine poller when a script server
 *  request has been initiated for a host.  It will place the PHP Script Server
 *  command on it's output pipe and then wait the pre-defined timeout period for
 *  a response on the PHP Script Servers output pipe.
 *
 *  \return pointer to the string results.  Must be freed by the parent.
 *
 */
char *php_cmd(const char *php_command, int php_process) {
	char *result_string;
	char command[BUFSIZE];
	int write_status;

	assert(php_command != 0);

	/* pad command with CR-LF */
	snprintf(command, BUFSIZE, "%s\r\n", php_command);

	/* place lock around mutex */
	switch (php_process) {
	case 0: thread_mutex_lock(LOCK_PHP_PROC_0);	break;
	case 1: thread_mutex_lock(LOCK_PHP_PROC_1);	break;
	case 2: thread_mutex_lock(LOCK_PHP_PROC_2);	break;
	case 3: thread_mutex_lock(LOCK_PHP_PROC_3);	break;
	case 4: thread_mutex_lock(LOCK_PHP_PROC_4);	break;
	case 5: thread_mutex_lock(LOCK_PHP_PROC_5);	break;
	case 6: thread_mutex_lock(LOCK_PHP_PROC_6);	break;
	case 7: thread_mutex_lock(LOCK_PHP_PROC_7);	break;
	case 8: thread_mutex_lock(LOCK_PHP_PROC_8);	break;
	case 9: thread_mutex_lock(LOCK_PHP_PROC_9);	break;
	}

	/* send command to the script server */
	write_status = write(php_processes[php_process].php_write_fd, command, strlen(command));

	/* if write status is <= 0 then the script server may be hung */
	if (write_status <= 0) {
		result_string = strdup("U");
		SPINE_LOG(("ERROR: SS[%i] PHP Script Server communications lost.\n", php_process));
		php_close(php_process);
	}else{
		/* read the result from the php_command */
		result_string = php_readpipe(php_process);
	}

	/* unlock around php process */
	switch (php_process) {
	case 0: thread_mutex_unlock(LOCK_PHP_PROC_0); break;
	case 1: thread_mutex_unlock(LOCK_PHP_PROC_1); break;
	case 2: thread_mutex_unlock(LOCK_PHP_PROC_2); break;
	case 3: thread_mutex_unlock(LOCK_PHP_PROC_3); break;
	case 4: thread_mutex_unlock(LOCK_PHP_PROC_4); break;
	case 5: thread_mutex_unlock(LOCK_PHP_PROC_5); break;
	case 6: thread_mutex_unlock(LOCK_PHP_PROC_6); break;
	case 7: thread_mutex_unlock(LOCK_PHP_PROC_7); break;
	case 8: thread_mutex_unlock(LOCK_PHP_PROC_8); break;
	case 9: thread_mutex_unlock(LOCK_PHP_PROC_9); break;
	}

	return result_string;
}
Exemple #2
0
/*! \fn int php_init(int php_process)
 *  \brief initialize either a specific PHP Script Server or all of them.
 *  \param php_process the process number to start or PHP_INIT
 *
 *  This function will either start an individual PHP Script Server process
 *  or all of them if the input parameter is the PHP_INIT constant.  The function
 *  will check the status of the process to verify that it is ready to process
 *  scripts as well.
 *
 *  \return TRUE if the PHP Script Server is know running or FALSE otherwise
 */
int php_init(int php_process) {
	int  cacti2php_pdes[2];
	int  php2cacti_pdes[2];
	pid_t  pid;
	char poller_id[TINY_BUFSIZE];
	char *argv[6];
	int  cancel_state;
	char *result_string = 0;
	int num_processes;
	int i;
	int retry_count = 0;

	/* special code to start all PHP Servers */
	if (php_process == PHP_INIT) {
		num_processes = set.php_servers;
	}else{
		num_processes = 1;
	}

	for (i=0; i < num_processes; i++) {
		SPINE_LOG_DEBUG(("DEBUG: SS[%i] PHP Script Server Routine Starting\n", i));

		/* create the output pipes from Spine to php*/
		if (pipe(cacti2php_pdes) < 0) {
			SPINE_LOG(("ERROR: SS[%i] Could not allocate php server pipes\n", i));
			return FALSE;
		}

		/* create the input pipes from php to Spine */
		if (pipe(php2cacti_pdes) < 0) {
			SPINE_LOG(("ERROR: SS[%i] Could not allocate php server pipes\n", i));
			return FALSE;
		}

		/* disable thread cancellation from this point forward. */
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);

		/* establish arguments for script server execution */
		argv[0] = set.path_php;
		argv[1] = "-q";
		argv[2] = set.path_php_server;
		argv[3] = "spine";
		snprintf(poller_id, TINY_BUFSIZE, "%d", set.poller_id);
		argv[4] = poller_id;
		argv[5] = NULL;

		/* fork a child process */
		SPINE_LOG_DEBUG(("DEBUG: SS[%i] PHP Script Server About to FORK Child Process\n", i));

		retry:

		pid = vfork();

		/* check the pid status and process as required */
		switch (pid) {
			case -1: /* ERROR: Could not fork() */
				switch (errno) {
				case EAGAIN:
					if (retry_count < 3) {
						retry_count++;
						#ifndef SOLAR_THREAD
						/* take a moment */
						usleep(50000);
						#endif
						goto retry;
					}else{
						SPINE_LOG(("ERROR: SS[%i] Cound not fork PHP Script Server Out of Resources\n", i));
					}
				case ENOMEM:
					if (retry_count < 3) {
						retry_count++;
						#ifndef SOLAR_THREAD
						/* take a moment */
						usleep(50000);
						#endif
						goto retry;
					}else{
						SPINE_LOG(("ERROR: SS[%i] Cound not fork PHP Script Server Out of Memory\n", i));
					}
				default:
					SPINE_LOG(("ERROR: SS[%i] Cound not fork PHP Script Server Unknown Reason\n", i));
				}

				close(php2cacti_pdes[0]);
				close(php2cacti_pdes[1]);
				close(cacti2php_pdes[0]);
				close(cacti2php_pdes[1]);

				SPINE_LOG(("ERROR: SS[%i] Cound not fork PHP Script Server\n", i));
				pthread_setcancelstate(cancel_state, NULL);

				return FALSE;
				/* NOTREACHED */
			case 0:	/* SUCCESS: I am now the child */
				/* set the standard input/output channels of the new process.  */
				dup2(cacti2php_pdes[0], STDIN_FILENO);
				dup2(php2cacti_pdes[1], STDOUT_FILENO);

				/* close unneeded Pipes */
				(void)close(php2cacti_pdes[0]);
				(void)close(php2cacti_pdes[1]);
				(void)close(cacti2php_pdes[0]);
				(void)close(cacti2php_pdes[1]);

				/* start the php script server process */
				execv(argv[0], argv);
				_exit(127);
				/* NOTREACHED */
			default: /* I am the parent process */
				SPINE_LOG_DEBUG(("DEBUG: SS[%i] PHP Script Server Child FORK Success\n", i));
		}

		/* Parent */
		/* close unneeded pipes */
		close(cacti2php_pdes[0]);
		close(php2cacti_pdes[1]);

		if (php_process == PHP_INIT) {
			php_processes[i].php_pid = pid;
			php_processes[i].php_write_fd = cacti2php_pdes[1];
			php_processes[i].php_read_fd = php2cacti_pdes[0];
		}else{
			php_processes[php_process].php_pid = pid;
			php_processes[php_process].php_write_fd = cacti2php_pdes[1];
			php_processes[php_process].php_read_fd = php2cacti_pdes[0];
		}

		/* restore caller's cancellation state. */
		pthread_setcancelstate(cancel_state, NULL);

		/* check pipe to insure startup took place */
		if (php_process == PHP_INIT) {
			result_string = php_readpipe(i);
		}else{
			result_string = php_readpipe(php_process);
		}

		if (strstr(result_string, "Started")) {
			if (php_process == PHP_INIT) {
				SPINE_LOG_DEBUG(("DEBUG: SS[%i] Confirmed PHP Script Server running\n", i));

				php_processes[i].php_state = PHP_READY;
			}else{
				SPINE_LOG_DEBUG(("DEBUG: SS[%i] Confirmed PHP Script Server running\n", php_process));

				php_processes[php_process].php_state = PHP_READY;
			}
		}else{
			SPINE_LOG(("ERROR: SS[%i] Script Server did not start properly return message was: '%s'\n", php_process, result_string));

			if (php_process == PHP_INIT) {
				php_processes[i].php_state = PHP_BUSY;
			}else{
				php_processes[php_process].php_state = PHP_BUSY;
			}
		}
	}

	free(result_string);

	return TRUE;
}
Exemple #3
0
/*! \fn char *php_cmd(const char *php_command, int php_process)
 *  \brief calls the script server and executes a script command
 *  \param php_command the formatted php script server command
 *  \param php_process the php script server process to call
 *
 *  This function is called directly by the spine poller when a script server
 *  request has been initiated for a host.  It will place the PHP Script Server
 *  command on it's output pipe and then wait the pre-defined timeout period for
 *  a response on the PHP Script Servers output pipe.
 *
 *  \return pointer to the string results.  Must be freed by the parent.
 *
 */
char *php_cmd(const char *php_command, int php_process) {
    char *result_string;
    char command[BUFSIZE];
    ssize_t bytes;
    int retries = 0;

    assert(php_command != 0);

    /* pad command with CR-LF */
    snprintf(command, BUFSIZE, "%s\r\n", php_command);

    /* place lock around mutex */
    switch (php_process) {
    case 0:
        thread_mutex_lock(LOCK_PHP_PROC_0);
        break;
    case 1:
        thread_mutex_lock(LOCK_PHP_PROC_1);
        break;
    case 2:
        thread_mutex_lock(LOCK_PHP_PROC_2);
        break;
    case 3:
        thread_mutex_lock(LOCK_PHP_PROC_3);
        break;
    case 4:
        thread_mutex_lock(LOCK_PHP_PROC_4);
        break;
    case 5:
        thread_mutex_lock(LOCK_PHP_PROC_5);
        break;
    case 6:
        thread_mutex_lock(LOCK_PHP_PROC_6);
        break;
    case 7:
        thread_mutex_lock(LOCK_PHP_PROC_7);
        break;
    case 8:
        thread_mutex_lock(LOCK_PHP_PROC_8);
        break;
    case 9:
        thread_mutex_lock(LOCK_PHP_PROC_9);
        break;
    }

    /* send command to the script server */
retry:
    bytes = write(php_processes[php_process].php_write_fd, command, strlen(command));

    /* if write status is <= 0 then the script server may be hung */
    if (bytes <= 0) {
        result_string = strdup("U");
        SPINE_LOG(("ERROR: SS[%i] PHP Script Server communications lost.  Restarting PHP Script Server", php_process));
        php_close(php_process);
        php_init(php_process);
        /* increment and retry a few times on the next item */
        retries++;
        if (retries < 3) {
            goto retry;
        }
    } else {
        /* read the result from the php_command */
        result_string = php_readpipe(php_process);

        /* check for a null */
        if (!strlen(result_string)) {
            SET_UNDEFINED(result_string);
        }
    }

    /* unlock around php process */
    switch (php_process) {
    case 0:
        thread_mutex_unlock(LOCK_PHP_PROC_0);
        break;
    case 1:
        thread_mutex_unlock(LOCK_PHP_PROC_1);
        break;
    case 2:
        thread_mutex_unlock(LOCK_PHP_PROC_2);
        break;
    case 3:
        thread_mutex_unlock(LOCK_PHP_PROC_3);
        break;
    case 4:
        thread_mutex_unlock(LOCK_PHP_PROC_4);
        break;
    case 5:
        thread_mutex_unlock(LOCK_PHP_PROC_5);
        break;
    case 6:
        thread_mutex_unlock(LOCK_PHP_PROC_6);
        break;
    case 7:
        thread_mutex_unlock(LOCK_PHP_PROC_7);
        break;
    case 8:
        thread_mutex_unlock(LOCK_PHP_PROC_8);
        break;
    case 9:
        thread_mutex_unlock(LOCK_PHP_PROC_9);
        break;
    }

    return result_string;
}