/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* (C) COPYRIGHT International Business Machines Corp. 1996,2019 */ /* 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.6 src/rsct/pgs/samples/sample_deactive_c_prog.c, gssamples, rsct_rady, rady2035a 5/20/02 18:49:28"; #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 RSCT 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 #include #include #include #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); }