int main(int argc, char *argv[]) { START(argc, argv, "util_file_create"); if (argc < 3) UT_FATAL("usage: %s minlen len:path...", argv[0]); char *fname; size_t minsize = strtoul(argv[1], &fname, 0); for (int arg = 2; arg < argc; arg++) { size_t size = strtoul(argv[arg], &fname, 0); if (*fname != ':') UT_FATAL("usage: %s minlen len:path...", argv[0]); fname++; int fd; if ((fd = util_file_create(fname, size, minsize)) == -1) UT_OUT("!%s: util_file_create", fname); else { UT_OUT("%s: created", fname); close(fd); } } DONE(NULL); }
/* * pool_copy -- make a copy of the pool */ int pool_copy(struct pool_data *pool, const char *dst_path) { struct pool_set_file *file = pool->set_file; int dfd = util_file_create(dst_path, file->size, 0); if (dfd < 0) return -1; int result = 0; struct stat stat_buf; if (stat(file->fname, &stat_buf)) { result = -1; goto out_close; } if (fchmod(dfd, stat_buf.st_mode)) { result = -1; goto out_close; } void *daddr = mmap(NULL, file->size, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0); if (daddr == MAP_FAILED) { result = -1; goto out_close; } if (pool->params.type != POOL_TYPE_BTT) { void *saddr = pool_set_file_map(file, 0); memcpy(daddr, saddr, file->size); goto out_unmap; } void *buf = malloc(RW_BUFFERING_SIZE); if (buf == NULL) { ERR("!malloc"); result = -1; goto out_unmap; } pool_btt_lseek(pool, 0, SEEK_SET); ssize_t buf_read = 0; void *dst = daddr; while ((buf_read = pool_btt_read(pool, buf, RW_BUFFERING_SIZE))) { if (buf_read == -1) break; memcpy(dst, buf, (size_t)buf_read); dst = (void *)((ssize_t)dst + buf_read); } free(buf); out_unmap: munmap(daddr, file->size); out_close: if (dfd >= 0) close(dfd); return result; }
/* * util_poolset_file -- (internal) open or create a single part file */ static int util_poolset_file(struct pool_set_part *part, size_t minsize, int create) { LOG(3, "part %p minsize %zu create %d", part, minsize, create); /* check if file exists */ if (access(part->path, F_OK) == 0) create = 0; size_t size; if (create) { size = part->filesize; part->fd = util_file_create(part->path, size, minsize); part->created = 1; if (part->fd == -1) { LOG(2, "failed to create file: %s", part->path); return -1; } } else { size = 0; part->fd = util_file_open(part->path, &size, minsize, O_RDWR); part->created = 0; if (part->fd == -1) { LOG(2, "failed to open file: %s", part->path); return -1; } /* check if filesize matches */ if (part->filesize != size) { ERR("file size does not match config: %s, %zu != %zu", part->path, size, part->filesize); errno = EINVAL; return -1; } } return 0; }
/* * pool_copy -- make a copy of the pool */ int pool_copy(struct pool_data *pool, const char *dst_path, int overwrite) { struct pool_set_file *file = pool->set_file; int dfd; if (!os_access(dst_path, F_OK)) { if (!overwrite) { errno = EEXIST; return -1; } dfd = util_file_open(dst_path, NULL, 0, O_RDWR); } else { if (errno == ENOENT) { errno = 0; dfd = util_file_create(dst_path, file->size, 0); } else { return -1; } } if (dfd < 0) return -1; int result = 0; os_stat_t stat_buf; if (os_stat(file->fname, &stat_buf)) { result = -1; goto out_close; } if (fchmod(dfd, stat_buf.st_mode)) { result = -1; goto out_close; } void *daddr = mmap(NULL, file->size, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0); if (daddr == MAP_FAILED) { result = -1; goto out_close; } if (pool->params.type != POOL_TYPE_BTT) { void *saddr = pool_set_file_map(file, 0); memcpy(daddr, saddr, file->size); goto out_unmap; } void *buf = malloc(RW_BUFFERING_SIZE); if (buf == NULL) { ERR("!malloc"); result = -1; goto out_unmap; } if (pool_btt_lseek(pool, 0, SEEK_SET) == -1) { result = -1; goto out_free; } ssize_t buf_read = 0; void *dst = daddr; while ((buf_read = pool_btt_read(pool, buf, RW_BUFFERING_SIZE))) { if (buf_read == -1) break; memcpy(dst, buf, (size_t)buf_read); dst = (void *)((ssize_t)dst + buf_read); } out_free: free(buf); out_unmap: munmap(daddr, file->size); out_close: (void) os_close(dfd); return result; }
/* * util_poolset_create -- (internal) create a new memory pool set * * On success returns 0 and a pointer to a newly allocated structure * containing the info of all the parts of the pool set and replicas. */ static int util_poolset_create(struct pool_set **setp, const char *path, size_t poolsize, size_t minsize) { LOG(3, "setp %p path %s poolsize %zu minsize %zu", setp, path, poolsize, minsize); int oerrno; int ret = 0; int fd; size_t size = 0; if (poolsize != 0) { /* create a new file */ fd = util_file_create(path, poolsize, minsize); if (fd == -1) return -1; /* close the file and open with O_RDWR */ *setp = util_poolset_single(path, poolsize, fd, 1); if (*setp == NULL) { ret = -1; goto err; } /* do not close the file */ return 0; } /* do not check minsize */ if ((fd = util_file_open(path, &size, 0, O_RDONLY)) == -1) return -1; char signature[POOLSET_HDR_SIG_LEN]; ret = read(fd, signature, POOLSET_HDR_SIG_LEN); if (ret < 0) { ERR("!read %d", fd); goto err; } if (ret < POOLSET_HDR_SIG_LEN || strncmp(signature, POOLSET_HDR_SIG, POOLSET_HDR_SIG_LEN)) { LOG(4, "not a pool set header"); if (size < minsize) { ERR("size %zu smaller than %zu", size, minsize); errno = EINVAL; ret = -1; goto err; } (void) close(fd); size = 0; if ((fd = util_file_open(path, &size, 0, O_RDWR)) == -1) return -1; *setp = util_poolset_single(path, size, fd, 0); if (*setp == NULL) { ret = -1; goto err; } /* do not close the file */ return 0; } ret = util_poolset_parse(path, fd, setp); if (ret != 0) goto err; ret = util_poolset_files(*setp, minsize, 1); if (ret != 0) util_poolset_close(*setp, 1); err: oerrno = errno; (void) close(fd); errno = oerrno; return ret; }