Commit d071fefb authored by Leigh Stoller's avatar Leigh Stoller

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents 5d6c7af9 a25d63e1
This diff is collapsed.
......@@ -2143,6 +2143,7 @@ else
event/etc/elvind-boss.conf event/etc/elvind-ops.conf \
event/etc/elvind-inetd.conf event/etc/GNUmakefile\
event/sched/GNUmakefile \
event/new_sched/GNUmakefile \
event/tbgen/GNUmakefile \
event/example/GNUmakefile event/example/tbsend.pl \
event/example/tbrecv.pl event/example/tbsend-short.pl \
......@@ -2639,7 +2640,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
lib/GNUmakefile lib/libtb/GNUmakefile \
os/GNUmakefile os/split-image.sh os/imagezip/GNUmakefile \
os/imagezip/ffs/GNUmakefile os/imagezip/extfs/GNUmakefile os/imagezip/ext4fs/GNUmakefile \
os/imagezip/shd/GNUmakefile os/imagezip/hashmap/GNUmakefile \
os/imagezip/hashmap/GNUmakefile \
os/frisbee.redux/GNUmakefile os/growdisk/GNUmakefile \
os/syncd/GNUmakefile os/dijkstra/GNUmakefile \
os/genhostsfile/GNUmakefile os/zapdisk/GNUmakefile \
......
......@@ -691,6 +691,7 @@ else
event/etc/elvind-boss.conf event/etc/elvind-ops.conf \
event/etc/elvind-inetd.conf event/etc/GNUmakefile\
event/sched/GNUmakefile \
event/new_sched/GNUmakefile \
event/tbgen/GNUmakefile \
event/example/GNUmakefile event/example/tbsend.pl \
event/example/tbrecv.pl event/example/tbsend-short.pl \
......@@ -875,7 +876,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
lib/GNUmakefile lib/libtb/GNUmakefile \
os/GNUmakefile os/split-image.sh os/imagezip/GNUmakefile \
os/imagezip/ffs/GNUmakefile os/imagezip/extfs/GNUmakefile os/imagezip/ext4fs/GNUmakefile \
os/imagezip/shd/GNUmakefile os/imagezip/hashmap/GNUmakefile \
os/imagezip/hashmap/GNUmakefile \
os/frisbee.redux/GNUmakefile os/growdisk/GNUmakefile \
os/syncd/GNUmakefile os/dijkstra/GNUmakefile \
os/genhostsfile/GNUmakefile os/zapdisk/GNUmakefile \
......
......@@ -20,7 +20,7 @@ endif
ifeq ($(SYSTEM),FreeBSD)
FBSDREL := $(shell uname -r | sed -e 's/\([^-][^-]*\)-.*/\1/')
FBSDMAJ := $(basename $(FBSDREL))
SUBDIRS += sched stated
SUBDIRS += sched new_sched stated
ifneq ($(FBSDMAJ),8)
# doesn't build right now due to API changes
SUBDIRS += delay-agent
......@@ -44,6 +44,7 @@ etc-subdir:
install:
@$(MAKE) -C lib install
@$(MAKE) -C sched install
@$(MAKE) -C new_sched install
@$(MAKE) -C tbgen install
@$(MAKE) -C stated install
@$(MAKE) -C linktest install
......@@ -57,6 +58,7 @@ control-install:
@$(MAKE) -C lib control-install
@$(MAKE) -C tbgen control-install
@$(MAKE) -C sched control-install
@$(MAKE) -C new_sched control-install
@$(MAKE) -C linktest control-install
@$(MAKE) -C program-agent control-install
@$(MAKE) -C proxy control-install
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
# All rights reserved.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../..
SUBDIR = event/new_sched
include $(OBJDIR)/Makeconf
all: event-sched_rrpc
include $(TESTBED_SRCDIR)/GNUmakerules
CFLAGS += -g -pthread -DBINDIR='"$(INSTALL_BINDIR)"'
CFLAGS += -DSBINDIR='"$(INSTALL_SBINDIR)"'
#CFLAGS += -DDEBUG
CFLAGS += -O -Wall
CFLAGS += -I. -I${OBJDIR} -I$(SRCDIR)/../lib -I$(TESTBED_SRCDIR)/lib/libtb
CFLAGS += -I/usr/local/include
LDFLAGS += -pthread
LDFLAGS += -L../lib -L${OBJDIR}/lib/libtb
LDFLAGS += $(LDSTATIC)
DBLIBS = -L/usr/local/lib/mysql -lmysqlclient -lz
LIBS += -levent_r -ltb -lz
XMLRPCINC = `xmlrpc-c-config c++2 client --cflags`
CXXFLAGS += -pthread -O $(XMLRPCINC) -I$(OBJDIR) -I$(TESTBED_SRCDIR)/lib/libtb
CXXFLAGS += -I$(SRCDIR)/../lib
XMLRPCLIBS = `xmlrpc-c-config c++2 client --libs`
#
# XXX elvin-config adds -lc which is rather bogus, and messes up -pthread
# build on freebsd. I made a vain attempt to filter it out, but
# gave up quickly. Deal with it later.
#
#LIBS += `elvin-config --libs vin4mt`
LIBS += -L/usr/local/lib -lpubsub_r -lssl -lcrypto -lm
OBJS = event-sched.o
version.c: event-sched.c
echo >$@ "char build_info[] = \"Built on `date +%d-%b-%Y` by `id -nu`@`hostname | sed 's/\..*//'`:`pwd`\";"
OBJS = \
emulab_proxy.o \
console-agent.o \
error-record.o \
event-sched_rpc.o \
group-agent.o \
listNode.o \
local-agent.o \
node-agent.o \
queue.o \
rrpc.o \
simulator-agent.o \
timeline-agent.o \
version.o
event-sched_rrpc: $(OBJS) event-sched.h ../lib/libevent.a
$(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(XMLRPCLIBS) $(LIBS)
DEPS = \
console-agent.h error-record.h event-sched.h group-agent.h listNode.h \
local-agent.h node-agent.h rpc.h simulator-agent.h timeline-agent.h \
../lib/event.h
emulab_proxy.o: emulab_proxy.cc $(DEPS)
queue.o: queue.c $(DEPS)
listNode.o: listNode.c $(DEPS)
error-record.o: error-record.c $(DEPS)
local-agent.o: local-agent.c $(DEPS)
group-agent.o: group-agent.c $(DEPS)
simulator-agent.o: simulator-agent.cc $(DEPS)
console-agent.o: console-agent.cc $(DEPS)
node-agent.o: node-agent.cc $(DEPS)
event-sched_rpc.o: event-sched.c $(DEPS)
$(CC) $(CFLAGS) -DRPC -c -o $@ $<
rpc.o: rpc.cc rpc.h event-sched.h
$(CXX) $(CXXFLAGS) -DSSHRPC $(XMLRPCINC) -c $<
rrpc.o: rpc.cc $(DEPS)
$(CXX) -g $(CXXFLAGS) -DSSLRPC $(XMLRPCINC) -c -o rrpc.o $<
install: event-sched_rrpc
-mkdir -p $(INSTALL_DIR)/opsdir/sbin
$(INSTALL_PROGRAM) $< $(INSTALL_DIR)/opsdir/sbin/new-event-sched
-mkdir -p $(INSTALL_DIR)/opsdir/man/man8
$(INSTALL) -m 0644 $(SRCDIR)/event-sched.8 \
$(INSTALL_DIR)/opsdir/man/man8/event-sched.8
-mkdir -p $(INSTALL_DIR)/opsdir/bin
$(INSTALL_PROGRAM) $(SRCDIR)/elog2xplot \
$(INSTALL_DIR)/opsdir/bin/elog2xplot
control-install: event-sched_rrpc
$(INSTALL_PROGRAM) $< $(INSTALL_SBINDIR)/new-event-sched
# not a client thing
client:
client-install: client
clean:
/bin/rm -f *.o event-sched event-sched_rpc event-sched_rrpc version.c
#
# EMULAB-COPYRIGHT
# Copyright (c) 2002 University of Utah and the Flux Group.
# All rights reserved.
#
# Makefile for building event scheduler
#
# $Id: Makefile,v 1.5 2006-12-01 22:59:37 mike Exp $
CC = gcc
CFLAGS = -g -I. -I../lib -Wall -DDEBUG
LDFLAGS =
LIBS = -lpthread -L../lib -levent
CFLAGS += `elvin-config --cflags vin4mt`
LIBS += `elvin-config --libs vin4mt`
MV = mv -f
RM = rm -f
program = event-sched
source = event-sched.c queue.c
object = event-sched.o queue.o
header = event-sched.h
.c.o:
$(CC) $(CFLAGS) -c $<
default: $(program)
$(program): $(object)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(LIBS)
$(program): ../lib/libevent.a
$(object): $(header) ../lib/event.h
clean:
$(RM) $(program) $(object)
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2004, 2005, 2007 University of Utah and the Flux Group.
* All rights reserved.
*/
#include "config.h"
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <unistd.h>
#include <string.h>
#include "console-agent.h"
#ifndef min
#define min(x, y) ((x) < (y)) ? (x) : (y)
#endif
/**
* A "looper" function for console agents that dequeues and processes events
* for a particular console. This function will be passed to pthread_create
* when a new thread needs to be created to handle events.
*
* @param arg The console agent object to handle events for.
* @return NULL
*
* @see reload_with
* @see do_reboot
* @see local_agent_queue
* @see local_agent_dequeue
*/
static void *console_agent_looper(void *arg);
console_agent_t create_console_agent(void)
{
console_agent_t ca, retval;
if ((ca = (console_agent_t)
malloc(sizeof(struct _console_agent))) == NULL) {
retval = NULL;
errno = ENOMEM;
}
else if (local_agent_init(&ca->ca_local_agent) != 0) {
retval = NULL;
}
else {
ca->ca_local_agent.la_flags |= LAF_MULTIPLE;
ca->ca_local_agent.la_looper = console_agent_looper;
ca->ca_mark = -1;
retval = ca;
ca = NULL;
}
free(ca);
ca = NULL;
return retval;
}
int console_agent_invariant(console_agent_t ca)
{
assert(ca != NULL);
assert(local_agent_invariant(&ca->ca_local_agent));
}
static void do_start(console_agent_t ca, sched_event_t *se)
{
int lpc;
assert(ca != NULL);
assert(console_agent_invariant(ca));
assert(se != NULL);
for (lpc = 0; lpc < se->length; lpc++) {
char path[MAXPATHLEN];
struct agent *agent;
struct stat st;
if (se->length == 1)
agent = se->agent.s;
else
agent = se->agent.m[lpc];
snprintf(path, sizeof(path),
"%s/%s.run",
TIPLOGDIR, agent->nodeid);
if (stat(path, &st) < 0) {
error("could not stat %s\n", path);
}
else {
ca = (console_agent_t)agent->handler;
ca->ca_mark = st.st_size;
}
}
}
static void do_stop(console_agent_t ca, sched_event_t *se, char *args)
{
char *filename;
int rc, lpc;
assert(ca != NULL);
assert(console_agent_invariant(ca));
assert(se != NULL);
assert(args != NULL);
if (ca->ca_mark == -1) {
error("CONSOLE STOP event without a START");
return;
}
if ((rc = event_arg_get(args, "FILE", &filename)) < 0) {
error("no filename given in CONSOLE STOP event");
return;
}
filename[rc] = '\0';
for (lpc = 0; lpc < se->length; lpc++) {
char path[MAXPATHLEN], outpath[MAXPATHLEN];
int infd = -1, outfd = -1;
struct agent *agent;
size_t end_mark;
struct stat st;
if (se->length == 1)
agent = se->agent.s;
else
agent = se->agent.m[lpc];
snprintf(path, sizeof(path),
"%s/%s.run",
TIPLOGDIR, agent->nodeid);
if (stat(path, &st) < 0) {
error("could not stat %s\n", path);
ca->ca_mark = -1;
continue;
}
snprintf(outpath, sizeof(outpath),
"logs/%s-%s.log",
agent->name,
filename);
ca = (console_agent_t)agent->handler;
end_mark = st.st_size;
if ((infd = open(path, O_RDONLY)) < 0) {
error("could not open %s\n", path);
}
else if (lseek(infd, ca->ca_mark, SEEK_SET) < 0) {
error("could not seek to right place\n");
}
else if ((outfd = open(outpath,
O_WRONLY|O_CREAT|O_TRUNC,
0640)) < 0) {
error("could not create output file\n");
}
else {
size_t remaining = end_mark - ca->ca_mark;
char buffer[4096];
while ((rc = read(infd,
buffer,
min(remaining,
sizeof(buffer)))) > 0) {
write(outfd, buffer, rc);
remaining -= rc;
}
}
if (infd != -1)
close(infd);
if (outfd != -1)
close(outfd);
ca->ca_mark = -1;
}
}
static void *console_agent_looper(void *arg)
{
console_agent_t ca = (console_agent_t)arg;
event_handle_t handle;
void *retval = NULL;
sched_event_t se;
assert(arg != NULL);
handle = ca->ca_local_agent.la_handle;
while (local_agent_dequeue(&ca->ca_local_agent, 0, &se) == 0) {
char evtype[TBDB_FLEN_EVEVENTTYPE];
event_notification_t en;
char argsbuf[BUFSIZ];
en = se.notification;
if (!event_notification_get_eventtype(
handle, en, evtype, sizeof(evtype))) {
error("couldn't get event type from notification %p\n",
en);
}
else {
struct agent **agent_array, *agent_singleton[1];
int rc, lpc, token = ~0;
event_notification_get_arguments(handle,
en,
argsbuf,
sizeof(argsbuf));
event_notification_get_int32(handle,
en,
"TOKEN",
(int32_t *)&token);
argsbuf[sizeof(argsbuf) - 1] = '\0';
if (strcmp(evtype, TBDB_EVENTTYPE_START) == 0) {
do_start(ca, &se);
}
else if (strcmp(evtype, TBDB_EVENTTYPE_STOP) == 0) {
do_stop(ca, &se, argsbuf);
}
else {
error("cannot handle CONSOLE event %s.",
evtype);
rc = -1;
}
}
sched_event_free(handle, &se);
}
return retval;
}
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2005 University of Utah and the Flux Group.
* All rights reserved.
*/
/**
* @file console-agent.h
*/
#ifndef _console_agent_h
#define _console_agent_h
#include "event-sched.h"
#include "local-agent.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TIPLOGDIR "/var/log/tiplogs"
/**
* A local agent structure for Console objects.
*/
struct _console_agent {
struct _local_agent ca_local_agent; /*< Local agent base. */
off_t ca_mark;
};
/**
* Pointer type for the _console_agent structure.
*/
typedef struct _console_agent *console_agent_t;
/**
* Create a console agent and intialize it with the default values.
*
* @return An initialized console agent object.
*/
console_agent_t create_console_agent(void);
/**
* Check a console agent object against the following invariants:
*
* @li na_local_agent is sane
*
* @param na An initialized console agent object.
* @return True.
*/
int console_agent_invariant(console_agent_t na);
#ifdef __cplusplus
}
#endif
#endif
#! /usr/bin/awk -f
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# All rights reserved.
#
BEGIN {
printf("timeval unsigned\n");
printf("title\n");
printf("Event Timeline\n");
printf("xlabel\n");
printf("time\n");
printf("ylabel\n");
printf("agent\n");
printf("white\n");
firsttime = 0;
agents = 0;
}
/Agent: / {
agents += 1;
agent[$2] = agents;
}
/Fire: / {
split($3, tv, /:/);
split($5, aname, /:/);
if (firsttime == 0 || tv[2] < firsttime)
firsttime = tv[2];
if (aname[2] in agent) {
printf("x %s.%s %s\n", tv[2], tv[3], agent[aname[2]]);
}
}
END {
for (ag in agent) {
printf("rtext %s.0 %d\n%s\n", firsttime - 5, agent[ag], ag);
}
printf("go\n");
}
/*
* emulab_proxy.cpp
*
* Copyright (c) 2004 The University of Utah and the Flux Group.
* All rights reserved.
*
* This file is licensed under the terms of the GNU Public License.
* See the file "license.terms" for restrictions on redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/client.hpp>
#include <assert.h>
#include <xmlrpc-c/girerr.hpp>
#include <map>
#include <iostream>
#include "emulab_proxy.h"
using namespace emulab;
/**
* The Emulab XML-RPC protocol version number.
*/
static const double PROTOCOL_VERSION = 0.1;
EmulabResponse::EmulabResponse(const er_code_t code,
const xmlrpc_c::value value,
const xmlrpc_c::value output)
: er_Code(code), er_Value(value), er_Output(output)
{
}
EmulabResponse::EmulabResponse(xmlrpc_c::value result)
{
std::map<std::string, xmlrpc_c::value> result_map;
std::map<std::string, xmlrpc_c::value>::iterator p;
if (!result.type() == xmlrpc_c::value::TYPE_STRUCT)
{
throw girerr::error("Invalid response from server");
}
result_map = (xmlrpc_c::value_struct)result;
/* Make sure the result has what we expect before */
p = result_map.find("code");
if (p == result_map.end()) {
throw girerr::error("Invalid response from server");
}
/* ... decoding its contents. */
this->er_Code = (er_code_t)(int)(xmlrpc_c::value_int)result_map["code"];
this->er_Value = result_map["value"];
this->er_Output = result_map["output"];
}
EmulabResponse::~EmulabResponse()
{
}
ServerProxy::ServerProxy(xmlrpc_c::clientXmlTransportPtr transport,
bool wbxml_mode,
const char *url)
{
this->transport = transport;
this->server_url = url;
}
ServerProxy::~ServerProxy()
{
}
xmlrpc_c::value ServerProxy::call(xmlrpc_c::rpcPtr rpc)
{
xmlrpc_c::client_xml client(this->transport);
xmlrpc_c::carriageParm_curl0 carriage_parm(this->server_url);
rpc->call(&client, &carriage_parm);
assert(rpc->isFinished());
/* This will throw an exception if the RPC call failed */
return rpc->getResult();
}
EmulabResponse ServerProxy::invoke(const char *method_name,
spa_attr_t tag,
...)
{
va_list args;
va_start(args, tag);
EmulabResponse retval = this->invoke(method_name, tag, args);
va_end(args);
return( retval );
}
EmulabResponse ServerProxy::invoke(const char *method_name,
spa_attr_t tag,
va_list args)
{
xmlrpc_c::paramList params;
std::map <std::string, xmlrpc_c::value> struct_data;
/* Iterate over the tag list to build the argument structure, */
while( tag != SPA_TAG_DONE )
{
std::string key;
key = std::string(va_arg(args, const char *));
switch( tag )
{
case SPA_Boolean:
struct_data[key] =
xmlrpc_c::value_boolean((bool)va_arg(args, int));
break;
case SPA_Integer:
struct_data[key] =
xmlrpc_c::value_int(va_arg(args, int));
break;
case SPA_Double:
struct_data[key] =
xmlrpc_c::value_double(va_arg(args, double));
break;
case SPA_String:
struct_data[key] =
xmlrpc_c::value_string(
std::string(va_arg(args, const char *)));
break;
default:
break;
}
tag = (spa_attr_t)va_arg(args, int);
}
/* ... add the parameters, and */
params.add(xmlrpc_c::value_double(PROTOCOL_VERSION));
params.add(xmlrpc_c::value_struct(struct_data));
xmlrpc_c::rpcPtr rpc(std::string(method_name), params);
/* ... call the method. */
return EmulabResponse(this->call(rpc));
}
/*
* emulab_proxy.h
*
* Copyright (c) 2004 The University of Utah and the Flux Group.
* All rights reserved.
*
* This file is licensed under the terms of the GNU Public License.
* See the file "license.terms" for restrictions on redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef emulab_proxy_h
#define emulab_proxy_h
#include <xmlrpc-c/base.hpp>
#include <stdarg.h>
#include <string>