From 5bb3bea07b0ff38e4646ed6f835d9bdac6beced6 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Thu, 3 Aug 2017 14:51:41 +0200 Subject: build: Add check for robust mutexes This adds a check for robust mutexes. The constant HAVE_ROBUST_MUTEX is set accordingly in config.h. It also adds some other fixes to make the prototype compile on the Hurd. --- CMakeLists.txt | 6 ++++++ include/ouroboros/config.h.in | 1 + include/ouroboros/endian.h | 2 +- src/ipcpd/CMakeLists.txt | 2 +- src/lib/CMakeLists.txt | 3 +-- src/lib/shm_flow_set.c | 6 +++--- src/lib/shm_rbuff_ll.c | 10 +++++----- src/lib/shm_rbuff_pthr.c | 20 ++++++++++---------- src/lib/shm_rdrbuff.c | 14 +++++++------- src/lib/tests/time_utils_test.c | 4 ++-- 10 files changed, 37 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c7266eb..85040496 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,12 @@ add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) find_package(ProtobufC REQUIRED) include_directories(${PROTOBUF_C_INCLUDE_DIRS}) +include(CheckSymbolExists) +list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200809L) +list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__XSI_VISIBLE=500) +list(APPEND CMAKE_REQUIRED_LIBRARIES pthread) +check_symbol_exists(pthread_mutexattr_setrobust pthread.h HAVE_ROBUST_MUTEX) + add_subdirectory(src) add_subdirectory(include) add_subdirectory(doc) diff --git a/include/ouroboros/config.h.in b/include/ouroboros/config.h.in index e8341ee2..4c255da5 100644 --- a/include/ouroboros/config.h.in +++ b/include/ouroboros/config.h.in @@ -36,6 +36,7 @@ #define IPCP_SHIM_ETH_LLC_EXEC "@IPCP_SHIM_ETH_LLC_TARGET@" #define IPCP_NORMAL_EXEC "@IPCP_NORMAL_TARGET@" #define IPCP_LOCAL_EXEC "@IPCP_LOCAL_TARGET@" +#cmakedefine HAVE_ROBUST_MUTEX #define AP_MAX_FLOWS 2048 #define AP_RES_FDS 64 #define AP_MAX_FQUEUES 64 diff --git a/include/ouroboros/endian.h b/include/ouroboros/endian.h index 16200028..873aff73 100644 --- a/include/ouroboros/endian.h +++ b/include/ouroboros/endian.h @@ -24,7 +24,7 @@ #ifndef OUROBOROS_ENDIAN_H #define OUROBOROS_ENDIAN_H -#if defined(__linux__) || defined(__CYGWIN__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(__MACH__) #ifndef _BSD_SOURCE #define _BSD_SOURCE diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt index 00baa762..e0b375b6 100644 --- a/src/ipcpd/CMakeLists.txt +++ b/src/ipcpd/CMakeLists.txt @@ -8,7 +8,7 @@ set(IPCP_SOURCES add_subdirectory(local) add_subdirectory(normal) add_subdirectory(shim-udp) -if (NOT APPLE) +if (NOT APPLE AND NOT CMAKE_SYSTEM_NAME STREQUAL GNU) add_subdirectory(shim-eth-llc) endif () add_subdirectory(tests) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 75eac6f9..fe4dd88c 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -77,9 +77,8 @@ else() if (${LINUX_RND_HDR} STREQUAL "LINUX_RND_HDR-NOTFOUND") find_package(OpenSSL) if (NOT OPENSSL_FOUND) - message(STATUS "No secure random generation, please install OpenSSL.") + message(FATAL_ERROR "No secure random generation, please install libssl.") else() - message(STATUS "OpenSSL found") include_directories($OPENSSL_INCLUDE_DIR}) add_compile_flags(ouroboros -DHAVE_OPENSSL) endif() diff --git a/src/lib/shm_flow_set.c b/src/lib/shm_flow_set.c index 67abbb5b..7660b1dd 100644 --- a/src/lib/shm_flow_set.c +++ b/src/lib/shm_flow_set.c @@ -117,7 +117,7 @@ struct shm_flow_set * shm_flow_set_create() (set->fqueues + AP_MAX_FQUEUES * (SHM_BUFFER_SIZE)); pthread_mutexattr_init(&mattr); -#ifndef __APPLE__ +#ifdef HAVE_ROBUST_MUTEX pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST); #endif pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); @@ -336,7 +336,7 @@ ssize_t shm_flow_set_wait(const struct shm_flow_set * set, assert(idx < AP_MAX_FQUEUES); assert(fqueue); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(set->lock); #else if (pthread_mutex_lock(set->lock) == EOWNERDEAD) @@ -358,7 +358,7 @@ ssize_t shm_flow_set_wait(const struct shm_flow_set * set, else ret = -pthread_cond_wait(set->conds + idx, set->lock); -#ifndef __APPLE__ +#ifdef HAVE_ROBUST_MUTEX if (ret == -EOWNERDEAD) pthread_mutex_consistent(set->lock); #endif diff --git a/src/lib/shm_rbuff_ll.c b/src/lib/shm_rbuff_ll.c index 1e072b21..757f65c8 100644 --- a/src/lib/shm_rbuff_ll.c +++ b/src/lib/shm_rbuff_ll.c @@ -127,7 +127,7 @@ struct shm_rbuff * shm_rbuff_create(pid_t api, int port_id) rb->del = rb->add + 1; pthread_mutexattr_init(&mattr); -#ifndef __APPLE__ +#ifdef HAVE_ROBUST_MUTEX pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST); #endif pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); @@ -299,7 +299,7 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff * rb, ts_add(&abstime, timeout, &abstime); } -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -315,7 +315,7 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff * rb, &abstime); else idx = -pthread_cond_wait(rb->add, rb->lock); -#ifndef __APPLE__ +#ifdef HAVE_ROBUST_MUTEX if (idx == -EOWNERDEAD) pthread_mutex_consistent(rb->lock); #endif @@ -356,7 +356,7 @@ void shm_rbuff_fini(struct shm_rbuff * rb) if (shm_rbuff_empty(rb)) return; -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -367,7 +367,7 @@ void shm_rbuff_fini(struct shm_rbuff * rb) (void *) rb->lock); while (!shm_rbuff_empty(rb)) -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_cond_wait(rb->del, rb->lock); #else if (pthread_cond_wait(rb->del, rb->lock) == EOWNERDEAD) diff --git a/src/lib/shm_rbuff_pthr.c b/src/lib/shm_rbuff_pthr.c index d3c1e143..1b9f07d1 100644 --- a/src/lib/shm_rbuff_pthr.c +++ b/src/lib/shm_rbuff_pthr.c @@ -124,7 +124,7 @@ struct shm_rbuff * shm_rbuff_create(pid_t api, int port_id) rb->del = rb->add + 1; pthread_mutexattr_init(&mattr); -#ifndef __APPLE__ +#ifdef HAVE_ROBUST_MUTEX pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST); #endif pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); @@ -231,7 +231,7 @@ int shm_rbuff_write(struct shm_rbuff * rb, size_t idx) assert(rb); assert(idx < SHM_BUFFER_SIZE); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -264,7 +264,7 @@ ssize_t shm_rbuff_read(struct shm_rbuff * rb) assert(rb); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -297,7 +297,7 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff * rb, ts_add(&abstime, timeout, &abstime); } -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -313,7 +313,7 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff * rb, &abstime); else idx = -pthread_cond_wait(rb->add, rb->lock); -#ifndef __APPLE__ +#ifdef HAVE_ROBUST_MUTEX if (idx == -EOWNERDEAD) pthread_mutex_consistent(rb->lock); #endif @@ -334,7 +334,7 @@ void shm_rbuff_block(struct shm_rbuff * rb) { assert(rb); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -349,7 +349,7 @@ void shm_rbuff_unblock(struct shm_rbuff * rb) { assert(rb); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -364,7 +364,7 @@ void shm_rbuff_fini(struct shm_rbuff * rb) { assert(rb); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) @@ -376,7 +376,7 @@ void shm_rbuff_fini(struct shm_rbuff * rb) (void *) rb->lock); while (!shm_rbuff_empty(rb)) -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_cond_wait(rb->del, rb->lock); #else if (pthread_cond_wait(rb->del, rb->lock) == EOWNERDEAD) @@ -391,7 +391,7 @@ size_t shm_rbuff_queued(struct shm_rbuff * rb) assert(rb); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rb->lock); #else if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) diff --git a/src/lib/shm_rdrbuff.c b/src/lib/shm_rdrbuff.c index 1f999f93..d454fef8 100644 --- a/src/lib/shm_rdrbuff.c +++ b/src/lib/shm_rdrbuff.c @@ -192,7 +192,7 @@ struct shm_rdrbuff * shm_rdrbuff_create() pthread_mutexattr_init(&mattr); pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); -#ifndef __APPLE__ +#ifdef HAVE_ROBUST_MUTEX pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST); #endif pthread_mutex_init(rdrb->lock, &mattr); @@ -274,7 +274,7 @@ int shm_rdrbuff_wait_full(struct shm_rdrbuff * rdrb, ts_add(&abstime, timeo, &abstime); } -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rdrb->lock); #else if (pthread_mutex_lock(rdrb->lock) == EOWNERDEAD) @@ -282,9 +282,9 @@ int shm_rdrbuff_wait_full(struct shm_rdrbuff * rdrb, #endif while (shm_rdrb_free(rdrb, WAIT_BLOCKS)) { -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX if (pthread_cond_timedwait(rdrb->full, - rdrb->lock + rdrb->lock, &abstime) == ETIMEDOUT) { pthread_mutex_unlock(rdrb->lock); return -ETIMEDOUT; @@ -358,7 +358,7 @@ ssize_t shm_rdrbuff_write(struct shm_rdrbuff * rdrb, if (sz > SHM_RDRB_BLOCK_SIZE) return -EMSGSIZE; #endif -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rdrb->lock); #else if (pthread_mutex_lock(rdrb->lock) == EOWNERDEAD) @@ -437,7 +437,7 @@ ssize_t shm_rdrbuff_write_b(struct shm_rdrbuff * rdrb, if (sz > SHM_RDRB_BLOCK_SIZE) return -EMSGSIZE; #endif -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rdrb->lock); #else if (pthread_mutex_lock(rdrb->lock) == EOWNERDEAD) @@ -535,7 +535,7 @@ int shm_rdrbuff_remove(struct shm_rdrbuff * rdrb, assert(rdrb); assert(idx < (SHM_BUFFER_SIZE)); -#ifdef __APPLE__ +#ifndef HAVE_ROBUST_MUTEX pthread_mutex_lock(rdrb->lock); #else if (pthread_mutex_lock(rdrb->lock) == EOWNERDEAD) diff --git a/src/lib/tests/time_utils_test.c b/src/lib/tests/time_utils_test.c index 6d1ae32f..86636c15 100644 --- a/src/lib/tests/time_utils_test.c +++ b/src/lib/tests/time_utils_test.c @@ -28,12 +28,12 @@ static void ts_print(struct timespec * s) { - printf("timespec is %zd:%zd.\n", s->tv_sec, s->tv_nsec); + printf("timespec is %zd:%ld.\n", (ssize_t) s->tv_sec, s->tv_nsec); } static void tv_print(struct timeval * v) { - printf("timeval is %zd:%zd.\n", v->tv_sec, v->tv_usec); + printf("timeval is %zd:%ld.\n", (ssize_t) v->tv_sec, v->tv_usec); } static void ts_init(struct timespec * s, -- cgit v1.2.3 From 055835e5b06d7f18d94ca1d6b2df5f0a3ec3e954 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Fri, 4 Aug 2017 11:47:41 +0200 Subject: irmd: Release lock before ipcp_query The blocking ipcp_query call was called under reg_lock, causing flow_allocs over the shim-eth-llc to block the irmd for prolonged timespans. --- src/irmd/main.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/irmd/main.c b/src/irmd/main.c index 63ae6b13..912234d6 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -232,10 +232,14 @@ static struct ipcp_entry * get_ipcp_entry_by_name(const char * name) static struct ipcp_entry * get_ipcp_by_dst_name(const char * name) { - struct list_head * p = NULL; - uint8_t * hash; + struct list_head * p; + struct list_head * h; + uint8_t * hash; + pid_t api; - list_for_each(p, &irmd.ipcps) { + pthread_rwlock_rdlock(&irmd.reg_lock); + + list_for_each_safe(p, h, &irmd.ipcps) { struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); if (e->dif_name == NULL) continue; @@ -246,14 +250,22 @@ static struct ipcp_entry * get_ipcp_by_dst_name(const char * name) str_hash(e->dir_hash_algo, hash, name); - if (ipcp_query(e->api, hash, IPCP_HASH_LEN(e)) == 0) { + api = e->api; + + pthread_rwlock_unlock(&irmd.reg_lock); + + if (ipcp_query(api, hash, IPCP_HASH_LEN(e)) == 0) { free(hash); return e; } free(hash); + + pthread_rwlock_rdlock(&irmd.reg_lock); } + pthread_rwlock_unlock(&irmd.reg_lock); + return NULL; } @@ -1099,16 +1111,12 @@ static int flow_alloc(pid_t api, int state; uint8_t * hash; - pthread_rwlock_rdlock(&irmd.reg_lock); - ipcp = get_ipcp_by_dst_name(dst); if (ipcp == NULL) { - pthread_rwlock_unlock(&irmd.reg_lock); log_info("Destination %s unreachable.", dst); return -1; } - pthread_rwlock_unlock(&irmd.reg_lock); pthread_rwlock_wrlock(&irmd.flows_lock); port_id = bmp_allocate(irmd.port_ids); if (!bmp_is_id_valid(irmd.port_ids, port_id)) { -- cgit v1.2.3 From 0fe8d5aa50fcadc3b4eef65b2833944a76eb8f3e Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Fri, 4 Aug 2017 11:55:49 +0200 Subject: ipcpd: Fix missing space in shim-eth-llc --- src/ipcpd/shim-eth-llc/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index 4899cd83..dcbbc047 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -1037,7 +1037,7 @@ static int eth_llc_ipcp_flow_alloc_resp(int fd, pthread_mutex_lock(&ipcpi.alloc_lock); - while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL){ + while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL) { ts_add(&abstime, &ts, &abstime); pthread_cond_timedwait(&ipcpi.alloc_cond, &ipcpi.alloc_lock, -- cgit v1.2.3