diff --git a/bindings/rust/Makefile.am b/bindings/rust/Makefile.am index b152ba7e..2fd46a21 100644 --- a/bindings/rust/Makefile.am +++ b/bindings/rust/Makefile.am @@ -1,60 +1,60 @@ # # Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. # # Author: Christine Caulfield # # This software licensed under GPL-2.0+ # MAINTAINERCLEANFILES = Makefile.in include $(top_srcdir)/build-aux/rust.mk # required for make check localver = $(corosyncrustver) SUBDIRS = . tests EXTRA_DIST = \ $(RUST_COMMON) \ $(RUST_SHIP_SRCS) \ README.md RUST_SHIP_SRCS = \ src/cpg.rs \ src/cfg.rs \ src/quorum.rs \ src/votequorum.rs \ src/cmap.rs \ src/lib.rs \ src/sys/mod.rs RUST_BUILT_SRCS = \ src/sys/cpg.rs \ src/sys/cfg.rs \ src/sys/quorum.rs \ src/sys/votequorum.rs \ src/sys/cmap.rs src/sys/cpg.rs: ../../include/corosync/cpg.h - $(top_srcdir)/build-aux/rust-regen.sh $^ $@ CPG -- -I$(top_srcdir)/include + $(top_srcdir)/build-aux/rust-regen.sh $^ $@ CPG --blocklist-function=inet6.* --blocklist-function==.*etsourcefilter -- -I$(top_srcdir)/include src/sys/cfg.rs: ../../include/corosync/cfg.h - $(top_srcdir)/build-aux/rust-regen.sh $^ $@ CFG -- -I$(top_srcdir)/include + $(top_srcdir)/build-aux/rust-regen.sh $^ $@ CFG --blocklist-function=inet6.* --blocklist-function=.*etsourcefilter -- -I$(top_srcdir)/include src/sys/quorum.rs: ../../include/corosync/quorum.h $(top_srcdir)/build-aux/rust-regen.sh $^ $@ QUORUM -- -I$(top_srcdir)/include src/sys/votequorum.rs: ../../include/corosync/votequorum.h $(top_srcdir)/build-aux/rust-regen.sh $^ $@ VOTEQUORUM -- -I$(top_srcdir)/include src/sys/cmap.rs: ../../include/corosync/cmap.h - $(top_srcdir)/build-aux/rust-regen.sh $^ $@ CMAP -- -I$(top_srcdir)/include + $(top_srcdir)/build-aux/rust-regen.sh $^ $@ CMAP -- -I$(top_srcdir)/include $(LIBQB_CFLAGS) all-local: cargo-tree-prep target/$(RUST_TARGET_DIR)/cpg.rlib \ target/$(RUST_TARGET_DIR)/cfg.rlib \ target/$(RUST_TARGET_DIR)/quorum.rlib \ target/$(RUST_TARGET_DIR)/votequorum.rlib \ target/$(RUST_TARGET_DIR)/cmap.rlib clean-local: cargo-clean diff --git a/bindings/rust/tests/build.rs.in b/bindings/rust/tests/build.rs.in index b187d1a5..39a97ba4 100644 --- a/bindings/rust/tests/build.rs.in +++ b/bindings/rust/tests/build.rs.in @@ -1,21 +1,22 @@ // Copyright (C) 2021-2023 Red Hat, Inc. // // All rights reserved. // // Author: Christine Caulfield (ccaulfi@redhat.com) // extern crate pkg_config; fn main() { // Tell the compiler to use the build-tree libs & headers for compiling println!("cargo:rustc-link-search=native=../../../lib/.libs/"); println!("cargo:rustc-link-search=native=../../../common_lib/.libs/"); + println!("cargo:rustc-flags=@LIBQBLIBS@"); println!("cargo:rustc-link-lib=cpg"); println!("cargo:rustc-link-lib=cfg"); println!("cargo:rustc-link-lib=cmap"); println!("cargo:rustc-link-lib=quorum"); println!("cargo:rustc-link-lib=votequorum"); println!("cargo:rustc-link-lib=corosync_common"); println!("cargo:rustc-link-lib=qb"); } diff --git a/build-aux/rust-regen.sh b/build-aux/rust-regen.sh index 15a3790d..bfb17494 100755 --- a/build-aux/rust-regen.sh +++ b/build-aux/rust-regen.sh @@ -1,30 +1,29 @@ #!/bin/sh # # Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved. # # Authors: Christine Caulfield # Fabio M. Di Nitto # # This software licensed under GPL-2.0+ # # # Regerate the FFI bindings in src/sys from the current headers # srcheader="$1" dstrs="$2" filter="$3" shift; shift; shift bindgen \ --size_t-is-usize \ - --no-recursive-allowlist \ --no-prepend-enum-name \ --no-layout-tests \ --no-doc-comments \ --generate functions,types \ --fit-macro-constant-types \ --allowlist-var=$filter.* \ --allowlist-type=.* \ --allowlist-function=.* \ $srcheader -o $dstrs "$@" diff --git a/build-aux/rust.mk b/build-aux/rust.mk index a1fee17f..00beb1f4 100644 --- a/build-aux/rust.mk +++ b/build-aux/rust.mk @@ -1,113 +1,114 @@ # # Copyright (C) 2021-2022 Red Hat, Inc. All rights reserved. # # Author: Fabio M. Di Nitto # # This software licensed under GPL-2.0+ # RUST_COMMON = \ build.rs.in RUST_SRCS = $(RUST_SHIP_SRCS) $(RUST_BUILT_SRCS) %.rlib: $(RUST_SRCS) Cargo.toml build.rs PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS) %-test: $(RUST_SRCS) Cargo.toml build.rs PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS) build.rs: build.rs.in rm -f $@ $@-t cat $^ | sed \ -e 's#@ABSTOPLEVELSRC@#$(abs_top_srcdir)#g' \ -e 's#@ABSTOPLEVELBUILD@#$(abs_top_builddir)#g' \ + -e 's#@LIBQBLIBS@#$(LIBQB_LIBS)#g' \ > $@-t chmod a-w $@-t mv $@-t $@ rm -f $@-t cargo-tree-prep: if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \ echo "Generating builddir out-of-tree rust symlinks"; \ src_realpath=$(shell realpath ${abs_srcdir}); \ for i in `find "$$src_realpath/" -type d | \ grep -v "${abs_builddir}" | \ sed -e 's#^'$$src_realpath'/##g'`; do \ $(MKDIR_P) ${abs_builddir}/$${i}; \ done; \ find "$$src_realpath/" -type f | { while read src; do \ process=no; \ copy=no; \ case $$src in \ ${abs_builddir}*) \ ;; \ *Makefile.*|*.in) \ ;; \ *) \ process=yes; \ ;; \ esac ; \ dst=`echo $$src | sed -e 's#^'$$src_realpath'/##g'`; \ if [ $${process} == yes ]; then \ rm -f ${abs_builddir}/$$dst; \ $(LN_S) $$src ${abs_builddir}/$$dst; \ fi; \ if [ $${copy} == yes ]; then \ rm -f ${abs_builddir}/$$dst; \ cp $$src ${abs_builddir}/$$dst; \ chmod u+w ${abs_builddir}/$$dst; \ fi; \ done; }; \ fi cargo-clean: -$(CARGO) clean rm -rf Cargo.lock $(RUST_BUILT_SRCS) build.rs target/ if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \ echo "Cleaning out-of-tree rust symlinks" ; \ find "${abs_builddir}/" -type l -delete; \ find "${abs_builddir}/" -type d -empty -delete; \ fi clippy-check: $(CARGO) clippy --verbose --all-features -- -D warnings format-check: if [ "${abs_builddir}" = "${abs_srcdir}" ]; then \ $(CARGO) fmt --all --check; \ else \ echo "!!!!! WARNING: skipping format check !!!!!"; \ fi doc-check: $(CARGO) doc --verbose --all-features publish-check: if [ -f "${abs_srcdir}/README.md" ]; then \ $(CARGO) publish --dry-run; \ fi crates-publish: if [ -f "${abs_srcdir}/README.md" ]; then \ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \ if [ "$$cratesver" != "$$testver" ]; then \ $(CARGO) publish; \ fi; \ fi crates-check: if [ -f "${abs_srcdir}/README.md" ]; then \ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \ if [ "$$cratesver" != "$$testver" ]; then \ echo "!!!!! WARNING !!!!!"; \ echo "!!!!! WARNING: $$bindingname local version ($$testver) is higher than the current published one on crates.io ($$cratesver)"; \ echo "!!!!! WARNING !!!!!"; \ fi; \ fi check-local: clippy-check format-check doc-check crates-check publish-check diff --git a/include/corosync/cpg.h b/include/corosync/cpg.h index 600bbf70..39200fd5 100644 --- a/include/corosync/cpg.h +++ b/include/corosync/cpg.h @@ -1,439 +1,440 @@ /* * Copyright (c) 2006-2019 Red Hat, Inc. * * All rights reserved. * * Author: Christine Caulfield (ccaulfi@redhat.com) * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the MontaVista Software, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef COROSYNC_CPG_H_DEFINED #define COROSYNC_CPG_H_DEFINED #include +#include #include #ifdef __cplusplus extern "C" { #endif /** * @addtogroup cpg_corosync * * @{ */ /** * @brief cpg_handle_t */ typedef uint64_t cpg_handle_t; /** * @brief cpg_iteration_handle_t */ typedef uint64_t cpg_iteration_handle_t; /** * @brief The cpg_guarantee_t enum */ typedef enum { CPG_TYPE_UNORDERED, /**< not implemented */ CPG_TYPE_FIFO, /**< same as agreed */ CPG_TYPE_AGREED, CPG_TYPE_SAFE /**< not implemented */ } cpg_guarantee_t; /** * @brief The cpg_flow_control_state_t enum */ typedef enum { CPG_FLOW_CONTROL_DISABLED, /**< flow control is disabled - new messages may be sent */ CPG_FLOW_CONTROL_ENABLED /**< flow control is enabled - new messages should not be sent */ } cpg_flow_control_state_t; /** * @brief The cpg_reason_t enum */ typedef enum { CPG_REASON_UNDEFINED = 0, CPG_REASON_JOIN = 1, CPG_REASON_LEAVE = 2, CPG_REASON_NODEDOWN = 3, CPG_REASON_NODEUP = 4, CPG_REASON_PROCDOWN = 5 } cpg_reason_t; /** * @brief The cpg_iteration_type_t enum */ typedef enum { CPG_ITERATION_NAME_ONLY = 1, CPG_ITERATION_ONE_GROUP = 2, CPG_ITERATION_ALL = 3, } cpg_iteration_type_t; /** * @brief The cpg_model_t enum */ typedef enum { CPG_MODEL_V1 = 1, } cpg_model_t; /** * @brief The cpg_address struct */ struct cpg_address { uint32_t nodeid; uint32_t pid; uint32_t reason; }; #define CPG_MAX_NAME_LENGTH 128 /** * @brief The cpg_name struct */ struct cpg_name { uint32_t length; char value[CPG_MAX_NAME_LENGTH]; }; #define CPG_MEMBERS_MAX 128 /** * @brief The cpg_iteration_description_t struct */ struct cpg_iteration_description_t { struct cpg_name group; uint32_t nodeid; uint32_t pid; }; /** * @brief The cpg_ring_id struct */ struct cpg_ring_id { uint32_t nodeid; uint64_t seq; }; /** * @brief The cpg_deliver_fn_t callback */ typedef void (*cpg_deliver_fn_t) ( cpg_handle_t handle, const struct cpg_name *group_name, uint32_t nodeid, uint32_t pid, /** * Unlike many "msg" pointers, this one is deliberately *not* * declared const in order to permit in-place endian conversion. */ void *msg, size_t msg_len); /** * @brief The cpg_confchg_fn_t callback */ typedef void (*cpg_confchg_fn_t) ( cpg_handle_t handle, const struct cpg_name *group_name, const struct cpg_address *member_list, size_t member_list_entries, const struct cpg_address *left_list, size_t left_list_entries, const struct cpg_address *joined_list, size_t joined_list_entries); /** * @brief The cpg_totem_confchg_fn_t callback */ typedef void (*cpg_totem_confchg_fn_t) ( cpg_handle_t handle, struct cpg_ring_id ring_id, uint32_t member_list_entries, const uint32_t *member_list); /** * @brief The cpg_callbacks_t struct */ typedef struct { cpg_deliver_fn_t cpg_deliver_fn; cpg_confchg_fn_t cpg_confchg_fn; } cpg_callbacks_t; /** * @brief The cpg_model_data_t struct */ typedef struct { cpg_model_t model; } cpg_model_data_t; #define CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF 0x01 /** * @brief The cpg_model_v1_data_t struct */ typedef struct { cpg_model_t model; cpg_deliver_fn_t cpg_deliver_fn; cpg_confchg_fn_t cpg_confchg_fn; cpg_totem_confchg_fn_t cpg_totem_confchg_fn; unsigned int flags; } cpg_model_v1_data_t; /** @} */ /** * @brief Create a new cpg connection * @param handle * @param callbacks * @return */ cs_error_t cpg_initialize ( cpg_handle_t *handle, cpg_callbacks_t *callbacks); /** * @brief Create a new cpg connection, initialize with model * @param handle * @param model * @param model_data * @param context * @return */ cs_error_t cpg_model_initialize ( cpg_handle_t *handle, cpg_model_t model, cpg_model_data_t *model_data, void *context); /** * @brief Close the cpg handle * @param handle * @return */ cs_error_t cpg_finalize ( cpg_handle_t handle); /** * @brief Get a file descriptor on which to poll. * * cpg_handle_t is NOT a file descriptor and may not be used directly. * * @param handle * @param fd * @return */ cs_error_t cpg_fd_get ( cpg_handle_t handle, int *fd); /** * @brief Get maximum size of a message that will not be fragmented * @param handle * @param size * @return */ cs_error_t cpg_max_atomic_msgsize_get ( cpg_handle_t handle, uint32_t *size); /** * @brief Get contexts for a CPG handle * @param handle * @param context * @return */ cs_error_t cpg_context_get ( cpg_handle_t handle, void **context); /** * @brief Set contexts for a CPG handle * @param handle * @param context * @return */ cs_error_t cpg_context_set ( cpg_handle_t handle, void *context); /** * @brief Dispatch messages and configuration changes * @param handle * @param dispatch_types * @return */ cs_error_t cpg_dispatch ( cpg_handle_t handle, cs_dispatch_flags_t dispatch_types); /** * @brief Join one or more groups. * * messages multicasted with cpg_mcast_joined will be sent to every * group that has been joined on handle handle. Any message multicasted * to a group that has been previously joined will be delivered in cpg_dispatch * * @param handle * @param group * @return */ cs_error_t cpg_join ( cpg_handle_t handle, const struct cpg_name *group); /** * @brief Leave one or more groups * @param handle * @param group * @return */ cs_error_t cpg_leave ( cpg_handle_t handle, const struct cpg_name *group); /** * @brief Multicast to groups joined with cpg_join. * * @param handle * @param guarantee * @param iovec This iovec will be multicasted to all groups joined with * the cpg_join interface for handle. * @param iov_len */ cs_error_t cpg_mcast_joined ( cpg_handle_t handle, cpg_guarantee_t guarantee, const struct iovec *iovec, unsigned int iov_len); /** * @brief Get membership information from cpg * @param handle * @param groupName * @param member_list * @param member_list_entries * @return */ cs_error_t cpg_membership_get ( cpg_handle_t handle, struct cpg_name *groupName, struct cpg_address *member_list, int *member_list_entries); /** * @brief cpg_local_get * @param handle * @param local_nodeid * @return */ cs_error_t cpg_local_get ( cpg_handle_t handle, unsigned int *local_nodeid); /** * @brief cpg_flow_control_state_get * @param handle * @param flow_control_enabled * @return */ cs_error_t cpg_flow_control_state_get ( cpg_handle_t handle, cpg_flow_control_state_t *flow_control_enabled); /** * @brief cpg_zcb_alloc * @param handle * @param size * @param buffer * @return */ cs_error_t cpg_zcb_alloc ( cpg_handle_t handle, size_t size, void **buffer); /** * @brief cpg_zcb_free * @param handle * @param buffer * @return */ cs_error_t cpg_zcb_free ( cpg_handle_t handle, void *buffer); /** * @brief cpg_zcb_mcast_joined * @param handle * @param guarantee * @param msg * @param msg_len * @return */ cs_error_t cpg_zcb_mcast_joined ( cpg_handle_t handle, cpg_guarantee_t guarantee, void *msg, size_t msg_len); /** * @brief cpg_iteration_initialize * @param handle * @param iteration_type * @param group * @param cpg_iteration_handle * @return */ cs_error_t cpg_iteration_initialize( cpg_handle_t handle, cpg_iteration_type_t iteration_type, const struct cpg_name *group, cpg_iteration_handle_t *cpg_iteration_handle); /** * @brief cpg_iteration_next * @param handle * @param description * @return */ cs_error_t cpg_iteration_next( cpg_iteration_handle_t handle, struct cpg_iteration_description_t *description); /** * @brief cpg_iteration_finalize * @param handle * @return */ cs_error_t cpg_iteration_finalize ( cpg_iteration_handle_t handle); #ifdef __cplusplus } #endif #endif /* COROSYNC_CPG_H_DEFINED */