diff --git a/src/common/set.c b/src/common/set.c index 590421a145b47ab52e82ac4924921f767175a6b4..a8282ed35eee2bc7f136e529b96134ecbd504b06 100644 --- a/src/common/set.c +++ b/src/common/set.c @@ -3887,6 +3887,38 @@ util_read_compat_features(struct pool_set *set, uint32_t *compat_features) return 0; } +/* + * unlink_remote_replicas -- removes remote replicas from poolset + * + * It is necessary when COW flag is set because remote replicas + * cannot be mapped privately + */ +static int +unlink_remote_replicas(struct pool_set *set) +{ + unsigned i = 0; + while (i < set->nreplicas) { + if (set->replica[i]->remote == NULL) { + i++; + continue; + } + + util_replica_close(set, i); + int ret = util_replica_close_remote(set->replica[i], i, + DO_NOT_DELETE_PARTS); + if (ret != 0) + return ret; + + size_t size = sizeof(set->replica[i]) * + (set->nreplicas - i - 1); + memmove(&set->replica[i], &set->replica[i + 1], size); + set->nreplicas--; + } + + set->remote = 0; + return 0; +} + /* * util_pool_open -- open a memory pool (set or a single file) * @@ -4001,6 +4033,13 @@ util_pool_open(struct pool_set **setp, const char *path, size_t minpartsize, /* unmap all headers */ util_unmap_all_hdrs(set); + /* remove all remote replicas from poolset when cow */ + if (cow && set->remote) { + ret = unlink_remote_replicas(set); + if (ret != 0) + goto err_replica; + } + return 0; err_replica: diff --git a/src/test/Makefile b/src/test/Makefile index f1c14e9c68e14f30185149a4668ef6034df2af64..bb1b97263f960f39505ba0b4cdbac3b14d397661 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -151,7 +151,8 @@ OBJ_REMOTE_DEPS = \ OBJ_REMOTE_TESTS = \ obj_rpmem_basic_integration\ obj_rpmem_heap_interrupt\ - obj_rpmem_heap_state + obj_rpmem_heap_state\ + obj_check_remote OTHER_TESTS = \ arch_flags\ diff --git a/src/test/obj_check_remote/.gitignore b/src/test/obj_check_remote/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d52f000e9b4924bf55a19a41daad4167451ef376 --- /dev/null +++ b/src/test/obj_check_remote/.gitignore @@ -0,0 +1 @@ +obj_check_remote diff --git a/src/test/obj_check_remote/Makefile b/src/test/obj_check_remote/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ff304cf360753df8d515b89b5a1edf7d2dc6056c --- /dev/null +++ b/src/test/obj_check_remote/Makefile @@ -0,0 +1,42 @@ +# +# Copyright 2019, Intel Corporation +# +# 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 copyright holder 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. +# + +# +# src/test/obj_check_remote/Makefile -- build obj_check_remote test +# +TARGET = obj_check_remote +OBJS = obj_check_remote.o + +LIBPMEMOBJ=y +SCP_TO_REMOTE_NODES = y + +include ../Makefile.inc diff --git a/src/test/obj_check_remote/TEST0 b/src/test/obj_check_remote/TEST0 new file mode 100755 index 0000000000000000000000000000000000000000..dfd92e78a82480f2c8c1bf60e58b49e44a232338 --- /dev/null +++ b/src/test/obj_check_remote/TEST0 @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# +# Copyright 2019, Intel Corporation +# +# 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 copyright holder 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. +# + +# +# src/test/obj_check_remote/TEST0 -- unit test which checks if remote +# replicas were removed from poolset and were not modified by +# pmemobj_check. (pmemobj_check used to rely on copy on write (MAP_PRIVATE) +# for all replicas but it have never worked for remote ones) +# + +# standard unit test setup +. ../unittest/unittest.sh + +require_test_type medium +require_command md5sum + +setup + +require_nodes 2 + +require_node_libfabric 0 $RPMEM_PROVIDER +require_node_libfabric 1 $RPMEM_PROVIDER + +init_rpmem_on_node 1 0 + +# binary for this test +EXE=obj_check_remote + +# define files and directories +TEST_SET_LOCAL="testset_local" +TEST_SET_REMOTE="testset_remote" + +# remove files created by previous test +rm_files_from_node 1 ${NODE_DIR[1]}/testfile1 +rm_files_from_node 1 ${NODE_DIR[1]}/testfile2 +rm_files_from_node 1 ${NODE_DIR[1]}/testfile3 +rm_files_from_node 1 ${NODE_DIR[1]}/testfile4 +rm_files_from_node 0 ${NODE_DIR[0]}/testfile5 +rm_files_from_node 0 ${NODE_DIR[0]}/testfile6 + +create_poolset $DIR/$TEST_SET_LOCAL 32M:${NODE_DIR[1]}/testfile1:z 32M:${NODE_DIR[1]}/testfile2:z \ + R 32M:${NODE_DIR[1]}/testfile3:z 32M:${NODE_DIR[1]}/testfile4:z \ + m ${NODE_ADDR[0]}:$TEST_SET_REMOTE + +create_poolset $DIR/$TEST_SET_REMOTE 32M:${NODE_DIR[0]}/testfile5:z 32M:${NODE_DIR[0]}/testfile6:z + +copy_files_to_node 0 ${NODE_DIR[0]} $DIR/$TEST_SET_REMOTE +copy_files_to_node 1 ${NODE_DIR[1]} $DIR/$TEST_SET_LOCAL + +expect_normal_exit run_on_node 1 ../pmempool create obj ${NODE_DIR[1]}/$TEST_SET_LOCAL + +expect_abnormal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}/$TEST_SET_LOCAL abort + +copy_files_from_node 0 $DIR ${NODE_DIR[0]}/testfile5 + +REPAB=`md5sum -b $DIR/testfile5` + +expect_normal_exit run_on_node 1 ./$EXE$EXESUFFIX ${NODE_DIR[1]}/$TEST_SET_LOCAL check + +copy_files_from_node 0 $DIR ${NODE_DIR[0]}/testfile5 + +REPCHECK=`md5sum -b $DIR/testfile5` + +if [ "$REPAB" != "$REPCHECK" ] +then + fatal "$REPAB != $REPCHECK" +fi + +check + +pass diff --git a/src/test/obj_check_remote/config.sh b/src/test/obj_check_remote/config.sh new file mode 100644 index 0000000000000000000000000000000000000000..94bf0853482cfbc0faf9bb0bbe4b85c59e59d671 --- /dev/null +++ b/src/test/obj_check_remote/config.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# +# Copyright 2019, Intel Corporation +# +# 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 copyright holder 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. +# +# +# obj_check_remote/config.sh -- test configuration +# + +CONF_GLOBAL_FS_TYPE=any +CONF_GLOBAL_BUILD_TYPE="debug nondebug" +CONF_GLOBAL_TEST_TYPE=medium + +CONF_GLOBAL_RPMEM_PROVIDER=sockets +CONF_GLOBAL_RPMEM_PMETHOD=all diff --git a/src/test/obj_check_remote/obj_check_remote.c b/src/test/obj_check_remote/obj_check_remote.c new file mode 100644 index 0000000000000000000000000000000000000000..63f2942ec19c52e3273481a8be791c6e79ca69fe --- /dev/null +++ b/src/test/obj_check_remote/obj_check_remote.c @@ -0,0 +1,96 @@ +/* + * Copyright 2019, Intel Corporation + * + * 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 copyright holder 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. + */ + +/* + * obj_check_remote.c -- unit tests for pmemobj_check_remote + */ + +#include <stddef.h> +#include "unittest.h" +#include "libpmemobj.h" + +struct vector { + int x; + int y; + int z; +}; + +int +main(int argc, char *argv[]) +{ + START(argc, argv, "obj_check_remote"); + + if (argc < 3) + UT_FATAL("insufficient number of arguments"); + + const char *path = argv[1]; + const char *action = argv[2]; + const char *layout = NULL; + PMEMobjpool *pop = NULL; + + if (strcmp(action, "abort") == 0) { + pop = pmemobj_open(path, layout); + if (pop == NULL) + UT_FATAL("usage: %s filename abort|check", argv[0]); + + PMEMoid root = pmemobj_root(pop, sizeof(struct vector)); + struct vector *vectorp = pmemobj_direct(root); + + TX_BEGIN(pop) { + pmemobj_tx_add_range(root, 0, sizeof(struct vector)); + vectorp->x = 5; + vectorp->y = 10; + vectorp->z = 15; + } TX_ONABORT { + UT_ASSERT(0); + } TX_END + + int *to_modify = &vectorp->x; + + TX_BEGIN(pop) { + pmemobj_tx_add_range_direct(to_modify, sizeof(int)); + *to_modify = 30; + pmemobj_persist(pop, to_modify, sizeof(*to_modify)); + abort(); + } TX_END + } else if (strcmp(action, "check") == 0) { + int ret = pmemobj_check(path, layout); + if (ret == 1) + return 0; + else + return ret; + } else { + UT_FATAL("%s is not a valid action", action); + } + + return 0; +}