[Beowulf] KVM to a compute node

Mark Hahn hahn at physics.mcmaster.ca
Thu Jun 3 08:36:28 PDT 2004


> These USB->serial boxes work fine with linux (ours uses the ftdi_sio kernel

sounds a bit fragile to me.  if I really wanted serial on a bunch of boxes,
I'd be most tempted to simply have box N plugged into box N+1.  and use a 
script to do the appropriate connection, of course.

> We use kermit to log on the local console to each machine, and have aliases
> for the combination of ssh (to the server) and kermit on the right tty. 

eeew, why do people still use grossness like kermit for such a simple task?
here's a bit of serial-port plumbing I wrote over a decade ago (gulp!)
that works on any unix machine.  feel free to hack it to your port
names/speeds/etc, remove the silly logging, etc.

/* written by Mark Hahn <hahn at mcmaster.ca> */
#include <unistd.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <stdarg.h>

double gtod() {
    struct timeval tv;
    gettimeofday(&tv,0);
    return tv.tv_sec + 1e-6 * tv.tv_usec;
}
double startTime;
double ts() { 
    if (startTime == 0.0)
	startTime = gtod();
    return gtod() - startTime;
}

FILE *fpLog = 0;
void log(char *format,...) {
    va_list ap;
    va_start(ap,format);

    if (!fpLog)
	fpLog = fopen("debug.log","a");
    fprintf(fpLog,"%2.8f: ",ts());
    vfprintf(fpLog,format,ap);
    va_end(ap);
    fflush(fpLog);
}
void fatal(char *format,...) {
    static FILE *fpLog = 0;
    va_list ap;
    va_start(ap,format);

    if (!fpLog)
	fpLog = fopen("debug.log","a");
    fprintf(fpLog,"%2.8f: ",ts());
    vfprintf(fpLog,format,ap);
    va_end(ap);
    fclose(fpLog);
    exit(0);
}

int 
main() {
    struct termios t, tOrg;
    int fdSer = open("/dev/tty01", O_RDWR);

    log("starting...\n");

    if (fdSer == -1) {
	perror("open of serial device failed");
	return 1;
    }
    log("opened...\n");

    t.c_iflag = IGNBRK | INPCK;
    t.c_oflag = 0;
    t.c_cflag = CS8 | CREAD | CLOCAL | CSTOPB;
    t.c_lflag = 0;
    cfsetispeed(&t,B19200);
    cfsetospeed(&t,B19200);
    tcsetattr(fdSer,TCSANOW,&t);

    log("serial attr set...\n");

    tcgetattr(0,&t);
    tOrg = t;
    t.c_iflag = 0;
    t.c_lflag = 0;
    t.c_cc[VTIME] = 1;
    t.c_cc[VMIN] = 1;
    tcsetattr(0,TCSANOW,&t);

    log("console attr set...\n");
    
    while (1) {
#define bufSize 4096
	unsigned char buf[bufSize+1];
	struct timeval timeout;
	fd_set readset;

	timeout.tv_sec = 10;
	timeout.tv_usec = 0;

	FD_ZERO(&readset);
	FD_SET(0,&readset);
	FD_SET(fdSer,&readset);

	log("about to select...\n");

	if (select(fdSer+1,&readset,0,0,&timeout) == -1)
	    continue;

	if (FD_ISSET(0,&readset)) {
	    log("stdin readable...\n");

	    int c = read(0,buf,bufSize);
	    if (c > 0) {
		buf[c] = 0;	
	        log("got %d bytes from stdin: '%s'...\n",c,buf);

		static unsigned char prev = 0;
	        log("prev is %02x\n\n",prev);
		if (prev == 0x1d && buf[0] == 'q')
		    break;
		prev = buf[0];
	        log("writing to serial...\n");
		write(fdSer,buf,c);
	        log("serial write done...\n");
	    }
	}
	if (FD_ISSET(fdSer,&readset)) {
	    log("serial readable...\n");
	    int c = read(fdSer,buf,bufSize);
	    if (c > 0) {
		buf[c] = 0;	
	        log("got %d bytes from serial: '%s'...\n",c,buf);
		write(1,buf,c);
	        log("stdout write done...\n");
	    }
	}
    }
    tcsetattr(0,TCSANOW,&tOrg);
    return 0;
}




More information about the Beowulf mailing list