Commit 039a86c8 authored by Leigh Stoller's avatar Leigh Stoller

Minor reorganization simply so I can include the guts into tmcd to do

bootwhat without code duplication.
parent bbda9677
......@@ -45,9 +45,10 @@ CFLAGS += -DEVENTSYS -I$(TESTBED_SRCDIR)/event/lib -I/usr/local/include
LFLAGS += $(OBJDIR)/event/lib/libevent.a -L/usr/local/lib -lpubsub -lcrypto
endif
bootinfo: bootinfo.o bootinfo.h bootinfo_version.o bootwhat.h $(BI_DBOBJ)
bootinfo: main.o bootinfo.o bootinfo.h bootinfo_version.o \
bootwhat.h $(BI_DBOBJ)
cc $(CFLAGS) $(DBFLAG) $(INCS) \
-o bootinfo bootinfo.o bootinfo_version.o $(BI_DBOBJ) \
-o bootinfo main.o bootinfo.o bootinfo_version.o $(BI_DBOBJ) \
$(LFLAGS) -L/usr/local/lib/mysql -lmysqlclient
bootinfosend: bootinfosend.o bootinfo.h bootinfo_version.o bootwhat.h $(BI_DBOBJ)
......@@ -60,6 +61,7 @@ bootinfoclient: bootinfoclient.o bootinfo.h bootinfo_version.o bootwhat.h
-o bootinfoclient bootinfoclient.o bootinfo_version.o
bootinfo_mysql.o: bootinfo.h bootwhat.h
main.o: bootinfo.h bootwhat.h
testbootinfo_mysql: bootinfo_mysql.c
cc $(CFLAGS) -DUSE_MYSQL_DB -DTEST $(INCS) \
......
......@@ -29,222 +29,96 @@
*/
#define MINEVENTTIME 10
static void log_bootwhat(struct in_addr ipaddr, boot_what_t *bootinfo);
static void onhup(int sig);
static char *progname;
static int bicache_init(void);
static int bicache_shutdown(void);
static int bicache_needevent(struct in_addr ipaddr);
int debug = 0;
void
usage()
{
fprintf(stderr,
"Usage: %s <options> [-d]\n"
"options:\n"
"-d - Turn on debugging\n"
"-p port - Specify port number to listen on\n",
progname);
exit(-1);
}
int
main(int argc, char **argv)
bootinfo_init(void)
{
int sock, length, mlen, err, c;
struct sockaddr_in name, client;
boot_info_t boot_info;
boot_what_t *boot_whatp = (boot_what_t *) &boot_info.data;
int port = BOOTWHAT_DSTPORT;
char buf[BUFSIZ];
FILE *fp;
extern char build_info[];
progname = argv[0];
while ((c = getopt(argc, argv, "p:dhv")) != -1) {
switch (c) {
case 'd':
debug++;
break;
case 'p':
port = atoi(optarg);
break;
case 'v':
fprintf(stderr, "%s\n", build_info);
exit(0);
break;
case 'h':
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc)
usage();
if (debug)
loginit(0, 0);
else {
/* Become a daemon */
daemon(0, 0);
loginit(1, "bootinfo");
}
info("%s\n", build_info);
/*
* Write out a pidfile.
*/
sprintf(buf, "%s/bootinfo.pid", _PATH_VARRUN);
fp = fopen(buf, "w");
if (fp != NULL) {
fprintf(fp, "%d\n", getpid());
(void) fclose(fp);
}
int err;
/* Initialize data base */
err = open_bootinfo_db();
if (err) {
error("could not open database");
exit(1);
return -1;
}
err = bicache_init();
if (err) {
error("could not initialize cache");
exit(1);
return -1;
}
#ifdef EVENTSYS
err = bievent_init();
if (err) {
error("could not initialize event system");
exit(1);
return -1;
}
#endif
/* Create socket from which to read. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
errorc("opening datagram socket");
exit(1);
}
/* Create name. */
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = htons((u_short) port);
if (bind(sock, (struct sockaddr *) &name, sizeof(name))) {
errorc("binding datagram socket");
exit(1);
}
/* Find assigned port value and print it out. */
length = sizeof(name);
if (getsockname(sock, (struct sockaddr *) &name, &length)) {
errorc("getting socket name");
exit(1);
}
info("listening on port %d\n", ntohs(name.sin_port));
signal(SIGHUP, onhup);
while (1) {
int needevent = 1;
if ((mlen = recvfrom(sock, &boot_info, sizeof(boot_info),
0, (struct sockaddr *)&client, &length))
< 0) {
errorc("receiving datagram packet");
exit(1);
}
return 0;
}
switch (boot_info.opcode) {
case BIOPCODE_BOOTWHAT_REQUEST:
case BIOPCODE_BOOTWHAT_INFO:
info("%s: REQUEST (vers %d)\n",
inet_ntoa(client.sin_addr), boot_info.version);
int
bootinfo(struct in_addr ipaddr, struct boot_info *boot_info, void *opaque)
{
int needevent = 0;
int err;
boot_what_t *boot_whatp = (boot_what_t *) &boot_info->data;
switch (boot_info->opcode) {
case BIOPCODE_BOOTWHAT_REQUEST:
case BIOPCODE_BOOTWHAT_INFO:
info("%s: REQUEST (vers %d)\n",
inet_ntoa(ipaddr), boot_info->version);
#ifdef EVENTSYS
needevent = bicache_needevent(client.sin_addr);
if (needevent)
bievent_send(client.sin_addr,
TBDB_NODESTATE_PXEBOOTING);
needevent = bicache_needevent(ipaddr);
if (needevent)
bievent_send(ipaddr, opaque,
TBDB_NODESTATE_PXEBOOTING);
#endif
err = query_bootinfo_db(client.sin_addr,
boot_info.version,
boot_whatp);
break;
err = query_bootinfo_db(ipaddr,
boot_info->version, boot_whatp);
break;
default:
info("%s: invalid packet %d\n",
inet_ntoa(client.sin_addr), boot_info.opcode);
continue;
}
if (err)
boot_info.status = BISTAT_FAIL;
else {
boot_info.status = BISTAT_SUCCESS;
log_bootwhat(client.sin_addr, boot_whatp);
default:
info("%s: invalid packet %d\n",
inet_ntoa(ipaddr), boot_info->opcode);
return -1;
}
if (err)
boot_info->status = BISTAT_FAIL;
else {
boot_info->status = BISTAT_SUCCESS;
#ifdef EVENTSYS
if (needevent) {
switch (boot_whatp->type) {
case BIBOOTWHAT_TYPE_PART:
case BIBOOTWHAT_TYPE_SYSID:
case BIBOOTWHAT_TYPE_MB:
case BIBOOTWHAT_TYPE_MFS:
bievent_send(client.sin_addr,
TBDB_NODESTATE_BOOTING);
break;
if (needevent) {
switch (boot_whatp->type) {
case BIBOOTWHAT_TYPE_PART:
case BIBOOTWHAT_TYPE_SYSID:
case BIBOOTWHAT_TYPE_MB:
case BIBOOTWHAT_TYPE_MFS:
bievent_send(ipaddr, opaque,
TBDB_NODESTATE_BOOTING);
break;
case BIBOOTWHAT_TYPE_WAIT:
bievent_send(client.sin_addr,
TBDB_NODESTATE_PXEWAIT);
break;
case BIBOOTWHAT_TYPE_REBOOT:
bievent_send(client.sin_addr,
TBDB_NODESTATE_REBOOTING);
break;
default:
error("%s: invalid boot directive: %d\n",
inet_ntoa(client.sin_addr),
boot_whatp->type);
break;
}
case BIBOOTWHAT_TYPE_WAIT:
bievent_send(ipaddr, opaque,
TBDB_NODESTATE_PXEWAIT);
break;
case BIBOOTWHAT_TYPE_REBOOT:
bievent_send(ipaddr, opaque,
TBDB_NODESTATE_REBOOTING);
break;
default:
error("%s: invalid boot directive: %d\n",
inet_ntoa(ipaddr), boot_whatp->type);
break;
}
#endif
}
boot_info.opcode = BIOPCODE_BOOTWHAT_REPLY;
client.sin_family = AF_INET;
client.sin_port = htons(BOOTWHAT_SRCPORT);
if (sendto(sock, (char *)&boot_info, sizeof(boot_info), 0,
(struct sockaddr *)&client, sizeof(client)) < 0)
errorc("sendto");
}
close(sock);
close_bootinfo_db();
#ifdef EVENTSYS
bievent_shutdown();
#endif
bicache_shutdown();
info("daemon terminating\n");
exit(0);
}
static void
onhup(int sig)
{
int err;
info("re-initializing configuration database\n");
close_bootinfo_db();
err = open_bootinfo_db();
if (err) {
error("Could not reopen database");
exit(1);
}
return 0;
}
/*
......@@ -258,22 +132,10 @@ static DB *dbp;
static int
bicache_init(void)
{
if ((dbp =
dbopen(NULL, O_CREAT|O_TRUNC|O_RDWR, 664, DB_HASH, NULL)) == NULL) {
errorc("failed to initialize the bootinfo DBM");
return 1;
}
return 0;
}
static int
bicache_shutdown(void)
{
if (dbp) {
if (dbp->close(dbp) < 0) {
errorc("failed to sutdown the bootinfo DBM");
return 1;
}
if ((dbp = dbopen(NULL, O_CREAT|O_TRUNC|O_RDWR, 664, DB_HASH, NULL))
== NULL) {
pfatal("failed to initialize the bootinfo DBM");
return -1;
}
return 0;
}
......@@ -292,6 +154,10 @@ bicache_needevent(struct in_addr ipaddr)
time_t tt = time(NULL);
int rval = 1, r;
/* So we can include bootinfo into tmcd; always send the event. */
if (!dbp)
return 1;
key.data = (void *) &ipaddr;
key.size = sizeof(ipaddr);
......@@ -329,38 +195,3 @@ bicache_needevent(struct in_addr ipaddr)
return rval;
}
static void
log_bootwhat(struct in_addr ipaddr, boot_what_t *bootinfo)
{
char ipstr[32];
strncpy(ipstr, inet_ntoa(ipaddr), sizeof ipstr);
switch (bootinfo->type) {
case BIBOOTWHAT_TYPE_PART:
info("%s: REPLY: boot from partition %d\n",
ipstr, bootinfo->what.partition);
break;
case BIBOOTWHAT_TYPE_SYSID:
info("%s: REPLY: boot from partition with sysid %d\n",
ipstr, bootinfo->what.sysid);
break;
case BIBOOTWHAT_TYPE_MB:
info("%s: REPLY: boot multiboot image %s:%s\n",
ipstr, inet_ntoa(bootinfo->what.mb.tftp_ip),
bootinfo->what.mb.filename);
break;
case BIBOOTWHAT_TYPE_WAIT:
info("%s: REPLY: wait mode\n", ipstr);
break;
case BIBOOTWHAT_TYPE_MFS:
info("%s: REPLY: boot from mfs %s\n", ipstr, bootinfo->what.mfs);
break;
case BIBOOTWHAT_TYPE_REBOOT:
info("%s: REPLY: reboot (alternate PXE boot)\n", ipstr);
break;
}
if (bootinfo->cmdline[0]) {
info("%s: REPLY: command line: %s\n", ipstr, bootinfo->cmdline);
}
}
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2004 University of Utah and the Flux Group.
* Copyright (c) 2000-2004, 2007 University of Utah and the Flux Group.
* All rights reserved.
*/
struct boot_what;
struct boot_info;
int open_bootinfo_db(void);
int close_bootinfo_db(void);
int bootinfo_init(void);
int bootinfo(struct in_addr ipaddr,
struct boot_info *info, void *opaque);
int query_bootinfo_db(struct in_addr ipaddr, int version,
struct boot_what *info);
int elabinelab_hackcheck(struct sockaddr_in *target);
......@@ -16,6 +20,6 @@ extern int debug;
#ifdef EVENTSYS
int bievent_init(void);
int bievent_shutdown(void);
int bievent_send(struct in_addr ipaddr, char *event);
int bievent_send(struct in_addr ipaddr, void *opaque, char *event);
#endif
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2004, 2006 University of Utah and the Flux Group.
* Copyright (c) 2000-2004, 2006, 2007 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -134,13 +134,15 @@ main(int argc, char **argv)
if (reboot) {
boot_whatp->type = BIBOOTWHAT_TYPE_REBOOT;
#ifdef EVENTSYS
bievent_send(target.sin_addr, TBDB_NODESTATE_SHUTDOWN);
bievent_send(target.sin_addr, (void *) NULL,
TBDB_NODESTATE_SHUTDOWN);
#endif
}
else if (query) {
boot_whatp->type = BIBOOTWHAT_TYPE_AUTO;
#ifdef EVENTSYS
bievent_send(target.sin_addr, TBDB_NODESTATE_PXEWAKEUP);
bievent_send(target.sin_addr, (void *) NULL,
TBDB_NODESTATE_PXEWAKEUP);
#endif
}
else {
......@@ -151,17 +153,20 @@ main(int argc, char **argv)
fatal("Could not send bootinfo packet!");
}
#ifdef EVENTSYS
bievent_send(target.sin_addr, TBDB_NODESTATE_PXEBOOTING);
bievent_send(target.sin_addr, (void *) NULL,
TBDB_NODESTATE_PXEBOOTING);
switch (boot_whatp->type) {
case BIBOOTWHAT_TYPE_PART:
case BIBOOTWHAT_TYPE_SYSID:
case BIBOOTWHAT_TYPE_MB:
case BIBOOTWHAT_TYPE_MFS:
bievent_send(target.sin_addr, TBDB_NODESTATE_BOOTING);
bievent_send(target.sin_addr, (void *) NULL,
TBDB_NODESTATE_BOOTING);
break;
case BIBOOTWHAT_TYPE_WAIT:
bievent_send(target.sin_addr, TBDB_NODESTATE_PXEWAIT);
bievent_send(target.sin_addr, (void *) NULL,
TBDB_NODESTATE_PXEWAIT);
break;
default:
error("%s: invalid boot directive: %d\n",
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2006 University of Utah and the Flux Group.
* Copyright (c) 2000-2007 University of Utah and the Flux Group.
* All rights reserved.
*
* boot/bootwhat.h from the OSKit.
......@@ -26,7 +26,7 @@
#define MAX_BOOT_PATH 256
#define MAX_BOOT_CMDLINE ((MAX_BOOT_DATA - MAX_BOOT_PATH) - 32)
typedef struct {
typedef struct boot_info {
short version;
short opcode;
int status;
......
......@@ -69,7 +69,7 @@ bievent_shutdown(void)
* if not already done. Returns 0 on sucess, 1 on failure.
*/
int
bievent_send(struct in_addr ipaddr, char *event)
bievent_send(struct in_addr ipaddr, void *opaque, char *event)
{
event_notification_t notification;
char nodeid[TBDB_FLEN_NODEID];
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2004, 2006, 2007 University of Utah and the Flux Group.
* All rights reserved.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <paths.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <db.h>
#include <fcntl.h>
#include <time.h>
#include "log.h"
#include "tbdefs.h"
#include "bootwhat.h"
#include "bootinfo.h"
/*
* Minimum number of seconds that must pass before we send another
* event for a node. This is to decrease the number of spurious events
* we get from nodes when bootinfo packets are lost.
*/
#define MINEVENTTIME 10
static void log_bootwhat(struct in_addr ipaddr, boot_what_t *bootinfo);
static void onhup(int sig);
static char *progname;
int debug = 0;
void
usage()
{
fprintf(stderr,
"Usage: %s <options> [-d]\n"
"options:\n"
"-d - Turn on debugging\n"
"-p port - Specify port number to listen on\n",
progname);
exit(-1);
}
int
main(int argc, char **argv)
{
int sock, length, mlen, err, c;
struct sockaddr_in name, client;
boot_info_t boot_info;
int port = BOOTWHAT_DSTPORT;
char buf[BUFSIZ];
FILE *fp;
extern char build_info[];
progname = argv[0];
while ((c = getopt(argc, argv, "p:dhv")) != -1) {
switch (c) {
case 'd':
debug++;
break;
case 'p':
port = atoi(optarg);
break;
case 'v':
fprintf(stderr, "%s\n", build_info);
exit(0);
break;
case 'h':
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc)
usage();
if (debug)
loginit(0, 0);
else {
/* Become a daemon */
daemon(0, 0);
loginit(1, "bootinfo");
}
info("%s\n", build_info);
/*
* Write out a pidfile.
*/
sprintf(buf, "%s/bootinfo.pid", _PATH_VARRUN);
fp = fopen(buf, "w");
if (fp != NULL) {
fprintf(fp, "%d\n", getpid());
(void) fclose(fp);
}
err = bootinfo_init();
if (err) {
error("could not initialize bootinfo");
exit(1);
}
/* Create socket from which to read. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
errorc("opening datagram socket");
exit(1);
}
/* Create name. */
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = htons((u_short) port);
if (bind(sock, (struct sockaddr *) &name, sizeof(name))) {
errorc("binding datagram socket");
exit(1);
}
/* Find assigned port value and print it out. */
length = sizeof(name);
if (getsockname(sock, (struct sockaddr *) &name, &length)) {
errorc("getting socket name");
exit(1);
}
info("listening on port %d\n", ntohs(name.sin_port));
signal(SIGHUP, onhup);
while (1) {
if ((mlen = recvfrom(sock, &boot_info, sizeof(boot_info),
0, (struct sockaddr *)&client, &length))
< 0) {
errorc("receiving datagram packet");
exit(1);
}
err = bootinfo(client.sin_addr, &boot_info, (void *) NULL);
if (err < 0)
continue;
if (boot_info.status == BISTAT_SUCCESS)
log_bootwhat(client.sin_addr,
(boot_what_t *) &boot_info.data);
boot_info.opcode = BIOPCODE_BOOTWHAT_REPLY;
client.sin_family = AF_INET;
client.sin_port = htons(BOOTWHAT_SRCPORT);
if (sendto(sock, (char *)&boot_info, sizeof(boot_info), 0,
(struct sockaddr *)&client, sizeof(client)) < 0)
errorc("sendto");
}
close(sock);
close_bootinfo_db();
info("daemon terminating\n");
exit(0);
}
static void
onhup(int sig)
{
int err;
info("re-initializing configuration database\n");
close_bootinfo_db();
err = open_bootinfo_db();
if (err) {
error("Could not reopen database");
exit(1);
}
}
static void
log_bootwhat(struct in_addr ipaddr, boot_what_t *bootinfo)
{
char ipstr[32];
strncpy(ipstr, inet_ntoa(ipaddr), sizeof ipstr);
switch (bootinfo->type) {
case BIBOOTWHAT_TYPE_PART:
info("%s: REPLY: boot from partition %d\n",
ipstr, bootinfo->what.partition);
break;
case BIBOOTWHAT_TYPE_SYSID:
info("%s: REPLY: boot from partition with sysid %d\n",
ipstr, bootinfo->what.sysid);
break;
case BIBOOTWHAT_TYPE_MB:
info("%s: REPLY: boot multiboot image %s:%s\n",
ipstr, inet_ntoa(bootinfo->what.mb.tftp_ip),
bootinfo->what.mb.filename);
break;
case BIBOOTWHAT_TYPE_WAIT:
info("%s: REPLY: wait mode\n", ipstr);
break;
case BIBOOTWHAT_TYPE_MFS:
info("%s: REPLY: boot from mfs %s\n", ipstr, bootinfo->what.mfs);
break;
case BIBOOTWHAT_TYPE_REBOOT:
info("%s: REPLY: reboot (alternate PXE boot)\n", ipstr);
break;
}
if (bootinfo->cmdline[0]) {
info("%s: REPLY: command line: %s\n", ipstr, bootinfo->cmdline);
}
}
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