/* * blk_do_warmup -- perform warm-up by writing to each block */ static int blk_do_warmup(struct blk_bench *bb, struct benchmark_args *args) { struct blk_args *ba = (struct blk_args *)args->opts; size_t lba; int ret = 0; char *buff = (char *)calloc(1, args->dsize); if (!buff) { perror("calloc"); return -1; } for (lba = 0; lba < bb->nblocks; ++lba) { if (ba->file_io) { size_t off = lba * args->dsize; if (pwrite(bb->fd, buff, args->dsize, off) != (ssize_t)args->dsize) { perror("pwrite"); ret = -1; goto out; } } else { if (pmemblk_write(bb->pbp, buff, lba) < 0) { perror("pmemblk_write"); ret = -1; goto out; } } } out: free(buff); return ret; }
/* * worker -- the work each thread performs */ void * worker(void *arg) { long mytid = (long)arg; unsigned myseed = Seed + mytid; unsigned char buf[Bsize]; int ord = 1; for (int i = 0; i < Nops; i++) { off_t lba = rand_r(&myseed) % Nblock; if (rand_r(&myseed) % 2) { /* read */ if (pmemblk_read(Handle, buf, lba) < 0) OUT("!read lba %zu", lba); else check(buf); } else { /* write */ construct(&ord, buf); if (pmemblk_write(Handle, buf, lba) < 0) OUT("!write lba %zu", lba); } } return NULL; }
/* * blk_write -- write function for pmemblk */ static int blk_write(struct blk_bench *bb, struct benchmark_args *ba, struct blk_worker *bworker, off_t off) { if (pmemblk_write(bb->pbp, bworker->buff, off) < 0) { perror("pmemblk_write"); return -1; } return 0; }
int main(int argc, char *argv[]) { PMEMblkpool *pbp; struct asset asset; int assetid; if (argc < 4) { fprintf(stderr, "usage: %s assetdb asset-ID name\n", argv[0]); exit(1); } const char *path = argv[1]; assetid = atoi(argv[2]); /* open an array of atomically writable elements */ if ((pbp = pmemblk_open(path, sizeof (struct asset))) == NULL) { perror("pmemblk_open"); exit(1); } /* read a required element in */ if (pmemblk_read(pbp, &asset, (off_t)assetid) < 0) { perror("pmemblk_read"); exit(1); } /* check if it contains any data */ if ((asset.state != ASSET_FREE) && (asset.state != ASSET_CHECKED_OUT)) { fprintf(stderr, "Asset ID %d not found", assetid); exit(1); } if (asset.state == ASSET_CHECKED_OUT) { fprintf(stderr, "Asset ID %d already checked out\n", assetid); exit(1); } /* update user name, set checked out state, and take timestamp */ strncpy(asset.user, argv[3], ASSET_USER_NAME_MAX - 1); asset.user[ASSET_USER_NAME_MAX - 1] = '\0'; asset.state = ASSET_CHECKED_OUT; time(&asset.time); /* put it back in the block */ if (pmemblk_write(pbp, &asset, assetid) < 0) { perror("pmemblk_write"); exit(1); } pmemblk_close(pbp); }
/* * w_worker -- write worker function */ void * w_worker(void *arg) { struct worker_info *my_info = arg; unsigned char buf[my_info->block_size]; memset(buf, 1, my_info->block_size); for (int i = 0; i < my_info->num_ops; i++) { off_t lba = rand_r(&my_info->seed) % my_info->num_blocks; if (pmemblk_write(my_info->handle, buf, lba) < 0) { warn("write lba %zu", lba); } } return NULL; }
int main(int argc, char *argv[]) { PMEMblkpool *pbp; struct asset asset; int assetid; if (argc < 3) { fprintf(stderr, "usage: %s assetdb asset-ID\n", argv[0]); exit(1); } const char *path = argv[1]; assetid = atoi(argv[2]); assert(assetid > 0); /* open an array of atomically writable elements */ if ((pbp = pmemblk_open(path, sizeof(struct asset))) == NULL) { perror("pmemblk_open"); exit(1); } /* read a required element in */ if (pmemblk_read(pbp, &asset, assetid) < 0) { perror("pmemblk_read"); exit(1); } /* check if it contains any data */ if ((asset.state != ASSET_FREE) && (asset.state != ASSET_CHECKED_OUT)) { fprintf(stderr, "Asset ID %d not found\n", assetid); exit(1); } /* change state to free, clear user name and timestamp */ asset.state = ASSET_FREE; asset.user[0] = '\0'; asset.time = 0; if (pmemblk_write(pbp, &asset, assetid) < 0) { perror("pmemblk_write"); exit(1); } pmemblk_close(pbp); }
/* * prep_worker -- worker for the prep mode. Writes the whole * calculated range of lba's. This is similar to the rf_worker. */ void * prep_worker(void *arg) { struct worker_info *my_info = arg; unsigned long long blocks_in_lane = my_info->num_blocks / my_info->file_lanes; off_t start_lba = my_info->thread_index * blocks_in_lane; off_t stop_lba = (my_info->thread_index + 1) * blocks_in_lane; unsigned char buf[my_info->block_size]; memset(buf, 1, my_info->block_size); for (off_t lba = start_lba; lba < stop_lba; ++lba) { if (pmemblk_write(my_info->handle, buf, lba) < 0) { warn("write lba %zu", lba); } } return 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); }
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); }