static void pool_create(const char *path, size_t bsize, size_t poolsize, unsigned mode) { PMEMblkpool *pbp = pmemblk_create(path, bsize, poolsize, mode); if (pbp == NULL) UT_OUT("!%s: pmemblk_create", path); else { struct stat stbuf; STAT(path, &stbuf); UT_OUT("%s: file size %zu usable blocks %zu mode 0%o", path, stbuf.st_size, pmemblk_nblock(pbp), stbuf.st_mode & 0777); pmemblk_close(pbp); int result = pmemblk_check(path, bsize); if (result < 0) UT_OUT("!%s: pmemblk_check", path); else if (result == 0) UT_OUT("%s: pmemblk_check: not consistent", path); else UT_ASSERTeq(pmemblk_check(path, bsize * 2), -1); } }
int main(int argc, char *argv[]) { PMEMblkpool *pbp; int assetid; size_t nelements; struct asset asset; if (argc < 2) { fprintf(stderr, "usage: %s assetdb\n", argv[0]); exit(1); } const char *path = argv[1]; /* open an array of atomically writable elements */ if ((pbp = pmemblk_open(path, sizeof(struct asset))) == NULL) { perror(path); exit(1); } /* how many elements do we have? */ nelements = pmemblk_nblock(pbp); /* print out all the elements that contain assets data */ for (assetid = 0; assetid < nelements; ++assetid) { if (pmemblk_read(pbp, &asset, assetid) < 0) { perror("pmemblk_read"); exit(1); } if ((asset.state != ASSET_FREE) && (asset.state != ASSET_CHECKED_OUT)) { break; } printf("Asset ID: %d\n", assetid); if (asset.state == ASSET_FREE) printf(" State: Free\n"); else { printf(" State: Checked out\n"); printf(" User: %s\n", asset.user); printf(" Time: %s", ctime(&asset.time)); } printf(" Name: %s\n", asset.name); } pmemblk_close(pbp); }
int main(int argc, char *argv[]) { START(argc, argv, "blk_rw_mt"); if (argc != 6) FATAL("usage: %s bsize file seed nthread nops", argv[0]); Bsize = strtoul(argv[1], NULL, 0); const char *path = argv[2]; if ((Handle = pmemblk_pool_open(path, Bsize)) == NULL) FATAL("!%s: pmemblk_pool_open", path); if (Nblock == 0) Nblock = pmemblk_nblock(Handle); Seed = strtoul(argv[3], NULL, 0); Nthread = strtoul(argv[4], NULL, 0); Nops = strtoul(argv[5], NULL, 0); OUT("%s block size %zu usable blocks %zu", argv[1], Bsize, Nblock); pthread_t threads[Nthread]; /* kick off nthread threads */ for (int i = 0; i < Nthread; i++) PTHREAD_CREATE(&threads[i], NULL, worker, (void *)(long)i); /* wait for all the threads to complete */ for (int i = 0; i < Nthread; i++) PTHREAD_JOIN(threads[i], NULL); pmemblk_pool_close(Handle); /* XXX not ready to pass this part of the test yet */ int result = pmemblk_pool_check(path); if (result < 0) OUT("!%s: pmemblk_pool_check", path); else if (result == 0) OUT("%s: pmemblk_pool_check: not consistent", path); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "blk_nblock"); if (argc < 2) FATAL("usage: %s bsize:file...", argv[0]); /* map each file argument with the given map type */ for (int arg = 1; arg < argc; arg++) { char *fname; size_t bsize = strtoul(argv[arg], &fname, 0); if (*fname != ':') FATAL("usage: %s bsize:file...", argv[0]); fname++; PMEMblkpool *handle; handle = pmemblk_create(fname, bsize, 0, S_IWUSR | S_IRUSR); if (handle == NULL) { OUT("!%s: pmemblk_create", fname); } else { OUT("%s: block size %zu usable blocks: %zu", fname, bsize, pmemblk_nblock(handle)); ASSERTeq(pmemblk_bsize(handle), bsize); pmemblk_close(handle); int result = pmemblk_check(fname, bsize); if (result < 0) OUT("!%s: pmemblk_check", fname); else if (result == 0) OUT("%s: pmemblk_check: not consistent", fname); else { ASSERTeq(pmemblk_check(fname, bsize + 1), -1); ASSERTeq(pmemblk_check(fname, 0), 1); handle = pmemblk_open(fname, 0); ASSERTeq(pmemblk_bsize(handle), bsize); pmemblk_close(handle); } } } DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "blk_non_zero"); if (argc < 5) UT_FATAL("usage: %s bsize file func [file_size] op:lba...", argv[0]); int read_arg = 1; Bsize = strtoul(argv[read_arg++], NULL, 0); const char *path = argv[read_arg++]; PMEMblkpool *handle = NULL; switch (*argv[read_arg++]) { case 'c': { size_t fsize = strtoul(argv[read_arg++], NULL, 0); handle = pmemblk_create(path, Bsize, fsize, S_IRUSR | S_IWUSR); if (handle == NULL) UT_FATAL("!%s: pmemblk_create", path); break; } case 'o': handle = pmemblk_open(path, Bsize); if (handle == NULL) UT_FATAL("!%s: pmemblk_open", path); break; default: UT_FATAL("unrecognized command %s", argv[read_arg - 1]); } UT_OUT("%s block size %zu usable blocks %zu", argv[1], Bsize, pmemblk_nblock(handle)); UT_OUT("is zeroed:\t%d", is_zeroed(path)); /* map each file argument with the given map type */ for (; read_arg < argc; read_arg++) { if (strchr("rwze", argv[read_arg][0]) == NULL || argv[read_arg][1] != ':') UT_FATAL("op must be r: or w: or z: or e:"); off_t lba = strtoul(&argv[read_arg][2], NULL, 0); unsigned char buf[Bsize]; switch (argv[read_arg][0]) { case 'r': if (pmemblk_read(handle, buf, lba) < 0) UT_OUT("!read lba %zu", lba); else UT_OUT("read lba %zu: %s", lba, ident(buf)); break; case 'w': construct(buf); if (pmemblk_write(handle, buf, lba) < 0) UT_OUT("!write lba %zu", lba); else UT_OUT("write lba %zu: %s", lba, ident(buf)); break; case 'z': if (pmemblk_set_zero(handle, lba) < 0) UT_OUT("!set_zero lba %zu", lba); else UT_OUT("set_zero lba %zu", lba); break; case 'e': if (pmemblk_set_error(handle, lba) < 0) UT_OUT("!set_error lba %zu", lba); else UT_OUT("set_error lba %zu", lba); break; } } pmemblk_close(handle); int result = pmemblk_check(path, Bsize); if (result < 0) UT_OUT("!%s: pmemblk_check", path); else if (result == 0) UT_OUT("%s: pmemblk_check: not consistent", path); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "blk_recovery"); if (argc != 5) FATAL("usage: %s bsize file first_lba lba", argv[0]); Bsize = strtoul(argv[1], NULL, 0); const char *path = argv[2]; PMEMblkpool *handle; if ((handle = pmemblk_create(path, Bsize, 0, S_IWUSR | S_IRUSR)) == NULL) FATAL("!%s: pmemblk_create", path); OUT("%s block size %zu usable blocks %zu", argv[1], Bsize, pmemblk_nblock(handle)); /* write the first lba */ off_t lba = strtoul(argv[3], NULL, 0); unsigned char buf[Bsize]; construct(buf); if (pmemblk_write(handle, buf, lba) < 0) FATAL("!write lba %zu", lba); OUT("write lba %zu: %s", lba, ident(buf)); /* reach into the layout and write-protect the map */ struct btt_info *infop = (void *)handle + roundup(sizeof (struct pmemblk), BLK_FORMAT_DATA_ALIGN); void *mapaddr = (void *)infop + le32toh(infop->mapoff); void *flogaddr = (void *)infop + le32toh(infop->flogoff); OUT("write-protecting map, length %zu", (size_t)(flogaddr - mapaddr)); MPROTECT(mapaddr, (size_t)(flogaddr - mapaddr), PROT_READ); /* arrange to catch SEGV */ struct sigaction v; sigemptyset(&v.sa_mask); v.sa_flags = 0; v.sa_handler = signal_handler; SIGACTION(SIGSEGV, &v, NULL); /* map each file argument with the given map type */ lba = strtoul(argv[4], NULL, 0); construct(buf); if (!sigsetjmp(Jmp, 1)) { if (pmemblk_write(handle, buf, lba) < 0) FATAL("!write lba %zu", lba); else FATAL("write lba %zu: %s", lba, ident(buf)); } pmemblk_close(handle); int result = pmemblk_check(path); if (result < 0) OUT("!%s: pmemblk_check", path); else if (result == 0) OUT("%s: pmemblk_check: not consistent", path); else OUT("%s: consistent", path); DONE(NULL); }
static fio_pmemblk_file_t pmb_open(const char *pathspec, int flags) { fio_pmemblk_file_t pmb; char *path = NULL; uint64_t bsize = 0; uint64_t fsize = 0; pmb_parse_path(pathspec, &path, &bsize, &fsize); if (!path) return NULL; pthread_mutex_lock(&CacheLock); pmb = fio_pmemblk_cache_lookup(path); if (!pmb) { /* load libpmemblk if needed */ if (!pmemblk_open) if (load_libpmemblk(getenv("FIO_PMEMBLK_LIB"))) goto error; pmb = malloc(sizeof(*pmb)); if (!pmb) goto error; /* try opening existing first, create it if needed */ pmb->pmb_pool = pmemblk_open(path, bsize); if (!pmb->pmb_pool && (errno == ENOENT) && (flags & PMB_CREATE) && (0 < fsize) && (0 < bsize)) { pmb->pmb_pool = pmemblk_create(path, bsize, fsize, 0644); } if (!pmb->pmb_pool) { log_err ("fio: enable to open pmemblk pool file (errno %d)\n", errno); goto error; } pmb->pmb_filename = path; pmb->pmb_next = NULL; pmb->pmb_refcnt = 0; pmb->pmb_bsize = pmemblk_bsize(pmb->pmb_pool); pmb->pmb_nblocks = pmemblk_nblock(pmb->pmb_pool); fio_pmemblk_cache_insert(pmb); } pmb->pmb_refcnt += 1; pthread_mutex_unlock(&CacheLock); return pmb; error: if (pmb) { if (pmb->pmb_pool) pmemblk_close(pmb->pmb_pool); pmb->pmb_pool = NULL; pmb->pmb_filename = NULL; free(pmb); } if (path) free(path); pthread_mutex_unlock(&CacheLock); return NULL; }
int main(int argc, char *argv[]) { START(argc, argv, "blk_rw"); if (argc < 5) FATAL("usage: %s bsize file func op:lba...", argv[0]); Bsize = strtoul(argv[1], NULL, 0); const char *path = argv[2]; PMEMblkpool *handle; switch (*argv[3]) { case 'c': handle = pmemblk_create(path, Bsize, 0, S_IWUSR | S_IRUSR); if (handle == NULL) FATAL("!%s: pmemblk_create", path); break; case 'o': handle = pmemblk_open(path, Bsize); if (handle == NULL) FATAL("!%s: pmemblk_open", path); break; } OUT("%s block size %zu usable blocks %zu", argv[1], Bsize, pmemblk_nblock(handle)); /* map each file argument with the given map type */ for (int arg = 4; arg < argc; arg++) { if (strchr("rwze", argv[arg][0]) == NULL || argv[arg][1] != ':') FATAL("op must be r: or w: or z: or e:"); off_t lba = strtol(&argv[arg][2], NULL, 0); unsigned char buf[Bsize]; switch (argv[arg][0]) { case 'r': if (pmemblk_read(handle, buf, lba) < 0) OUT("!read lba %jd", lba); else OUT("read lba %jd: %s", lba, ident(buf)); break; case 'w': construct(buf); if (pmemblk_write(handle, buf, lba) < 0) OUT("!write lba %jd", lba); else OUT("write lba %jd: %s", lba, ident(buf)); break; case 'z': if (pmemblk_set_zero(handle, lba) < 0) OUT("!set_zero lba %jd", lba); else OUT("set_zero lba %jd", lba); break; case 'e': if (pmemblk_set_error(handle, lba) < 0) OUT("!set_error lba %jd", lba); else OUT("set_error lba %jd", lba); break; } } pmemblk_close(handle); int result = pmemblk_check(path, Bsize); if (result < 0) OUT("!%s: pmemblk_check", path); else if (result == 0) OUT("%s: pmemblk_check: not consistent", path); DONE(NULL); }
int main(int argc, char *argv[]) { FILE *fp; int len = ASSET_NAME_MAX; PMEMblkpool *pbp; int assetid = 0; size_t nelements; char *line; if (argc < 3) { fprintf(stderr, "usage: %s assetdb assetlist\n", argv[0]); exit(1); } const char *path_pool = argv[1]; const char *path_list = argv[2]; /* create pmemblk pool in existing (but as yet unmodified) file */ pbp = pmemblk_create(path_pool, sizeof(struct asset), 0, CREATE_MODE_RW); if (pbp == NULL) { perror(path_pool); exit(1); } nelements = pmemblk_nblock(pbp); if ((fp = fopen(path_list, "r")) == NULL) { perror(path_list); exit(1); } /* * Read in all the assets from the assetfile and put them in the * array, if a name of the asset is longer than ASSET_NAME_SIZE_MAX, * truncate it. */ line = malloc(len); if (line == NULL) { perror("malloc"); exit(1); } while (fgets(line, len, fp) != NULL) { struct asset asset; if (assetid >= nelements) { fprintf(stderr, "%s: too many assets to fit in %s " "(only %d assets loaded)\n", path_list, path_pool, assetid); exit(1); } memset(&asset, '\0', sizeof(asset)); asset.state = ASSET_FREE; strncpy(asset.name, line, ASSET_NAME_MAX - 1); asset.name[ASSET_NAME_MAX - 1] = '\0'; if (pmemblk_write(pbp, &asset, assetid) < 0) { perror("pmemblk_write"); exit(1); } assetid++; } free(line); fclose(fp); pmemblk_close(pbp); }
int main(int argc, char *argv[]) { START(argc, argv, "out_err_mt"); if (argc != 5) UT_FATAL("usage: %s filename1 filename2 filename3 dir", argv[0]); PMEMobjpool *pop = pmemobj_create(argv[1], "test", PMEMOBJ_MIN_POOL, 0666); PMEMlogpool *plp = pmemlog_create(argv[2], PMEMLOG_MIN_POOL, 0666); PMEMblkpool *pbp = pmemblk_create(argv[3], 128, PMEMBLK_MIN_POOL, 0666); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ VMEM *vmp = vmem_create(argv[4], VMEM_MIN_POOL); #endif util_init(); pmem_check_version(10000, 0); pmemobj_check_version(10001, 0); pmemlog_check_version(10002, 0); pmemblk_check_version(10003, 0); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ vmem_check_version(10004, 0); #endif pmempool_check_version(10005, 0); print_errors("version check"); void *ptr = NULL; /* * We are testing library error reporting and we don't want this test * to fail under memcheck. */ VALGRIND_DO_DISABLE_ERROR_REPORTING; pmem_msync(ptr, 1); VALGRIND_DO_ENABLE_ERROR_REPORTING; print_errors("pmem_msync"); pmemlog_append(plp, NULL, PMEMLOG_MIN_POOL); print_errors("pmemlog_append"); size_t nblock = pmemblk_nblock(pbp); pmemblk_set_error(pbp, nblock + 1); print_errors("pmemblk_set_error"); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ VMEM *vmp2 = vmem_create_in_region(NULL, 1); UT_ASSERTeq(vmp2, NULL); print_errors("vmem_create_in_region"); #endif run_mt_test(do_test); pmemobj_close(pop); pmemlog_close(plp); pmemblk_close(pbp); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ vmem_delete(vmp); #endif PMEMpoolcheck *ppc; struct pmempool_check_args args = {0, }; ppc = pmempool_check_init(&args, sizeof(args) / 2); UT_ASSERTeq(ppc, NULL); print_errors("pmempool_check_init"); DONE(NULL); }
/* * blk_init -- function for initialization benchmark */ static int blk_init(struct blk_bench *bb, struct benchmark_args *args) { struct blk_args *ba = (struct blk_args *)args->opts; assert(ba != NULL); if (ba->fsize == 0) ba->fsize = PMEMBLK_MIN_POOL; if (ba->fsize / args->dsize < args->n_threads || ba->fsize < PMEMBLK_MIN_POOL) { fprintf(stderr, "too small file size\n"); return -1; } if (args->dsize >= ba->fsize) { fprintf(stderr, "block size bigger than file size\n"); return -1; } if (args->is_poolset) { if (args->fsize < ba->fsize) { fprintf(stderr, "insufficient size of poolset\n"); return -1; } ba->fsize = 0; } bb->fd = -1; /* * Create pmemblk in order to get the number of blocks * even for file-io mode. */ bb->pbp = pmemblk_create(args->fname, args->dsize, ba->fsize, args->fmode); if (bb->pbp == NULL) { perror("pmemblk_create"); return -1; } bb->nblocks = pmemblk_nblock(bb->pbp); if (bb->nblocks < args->n_threads) { fprintf(stderr, "too small file size"); goto out_close; } if (ba->file_io) { pmemblk_close(bb->pbp); bb->pbp = NULL; int flags = O_RDWR | O_CREAT | O_SYNC; #ifdef _WIN32 flags |= O_BINARY; #endif bb->fd = os_open(args->fname, flags, args->fmode); if (bb->fd < 0) { perror("open"); return -1; } } bb->blocks_per_thread = bb->nblocks / args->n_threads; if (!ba->no_warmup) { if (blk_do_warmup(bb, args) != 0) goto out_close; } return 0; out_close: if (ba->file_io) os_close(bb->fd); else pmemblk_close(bb->pbp); return -1; }
int main(int argc, char *argv[]) { struct blk_arguments arguments; /* set the random seed value */ srand(time(NULL)); /* set default values */ memset(&arguments, 0, sizeof (struct blk_arguments)); arguments.block_size = 512; arguments.num_ops = 100; arguments.file_size = (PMEMBLK_MIN_POOL / 1024) / 1024; if (argp_parse(&argp, argc, argv, 0, 0, &arguments) != 0) { exit(1); } struct worker_info worker_params[arguments.thread_count]; memset(worker_params, 0, sizeof (struct worker_info)); /* set common values */ worker_params[0].block_size = arguments.block_size; worker_params[0].num_ops = arguments.num_ops; worker_params[0].file_lanes = arguments.thread_count; /* file_size is provided in MB */ unsigned long long file_size_bytes = arguments.file_size * 1024 * 1024; worker *thread_workers = NULL; /* prepare parameters specific for file/pmem */ if (arguments.file_io) { /* prepare open flags */ int flags = O_RDWR | O_CREAT | O_SYNC; /* create file on PMEM-aware file system */ if ((worker_params[0].file_desc = open(arguments.file_path, flags, FILE_MODE)) < 0) { perror(arguments.file_path); exit(1); } /* pre-allocate file_size MB of persistent memory */ if ((errno = posix_fallocate(worker_params[0].file_desc, (off_t)0, (off_t)file_size_bytes)) != 0) { warn("posix_fallocate"); close(worker_params[0].file_desc); exit(1); } worker_params[0].num_blocks = file_size_bytes / worker_params[0].block_size; thread_workers = file_workers; } else { worker_params[0].file_desc = -1; if (arguments.prep_blk_file) { if ((worker_params[0].handle = pmemblk_create( arguments.file_path, worker_params[0].block_size, (off_t)file_size_bytes, FILE_MODE)) == NULL) { err(1, "%s: pmemblk_open", argv[2]); } } else { if ((worker_params[0].handle = pmemblk_open( arguments.file_path, worker_params[0].block_size)) == NULL) { err(1, "%s: pmemblk_open", argv[2]); } } worker_params[0].num_blocks = pmemblk_nblock( worker_params[0].handle); thread_workers = pmem_workers; } /* propagate params to each info_t */ for (int i = 1; i < arguments.thread_count; ++i) { memcpy(&worker_params[i], &worker_params[0], sizeof (struct worker_info)); worker_params[i].thread_index = i; worker_params[i].seed = rand(); } /* The blk mode file prep */ if (arguments.prep_blk_file) { if (worker_params[0].file_desc >= 0) close(worker_params[0].file_desc); return run_threads(prep_worker, arguments.thread_count, worker_params); } struct measurements perf_meas; perf_meas.total_ops = arguments.thread_count * worker_params[0].num_ops; /* perform PMEMBLK warmup */ if (!arguments.file_io) { if (run_threads(warmup_worker, arguments.thread_count, worker_params) != 0) { if (worker_params[0].file_desc >= 0) close(worker_params[0].file_desc); exit(1); } } for (int i = 0; i < WORKER_COUNT_MAX; ++i) { clock_gettime(CLOCK_MONOTONIC, &perf_meas.start_time); if (run_threads(thread_workers[i], arguments.thread_count, worker_params) != 0) { if (worker_params[0].file_desc >= 0) close(worker_params[0].file_desc); exit(1); } clock_gettime(CLOCK_MONOTONIC, &perf_meas.stop_time); calculate_stats(&perf_meas); printf("%f;%f;", perf_meas.total_run_time, perf_meas.ops_per_second); } printf("\n"); if (worker_params[0].file_desc >= 0) close(worker_params[0].file_desc); /* cleanup and check pmem file */ if (!arguments.file_io) { pmemblk_close(worker_params[0].handle); /* not really necessary, but check consistency */ int result = pmemblk_check(arguments.file_path); if (result < 0) { warn("%s: pmemblk_check", arguments.file_path); } else if (result == 0) { warnx("%s: pmemblk_check: not consistent", arguments.file_path); } } exit(0); }