On Thu, Feb 22, 2007 at 12:58:37AM +0100, Blaisorblade wrote:
> On Thursday 22 February 2007 00:51, Blaisorblade wrote:
> > On Wednesday 21 February 2007 21:19, Jeroen van der Ham wrote:
> > > Blaisorblade wrote:
> > > > Using > /dev/null 2>&1 is not suitable?
> > >
> > > Well yes, that might also help.
> > > However, when you supply a daemon mode, I think it is also a good idea to
> > > add a silent feature, so that it is more easily and cleanly scriptable.
> >
> > Hmm. It's a possibility, implemented and attached (1st uml_switch-* then
> > use-sil_-funcs), but I don't like it. Unless we don't use syslog(3), or at
> > least errors early at boot are reported.
> I forgot: Stefano, Mattia, what do you think on this? Have you got any
> suggestion? I cc'ed you on last mail for this (and forgot Mattia because it's
> late and I'm tired).
I admit the syslog option is quite intriguing. I implemented something
similar for cpufreqd:
if deamonized
log to syslog
else
log to stdout/stderr
Moreover I had a -verbosity switch, but I see this may be superfluous
since you seem to prefer an either-log-or-dont-at-all approach.
I attached a patch[1] that implements the above pseudocode, consider it
preliminary as it currently doesn't implement the -quiet switch and I
gave almost no testing, just a quick run.
BTW: I also changed the daemon() call to redirect all FDs
to /dev/null as using syslog when daemonized has no use for them.
[1]: it applies on top of your previous switch-io-fixes patch
PS: keep Cc-ing me as I'm periodically unsubscribed by the list because
of spam/virus (fake?) bounces...
--
mattia
:wq!
diff -ur tools-20060622.orig/uml_switch/hash.c tools-20060622/uml_switch/hash.c
--- tools-20060622.orig/uml_switch/hash.c 2007-02-22 12:59:13.905544910 +0100
+++ tools-20060622/uml_switch/hash.c 2007-02-22 13:53:12.590107025 +0100
@@ -61,7 +61,7 @@
new = malloc(sizeof(*new));
if(new == NULL){
- perror("Failed to malloc hash entry");
+ log_perror("Failed to malloc hash entry");
return;
}
@@ -123,7 +123,7 @@
{
struct printer *p = arg;
- printf("Hash: %d Addr: %02x:%02x:%02x:%02x:%02x:%02x to port: %s "
+ log_info("Hash: %d Addr: %02x:%02x:%02x:%02x:%02x:%02x to port: %s "
"age %ld secs\n", calc_hash(e->dst),
e->dst[0], e->dst[1], e->dst[2], e->dst[3], e->dst[4], e->dst[5],
(*p->port_id)(e->port), (int) p->now - e->last_seen);
@@ -168,7 +168,7 @@
sa.sa_handler = sig_alarm;
sa.sa_flags = SA_RESTART;
if(sigaction(SIGALRM, &sa, NULL) < 0){
- perror("Setting handler for SIGALRM");
+ log_perror("Setting handler for SIGALRM");
return;
}
kill(getpid(), SIGALRM);
diff -ur tools-20060622.orig/uml_switch/port.c tools-20060622/uml_switch/port.c
--- tools-20060622.orig/uml_switch/port.c 2007-02-22 14:08:52.643677625 +0100
+++ tools-20060622/uml_switch/port.c 2007-02-22 14:31:10.719930245 +0100
@@ -47,7 +47,7 @@
if(port->control == fd) break;
}
if(port == NULL){
- fprintf(stderr, "No port associated with descriptor %d\n", fd);
+ log_error("No port associated with descriptor %d\n", fd);
return;
}
delete_hash(port->src);
@@ -66,16 +66,16 @@
if(port != last){
/* old value differs from actual input port */
- printf(" Addr: %02x:%02x:%02x:%02x:%02x:%02x New port %d",
+ log_info(" Addr: %02x:%02x:%02x:%02x:%02x:%02x New port %d",
p->header.src[0], p->header.src[1], p->header.src[2],
p->header.src[3], p->header.src[4], p->header.src[5],
port->control);
if(last != NULL){
- printf(" old port %d", last->control);
+ log_info(" old port %d", last->control);
delete_hash(p->header.src);
}
- printf("\n");
+ log_info("\n");
memcpy(port->src, p->header.src, sizeof(port->src));
insert_into_hash(p->header.src, port);
@@ -91,12 +91,12 @@
target = find_in_hash(packet->header.dest);
if((target == NULL) || IS_BROADCAST(packet->header.dest) || hub){
if((target == NULL) && !IS_BROADCAST(packet->header.dest)){
- printf("unknown Addr: %02x:%02x:%02x:%02x:%02x:%02x from port ",
+ log_info("unknown Addr: %02x:%02x:%02x:%02x:%02x:%02x from port ",
packet->header.src[0], packet->header.src[1],
packet->header.src[2], packet->header.src[3],
packet->header.src[4], packet->header.src[5]);
- if(port == NULL) printf("UNKNOWN\n");
- else printf("%d\n", port->control);
+ if(port == NULL) log_info("UNKNOWN\n");
+ else log_info("%d\n", port->control);
}
/* no cache or broadcast/multicast == all ports */
@@ -124,7 +124,7 @@
/* if we have an incoming port (we should) */
if(p != NULL) update_src(p, packet);
- else printf("Unknown connection for packet, shouldn't happen.\n");
+ else log_info("Unknown connection for packet, shouldn't happen.\n");
send_dst(p, packet, len, hub);
}
@@ -142,7 +142,7 @@
len = read(fd, &packet, sizeof(packet));
if(len < 0){
- if(errno != EAGAIN) perror("Reading tap data");
+ if(errno != EAGAIN) log_perror("Reading tap data");
return;
}
handle_data(fd, hub, &packet, len, NULL, match_tap);
@@ -155,7 +155,7 @@
port = malloc(sizeof(struct port));
if(port == NULL){
- perror("malloc");
+ log_perror("malloc");
return(-1);
}
port->next = head;
@@ -166,7 +166,7 @@
port->data_len = data_len;
port->sender = sender;
head = port;
- printf("New connection\n");
+ log_info("New connection\n");
return(0);
}
@@ -179,15 +179,15 @@
{
struct sock_data *mine = data;
int err;
-
+
err = sendto(mine->fd, packet, len, 0, (struct sockaddr *) &mine->sock,
- sizeof(mine->sock));
- if(err != len) {
+ sizeof(mine->sock));
+ if(err != len){
int saved_errno = errno;
if (saved_errno != EAGAIN) {
- fprintf(stderr, "send_sock sending to fd %d ", mine->fd);
+ log_error("send_sock sending to fd %d ", mine->fd);
errno = saved_errno;
- perror("");
+ log_perror("");
}
}
}
@@ -212,7 +212,7 @@
len = recvfrom(fd, &packet, sizeof(packet), 0,
(struct sockaddr *) &data.sock, &socklen);
if(len < 0){
- if(errno != EAGAIN) perror("handle_sock_data");
+ if(errno != EAGAIN) log_perror("handle_sock_data");
return;
}
data.fd = fd;
@@ -226,7 +226,7 @@
data = malloc(sizeof(*data));
if(data == NULL){
- perror("setup_sock_port");
+ log_perror("setup_sock_port");
return(-1);
}
*data = ((struct sock_data) { fd : data_fd,
@@ -240,9 +240,9 @@
char c;
n = read(port->control, &c, sizeof(c));
- if(n < 0) perror("Reading request");
- else if(n == 0) printf("Disconnect\n");
- else printf("Bad request\n");
+ if(n < 0) log_perror("Reading request");
+ else if(n == 0) log_info("Disconnect\n");
+ else log_info("Bad request\n");
}
int handle_port(int fd)
diff -ur tools-20060622.orig/uml_switch/switch.h tools-20060622/uml_switch/switch.h
--- tools-20060622.orig/uml_switch/switch.h 2007-02-22 12:59:13.905544910 +0100
+++ tools-20060622/uml_switch/switch.h 2007-02-22 14:32:26.224232990 +0100
@@ -7,4 +7,12 @@
#define ETH_ALEN 6
+/* to provide log levels */
+#include <syslog.h>
+
+void log_message(const int prio, const char *fmt, ...);
+#define log_perror(mesg) log_message(LOG_ERR, "%s: %s\n", mesg, strerror(errno))
+#define log_error(mesg...) log_message(LOG_ERR, mesg)
+#define log_info(mesg...) log_message(LOG_INFO, mesg)
+
#endif
diff -ur tools-20060622.orig/uml_switch/tuntap.c tools-20060622/uml_switch/tuntap.c
--- tools-20060622.orig/uml_switch/tuntap.c 2007-02-22 12:59:13.905544910 +0100
+++ tools-20060622/uml_switch/tuntap.c 2007-02-22 13:55:18.597287765 +0100
@@ -6,6 +6,7 @@
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_tun.h>
+#include "switch.h"
#include "port.h"
static void send_tap(int fd, void *packet, int len, void *unused)
@@ -14,7 +15,7 @@
n = write(fd, packet, len);
if(n != len){
- if(errno != EAGAIN) perror("send_tap");
+ if(errno != EAGAIN) log_perror("send_tap");
}
}
@@ -24,14 +25,14 @@
int fd, err;
if((fd = open("/dev/net/tun", O_RDWR)) < 0){
- perror("Failed to open /dev/net/tun");
+ log_perror("Failed to open /dev/net/tun");
return(-1);
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name) - 1);
if(ioctl(fd, TUNSETIFF, (void *) &ifr) < 0){
- perror("TUNSETIFF failed");
+ log_perror("TUNSETIFF failed");
close(fd);
return(-1);
}
diff -ur tools-20060622.orig/uml_switch/uml_switch.c tools-20060622/uml_switch/uml_switch.c
--- tools-20060622.orig/uml_switch/uml_switch.c 2007-02-22 14:08:52.643677625 +0100
+++ tools-20060622/uml_switch/uml_switch.c 2007-02-22 14:34:38.731784165 +0100
@@ -4,6 +4,8 @@
#include <stdio.h>
#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
@@ -78,6 +80,22 @@
struct request_v3 v3;
};
+static int use_syslog = 0;
+
+void log_message(const int prio, const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ if (use_syslog)
+ vsyslog(prio, fmt, argp);
+ else {
+ if (prio <= LOG_ERR)
+ vfprintf(stderr, fmt, argp);
+ else
+ vfprintf(stdout, fmt, argp);
+ }
+ va_end(argp);
+}
+
static char *ctl_socket = "/tmp/uml.ctl";
static char *data_socket = NULL;
@@ -86,12 +104,12 @@
static void cleanup(void)
{
if(unlink(ctl_socket) < 0){
- printf("Couldn't remove control socket '%s' : ", ctl_socket);
- perror("");
+ log_info("Couldn't remove control socket '%s' : ", ctl_socket);
+ log_perror("");
}
if((data_socket != NULL) && (unlink(data_socket) < 0)){
- printf("Couldn't remove data socket '%s' : ", data_socket);
- perror("");
+ log_info("Couldn't remove data socket '%s' : ", data_socket);
+ log_perror("");
}
}
@@ -106,7 +124,7 @@
if(nfds == maxfds){
maxfds = maxfds ? 2 * maxfds : 4;
if((fds = realloc(fds, maxfds * sizeof(struct pollfd))) == NULL){
- perror("realloc");
+ log_perror("realloc");
cleanup();
exit(1);
}
@@ -124,7 +142,7 @@
if(fds[i].fd == fd) break;
}
if(i == nfds){
- fprintf(stderr, "remove_fd : Couldn't find descriptor %d\n", fd);
+ log_error("remove_fd : Couldn't find descriptor %d\n", fd);
}
memmove(&fds[i], &fds[i + 1], (maxfds - i - 1) * sizeof(struct pollfd));
nfds--;
@@ -132,7 +150,7 @@
static void sig_handler(int sig)
{
- printf("Caught signal %d, cleaning up and exiting\n", sig);
+ log_info("Caught signal %d, cleaning up and exiting\n", sig);
cleanup();
signal(sig, SIG_DFL);
kill(getpid(), sig);
@@ -152,7 +170,7 @@
setup_sock_port(fd, &req->u.new_control.name, data_fd);
break;
default:
- printf("Bad request type : %d\n", req->type);
+ log_info("Bad request type : %d\n", req->type);
close_descriptor(fd);
}
}
@@ -168,19 +186,19 @@
if(err) return;
n = write(fd, &data_sun, sizeof(data_sun));
if(n != sizeof(data_sun)){
- perror("Sending data socket name");
+ log_perror("Sending data socket name");
close_descriptor(fd);
}
break;
default:
- printf("Bad request type : %d\n", type);
+ log_info("Bad request type : %d\n", type);
close_descriptor(fd);
}
}
static void new_port_v2(int fd)
{
- fprintf(stderr, "Version 2 is not supported\n");
+ log_error("Version 2 is not supported\n");
close_descriptor(fd);
}
@@ -192,13 +210,13 @@
len = read(fd, &req, sizeof(req));
if(len < 0){
if(errno != EAGAIN){
- perror("Reading request");
+ log_perror("Reading request");
close_descriptor(fd);
}
return;
}
else if(len == 0){
- printf("EOF from new port\n");
+ log_info("EOF from new port\n");
close_descriptor(fd);
return;
}
@@ -207,7 +225,7 @@
if(req.v3.version == 3)
new_port_v1_v3(fd, req.v3.type, &req.v3.sock, data_fd);
else if(req.v2.version > 2)
- fprintf(stderr, "Request for a version %d port, which this "
+ log_error("Request for a version %d port, which this "
"uml_switch doesn't support\n", req.v2.version);
else new_port_v1_v3(fd, req.v1.type, &req.v1.u.new_control.name, data_fd);
}
@@ -223,11 +241,11 @@
len = sizeof(addr);
new = accept(fd, &addr, &len);
if(new < 0){
- perror("accept");
+ log_perror("accept");
return;
}
if(fcntl(new, F_SETFL, O_NONBLOCK) < 0){
- perror("fcntl - setting O_NONBLOCK");
+ log_perror("fcntl - setting O_NONBLOCK");
close(new);
return;
}
@@ -239,19 +257,19 @@
int test_fd, ret = 1;
if((test_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){
- perror("socket");
+ log_perror("socket");
exit(1);
}
if(connect(test_fd, (struct sockaddr *) sun, sizeof(*sun)) < 0){
if(errno == ECONNREFUSED){
if(unlink(sun->sun_path) < 0){
- fprintf(stderr, "Failed to removed unused socket '%s': ",
+ log_error("Failed to removed unused socket '%s': ",
sun->sun_path);
- perror("");
+ log_perror("");
}
ret = 0;
}
- else perror("connect");
+ else log_perror("connect");
}
close(test_fd);
return(ret);
@@ -267,7 +285,7 @@
if(bind(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){
if((errno == EADDRINUSE) && still_used(&sun)) return(EADDRINUSE);
else if(bind(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){
- perror("bind");
+ log_perror("bind");
return(EPERM);
}
}
@@ -299,40 +317,40 @@
try_remove_ctl = ctl_present;
try_remove_data = data_present;
if(ctl_present && ctl_used){
- fprintf(stderr, "The control socket '%s' has another server "
+ log_error("The control socket '%s' has another server "
"attached to it\n", ctl_name);
try_remove_ctl = 0;
}
else if(ctl_present && !ctl_used)
- fprintf(stderr, "The control socket '%s' exists, isn't used, but couldn't "
+ log_error("The control socket '%s' exists, isn't used, but couldn't "
"be removed\n", ctl_name);
if(data_present && data_used){
- fprintf(stderr, "The data socket '%s' has another server "
+ log_error("The data socket '%s' has another server "
"attached to it\n", data_name);
try_remove_data = 0;
}
else if(data_present && !data_used)
- fprintf(stderr, "The data socket '%s' exists, isn't used, but couldn't "
+ log_error("The data socket '%s' exists, isn't used, but couldn't "
"be removed\n", data_name);
if(try_remove_ctl || try_remove_data){
- fprintf(stderr, "You can either\n");
+ log_error("You can either\n");
if(try_remove_ctl && !try_remove_data)
- fprintf(stderr, "\tremove '%s'\n", ctl_socket);
+ log_error("\tremove '%s'\n", ctl_socket);
else if(!try_remove_ctl && try_remove_data)
- fprintf(stderr, "\tremove '%s'\n", data_socket);
- else fprintf(stderr, "\tremove '%s' and '%s'\n", ctl_socket, data_socket);
- fprintf(stderr, "\tor rerun with different, unused filenames for "
+ log_error("\tremove '%s'\n", data_socket);
+ else log_error("\tremove '%s' and '%s'\n", ctl_socket, data_socket);
+ log_error("\tor rerun with different, unused filenames for "
"sockets:\n");
- fprintf(stderr, "\t\t%s -unix <control> <data>\n", prog);
- fprintf(stderr, "\t\tand run the UMLs with "
+ log_error("\t\t%s -unix <control> <data>\n", prog);
+ log_error("\t\tand run the UMLs with "
"'eth0=daemon,,unix,<control>,<data>\n");
exit(1);
}
else {
- fprintf(stderr, "You should rerun with different, unused filenames for "
+ log_error("You should rerun with different, unused filenames for "
"sockets:\n");
- fprintf(stderr, "\t%s -unix <control> <data>\n", prog);
- fprintf(stderr, "\tand run the UMLs with "
+ log_error("\t%s -unix <control> <data>\n", prog);
+ log_error("\tand run the UMLs with "
"'eth0=daemon,,unix,<control>,<data>'\n");
exit(1);
}
@@ -354,7 +372,7 @@
sun->sun_family = AF_UNIX;
memcpy(sun->sun_path, &name, sizeof(name));
if(bind(fd, (struct sockaddr *) sun, sizeof(*sun)) < 0){
- perror("Binding to data socket");
+ log_perror("Binding to data socket");
exit(1);
}
}
@@ -371,15 +389,15 @@
else if(err == EADDRINUSE) used = 1;
if(used){
- fprintf(stderr, "The control socket '%s' has another server "
+ log_error("The control socket '%s' has another server "
"attached to it\n", ctl_name);
- fprintf(stderr, "You can either\n");
- fprintf(stderr, "\tremove '%s'\n", ctl_name);
- fprintf(stderr, "\tor rerun with a different, unused filename for a "
+ log_error("You can either\n");
+ log_error("\tremove '%s'\n", ctl_name);
+ log_error("\tor rerun with a different, unused filename for a "
"socket\n");
}
else
- fprintf(stderr, "The control socket '%s' exists, isn't used, but couldn't "
+ log_error("The control socket '%s' exists, isn't used, but couldn't "
"be removed\n", ctl_name);
exit(1);
}
@@ -392,7 +410,7 @@
tap_str = "[ -tap tap-device ]";
#endif
- fprintf(stderr, "Usage : %s [ -unix control-socket ] [ -hub ] %s\n"
+ log_error("Usage : %s [ -unix control-socket ] [ -hub ] %s\n"
"or : %s -compat-v0 [ -unix control-socket data-socket ] "
"[ -hub ] %s\n", prog, tap_str, prog, tap_str);
@@ -433,18 +451,18 @@
argv += 2;
argc -= 2;
#else
- fprintf(stderr, "-tap isn't supported since TUNTAP isn't enabled\n");
+ log_error("-tap isn't supported since TUNTAP isn't enabled\n");
Usage();
#endif
}
else if(!strcmp(argv[0], "-hub")){
- printf("%s will be a hub instead of a switch\n", prog);
+ log_info("%s will be a hub instead of a switch\n", prog);
hub = 1;
argc--;
argv++;
}
else if(!strcmp(argv[0], "-compat-v0")){
- printf("Control protocol 0 compatibility\n");
+ log_info("Control protocol 0 compatibility\n");
compat_v0 = 1;
data_socket = "/tmp/uml.data";
argc--;
@@ -459,24 +477,24 @@
}
if((connect_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){
- perror("socket");
+ log_perror("socket");
exit(1);
}
if(setsockopt(connect_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
sizeof(one)) < 0){
- perror("setsockopt");
+ log_perror("setsockopt");
exit(1);
}
if(fcntl(connect_fd, F_SETFL, O_NONBLOCK) < 0){
- perror("Setting O_NONBLOCK on connection fd");
+ log_perror("Setting O_NONBLOCK on connection fd");
exit(1);
}
if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0){
- perror("socket");
+ log_perror("socket");
exit(1);
}
if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0){
- perror("Setting O_NONBLOCK on data fd");
+ log_perror("Setting O_NONBLOCK on data fd");
exit(1);
}
@@ -484,24 +502,24 @@
else bind_sockets(connect_fd, ctl_socket, data_fd);
if(listen(connect_fd, 15) < 0){
- perror("listen");
+ log_perror("listen");
exit(1);
}
if(signal(SIGINT, sig_handler) == SIG_ERR)
- perror("Setting handler for SIGINT");
+ log_perror("Setting handler for SIGINT");
hash_init();
if(compat_v0)
- printf("%s attached to unix sockets '%s' and '%s'", prog, ctl_socket,
+ log_info("%s attached to unix sockets '%s' and '%s'", prog, ctl_socket,
data_socket);
- else printf("%s attached to unix socket '%s'", prog, ctl_socket);
+ else log_info("%s attached to unix socket '%s'", prog, ctl_socket);
#ifdef TUNTAP
if(tap_dev != NULL)
- printf(" tap device '%s'", tap_dev);
+ log_info(" tap device '%s'", tap_dev);
#endif
- printf("\n");
+ log_info("\n");
if(isatty(0) && !daemonize)
add_fd(0);
@@ -514,15 +532,15 @@
#endif
if (daemonize) {
- int nullfd;
- if (daemon(0, 1)) {
- perror("daemon");
+ if (daemon(0, 0)) {
+ log_perror("daemon");
exit(1);
}
- nullfd = open("/dev/null", O_RDONLY);
- if (dup2(nullfd, 0))
- perror("dup2 /dev/null to 0");
- close(nullfd);
+ /* open syslog */
+ openlog("uml_switch", LOG_CONS, LOG_DAEMON);
+ /* from now on we will be using
+ syslog to print messages */
+ use_syslog = 1;
}
while(1){
@@ -531,30 +549,30 @@
n = poll(fds, nfds, -1);
if(n < 0){
if(errno == EINTR) continue;
- perror("poll");
+ log_perror("poll");
break;
}
for(i = 0; i < nfds; i++){
if(fds[i].revents == 0) continue;
if(fds[i].fd == 0){
if(fds[i].revents & POLLHUP){
- printf("EOF on stdin, cleaning up and exiting\n");
+ log_info("EOF on stdin, cleaning up and exiting\n");
goto out;
}
n = read(0, buf, sizeof(buf));
if(n < 0){
- perror("Reading from stdin");
+ log_perror("Reading from stdin");
break;
}
else if(n == 0){
- printf("EOF on stdin, cleaning up and exiting\n");
+ log_info("EOF on stdin, cleaning up and exiting\n");
goto out;
}
}
else if(fds[i].fd == connect_fd){
if(fds[i].revents & POLLHUP){
- printf("Error on connection fd\n");
+ log_info("Error on connection fd\n");
continue;
}
accept_connection(connect_fd);
@@ -571,6 +589,8 @@
}
}
out:
+ if (daemonize)
+ closelog();
cleanup();
return 0;
}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
User-mode-linux-user mailing list
User-mode-linux-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-user