evproxyplab.cc 15.7 KB
Newer Older
Sachin Goyal's avatar
 
Sachin Goyal committed
1
2
/*
 * EMULAB-COPYRIGHT
Leigh B. Stoller's avatar
Leigh B. Stoller committed
3
 * Copyright (c) 2003-2009 University of Utah and the Flux Group.
Sachin Goyal's avatar
 
Sachin Goyal committed
4
5
6
7
 * All rights reserved.
 */

/*
Leigh B. Stoller's avatar
Leigh B. Stoller committed
8
 * Dave swears we use this on plab nodes. Hand installed into the rootball.
Sachin Goyal's avatar
 
Sachin Goyal committed
9
10
11
12
13
14
15
16
 */
#include <stdio.h>
#include <ctype.h>
#include <netdb.h>
#include <unistd.h>
#include <time.h>
#include <math.h>
#include <paths.h>
17
#include <sys/errno.h>
Sachin Goyal's avatar
 
Sachin Goyal committed
18
19
20
21
22
23
24
25
26
27
28
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "config.h"
#include "event.h"
#include "tbdefs.h"
#include "log.h"
#include <map>
#include <string>
#include <iostream>
29
#include <cstring>
Sachin Goyal's avatar
 
Sachin Goyal committed
30

Kirk Webb's avatar
   
Kirk Webb committed
31
32
#define IPADDRFILE "/var/emulab/boot/myip"

Sachin Goyal's avatar
 
Sachin Goyal committed
33
34
35
36
37
38
39
40
41
42
static int debug = 0;
static event_handle_t localhandle;
static event_handle_t bosshandle;
static std::map<std::string, event_subscription_t> exptmap;
static char nodeidstr[BUFSIZ], ipaddr[32];
;

void
usage(char *progname)
{
43
44
    fprintf(stderr, "Usage: %s [-s server] [-p port] [-l local_elvin_port] "
	    "-n pnodeid \n", progname);
Sachin Goyal's avatar
 
Sachin Goyal committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    exit(-1);
}

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

static void
expt_callback(event_handle_t handle,
	 event_notification_t notification, void *data);

static void
sched_callback(event_handle_t handle,
	       event_notification_t notification, void *data);

static void subscribe_callback(event_handle_t handle,  int result,
			       event_subscription_t es, void *data);

63
64
65
static void status_callback(pubsub_handle_t *handle,
                            pubsub_status_t status, void *data,
                            pubsub_error_t *error);
Kirk Webb's avatar
   
Kirk Webb committed
66

Kirk Webb's avatar
   
Kirk Webb committed
67
static void schedule_updateevent();
Sachin Goyal's avatar
 
Sachin Goyal committed
68

Kirk Webb's avatar
   
Kirk Webb committed
69
70
static int do_remote_register(char *server);

Sachin Goyal's avatar
 
Sachin Goyal committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

int
main(int argc, char **argv)
{
	address_tuple_t		tuple;
	char			*progname;
	char			*server = NULL;
	char			*port = NULL, *lport = NULL;
	char			*myeid = NULL;
	char			*pnodeid = NULL;
	char			buf[BUFSIZ];
	char			hostname[MAXHOSTNAMELEN];
	struct hostent		*he;
	int			c;
	struct in_addr		myip;
Kirk Webb's avatar
   
Kirk Webb committed
86
87
        int                     o1, o2, o3, o4;
        int                     scanres;
Sachin Goyal's avatar
 
Sachin Goyal committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
	FILE			*fp;

	progname = argv[0];
	
	while ((c = getopt(argc, argv, "ds:p:e:n:l:")) != -1) {
		switch (c) {
		case 'd':
			debug++;
			break;
		case 's':
			server = optarg;
			break;
		case 'p':
			port = optarg;
			break;
		case 'l':
			lport = optarg;
			break;
		case 'e':
			myeid = optarg;
			break;
		case 'n':
		        pnodeid = optarg;
                        break;
		default:
			usage(progname);
		}
	}
	argc -= optind;
	argv += optind;

	if (argc)
		usage(progname);

122
123
	if (! pnodeid)
	   fatal("Must provide pnodeid"); 
Sachin Goyal's avatar
 
Sachin Goyal committed
124

Kirk Webb's avatar
   
Kirk Webb committed
125
	if (debug) {
Sachin Goyal's avatar
 
Sachin Goyal committed
126
	        loginit(0, 0);
Kirk Webb's avatar
   
Kirk Webb committed
127
        }
Sachin Goyal's avatar
 
Sachin Goyal committed
128
129
130
131
132

	/*
	 * Get our IP address. Thats how we name this host to the
	 * event System. 
	 */
Kirk Webb's avatar
   
Kirk Webb committed
133
134
135
136
137
        if (gethostname(hostname, MAXHOSTNAMELEN) == -1) {
                fatal("could not get hostname: %s\n", strerror(errno));
        }

        if ((he = gethostbyname(hostname)) != NULL) {
Kirk Webb's avatar
   
Kirk Webb committed
138
139
                memcpy((char *)&myip, he->h_addr, he->h_length);
                strcpy(ipaddr, inet_ntoa(myip));
Kirk Webb's avatar
   
Kirk Webb committed
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
        } else {
                error("could not get IP address from hostname: %s\n"
                      "Attempting to get it from local config file...\n", 
                      hostname);
                fp = fopen(IPADDRFILE, "r");
                if (fp != NULL) {
                        scanres = fscanf(fp, "%3u.%3u.%3u.%3u", 
                                         &o1, &o2, &o3, &o4);
                        (void) fclose(fp);
                        if (scanres != 4) {
                                fatal("IP address not found on first "
                                      "line of file!\n");
                        }
                        if (o1 > 255 || o2 > 255 || o3 > 255 || o4 > 255) {
                                fatal("IP address inside file is "
                                      "invalid!\n");
                        }
                        snprintf(ipaddr, sizeof(ipaddr), 
                                 "%u.%u.%u.%u", o1, o2, o3, o4);
                } else {
                        fatal("could not get IP from local file %s either!", 
                              IPADDRFILE);
                }
Kirk Webb's avatar
   
Kirk Webb committed
163
        }
Kirk Webb's avatar
   
Kirk Webb committed
164

Kirk Webb's avatar
   
Kirk Webb committed
165
166
167
        if (debug) {
                printf("My IP: %s\n", ipaddr);
        }
Sachin Goyal's avatar
 
Sachin Goyal committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

	/*
	 * If server is not specified, then it defaults to EVENTSERVER.
	 * This allows the client to work on either users.emulab.net
	 * or on a client node. 
	 */
	if (!server)
	  server = EVENTSERVER;
	

	/*
	 * Convert server/port to elvin thing.
	 *
	 * XXX This elvin string stuff should be moved down a layer. 
	 */
	snprintf(buf, sizeof(buf), "elvin://%s%s%s",
		 server,
		 (port ? ":"  : ""),
		 (port ? port : ""));
Kirk Webb's avatar
   
Kirk Webb committed
187
	server = strdup(buf);
Sachin Goyal's avatar
 
Sachin Goyal committed
188

Kirk Webb's avatar
   
Kirk Webb committed
189
190
        /* Create nodeid string from pnode id passed in. */
	snprintf(nodeidstr, sizeof(nodeidstr), "__%s_proxy", pnodeid);
Sachin Goyal's avatar
 
Sachin Goyal committed
191
192

	/* Register with the event system on the local node */
193
194
195
	snprintf(buf, sizeof(buf), "elvin://localhost%s%s",
		 (lport ? ":"  : ""),
		 (lport ? lport : ""));
Sachin Goyal's avatar
 
Sachin Goyal committed
196
197
198
199
200
	localhandle = event_register(buf, 0);
	if (localhandle == NULL) {
		fatal("could not register with local event system");
	}
	
Kirk Webb's avatar
   
Kirk Webb committed
201
        /*
202
         * Setup local subscriptions:
Kirk Webb's avatar
   
Kirk Webb committed
203
204
205
206
207
         */
	tuple = address_tuple_alloc();
        
        tuple->host = ADDRESSTUPLE_ALL;
        tuple->scheduler = 1;
Sachin Goyal's avatar
 
Sachin Goyal committed
208
209
210
	
	if (! event_subscribe(localhandle, sched_callback, tuple,
			      NULL)) {
Kirk Webb's avatar
   
Kirk Webb committed
211
		fatal("could not subscribe to events on local server");
Sachin Goyal's avatar
 
Sachin Goyal committed
212
213
	}

214
        info("Successfully connected to local pubsubd.\n");
Kirk Webb's avatar
   
Kirk Webb committed
215

Sachin Goyal's avatar
 
Sachin Goyal committed
216
217
218
	/*
	 * Stash the pid away.
	 */
Kirk Webb's avatar
   
Kirk Webb committed
219
	snprintf(buf, sizeof(buf), "%s/evproxy.pid", _PATH_VARRUN);
Sachin Goyal's avatar
 
Sachin Goyal committed
220
221
222
223
224
225
226
227
228
229
	fp = fopen(buf, "w");
	if (fp != NULL) {
		fprintf(fp, "%d\n", getpid());
		(void) fclose(fp);
	}

	/*
	 * Do this now, once we have had a chance to fail on the above
	 * event system calls.
	 */
Kirk Webb's avatar
   
Kirk Webb committed
230
	if (!debug) {
Sachin Goyal's avatar
 
Sachin Goyal committed
231
		daemon(0, 0);
Kirk Webb's avatar
   
Kirk Webb committed
232
233
		loginit(0, "/var/emulab/logs/evproxy.log");
	}
Sachin Goyal's avatar
 
Sachin Goyal committed
234
235
	
	/* Begin the event loop, waiting to receive event notifications */
Kirk Webb's avatar
   
Kirk Webb committed
236
        info("Entering main event loop.\n");
Kirk Webb's avatar
   
Kirk Webb committed
237
        while (1) {
Kirk Webb's avatar
   
Kirk Webb committed
238
239
240
241
242
243
244
245
246
247
          /* 
           * Register with the remote event system.
           * Keep trying until we get a connection.
           */
          while (do_remote_register(server) == 0) {
            event_unregister(bosshandle); /* just to be safe... */
            error("Failed to register with remote event system!\n"
                  "Sleeping for a bit before trying again...\n");
            sleep(10);
          }
248
          info("Remote pubsub registration complete.\n");
Kirk Webb's avatar
   
Kirk Webb committed
249
          /* Jump into the main event loop. */
Kirk Webb's avatar
   
Kirk Webb committed
250
          event_main(bosshandle);
Kirk Webb's avatar
   
Kirk Webb committed
251
252
          /* 
           * If we drop out of the event loop, it's because there was/is
253
254
           * some kind of problem with the connection to the remote event
           * server. So, clean up and re-register (re-subscribe).
Kirk Webb's avatar
   
Kirk Webb committed
255
           */
Kirk Webb's avatar
   
Kirk Webb committed
256
          error("exited event_main: retrying remote registration.\n");
Kirk Webb's avatar
   
Kirk Webb committed
257
258
259
          event_unregister(bosshandle);
          exptmap.clear(); /* clear our list of subs - it's invalid now. */
        }
Sachin Goyal's avatar
 
Sachin Goyal committed
260
261
262
263
264
265
266
267
268
269
270
271
272
273

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

	return 0;
}


Kirk Webb's avatar
   
Kirk Webb committed
274
275
276
277
278
int do_remote_register(char *server) {
        address_tuple_t		tuple;
	char			buf[BUFSIZ];

	/* Register with the event system on boss */
Kirk Webb's avatar
   
Kirk Webb committed
279
	while ((bosshandle = event_register(server, 0)) == 0) {
Kirk Webb's avatar
   
Kirk Webb committed
280
281
282
283
284
285
286
287
288
289
290
291
292
		error("Could not register with remote event system\n"
                      "\tSleeping for a bit, then trying again.\n");
                sleep(60);
	}

        /* Setup handle to periodically ping remote event server */
        event_set_idle_period(bosshandle, 30);

        /* Turn off failover on the remote connection - we'll manage it
           ourselves via the status callback. */
        event_set_failover(bosshandle, 0);

        /* Setup a status callback to watch the remote connection. */
293
294
295
        if (pubsub_set_status_callback(bosshandle->server,
				       status_callback,
				       server, &bosshandle->status) != 0) {
Kirk Webb's avatar
   
Kirk Webb committed
296
          error("Could not register status callback!");
Kirk Webb's avatar
   
Kirk Webb committed
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
        }

	/*
	 * Create a subscription to pass to the remote server. We want
	 * all events for this node, or all events for the experiment
	 * if the node is unspecified (we want to avoid getting events
	 * that are directed at specific nodes that are not us!). 
	 */
	snprintf(buf, sizeof(buf), "%s,%s,%s", 
                 TBDB_EVENTTYPE_UPDATE, TBDB_EVENTTYPE_CLEAR,
                 TBDB_EVENTTYPE_RELOAD);

        tuple = address_tuple_alloc();
	tuple->eventtype = buf;
	tuple->host = ipaddr;
	tuple->objname = nodeidstr;
	tuple->objtype = TBDB_OBJECTTYPE_EVPROXY;
	
	/* Subscribe to the test event: */
	if (! event_subscribe(bosshandle, callback, tuple, 
			      (void *)"event received")) {
Kirk Webb's avatar
   
Kirk Webb committed
318
319
		error("could not subscribe to events on remote server");
                return 0;
Kirk Webb's avatar
   
Kirk Webb committed
320
321
322
323
324
325
326
327
328
329
330
331
332
333
        }

        /* Setup the global event passthru */
	address_tuple_free(tuple);
	tuple = address_tuple_alloc();

	snprintf(buf, sizeof(buf), "%s,%s", 
                 ipaddr, ADDRESSTUPLE_ALL);

	tuple->host = buf;
	tuple->expt = TBDB_EVENTEXPT_NONE;

	if (! event_subscribe(bosshandle, expt_callback, tuple, 
			      NULL)) {
Kirk Webb's avatar
   
Kirk Webb committed
334
335
		error("could not subscribe to events on remote server");
                return 0;
Kirk Webb's avatar
   
Kirk Webb committed
336
337
338
339
340
341
342
343
        }

        schedule_updateevent();

        return 1;
}


Sachin Goyal's avatar
 
Sachin Goyal committed
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
/*
 * Handle incoming events from the remote server. 
 */
static void
callback(event_handle_t handle, event_notification_t notification, void *data)
{
	char		eventtype[TBDB_FLEN_EVEVENTTYPE];
	char		objecttype[TBDB_FLEN_EVOBJTYPE];
	char		objectname[TBDB_FLEN_EVOBJNAME];
	char            expt[TBDB_FLEN_PID + TBDB_FLEN_EID + 1];

	
	event_notification_get_eventtype(handle,
					 notification, eventtype, sizeof(eventtype));
	event_notification_get_objtype(handle,
				       notification, objecttype, sizeof(objecttype));
	event_notification_get_objname(handle,
				       notification, objectname, sizeof(objectname));
	event_notification_get_expt(handle, notification, expt, sizeof(expt));
	
	if (debug) {
	  info("%s %s %s\n", eventtype, objecttype, objectname);  
	}
	
	if (strcmp(objecttype,TBDB_OBJECTTYPE_EVPROXY) == 0) {
	  
	  /* Add a new subcription request if a new expt is added on
	   * the plab node.
	   */

	  if (strcmp(eventtype,TBDB_EVENTTYPE_UPDATE) == 0) {
	    
	    std::string key(expt);
	    std::map<std::string, event_subscription_t>::iterator member = 
	      exptmap.find(key);
	    
	    if(member == exptmap.end()) {

	      address_tuple_t tuple = address_tuple_alloc();
	      if (tuple == NULL) {
		fatal("could not allocate an address tuple");
	      }
	      
	      tuple->expt = expt;
		  
	      /* malloc data -- to be freed in subscribe_callback */
	      char *data = (char *) xmalloc(sizeof(expt));
	      strcpy(data, expt);

	      int retval = event_async_subscribe(bosshandle, 
					  expt_callback, tuple, NULL,
					  subscribe_callback, 
					  (void *) data, 1);
	      if (! retval) {
Kirk Webb's avatar
   
Kirk Webb committed
398
399
400
401
		error("could not subscribe to events on remote server.\n");
	      }
              info("Subscribing to experiment: %s\n", expt);

Sachin Goyal's avatar
 
Sachin Goyal committed
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
	      address_tuple_free(tuple);
	    }
	  } 

	  
	  /* Remove a old subcription whenever get a CLEAR message */
	  
	  else if (strcmp(eventtype,TBDB_EVENTTYPE_CLEAR) == 0) {
	    std::string key(expt);
	    
	    std::map<std::string, event_subscription_t>::iterator member = 
	      exptmap.find(key);
	    
	    if(member != exptmap.end()) {
	      event_subscription_t tmp = member->second;
	      
	      /* remove the subscription */
	      int success = event_async_unsubscribe(handle, tmp);
	      
	      if (!success) {
Kirk Webb's avatar
   
Kirk Webb committed
422
		error("not able to delete the subscription.\n");
423
		pubsub_error_fprintf(stderr, &handle->status);
Sachin Goyal's avatar
 
Sachin Goyal committed
424
425
	      } else {
		exptmap.erase(key);
Kirk Webb's avatar
   
Kirk Webb committed
426
                info("Unsubscribing from experiment: %s\n", expt);
Sachin Goyal's avatar
 
Sachin Goyal committed
427
428
429
430
431
432
	      }
	    }
	  }
	  
	  /* reset all subscriptions if you get a RELOAD event */
	  else if (strcmp(eventtype,TBDB_EVENTTYPE_RELOAD) == 0) {
Kirk Webb's avatar
   
Kirk Webb committed
433
434
435

            info("RELOAD received.  Clearing experiment subscriptions "
                 "and scheduling an UPDATE.\n");
Sachin Goyal's avatar
 
Sachin Goyal committed
436
437
438
439
440
441
442
443
444
445
446
	   
	    std::map<std::string, event_subscription_t>::iterator iter;
	    
	    for(iter = exptmap.begin(); iter != exptmap.end(); iter++) {
	      /* remove the subscription */
	      std::string key = iter->first;
	      event_subscription_t tmp = iter->second;
		
	      int success = event_async_unsubscribe(handle, tmp);
	      
	      if (!success) {
Kirk Webb's avatar
   
Kirk Webb committed
447
		error("not able to delete the subscription.\n");
448
		pubsub_error_fprintf(stderr, &handle->status);
Sachin Goyal's avatar
 
Sachin Goyal committed
449
450
451
452
	      }
	    }
	      
	    exptmap.clear();
Kirk Webb's avatar
   
Kirk Webb committed
453
            schedule_updateevent();
Sachin Goyal's avatar
 
Sachin Goyal committed
454
455
456
	    
	  }
	  
Sachin Goyal's avatar
   
Sachin Goyal committed
457
458
459
460
	  /* pass thru EVPROXY events to plab-scheduler */
	  if (! event_notify(localhandle, notification))
            error("Failed to deliver notification!\n");
	  
Sachin Goyal's avatar
 
Sachin Goyal committed
461
462
463
464
465
466
467
468
469
470
	}
}

/*
 * Handle incoming experiment events from the remote server  
 */
static void
expt_callback(event_handle_t handle, event_notification_t notification, void *data)
{
	char		objecttype[TBDB_FLEN_EVOBJTYPE];
Kirk Webb's avatar
   
Kirk Webb committed
471
472
        char		objectname[TBDB_FLEN_EVOBJNAME];
	char            expt[TBDB_FLEN_PID + TBDB_FLEN_EID + 1];
Sachin Goyal's avatar
 
Sachin Goyal committed
473
474
475

	event_notification_get_objtype(handle,
				       notification, objecttype, sizeof(objecttype));
Kirk Webb's avatar
   
Kirk Webb committed
476
477
478
479
480
481
482
483
        event_notification_get_objname(handle,
				       notification, objectname, sizeof(objectname));
        event_notification_get_expt(handle, notification, expt, sizeof(expt));

        if (debug) {
          info("Received event for %s: %s %s\n", expt, objecttype, objectname);
	}

Sachin Goyal's avatar
 
Sachin Goyal committed
484
	if (strcmp(objecttype,TBDB_OBJECTTYPE_EVPROXY) != 0) {
485
486
	  if (! event_notify(localhandle, notification))
	    error("Failed to deliver notification!\n");
Sachin Goyal's avatar
 
Sachin Goyal committed
487
488
489
490
491
492
493
494
495
	}
}

static void
sched_callback(event_handle_t handle,
	       event_notification_t notification,
	       void *data)
{
        if (! event_notify(bosshandle, notification))
Kirk Webb's avatar
   
Kirk Webb committed
496
		error("Failed to deliver scheduled notification!\n");
Sachin Goyal's avatar
 
Sachin Goyal committed
497
498
499
500
501
  
}



Sachin Goyal's avatar
   
Sachin Goyal committed
502
/* Callback functions for asysn event subscribe */
Sachin Goyal's avatar
 
Sachin Goyal committed
503
504
505

void subscribe_callback(event_handle_t handle,  int result,
			event_subscription_t es, void *data) {
506
  if (!result) {
Sachin Goyal's avatar
 
Sachin Goyal committed
507
508
    std::string key((char *)data);
    exptmap[key] = es;
Kirk Webb's avatar
   
Kirk Webb committed
509
    info("Subscription for %s added successfully.\n", (char *)data);
Sachin Goyal's avatar
 
Sachin Goyal committed
510
  } else {
Sachin Goyal's avatar
   
Sachin Goyal committed
511
    error("not able to add the subscription.\n");
512
    pubsub_error_fprintf(stderr, &handle->status);
Sachin Goyal's avatar
 
Sachin Goyal committed
513
514
515
516
517
518
519
  }
  
  free(data);

}


Kirk Webb's avatar
   
Kirk Webb committed
520
/* Status callback function - tries to maintain remote connection */
521
522
523
524
525
static void status_callback(pubsub_handle_t *handle,
                            pubsub_status_t status, void *data,
                            pubsub_error_t *ignored)
{
  switch (status) {
Kirk Webb's avatar
   
Kirk Webb committed
526

527
  case PUBSUB_STATUS_CONNECTION_FAILED:
Kirk Webb's avatar
   
Kirk Webb committed
528
529
530
531
532
    /* sleep, and try to connect again. */
    error("Failed to connect to remote server");
    /* XXX: may need to do something more. */
    break;

533
  case PUBSUB_STATUS_CONNECTION_LOST:
Kirk Webb's avatar
   
Kirk Webb committed
534
535
536
537
    error("Connection loss/failure, trying to reconnect...\n");
    event_stop_main(bosshandle);
    break;

538
  case PUBSUB_STATUS_CONNECTION_FOUND:
Kirk Webb's avatar
   
Kirk Webb committed
539
540
541
542
543
544
545
546
    info("Remote connection established.");
    break;

  default:
    break;
  }
}

Sachin Goyal's avatar
   
Sachin Goyal committed
547

Kirk Webb's avatar
   
Kirk Webb committed
548
void schedule_updateevent() {
549
  /* send a message to event server on ops */
Sachin Goyal's avatar
 
Sachin Goyal committed
550
  address_tuple_t tuple = address_tuple_alloc();
Kirk Webb's avatar
   
Kirk Webb committed
551
552
553
554

  struct timeval now;
  gettimeofday(&now, NULL);

Sachin Goyal's avatar
 
Sachin Goyal committed
555
556
557
558
559
560
  if (tuple == NULL) {
    fatal("could not allocate an address tuple");
  }
  
  tuple->objtype = TBDB_OBJECTTYPE_EVPROXY;
  tuple->objname = nodeidstr;
Kirk Webb's avatar
   
Kirk Webb committed
561
  tuple->eventtype = TBDB_EVENTTYPE_UPDATE;
Sachin Goyal's avatar
 
Sachin Goyal committed
562
563
564
565
566
567
568
569
570
  tuple->host = ipaddr;
  
  event_notification_t notification = 
    event_notification_alloc(bosshandle, tuple);
  
  if (notification == NULL) {
    fatal("could not allocate notification\n");
  }
  
Kirk Webb's avatar
   
Kirk Webb committed
571
572
  if (event_schedule(bosshandle, notification, &now) == 0) {
    error("could not schedule update event.\n");
Sachin Goyal's avatar
 
Sachin Goyal committed
573
  }
Kirk Webb's avatar
   
Kirk Webb committed
574
575
576

  info("Scheduled remote UPDATE event.\n");

Sachin Goyal's avatar
 
Sachin Goyal committed
577
578
579
580
581
  event_notification_free(bosshandle, notification);
  
  address_tuple_free(tuple);

}