Dear Developers,
I've encountered a problem in OpenIPMI something I see as a bug, the issue is
that the library uses gettimeofday as its source for creating timeouts
this can cause a problem if some action is registered and the date of the
machine is changed (backwards) this way the selector will take much longer
to call the action to happen. I'm sending you a patch that I use in my system,
it speaks for itself, please take a look and tell me what you think (basicly
I changed the the use of gettimeofday --> clock(MONOTONIC_CLOCK))
Thanks a lot,
George Lashenko
From 102a118883d652b37e867ef81a5ce9c6878e1ced Mon Sep 17 00:00:00 2001
From: George Lashenko <[email protected]>
Date: Tue, 1 Oct 2013 14:25:26 +0300
Subject: [PATCH] Changing the clock to be monotonic so that system time
changes wont affect us.
---
include/OpenIPMI/selector.h | 2 +-
include/OpenIPMI/time_helpers.h | 3 +++
lanserv/Makefile.am | 4 ++--
lanserv/Makefile.in | 4 ++--
lanserv/emu.c | 25 +++++++++++++------------
lib/ipmi_lan.c | 5 +++--
lib/mc.c | 5 +++--
lib/oem_atca_conn.c | 5 +++--
ui/ui.c | 7 ++++---
unix/posix_os_hnd.c | 3 ++-
unix/posix_thread_os_hnd.c | 5 +++--
unix/selector.c | 5 +++--
utils/Makefile.am | 2 +-
utils/Makefile.in | 5 +++--
utils/time_helpers.c | 14 ++++++++++++++
15 files changed, 60 insertions(+), 34 deletions(-)
create mode 100644 include/OpenIPMI/time_helpers.h
create mode 100644 utils/time_helpers.c
diff --git a/include/OpenIPMI/selector.h b/include/OpenIPMI/selector.h
index a8262dc..53ec9b5 100644
--- a/include/OpenIPMI/selector.h
+++ b/include/OpenIPMI/selector.h
@@ -34,6 +34,7 @@
#ifndef SELECTOR
#define SELECTOR
#include <sys/time.h> /* For timeval */
+#include <time.h>
#include <OpenIPMI/os_handler.h>
#ifdef __cplusplus
@@ -50,7 +51,6 @@ int sel_alloc_selector(os_handler_t *os_hnd, selector_t **new_selector);
/* Used to destroy a selector. */
int sel_free_selector(selector_t *new_selector);
-
/* A function to call when select sees something on a file
descriptor. */
typedef void (*sel_fd_handler_t)(int fd, void *data);
diff --git a/include/OpenIPMI/time_helpers.h b/include/OpenIPMI/time_helpers.h
new file mode 100644
index 0000000..ce2980e
--- /dev/null
+++ b/include/OpenIPMI/time_helpers.h
@@ -0,0 +1,3 @@
+#include <time.h>
+
+void time_get_monotonic_time(struct timeval *dest);
diff --git a/lanserv/Makefile.am b/lanserv/Makefile.am
index f3b00ce..df1457a 100644
--- a/lanserv/Makefile.am
+++ b/lanserv/Makefile.am
@@ -26,7 +26,7 @@ libIPMIlanserv_la_SOURCES = lanserv_ipmi.c lanserv_asf.c priv_table.c \
lanserv_oem_force.c lanserv_config.c
nodist_libIPMIlanserv_la_SOURCES = ../utils/ipmi_auth.c ../utils/md2.c \
../utils/md5.c
-libIPMIlanserv_la_LIBADD = $(OPENSSLLIBS)
+libIPMIlanserv_la_LIBADD = $(OPENSSLLIBS) $(top_builddir)/utils/libOpenIPMIutils.la
libIPMIlanserv_la_LDFLAGS = -version-info $(LD_VERSION) \
-Wl,-Map -Wl,libIPMIlanserv.map
@@ -37,7 +37,7 @@ ipmilan_LDADD = $(POPTLIBS) libIPMIlanserv.la
ipmilan_LDFLAGS = -rdynamic
lanserv_emu_SOURCES = lanserv_emu.c emu.c emu_cmd.c
-lanserv_emu_LDADD = $(POPTLIBS) libIPMIlanserv.la
+lanserv_emu_LDADD = $(POPTLIBS) libIPMIlanserv.la $(top_builddir)/utils/libOpenIPMIutils.la
lanserv_emu_LDFLAGS = -rdynamic
EXTRA_DIST = atca.emu README.emulator
diff --git a/lanserv/Makefile.in b/lanserv/Makefile.in
index d0220c7..05d9409 100644
--- a/lanserv/Makefile.in
+++ b/lanserv/Makefile.in
@@ -297,7 +297,7 @@ libIPMIlanserv_la_SOURCES = lanserv_ipmi.c lanserv_asf.c priv_table.c \
nodist_libIPMIlanserv_la_SOURCES = ../utils/ipmi_auth.c ../utils/md2.c \
../utils/md5.c
-libIPMIlanserv_la_LIBADD = $(OPENSSLLIBS)
+libIPMIlanserv_la_LIBADD = $(OPENSSLLIBS) $(top_builddir)/utils/libOpenIPMIutils.la
libIPMIlanserv_la_LDFLAGS = -version-info $(LD_VERSION) \
-Wl,-Map -Wl,libIPMIlanserv.map
@@ -306,7 +306,7 @@ ipmilan_SOURCES = lanserv.c
ipmilan_LDADD = $(POPTLIBS) libIPMIlanserv.la
ipmilan_LDFLAGS = -rdynamic
lanserv_emu_SOURCES = lanserv_emu.c emu.c emu_cmd.c
-lanserv_emu_LDADD = $(POPTLIBS) libIPMIlanserv.la
+lanserv_emu_LDADD = $(POPTLIBS) libIPMIlanserv.la $(top_builddir)/utils/libOpenIPMIutils.la
lanserv_emu_LDFLAGS = -rdynamic
EXTRA_DIST = atca.emu README.emulator
CLEANFILES = libIPMIlanserv.map
diff --git a/lanserv/emu.c b/lanserv/emu.c
index ed48b23..58e16bb 100644
--- a/lanserv/emu.c
+++ b/lanserv/emu.c
@@ -36,6 +36,7 @@
#include <sys/time.h>
#include <stdio.h>
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/ipmi_err.h>
#include <OpenIPMI/ipmi_msgbits.h>
#include <OpenIPMI/ipmi_picmg.h>
@@ -372,7 +373,7 @@ ipmi_mc_add_to_sel(lmc_data_t *mc,
mc->sel.next_entry++;
}
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
ipmi_set_uint16(e->data, e->record_id);
e->data[2] = record_type;
@@ -730,7 +731,7 @@ handle_clear_sel(lmc_data_t *mc,
}
}
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
mc->sel.last_erase_time = t.tv_sec + mc->sel.time_offset;
rdata[0] = 0;
@@ -750,7 +751,7 @@ handle_get_sel_time(lmc_data_t *mc,
return;
}
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
rdata[0] = 0;
ipmi_set_uint32(rdata+1, t.tv_sec + mc->sel.time_offset);
*rdata_len = 5;
@@ -772,7 +773,7 @@ handle_set_sel_time(lmc_data_t *mc,
if (check_msg_length(msg, 4, rdata, rdata_len))
return;
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
mc->sel.time_offset = ipmi_get_uint32(msg->data) - t.tv_sec;
rdata[0] = 0;
@@ -865,7 +866,7 @@ add_sdr_entry(lmc_data_t *mc, sdrs_t *sdrs, sdr_t *entry)
p->next = entry;
}
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
sdrs->last_add_time = t.tv_sec + mc->main_sdrs.time_offset;
sdrs->sdr_count++;
}
@@ -921,7 +922,7 @@ ipmi_mc_add_device_sdr(lmc_data_t *mc,
memcpy(entry->data+2, data+2, data_len-2);
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
mc->sensor_population_change_time = t.tv_sec + mc->main_sdrs.time_offset;
mc->lun_has_sensors[lun] = 1;
mc->num_sensors_per_lun[lun]++;
@@ -1307,7 +1308,7 @@ handle_delete_sdr(lmc_data_t *mc,
free_sdr(entry);
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
mc->main_sdrs.last_erase_time = t.tv_sec + mc->main_sdrs.time_offset;
mc->main_sdrs.sdr_count--;
}
@@ -1370,7 +1371,7 @@ handle_clear_sdr_repository(lmc_data_t *mc,
rdata[0] = 0;
*rdata_len = 2;
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
mc->main_sdrs.last_erase_time = t.tv_sec + mc->main_sdrs.time_offset;
}
@@ -1387,7 +1388,7 @@ handle_get_sdr_repository_time(lmc_data_t *mc,
return;
}
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
rdata[0] = 0;
ipmi_set_uint32(rdata+1, t.tv_sec + mc->main_sdrs.time_offset);
*rdata_len = 5;
@@ -1409,7 +1410,7 @@ handle_set_sdr_repository_time(lmc_data_t *mc,
if (check_msg_length(msg, 4, rdata, rdata_len))
return;
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
mc->main_sdrs.time_offset = ipmi_get_uint32(msg->data) - t.tv_sec;
rdata[0] = 0;
@@ -4095,7 +4096,7 @@ ipmi_emu_set_addr(emu_data_t *emu, unsigned int addr_num,
if (addr_len > sizeof(addr->addr_data))
return EINVAL;
- gettimeofday(&emu->last_addr_change_time, NULL);
+ time_get_monotonic_time(&emu->last_addr_change_time);
addr->addr_type = addr_type;
memcpy(addr->addr_data, addr_data, addr_len);
addr->addr_len = addr_len;
@@ -4221,7 +4222,7 @@ ipmi_emu_add_mc(emu_data_t *emu,
memcpy(mc->product_id, product_id, 2);
/* Start the time at zero. */
- gettimeofday(&t, NULL);
+ time_get_monotonic_time(&t);
mc->sel.time_offset = -t.tv_sec;
mc->main_sdrs.time_offset = -t.tv_sec;
mc->main_sdrs.next_entry = 1;
diff --git a/lib/ipmi_lan.c b/lib/ipmi_lan.c
index 74038f5..af10068 100644
--- a/lib/ipmi_lan.c
+++ b/lib/ipmi_lan.c
@@ -47,6 +47,7 @@
#include <netdb.h>
#include <arpa/inet.h>
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/ipmi_conn.h>
#include <OpenIPMI/ipmi_msgbits.h>
#include <OpenIPMI/ipmi_auth.h>
@@ -2410,7 +2411,7 @@ rsp_timeout_handler(void *cb_data,
if (lan->ip[ip_num].consecutive_failures == 0) {
/* Set the time when the connection will be considered
failed. */
- gettimeofday(&(lan->ip[ip_num].failure_time), NULL);
+ time_get_monotonic_time(&(lan->ip[ip_num].failure_time));
lan->ip[ip_num].failure_time.tv_sec += IP_FAIL_TIME / 1000000;
lan->ip[ip_num].failure_time.tv_usec += IP_FAIL_TIME % 1000000;
if (lan->ip[ip_num].failure_time.tv_usec > 1000000) {
@@ -2426,7 +2427,7 @@ rsp_timeout_handler(void *cb_data,
if (lan->ip[ip_num].consecutive_failures >= IP_FAIL_COUNT) {
struct timeval now;
ipmi_unlock(lan->ip_lock);
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
if (cmp_timeval(&now, &lan->ip[ip_num].failure_time) > 0)
{
/* Can't report yet, still holding locks. */
diff --git a/lib/mc.c b/lib/mc.c
index 93127fe..224846d 100644
--- a/lib/mc.c
+++ b/lib/mc.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <errno.h>
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/ipmiif.h>
#include <OpenIPMI/ipmi_sdr.h>
#include <OpenIPMI/ipmi_msgbits.h>
@@ -1949,7 +1950,7 @@ do_sel_time_set(ipmi_mc_t *mc, mc_reread_sel_t *info)
msg.cmd = IPMI_SET_SEL_TIME_CMD;
msg.data = data;
msg.data_len = 4;
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
ipmi_set_uint32(data, now.tv_sec);
mc->startup_SEL_time = ipmi_seconds_to_time(now.tv_sec);
rv = ipmi_mc_send_command(mc, 0, &msg, startup_set_sel_time, info);
@@ -2048,7 +2049,7 @@ startup_got_sel_time(ipmi_mc_t *mc,
goto out;
}
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
time = ipmi_get_uint32(rsp->data+1);
if ((time < (uint32_t)now.tv_sec) && ipmi_option_set_sel_time(mc->domain)) {
diff --git a/lib/oem_atca_conn.c b/lib/oem_atca_conn.c
index 2dd4ed1..53b8977 100644
--- a/lib/oem_atca_conn.c
+++ b/lib/oem_atca_conn.c
@@ -41,6 +41,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/ipmi_conn.h>
#include <OpenIPMI/ipmi_err.h>
#include <OpenIPMI/ipmi_msgbits.h>
@@ -209,7 +210,7 @@ fd_sock_handler(int fd, void *cb_data, os_hnd_fd_id_t *id)
ainfo->connected = 1;
ainfo->changed = 1;
}
- gettimeofday(&ainfo->last_pong_time, NULL);
+ time_get_monotonic_time(&ainfo->last_pong_time);
ainfo->dropped_pings = 0;
}
}
@@ -320,7 +321,7 @@ atca_check_and_ping(ipmi_con_t *ipmi, atca_conn_info_t *info)
struct timeval now;
unsigned int i;
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
data[0] = 0x06; /* RMCP version 1.0 */
data[1] = 0x00; /* reserved */
diff --git a/ui/ui.c b/ui/ui.c
index e4487fa..9f33e0e 100644
--- a/ui/ui.c
+++ b/ui/ui.c
@@ -44,6 +44,7 @@
#include <sys/time.h>
#include <ctype.h>
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/selector.h>
#include <OpenIPMI/ipmi_err.h>
#include <OpenIPMI/ipmi_msgbits.h>
@@ -5567,7 +5568,7 @@ addevent_cmd(char *cmd, char **toks, void *cb_data)
return 0;
}
- gettimeofday(&time, NULL);
+ time_get_monotonic_time(&time);
info.timestamp = time.tv_sec * 1000000000;
rv = ipmi_mc_pointer_noseq_cb(info.mc_id, addevent_cmder, &info);
@@ -6990,7 +6991,7 @@ redisplay_timeout(selector_t *sel,
rv);
}
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
now.tv_sec += 1;
rv = sel_start_timer(timer, &now);
if (rv)
@@ -7132,7 +7133,7 @@ ipmi_ui_init(selector_t **selector, int do_full_screen)
&redisplay_timer);
if (rv)
leave_err(rv, "sel_alloc_timer");
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
now.tv_sec += 1;
rv = sel_start_timer(redisplay_timer, &now);
if (rv)
diff --git a/unix/posix_os_hnd.c b/unix/posix_os_hnd.c
index f234bd5..8fd2f24 100644
--- a/unix/posix_os_hnd.c
+++ b/unix/posix_os_hnd.c
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/os_handler.h>
#include <OpenIPMI/selector.h>
#include <sys/types.h>
@@ -189,7 +190,7 @@ start_timer(os_handler_t *handler,
id->cb_data = cb_data;
id->timed_out = timed_out;
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
now.tv_sec += timeout->tv_sec;
now.tv_usec += timeout->tv_usec;
while (now.tv_usec >= 1000000) {
diff --git a/unix/posix_thread_os_hnd.c b/unix/posix_thread_os_hnd.c
index b52b1d2..5ba6166 100644
--- a/unix/posix_thread_os_hnd.c
+++ b/unix/posix_thread_os_hnd.c
@@ -51,6 +51,7 @@
#include <gdbm.h>
#endif
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/os_handler.h>
#include <OpenIPMI/selector.h>
#include <OpenIPMI/ipmi_posix.h>
@@ -200,7 +201,7 @@ start_timer(os_handler_t *handler,
id->cb_data = cb_data;
id->timed_out = timed_out;
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
now.tv_sec += timeout->tv_sec;
now.tv_usec += timeout->tv_usec;
while (now.tv_usec >= 1000000) {
@@ -511,7 +512,7 @@ cond_timedwait(os_handler_t *handler,
int old_lock_count;
pthread_t old_owner;
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
spec.tv_sec = timeout->tv_sec + now.tv_sec;
spec.tv_nsec = (timeout->tv_usec + now.tv_usec) * 1000;
while (spec.tv_nsec > 1000000000) {
diff --git a/unix/selector.c b/unix/selector.c
index 0792a46..6f4e0fd 100644
--- a/unix/selector.c
+++ b/unix/selector.c
@@ -38,6 +38,7 @@
things happen on those file descriptors this code will call
routines registered with it. */
+#include <OpenIPMI/time_helpers.h>
#include <OpenIPMI/selector.h>
#include <OpenIPMI/os_handler.h>
@@ -527,7 +528,7 @@ process_timers(selector_t *sel,
int called = 0;
timer = theap_get_top(&sel->timer_heap);
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
while (timer && cmp_timeval(&now, &timer->val.timeout) >= 0) {
called = 1;
theap_remove(&(sel->timer_heap), timer);
@@ -547,7 +548,7 @@ process_timers(selector_t *sel,
timeout->tv_sec = 0;
timeout->tv_usec = 0;
} else if (timer) {
- gettimeofday(&now, NULL);
+ time_get_monotonic_time(&now);
diff_timeval((struct timeval *) timeout,
(struct timeval *) &timer->val.timeout,
&now);
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 10f9b0d..d03f77a 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -14,7 +14,7 @@ AM_CFLAGS = -Wall -Wsign-compare -I$(top_srcdir)/include -DIPMI_CHECK_LOCKS
lib_LTLIBRARIES = libOpenIPMIutils.la
-libOpenIPMIutils_la_SOURCES = md5.c md2.c ipmi_auth.c \
+libOpenIPMIutils_la_SOURCES = time_helpers.c md5.c md2.c ipmi_auth.c \
ipmi_malloc.c ilist.c locks.c hash.c \
locked_list.c os_handler.c
libOpenIPMIutils_la_LDFLAGS = -rdynamic -version-info $(LD_VERSION) \
diff --git a/utils/Makefile.in b/utils/Makefile.in
index 71f516a..54106aa 100644
--- a/utils/Makefile.in
+++ b/utils/Makefile.in
@@ -57,7 +57,7 @@ am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libOpenIPMIutils_la_LIBADD =
-am_libOpenIPMIutils_la_OBJECTS = md5.lo md2.lo ipmi_auth.lo \
+am_libOpenIPMIutils_la_OBJECTS = md5.lo md2.lo time_helpers.lo ipmi_auth.lo \
ipmi_malloc.lo ilist.lo locks.lo hash.lo locked_list.lo \
os_handler.lo
libOpenIPMIutils_la_OBJECTS = $(am_libOpenIPMIutils_la_OBJECTS)
@@ -258,7 +258,7 @@ VERSION_AGE = $(wordlist 2, 2, $(SPACE_VERSION))
LD_VERSION = $(VERSION_CURRENT):$(VERSION_REVISION):$(VERSION_AGE)
AM_CFLAGS = -Wall -Wsign-compare -I$(top_srcdir)/include -DIPMI_CHECK_LOCKS
lib_LTLIBRARIES = libOpenIPMIutils.la
-libOpenIPMIutils_la_SOURCES = md5.c md2.c ipmi_auth.c \
+libOpenIPMIutils_la_SOURCES = md5.c time_helpers.c md2.c ipmi_auth.c \
ipmi_malloc.c ilist.c locks.c hash.c \
locked_list.c os_handler.c
@@ -342,6 +342,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/locked_list.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/locks.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_helpers.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_handler.Plo@am__quote@
diff --git a/utils/time_helpers.c b/utils/time_helpers.c
new file mode 100644
index 0000000..1670562
--- /dev/null
+++ b/utils/time_helpers.c
@@ -0,0 +1,14 @@
+#define _POSIX_C_SOURCE 199309L
+#include <sys/time.h>
+#include <time.h>
+
+void time_get_monotonic_time(struct timeval *dest)
+{
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+
+ dest->tv_sec = now.tv_sec; \
+ dest->tv_usec = now.tv_nsec / 1000;
+
+}
+
--
1.7.7.6
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60134071&iu=/4140/ostg.clktrk
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer