void do_clone() { char filename[1024]; char imagename[1024]; char lastimagename[1024]; int ret, fd; int order = 0, stripe_unit = 0, stripe_count = 0; if (randomize_striping) { order = 18 + rand() % 8; stripe_unit = 1ull << (order - 1 - (rand() % 8)); stripe_count = 2 + rand() % 14; } log4(OP_CLONE, 0, 0, 0); ++num_clones; prt("%lu clone\t%d order %d su %d sc %d\n", testcalls, num_clones, order, stripe_unit, stripe_count); clone_filename(filename, sizeof(filename), num_clones); if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { simple_err("do_clone: open", -errno); exit(162); } save_buffer(good_buf, file_size, fd); if ((ret = close(fd)) < 0) { simple_err("do_clone: close", -errno); exit(163); } if ((ret = rbd_snap_create(image, "snap")) < 0) { simple_err("do_clone: rbd create snap", ret); exit(164); } if ((ret = rbd_snap_protect(image, "snap")) < 0) { simple_err("do_clone: rbd protect snap", ret); exit(164); } clone_imagename(imagename, sizeof(imagename), num_clones); clone_imagename(lastimagename, sizeof(lastimagename), num_clones - 1); ret = rbd_clone2(ioctx, lastimagename, "snap", ioctx, imagename, RBD_FEATURES_ALL, &order, stripe_unit, stripe_count); if (ret < 0) { simple_err("do_clone: rbd clone", ret); exit(165); } rbd_close(image); if ((ret = rbd_open(ioctx, imagename, &image, NULL)) < 0) { simple_err("do_clone: rbd open", ret); exit(166); } }
void check_clones() { char filename[1024]; char imagename[1024]; int ret, fd; rbd_image_t cur_image; struct stat file_info; while (num_clones > 0) { prt("checking clone #%d\n", num_clones); --num_clones; clone_imagename(imagename, sizeof(imagename), num_clones); if ((ret = rbd_open(ioctx, imagename, &cur_image, NULL)) < 0) { simple_err("check_clones: rbd open", ret); exit(167); } clone_filename(filename, sizeof(filename), num_clones + 1); if ((fd = open(filename, O_RDONLY)) < 0) { simple_err("check_clones: open", -errno); exit(168); } prt("checking image %s against file %s\n", imagename, filename); if ((ret = fstat(fd, &file_info)) < 0) { simple_err("check_clones: fstat", -errno); exit(169); } if ((ret = pread(fd, good_buf, file_info.st_size, 0)) < 0) { simple_err("check_clones: pread", -errno); exit(170); } if ((ret = rbd_read(cur_image, 0, file_info.st_size, temp_buf)) < 0) { simple_err("check_clones: rbd_read", ret); exit(171); } close(fd); check_buffers(0, file_info.st_size); unlink(filename); /* remove the snapshot if it exists, ignore the error from the last clone. */ rbd_snap_unprotect(cur_image, "snap"); rbd_snap_remove(cur_image, "snap"); rbd_close(cur_image); rbd_remove(ioctx, imagename); } }
void check_clone(int clonenum) { char filename[128]; char imagename[128]; int ret, fd; struct rbd_ctx cur_ctx = RBD_CTX_INIT; struct stat file_info; char *good_buf, *temp_buf; clone_imagename(imagename, sizeof(imagename), clonenum); if ((ret = ops->open(imagename, &cur_ctx)) < 0) { prterrcode("check_clone: ops->open", ret); exit(167); } clone_filename(filename, sizeof(filename), clonenum + 1); if ((fd = open(filename, O_RDONLY)) < 0) { simple_err("check_clone: open", -errno); exit(168); } prt("checking clone #%d, image %s against file %s\n", clonenum, imagename, filename); if ((ret = fstat(fd, &file_info)) < 0) { simple_err("check_clone: fstat", -errno); exit(169); } good_buf = NULL; ret = posix_memalign((void **)&good_buf, MAX(writebdy, (int)sizeof(void *)), file_info.st_size); if (ret > 0) { prterrcode("check_clone: posix_memalign(good_buf)", -ret); exit(96); } temp_buf = NULL; ret = posix_memalign((void **)&temp_buf, MAX(readbdy, (int)sizeof(void *)), file_info.st_size); if (ret > 0) { prterrcode("check_clone: posix_memalign(temp_buf)", -ret); exit(97); } if ((ret = pread(fd, good_buf, file_info.st_size, 0)) < 0) { simple_err("check_clone: pread", -errno); exit(170); } if ((ret = ops->read(&cur_ctx, 0, file_info.st_size, temp_buf)) < 0) { prterrcode("check_clone: ops->read", ret); exit(171); } close(fd); if ((ret = ops->close(&cur_ctx)) < 0) { prterrcode("check_clone: ops->close", ret); exit(174); } check_buffers(good_buf, temp_buf, 0, file_info.st_size); unlink(filename); free(good_buf); free(temp_buf); }
void do_clone() { char filename[1024]; char imagename[1024]; char lastimagename[1024]; int ret, fd; int order = 0, stripe_unit = 0, stripe_count = 0; uint64_t newsize = file_size; log4(OP_CLONE, 0, 0, 0); ++num_clones; if (randomize_striping) { order = 18 + get_random() % 8; stripe_unit = 1ull << (order - 1 - (get_random() % 8)); stripe_count = 2 + get_random() % 14; } prt("%lu clone\t%d order %d su %d sc %d\n", testcalls, num_clones, order, stripe_unit, stripe_count); clone_imagename(imagename, sizeof(imagename), num_clones); clone_imagename(lastimagename, sizeof(lastimagename), num_clones - 1); assert(strcmp(lastimagename, ctx.name) == 0); ret = ops->clone(&ctx, "snap", imagename, &order, stripe_unit, stripe_count); if (ret < 0) { prterrcode("do_clone: ops->clone", ret); exit(165); } if (randomize_parent_overlap && rbd_image_has_parent(&ctx)) { int rand = get_random() % 16 + 1; // [1..16] if (rand < 13) { uint64_t overlap; ret = rbd_get_overlap(ctx.image, &overlap); if (ret < 0) { prterrcode("do_clone: rbd_get_overlap", ret); exit(1); } if (rand < 10) { // 9/16 newsize = overlap * ((double)rand / 10); newsize -= newsize % truncbdy; } else { // 3/16 newsize = 0; } assert(newsize != (uint64_t)file_size); prt("truncating image %s from 0x%llx (overlap 0x%llx) to 0x%llx\n", ctx.name, file_size, overlap, newsize); ret = ops->resize(&ctx, newsize); if (ret < 0) { prterrcode("do_clone: ops->resize", ret); exit(1); } } else if (rand < 15) { // 2/16 prt("flattening image %s\n", ctx.name); ret = ops->flatten(&ctx); if (ret < 0) { prterrcode("do_clone: ops->flatten", ret); exit(1); } } else { // 2/16 prt("leaving image %s intact\n", ctx.name); } } clone_filename(filename, sizeof(filename), num_clones); if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { simple_err("do_clone: open", -errno); exit(162); } save_buffer(good_buf, newsize, fd); if ((ret = close(fd)) < 0) { simple_err("do_clone: close", -errno); exit(163); } /* * Close parent. */ if ((ret = ops->close(&ctx)) < 0) { prterrcode("do_clone: ops->close", ret); exit(174); } /* * Open freshly made clone. */ if ((ret = ops->open(imagename, &ctx)) < 0) { prterrcode("do_clone: ops->open", ret); exit(166); } if (num_clones > 1) check_clone(num_clones - 2); }