diff --git a/cmake/FindLibUUID.cmake b/cmake/FindLibUUID.cmake index d6c4163e96b1e59ce23f87bab6372d5bec4f87c3..0db8ae7e5e155eb0b371a02909566c449b2ff255 100644 --- a/cmake/FindLibUUID.cmake +++ b/cmake/FindLibUUID.cmake @@ -3,25 +3,29 @@ if(NOT LIBUUID_FOUND) NAMES uuid.h PATH_SUFFIXES uuid ) - find_library(LIBUUID_LIBRARIES - NAMES uuid - ) - - if (LIBUUID_INCLUDE_DIR AND LIBUUID_LIBRARIES) - set(LIBUUID_FOUND ON) - endif(LIBUUID_INCLUDE_DIR AND LIBUUID_LIBRARIES) - - if(LIBUUID_FOUND) + if (LIBUUID_INCLUDE_DIR) if (NOT LIBUUID_FIND_QUIETLY) message(STATUS "Found libuuid includes: ${LIBUUID_INCLUDE_DIR}") - message(STATUS "Found libuuid library: ${LIBUUID_LIBRARIES}") - endif (NOT LIBUUID_FIND_QUIETLY) + endif () set(LIBUUID_INCLUDE_DIRS ${LIBUUID_INCLUDE_DIR}) - else(LIBUUID_FOUND) - if (LIBUUID_FIND_REQUIRED) - message(FATAL_ERROR "Could not find libuuid development files") - endif (LIBUUID_FIND_REQUIRED) - endif(LIBUUID_FOUND) + check_library_exists(uuid uuid_is_null "" HAVE_LIBUUID_LINUX) + if (HAVE_LIBUUID_LINUX) + if (NOT LIBUUID_FIND_QUIETLY) + message(STATUS "Found libuuid library: ${LIBUUID_LIBRARIES}") + endif () + set(LIBUUID_FOUND ON) + set(LIBUUID_LIBRARIES uuid) + else() + check_library_exists(c uuid_is_nil "" HAVE_LIBUUID_BSD) + if (HAVE_LIBUUID_BSD) + set(LIBUUID_FOUND ON) + elseif (LIBUUID_FIND_REQUIRED) + message(FATAL_ERROR "Could not find uuid libraries") + endif() + endif() + elseif(LIBUUID_FIND_REQUIRED) + message(FATAL_ERROR "Could not find uuid development files") + endif() endif (NOT LIBUUID_FOUND) mark_as_advanced(LIBUUID_LIBRARIES LIBUUID_INCLUDE_DIRS) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc437eb7cd6c599b00eaf999f11d87aff280508c..543ac6eddb7e0a7a44c82337c7446497701373cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,7 +139,7 @@ if (ENABLE_BACKTRACE AND HAVE_BFD) endif() endif() -set (common_libraries ${common_libraries} uuid) +set (common_libraries ${common_libraries} ${LIBUUID_LIBRARIES}) set (common_libraries ${common_libraries} PARENT_SCOPE) add_subdirectory(lib) diff --git a/src/replica.cc b/src/replica.cc index 7ae0355eec27ec570977305672fa95f35a7e5e73..cdd3bb12f9face0cfb5c803d090008d999b706ce 100644 --- a/src/replica.cc +++ b/src/replica.cc @@ -154,8 +154,9 @@ replica_bootstrap(struct recovery_state *r, const char *replication_source) char *data = buf; data = mp_encode_map(data, 1); data = mp_encode_uint(data, IPROTO_NODE_UUID); - data = mp_encode_str(data, (const char *) &recovery_state->node_uuid, - sizeof(tt_uuid)); + data = mp_encode_strl(data, UUID_LEN); + tt_uuid_enc_be(&recovery_state->node_uuid, data); + data += UUID_LEN; assert(data <= buf + sizeof(buf)); packet.body[0].iov_base = buf; @@ -212,11 +213,13 @@ remote_connect(struct recovery_state *r, struct ev_io *coio,const char **err) char *data = buf; data = mp_encode_map(data, 3); data = mp_encode_uint(data, IPROTO_CLUSTER_UUID); - data = mp_encode_str(data, (const char *) &r->cluster_uuid, - sizeof(tt_uuid)); + data = mp_encode_strl(data, UUID_LEN); + tt_uuid_enc_be(&r->cluster_uuid, data); + data += UUID_LEN; data = mp_encode_uint(data, IPROTO_NODE_UUID); - data = mp_encode_str(data, (const char *) &r->node_uuid, - sizeof(tt_uuid)); + data = mp_encode_strl(data, UUID_LEN); + tt_uuid_enc_be(&recovery_state->node_uuid, data); + data += UUID_LEN; data = mp_encode_uint(data, IPROTO_LSNMAP); data = mp_encode_map(data, cluster_size); uint32_t k; diff --git a/src/replication.cc b/src/replication.cc index 5f72b453a4d967041b86135fc4227a27ac36486f..ce303d670704f2f44f53ea6c0eafe861a60fe9e6 100644 --- a/src/replication.cc +++ b/src/replication.cc @@ -239,12 +239,12 @@ replication_join(int fd, struct iproto_packet *packet) uint8_t key = mp_decode_uint(&d); if (key == IPROTO_NODE_UUID) { if (mp_typeof(*d) != MP_STR || - mp_decode_strl(&d) != sizeof(tt_uuid)) { + mp_decode_strl(&d) != UUID_LEN) { tnt_raise(ClientError, ER_INVALID_MSGPACK, "invalid Node-UUID"); } - tt_uuid_set(&node_uuid, d); - d += sizeof(node_uuid); + tt_uuid_dec_be(d, &node_uuid); + d += UUID_LEN; } else { mp_next(&d); /* value */ } @@ -302,21 +302,21 @@ replication_subscribe(int fd, struct iproto_packet *packet) switch (key) { case IPROTO_CLUSTER_UUID: if (mp_typeof(*d) != MP_STR || - mp_decode_strl(&d) != sizeof(cluster_uuid)) { + mp_decode_strl(&d) != UUID_LEN) { tnt_raise(ClientError, ER_INVALID_MSGPACK, "invalid Cluster-UUID"); } - tt_uuid_set(&cluster_uuid, d); - d += sizeof(cluster_uuid); + tt_uuid_dec_be(d, &cluster_uuid); + d += UUID_LEN; break; case IPROTO_NODE_UUID: if (mp_typeof(*d) != MP_STR || - mp_decode_strl(&d) != sizeof(node_uuid)) { + mp_decode_strl(&d) != UUID_LEN) { tnt_raise(ClientError, ER_INVALID_MSGPACK, "invalid Node-UUID"); } - tt_uuid_set(&node_uuid, d); - d += sizeof(node_uuid); + tt_uuid_dec_be(d, &node_uuid); + d += UUID_LEN; break; case IPROTO_LSNMAP: if (mp_typeof(*d) != MP_MAP) { diff --git a/src/trivia/config.h.cmake b/src/trivia/config.h.cmake index d2d675cb72524c5090aafe46fbbb65940e275b50..9f19173ce843f8a4f80a46b76cf900f42c1dc11a 100644 --- a/src/trivia/config.h.cmake +++ b/src/trivia/config.h.cmake @@ -133,6 +133,9 @@ #cmakedefine HAVE_OPEN_MEMSTREAM 1 #cmakedefine HAVE_FMEMOPEN 1 +#cmakedefine HAVE_LIBUUID_LINUX 1 +#cmakedefine HAVE_LIBUUID_BSD 1 + /* * predefined /etc directory prefix. */ diff --git a/src/tt_uuid.c b/src/tt_uuid.c index 502809c672b15c0a76fb00b19a7ed7287b712546..6127f5258a0378fe8715d5be4f8f3e18fc24b16f 100644 --- a/src/tt_uuid.c +++ b/src/tt_uuid.c @@ -28,10 +28,10 @@ */ #include "tt_uuid.h" /* Zeroed by the linker. */ -tt_uuid uuid_nil; +const tt_uuid uuid_nil; char * -tt_uuid_str(const struct tt_uuid *uu) +tt_uuid_str(const tt_uuid *uu) { static __thread char buf[UUID_STR_LEN + 1]; tt_uuid_to_string(uu, buf); diff --git a/src/tt_uuid.h b/src/tt_uuid.h index 2e934ebf25cbba370069770c2468b9b76a6aa6f6..3f584008ce7b97d323727e68f8a5131bdf179773 100644 --- a/src/tt_uuid.h +++ b/src/tt_uuid.h @@ -28,22 +28,26 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include <uuid/uuid.h> +#include <trivia/config.h> #include <string.h> #include <stdbool.h> +#include <stdlib.h> +#include <assert.h> #if defined(__cplusplus) extern "C" { #endif -enum { UUID_STR_LEN = 36 }; +enum { UUID_LEN = 16, UUID_STR_LEN = 36 }; + +#if defined(HAVE_LIBUUID_LINUX) + +#include <uuid/uuid.h> typedef struct tt_uuid { uuid_t id; } tt_uuid; -extern tt_uuid uuid_nil; - static inline void tt_uuid_create(tt_uuid *uu) { @@ -63,13 +67,22 @@ tt_uuid_to_string(const tt_uuid *uu, char *out) } static inline void -tt_uuid_set(tt_uuid *uu, const void *data) +tt_uuid_dec_be(const void *in, tt_uuid *uu) { - memcpy(uu->id, data, sizeof(uu->id)); + memcpy(uu->id, in, sizeof(uu->id)); } -char * -tt_uuid_str(const struct tt_uuid *uu); +static inline void +tt_uuid_enc_be(const tt_uuid *uu, void *out) +{ + memcpy(out, uu->id, sizeof(uu->id)); +} + +static inline bool +tt_uuid_is_nil(const tt_uuid *uu) +{ + return uuid_is_null(uu->id); +} static inline bool tt_uuid_cmp(const tt_uuid *lhs, const tt_uuid *rhs) @@ -77,12 +90,75 @@ tt_uuid_cmp(const tt_uuid *lhs, const tt_uuid *rhs) return uuid_compare(lhs->id, rhs->id); } +#elif defined(HAVE_LIBUUID_BSD) + +#include <uuid.h> + +typedef struct uuid tt_uuid; + +static inline int +tt_uuid_create(tt_uuid *uu) +{ + uint32_t status; + uuid_create(uu, &status); + return status == uuid_s_ok; +} + +static inline int +tt_uuid_from_string(const char *in, tt_uuid *uu) +{ + uint32_t status; + uuid_from_string(in, uu, &status); + return status == uuid_s_ok; +} + +static inline void +tt_uuid_to_string(const tt_uuid *uu, char *out) +{ + uint32_t status; + char *buf = NULL; + uuid_to_string(uu, &buf, &status); + assert(status == uuid_s_ok); + strncpy(out, buf, UUID_STR_LEN); + out[UUID_STR_LEN] = '\0'; + free(buf); +} + +static inline bool +tt_uuid_cmp(const tt_uuid *lhs, const tt_uuid *rhs) +{ + uint32_t status; + return uuid_compare(lhs, rhs, &status); +} + static inline bool tt_uuid_is_nil(const tt_uuid *uu) { - return uuid_is_null(uu->id); + uint32_t status; + return uuid_is_nil(uu, &status); } +static inline void +tt_uuid_dec_be(const void *in, tt_uuid *uu) +{ + uuid_dec_be(in, uu); + +} + +static inline void +tt_uuid_enc_be(const tt_uuid *uu, void *out) +{ + uuid_enc_be(out, uu); +} +#else +#error Unsupported libuuid +#endif /* HAVE_LIBUUID_XXX */ + +extern const tt_uuid uuid_nil; + +char * +tt_uuid_str(const tt_uuid *uu); + #if defined(__cplusplus) } /* extern "C" */ #endif diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 41ac98c10eb75e5d59a726a8628d29e3d2913145..e0ba1a678e46d02f543aaadc7fd8e5d4b7f599df 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -38,7 +38,7 @@ target_link_libraries(arena_mt.test small pthread) add_executable(pt_alloc.test pt_alloc.cc) target_link_libraries(pt_alloc.test small) add_executable(log_dir.test log_dir.cc test.c) -target_link_libraries(log_dir.test uuid core small salad misc bitset msgpuck +target_link_libraries(log_dir.test ${LIBUUID_LIBRARIES} core small salad misc bitset msgpuck ${LIBEV_LIBRARIES} ${LIBEIO_LIBRARIES} ${LIBCORO_LIBRARIES})