Commit 52b499d4 authored by Leigh Stoller's avatar Leigh Stoller

New and improved library for testbed C programs. Includes generic

mysql code (similar to whats in tmcd.c) plus some logging function
support.
parent 1082e7f6
......@@ -9,14 +9,15 @@ all: event-sched
include $(TESTBED_SRCDIR)/GNUmakerules
CFLAGS += -O -g -I. -I${OBJDIR} -I$(SRCDIR)/../lib -Wall -pthread -DDEBUG
CFLAGS += -O -g -Wall -pthread -DDEBUG
CFLAGS += -I. -I${OBJDIR} -I$(SRCDIR)/../lib -I$(TESTBED_SRCDIR)/lib/libtb
CFLAGS += `elvin-config --cflags vin4mt`
LDFLAGS += -pthread -L../lib
LIBS += -levent -lcipher -L/usr/local/lib/mysql -lmysqlclient
LDFLAGS += -pthread -L../lib -L${OBJDIR}/lib/libtb
LIBS += -levent -ltb -lcipher -L/usr/local/lib/mysql -lmysqlclient
LIBS += `elvin-config --libs vin4mt`
OBJS = event-sched.o queue.o libdb.o
OBJS = event-sched.o queue.o
event-sched: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
......
/*
* Testbed DB interface and support.
*/
#include <stdarg.h>
#include <mysql/mysql.h>
/*
* Generic interface.
*/
int dbinit(void);
/*
* mysql specific routines.
*/
MYSQL_RES *mydb_query(char *query, int ncols, ...);
int mydb_update(char *query, ...);
......@@ -8,8 +8,26 @@ SUBDIR = lib
include $(OBJDIR)/Makeconf
all:
SUBDIRS = libtb
all: $(SUBDIRS)
include $(TESTBED_SRCDIR)/GNUmakerules
install:
libtb:
@$(MAKE) -C libtb all
install:
@$(MAKE) -C libtb install
clean: subdir-clean
subdir-clean:
@$(MAKE) -C libtb clean
distclean: subdir-distclean
subdir-distclean:
@$(MAKE) -C libtb distclean
.PHONY: $(SUBDIRS)
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../..
SUBDIR = lib/libtb
include $(OBJDIR)/Makeconf
all: libtb.a
include $(TESTBED_SRCDIR)/GNUmakerules
SYSTEM := $(shell uname -s)
OBJS = log.o
ifneq ($(SYSTEM),Linux)
OBJS += tbdb.o
endif
CFLAGS += -O -g -Wall -I${OBJDIR} -I/usr/local/include
libtb.a: $(OBJS)
$(AR) crv $@ $(OBJS)
$(RANLIB) $@
log.o: log.h
tbdb.o: tbdb.h log.h
install:
clean:
/bin/rm -f *.o *.a
/*
* Logging and debug routines.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <assert.h>
#include <errno.h>
#include "log.h"
static int usesyslog = 0;
/*
* Init.
*/
int
loginit(char *progname, int slog)
{
if (! slog) {
usesyslog = 0;
return 1;
}
usesyslog = 1;
openlog(progname, LOG_PID, LOG_USER);
return 0;
}
void
info(const char *fmt, ...)
{
va_list args;
char buf[BUFSIZ];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (!usesyslog) {
fputs(buf, stderr);
fputc('\n', stderr);
}
else
syslog(LOG_INFO, "%s", buf);
}
void
warning(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (!usesyslog) {
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
fflush(stderr);
}
else
vsyslog(LOG_WARNING, fmt, args);
va_end(args);
}
void
error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (!usesyslog) {
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
fflush(stderr);
}
else
vsyslog(LOG_ERR, fmt, args);
va_end(args);
}
void
fatal(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (!usesyslog) {
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
fflush(stderr);
}
else
vsyslog(LOG_ERR, fmt, args);
va_end(args);
exit(-1);
}
void
pwarning(const char *fmt, ...)
{
va_list args;
char buf[BUFSIZ];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
warning("%s : %s", buf, strerror(errno));
}
void
pfatal(const char *fmt, ...)
{
va_list args;
char buf[BUFSIZ];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
fatal("%s : %s", buf, strerror(errno));
}
/*
* Log defs.
*/
#include <stdarg.h>
int loginit(char *progname, int usesyslog);
void info(const char *fmt, ...);
void warning(const char *fmt, ...);
void error(const char *fmt, ...);
void fatal(const char *fmt, ...);
void pwarning(const char *fmt, ...);
void pfatal(const char *fmt, ...);
......@@ -3,9 +3,6 @@
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -13,8 +10,8 @@
#include <unistd.h>
#include <syslog.h>
#include <assert.h>
#include "event-sched.h"
#include "libdb.h"
#include "tbdb.h"
#include "log.h"
#include "config.h"
/*
......@@ -29,7 +26,7 @@ dbinit(void)
mysql_init(&db);
if (mysql_real_connect(&db, 0, 0, 0,
dbname, 0, 0, CLIENT_INTERACTIVE) == 0) {
ERROR("%s: connect failed: %s", dbname, mysql_error(&db));
error("%s: connect failed: %s", dbname, mysql_error(&db));
return 0;
}
return 1;
......@@ -46,23 +43,23 @@ mydb_query(char *query, int ncols, ...)
va_start(ap, ncols);
n = vsnprintf(querybuf, sizeof(querybuf), query, ap);
if (n > sizeof(querybuf)) {
ERROR("query too long for buffer");
error("query too long for buffer");
return (MYSQL_RES *) 0;
}
if (mysql_real_query(&db, querybuf, n) != 0) {
ERROR("%s: query failed: %s", dbname, mysql_error(&db));
error("%s: query failed: %s", dbname, mysql_error(&db));
return (MYSQL_RES *) 0;
}
res = mysql_store_result(&db);
if (res == 0) {
ERROR("%s: store_result failed: %s", dbname, mysql_error(&db));
error("%s: store_result failed: %s", dbname, mysql_error(&db));
return (MYSQL_RES *) 0;
}
if (ncols && ncols != (int)mysql_num_fields(res)) {
ERROR("%s: Wrong number of fields returned "
error("%s: Wrong number of fields returned "
"Wanted %d, Got %d",
dbname, ncols, (int)mysql_num_fields(res));
mysql_free_result(res);
......@@ -81,13 +78,114 @@ mydb_update(char *query, ...)
va_start(ap, query);
n = vsnprintf(querybuf, sizeof(querybuf), query, ap);
if (n > sizeof(querybuf)) {
ERROR("query too long for buffer");
return 1;
error("query too long for buffer");
return 0;
}
if (mysql_real_query(&db, querybuf, n) != 0) {
ERROR("%s: query failed: %s", dbname, mysql_error(&db));
return 1;
error("%s: query failed: %s", dbname, mysql_error(&db));
return 0;
}
return 1;
}
/*
* Map IP to node ID.
*/
int
mydb_iptonodeid(char *ipaddr, char *bufp)
{
MYSQL_RES *res;
MYSQL_ROW row;
res = mydb_query("select node_id from interfaces where IP='%s'",
1, ipaddr);
if (!res) {
error("iptonodeid: DB Error: %s", ipaddr);
return 0;
}
return 0;
if (! (int)mysql_num_rows(res)) {
error("iptonodeid: No such nodeid: %s", ipaddr);
mysql_free_result(res);
return 0;
}
row = mysql_fetch_row(res);
mysql_free_result(res);
strcpy(bufp, row[0]);
return 1;
}
/*
* Set the node event status.
*/
int
mydb_setnodeeventstate(char *nodeid, char *eventtype)
{
if (! mydb_update("update nodes set eventstatus='%s' "
"where node_id='%s'",
eventtype, nodeid)) {
error("setnodestatus: DB Error: %s/%s!", nodeid, eventtype);
return 0;
}
return 1;
}
/*
* See if all nodes in an experiment are at the specified event state.
* Return number of nodes not in the proper state.
*/
int
mydb_checkexptnodeeventstate(char *pid, char *eid,
char *eventtype, int *count)
{
MYSQL_RES *res;
MYSQL_ROW row;
int nrows;
res = mydb_query("select eventstatus from nodes "
"left join reserved on "
" nodes.node_id=reserved.node_id "
"where reserved.pid='%s' and reserved.eid='%s' ",
1, pid, eid);
if (!res) {
error("checkexptnodeeventstate: DB Error: %s/%s/%s",
pid, eid, eventtype);
return 0;
}
if (! (nrows = mysql_num_rows(res))) {
error("checkexptnodeeventstate: No such experiment: %s/%s",
pid, eid);
mysql_free_result(res);
return 0;
}
*count = 0;
while (nrows) {
row = mysql_fetch_row(res);
if (!row[0] || !row[0][0] || strcmp(row[0], eventtype))
*count += 1;
nrows--;
}
mysql_free_result(res);
return 1;
}
/*
* Set (or clear) event scheduler process ID. A zero is treated as
* a request to clear it.
*/
int
mydb_seteventschedulerpid(char *pid, char *eid, int processid)
{
if (! mydb_update("update experiments set event_sched_pid=%d "
"where pid='%s' and eid='%s'",
processid, pid, eid)) {
error("seteventschedulerpid: DB Error: %s/%s!", pid, eid);
return 0;
}
return 1;
}
/*
* Testbed DB interface and support.
*/
#include <stdarg.h>
#include <mysql/mysql.h>
/*
* Generic interface.
*/
int dbinit(void);
/*
* TB functions.
*/
int mydb_iptonodeid(char *ipaddr, char *bufp);
int mydb_setnodeeventstate(char *nodeid, char *eventtype);
int mydb_checkexptnodeeventstate(char *pid, char *eid,char *ev,int *count);
int mydb_seteventschedulerpid(char *pid, char *eid, int processid);
/*
* mysql specific routines.
*/
MYSQL_RES *mydb_query(char *query, int ncols, ...);
int mydb_update(char *query, ...);
/*
* Various constants.
*/
#define TBDB_FLEN_NODEID 64
#define TBDB_FLEN_EVOBJTYPE 128
#define TBDB_FLEN_EVOBJNAME 128
#define TBDB_FLEN_EVEVENTTYPE 128
/*
* Event system stuff
*/
#define TBDB_OBJECTTYPE_TESTBED "TBCONTROL"
#define TBDB_OBJECTTYPE_LINK "LINK"
#define TBDB_OBJECTTYPE_TRAFGEN "TRAFGEN"
#define TBDB_EVENTTYPE_ISUP "ISUP"
#define TBDB_EVENTTYPE_REBOOT "REBOOT"
#define TBDB_EVENTTYPE_UP "UP"
#define TBDB_EVENTTYPE_DOWN "DOWN"
#define TBDB_EVENTTYPE_MODIFY "MODIFY"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment