int main(int argc, char *argv[]) { int fd; char *dest; char *src; struct stat stbuf; START(argc, argv, "pmem_memcpy"); if (argc != 5) FATAL("usage: %s file srcoff destoff length", argv[0]); fd = OPEN(argv[1], O_RDWR); int dest_off = atoi(argv[2]); int src_off = atoi(argv[3]); size_t bytes = strtoul(argv[4], NULL, 0); FSTAT(fd, &stbuf); /* src > dst */ dest = pmem_map(fd); if (dest == NULL) FATAL("!could not map file: %s", argv[1]); src = MMAP(dest + stbuf.st_size, stbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); /* * Its very unlikely that src would not be > dest. pmem_map * chooses the first unused address >= 1TB, large * enough to hold the give range, and 1GB aligned. If the * addresses did not get swapped to allow src > dst, log error * and allow test to continue. */ if (src <= dest) { swap_mappings(&dest, &src, stbuf.st_size, fd); if (src <= dest) ERR("cannot map files in memory order"); } memset(dest, 0, (2 * bytes)); memset(src, 0, (2 * bytes)); do_memcpy(fd, dest, dest_off, src, src_off, bytes, argv[1]); /* dest > src */ swap_mappings(&dest, &src, stbuf.st_size, fd); if (dest <= src) { ERR("cannot map files in memory order"); } do_memcpy(fd, dest, dest_off, src, src_off, bytes, argv[1]); MUNMAP(dest, stbuf.st_size); MUNMAP(src, stbuf.st_size); CLOSE(fd); DONE(NULL); }
int main(int argc, char *argv[]) { int srcfd; int dstfd; struct stat stbuf; char *pmemaddr; if (argc != 3) { fprintf(stderr, "usage: %s src-file dst-file\n", argv[0]); exit(1); } /* open src-file */ if ((srcfd = open(argv[1], O_RDONLY)) < 0) { perror(argv[1]); exit(1); } /* create a pmem file */ if ((dstfd = open(argv[2], O_CREAT|O_EXCL|O_RDWR, 0666)) < 0) { perror(argv[2]); exit(1); } /* find the size of the src-file */ if (fstat(srcfd, &stbuf) < 0) { perror("fstat"); exit(1); } /* allocate the pmem */ if ((errno = posix_fallocate(dstfd, 0, stbuf.st_size)) != 0) { perror("posix_fallocate"); exit(1); } /* memory map it */ if ((pmemaddr = pmem_map(dstfd)) == NULL) { perror("pmem_map"); exit(1); } close(dstfd); /* determine if range is true pmem, call appropriate copy routine */ if (pmem_is_pmem(pmemaddr, stbuf.st_size)) do_copy_to_pmem(pmemaddr, srcfd, stbuf.st_size); else do_copy_to_non_pmem(pmemaddr, srcfd, stbuf.st_size); close(srcfd); exit(0); }
int main(int argc, char *argv[]) { int fd; struct stat stbuf; char *dest; START(argc, argv, "pmem_valgr_simple"); if (argc != 4) FATAL("usage: %s file offset length", argv[0]); fd = OPEN(argv[1], O_RDWR); int dest_off = atoi(argv[2]); size_t bytes = strtoul(argv[3], NULL, 0); FSTAT(fd, &stbuf); dest = pmem_map(fd); if (dest == NULL) FATAL("!Could not mmap %s\n", argv[1]); /* these will not be made persistent */ *(int *)dest = 4; /* this will be made persistent */ uint64_t *tmp64dst = (void *)((uintptr_t)dest + 4096); *tmp64dst = 50; if (pmem_is_pmem(dest, sizeof (*tmp64dst))) { pmem_persist(tmp64dst, sizeof (*tmp64dst)); } else { pmem_msync(tmp64dst, sizeof (*tmp64dst)); } uint16_t *tmp16dst = (void *)((uintptr_t)dest + 1024); *tmp16dst = 21; /* will appear as flushed in valgrind log */ pmem_flush(tmp16dst, sizeof (*tmp16dst)); /* shows strange behavior of memset in some cases */ memset(dest + dest_off, 0, bytes); pmem_unmap(dest, stbuf.st_size); CLOSE(fd); DONE(NULL); }
PMEMobjpool * pmemobj_open_mock(const char *fname) { int fd = open(fname, O_RDWR); if (fd == -1) { OUT("!%s: open", fname); return NULL; } struct stat stbuf; if (fstat(fd, &stbuf) < 0) { OUT("!fstat"); return NULL; } ASSERT(stbuf.st_size > PMEMOBJ_POOL_HDR_SIZE); void *addr = pmem_map(fd); if (!addr) { OUT("!%s: pmem_map", fname); return NULL; } close(fd); PMEMobjpool *pop = (PMEMobjpool *)addr; VALGRIND_REMOVE_PMEM_MAPPING(addr + sizeof (pop->hdr), 4096); pop->addr = addr; pop->size = stbuf.st_size; pop->is_pmem = pmem_is_pmem(addr, stbuf.st_size); pop->rdonly = 0; if (pop->is_pmem) { pop->persist = pmem_persist; pop->flush = pmem_flush; pop->drain = pmem_drain; } else { pop->persist = (persist_fn)pmem_msync; pop->flush = (persist_fn)pmem_msync; pop->drain = pmem_drain_nop; } return pop; }
/* * pmem_memcpy_init -- benchmark initialization * * Parses command line arguments, allocates persistent memory, and maps it. */ static int pmem_memcpy_init(struct benchmark *bench, struct benchmark_args *args) { assert(bench != NULL); assert(args != NULL); int ret = 0; struct pmem_bench *pmb = malloc(sizeof (struct pmem_bench)); assert(pmb != NULL); pmb->pargs = args->opts; assert(pmb->pargs != NULL); pmb->pargs->chunk_size = args->dsize; enum operation_type op_type; /* * Assign file and buffer size depending on the operation type * (READ from PMEM or WRITE to PMEM) */ if (assign_size(pmb, args, &op_type) != 0) { ret = -1; goto err_free_pmb; } if ((errno = posix_memalign( (void **) &pmb->buf, FLUSH_ALIGN, pmb->bsize)) != 0) { perror("posix_memalign"); ret = -1; goto err_free_pmb; } pmb->n_rand_offsets = args->n_ops_per_thread * args->n_threads; pmb->rand_offsets = malloc(pmb->n_rand_offsets * sizeof (*pmb->rand_offsets)); for (size_t i = 0; i < pmb->n_rand_offsets; ++i) pmb->rand_offsets[i] = rand() % args->n_ops_per_thread; /* create a pmem file */ pmb->fd = open(args->fname, O_CREAT|O_EXCL|O_RDWR, args->fmode); if (pmb->fd == -1) { perror(args->fname); ret = -1; goto err_free_buf; } /* allocate the pmem */ if ((errno = posix_fallocate(pmb->fd, 0, pmb->fsize)) != 0) { perror("posix_fallocate"); ret = -1; goto err_close_file; } /* memory map it */ if ((pmb->pmem_addr = pmem_map(pmb->fd)) == NULL) { perror("pmem_map"); ret = -1; goto err_close_file; } if (op_type == OP_TYPE_READ) { pmb->src_addr = pmb->pmem_addr; pmb->dest_addr = pmb->buf; } else { pmb->src_addr = pmb->buf; pmb->dest_addr = pmb->pmem_addr; } /* set proper func_src() and func_dest() depending on benchmark args */ if ((pmb->func_src = assign_mode_func(pmb->pargs->src_mode)) == NULL) { fprintf(stderr, "wrong src_mode parameter -- '%s'", pmb->pargs->src_mode); ret = -1; goto err_unmap; } if ((pmb->func_dest = assign_mode_func(pmb->pargs->dest_mode)) == NULL) { fprintf(stderr, "wrong dest_mode parameter -- '%s'", pmb->pargs->dest_mode); ret = -1; goto err_unmap; } close(pmb->fd); if (pmb->pargs->memcpy) { pmb->func_op = pmb->pargs->persist ? libc_memcpy_persist : libc_memcpy; } else { pmb->func_op = pmb->pargs->persist ? libpmem_memcpy_persist : libpmem_memcpy_nodrain; } pmembench_set_priv(bench, pmb); return 0; err_unmap: munmap(pmb->pmem_addr, pmb->fsize); err_close_file: close(pmb->fd); err_free_buf: free(pmb->buf); err_free_pmb: free(pmb); return ret; }
void set_meminfo_ptr(meminfo_page_t** firstPage) { meminfo_store = (meminfo_page_t*)(((void*)*firstPage)); memzero((void*)KMEM_PMEM_DIR_LOC, KMEM_PMEM_DIR_SIZE); pmem_map(); }
int main(int argc, char *argv[]) { int srcfd; int dstfd; char buf[BUF_LEN]; char *pmemaddr; int is_pmem; int cc; if (argc != 3) { fprintf(stderr, "usage: %s src-file dst-file\n", argv[0]); exit(1); } /* open src-file */ if ((srcfd = open(argv[1], O_RDONLY)) < 0) { perror(argv[1]); exit(1); } /* create a pmem file */ if ((dstfd = open(argv[2], O_CREAT|O_EXCL|O_RDWR, 0666)) < 0) { perror(argv[2]); exit(1); } /* allocate the pmem */ if ((errno = posix_fallocate(dstfd, 0, BUF_LEN)) != 0) { perror("posix_fallocate"); exit(1); } /* memory map it */ if ((pmemaddr = pmem_map(dstfd)) == NULL) { perror("pmem_map"); exit(1); } close(dstfd); /* determine if range is true pmem */ is_pmem = pmem_is_pmem(pmemaddr, BUF_LEN); /* read up to BUF_LEN from srcfd */ if ((cc = read(srcfd, buf, BUF_LEN)) < 0) { perror("read"); exit(1); } /* write it to the pmem */ if (is_pmem) { pmem_memcpy(pmemaddr, buf, cc); } else { memcpy(pmemaddr, buf, cc); pmem_msync(pmemaddr, cc); } close(srcfd); exit(0); }
int main(int argc, char *argv[]) { char *path; size_t data_size, pool_size; int iterations; int is_pmem; int fd; uint8_t *pool; double exec_time_pmem_persist, exec_time_pmem_msync; if (argc < 4) { printf("Usage %s <file_name> <data_size> <iterations>\n", argv[0]); return 0; } path = argv[1]; data_size = atoi(argv[2]); iterations = atoi(argv[3]); pool_size = data_size * iterations; if ((fd = open(path, O_RDWR|O_CREAT|O_EXCL, S_IRWXU)) < 0) { perror("open"); return -1; } if ((errno = posix_fallocate(fd, 0, pool_size)) != 0) { perror("posix_fallocate"); goto err; } if ((pool = pmem_map(fd)) == NULL) { perror("pmem_map"); goto err; } close(fd); /* check if range is true pmem */ is_pmem = pmem_is_pmem(pool, pool_size); if (is_pmem) { /* benchmarking pmem_persist */ exec_time_pmem_persist = benchmark_func(pmem_persist, pool, data_size, iterations); } else { fprintf(stderr, "Notice: pmem_persist is not benchmarked," " because given file (%s) is not in Persistent Memory" " aware file system.\n", path); exec_time_pmem_persist = 0.0; } /* benchmarking pmem_msync */ exec_time_pmem_msync = benchmark_func((persist_fn)pmem_msync, pool, data_size, iterations); printf("%zu;%e;%zu;%e;%zu;%e\n", data_size, exec_time_pmem_persist, data_size, exec_time_pmem_msync, data_size, exec_time_pmem_persist / exec_time_pmem_msync); return 0; err: close(fd); unlink(path); return -1; }
int main(int argc, char *argv[]) { int opt; int iflag = 0; unsigned long icount; const char *path; struct stat stbuf; size_t size; int fd; char *pmaddr; Myname = argv[0]; while ((opt = getopt(argc, argv, "FMdi:")) != -1) { switch (opt) { case 'F': pmem_fit_mode(); break; case 'M': pmem_msync_mode(); break; case 'd': Debug++; break; case 'i': iflag++; icount = strtoul(optarg, NULL, 10); break; default: USAGE(NULL); } } if (optind >= argc) USAGE("No path given"); path = argv[optind++]; if (stat(path, &stbuf) < 0) { /* * file didn't exist, create it with DEFAULT_SIZE */ if ((fd = open(path, O_CREAT|O_RDWR, 0666)) < 0) FATALSYS("can't create %s", path); if ((errno = posix_fallocate(fd, 0, DEFAULT_SIZE)) != 0) FATALSYS("posix_fallocate"); size = DEFAULT_SIZE; } else { /* * file exists, just open it */ if ((fd = open(path, O_RDWR)) < 0) FATALSYS("open %s", path); size = stbuf.st_size; } /* * map the file into our address space. */ if ((pmaddr = pmem_map(fd, size)) == NULL) FATALSYS("pmem_map"); if (optind < argc) { /* strings supplied as arguments? */ int i; char *ptr = pmaddr; if (iflag) icount_start(icount); /* start instruction count */ for (i = optind; i < argc; i++) { size_t len = strlen(argv[i]) + 1; /* includes '\0' */ if (len > size) FATAL("no more room for %d-byte string", len); /* store to Persistent Memory */ strcpy(ptr, argv[i]); /* make that change durable */ pmem_persist(ptr, len, 0); ptr += len; size -= len; } if (iflag) { icount_stop(); /* end instruction count */ printf("Total instruction count: %lu\n", icount_total()); } } else { char *ptr = pmaddr; char *sep = ""; /* * dump out all the strings we find in Persistent Memory */ while (ptr < &pmaddr[size]) { /* load from Persistent Memory */ if (isprint(*ptr)) { putc(*ptr, stdout); sep = "\n"; } else if (*ptr == '\0') { fputs(sep, stdout); sep = ""; } ptr++; } } exit(0); }
int main(int argc, char *argv[]) { int fd; struct stat stbuf; void *dest; void *src; off_t dest_off = 0; off_t src_off = 0; uint64_t bytes = 0; int who = 0; off_t overlap = 0; START(argc, argv, "pmem_memmove"); fd = OPEN(argv[1], O_RDWR); FSTAT(fd, &stbuf); if (argc < 3) USAGE(); for (int arg = 2; arg < argc; arg++) { if (strchr("dsboS", argv[arg][0]) == NULL || argv[arg][1] != ':') FATAL("op must be d: or s: or b: or o: or S:"); off_t val = strtoul(&argv[arg][2], NULL, 0); switch (argv[arg][0]) { case 'd': if (val <= 0) FATAL("bad offset (%lu) with d: option", val); dest_off = val; break; case 's': if (val <= 0) FATAL("bad offset (%lu) with s: option", val); src_off = val; break; case 'b': if (val <= 0) FATAL("bad length (%lu) with b: option", val); bytes = val; break; case 'o': if (val != 1 && val != 2) FATAL("bad val (%lu) with o: option", val); who = (int)val; break; case 'S': overlap = val; break; } } if (who == 0 && overlap != 0) USAGE(); /* for overlap the src and dest must be created differently */ if (who == 0) { /* src > dest */ dest = pmem_map(fd); if (dest == NULL) FATAL("!could not mmap dest file %s", argv[1]); src = MMAP(dest + stbuf.st_size, stbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); /* * Its very unlikely that src would not be > dest. pmem_map * chooses the first unused address >= 1TB, large * enough to hold the give range, and 1GB aligned. Log * the error if the mapped addresses cannot be swapped * but allow the test to continue. */ if (src <= dest) { swap_mappings(&dest, &src, stbuf.st_size, fd); if (src <= dest) ERR("cannot map files in memory order"); } do_memmove(fd, dest, src, argv[1], dest_off, src_off, 0, bytes); /* dest > src */ swap_mappings(&dest, &src, stbuf.st_size, fd); if (dest <= src) ERR("cannot map files in memory order"); do_memmove(fd, dest, src, argv[1], dest_off, src_off, 0, bytes); MUNMAP(dest, stbuf.st_size); MUNMAP(src, stbuf.st_size); } else if (who == 1) { /* src overlap with dest */ dest = pmem_map(fd); if (dest == NULL) FATAL("!Could not mmap %s: \n", argv[1]); src = dest + overlap; memset(dest, 0, bytes); do_memmove(fd, dest, src, argv[1], dest_off, src_off, overlap, bytes); MUNMAP(dest, stbuf.st_size); } else { /* dest overlap with src */ dest = pmem_map(fd); if (dest == NULL) { FATAL("!Could not mmap %s: \n", argv[1]); } src = dest; dest = src + overlap; memset(src, 0, bytes); do_memmove(fd, dest, src, argv[1], dest_off, src_off, overlap, bytes); MUNMAP(src, stbuf.st_size); } CLOSE(fd); DONE(NULL); }
// pmemalloc_init -- setup a Persistent Memory pool for use void *pmemalloc_init(const char *path, size_t size) { int err; int fd = -1; struct stat stbuf; if (pthread_mutex_init(&pmp_mutex, NULL) != 0) { printf("\n mutex init failed\n"); exit(0); } DEBUG("path=%s size=0x%lx", path, size); pmem_orig_size = size; if (stat(path, &stbuf) < 0) { struct clump cl; init_clump(&cl); struct pool_header hdr; init_pool_header(&hdr); size_t lastclumpoff; if (errno != ENOENT) goto out; /* * file didn't exist, we're creating a new memory pool */ if (size < PMEM_MIN_POOL_SIZE) { DEBUG("size %lu too small (must be at least %lu)", size, PMEM_MIN_POOL_SIZE); errno = EINVAL; goto out; } ASSERTeq(sizeof(cl), PMEM_CHUNK_SIZE);ASSERTeq(sizeof(hdr), PMEM_PAGE_SIZE); if ((fd = open(path, O_CREAT | O_RDWR, 0666)) < 0) goto out; if ((errno = posix_fallocate(fd, 0, size)) != 0) goto out; /* * location of last clump is calculated by rounding the file * size down to a multiple of 64, and then subtracting off * another 64 to hold the struct clump. the last clump is * indicated by a size of zero (so no write is necessary * here since the file is initially zeros. */ lastclumpoff = (size & ~(PMEM_CHUNK_SIZE - 1)) - PMEM_CHUNK_SIZE; /* * create the first clump to cover the entire pool */ cl.size = lastclumpoff - PMEM_CLUMP_OFFSET; if (pwrite(fd, &cl, sizeof(cl), PMEM_CLUMP_OFFSET) < 0){ DEBUG("[0x%lx] created clump, size 0x%lx", PMEM_CLUMP_OFFSET, cl.size); goto out; } /* * write the pool header */ strcpy(hdr.signature, PMEM_SIGNATURE); hdr.totalsize = size; if (pwrite(fd, &hdr, sizeof(hdr), PMEM_HDR_OFFSET) < 0) goto out; if (fsync(fd) < 0) goto out; } else { if ((fd = open(path, O_RDWR)) < 0) goto out; size = stbuf.st_size; } /* * map the file */ if ((pmp = pmem_map(fd, size)) == NULL) { DEBUG("fd : %d size : %lu \n", fd, size); perror("mapping failed "); goto out; } return pmp; out: err = errno; if (fd != -1) close(fd); errno = err; return NULL; }
int main(int argc, char *argv[]) { START(argc, argv, "pmem_map"); if (argc != 2) FATAL("usage: %s file", argv[0]); int fd; void *addr; fd = OPEN(argv[1], O_RDWR); struct stat stbuf; FSTAT(fd, &stbuf); char pat[CHECK_BYTES]; char buf[CHECK_BYTES]; addr = pmem_map(fd); if (addr == NULL) { OUT("!pmem_map"); goto err; } /* write some pattern to the file */ memset(pat, 0x5A, CHECK_BYTES); WRITE(fd, pat, CHECK_BYTES); if (memcmp(pat, addr, CHECK_BYTES)) OUT("%s: first %d bytes do not match", argv[1], CHECK_BYTES); /* fill up mapped region with new pattern */ memset(pat, 0xA5, CHECK_BYTES); memcpy(addr, pat, CHECK_BYTES); MUNMAP(addr, stbuf.st_size); LSEEK(fd, (off_t)0, SEEK_SET); if (READ(fd, buf, CHECK_BYTES) == CHECK_BYTES) { if (memcmp(pat, buf, CHECK_BYTES)) OUT("%s: first %d bytes do not match", argv[1], CHECK_BYTES); } CLOSE(fd); /* re-open the file with read-only access */ fd = OPEN(argv[1], O_RDONLY); addr = pmem_map(fd); if (addr != NULL) { MUNMAP(addr, stbuf.st_size); OUT("expected pmem_map failure"); } err: CLOSE(fd); DONE(NULL); }
/* * pmemalloc_init -- setup a Persistent Memory pool for use * * Inputs: * path -- path to the file which will contain the memory pool * * If the file doesn't exist, it is created. If it exists, * the state of the memory pool is initialized from the file. * * size -- size of the memory pool in bytes * * The size is only used when creating the memory pool * the first time (the file created will be extended to * that size). The smallest size allowed is 1 meg. The * largest size allowed is whatever the underlaying file * system allows as a max file size. * * Outputs: * An opaque memory pool handle is returned on success. That * handle must be passed in to most of the other pmem routines. * * On error, NULL is returned and errno is set. * * This function must be called before any other pmem functions. */ void * pmemalloc_init(const char *path, size_t size) { void *pmp; int err; int fd = -1; struct stat stbuf; DEBUG("path=%s size=0x%lx", path, size); if (stat(path, &stbuf) < 0) { struct clump cl = { 0 }; struct pool_header hdr = { 0 }; size_t lastclumpoff; if (errno != ENOENT) goto out; /* * file didn't exist, we're creating a new memory pool */ if (size < PMEM_MIN_POOL_SIZE) { DEBUG("size %lu too small (must be at least %lu)", size, PMEM_MIN_POOL_SIZE); errno = EINVAL; goto out; } ASSERTeq(sizeof(cl), PMEM_CHUNK_SIZE); ASSERTeq(sizeof(hdr), PMEM_PAGE_SIZE); if ((fd = open(path, O_CREAT|O_RDWR, 0666)) < 0) goto out; if ((errno = posix_fallocate(fd, 0, size)) != 0) goto out; /* * location of last clump is calculated by rounding the file * size down to a multiple of 64, and then subtracting off * another 64 to hold the struct clump. the last clump is * indicated by a size of zero (so no write is necessary * here since the file is initially zeros. */ lastclumpoff = (size & ~(PMEM_CHUNK_SIZE - 1)) - PMEM_CHUNK_SIZE; /* * create the first clump to cover the entire pool */ cl.size = lastclumpoff - PMEM_CLUMP_OFFSET; if (pwrite(fd, &cl, sizeof(cl), PMEM_CLUMP_OFFSET) < 0) goto out; DEBUG("[0x%lx] created clump, size 0x%lx", PMEM_CLUMP_OFFSET, cl.size); /* * write the pool header */ strcpy(hdr.signature, PMEM_SIGNATURE); hdr.totalsize = size; pthread_mutex_init( &hdr.pool_lock, NULL ); pthread_mutex_init( &hdr.activation_lock, NULL ); if (pwrite(fd, &hdr, sizeof(hdr), PMEM_HDR_OFFSET) < 0) goto out; if (fsync(fd) < 0) goto out; } else { if ((fd = open(path, O_RDWR)) < 0) goto out; size = stbuf.st_size; /* XXX handle recovery case 1 described below */ } /* * map the file */ if ((pmp = pmem_map(fd, size)) == NULL) goto out; /* * scan pool for recovery work, five kinds: * 1. pmem pool file sisn't even fully setup * 2. RESERVED clumps that need to be freed * 3. ACTIVATING clumps that need to be ACTIVE * 4. FREEING clumps that need to be freed * 5. adjacent free clumps that need to be coalesced */ pmemalloc_recover(pmp); pmemalloc_coalesce_free(pmp); DEBUG("return pmp 0x%lx", pmp); return pmp; out: err = errno; if (fd != -1) close(fd); errno = err; return NULL; }
StorageManager::StorageManager() : data_file_address(nullptr), is_pmem(false), data_file_len(0), data_file_offset(0) { // Check if we need a data pool if (IsBasedOnWriteAheadLogging(peloton_logging_mode) == true || peloton_logging_mode == LOGGING_TYPE_INVALID) { return; } int data_fd; std::string data_file_name; struct stat data_stat; // Initialize file size if (peloton_data_file_size != 0) data_file_len = peloton_data_file_size * 1024 * 1024; // MB else data_file_len = DATA_FILE_LEN; // Check for relevant file system bool found_file_system = false; switch (peloton_logging_mode) { // Check for NVM FS for data case LOGGING_TYPE_NVM_NVM: case LOGGING_TYPE_NVM_HDD: case LOGGING_TYPE_NVM_SSD: { int status = stat(NVM_DIR, &data_stat); if (status == 0 && S_ISDIR(data_stat.st_mode)) { data_file_name = std::string(NVM_DIR) + std::string(DATA_FILE_NAME); found_file_system = true; } } break; // Check for SSD FS case LOGGING_TYPE_SSD_NVM: case LOGGING_TYPE_SSD_SSD: case LOGGING_TYPE_SSD_HDD: { int status = stat(SSD_DIR, &data_stat); if (status == 0 && S_ISDIR(data_stat.st_mode)) { data_file_name = std::string(SSD_DIR) + std::string(DATA_FILE_NAME); found_file_system = true; } } break; // Check for HDD FS case LOGGING_TYPE_HDD_NVM: case LOGGING_TYPE_HDD_SSD: case LOGGING_TYPE_HDD_HDD: { int status = stat(HDD_DIR, &data_stat); if (status == 0 && S_ISDIR(data_stat.st_mode)) { data_file_name = std::string(HDD_DIR) + std::string(DATA_FILE_NAME); found_file_system = true; } } break; default: break; } // Fallback to tmp directory if needed if (found_file_system == false) { int status = stat(TMP_DIR, &data_stat); if (status == 0 && S_ISDIR(data_stat.st_mode)) { data_file_name = std::string(TMP_DIR) + std::string(DATA_FILE_NAME); } else { throw Exception("Could not find temp directory : " + std::string(TMP_DIR)); } } LOG_INFO("DATA DIR :: %s ", data_file_name.c_str()); // TODO: std::cout << "Data path :: " << data_file_name << "\n"; // Create a data file if ((data_fd = open(data_file_name.c_str(), O_CREAT | O_RDWR, 0666)) < 0) { perror(data_file_name.c_str()); exit(EXIT_FAILURE); } // Allocate the data file if ((errno = posix_fallocate(data_fd, 0, data_file_len)) != 0) { perror("posix_fallocate"); exit(EXIT_FAILURE); } // memory map the data file if ((data_file_address = reinterpret_cast<char *>(pmem_map(data_fd))) == NULL) { perror("pmem_map"); exit(EXIT_FAILURE); } // true only if the entire range [addr, addr+len) consists of persistent // memory is_pmem = pmem_is_pmem(data_file_address, data_file_len); // close the pmem file -- it will remain mapped close(data_fd); }
int main(int argc, char *argv[]) { START(argc, argv, "pmem_map"); if (argc != 2) FATAL("usage: %s file", argv[0]); /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); int fd; void *addr; fd = OPEN(argv[1], O_RDWR); struct stat stbuf; FSTAT(fd, &stbuf); char pat[CHECK_BYTES]; char buf[CHECK_BYTES]; addr = pmem_map(fd); if (addr == NULL) { OUT("!pmem_map"); goto err; } /* write some pattern to the file */ memset(pat, 0x5A, CHECK_BYTES); WRITE(fd, pat, CHECK_BYTES); if (memcmp(pat, addr, CHECK_BYTES)) OUT("%s: first %d bytes do not match", argv[1], CHECK_BYTES); /* fill up mapped region with new pattern */ memset(pat, 0xA5, CHECK_BYTES); memcpy(addr, pat, CHECK_BYTES); pmem_unmap(addr, stbuf.st_size); if (!sigsetjmp(Jmp, 1)) { /* same memcpy from above should now fail */ memcpy(addr, pat, CHECK_BYTES); } else { OUT("unmap successful"); } LSEEK(fd, (off_t)0, SEEK_SET); if (READ(fd, buf, CHECK_BYTES) == CHECK_BYTES) { if (memcmp(pat, buf, CHECK_BYTES)) OUT("%s: first %d bytes do not match", argv[1], CHECK_BYTES); } CLOSE(fd); /* re-open the file with read-only access */ fd = OPEN(argv[1], O_RDONLY); addr = pmem_map(fd); if (addr != NULL) { MUNMAP(addr, stbuf.st_size); OUT("expected pmem_map failure"); } err: CLOSE(fd); DONE(NULL); }