diff --git a/src/common/set.c b/src/common/set.c index e3f8b6f63f8502ee2deec23ba713309f2c65dd8f..60cf16e770697c1ffb170b89e914791d949c7413 100644 --- a/src/common/set.c +++ b/src/common/set.c @@ -71,6 +71,7 @@ #include "fs.h" #include "os_deep.h" #include "set_badblocks.h" +#include "shutdown_state.h" #define LIBRARY_REMOTE "librpmem.so.1" #define SIZE_AUTODETECT_STR "AUTO" @@ -2253,6 +2254,13 @@ util_header_create(struct pool_set *set, unsigned repidx, unsigned partidx, if (set->options & OPTION_SINGLEHDR) hdrp->features.incompat |= POOL_FEAT_SINGLEHDR; + /* Update SDS feature if the device don't supports it */ + if (!shutdown_state_is_supported(rep->part[partidx].fd)) { + hdrp->features.incompat &= ~POOL_FEAT_SDS; + set->ignore_sds |= IGNORE_SDS(HDR(rep, 0)); + LOG(3, "SDS disabled at runtime"); + } + memcpy(hdrp->poolset_uuid, set->uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->uuid, PART(rep, partidx)->uuid, POOL_HDR_UUID_LEN); diff --git a/src/common/shutdown_state.c b/src/common/shutdown_state.c index 3a2bb11fa2e2906ff4eed37b4afe911e09457783..d6d7190020871f56fb7b70cc2c0de3dc10d43811 100644 --- a/src/common/shutdown_state.c +++ b/src/common/shutdown_state.c @@ -20,6 +20,29 @@ #define FLUSH_SDS(sds, rep) \ if ((rep) != NULL) os_part_deep_common(rep, 0, sds, sizeof(*(sds)), 1) +/* + * shutdown_state_is_supported -- (internal) check if device supports SDS + * + * Returns 1 if supports and 0 if not. + */ +int +shutdown_state_is_supported(int fd) +{ + uint64_t usc; + struct pmem2_source *src; + + if (pmem2_source_from_fd(&src, fd)) + return 0; + + if (pmem2_source_device_usc(src, &usc) == PMEM2_E_NOSUPP) { + pmem2_source_delete(&src); + return 0; + } + + pmem2_source_delete(&src); + return 1; +} + /* * shutdown_state_checksum -- (internal) counts SDS checksum and flush it */ @@ -71,9 +94,7 @@ shutdown_state_add_part(struct shutdown_state *sds, int fd, int ret = pmem2_source_device_usc(src, &usc); - if (ret == PMEM2_E_NOSUPP) { - usc = 0; - } else if (ret != 0) { + if (ret != 0) { if (ret == -EPERM) { /* overwrite error message */ ERR( diff --git a/src/common/shutdown_state.h b/src/common/shutdown_state.h index 60031bb5ce3a24d86a2a2e231ce1397127d89246..147cd1f40cddc806979139e0dab0c7fea90343ad 100644 --- a/src/common/shutdown_state.h +++ b/src/common/shutdown_state.h @@ -33,6 +33,7 @@ void shutdown_state_clear_dirty(struct shutdown_state *sds, int shutdown_state_check(struct shutdown_state *curr_sds, struct shutdown_state *pool_sds, struct pool_replica *rep); +int shutdown_state_is_supported(int fd); #ifdef __cplusplus } diff --git a/src/libpmempool/check_pool_hdr.c b/src/libpmempool/check_pool_hdr.c index 9d24855b0a3342bc96da1ba6bb92ebfcc04d1179..e9cf7173d026efc90e7e0c5ab25339d23c24eb5c 100644 --- a/src/libpmempool/check_pool_hdr.c +++ b/src/libpmempool/check_pool_hdr.c @@ -234,6 +234,11 @@ pool_hdr_default_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, loc->hdr.features.compat = def_hdr.features.compat; break; case Q_DEFAULT_INCOMPAT_FEATURES: + /* Check if SDS is supported */ + if (!shutdown_state_is_supported( + PART(REP(ppc->pool->set_file->poolset, 0), 0)->fd)) { + def_hdr.features.incompat &= ~POOL_FEAT_SDS; + } CHECK_INFO(ppc, "%ssetting pool_hdr.features.incompat to 0x%x", loc->prefix, def_hdr.features.incompat); loc->hdr.features.incompat = def_hdr.features.incompat;