#include <stdlib.h>
#include <unistd.h>
#include "libpmem.h"
#include "rpmem_common.h"
#include "rpmemd_log.h"
#include "rpmemd_util.h"
int
rpmemd_pmem_persist(const void *addr, size_t len)
{
pmem_persist(addr, len);
return 0;
}
int
rpmemd_flush_fatal(const void *addr, size_t len)
{
RPMEMD_FATAL("rpmemd_flush_fatal should never be called");
}
static const char *
rpmemd_persist_to_str(int (*persist)(const void *addr, size_t len))
{
if (persist == rpmemd_pmem_persist) {
return "pmem_persist";
} else if (persist == pmem_msync) {
return "pmem_msync";
} else if (persist == rpmemd_flush_fatal) {
return "none";
} else {
return NULL;
}
}
static void
rpmem_print_pm_policy(enum rpmem_persist_method persist_method,
int (*persist)(const void *addr, size_t len))
{
RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "persist method: %s",
rpmem_persist_method_to_str(persist_method));
RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "persist flush: %s",
rpmemd_persist_to_str(persist));
}
int
rpmemd_apply_pm_policy(enum rpmem_persist_method *persist_method,
int (**persist)(const void *addr, size_t len),
const int is_pmem)
{
switch (*persist_method) {
case RPMEM_PM_APM:
if (is_pmem) {
*persist_method = RPMEM_PM_APM;
*persist = rpmemd_flush_fatal;
} else {
*persist_method = RPMEM_PM_GPSPM;
*persist = pmem_msync;
}
break;
case RPMEM_PM_GPSPM:
*persist_method = RPMEM_PM_GPSPM;
*persist = is_pmem ? rpmemd_pmem_persist : pmem_msync;
break;
default:
RPMEMD_FATAL("invalid persist method: %d", *persist_method);
return -1;
}
RPMEMD_LOG(NOTICE, "persistency policy:");
rpmem_print_pm_policy(*persist_method, *persist);
return 0;
}