Hello community, here is the log from the commit of package OpenIPMI for openSUSE:Factory checked in at 2020-08-28 21:17:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/OpenIPMI (Old) and /work/SRC/openSUSE:Factory/.OpenIPMI.new.3399 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "OpenIPMI" Fri Aug 28 21:17:55 2020 rev:48 rq:828914 version:2.0.29 Changes: -------- --- /work/SRC/openSUSE:Factory/OpenIPMI/OpenIPMI.changes 2020-01-29 13:11:41.869964847 +0100 +++ /work/SRC/openSUSE:Factory/.OpenIPMI.new.3399/OpenIPMI.changes 2020-08-28 21:20:30.816299516 +0200 @@ -1,0 +2,6 @@ +Mon Aug 17 21:38:50 UTC 2020 - Dirk Mueller <dmuel...@suse.com> + +- update to 2.0.29: + * changelog not available + +------------------------------------------------------------------- Old: ---- OpenIPMI-2.0.28.tar.gz New: ---- OpenIPMI-2.0.29.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ OpenIPMI.spec ++++++ --- /var/tmp/diff_new_pack.VvynHX/_old 2020-08-28 21:20:31.676299933 +0200 +++ /var/tmp/diff_new_pack.VvynHX/_new 2020-08-28 21:20:31.680299936 +0200 @@ -1,7 +1,7 @@ # # spec file for package OpenIPMI # -# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -31,12 +31,12 @@ %endif Name: OpenIPMI -Version: 2.0.28 +Version: 2.0.29 Release: 0 Summary: Service processor access via IPMI License: LGPL-2.1-or-later Group: System/Monitoring -Url: http://openipmi.sourceforge.net +URL: http://openipmi.sourceforge.net Source0: http://prdownloads.sourceforge.net/openipmi/%{name}-%{version}.tar.gz Source1: sysconfig.ipmi Source2: ipmi.service ++++++ OpenIPMI-2.0.28.tar.gz -> OpenIPMI-2.0.29.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/OpenIPMI.spec new/OpenIPMI-2.0.29/OpenIPMI.spec --- old/OpenIPMI-2.0.28/OpenIPMI.spec 2019-12-12 17:40:07.000000000 +0100 +++ new/OpenIPMI-2.0.29/OpenIPMI.spec 2020-06-12 16:14:29.000000000 +0200 @@ -3,14 +3,14 @@ Name: OpenIPMI Summary: %{name} - Library interface to IPMI -Version: 2.0.27 +Version: 2.0.29 Release: 2 License: LGPL URL: http://openipmi.sourceforge.net Group: Utilities Vendor: OpenIPMI Project Packager: Tariq Shureih <tariq.shur...@intel.com> -Source: %{name}-2.0.28.tar.gz +Source: %{name}-2.0.29.tar.gz Buildroot: /var/tmp/%{name}-root BuildRequires: pkgconfig, perl >= 5, swig >= 1.3 Summary: IPMI Library diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/cmdlang/ipmish.c new/OpenIPMI-2.0.29/cmdlang/ipmish.c --- old/OpenIPMI-2.0.28/cmdlang/ipmish.c 2018-06-12 03:09:56.000000000 +0200 +++ new/OpenIPMI-2.0.29/cmdlang/ipmish.c 2019-12-16 15:31:11.000000000 +0100 @@ -51,6 +51,7 @@ #include <OpenIPMI/ipmi_cmdlang.h> #include <OpenIPMI/ipmi_debug.h> #include <readline/readline.h> +#include <readline/history.h> #ifdef HAVE_GLIB #include <glib.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/configure new/OpenIPMI-2.0.29/configure --- old/OpenIPMI-2.0.28/configure 2019-12-12 17:40:04.000000000 +0100 +++ new/OpenIPMI-2.0.29/configure 2020-06-12 16:14:25.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for OpenIPMI 2.0.28. +# Generated by GNU Autoconf 2.69 for OpenIPMI 2.0.29. # # Report bugs to <miny...@acm.org>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='OpenIPMI' PACKAGE_TARNAME='OpenIPMI' -PACKAGE_VERSION='2.0.28' -PACKAGE_STRING='OpenIPMI 2.0.28' +PACKAGE_VERSION='2.0.29' +PACKAGE_STRING='OpenIPMI 2.0.29' PACKAGE_BUGREPORT='miny...@acm.org' PACKAGE_URL='' @@ -1421,7 +1421,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures OpenIPMI 2.0.28 to adapt to many kinds of systems. +\`configure' configures OpenIPMI 2.0.29 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1493,7 +1493,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OpenIPMI 2.0.28:";; + short | recursive ) echo "Configuration of OpenIPMI 2.0.29:";; esac cat <<\_ACEOF @@ -1635,7 +1635,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OpenIPMI configure 2.0.28 +OpenIPMI configure 2.0.29 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2004,7 +2004,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by OpenIPMI $as_me 2.0.28, which was +It was created by OpenIPMI $as_me 2.0.29, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2977,7 +2977,7 @@ # Define the identity of the package. PACKAGE='OpenIPMI' - VERSION='2.0.28' + VERSION='2.0.29' cat >>confdefs.h <<_ACEOF @@ -4290,7 +4290,7 @@ OPENIPMI_VERSION_MINOR=0 -OPENIPMI_VERSION_RELEASE=27 +OPENIPMI_VERSION_RELEASE=29 @@ -15427,7 +15427,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by OpenIPMI $as_me 2.0.28, which was +This file was extended by OpenIPMI $as_me 2.0.29, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15493,7 +15493,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -OpenIPMI config.status 2.0.28 +OpenIPMI config.status 2.0.29 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/configure.ac new/OpenIPMI-2.0.29/configure.ac --- old/OpenIPMI-2.0.28/configure.ac 2019-12-12 17:39:40.000000000 +0100 +++ new/OpenIPMI-2.0.29/configure.ac 2020-06-12 16:14:21.000000000 +0200 @@ -1,5 +1,5 @@ OPENIPMI_PKG_NAME=OpenIPMI -AC_INIT([OpenIPMI], [2.0.28], [miny...@acm.org], [OpenIPMI]) +AC_INIT([OpenIPMI], [2.0.29], [miny...@acm.org], [OpenIPMI]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([-Wall]) AC_CONFIG_HEADER([config.h]) @@ -9,7 +9,7 @@ AC_SUBST(OPENIPMI_VERSION_MAJOR, 2) AC_SUBST(OPENIPMI_VERSION_MINOR, 0) -AC_SUBST(OPENIPMI_VERSION_RELEASE, 27) +AC_SUBST(OPENIPMI_VERSION_RELEASE, 29) AC_SUBST(OPENIPMI_VERSION_EXTRA, ) Binary files old/OpenIPMI-2.0.28/doc/IPMI.pdf and new/OpenIPMI-2.0.29/doc/IPMI.pdf differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/include/OpenIPMI/ipmiif.h new/OpenIPMI-2.0.29/include/OpenIPMI/ipmiif.h --- old/OpenIPMI-2.0.28/include/OpenIPMI/ipmiif.h 2019-12-12 17:40:07.000000000 +0100 +++ new/OpenIPMI-2.0.29/include/OpenIPMI/ipmiif.h 2020-06-12 16:14:29.000000000 +0200 @@ -47,7 +47,7 @@ /* For version detection */ #define OPENIPMI_VERSION_MAJOR 2 #define OPENIPMI_VERSION_MINOR 0 -#define OPENIPMI_VERSION_RELEASE 27 +#define OPENIPMI_VERSION_RELEASE 29 #define OPENIPMI_VERSION_EXTRA #define OPENIPMI_STRINGX(x) #x #define OPENIPMI_XSTRING(x) OPENIPMI_STRINGX(x) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/include/OpenIPMI/selector.h new/OpenIPMI-2.0.29/include/OpenIPMI/selector.h --- old/OpenIPMI-2.0.28/include/OpenIPMI/selector.h 2018-09-02 22:46:57.000000000 +0200 +++ new/OpenIPMI-2.0.29/include/OpenIPMI/selector.h 2020-03-01 20:41:03.000000000 +0100 @@ -51,8 +51,13 @@ /* You have to create a selector before you can use it. */ -/* Create a selector for use with threads. You have to pass in the - lock functions and a signal used to wake waiting threads. */ +/* + * Create a selector for use with threads. You have to pass in the + * lock functions and a signal used to wake waiting threads. + * + * Note that this function will block wake_sig in the calling thread, and you + * must have it blocked on all threads. + */ typedef struct sel_lock_s sel_lock_t; int sel_alloc_selector_thread(struct selector_s **new_selector, int wake_sig, sel_lock_t *(*sel_lock_alloc)(void *cb_data), @@ -69,7 +74,6 @@ /* Used to destroy a selector. */ int sel_free_selector(struct selector_s *new_selector); - /* A function to call when select sees something on a file descriptor. */ typedef void (*sel_fd_handler_t)(int fd, void *data); @@ -176,6 +180,17 @@ void *cb_data, struct timeval *timeout); +/* + * Like the above call, but allows the user to install their own sigmask + * while waiting. + */ +int sel_select_intr_sigmask(struct selector_s *sel, + sel_send_sig_cb send_sig, + long thread_id, + void *cb_data, + struct timeval *timeout, + sigset_t *sigmask); + /* This is the main loop for the program. If NULL is passed in to send_sig, then the signal sender is not used. If this encounters an unrecoverable problem with select(), it will return the errno. @@ -212,6 +227,13 @@ int sel_alloc_selector(os_handler_t *os_hnd, struct selector_s **new_selector) IPMI_FUNC_DEPRECATED; +/* + * If you fork and expect to use the selector in the forked process, + * you *must* call this function in the forked process or you may + * get strange results. + */ +int sel_setup_forked_process(struct selector_s *sel); + #ifdef __cplusplus } #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/OpenIPMI/mcserv.h new/OpenIPMI-2.0.29/lanserv/OpenIPMI/mcserv.h --- old/OpenIPMI-2.0.28/lanserv/OpenIPMI/mcserv.h 2017-09-19 22:23:47.000000000 +0200 +++ new/OpenIPMI-2.0.29/lanserv/OpenIPMI/mcserv.h 2019-12-18 14:40:18.000000000 +0100 @@ -345,6 +345,13 @@ #define OPENIPMI_IANA_CMD_GET_HISTORY_RETURN_SIZE 2 /* + * Registration for group extensions + */ +void ipmi_emu_register_group_extension_handler(uint8_t group_extension, + cmd_handler_f handler, + void *cb_data); + +/* * SOL handling */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/bmc.c new/OpenIPMI-2.0.29/lanserv/bmc.c --- old/OpenIPMI-2.0.28/lanserv/bmc.c 2019-11-13 13:37:58.000000000 +0100 +++ new/OpenIPMI-2.0.29/lanserv/bmc.c 2019-12-18 14:48:53.000000000 +0100 @@ -71,6 +71,19 @@ return PVERSION; } +struct { + cmd_handler_f handler; + void *cb_data; +} group_extension_handlers[256]; + +void +ipmi_emu_register_group_extension_handler(uint8_t group_extension, + cmd_handler_f handler, void *cb_data) +{ + group_extension_handlers[group_extension].handler = handler; + group_extension_handlers[group_extension].cb_data = cb_data; +} + static void handle_group_extension_netfn(lmc_data_t *mc, msg_t *msg, @@ -78,21 +91,17 @@ unsigned int *rdata_len, void *cb_data) { + uint8_t ge; + if (check_msg_length(msg, 1, rdata, rdata_len)) return; - switch (msg->data[0]) { - case IPMI_PICMG_GRP_EXT: - if (mc->emu->atca_mode) - handle_picmg_msg(mc, msg, rdata, rdata_len); - else - handle_invalid_cmd(mc, rdata, rdata_len); - break; - - default: + ge = msg->data[0]; + if (group_extension_handlers[ge].handler) + group_extension_handlers[ge].handler(mc, msg, rdata, rdata_len, + group_extension_handlers[ge].cb_data); + else handle_invalid_cmd(mc, rdata, rdata_len); - break; - } } static struct iana_handler_elem { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/bmc.h new/OpenIPMI-2.0.29/lanserv/bmc.h --- old/OpenIPMI-2.0.28/lanserv/bmc.h 2017-09-19 01:12:49.000000000 +0200 +++ new/OpenIPMI-2.0.29/lanserv/bmc.h 2019-12-18 14:45:05.000000000 +0100 @@ -425,11 +425,6 @@ extern cmd_handler_f sensor_event_netfn_handlers[256]; extern cmd_handler_f oem0_netfn_handlers[256]; -void handle_picmg_msg(lmc_data_t *mc, - msg_t *msg, - unsigned char *rdata, - unsigned int *rdata_len); - #define set_bit(m, b, v) (m) = (v) ? ((m) | (1 << (b))) : ((m) & ~(1 << (b))) #define bit_set(m, b) (!!((m) & (1 << (b)))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/bmc_picmg.c new/OpenIPMI-2.0.29/lanserv/bmc_picmg.c --- old/OpenIPMI-2.0.28/lanserv/bmc_picmg.c 2017-02-17 14:39:52.000000000 +0100 +++ new/OpenIPMI-2.0.29/lanserv/bmc_picmg.c 2019-12-18 14:45:23.000000000 +0100 @@ -1062,10 +1062,18 @@ *rdata_len = 10 + ap->addr_len; } +void handle_picmg_msg(lmc_data_t *mc, + msg_t *msg, + unsigned char *rdata, + unsigned int *rdata_len, + void *cb_data); + int ipmi_emu_atca_enable(emu_data_t *emu) { emu->atca_mode = 1; + ipmi_emu_register_group_extension_handler(IPMI_PICMG_GRP_EXT, + handle_picmg_msg, NULL); return 0; } @@ -1089,7 +1097,8 @@ handle_picmg_msg(lmc_data_t *mc, msg_t *msg, unsigned char *rdata, - unsigned int *rdata_len) + unsigned int *rdata_len, + void *cb_data) { switch(msg->cmd) { case IPMI_PICMG_CMD_GET_PROPERTIES: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/ipmi_sim.c new/OpenIPMI-2.0.29/lanserv/ipmi_sim.c --- old/OpenIPMI-2.0.28/lanserv/ipmi_sim.c 2019-08-02 03:03:27.000000000 +0200 +++ new/OpenIPMI-2.0.29/lanserv/ipmi_sim.c 2020-04-28 20:10:10.000000000 +0200 @@ -678,7 +678,7 @@ #define mformat " channel=%d netfn=0x%x cmd=0x%x rs_addr=0x%x rs_lun=0x%x" \ " rq_addr=0x%x\n rq_lun=0x%x rq_seq=0x%x\n" - len += snprintf(&dummy, 1, mformat, msg->channel, msg->netfn, + len += snprintf(&dummy, 0, mformat, msg->channel, msg->netfn, msg->cmd, msg->rs_addr, msg->rs_lun, msg->rq_addr, msg->rq_lun, msg->rq_seq); len += 3 * msg->len + 3; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/lanserv.c new/OpenIPMI-2.0.29/lanserv/lanserv.c --- old/OpenIPMI-2.0.28/lanserv/lanserv.c 2017-09-19 22:26:47.000000000 +0200 +++ new/OpenIPMI-2.0.29/lanserv/lanserv.c 2020-04-28 20:10:28.000000000 +0200 @@ -441,7 +441,7 @@ #define mformat " channel=%d netfn=0x%x cmd=0x%x rs_addr=0x%x rs_lun=0x%x" \ " rq_addr=0x%x\n rq_lun=0x%x rq_seq=0x%x\n" - len += snprintf(&dummy, 1, mformat, msg->channel, msg->netfn, + len += snprintf(&dummy, 0, mformat, msg->channel, msg->netfn, msg->cmd, msg->rs_addr, msg->rs_lun, msg->rq_addr, msg->rq_lun, msg->rq_seq); len += 3 * msg->len + 3; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/lanserv_ipmi.c new/OpenIPMI-2.0.29/lanserv/lanserv_ipmi.c --- old/OpenIPMI-2.0.28/lanserv/lanserv_ipmi.c 2019-05-16 00:00:39.000000000 +0200 +++ new/OpenIPMI-2.0.29/lanserv/lanserv_ipmi.c 2020-04-28 20:09:18.000000000 +0200 @@ -248,7 +248,7 @@ "Raw LAN send to:"); for (i = 0; i < vecs; i++) len += vec[i].iov_len; - slen = snprintf(&dummy, 1, format); + slen = snprintf(&dummy, 0, format); slen += len * 3 + 3; str = malloc(slen); if (!str) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lanserv/serv.c new/OpenIPMI-2.0.29/lanserv/serv.c --- old/OpenIPMI-2.0.28/lanserv/serv.c 2018-10-24 15:27:45.000000000 +0200 +++ new/OpenIPMI-2.0.29/lanserv/serv.c 2020-04-28 20:09:40.000000000 +0200 @@ -251,8 +251,8 @@ gettimeofday(&tv, NULL); va_start(ap, format); - slen = vsnprintf(&dummy, 1, format, ap); - slen += snprintf(&dummy, 1, " %ld.%6.6ld", tv.tv_sec, tv.tv_usec); + slen = vsnprintf(&dummy, 0, format, ap); + slen += snprintf(&dummy, 0, " %ld.%6.6ld", tv.tv_sec, tv.tv_usec); va_end(ap); slen += len * 3 + 2; str = malloc(slen); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lib/conn.c new/OpenIPMI-2.0.29/lib/conn.c --- old/OpenIPMI-2.0.28/lib/conn.c 2017-08-04 23:01:27.000000000 +0200 +++ new/OpenIPMI-2.0.29/lib/conn.c 2020-04-28 19:54:45.000000000 +0200 @@ -269,7 +269,6 @@ { conn_check_oem_t *check; int rv; - unsigned int count = 0; check = ipmi_mem_alloc(sizeof(*check)); if (!check) @@ -285,10 +284,6 @@ locked_list_iterate(oem_handlers, conn_handler_call, check); - ipmi_lock(check->lock); - count = check->count; - ipmi_unlock(check->lock); - /* Say that this function is done with the check. */ conn_oem_check_done(conn, check); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lib/ipmi.c new/OpenIPMI-2.0.29/lib/ipmi.c --- old/OpenIPMI-2.0.28/lib/ipmi.c 2018-11-19 17:45:40.000000000 +0100 +++ new/OpenIPMI-2.0.29/lib/ipmi.c 2020-04-28 20:03:59.000000000 +0200 @@ -429,6 +429,7 @@ int i_ipmi_smi_init(os_handler_t *os_hnd); int i_ipmi_lan_init(os_handler_t *os_hnd); int ipmi_malloc_init(os_handler_t *os_hnd); +void ipmi_malloc_shutdown(void); int i_ipmi_rakp_init(void); int i_ipmi_aes_cbc_init(void); int i_ipmi_hmac_init(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/lib/ipmi_smi.c new/OpenIPMI-2.0.29/lib/ipmi_smi.c --- old/OpenIPMI-2.0.28/lib/ipmi_smi.c 2019-01-21 00:14:27.000000000 +0100 +++ new/OpenIPMI-2.0.29/lib/ipmi_smi.c 2020-04-28 20:04:44.000000000 +0200 @@ -1644,7 +1644,7 @@ " would be 0. This is an integer value."; if (*value) { int len; - len = snprintf(dummy, 1, "%d", sargs->ifnum); + len = snprintf(dummy, 0, "%d", sargs->ifnum); sval = ipmi_mem_alloc(len+1); if (! sval) return ENOMEM; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/sample/eventd.c new/OpenIPMI-2.0.29/sample/eventd.c --- old/OpenIPMI-2.0.28/sample/eventd.c 2019-01-05 06:05:55.000000000 +0100 +++ new/OpenIPMI-2.0.29/sample/eventd.c 2020-04-28 20:04:26.000000000 +0200 @@ -732,8 +732,12 @@ /* * We have to daemonize before we fork or sigchld won't work. */ - if (daemonize) - daemon(0, 0); + if (daemonize) { + if (daemon(0, 0) == -1) { + perror("Call to daemonize failed"); + exit(1); + } + } if (execnow) { int infd = newpipe(&outfile); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/sample/ipmi_serial_bmc_emu.c new/OpenIPMI-2.0.29/sample/ipmi_serial_bmc_emu.c --- old/OpenIPMI-2.0.28/sample/ipmi_serial_bmc_emu.c 2019-08-22 18:46:55.000000000 +0200 +++ new/OpenIPMI-2.0.29/sample/ipmi_serial_bmc_emu.c 2019-12-16 15:31:11.000000000 +0100 @@ -43,6 +43,7 @@ #include <stdlib.h> #include <sys/select.h> #include <readline/readline.h> +#include <readline/history.h> #define _GNU_SOURCE #include <getopt.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/unix/selector.c new/OpenIPMI-2.0.29/unix/selector.c --- old/OpenIPMI-2.0.28/unix/selector.c 2018-09-02 22:46:57.000000000 +0200 +++ new/OpenIPMI-2.0.29/unix/selector.c 2020-03-01 21:06:28.000000000 +0100 @@ -173,10 +173,6 @@ sel_send_sig_cb send_sig; void *send_sig_cb_data; - /* This is the memory used to hold the timeout for select - operation. */ - volatile struct timeval *timeout; - struct sel_wait_list_s *next, *prev; } sel_wait_list_t; @@ -196,6 +192,11 @@ volatile int maxfd; /* The largest file descriptor registered with this code. */ + /* If something is deleted, we increment this count. This way when + a select/epoll returns a non-timeout, we know that we need to ignore + it as it may be from the just deleted fd. */ + unsigned long fd_del_count; + void *fd_lock; /* The timer heap. */ @@ -268,8 +269,6 @@ item = sel->wait_list.next; while (item != &sel->wait_list) { - item->timeout->tv_sec = 0; - item->timeout->tv_usec = 0; if (item->send_sig) item->send_sig(item->thread_id, item->send_sig_cb_data); item = item->next; @@ -285,13 +284,6 @@ } static void -wake_fd_sel_thread(struct selector_s *sel) -{ - sel_wake_all(sel); - sel_fd_unlock(sel); -} - -static void wake_timer_sel_thread(struct selector_s *sel, volatile sel_timer_t *old_top) { if (old_top != theap_get_top(&sel->timer_heap)) @@ -306,10 +298,9 @@ add_sel_wait_list(struct selector_s *sel, sel_wait_list_t *item, sel_send_sig_cb send_sig, void *cb_data, - long thread_id, volatile struct timeval *timeout) + long thread_id) { item->thread_id = thread_id; - item->timeout = timeout; item->send_sig = send_sig; item->send_sig_cb_data = cb_data; item->next = sel->wait_list.next; @@ -337,10 +328,11 @@ #ifdef HAVE_EPOLL_PWAIT static int -sel_update_epoll(struct selector_s *sel, int fd, int op, int read_enable) +sel_update_fd(struct selector_s *sel, int fd, int op) { fd_control_t *fdc = (fd_control_t *) &sel->fds[fd]; struct epoll_event event; + int rv; if (sel->epollfd < 0) return 1; @@ -349,11 +341,17 @@ event.events = EPOLLONESHOT; event.data.fd = fd; if (fdc->saved_events) { - if (!read_enable) + if (op == EPOLL_CTL_DEL) return 0; + if (!FD_ISSET(fd, &sel->read_set) && !FD_ISSET(fd, &sel->except_set)) + return 0; + fdc->saved_events = 0; op = EPOLL_CTL_ADD; - event.events = EPOLLIN | EPOLLHUP; - } else { + if (FD_ISSET(fd, &sel->read_set)) + event.events |= EPOLLIN | EPOLLHUP; + if (FD_ISSET(fd, &sel->except_set)) + event.events |= EPOLLERR | EPOLLPRI; + } else if (op != EPOLL_CTL_DEL) { if (FD_ISSET(fd, &sel->read_set)) event.events |= EPOLLIN | EPOLLHUP; if (FD_ISSET(fd, &sel->write_set)) @@ -361,12 +359,18 @@ if (FD_ISSET(fd, &sel->except_set)) event.events |= EPOLLERR | EPOLLPRI; } - epoll_ctl(sel->epollfd, op, fd, &event); + /* This should only fail due to system problems, and if that's the case, + well, we should probably terminate. */ + rv = epoll_ctl(sel->epollfd, op, fd, &event); + if (rv) { + perror("epoll_ctl"); + assert(0); + } return 0; } #else static int -sel_update_epoll(struct selector_s *sel, int fd, int op, int dummy) +sel_update_fd(struct selector_s *sel, int fd, int op) { return 1; } @@ -411,6 +415,10 @@ oldstate = fdc->state; olddata = fdc->data; added = 0; +#ifdef HAVE_EPOLL_PWAIT + fdc->saved_events = 0; +#endif + sel->fd_del_count++; } fdc->state = state; fdc->data = data; @@ -424,14 +432,14 @@ sel->maxfd = fd; } - if (sel_update_epoll(sel, fd, EPOLL_CTL_ADD, 0)) { - wake_fd_sel_thread(sel); - goto out; - } + if (sel_update_fd(sel, fd, EPOLL_CTL_ADD)) + sel_wake_all(sel); + } else { + if (sel_update_fd(sel, fd, EPOLL_CTL_MOD)) + sel_wake_all(sel); } sel_fd_unlock(sel); - out: if (oldstate) { oldstate->deleted = 1; if (oldstate->use_count == 0) { @@ -458,8 +466,11 @@ olddata = fdc->data; fdc->state = NULL; - sel_update_epoll(sel, fd, EPOLL_CTL_DEL, 0); + sel_update_fd(sel, fd, EPOLL_CTL_DEL); +#ifdef HAVE_EPOLL_PWAIT fdc->saved_events = 0; +#endif + sel->fd_del_count++; } init_fd(fdc); @@ -526,11 +537,8 @@ goto out; FD_CLR(fd, &sel->read_set); } - if (sel_update_epoll(sel, fd, EPOLL_CTL_MOD, - state == SEL_FD_HANDLER_ENABLED)) { - wake_fd_sel_thread(sel); - return; - } + if (sel_update_fd(sel, fd, EPOLL_CTL_MOD)) + sel_wake_all(sel); out: sel_fd_unlock(sel); @@ -556,10 +564,8 @@ goto out; FD_CLR(fd, &sel->write_set); } - if (sel_update_epoll(sel, fd, EPOLL_CTL_MOD, 0)) { - wake_fd_sel_thread(sel); - return; - } + if (sel_update_fd(sel, fd, EPOLL_CTL_MOD)) + sel_wake_all(sel); out: sel_fd_unlock(sel); @@ -585,10 +591,8 @@ goto out; FD_CLR(fd, &sel->except_set); } - if (sel_update_epoll(sel, fd, EPOLL_CTL_MOD, 0)) { - wake_fd_sel_thread(sel); - return; - } + if (sel_update_fd(sel, fd, EPOLL_CTL_MOD)) + sel_wake_all(sel); out: sel_fd_unlock(sel); @@ -653,6 +657,24 @@ return 0; } +static int +sel_stop_timer_i(struct selector_s *sel, sel_timer_t *timer) +{ + if (timer->val.stopped) + return ETIMEDOUT; + + if (timer->val.in_heap) { + volatile sel_timer_t *old_top = theap_get_top(&sel->timer_heap); + + theap_remove(&sel->timer_heap, timer); + timer->val.in_heap = 0; + wake_timer_sel_thread(sel, old_top); + } + timer->val.stopped = 1; + + return 0; +} + int sel_free_timer(sel_timer_t *timer) { @@ -660,9 +682,8 @@ int in_handler; sel_timer_lock(sel); - if (timer->val.in_heap) { - sel_stop_timer(timer); - } + if (timer->val.in_heap) + sel_stop_timer_i(sel, timer); timer->val.freed = 1; in_handler = timer->val.in_handler; sel_timer_unlock(sel); @@ -708,25 +729,13 @@ sel_stop_timer(sel_timer_t *timer) { struct selector_s *sel = timer->val.sel; + int rv; sel_timer_lock(sel); - if (timer->val.stopped) { - sel_timer_unlock(sel); - return ETIMEDOUT; - } - - if (timer->val.in_heap) { - volatile sel_timer_t *old_top = theap_get_top(&sel->timer_heap); - - theap_remove(&sel->timer_heap, timer); - timer->val.in_heap = 0; - wake_timer_sel_thread(sel, old_top); - } - timer->val.stopped = 1; - + rv = sel_stop_timer_i(sel, timer); sel_timer_unlock(sel); - return 0; + return rv; } int @@ -737,7 +746,11 @@ struct selector_s *sel = timer->val.sel; sel_timer_lock(sel); - if (timer->val.stopped || timer->val.done_handler) { + if (timer->val.done_handler) { + sel_timer_unlock(sel); + return EBUSY; + } + if (timer->val.stopped) { sel_timer_unlock(sel); return ETIMEDOUT; } @@ -966,6 +979,20 @@ } } +static void +setup_my_sigmask(sigset_t *sigmask, sigset_t *isigmask) +{ + if (isigmask) { + *sigmask = *isigmask; + } else { +#ifdef USE_PTHREADS + pthread_sigmask(SIG_SETMASK, NULL, sigmask); +#else + sigprocmask(SIG_SETMASK, NULL, sigmask); +#endif + } +} + /* * return == 0 when timeout * > 0 when successful @@ -973,7 +1000,8 @@ */ static int process_fds(struct selector_s *sel, - volatile struct timeval *timeout) + volatile struct timeval *timeout, + sigset_t *isigmask) { fd_set tmp_read_set; fd_set tmp_write_set; @@ -981,7 +1009,13 @@ int i; int err; int num_fds; + sigset_t sigmask; + struct timespec ts = { .tv_sec = timeout->tv_sec, + .tv_nsec = timeout->tv_usec * 1000 }; + unsigned long entry_fd_del_count = sel->fd_del_count; + setup_my_sigmask(&sigmask, isigmask); + retry: sel_fd_lock(sel); memcpy(&tmp_read_set, (void *) &sel->read_set, sizeof(tmp_read_set)); memcpy(&tmp_write_set, (void *) &sel->write_set, sizeof(tmp_write_set)); @@ -989,16 +1023,25 @@ num_fds = sel->maxfd+1; sel_fd_unlock(sel); - err = select(num_fds, - &tmp_read_set, - &tmp_write_set, - &tmp_except_set, - (struct timeval *) timeout); - if (err <= 0) + sigdelset(&sigmask, sel->wake_sig); + err = pselect(num_fds, + &tmp_read_set, + &tmp_write_set, + &tmp_except_set, + &ts, &sigmask); + if (err < 0) { + if (errno == EBADF || errno == EBADFD) + /* We raced, just retry it. */ + goto retry; goto out; + } /* We got some I/O. */ sel_fd_lock(sel); + if (entry_fd_del_count != sel->fd_del_count) + /* Something was deleted from the FD set, don't process this as it + may be from the old fd wakeup. */ + goto out_unlock; for (i = 0; i <= sel->maxfd; i++) { if (FD_ISSET(i, &tmp_read_set)) handle_selector_call(sel, i, &sel->read_set, @@ -1010,6 +1053,7 @@ handle_selector_call(sel, i, &sel->except_set, sel->fds[i].handle_except); } + out_unlock: sel_fd_unlock(sel); out: return err; @@ -1017,13 +1061,17 @@ #ifdef HAVE_EPOLL_PWAIT static int -process_fds_epoll(struct selector_s *sel, struct timeval *tvtimeout) +process_fds_epoll(struct selector_s *sel, struct timeval *tvtimeout, + sigset_t *isigmask) { int rv, fd; struct epoll_event event; int timeout; sigset_t sigmask; fd_control_t *fdc; + unsigned long entry_fd_del_count = sel->fd_del_count; + + setup_my_sigmask(&sigmask, isigmask); if (tvtimeout->tv_sec > 600) /* Don't wait over 10 minutes, to work around an old epoll bug @@ -1034,20 +1082,18 @@ timeout = ((tvtimeout->tv_sec * 1000) + (tvtimeout->tv_usec + 999) / 1000); -#ifdef USE_PTHREADS - pthread_sigmask(SIG_SETMASK, NULL, &sigmask); -#else - sigprocmask(SIG_SETMASK, NULL, &sigmask); -#endif sigdelset(&sigmask, sel->wake_sig); rv = epoll_pwait(sel->epollfd, &event, 1, timeout, &sigmask); - if (rv <= 0) return rv; sel_fd_lock(sel); fd = event.data.fd; fdc = (fd_control_t *) &sel->fds[fd]; + if (entry_fd_del_count != sel->fd_del_count) + /* Something was deleted from the FD set, don't process this as it + may be from the old fd wakeup. */ + goto rearm; if (event.events & (EPOLLHUP | EPOLLERR)) { /* * The crazy people that designed epoll made it so that EPOLLHUP @@ -1059,8 +1105,13 @@ * EPOLLHUP or EPOLLERR, anyway, and then doing the callback * by hand. */ - sel_update_epoll(sel, fd, EPOLL_CTL_DEL, 0); + sel_update_fd(sel, fd, EPOLL_CTL_DEL); fdc->saved_events = event.events & (EPOLLHUP | EPOLLERR); + /* + * Have it handle read data, too, so if there is a pending + * error it will get handled. + */ + event.events |= EPOLLIN; } if (event.events & (EPOLLIN | EPOLLHUP)) handle_selector_call(sel, fd, &sel->read_set, fdc->handle_read); @@ -1069,27 +1120,62 @@ if (event.events & (EPOLLPRI | EPOLLERR)) handle_selector_call(sel, fd, &sel->except_set, fdc->handle_except); + rearm: /* Rearm the event. Remember it could have been deleted in the handler. */ if (fdc->state) - sel_update_epoll(sel, fd, EPOLL_CTL_MOD, 0); + sel_update_fd(sel, fd, EPOLL_CTL_MOD); sel_fd_unlock(sel); return rv; } + +int +sel_setup_forked_process(struct selector_s *sel) +{ + int i; + + /* + * More epoll stupidity. In a forked process we must create a new + * epoll because the epoll state is shared between a parent and a + * child. If it worked like it should, each epoll instance would + * be independent. If you don't do this, disabling an fd in the + * child disables the parent, too, and vice versa. + */ + close(sel->epollfd); + sel->epollfd = epoll_create(32768); + if (sel->epollfd == -1) { + return errno; + } + + for (i = 0; i <= sel->maxfd; i++) { + volatile fd_control_t *fdc = &sel->fds[i]; + if (fdc->state) + sel_update_fd(sel, i, EPOLL_CTL_ADD); + } + return 0; +} +#else +int +sel_setup_forked_process(struct selector_s *sel) +{ + /* Nothing to do. */ + return 0; +} #endif int -sel_select_intr(struct selector_s *sel, - sel_send_sig_cb send_sig, - long thread_id, - void *cb_data, - struct timeval *timeout) +sel_select_intr_sigmask(struct selector_s *sel, + sel_send_sig_cb send_sig, + long thread_id, + void *cb_data, + struct timeval *timeout, + sigset_t *sigmask) { int err, old_errno; struct timeval loc_timeout = { 0, 0 }; sel_wait_list_t wait_entry; unsigned int count; - struct timeval end, now; + struct timeval end = { 0, 0 }, now; int user_timeout = 0; if (timeout) { @@ -1099,24 +1185,22 @@ sel_timer_lock(sel); count = process_runners(sel); - /* If count is non-zero or any timers are processed, timeout is set to 0. */ - process_timers(sel, &count, (struct timeval *)(&loc_timeout)); + process_timers(sel, &count, &loc_timeout); if (timeout) { - if (cmp_timeval((struct timeval *)(&loc_timeout), timeout) >= 0) { + if (cmp_timeval(&loc_timeout, timeout) >= 0) { loc_timeout = *timeout; user_timeout = 1; } } - add_sel_wait_list(sel, &wait_entry, send_sig, cb_data, thread_id, - &loc_timeout); + add_sel_wait_list(sel, &wait_entry, send_sig, cb_data, thread_id); sel_timer_unlock(sel); #ifdef HAVE_EPOLL_PWAIT if (sel->epollfd >= 0) - err = process_fds_epoll(sel, &loc_timeout); + err = process_fds_epoll(sel, &loc_timeout, sigmask); else #endif - err = process_fds(sel, &loc_timeout); + err = process_fds(sel, &loc_timeout, sigmask); old_errno = errno; if (!user_timeout && !err) { @@ -1146,6 +1230,17 @@ } int +sel_select_intr(struct selector_s *sel, + sel_send_sig_cb send_sig, + long thread_id, + void *cb_data, + struct timeval *timeout) +{ + return sel_select_intr_sigmask(sel, send_sig, thread_id, cb_data, timeout, + NULL); +} + +int sel_select(struct selector_s *sel, sel_send_sig_cb send_sig, long thread_id, @@ -1154,7 +1249,8 @@ { int err; - err = sel_select_intr(sel, send_sig, thread_id, cb_data, timeout); + err = sel_select_intr_sigmask(sel, send_sig, thread_id, cb_data, timeout, + NULL); if (err < 0 && errno == EINTR) /* * If we get an EINTR, we don't want to report a timeout. Just @@ -1198,6 +1294,8 @@ { struct selector_s *sel; unsigned int i; + int rv; + sigset_t sigset; sel = malloc(sizeof(*sel)); if (!sel) @@ -1239,28 +1337,23 @@ } } -#ifdef HAVE_EPOLL_PWAIT - sel->epollfd = epoll_create(32768); - if (sel->epollfd == -1) { - syslog(LOG_ERR, "Unable to set up epoll, falling back to select: %m"); - } else { - int rv; - sigset_t sigset; - - sigemptyset(&sigset); - sigaddset(&sigset, wake_sig); - rv = sigprocmask(SIG_BLOCK, &sigset, NULL); - if (rv == -1) { - rv = errno; - close(sel->epollfd); - if (sel->sel_lock_alloc) { - sel->sel_lock_free(sel->fd_lock); + sigemptyset(&sigset); + sigaddset(&sigset, wake_sig); + rv = sigprocmask(SIG_BLOCK, &sigset, NULL); + if (rv == -1) { + rv = errno; + if (sel->sel_lock_alloc) { + sel->sel_lock_free(sel->fd_lock); sel->sel_lock_free(sel->timer_lock); - } - free(sel); - return rv; } + free(sel); + return rv; } + +#ifdef HAVE_EPOLL_PWAIT + sel->epollfd = epoll_create(32768); + if (sel->epollfd == -1) + syslog(LOG_ERR, "Unable to set up epoll, falling back to select: %m"); #endif *new_selector = sel; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OpenIPMI-2.0.28/unix/test_handlers.c new/OpenIPMI-2.0.29/unix/test_handlers.c --- old/OpenIPMI-2.0.28/unix/test_handlers.c 2016-12-15 23:03:27.000000000 +0100 +++ new/OpenIPMI-2.0.29/unix/test_handlers.c 2020-04-28 20:02:50.000000000 +0200 @@ -135,7 +135,6 @@ struct timeval *then = cb_data; struct timeval now; struct timeval diff; - int rv; fprintf(stderr, "Timeout!\n"); test_os_hnd->get_monotonic_time(test_os_hnd, &now); @@ -148,8 +147,8 @@ diff.tv_sec = 0; diff.tv_usec = 500000; *then = now; - rv = test_os_hnd->start_timer(test_os_hnd, id, &diff, - timeout_handler, then); + test_os_hnd->start_timer(test_os_hnd, id, &diff, + timeout_handler, then); } else if (expect_timeout == 1) { expect_timeout++; if (diff.tv_sec != 0)