(persist_record_converted= 0);
}
+/*---------- stupid mmap workaround ----------*/
+
+static Byte resaddrbuf[1024*1024], *resaddrbegin;
+static long pagesize;
+static unsigned long resaddruse;
+
+#define RESADDR_DIEFMT "(persist mapping parameters:" \
+ " %p+0x%lx%%0x%lx->%p+0x%lx)"
+#define RESADDR_DIEARGS resaddrbuf,(unsigned long)sizeof(resaddrbuf), \
+ pagesize, resaddrbegin,resaddruse
+
+static void resaddrdiee(const char *why) {
+ diee("%s " RESADDR_DIEFMT, why, RESADDR_DIEARGS);
+}
+
+static void showmaps(int lno) {
+ FILE *f;
+ int c;
+ fprintf(stderr,"=======%d======\n",lno);
+ f= fopen("/proc/self/maps","r"); if (!f) diee("open maps");
+ while ((c=getc(f)) != EOF)
+ fputc(c,stderr);
+ if (ferror(f)) diee("read maps");
+ fclose(f);
+system("grep Committed_AS /proc/meminfo");
+}
+
+#define SHOWMAPS showmaps(__LINE__);
+
+void persist_map_veryearly(void) {
+ int r;
+
+SHOWMAPS
+
+ errno= 0; pagesize= sysconf(_SC_PAGE_SIZE);
+ if (pagesize<=0) diee("could not find pagesize");
+
+ if (pagesize & (pagesize-1)) return;
+ if (pagesize > sizeof(resaddrbuf)/2) return;
+
+ resaddrbegin= (void*)(((unsigned long)resaddrbuf + pagesize - 1) &
+ ~(pagesize - 1UL));
+ resaddruse= sizeof(resaddrbuf) - pagesize;
+
+ r= mprotect(resaddrbegin,resaddruse,PROT_READ);
+ if (r) resaddrdiee("mprotect reserve buffer");
+
+SHOWMAPS
+}
+
+static void *mapmem(int fd, int datalen, int prot) {
+ void *rv;
+ int r;
+
+ if (!resaddruse)
+ die("inappropriate combination of sizes " RESADDR_DIEFMT, RESADDR_DIEARGS);
+
+ if (datalen > resaddruse)
+ die("data length %d too large " RESADDR_DIEFMT, datalen, RESADDR_DIEARGS);
+
+ r= munmap(resaddrbegin, resaddruse);
+ if (r) resaddrdiee("munmap reserve buffer");
+
+ rv= mmap(resaddrbegin, datalen, prot, MAP_SHARED|MAP_FIXED, fd, 0);
+ if (rv == MAP_FAILED)
+ resaddrdiee(prot==(PROT_READ|PROT_WRITE) ? "map data rw" :
+ prot==PROT_READ ? "map data ro" : "map data badly");
+
+ assert(rv == resaddrbegin);
+
+SHOWMAPS
+ return rv;
+}
+
/*---------- installing of our data as the current one ----------*/
void persist_install(void) {
fd= fileno(data);
- mapbase= mmap(0, datalen, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (mapbase == MAP_FAILED) diee("could not write mmap persist data file");
+ mapbase= mapmem(fd, datalen, PROT_READ|PROT_WRITE);
return mapbase;
}
#define PHI_LOAD(x) phi_load(&(x), sizeof(x), &offset);
DO_PERSIST_HEADER_ITEMS(PHI_CHECK, PHI_LOAD, PHI_LOAD)
- rv= mmap(0, datalen, PROT_READ|PROT_WRITE, MAP_PRIVATE, 0,0);
- if (rv == MAP_FAILED) diee("could not read mmap persist data file");
+ rv= mapmem(0, datalen, PROT_READ|PROT_WRITE);
return rv;
}
realbase= persist_mapread();
adjust= (Byte*)realbase - (Byte*)mapbase;
+ assert(!adjust);
#define CP(lvalue) \
((lvalue)= (lvalue) ? (void*)((Byte*)(lvalue) + adjust) : 0);