http://code.google.com/p/mcedaemon/source/detail?r=72
Modified:
/trunk/Changelog
/trunk/Makefile
/trunk/mced.8
/trunk/mced.c
/trunk/mced.h
/trunk/rules.c
=======================================
--- /trunk/Changelog Sat Feb 27 12:14:59 2010
+++ /trunk/Changelog Tue Apr 13 09:32:37 2010
@@ -1,4 +1,9 @@
%changelog
+* Tue Apr 13 2010 Tim Hockin <tho...@google.com>
+ - Change -O (--oldsocket) behavior to take an argument and open both the
+ old and new style sockets. [mced.c, mced.h, mced.8, rules.c]
+ - Bump to 2.0.1 for release.
+
* Sat Feb 27 2010 Tim Hockin <tho...@google.com>
- Rename examples to be valid config files.
=======================================
--- /trunk/Makefile Sat Feb 27 12:16:25 2010
+++ /trunk/Makefile Tue Apr 13 09:32:37 2010
@@ -5,7 +5,7 @@
BUILD_CONFIG = $(TOPDIR)/BUILD_CONFIG
# project version
-PRJ_VERSION = 2.0.0
+PRJ_VERSION = 2.0.1
# assign build options default values
# Use '?=' variable assignment so ENV variables can be used.
=======================================
--- /trunk/mced.8 Sat Feb 27 12:54:17 2010
+++ /trunk/mced.8 Tue Apr 13 09:32:37 2010
@@ -130,11 +130,11 @@
%c=0 %v=0 %b=4 %s=0x12345678 %a=0xabcdef %m=0x00000000 %g=0x00000000
%t=8675309 %B=42
.PP
-If the \-O (\--oldsocket) flag is specified, \fBmced\fP will be compatible
-with the socket behavior of \fBmced\fP version 1.x, including using
-\fI/var/run/mced.socket\fP as the default socket and falling back on the
-legacy data format. The \-s (\--socketfile) flag always overrides the
-default socket path, regardless of the \-O flag.
+If the \-O (\--oldsocket) flag is specified, \fBmced\fP will retain
+backwards-compatible socket behavior of \fBmced\fP version 1.x. In
+addition to the normal version 2.x socket, \fBmced\fP will open a second
+socket and report MCEs in the legacy data format. This interface is
+considered deprecated but is retained for ease of migration.
.PP
\fBmced\fP will not close the client socket except in the case of a SIGHUP
or \fBmced\fP exiting.
@@ -213,12 +213,14 @@
disable rate limiting for these messages. Using \-l (\--logevents) will
override this option. (Default is \fI10\fP seconds.
.TP
-.BI \-O "\fR, \fP" \--oldsocket
-This option forces \fBmced\fP to use the legacy socket path
-(\fI/var/run/mced.socket\fP) and data format (formatted as "%c %b %s %a %m
-%g %t %B\\n"). Use this if you have socket clients that require the
-\fBmced\fP version 1.x behavior. Use of this option is discouraged, as
-new MCE fields are only available with the modern socket data format.
+.BI \-O "\fR, \fP" \--oldsocket " filename"
+This option forces \fBmced\fP to open a second socket using the
+legacy-style data format ("%c %b %s %a %m %g %t %B\\n"). Use this if you
+have socket clients that require the \fBmced\fP version 1.x behavior. Use
+of this option is discouraged, as new MCE fields are only available with
+the modern socket data format. Passing and empty string argument ("")
+will make \fBmced\fP use the default v1.x socket path
+(\fI/var/run/mced.socket\fP).
.TP
.BI \-p "\fR, \fP" \--pidfile " filename"
This option changes the name of the pidfile to which \fBmced\fP writes.
=======================================
--- /trunk/mced.c Thu Feb 25 16:44:13 2010
+++ /trunk/mced.c Tue Apr 13 09:32:37 2010
@@ -64,9 +64,6 @@
/* the size of a kernel MCE record in bytes */
size_t mced_kernel_record_len;
-/* whether we force legacy socket output or not */
-int mced_legacy_socket;
-
#if ENABLE_MCEDB
/* global database handle */
struct mce_database *mced_db;
@@ -82,11 +79,11 @@
static cmdline_int max_interval_ms = MCED_MAX_INTERVAL;
static cmdline_int min_interval_ms = MCED_MIN_INTERVAL;
static cmdline_int mce_rate_limit = -1;
-static cmdline_string socketfile = NULL;
+static cmdline_string socketfile = MCED_SOCKETFILE_V2;
+static cmdline_string socketfile_compat = NULL;
static cmdline_bool nosocket = 0;
static cmdline_string socketgroup = NULL;
static cmdline_mode_t socketmode = MCED_SOCKETMODE;
-static cmdline_bool use_v1_socket = 0;
static cmdline_bool foreground = 0;
static cmdline_string pidfile = MCED_PIDFILE;
static cmdline_int clientmax = MCED_CLIENTMAX;
@@ -209,8 +206,8 @@
},
{
"O", "oldsocket",
- CMDLINE_OPT_BOOL, &use_v1_socket,
- "", "Make socket behavior compatible with mced v1.x"
+ CMDLINE_OPT_STRING, &socketfile_compat,
+ "", "Use the specified socket file for v1 compatible behavior"
},
#if ENABLE_DBUS
{
@@ -293,17 +290,9 @@
if (mce_rate_limit <= 0) {
mce_rate_limit = -1;
}
- if (use_v1_socket) {
- mced_legacy_socket = 1;
- if (socketfile == NULL) {
- socketfile = MCED_SOCKETFILE_V1;
- }
- } else {
- if (socketfile == NULL) {
- socketfile = MCED_SOCKETFILE_V2;
- }
- }
-
+ if (socketfile_compat && socketfile_compat[0] == '\0') {
+ socketfile_compat = MCED_SOCKETFILE_V1;
+ }
return 0;
}
@@ -1089,6 +1078,7 @@
{
int mcelog_fd;
int sock_fd = -1; /* init to avoid a compiler warning */
+ int compat_sock_fd = -1;
int interval_ms;
/* learn who we really are */
@@ -1101,12 +1091,19 @@
/* close any extra file descriptors */
close_fds();
- /* open our socket */
+ /* open our socket(s) */
if (!nosocket) {
sock_fd = open_socket(socketfile, socketmode, socketgroup);
if (sock_fd < 0) {
exit(EXIT_FAILURE);
}
+ if (socketfile_compat) {
+ compat_sock_fd = open_socket(socketfile_compat,
+ socketmode, socketgroup);
+ if (compat_sock_fd < 0) {
+ exit(EXIT_FAILURE);
+ }
+ }
}
/* if we're running in foreground, we don't daemonize */
@@ -1170,11 +1167,12 @@
mced_log_events ? "on" : "off");
interval_ms = max_interval_ms;
while (1) {
- struct pollfd ar[2];
+ struct pollfd ar[3];
int r;
int nfds = 0;
int mce_idx = -1;
int sock_idx = -1;
+ int compat_sock_idx = -1;
int timed_out;
/* open the device file */
@@ -1194,6 +1192,12 @@
ar[nfds].events = POLLIN;
sock_idx = nfds;
nfds++;
+ if (socketfile_compat) {
+ ar[nfds].fd = compat_sock_fd;
+ ar[nfds].events = POLLIN;
+ compat_sock_idx = nfds;
+ nfds++;
+ }
}
if (max_interval_ms > 0) {
mced_debug(2, "DBG: next interval = %d msecs\n",
@@ -1248,22 +1252,40 @@
}
/* was it a new connection? */
- if (sock_idx >= 0 && ar[sock_idx].revents) {
+ if ((sock_idx >= 0 && ar[sock_idx].revents)
+ || (compat_sock_idx >= 0 && ar[compat_sock_idx].revents)) {
int cli_fd;
struct ucred creds;
char buf[32];
static int accept_errors;
+ int idx;
+ int fd;
+ int is_legacy_client;
+
+ /*
+ * Prefer the new socket if forced to choose.
+ * We'll get the old socket on the next loop.
+ */
+ if (sock_idx >= 0 && ar[sock_idx].revents) {
+ is_legacy_client = 0;
+ idx = sock_idx;
+ fd = sock_fd;
+ } else {
+ is_legacy_client = 1;
+ idx = compat_sock_idx;
+ fd = compat_sock_fd;
+ }
/* this shouldn't happen */
- if (!ar[sock_idx].revents & POLLIN) {
+ if (!ar[idx].revents & POLLIN) {
mced_log(LOG_WARNING,
"odd, poll set flags 0x%x\n",
- ar[sock_idx].revents);
+ ar[idx].revents);
continue;
}
/* accept and add to our lists */
- cli_fd = ud_accept(sock_fd, &creds);
+ cli_fd = ud_accept(fd, &creds);
if (cli_fd < 0) {
mced_perror(LOG_ERR,
"ERR: can't accept client");
@@ -1288,7 +1310,7 @@
fcntl(cli_fd, F_SETFD, FD_CLOEXEC);
snprintf(buf, sizeof(buf)-1, "%d[%d:%d]",
creds.pid, creds.uid, creds.gid);
- mced_add_client(cli_fd, buf);
+ mced_add_client(cli_fd, buf, is_legacy_client);
}
}
=======================================
--- /trunk/mced.h Thu Feb 25 16:44:13 2010
+++ /trunk/mced.h Tue Apr 13 09:32:37 2010
@@ -133,7 +133,6 @@
extern int mced_log_events;
extern int mced_non_root_clients;
extern size_t mced_kernel_record_len;
-extern int mced_legacy_socket;
extern int mced_log(int level, const char *fmt, ...) PRINTF_ARGS(2, 3);
extern int mced_debug(int min_dbg_lvl, const char *fmt, ...)
PRINTF_ARGS(2, 3);
extern int mced_perror(int level, const char *str);
@@ -142,7 +141,7 @@
* rules.c
*/
extern int mced_read_conf(const char *confdir);
-extern int mced_add_client(int client, const char *origin);
+extern int mced_add_client(int client, const char *origin, int is_legacy);
extern int mced_cleanup_rules(int do_detach);
extern int mced_handle_mce(struct mce *mce);
extern void mced_close_dead_clients(void);
=======================================
--- /trunk/rules.c Fri Feb 26 16:18:37 2010
+++ /trunk/rules.c Tue Apr 13 09:32:37 2010
@@ -49,7 +49,8 @@
enum {
RULE_NONE = 0,
RULE_CMD,
- RULE_CLIENT,
+ RULE_V1_CLIENT,
+ RULE_V2_CLIENT,
} type;
char *origin;
union {
@@ -77,9 +78,10 @@
static void unlock_rules(void);
static sigset_t *signals_handled(void);
static struct rule *parse_file(const char *file);
-static struct rule *parse_client(int client);
+static struct rule *parse_client(int client, int is_legacy);
static int do_cmd_rule(struct rule *r, struct mce *mce);
-static int do_client_rule(struct rule *r, struct mce *mce);
+static int do_v1_client_rule(struct rule *r, struct mce *mce);
+static int do_v2_client_rule(struct rule *r, struct mce *mce);
static int safe_write(int fd, const char *buf, int len);
static char *parse_cmd(const char *cmd, struct mce *mce);
@@ -352,16 +354,17 @@
}
int
-mced_add_client(int clifd, const char *origin)
+mced_add_client(int clifd, const char *origin, int is_legacy)
{
struct rule *r;
int nrules = 0;
if (mced_log_events) {
- mced_log(LOG_NOTICE, "client connected from %s\n", origin);
+ mced_log(LOG_NOTICE, "%sclient connected from %s\n",
+ is_legacy ? "legacy " : "", origin);
}
- r = parse_client(clifd);
+ r = parse_client(clifd, is_legacy);
if (r) {
r->origin = strdup(origin);
enlist_rule(&client_list, r);
@@ -377,7 +380,7 @@
}
static struct rule *
-parse_client(int client)
+parse_client(int client, int is_legacy)
{
struct rule *r;
@@ -386,7 +389,7 @@
if (!r) {
return NULL;
}
- r->type = RULE_CLIENT;
+ r->type = is_legacy ? RULE_V1_CLIENT : RULE_V2_CLIENT;
r->action.fd = client;
return r;
@@ -543,8 +546,10 @@
nrules++;
if (p->type == RULE_CMD) {
do_cmd_rule(p, mce);
- } else if (p->type == RULE_CLIENT) {
- do_client_rule(p, mce);
+ } else if (p->type == RULE_V1_CLIENT) {
+ do_v1_client_rule(p, mce);
+ } else if (p->type == RULE_V2_CLIENT) {
+ do_v2_client_rule(p, mce);
} else {
mced_log(LOG_WARNING,
"unknown rule type: %d\n", p->type);
@@ -654,57 +659,15 @@
}
static int
-do_client_rule(struct rule *rule, struct mce *mce)
-{
- int r;
+write_to_client(struct rule *rule, const char *buf, size_t len) {
int client = rule->action.fd;
- char buf[2048];
+ int r;
if (mced_log_events) {
mced_log(LOG_NOTICE, "notifying client %s\n", rule->origin);
}
- if (mced_legacy_socket) {
- snprintf(buf, sizeof(buf)-1,
- "%u %u 0x%016llx 0x%016llx 0x%016llx 0x%016llx "
- "0x%016llx %d\n",
- mce->cpu, mce->bank,
- (unsigned long long)mce->mci_status,
- (unsigned long long)mce->mci_address,
- (unsigned long long)mce->mci_misc,
- (unsigned long long)mce->mcg_status,
- (unsigned long long)mce->time, mce->boot);
- } else {
- snprintf(buf, sizeof(buf)-1,
- "%%B=%d" // boot
- " %%c=%u %%S=%d" // cpu, socket
- " %%p=0x%08lx" // init_apic_id
- " %%v=%d %%A=0x%08lx" // vendor, cpuid_eax
- " %%b=%u" // bank
- " %%s=0x%016llx" // mci_status
- " %%a=0x%016llx" // mci_address
- " %%m=0x%016llx" // mci_misc
- " %%g=0x%016llx" // mcg_status
- " %%G=0x%08lx" // mcg_cap
- " %%t=0x%016llx" // time
- " %%T=0x%016llx" // tsc
- " %%C=0x%04x %%I=0x%016llx" // cs, ip
- "\n",
- (int)mce->boot,
- (unsigned)mce->cpu, (int)mce->socket,
- (unsigned long)mce->init_apic_id,
- (int)mce->vendor, (unsigned long)mce->cpuid_eax,
- (unsigned)mce->bank,
- (unsigned long long)mce->mci_status,
- (unsigned long long)mce->mci_address,
- (unsigned long long)mce->mci_misc,
- (unsigned long long)mce->mcg_status,
- (unsigned long)mce->mcg_cap,
- (unsigned long long)mce->time,
- (unsigned long long)mce->tsc,
- (unsigned)mce->cs, (unsigned long long)mce->ip);
- }
- r = safe_write(client, buf, strlen(buf));
+ r = safe_write(client, buf, len);
if (r < 0 && errno == EPIPE) {
struct ucred cred;
/* closed */
@@ -724,6 +687,61 @@
return 0;
}
+
+static int
+do_v1_client_rule(struct rule *rule, struct mce *mce)
+{
+ char buf[2048];
+
+ snprintf(buf, sizeof(buf)-1,
+ "%u %u 0x%016llx 0x%016llx 0x%016llx 0x%016llx "
+ "0x%016llx %d\n",
+ mce->cpu, mce->bank,
+ (unsigned long long)mce->mci_status,
+ (unsigned long long)mce->mci_address,
+ (unsigned long long)mce->mci_misc,
+ (unsigned long long)mce->mcg_status,
+ (unsigned long long)mce->time, mce->boot);
+
+ return write_to_client(rule, buf, strlen(buf));
+}
+
+static int
+do_v2_client_rule(struct rule *rule, struct mce *mce)
+{
+ char buf[2048];
+
+ snprintf(buf, sizeof(buf)-1,
+ "%%B=%d" // boot
+ " %%c=%u %%S=%d" // cpu, socket
+ " %%p=0x%08lx" // init_apic_id
+ " %%v=%d %%A=0x%08lx" // vendor, cpuid_eax
+ " %%b=%u" // bank
+ " %%s=0x%016llx" // mci_status
+ " %%a=0x%016llx" // mci_address
+ " %%m=0x%016llx" // mci_misc
+ " %%g=0x%016llx" // mcg_status
+ " %%G=0x%08lx" // mcg_cap
+ " %%t=0x%016llx" // time
+ " %%T=0x%016llx" // tsc
+ " %%C=0x%04x %%I=0x%016llx" // cs, ip
+ "\n",
+ (int)mce->boot,
+ (unsigned)mce->cpu, (int)mce->socket,
+ (unsigned long)mce->init_apic_id,
+ (int)mce->vendor, (unsigned long)mce->cpuid_eax,
+ (unsigned)mce->bank,
+ (unsigned long long)mce->mci_status,
+ (unsigned long long)mce->mci_address,
+ (unsigned long long)mce->mci_misc,
+ (unsigned long long)mce->mcg_status,
+ (unsigned long)mce->mcg_cap,
+ (unsigned long long)mce->time,
+ (unsigned long long)mce->tsc,
+ (unsigned)mce->cs, (unsigned long long)mce->ip);
+
+ return write_to_client(rule, buf, strlen(buf));
+}
#define NTRIES 100
static int