[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: new control.c
From: |
Jan-Henrik Haukeland |
Subject: |
Re: new control.c |
Date: |
02 Oct 2002 03:53:10 +0200 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Civil Service) |
Rory Toma <address@hidden> writes:
> I've mostly completely rewritten control.c. Before I check it in, here
> it is so I can get comments. I've tried to reduce the amount of
> redundant code, and I belive I've reduced the number of things like
> calls to get_process and the like.
This looks good Rory! Nice and modular. I also like that actions are
given as strings. I have cleaned up a bit (without trying to compile)
and since I'm a sucker for space, I added some. Please double check
the changes, since I just browsed fast through and I'm pretty tired.
/*
* Copyright (C), 2000-2002 by Contributors to the monit codebase.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <config.h>
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <sys/socket.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "monitor.h"
#include "net.h"
#include "control.h"
/* Private Prototypes */
static void atomic_control_process(Process_T p, char *action);
static void atomic_dcontrol_process(Process_T p, char *action);
static void control_dependant_process(Process_T p, char *action, int daemon);
/**
* Methods for controlling processes managed by monit.
*
* @author Jan-Henrik Haukeland, <address@hidden>
* @author Rory Toma, <address@hidden>
*
* @version \$Id: control.c,v 1.1 2002/09/26 02:39:27 rory Exp $
*
* @file
*/
/* ------------------------------------------------------------------ Public */
/**
* Execute an action for the submited process
* @param p A Process object
* @param action A string describing the action to execute
* @param daemon Flag indicating if the monit daemon should execute the action
*/
void control_process(Process_T p, char *action, int daemon) {
/* stop dependant processes */
control_dependant_process(p, "stop", method);
/* Start/stop the process we asked for */
if(daemon)
atomic_dcontrol_process(p, action);
else
atomic_control_process(p, action);
/* Restart dependant processes if needed */
if(is(action, "start")) {
control_dependant_process(p, action, method);
}
}
/**
* Start/stop all processes in process list
* @param action A string describing the action to execute
*/
void control(char *action) {
Process_T p;
for(p= processlist; p; p= p->next) {
check_process(p->name, action);
}
}
/*
* Start/stop all processes in a group
* @param name group name
* @param action A string describing the action to execute
*/
void control_group(char *G, char *action) {
Process_T p;
for(p= processlist; p; p= p->next) {
if(is(p->group, G)) {
check_process(p->name, action);
}
}
}
/**
* Check to see if we should try to start/stop process and by what method
* (monit daemon or force)
* @param name A process name as stated in the config file
* @param action A string describing the action to execute
*/
void check_process(char *P, char *action) {
Process_T p;
int pid;
int method;
if(NULL==(p= get_process(P))) {
error("%s: Cannot %s program '%s' -- not found in %s\n",
prog, action, P, Run.controlfile);
return;
}
if(is(action, "start")) {
if ( (pid= is_process_running(p)) ) {
error("%s: '%s' is already running with pid%d\n", prog, P, pid);
return;
}
if(! p->start) {
error("start: '%s' the start program is not defined\n", p->name);
return;
}
}
else if(is(action, "stop")) {
if(! is_process_running(p)) {
error("%s: '%s' is not running\n", prog, P);
return;
}
if(! p->stop) {
error("stop: '%s' the stop program is not defined\n", p->name);
return;
}
}
control_process(p, action, exist_daemon());
}
/* ----------------------------------------------------------------- Private */
/*
* Request that the monit daemon execute the action
* @param p A Process_T object
* @param action A string describing the action to execute
*/
static void atomic_dcontrol_process(Process_T p, char *action) {
int s;
char req[2*STRLEN];
char *auth= get_basic_authentication_header();
s= create_socket(Run.bind_addr?Run.bind_addr:"localhost",
Run.httpdport, SOCK_STREAM);
if(s<0) {
error("%s: Cannot connect to the monit daemon. "
"Did you start it with http support?\n", prog);
return;
}
else {
snprintf(req, sizeof(req),
"GET /%s?action=%s HTTP/1.0\r\n%s\r\n", p->name, action, auth);
sock_send(s, req, sizeof(req), 0);
close_socket(s);
free(auth);
}
}
/*
* Execute the given action for the process
* @param p A Process_T object
* @param action A string describing the action to execute
*/
static void atomic_control_process(Process_T p, char *action) {
log("%s: (%s) %s\n", action, p->name, p->start->arg[0]);
if(is(action, "start")) {
spawn(p, p->start);
}
else if(is(action, "stop")) {
spawn(p, p->stop);
}
}
/*
* Start/stop dependant processes
* @param p A Process_T object @param action A start/stop action
* @param daemon Flag indicating if the monit daemon should execute the action
*/
static void control_dependant_process(Process_T p, char *action, int daemon) {
Dependant_T d;
for(d= p->dependantlist; d; d= p->dependantlist->next) {
if(d->dependant == NULL) {
break;
}
control_process(get_process(d->dependant), action, daemon);
if (d->next == NULL) {
break;
}
}
}
--
Jan-Henrik Haukeland