Page MenuHomeFreeBSD

D43514.id133899.diff
No OneTemporary

D43514.id133899.diff

diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -639,7 +639,10 @@
continue;
/* We want to load PT_LOAD segments only.. */
- if (phdr[i].p_type != PT_LOAD)
+ /* If it is kernel, we load the note to make debugger match with
+ * coredump */
+ if (phdr[i].p_type != PT_LOAD &&
+ !(ef->kernel && phdr[i].p_type == PT_NOTE))
continue;
if (module_verbose >= MODULE_VERBOSE_FULL) {
diff --git a/usr.sbin/bhyve/uart_emul.c b/usr.sbin/bhyve/uart_emul.c
--- a/usr.sbin/bhyve/uart_emul.c
+++ b/usr.sbin/bhyve/uart_emul.c
@@ -28,7 +28,10 @@
*/
#include <sys/types.h>
+#include <sys/socket.h>
#include <dev/ic/ns16550.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#ifndef WITHOUT_CAPSICUM
#include <sys/capsicum.h>
#include <capsicum_helpers.h>
@@ -104,6 +107,7 @@
struct ttyfd {
bool opened;
+ bool connect_based;
int rfd; /* fd for reading */
int wfd; /* fd for writing, may be == rfd */
};
@@ -134,6 +138,7 @@
};
static void uart_drain(int fd, enum ev_type ev, void *arg);
+static void uart_tcp_disconnect(struct uart_softc *sc);
static void
ttyclose(void)
@@ -160,21 +165,23 @@
}
static int
-ttyread(struct ttyfd *tf)
+ttyread(struct ttyfd *tf, int *ret)
{
unsigned char rb;
+ int sz;
- if (read(tf->rfd, &rb, 1) == 1)
- return (rb);
- else
- return (-1);
+ sz = read(tf->rfd, &rb, 1);
+ if (ret != NULL)
+ *ret = rb;
+
+ return sz;
}
-static void
+static int
ttywrite(struct ttyfd *tf, unsigned char wb)
{
- (void)write(tf->wfd, &wb, 1);
+ return write(tf->wfd, &wb, 1);
}
static void
@@ -374,7 +381,7 @@
uart_drain(int fd, enum ev_type ev, void *arg)
{
struct uart_softc *sc;
- int ch;
+ int ch, sz;
sc = arg;
@@ -389,15 +396,26 @@
pthread_mutex_lock(&sc->mtx);
if ((sc->mcr & MCR_LOOPBACK) != 0) {
- (void) ttyread(&sc->tty);
+ if (ttyread(&sc->tty, NULL) == 0 && sc->tty.connect_based)
+ uart_tcp_disconnect(sc);
} else {
- while (rxfifo_available(sc) &&
- ((ch = ttyread(&sc->tty)) != -1)) {
- rxfifo_putchar(sc, ch);
+ while (rxfifo_available(sc)) {
+ sz = ttyread(&sc->tty, &ch);
+
+ if (sz <= 0) {
+ if (sz == 0 && sc->tty.connect_based) {
+ uart_tcp_disconnect(sc);
+ goto clear;
+ }
+ break;
+ } else {
+ rxfifo_putchar(sc, ch);
+ }
}
uart_toggle_intr(sc);
}
+clear:
pthread_mutex_unlock(&sc->mtx);
}
@@ -430,7 +448,9 @@
if (rxfifo_putchar(sc, value) != 0)
sc->lsr |= LSR_OE;
} else if (sc->tty.opened) {
- ttywrite(&sc->tty, value);
+ if (ttywrite(&sc->tty, value) == -1 &&
+ sc->tty.connect_based)
+ uart_tcp_disconnect(sc);
} /* else drop on floor */
sc->thre_int_pending = true;
break;
@@ -705,6 +725,104 @@
return (0);
}
+static void
+uart_tcp_listener(int fd, enum ev_type type __unused, void *arg)
+{
+ const static char tcp_error_msg[] = "Socket already connected\n";
+ struct uart_softc *sc = (struct uart_softc *)arg;
+ struct sockaddr_in dst_addr;
+ socklen_t len = sizeof(dst_addr);
+ int conn_fd;
+
+ conn_fd = accept(fd, (struct sockaddr *)&dst_addr, &len);
+ if (conn_fd == -1) {
+ errx(EX_OSERR, "Unable to accept the connection");
+ return;
+ }
+
+ if (fcntl(conn_fd, F_SETFL, O_NONBLOCK) != 0) {
+ errx(EX_OSERR, "Unable to set nonblocking mode to connection");
+ return;
+ }
+
+ pthread_mutex_lock(&sc->mtx);
+
+ if (sc->tty.opened) {
+ send(conn_fd, tcp_error_msg, sizeof(tcp_error_msg), 0);
+ close(conn_fd);
+ } else {
+ sc->tty.rfd = sc->tty.wfd = conn_fd;
+ sc->tty.opened = true;
+ uart_opentty(sc);
+ }
+
+ pthread_mutex_unlock(&sc->mtx);
+}
+
+static void
+uart_tcp_disconnect(struct uart_softc *sc)
+{
+ mevent_delete_close(sc->mev);
+ sc->mev = NULL;
+
+ sc->tty.opened = false;
+ sc->tty.rfd = sc->tty.wfd = -1;
+}
+
+// Listen to address and add to kqueue.
+// If connected (e.g. tcp_handler is triggered), we replace the handler to the
+// connected handler
+static int
+uart_tcp_backend(struct uart_softc *sc, const char *path)
+{
+#ifndef WITHOUT_CAPSICUM
+ cap_rights_t rights;
+ cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ };
+#endif
+ int bind_fd;
+ struct sockaddr_in src_addr;
+ char addr[256];
+ int port;
+
+ sscanf(path, "tcp:%255[^:]:%d", addr, &port);
+
+ bind_fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (bind_fd < 0)
+ return (-1);
+
+ memset(&src_addr, 0, sizeof(src_addr));
+ src_addr.sin_family = AF_INET;
+ src_addr.sin_port = htons(port);
+ inet_aton(addr, &src_addr.sin_addr);
+
+ if (bind(bind_fd, (struct sockaddr *)&src_addr,
+ (socklen_t)sizeof(src_addr)) == -1)
+ errx(EX_OSERR, "Unable to bind to address %s:%d", addr, port);
+
+ if (fcntl(bind_fd, F_SETFL, O_NONBLOCK) == -1)
+ return (-1);
+
+ if (listen(bind_fd, 1) == -1)
+ errx(EX_OSERR, "Unable to listen to address %s:%d", addr, port);
+
+ if (mevent_add(bind_fd, EVF_READ, uart_tcp_listener, (void *)sc) ==
+ NULL)
+ return (-1);
+
+#ifndef WITHOUT_CAPSICUM
+ cap_rights_init(&rights, CAP_EVENT, CAP_ACCEPT, CAP_RECV, CAP_SEND,
+ CAP_FCNTL, CAP_IOCTL);
+ if (caph_rights_limit(bind_fd, &rights) == -1)
+ errx(EX_OSERR, "Unable to apply rights for sandbox");
+ if (caph_ioctls_limit(bind_fd, cmds, nitems(cmds)) == -1)
+ errx(EX_OSERR, "Unable to apply ioctls for sandbox");
+ if (caph_fcntls_limit(bind_fd, CAP_FCNTL_SETFL) == -1)
+ errx(EX_OSERR, "Unable to apply fcntls for sandbox");
+#endif
+
+ return (0);
+}
+
int
uart_set_backend(struct uart_softc *sc, const char *device)
{
@@ -715,9 +833,12 @@
if (strcmp("stdio", device) == 0)
retval = uart_stdio_backend(sc);
- else
+ else if (strncmp("tcp", device, 3) == 0) {
+ retval = uart_tcp_backend(sc, device);
+ sc->tty.connect_based = true;
+ } else
retval = uart_tty_backend(sc, device);
- if (retval == 0)
+ if (retval == 0 && !sc->tty.connect_based)
uart_opentty(sc);
return (retval);

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 19, 1:55 AM (8 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23904564
Default Alt Text
D43514.id133899.diff (5 KB)

Event Timeline