Cluster events using AHAFS sample code
The sample program code, test_prog, is executed by using the following
arguments:
./test_prog /aha/cluster/nodeState.monFactory/nodeStateEvent.mon "CHANGED=YES;CLUSTER=YES" 10 /tmp/nodestateevent
The following is the code for test_prog:
#include <stdio.h>
#include <string.h> /* for strcmp() */
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libgen.h>
#include <usersec.h>
#define MAX_WRITE_STR_LEN 255
void syntax(char *prog);
int ahaMonFile(char *str);
static int mk_parent_dirs (char *path);
void read_data (int fd,int outfd);
char *monFile;
test_prog :: main
int main (int argc, char *argv[])
{
int fd,outfd, rc,i=0,cnt=0;
fd_set readfds;
char *outputFile;
char wrStr[MAX_WRITE_STR_LEN+1];
char waitInRead[] = "WAIT_TYPE=WAIT_IN_READ";
if (argc < 5)
syntax( argv[0]);
monFile = argv[1];
if ( ! ahaMonFile(monFile) ) /* Not a .mon file under /aha */
syntax( argv[0]);
/* Create intermediate directories of the .mon file */
rc = mk_parent_dirs(monFile);
if (rc)
{
fprintf (stderr,
"Could not create intermediate directories of the file %s !\n", monFile);
return(-1);
}
printf("Monitor file name: %s\n", monFile);
sprintf (wrStr, "%s", argv[2]);
cnt = atoi(argv[3]);
printf("Write String : %s\n", wrStr);
outputFile = argv[4];
fd = open (monFile, O_CREAT|O_RDWR);
if (fd < 0)
{
fprintf (stderr,"Could not open the file %s; errno = %d\n", monFile,errno);
exit (1);
}
outfd = open (outputFile, O_CREAT|O_RDWR);
if (outfd < 0)
{
fprintf (stderr, "Could not open the file %s; errno = %d !\n", monFile, errno);
return(-1);
}
write(fd, wrStr, strlen(wrStr));
for(i = 0; i < cnt; i++)
{
if (strstr(wrStr, waitInRead) == NULL)
{
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
printf(
"Entering select() to wait till the event corresponding to the AHA node %s occurs.\n",
monFile);
printf("Please issue a command from another window to trigger this event.\n");
rc = select (fd+1, &readfds, NULL, NULL, NULL);
printf("\nThe select() completed. \n");
if (rc <= 0) /* No event occurred or an error was found. */
{
fprintf (stderr, "The select() returned %d.\n", rc);
perror ("select: ");
return (-1);
}
if(! FD_ISSET(fd, &readfds))
goto end;
printf("The event corresponding to the AHA node %s has occurred.\n", monFile);
}
else
{
printf(
"Entering read() to wait till the event corresponding to the AHA node %s occurs.\n",
monFile);
printf("Please issue a command from another window to trigger this event.\n");
}
read_data(fd,outfd);
}
end:
close(fd);
close(outfd);
}
test_prog :: syntax
/* -------------------------------------------------------------------------- */
void syntax(char *prog)
{
printf("\nSYNTAX: %s <aha-monitor-file> [<key1>=<value1>[;<key2>=<value2>;...]] <count> <outfile> \n",prog);
exit (1);
}
test_prog :: ahaMonFile
/* --------------------------------------------------------------------------
* PURPOSE: To check whether the file provided is an AHA monitor file.
*/
int ahaMonFile(char *str)
{
char cwd[PATH_MAX];
int len1=strlen(str), len2=strlen(".mon");
int rc = 0;
struct stat sbuf;
/* Make sure /aha is mounted. */
if ((stat("/aha", &sbuf) < 0) ||
(sbuf.st_flag != FS_MOUNT))
{
printf("ERROR: The filesystem /aha is not mounted!\n");
return (rc);
}
/* Make sure the path has .mon as a suffix. */
if ((len1 <= len2) ||
(strcmp ( (str + len1 - len2), ".mon"))
)
goto end;
if (! strncmp (str, "/aha",4)) /* The given path starts with /aha */
rc = 1;
else /* It could be a relative path */
{
getcwd (cwd, PATH_MAX);
if ((str[0] != '/' ) && /* Relative path and */
(! strncmp (cwd, "/aha",4)) /* cwd starts with /aha . */
)
rc = 1;
}
end:
if (!rc)
printf("ERROR: %s is not an AHA monitor file !\n", str);
return (rc);
}
test_prog :: mk_parent_dirs
/*-----------------------------------------------------------------
* NAME: mk_parent_dirs()
* PURPOSE: To create intermediate directories of a .mon file if
* they are not created.
*/
static int
mk_parent_dirs (char *path)
{
char s[PATH_MAX];
char *dirp;
struct stat buf;
int rc=0;
dirp = dirname(path);
if (stat(dirp, &buf) != 0)
{
sprintf(s, "/usr/bin/mkdir -p %s", dirp);
rc = system(s);
}
return (rc);
}
test_prog :: read_data
/*-----------------------------------------------------------------
* PURPOSE: To parse and print the data received at the occurrence
* of the event.
*/
void
read_data (int fd,int outfd)
{
#define READ_BUF_SIZE 3072
char data[READ_BUF_SIZE];
char *p, *line;
char cmd[64];
time_t sec, nsec;
pid_t pid;
uid_t uid, luid;
gid_t gid;
char curTm[64];
int n;
int stackInfo = 0;
char uname[64], lname[64], gname[64];
bzero((char *)data, READ_BUF_SIZE);
/* Read the info from the beginning of the file. */
n=pread(fd, data,READ_BUF_SIZE, 0);
p = data;
printf("%s\n",p);
write(outfd, data, n);
}