xen/serial-split.patch
Charles Arnold 80e28a00ec - Update to Xen 4.2.0 FCS c/s 25844
- unmodified_drivers: handle IRQF_SAMPLE_RANDOM, it was removed
  in 3.6-rc1

- bnc#778105 - first XEN-PV VM fails to spawn
  xend: Increase wait time for disk to appear in host bootloader
  Modified existing xen-domUloader.diff

- Disable the snapshot patches. Snapshot only supported the qcow2
  image format which was poorly implemented qemu 0.10.2. Snapshot
  support may be restored in the future when the newer upstream
  qemu is used by Xen.

- bnc#776995 - attaching scsi control luns with pvscsi
  - xend/pvscsi: fix passing of SCSI control LUNs
  xen-bug776995-pvscsi-no-devname.patch
  - xend/pvscsi: fix usage of persistant device names for SCSI devices
  xen-bug776995-pvscsi-persistent-names.patch
  - xend/pvscsi: update sysfs parser for Linux 3.0
  xen-bug776995-pvscsi-sysfs-parser.patch

- Update to Xen 4.2.0 RC3+ c/s 25779 

- Update to Xen 4.2.0 RC2+ c/s 25765

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=199
2012-09-17 15:49:23 +00:00

453 lines
12 KiB
Diff

Index: xen-4.2.0-testing/tools/misc/serial-split/Makefile
===================================================================
--- /dev/null
+++ xen-4.2.0-testing/tools/misc/serial-split/Makefile
@@ -0,0 +1,20 @@
+CC ?= gcc
+CFLAGS ?= -Wall -Os
+CFILES = $(wildcard *.c)
+OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
+TARGET = serial-split
+
+all: $(TARGET)
+
+install: all
+ install -d $(DESTDIR)/usr/bin
+ install -s $(TARGET) $(DESTDIR)/usr/bin/
+
+clean:
+ rm *.o $(TARGET) *~
+
+$(TARGET): $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $^
+
+%.o: %.c Makefile
+ $(CC) $(CFLAGS) -c -o $@ $<
Index: xen-4.2.0-testing/tools/misc/serial-split/serial-split.c
===================================================================
--- /dev/null
+++ xen-4.2.0-testing/tools/misc/serial-split/serial-split.c
@@ -0,0 +1,422 @@
+/*
+ * serial-split.c
+ * pdb / console splitter
+ *
+ * Copyright 2005 Charles Coffing <ccoffing@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Typical setup:
+ *
+ * Development box Xen box
+ * ...-----+ +-----...
+ * +---------+ | |
+ * | gdb | | |
+ * | |\ high | |
+ * +---------+ \ | |
+ * \+-----------+ | serial | +------------------+
+ * | splitter |------------| Xen |
+ * /+-----------+ | | | - pdb (com1H)|
+ * +---------+ / | | | - printk (com1) |
+ * | console |/ low | | +------------------+
+ * | viewer | | |
+ * +---------+ | |
+ * ...-----+ +-----...
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+
+const unsigned int DefaultLowPort = 12010;
+const unsigned int DefaultBaud = 115200;
+const char DefaultSerialDevice[] = "/dev/ttyS0";
+
+#define DEBUG 0
+#define MAX(a,b) ((a)<(b)?(b):(a))
+
+
+static int cook_baud(int baud)
+{
+ int cooked_baud = 0;
+ switch (baud)
+ {
+ case 50: cooked_baud = B50; break;
+ case 75: cooked_baud = B75; break;
+ case 110: cooked_baud = B110; break;
+ case 134: cooked_baud = B134; break;
+ case 150: cooked_baud = B150; break;
+ case 200: cooked_baud = B200; break;
+ case 300: cooked_baud = B300; break;
+ case 600: cooked_baud = B600; break;
+ case 1200: cooked_baud = B1200; break;
+ case 1800: cooked_baud = B1800; break;
+ case 2400: cooked_baud = B2400; break;
+ case 4800: cooked_baud = B4800; break;
+ case 9600: cooked_baud = B9600; break;
+ case 19200: cooked_baud = B19200; break;
+ case 38400: cooked_baud = B38400; break;
+ case 57600: cooked_baud = B57600; break;
+ case 115200: cooked_baud = B115200; break;
+ }
+ return cooked_baud;
+}
+
+
+static int start_listener(unsigned short port)
+{
+ int fd;
+ struct sockaddr_in sin;
+ int on = 1;
+
+ if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror("socket");
+ goto out1;
+ }
+
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (port);
+ sin.sin_addr.s_addr = INADDR_ANY;
+ if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+ {
+ perror("bind");
+ goto out2;
+ }
+
+ if (listen(fd, 1) < 0)
+ {
+ perror("listen");
+ goto out2;
+ }
+
+ fprintf(stderr, "Listening on port %d\n", port);
+
+ return fd;
+
+out2:
+ close(fd);
+out1:
+ return -1;
+}
+
+
+static int accept_conn(int fd)
+{
+ int on = 1;
+ int new_fd;
+ struct sockaddr_in from;
+ socklen_t fromlen = sizeof(from);
+
+ new_fd = accept(fd, (struct sockaddr *)&from, &fromlen);
+ if (new_fd < 0)
+ perror("accept");
+ ioctl(new_fd, FIONBIO, &on);
+
+ fprintf(stderr, "Accepted connection on %d\n", new_fd);
+
+ return new_fd;
+}
+
+
+static void close_conn(int * fd)
+{
+ shutdown(*fd, 2);
+ close(*fd);
+ *fd = -1;
+}
+
+
+static int receive_data(int * fd, char * buf, ssize_t max_bytes, int * poll)
+{
+ ssize_t bytes;
+ if ((bytes = read(*fd, buf, max_bytes)) < 0)
+ {
+ perror("read");
+ *poll = 1;
+ return 0;
+ }
+ else if (bytes == 0)
+ {
+ close_conn(fd);
+ *poll = 0;
+ return 0;
+ }
+ else
+ {
+ if (bytes == max_bytes)
+ *poll = 1;
+ else
+ *poll = 0;
+#if DEBUG
+ {
+ ssize_t i;
+ fprintf(stderr, "Received %d bytes on %d:\n", bytes, *fd);
+ for (i = 0; i < bytes; ++ i)
+ {
+ if ((i & 0xf) == 0)
+ printf(" ");
+ printf("%02x", buf[i] & 0xff);
+ if (((i+1) & 0xf) == 0 || i + 1 == bytes)
+ printf("\n");
+ else
+ printf(" ");
+ }
+ }
+#endif
+ return bytes;
+ }
+}
+
+
+static void set_high_bit(char * buf, size_t bytes)
+{
+ size_t i;
+ for(i = 0; i < bytes; ++ i)
+ buf[i] |= 0x80;
+}
+
+
+static void clear_high_bit(char * buf, size_t bytes)
+{
+ size_t i;
+ for(i = 0; i < bytes; ++ i)
+ buf[i] &= 0x7f;
+}
+
+
+static int open_serial(char const * serial_dev, int baud)
+{
+ struct termios newsertio;
+ int serial_fd;
+ memset(&newsertio, 0, sizeof(newsertio));
+
+ if ((serial_fd = open(serial_dev, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
+ {
+ perror(serial_dev);
+ return -1;
+ }
+
+ newsertio.c_cflag = baud | CS8 | CLOCAL | CREAD;
+ newsertio.c_iflag = IGNBRK | IGNPAR; /* raw input */
+ newsertio.c_oflag = 0; /* raw output */
+ newsertio.c_lflag = 0; /* no echo, no signals */
+ newsertio.c_cc[VMIN] = 1;
+ newsertio.c_cc[VTIME] = 0;
+ tcflush(serial_fd, TCIFLUSH);
+ tcsetattr(serial_fd, TCSANOW, &newsertio);
+
+ fprintf(stderr, "Listening on %s\n", serial_dev);
+
+ return serial_fd;
+}
+
+
+static void main_loop(int serial_fd, int low_listener, int high_listener)
+{
+ fd_set rdfds;
+ int low_poll = 0, high_poll = 0, serial_poll = 0;
+ int low_fd = -1, high_fd = -1;
+
+ while(1)
+ {
+ char buf[1024];
+ ssize_t bytes;
+ int max;
+
+ FD_ZERO(&rdfds);
+ FD_SET(low_fd < 0 ? low_listener : low_fd, &rdfds);
+ FD_SET(high_fd < 0 ? high_listener : high_fd, &rdfds);
+ FD_SET(serial_fd, &rdfds);
+
+ max = MAX(low_fd, low_listener);
+ max = MAX(max, high_fd);
+ max = MAX(max, high_listener);
+ max = MAX(max, serial_fd);
+
+ if (select(max + 1, &rdfds, NULL, NULL, NULL) < 0)
+ {
+ perror("select");
+ continue;
+ }
+
+ if (FD_ISSET(low_listener, &rdfds))
+ {
+ assert(low_fd < 0);
+ low_fd = accept_conn(low_listener);
+ }
+
+ if (FD_ISSET(high_listener, &rdfds))
+ {
+ assert(high_fd < 0);
+ high_fd = accept_conn(high_listener);
+ }
+
+ if (low_poll || (low_fd >= 0 && FD_ISSET(low_fd, &rdfds)))
+ {
+ if ((bytes = receive_data(&low_fd, &buf[0], sizeof(buf),
+ &low_poll)) > 0)
+ {
+ clear_high_bit(&buf[0], bytes);
+ if (write(serial_fd, &buf[0], bytes) < 0)
+ perror("write");
+ }
+ }
+
+ if (high_poll || (high_fd >= 0 && FD_ISSET(high_fd, &rdfds)))
+ {
+ if ((bytes = receive_data(&high_fd, &buf[0], sizeof(buf),
+ &high_poll)) > 0)
+ {
+ set_high_bit(&buf[0], bytes);
+ if (write(serial_fd, &buf[0], bytes) < 0)
+ perror("write");
+ }
+ }
+
+ if (serial_poll || FD_ISSET(serial_fd, &rdfds))
+ {
+ if ((bytes = receive_data(&serial_fd, &buf[0], sizeof(buf),
+ &serial_poll)) > 0)
+ {
+ ssize_t i;
+ for (i = 0; i < bytes; ++ i)
+ {
+ if (buf[i] & 0x80)
+ {
+ if (high_fd >= 0)
+ {
+ buf[i] &= 0x7f;
+ if ((write(high_fd, &buf[i], 1)) < 0)
+ {
+ perror("write");
+ close_conn(&high_fd);
+ high_poll = 0;
+ }
+ }
+ }
+ else
+ {
+ if (low_fd >= 0)
+ {
+ if ((write(low_fd, &buf[i], 1)) < 0)
+ {
+ perror("write");
+ close_conn(&low_fd);
+ low_poll = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+static void usage()
+{
+ printf(
+"Description:\n"
+" Splits the serial port between two TCP ports. Bytes read from the\n"
+" serial port will be delivered to one of the two TCP ports (high or\n"
+" low) depending on whether the high bit is set. Bytes written to the\n"
+" TCP ports will be forwarded to the serial port; the high bit will be\n"
+" set or cleared to denote the source.\n"
+"Usage:\n"
+" serial-split [-d<serial-device>] [-b<baud>]\n"
+" [-l<low-port>] [-h<high-port>]\n"
+"Parameters:\n"
+" -d<serial-device> Defaults to %s.\n"
+" -b<baud> Baud rate of the serial port. Defaults to %d.\n"
+" Also assumes 8N1.\n"
+" -l<low-port> Low TCP port. Defaults to %d, or one less than\n"
+" the high port.\n"
+" -h<high-port> High TCP port. Defaults to %d, or one more than\n"
+" the low port.\n",
+DefaultSerialDevice, DefaultBaud, DefaultLowPort, DefaultLowPort + 1);
+
+ exit(1);
+}
+
+
+int main(int argc, char **argv)
+{
+ int cooked_baud = cook_baud(DefaultBaud);
+ char const * serial_dev = DefaultSerialDevice;
+ int low_port = -1, high_port = -1;
+ int serial_fd, low_listener, high_listener;
+
+ while ( --argc != 0 )
+ {
+ char *p = argv[argc];
+ if ( *(p++) != '-' )
+ usage();
+ switch (*(p++))
+ {
+ case 'b':
+ if ( (cooked_baud = cook_baud(atoi(p))) == 0 )
+ {
+ fprintf(stderr, "Bad baud rate\n");
+ exit(1);
+ }
+ break;
+ case 'd':
+ serial_dev = p;
+ break;
+ case 'l':
+ if ((low_port = atoi(p)) <= 0)
+ usage();
+ break;
+ case 'h':
+ if ((high_port = atoi(p)) <= 0)
+ usage();
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (low_port == -1 && high_port == -1)
+ low_port = DefaultLowPort;
+ if (low_port == -1)
+ low_port = high_port - 1;
+ if (high_port == -1)
+ high_port = low_port + 1;
+
+ if ((serial_fd = open_serial(serial_dev, cooked_baud)) < 0 ||
+ (low_listener = start_listener(low_port)) < 0 ||
+ (high_listener = start_listener(high_port)) < 0)
+ exit(1);
+
+ main_loop(serial_fd, low_listener, high_listener);
+
+ return 0;
+}
+