summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2001-10-23 03:08:42 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2001-10-23 03:08:42 (GMT)
commit9e0923f6291e0a6f98a91bf5cafcb9ef0ed0405f (patch)
tree7d03a25c159bf948a0b1b7694362cea2dc5d7120
parente2c07775f2cda3c25a8e2ed47fbf1f0de4d548c1 (diff)
downloadlpsm-9e0923f6291e0a6f98a91bf5cafcb9ef0ed0405f.zip
lpsm-9e0923f6291e0a6f98a91bf5cafcb9ef0ed0405f.tar.gz
lpsm-9e0923f6291e0a6f98a91bf5cafcb9ef0ed0405f.tar.bz2
lpsm-9e0923f6291e0a6f98a91bf5cafcb9ef0ed0405f.tar.xz
If the base address doesn't match, try to map at the required base
address instead.
-rw-r--r--Makefile2
-rw-r--r--README7
-rw-r--r--arena.c6
-rw-r--r--lpsm.h2
-rw-r--r--mgmt.c15
5 files changed, 22 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index 3a73508..fbbd173 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
TEST = teststore test_mmap ftrunctest testbuddy testalloc testrecovery
SONAME = libpsm.so.0
-VERSION = 0.1.3
+VERSION = 0.1.4
LIBPSM = libpsm.so libpsm.a
CFILES = arena.c bitops.c \
diff --git a/README b/README
index 1d929ae..4d2aa35 100644
--- a/README
+++ b/README
@@ -54,7 +54,8 @@ The LPSM library installs a signal handler for SIGSEGV.
* Functions to use in unmanaged mode:
-void *lpsm_arena_init(const char *datafile, const char *logfile, size_t *arena_size)
+void *lpsm_arena_init(const char *datafile, const char *logfile,
+ size_t *arena_size, void *arena_base)
Open the persistent memory arena that consists of the two
files datafile and logfile. If these files don't exist, they
@@ -64,6 +65,10 @@ void *lpsm_arena_init(const char *datafile, const char *logfile, size_t *arena_s
It returns a pointer to the arena, or NULL on error.
+ If arena_base is set, try to map the arena at that particular
+ base address. If arena_base is NULL, use an
+ architecture-specific default value.
+
pid_t lpsm_checkpoint(double ratio, enum psmsync wait)
diff --git a/arena.c b/arena.c
index f28cb45..0de97d9 100644
--- a/arena.c
+++ b/arena.c
@@ -285,15 +285,15 @@ static int lpsm_recover_log(void)
* playback (crash recovery) if the log file exists
* and is nonempty.
*/
-void *lpsm_arena_init(const char *main_file, const char *log_file, size_t *arena_len)
+void *lpsm_arena_init(const char *main_file, const char *log_file,
+ size_t *arena_len, void *arena_ptr)
{
- void *arena_ptr;
struct sigaction sigact;
struct flock lock;
off_t file_len, len = arena_len ? *arena_len : 0;
size_t file_pages, len_pages;
- arena_ptr = ARENA_ADDRESS;
+ arena_ptr = arena_ptr ? arena_ptr : ARENA_ADDRESS;
PM = malloc(sizeof(struct lpsm_arena));
if ( !PM )
diff --git a/lpsm.h b/lpsm.h
index 485d669..0af85bf 100644
--- a/lpsm.h
+++ b/lpsm.h
@@ -39,7 +39,7 @@ enum psmsync {
PSMSYNC_SYNC /* Wait until this writeback finishes */
};
-void *lpsm_arena_init(const char *, const char *, size_t *);
+void *lpsm_arena_init(const char *, const char *, size_t *, void *);
pid_t lpsm_checkpoint(double, enum psmsync);
int lpsm_extend(size_t);
void lpsm_shutdown(void);
diff --git a/mgmt.c b/mgmt.c
index c123d7d..956520a 100644
--- a/mgmt.c
+++ b/mgmt.c
@@ -59,11 +59,9 @@ void **lpsm_init(const char *main_file, const char *log_file)
{
size_t arena_len = sizeof(struct arena_header); /* Minimum initial size */
- if ( !lpsm_arena_init(main_file, log_file, &arena_len) )
+ if ( !(AH = lpsm_arena_init(main_file, log_file, &arena_len, NULL)) )
return NULL; /* Failed to initialize arena */
- AH = (struct arena_header *)PM->arena;
-
if ( memcmp(AH->arena_magic, lpsm_arena_magic, 16) != 0 ) {
if ( memcmp(AH->arena_magic, lpsm_arena_zero, 16) == 0 ) {
size_t total_size, bitmap_size;
@@ -128,10 +126,19 @@ void **lpsm_init(const char *main_file, const char *log_file)
AH->arena_byteorder != 0x12345678 ||
AH->arena_bytesize != CHAR_BIT ||
AH->arena_ptrsize != sizeof(void *) ||
- AH->arena_base != (void *)AH ||
AH->buddy_order_min != BUDDY_ORDER_MIN ) {
return NULL; /* Incompatible or corrupt arena */
}
+ if ( AH->arena_base != (void *)AH ) {
+ void *arena_base = AH->arena_base;
+ /* Arena mapped in the wrong place */
+ lpsm_shutdown(); /* Nothing written... */
+ if ( !(AH = lpsm_arena_init(main_file, log_file, &arena_len, arena_base)) )
+ return NULL; /* Failed to initialize arena */
+ if ( AH->arena_base != (void *)AH )
+ return NULL; /* Something went weird... */
+ }
+
return AH->root_data_ptrs;
}