mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-27 12:38:11 +00:00
tap-vsockd: add basic logging support
By default we write to syslog. If the `--debug` argument is provided then we also write to stderr. Signed-off-by: David Scott <dave.scott@docker.com>
This commit is contained in:
parent
4f4c807245
commit
4ffd1742dd
@ -5,6 +5,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
@ -20,11 +21,11 @@ int really_read(int fd, uint8_t *buffer, size_t total){
|
|||||||
while (remaining > 0){
|
while (remaining > 0){
|
||||||
n = read(fd, buffer, remaining);
|
n = read(fd, buffer, remaining);
|
||||||
if (n == 0){
|
if (n == 0){
|
||||||
fprintf(stderr, "EOF reading from socket: closing\n");
|
syslog(LOG_CRIT, "EOF reading from socket: closing\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (n < 0){
|
if (n < 0){
|
||||||
perror("Failure reading from socket: closing");
|
syslog(LOG_CRIT, "Failure reading from socket: closing: %s", strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
remaining -= (size_t)n;
|
remaining -= (size_t)n;
|
||||||
@ -43,11 +44,11 @@ int really_write(int fd, uint8_t *buffer, size_t total){
|
|||||||
while (remaining > 0){
|
while (remaining > 0){
|
||||||
n = write(fd, buffer, remaining);
|
n = write(fd, buffer, remaining);
|
||||||
if (n == 0){
|
if (n == 0){
|
||||||
fprintf(stderr, "EOF writing to socket: closing\n");
|
syslog(LOG_CRIT, "EOF writing to socket: closing");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (n < 0){
|
if (n < 0){
|
||||||
perror("Failure writing to socket: closing\n");
|
syslog(LOG_CRIT, "Failure writing to socket: closing: %s", strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
remaining -= (size_t) n;
|
remaining -= (size_t) n;
|
||||||
@ -85,7 +86,7 @@ char *print_init_message(struct init_message *m) {
|
|||||||
int read_init_message(int fd, struct init_message *ci) {
|
int read_init_message(int fd, struct init_message *ci) {
|
||||||
bzero(ci, sizeof(struct init_message));
|
bzero(ci, sizeof(struct init_message));
|
||||||
if (really_read(fd, (uint8_t*) &ci->hello[0], sizeof(ci->hello)) == -1){
|
if (really_read(fd, (uint8_t*) &ci->hello[0], sizeof(ci->hello)) == -1){
|
||||||
fprintf(stderr, "Failed to read hello from client\n");
|
syslog(LOG_CRIT, "Failed to read hello from client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (memcmp(&ci->hello[0], &expected_hello_old[0], sizeof(expected_hello_old)) == 0) {
|
if (memcmp(&ci->hello[0], &expected_hello_old[0], sizeof(expected_hello_old)) == 0) {
|
||||||
@ -93,15 +94,15 @@ int read_init_message(int fd, struct init_message *ci) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (memcmp(&ci->hello[0], &expected_hello[0], sizeof(expected_hello)) != 0) {
|
if (memcmp(&ci->hello[0], &expected_hello[0], sizeof(expected_hello)) != 0) {
|
||||||
fprintf(stderr, "Failed to read header magic from client\n");
|
syslog(LOG_CRIT, "Failed to read header magic from client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (really_read(fd, (uint8_t*) &ci->version, sizeof(ci->version)) == -1){
|
if (really_read(fd, (uint8_t*) &ci->version, sizeof(ci->version)) == -1){
|
||||||
fprintf(stderr, "Failed to read header version from client\n");
|
syslog(LOG_CRIT, "Failed to read header version from client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (really_read(fd, (uint8_t*) &ci->commit[0], sizeof(ci->commit)) == -1){
|
if (really_read(fd, (uint8_t*) &ci->commit[0], sizeof(ci->commit)) == -1){
|
||||||
fprintf(stderr, "Failed to read header hash from client\n");
|
syslog(LOG_CRIT, "Failed to read header hash from client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -109,16 +110,16 @@ int read_init_message(int fd, struct init_message *ci) {
|
|||||||
|
|
||||||
int write_init_message(int fd, struct init_message *ci) {
|
int write_init_message(int fd, struct init_message *ci) {
|
||||||
if (really_write(fd, (uint8_t*) &ci->hello[0], sizeof(ci->hello)) == -1){
|
if (really_write(fd, (uint8_t*) &ci->hello[0], sizeof(ci->hello)) == -1){
|
||||||
fprintf(stderr, "Failed to write hello to client\n");
|
syslog(LOG_CRIT, "Failed to write hello to client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ci->version > 0) {
|
if (ci->version > 0) {
|
||||||
if (really_write(fd, (uint8_t*) &ci->version, sizeof(ci->version)) == -1){
|
if (really_write(fd, (uint8_t*) &ci->version, sizeof(ci->version)) == -1){
|
||||||
fprintf(stderr, "Failed to write version to client\n");
|
syslog(LOG_CRIT, "Failed to write version to client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (really_write(fd, (uint8_t*) &ci->commit[0], sizeof(ci->commit)) == -1){
|
if (really_write(fd, (uint8_t*) &ci->commit[0], sizeof(ci->commit)) == -1){
|
||||||
fprintf(stderr, "Failed to write header hash to client\n");
|
syslog(LOG_CRIT, "Failed to write header hash to client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +129,7 @@ int write_init_message(int fd, struct init_message *ci) {
|
|||||||
int read_vif_info(int fd, struct vif_info *vif) {
|
int read_vif_info(int fd, struct vif_info *vif) {
|
||||||
uint8_t buffer[10];
|
uint8_t buffer[10];
|
||||||
if (really_read(fd, &buffer[0], sizeof(buffer)) == -1){
|
if (really_read(fd, &buffer[0], sizeof(buffer)) == -1){
|
||||||
fprintf(stderr, "Failed to read vif info from client\n");
|
syslog(LOG_CRIT, "Failed to read vif info from client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
vif->mtu = (size_t) (buffer[0] | (buffer[1] << 8));
|
vif->mtu = (size_t) (buffer[0] | (buffer[1] << 8));
|
||||||
@ -146,7 +147,7 @@ int write_vif_info(int fd, struct vif_info *vif) {
|
|||||||
buffer[3] = (uint8_t) ((vif->max_packet_size >> 8) & 0xff);
|
buffer[3] = (uint8_t) ((vif->max_packet_size >> 8) & 0xff);
|
||||||
memcpy(&buffer[0] + 4, &(vif->mac)[0], 6);
|
memcpy(&buffer[0] + 4, &(vif->mac)[0], 6);
|
||||||
if (really_write(fd, &buffer[0], sizeof(buffer)) == -1){
|
if (really_write(fd, &buffer[0], sizeof(buffer)) == -1){
|
||||||
fprintf(stderr, "Failed to write vif into to client\n");
|
syslog(LOG_CRIT, "Failed to write vif into to client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -155,7 +156,7 @@ int write_vif_info(int fd, struct vif_info *vif) {
|
|||||||
int write_command(int fd, enum command *c) {
|
int write_command(int fd, enum command *c) {
|
||||||
uint8_t command = *c;
|
uint8_t command = *c;
|
||||||
if (really_write(fd, (uint8_t*) &command, sizeof(command)) == -1){
|
if (really_write(fd, (uint8_t*) &command, sizeof(command)) == -1){
|
||||||
fprintf(stderr, "Failed to write command to client\n");
|
syslog(LOG_CRIT, "Failed to write command to client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -163,7 +164,7 @@ int write_command(int fd, enum command *c) {
|
|||||||
|
|
||||||
int write_ethernet_args(int fd, struct ethernet_args *args){
|
int write_ethernet_args(int fd, struct ethernet_args *args){
|
||||||
if (really_write(fd, (uint8_t*) &args->uuid_string[0], 36) == -1){
|
if (really_write(fd, (uint8_t*) &args->uuid_string[0], 36) == -1){
|
||||||
fprintf(stderr, "Failed to write ethernet args to client\n");
|
syslog(LOG_CRIT, "Failed to write ethernet args to client");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <syslog.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
int verbose_flag = 0;
|
int debug_flag = 0;
|
||||||
|
|
||||||
int alloc_tap(const char *dev) {
|
int alloc_tap(const char *dev) {
|
||||||
int fd;
|
int fd;
|
||||||
@ -49,7 +49,7 @@ int alloc_tap(const char *dev) {
|
|||||||
perror("TUNSETPERSIST failed");
|
perror("TUNSETPERSIST failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "successfully created TAP device %s\n", dev);
|
syslog(LOG_INFO, "successfully created TAP device %s", dev);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ int parseguid(const char *s, GUID *g)
|
|||||||
/* Slightly different error handling between Windows and Linux */
|
/* Slightly different error handling between Windows and Linux */
|
||||||
void sockerr(const char *msg)
|
void sockerr(const char *msg)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s Error: %d. %s", msg, errno, strerror(errno));
|
syslog(LOG_CRIT, "%s Error: %d. %s", msg, errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void negotiate(SOCKET fd, struct vif_info *vif)
|
void negotiate(SOCKET fd, struct vif_info *vif)
|
||||||
@ -125,7 +125,7 @@ void negotiate(SOCKET fd, struct vif_info *vif)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
char *txt = print_init_message(&you);
|
char *txt = print_init_message(&you);
|
||||||
fprintf(stderr, "Server reports %s\n", txt);
|
syslog(LOG_INFO, "Server reports %s", txt);
|
||||||
free(txt);
|
free(txt);
|
||||||
enum command command = ethernet;
|
enum command command = ethernet;
|
||||||
if (write_command(fd, &command) == -1) {
|
if (write_command(fd, &command) == -1) {
|
||||||
@ -142,7 +142,7 @@ void negotiate(SOCKET fd, struct vif_info *vif)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
fprintf(stderr, "Failed to negotiate with com.docker.slirp\n");
|
syslog(LOG_CRIT, "Failed to negotiate with com.docker.slirp");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,21 +163,21 @@ static void* vmnet_to_tap(void *arg)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (really_read(connection->fd, &header[0], 2) == -1){
|
if (really_read(connection->fd, &header[0], 2) == -1){
|
||||||
fprintf(stderr, "Failed to read a packet header from host\n");
|
syslog(LOG_CRIT, "Failed to read a packet header from host");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
length = (header[0] & 0xff) | ((header[1] & 0xff) << 8);
|
length = (header[0] & 0xff) | ((header[1] & 0xff) << 8);
|
||||||
if (length > sizeof(buffer)) {
|
if (length > sizeof(buffer)) {
|
||||||
fprintf(stderr, "Received an over-large packet: %d > %ld\n", length, sizeof(buffer));
|
syslog(LOG_CRIT, "Received an over-large packet: %d > %ld", length, sizeof(buffer));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (really_read(connection->fd, &buffer[0], length) == -1){
|
if (really_read(connection->fd, &buffer[0], length) == -1){
|
||||||
fprintf(stderr, "Failed to read packet contents from host\n");
|
syslog(LOG_CRIT, "Failed to read packet contents from host");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
n = write(connection->tapfd, &buffer[0], length);
|
n = write(connection->tapfd, &buffer[0], length);
|
||||||
if (n != length) {
|
if (n != length) {
|
||||||
fprintf(stderr, "Failed to write %d bytes to tap device (wrote %d)\n", length, n);
|
syslog(LOG_CRIT, "Failed to write %d bytes to tap device (wrote %d)", length, n);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,21 +194,21 @@ static void* tap_to_vmnet(void *arg)
|
|||||||
length = read(connection->tapfd, &buffer[0], sizeof(buffer));
|
length = read(connection->tapfd, &buffer[0], sizeof(buffer));
|
||||||
if (length == -1) {
|
if (length == -1) {
|
||||||
if (errno == ENXIO) {
|
if (errno == ENXIO) {
|
||||||
fprintf(stderr, "tap device has gone down\n");
|
syslog(LOG_CRIT, "tap device has gone down");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "ignoring error %d\n", errno);
|
syslog(LOG_WARNING, "ignoring error %d", errno);
|
||||||
/* This is what mirage-net-unix does. Is it a good idea really? */
|
/* This is what mirage-net-unix does. Is it a good idea really? */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
header[0] = (length >> 0) & 0xff;
|
header[0] = (length >> 0) & 0xff;
|
||||||
header[1] = (length >> 8) & 0xff;
|
header[1] = (length >> 8) & 0xff;
|
||||||
if (really_write(connection->fd, &header[0], 2) == -1){
|
if (really_write(connection->fd, &header[0], 2) == -1){
|
||||||
fprintf(stderr, "Failed to write packet header\n");
|
syslog(LOG_CRIT, "Failed to write packet header");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (really_write(connection->fd, &buffer[0], length) == -1) {
|
if (really_write(connection->fd, &buffer[0], length) == -1) {
|
||||||
fprintf(stderr, "Failed to write packet body\n");
|
syslog(LOG_CRIT, "Failed to write packet body");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ static void handle(SOCKET fd, const char *tap)
|
|||||||
|
|
||||||
connection.fd = fd;
|
connection.fd = fd;
|
||||||
negotiate(fd, &connection.vif);
|
negotiate(fd, &connection.vif);
|
||||||
fprintf(stderr, "VMNET VIF has MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
syslog(LOG_INFO, "VMNET VIF has MAC %02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
connection.vif.mac[0], connection.vif.mac[1], connection.vif.mac[2],
|
connection.vif.mac[0], connection.vif.mac[1], connection.vif.mac[2],
|
||||||
connection.vif.mac[3], connection.vif.mac[4], connection.vif.mac[5]
|
connection.vif.mac[3], connection.vif.mac[4], connection.vif.mac[5]
|
||||||
);
|
);
|
||||||
@ -234,19 +234,19 @@ static void handle(SOCKET fd, const char *tap)
|
|||||||
connection.tapfd = tapfd;
|
connection.tapfd = tapfd;
|
||||||
|
|
||||||
if (pthread_create(&v2t, NULL, vmnet_to_tap, &connection) != 0){
|
if (pthread_create(&v2t, NULL, vmnet_to_tap, &connection) != 0){
|
||||||
fprintf(stderr, "Failed to create the vmnet_to_tap thread\n");
|
syslog(LOG_CRIT, "Failed to create the vmnet_to_tap thread");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (pthread_create(&t2v, NULL, tap_to_vmnet, &connection) != 0){
|
if (pthread_create(&t2v, NULL, tap_to_vmnet, &connection) != 0){
|
||||||
fprintf(stderr, "Failed to create the tap_to_vmnet thread\n");
|
syslog(LOG_CRIT, "Failed to create the tap_to_vmnet thread");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (pthread_join(v2t, NULL) != 0){
|
if (pthread_join(v2t, NULL) != 0){
|
||||||
fprintf(stderr, "Failed to join the vmnet_to_tap thread\n");
|
syslog(LOG_CRIT, "Failed to join the vmnet_to_tap thread");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (pthread_join(t2v, NULL) != 0){
|
if (pthread_join(t2v, NULL) != 0){
|
||||||
fprintf(stderr, "Failed to join the tap_to_vmnet thread\n");
|
syslog(LOG_CRIT, "Failed to join the tap_to_vmnet thread");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ static int server(GUID serviceid, const char *tap)
|
|||||||
|
|
||||||
void usage(char *name)
|
void usage(char *name)
|
||||||
{
|
{
|
||||||
printf("%s: --verbose | --service id <id> | --tap <tap>\n", name);
|
printf("%s: --debug | --service id <id> | --tap <tap>\n", name);
|
||||||
printf("<id>: Hyper-V socket serviceId to bind\n");
|
printf("<id>: Hyper-V socket serviceId to bind\n");
|
||||||
printf("<tap>: tap device to connect to\n");
|
printf("<tap>: tap device to connect to\n");
|
||||||
}
|
}
|
||||||
@ -324,19 +324,20 @@ int __cdecl main(int argc, char **argv)
|
|||||||
while (1) {
|
while (1) {
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
/* These options set a flag. */
|
/* These options set a flag. */
|
||||||
{"verbose", no_argument, &verbose_flag, 1},
|
{"debug", no_argument, &debug_flag, 1},
|
||||||
{"serviceid", required_argument, NULL, 's'},
|
{"serviceid", required_argument, NULL, 's'},
|
||||||
{"tap", required_argument, NULL, 't'},
|
{"tap", required_argument, NULL, 't'},
|
||||||
|
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
|
||||||
c = getopt_long (argc, argv, "vs:t:", long_options, &option_index);
|
c = getopt_long (argc, argv, "ds:t:", long_options, &option_index);
|
||||||
if (c == -1) break;
|
if (c == -1) break;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'v':
|
case 'd':
|
||||||
verbose_flag = 1;
|
debug_flag = 1;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
serviceid = optarg;
|
serviceid = optarg;
|
||||||
@ -351,11 +352,16 @@ int __cdecl main(int argc, char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "serviceid=%s\n", serviceid);
|
int log_flags = LOG_CONS | LOG_NDELAY;
|
||||||
fprintf(stderr, "tap=%s\n", tap);
|
if (debug_flag) {
|
||||||
|
log_flags |= LOG_PERROR;
|
||||||
|
}
|
||||||
|
openlog(argv[0], log_flags, LOG_DAEMON);
|
||||||
|
|
||||||
|
syslog(LOG_INFO, "starting with serviceid=%s and tap=%s", serviceid, tap);
|
||||||
res = parseguid(serviceid, &sid);
|
res = parseguid(serviceid, &sid);
|
||||||
if (res) {
|
if (res) {
|
||||||
fprintf(stderr, "Failed to parse serviceid as GUID: %s\n", serviceid);
|
syslog(LOG_CRIT, "Failed to parse serviceid as GUID: %s", serviceid);
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user