All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 039a86c8 authored by Leigh B. Stoller's avatar Leigh B. 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];