linktest.c 3.89 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * EMULAB-COPYRIGHT
 * Copyright (c) 2000-2003 University of Utah and the Flux Group.
 * All rights reserved.
 */

#include <stdio.h>
#include <ctype.h>
#include <netdb.h>
#include <unistd.h>
#include <paths.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <pwd.h>
#include <time.h>
#include "tbdefs.h"
#include "log.h"
#include "event.h"
22
#include "linktest.h"
23

24 25 26
static void	callback(event_handle_t handle,
			 event_notification_t notification, void *data);

27
static void
28
start_linktest(char *args, int);
29 30 31 32 33 34 35 36 37 38

void
usage(char *progname)
{
	fprintf(stderr,
		"Usage: %s [-s server] [-p port] [-l logfile] -e pid/eid\n",
		progname);
	exit(-1);
}

39 40
int
main(int argc, char **argv) {
41 42 43 44 45 46 47 48 49 50 51
	event_handle_t handle;
	address_tuple_t	tuple;
	char *server = NULL;
	char *port = NULL;
	char *pideid = NULL;
	char *logfile = NULL;
	char *progname;
	char c;
	char buf[BUFSIZ];
	
	progname = argv[0];
52

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
	while ((c = getopt(argc, argv, "s:p:e:")) != -1) {
	  switch (c) {
	  case 's':
	    server = optarg;
	    break;
	  case 'p':
	    port = optarg;
	    break;
	  case 'e':
	    pideid = optarg;
	    break;
	  case 'l':
	    logfile = optarg;
	    break;
	  
	  default:
	    usage(progname);
	  }
	}

	if (!pideid)
	  usage(progname);

	loginit(0, logfile);

	
	/*
	 * Convert server/port to elvin thing.
	 *
	 * XXX This elvin string stuff should be moved down a layer. 
	 */
	if (server) {
		snprintf(buf, sizeof(buf), "elvin://%s%s%s",
			 server,
			 (port ? ":"  : ""),
			 (port ? port : ""));
		server = buf;
	}


	
	/*
	 * Construct an address tuple for subscribing to events for
	 * this node.
	 */
	tuple = address_tuple_alloc();
	if (tuple == NULL) {
		fatal("could not allocate an address tuple");
	}
	/*
103
	 * Ask for just the events we care about. 
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	 */
	tuple->expt      = pideid;
	tuple->objtype   = TBDB_OBJECTTYPE_LINKTEST;
	tuple->eventtype = ADDRESSTUPLE_ANY;

	/*
	 * Register with the event system. 
	 */
	handle = event_register(server, 0);
	if (handle == NULL) {
		fatal("could not register with event system");
	}
	
	/*
	 * Subscribe to the event we specified above.
	 */
	if (! event_subscribe(handle, callback, tuple, NULL)) {
		fatal("could not subscribe to event");
	}
	
	
	/*
	 * Begin the event loop, waiting to receive event notifications:
	 */
	event_main(handle);

	/*
	 * Unregister with the event system:
	 */
	if (event_unregister(handle) == 0) {
		fatal("could not unregister with event system");
	}

	return 0;
}
/*
 * Handle the events.
 */
static void
callback(event_handle_t handle, event_notification_t notification, void *data)
{
	char		objname[TBDB_FLEN_EVOBJTYPE];
	char		event[TBDB_FLEN_EVEVENTTYPE];
	char		args[BUFSIZ];
	struct timeval	now;

	gettimeofday(&now, NULL);
	
	if (! event_notification_get_objname(handle, notification,
					     objname, sizeof(objname))) {
		error("Could not get objname from notification!\n");
		return;
	}

	if (! event_notification_get_eventtype(handle, notification,
					       event, sizeof(event))) {
		error("Could not get event from notification!\n");
		return;
	}

	event_notification_get_arguments(handle,
					 notification, args, sizeof(args));

167 168
/*        info("Event: %lu:%d %s %s %s\n", now.tv_sec, now.tv_usec,
	     objname, event, args);*/
169 170 171
	/*
	 * Dispatch the event. 
	 */
172
	if (strcmp(event, TBDB_EVENTTYPE_START) == 0) {
173
          start_linktest(args, sizeof(args));
174
	}
175 176

}
177

178
/* convert arguments from the event into a form for Linktest.
179 180 181 182 183 184 185
 */
static void
start_linktest(char *args, int buflen) {
  pid_t lt_pid;
  int status;
  char *word;
  char *argv[MAX_ARGS];
186 187
  int i=1;
  
188 189 190 191 192 193
  word = strtok(args," \t");
  do {
    argv[i++] = word;
  } while ((word = strtok(NULL," \t"))
           && (i<MAX_ARGS));
  argv[i] = NULL;
194
  argv[0] = LINKTEST_SCRIPT;
195
/*  info("starting linktest.\n");*/
196 197 198 199 200 201
  
  lt_pid = fork();
  if(!lt_pid) {
    execv( LINKTEST_SCRIPT,argv);
  }
  waitpid(lt_pid, &status, 0);
202
/*  info("linktest completed.\n");*/
203
}
204