Group Services Programming Guide and Reference
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* */
/* */
/* Licensed Materials - Property of IBM */
/* */
/* (C) COPYRIGHT International Business Machines Corp. 1996,2001 */
/* All Rights Reserved */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/* */
/* IBM_PROLOG_END_TAG */
static char *sccsid =
"@(#)70 1.5 src/rsct/pgs/samples/sample_deactive_c_prog.c, gssamples, rsct_r43x 5/14/01 09:43:51";
#if !defined(_HAGSD_COPYRIGHT_H)
#define _HAGSD_COPYRIGHT_H
static char copyright[] = "Licensed Materials - Property of IBM\n\
(C) COPYRIGHT International Business Machines Corp. 1996,2001.\n\
All Rights Reserved.\n\
US Government Users Restricted Rights - Use, duplication or \n\
disclosure restricted by GSA ADP Schedule Contract with IBM Corp.\n";
#endif
/*********************************************************************/
/*
* Name: sample_deactive_c_prog.c
*
* This module provides a simple sample deactivation program that can
* be executed as part of an "expel" protocol against a provider,
* or an "failure" protocol if the deactivate-on-failure is enabled.
* It will expect the input parameters described as part of the
* Expel Protocol and the Deactivate-On-Failure Handling description
* in the IBM PSSP Group Services Programming Guide and Reference manual.
*/
/*********************************************************************/
/*********************************************************************/
/*
* Expected input conditions:
* - effective uid and gid set to that of the client process connected
* to the Group Services daemon, at the time it issued ha_gs_init().
* - current directory matches that of the client process connected
* to the Group Services daemon, at the time it issued ha_gs_init().
* - path and other environment variables set to those used by the
* Group Services daemon.
*
* Expected input parameters:
* target_pid -- client process pid containing the provider targeted by the expel.
* time_limit -- number of seconds within which this program must complete.
* group_name -- name of the group to which the targeted provider is joined.
* expel_flag -- flag specified by the provider initiating the expel,
* or "providerdied" as the deactivate-on-failure handling.
* failedProviders -- comma(,)-delimited list of the failed providers'
* local instance numbers. This parameter will be presented
* only for deactivate-on-failure handling.
*
* Special conditions:
* target_pid == 0 -- the provider's process id already failed during the
* expel protocol, or the deactivate-on-failure handling
* is initiated. Take any other necessary actions.
*
* expel_flag == NULL -- no flag was specified.
* == "providerdied" -- the deactivate-on-failure handling
* is initiated.
*
* Output (exit code):
* 0 -- means this program is "successful". It is up to this program to
* define "successful".
* !0 -- means this program is "unsuccessful". It is up to this program to
* define "unsuccessful".
*/
/*********************************************************************/
/*********************************************************************/
/*
* In the case of the expel protocol:
* It is assumed that part of the normal action of a deactivate "script"
* will be to "kill" the targeted provider's process, since if we are
* running an expel we assume that the process is hung, or otherwise
* misbehaving.
*
* For the deactivate-on-failure:
* It will wait until (timeLimit + 5) to exit. Exit with zero.
*
* However, this is optional. This program should perform whatever
* actions make sense for the group and its providers.
*/
/*********************************************************************/
/*********************************************************************/
/*
* For this sample program, we will use the *expel flag* as a key to
* our behavior.
*
* Flag values:
* NULL -- (no flag) No action, simply exit with 0 exit code.
* "kill" -- kill given process id (unless it is zero), exit with the
* return code from the kill command.
* "kill N" -- kill given process id (unless it is zero), exit with the
* value given by the integer N.
* "killwait" -- kill given process id (unless it is zero), but wait
* to exit until (timeLimit + 5). Always exit with zero.
* "wait" -- do not try to kill given process id, wait until
* (timeLimit + 5) to eixt. Always exit with zero.
* "wait N" -- do not try to kill given process id, wait until
* (timeLimit + 5) to exit. N should be an integer, use it
* as our exit code.
* "N" -- N should be an integer, exit immediately with N as our exit
* code.
* "providerdied" -- wait until (timeLimit + 5) to exit. Exit with zero.
* This indicates deactivate-on-failure.
*
*/
/*********************************************************************/
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include "ha_gs.h"
#define KILL "kill"
#define KILLWAIT "killwait"
#define WAIT "wait"
#define PROVIDERDIED "providerdied"
#define EXTRA_WAIT 5
int main(int argc,
void **argv)
{
char *sPid, *sTime, *groupName, *expelFlag;
char *failedProviders = NULL;
pid_t targetPid;
int timeLimit;
int killRC;
int exitCode, givenExit, haveExit;
haveExit = 0;
sPid = argv[1];
sTime = argv[2];
groupName = argv[3];
if (5 <= argc) {
expelFlag = argv[4];
if (6 <= argc) {
haveExit = 1;
givenExit = atoi(argv[5]);
}
} else {
expelFlag = NULL;
}
targetPid = atoi(sPid);
timeLimit = atoi(sTime);
/* check expel flag, and see what to do. */
if (NULL == expelFlag) {
exit(0); /* No flag given, just exit now. */
}
/*
* See if we should kill the target process, then wait for some
* amount of time before exiting.
*/
if (0 == strncmp(KILLWAIT, expelFlag, strlen(KILLWAIT))) {
if (0 != targetPid) {
kill(targetPid, 9); /* Have a pid. Kill the process. */
}
sleep(timeLimit + EXTRA_WAIT);
exit(0); /* Ignore kill return code. */
}
/*
* Kill the process? If so, we may have a specific exit code that we
* should use, rather than the kill return code.
*/
if (0 == strncmp(KILL, expelFlag, strlen(KILL))) {
if (haveExit) {
/* Use given code for exit value unless error. */
exitCode = givenExit;
} else {
exitCode = 0;
}
if (0 != targetPid) { /* Kill the process. */
if ((-1 == kill(targetPid, 9)) && (!haveExit)) {
exitCode = errno; /* Error, grab the error return code. */
}
}
exit(exitCode); /* Exit with whatever code worked out. */
}
/*
* No killing, but we need to wait for some amount of time before
* exiting. If given, use specified value for exit code.
*/
if (0 == strncmp(WAIT, expelFlag, strlen(WAIT))) {
if (haveExit) {
exitCode = givenExit; /* Use given code for exit value. */
} else {
exitCode = 0;
}
sleep(timeLimit + EXTRA_WAIT);
exit(exitCode);
}
/*
* In the case of the deactivate-on-failure:
* No killing, but we need to wait for some amount of time before
* exiting. If given, use specified value for exit code.
*/
if (0 == strncmp(PROVIDERDIED, expelFlag, strlen(PROVIDERDIED))) {
failedProviders=argv[5]; /* holds the list of failed providers */
exitCode = 0;
sleep(timeLimit + EXTRA_WAIT);
exit(exitCode);
}
/*
* Nothing else, simply exit with the given value.
*/
exitCode = atoi(expelFlag);
exit(exitCode);
}
[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]