|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2001-2008 Willem Dijkstra
|
|
|
+ * Copyright (c) 2001-2010 Willem Dijkstra
|
|
|
* All rights reserved.
|
|
|
*
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -58,13 +58,14 @@ void alarmhandler(int);
|
|
|
void drop_privileges();
|
|
|
void exithandler(int);
|
|
|
void huphandler(int);
|
|
|
-void set_stream_use(struct muxlist *);
|
|
|
+void init_streams(struct muxlist *mul);
|
|
|
+void drop_privileges(int unsecure);
|
|
|
__END_DECLS
|
|
|
|
|
|
int flag_unsecure = 0;
|
|
|
int flag_hup = 0;
|
|
|
int flag_testconf = 0;
|
|
|
-int symon_interval = SYMON_DEFAULT_INTERVAL;
|
|
|
+int symon_interval = 0;
|
|
|
|
|
|
/* map stream types to inits and getters */
|
|
|
struct funcmap streamfunc[] = {
|
|
@@ -84,23 +85,46 @@ struct funcmap streamfunc[] = {
|
|
|
{MT_IF2, 0, NULL, init_if, gets_if, get_if},
|
|
|
{MT_CPUIOW, 0, NULL, init_cpuiow, gets_cpuiow, get_cpuiow},
|
|
|
{MT_SMART, 0, NULL, init_smart, gets_smart, get_smart},
|
|
|
+ {MT_LOAD, 0, NULL, init_load, gets_load, get_load},
|
|
|
{MT_EOT, 0, NULL, NULL, NULL}
|
|
|
};
|
|
|
|
|
|
void
|
|
|
-set_stream_use(struct muxlist *mul)
|
|
|
+init_streams(struct muxlist *mul)
|
|
|
{
|
|
|
- struct mux *mux;
|
|
|
+ struct itimerval alarminterval;
|
|
|
struct stream *stream;
|
|
|
- int i;
|
|
|
+ struct mux *mux;
|
|
|
|
|
|
- for (i = 0; i < MT_EOT; i++)
|
|
|
- streamfunc[i].used = 0;
|
|
|
+ mux = NULL;
|
|
|
+
|
|
|
+ if ((mul == NULL) || ((mux = SLIST_FIRST(mul)) == NULL))
|
|
|
+ fatal("empty mux list");
|
|
|
|
|
|
+ symon_interval = mux->interval;
|
|
|
|
|
|
SLIST_FOREACH(mux, mul, muxes) {
|
|
|
- SLIST_FOREACH(stream, &mux->sl, streams)
|
|
|
- streamfunc[stream->type].used = 1;
|
|
|
+ /* determine gcd of alarm times */
|
|
|
+ symon_interval = gcd(symon_interval, mux->interval);
|
|
|
+
|
|
|
+ /* init network */
|
|
|
+ init_symon_packet(mux);
|
|
|
+ connect2mux(mux);
|
|
|
+
|
|
|
+ /* init modules */
|
|
|
+ SLIST_FOREACH(stream, &mux->sl, streams) {
|
|
|
+ (streamfunc[stream->type].init) (stream);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* setup alarm */
|
|
|
+ timerclear(&alarminterval.it_interval);
|
|
|
+ timerclear(&alarminterval.it_value);
|
|
|
+ alarminterval.it_interval.tv_sec =
|
|
|
+ alarminterval.it_value.tv_sec = symon_interval;
|
|
|
+
|
|
|
+ if (setitimer(ITIMER_REAL, &alarminterval, NULL) != 0) {
|
|
|
+ fatal("alarm setup failed: %.200s", strerror(errno));
|
|
|
}
|
|
|
}
|
|
|
void
|
|
@@ -172,7 +196,6 @@ int
|
|
|
main(int argc, char *argv[])
|
|
|
{
|
|
|
struct muxlist mul, newmul;
|
|
|
- struct itimerval alarminterval;
|
|
|
struct stream *stream;
|
|
|
struct mux *mux;
|
|
|
time_t now, last_update;
|
|
@@ -224,7 +247,11 @@ main(int argc, char *argv[])
|
|
|
exit(EX_OK);
|
|
|
}
|
|
|
|
|
|
- set_stream_use(&mul);
|
|
|
+ SLIST_FOREACH(mux, &mul, muxes) {
|
|
|
+ SLIST_FOREACH(stream, &mux->sl, streams) {
|
|
|
+ streamfunc[stream->type].used = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/* open resources that might not be available after privilege drop */
|
|
|
for (i = 0; i < MT_EOT; i++)
|
|
@@ -267,24 +294,7 @@ main(int argc, char *argv[])
|
|
|
/* prepare crc32 */
|
|
|
init_crc32();
|
|
|
|
|
|
- /* init modules */
|
|
|
- SLIST_FOREACH(mux, &mul, muxes) {
|
|
|
- init_symon_packet(mux);
|
|
|
- connect2mux(mux);
|
|
|
- SLIST_FOREACH(stream, &mux->sl, streams) {
|
|
|
- (streamfunc[stream->type].init) (stream);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* setup alarm */
|
|
|
- timerclear(&alarminterval.it_interval);
|
|
|
- timerclear(&alarminterval.it_value);
|
|
|
- alarminterval.it_interval.tv_sec =
|
|
|
- alarminterval.it_value.tv_sec = symon_interval;
|
|
|
-
|
|
|
- if (setitimer(ITIMER_REAL, &alarminterval, NULL) != 0) {
|
|
|
- fatal("alarm setup failed: %.200s", strerror(errno));
|
|
|
- }
|
|
|
+ init_streams(&mul);
|
|
|
|
|
|
last_update = time(NULL);
|
|
|
for (;;) { /* FOREVER */
|
|
@@ -306,14 +316,7 @@ main(int argc, char *argv[])
|
|
|
info("read configuration file '%.200s' successfully", cfgpath);
|
|
|
|
|
|
/* init modules */
|
|
|
- SLIST_FOREACH(mux, &mul, muxes) {
|
|
|
- init_symon_packet(mux);
|
|
|
- connect2mux(mux);
|
|
|
- SLIST_FOREACH(stream, &mux->sl, streams) {
|
|
|
- (streamfunc[stream->type].init) (stream);
|
|
|
- }
|
|
|
- }
|
|
|
- set_stream_use(&mul);
|
|
|
+ init_streams(&mul);
|
|
|
}
|
|
|
} else {
|
|
|
info("configuration unreachable because of privsep; keeping old configuration");
|
|
@@ -330,20 +333,36 @@ main(int argc, char *argv[])
|
|
|
}
|
|
|
last_update = now;
|
|
|
|
|
|
- /* populate for modules that get all their measurements in one go */
|
|
|
+ /* populate for modules that get all their measurements in one
|
|
|
+ * go. we bunch up calls together to ensure that the measurements
|
|
|
+ * happen "at the same time" */
|
|
|
for (i = 0; i < MT_EOT; i++)
|
|
|
- if (streamfunc[i].used && (streamfunc[i].gets != NULL))
|
|
|
- (streamfunc[i].gets) ();
|
|
|
+ streamfunc[i].used = 0;
|
|
|
+ SLIST_FOREACH(mux, &mul, muxes) {
|
|
|
+ mux->last += symon_interval;
|
|
|
+ if (mux->last >= mux->interval) {
|
|
|
+ SLIST_FOREACH(stream, &mux->sl, streams) {
|
|
|
+ if (streamfunc[stream->type].used == 0) {
|
|
|
+ streamfunc[stream->type].used = 1;
|
|
|
+ if (streamfunc[stream->type].gets != NULL)
|
|
|
+ (streamfunc[stream->type].gets)();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
SLIST_FOREACH(mux, &mul, muxes) {
|
|
|
- prepare_packet(mux);
|
|
|
+ if (mux->last >= mux->interval) {
|
|
|
+ mux->last = 0;
|
|
|
+ prepare_packet(mux, now);
|
|
|
|
|
|
- SLIST_FOREACH(stream, &mux->sl, streams)
|
|
|
- stream_in_packet(stream, mux);
|
|
|
+ SLIST_FOREACH(stream, &mux->sl, streams)
|
|
|
+ stream_in_packet(stream, mux);
|
|
|
|
|
|
- finish_packet(mux);
|
|
|
+ finish_packet(mux);
|
|
|
|
|
|
- send_packet(mux);
|
|
|
+ send_packet(mux);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|