Main Page   Compound List   File List   Compound Members   File Members   Related Pages  

ahm.c File Reference

#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <error.h>
#include <signal.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <glib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <syslog.h>
#include "ahm.h"
#include "utils.h"
#include "thread.h"
#include "watchdog.h"

Functions

void signal_shutdown (int a_arg)
int select_func (const struct dirent *dirent)
pid_t extract_pid (const char *d_name)
int authenticate_process (pid_t a_pid, registration_info *a_reginfo)
int verify_heartbeat_fifo (const char *a_fifoname, const registration_info *a_reginfo)
gboolean find_registration_files (gpointer a_data)
int main (int argc, char *argv[])

Variables

GHashTable * prochash
GMainLoop * mainloop
gboolean daemon_mode = TRUE
char registration_dir [NAME_LENGTH] = {'\0'}
unsigned long register_period = REGISTRATION_INTERVAL

Function Documentation

int authenticate_process pid_t    a_pid,
registration_info   a_reginfo
 

Determines if the process is listed under /proc and if the registration file belongs to that process.

Parameters:
a_pid  The pid to search for
a_reginfo  The registration information to compare against
Returns:
E_INVALID if stat fails E_UID_INVALID if the uid is invalid E_GID_INVALID if the gid is invalid E_MODE_INVALID if the mode is other than 0700 SUCCESS if file found ENOTFOUND if PID is not in our map

pid_t extract_pid const char *    d_name
 

Extracts the PID from a potentially qualified filename of the format .phm_<PID>_XXXXXX.

Parameters:
d_name  The filename from which to extract the PID
Returns:
The pid obtained, or -1 on error.

gboolean find_registration_files gpointer    a_data
 

This function looks under the specified registration directory for potential registration files. For every file found, extract_pid() is called to attempt to parse out the PID. The PID is checked to see if it is already in the hash table. If it is, then there is a duplicate registration file and one of them needs to be removed (and a log generated and possibly a recovery executed). If there is no PID already in the hash table (i.e. nothing already used that PID), then the registration file is opened and its contents parsed out and used to fill the registration_info structure. With this information, the process is then authenticated using /proc/<pid> information and compared against what was in the registration file. If all turns up ok, then the PID and registration_info are added to the hash table.

If a process was in the process of writing the registration file while it is being parsed, then it will be invalid and the registration will be picked up the next time this function is called. However, if the second time this function attempts to read the registration file and it still contains errors, it will be renamed (having "invalid" pre-pended to the name) and a log entry generated. It is up to the application owner or the system administrator to remove these files. They are not immediately deleted and are renamed instead, so that the application (or anyone else interested) may inspect the file to see what the problem may be.

If there are not files that fit the registration filename format, then this function returns without doing anything.

The following is a list of the log messages generated by this function (xxxx denotes a process identifier):

"malloc failed during registration key creation for PID xxxx" "malloc failed during registration of PID xxxx" "registration file invalid for PID xxxx" "unable to open client fifo for PID xxxx" "failed to create thread for PID xxxx" "registration completed for PID xxxx" "process xxxx not authenticated or does not exist" "renaming invalid registration file for PID xxxx"

Parameters:
a_data  (un-used)
Returns:
TRUE if we should continue to call this function; FALSE if the callback should be removed

Todo:
handle duplicate registrations

int main int    argc,
char *    argv[]
 

The amount of time to wait between checking for registrations is configurable, though not recommended to be changed because any clients will not know how long to wait before determining if registration has failed. Currently, the accepted values are 1 second or longer. This period determines how frequently the registration directory is scanned for new registration files. If it is too short and there are a lot of registered applications, it is possible that it will not have enough time to scan the entire directory before needing to scan again.

int select_func const struct dirent *    dirent
 

The filename must have the following form: .phm_<PID>_XXXXXX

Parameters:
dirent  The directory entry containing the filename in question
Returns:
1 if the filename has the proper format, 0 otherwise

void signal_shutdown int    a_arg
 

This method keeps the monitor from being killed and leaving various pipes and memory allocated when used to shutdown the heartbeat monitor.

Parameters:
a_arg  (unused)

int verify_heartbeat_fifo const char *    a_fifoname,
const registration_info   a_reginfo
 

Determine if the file is a fifo and if it is opened for writing by the process specified. The fifo must not be opened by anything other than the process wishing to be monitored and the heartbeat service that will be listening for heartbeats.

Parameters:
a_fifoname  The name of the fifo to be verified
a_reginfo  The information regarding the process that should own the fifo.
Returns:
SUCCESS (0) on success or E_INVALID (non-zero) on failure E_UID_INVALID if the uid is not that of the process registering E_GID_INVALID if the gid is not that of the process registering E_FILE_NOT_FOUND if the file could not be verified.


Variable Documentation

gboolean daemon_mode = TRUE
 

Indicates if the monitor should be run as a daemon or not. This intent of this is to help with debugging

GMainLoop* mainloop
 

This is the main event loop for the application

GHashTable* prochash
 

This is the hash table containing the registered processes

unsigned long register_period = REGISTRATION_INTERVAL
 

This is the approximate amount of time to allow to lapse between checking for new registrations

char registration_dir[NAME_LENGTH] = {'\0'}
 

This is the location where applications should register


Generated on Wed Oct 30 15:21:17 2002 for Application Heartbeat Monitor by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002