int sandbox_read_fdt_from_file(void) { struct sandbox_state *state = state_get_current(); const char *fname = state->fdt_fname; void *blob; loff_t size; int err; int fd; blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); if (!state->fdt_fname) { err = fdt_create_empty_tree(blob, 256); if (!err) goto done; printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); return -EINVAL; } err = os_get_filesize(fname, &size); if (err < 0) { printf("Failed to file FDT file '%s'\n", fname); return err; } fd = os_open(fname, OS_O_RDONLY); if (fd < 0) { printf("Failed to open FDT file '%s'\n", fname); return -EACCES; } if (os_read(fd, blob, size) != size) { os_close(fd); return -EIO; } os_close(fd); done: gd->fdt_blob = blob; return 0; }
static int state_read_file(struct sandbox_state *state, const char *fname) { loff_t size; int ret; int fd; ret = os_get_filesize(fname, &size); if (ret < 0) { printf("Cannot find sandbox state file '%s'\n", fname); return ret; } state->state_fdt = os_malloc(size); if (!state->state_fdt) { puts("No memory to read sandbox state\n"); return -ENOMEM; } fd = os_open(fname, OS_O_RDONLY); if (fd < 0) { printf("Cannot open sandbox state file '%s'\n", fname); ret = -EPERM; goto err_open; } if (os_read(fd, state->state_fdt, size) != size) { printf("Cannot read sandbox state file '%s'\n", fname); ret = -EIO; goto err_read; } os_close(fd); return 0; err_read: os_close(fd); err_open: os_free(state->state_fdt); state->state_fdt = NULL; return ret; }
/* * check_cpu_cache -- (internal) check if file contains "cpu_cache" entry */ static int check_cpu_cache(const char *domain_path) { LOG(3, "domain_path: %s", domain_path); char domain_value[DOMAIN_VALUE_LEN]; int domain_fd; int cpu_cache = 0; if ((domain_fd = os_open(domain_path, O_RDONLY)) < 0) { LOG(1, "!open(\"%s\", O_RDONLY)", domain_path); goto end; } ssize_t len = read(domain_fd, domain_value, DOMAIN_VALUE_LEN); if (len < 0) { ERR("!read(%d, %p, %d)", domain_fd, domain_value, DOMAIN_VALUE_LEN); cpu_cache = -1; goto end; } else if (len == 0) { errno = ENODATA; ERR("read(%d, %p, %d) empty string", domain_fd, domain_value, DOMAIN_VALUE_LEN); cpu_cache = -1; goto end; } else if (domain_value[len - 1] != '\n') { ERR("!read(%d, %p, %d) invalid format", domain_fd, domain_value, DOMAIN_VALUE_LEN); cpu_cache = -1; goto end; } LOG(15, "detected persistent_domain: %s", domain_value); if (strncmp(domain_value, "cpu_cache", strlen("cpu_cache")) == 0) { LOG(15, "cpu_cache in persistent_domain: %s", domain_path); cpu_cache = 1; } else { LOG(15, "cpu_cache not in persistent_domain: %s", domain_path); cpu_cache = 0; } end: if (domain_fd >= 0) os_close(domain_fd); return cpu_cache; }
bool module_file_has_module_header(const char *filename) { bool res = false; struct mach_header hdr; file_t fd = os_open(filename, OS_OPEN_READ); if (fd == INVALID_FILE) return false; if (os_read(fd, &hdr, sizeof(hdr)) == sizeof(hdr) && is_macho_header((app_pc)&hdr, sizeof(hdr))) res = true; os_close(fd); return res; }
/* * util_file_pread -- reads from a file with an offset */ ssize_t util_file_pread(const char *path, void *buffer, size_t size, os_off_t offset) { LOG(3, "path \"%s\" buffer %p size %zu offset %ju", path, buffer, size, offset); enum file_type type = util_file_get_type(path); if (type < 0) return -1; if (type == TYPE_NORMAL) { int fd = util_file_open(path, NULL, 0, O_RDONLY); if (fd < 0) { LOG(2, "failed to open file \"%s\"", path); return -1; } ssize_t read_len = pread(fd, buffer, size, offset); int olderrno = errno; (void) os_close(fd); errno = olderrno; return read_len; } ssize_t file_size = util_file_get_size(path); if (file_size < 0) { LOG(2, "cannot determine file length \"%s\"", path); return -1; } size_t max_size = (size_t)(file_size - offset); if (size > max_size) { LOG(2, "requested size of read goes beyond the file length, " "%zu > %zu", size, max_size); LOG(4, "adjusting size to %zu", max_size); size = max_size; } void *addr = util_file_map_whole(path); if (addr == NULL) { LOG(2, "failed to map entire file \"%s\"", path); return -1; } memcpy(buffer, ADDR_SUM(addr, offset), size); util_unmap(addr, (size_t)file_size); return (ssize_t)size; }
int sandbox_fs_read_at(const char *filename, loff_t pos, void *buffer, loff_t maxsize, loff_t *actread) { loff_t size; int fd, ret; fd = os_open(filename, OS_O_RDONLY); if (fd < 0) return fd; ret = os_lseek(fd, pos, OS_SEEK_SET); if (ret == -1) { os_close(fd); return ret; } if (!maxsize) { ret = os_get_filesize(filename, &size); if (ret) { os_close(fd); return ret; } maxsize = size; } size = os_read(fd, buffer, maxsize); os_close(fd); if (size < 0) { ret = -1; } else { ret = 0; *actread = size; } return ret; }
static void copy_files(const char *fname, void *arg) { struct CopyFileArg *cfa = (struct CopyFileArg *)arg; OutStream *os = cfa->to_store->new_output(cfa->to_store, fname); InStream *is = cfa->from_store->open_input(cfa->from_store, fname); int len = (int)is_length(is); uchar *buffer = ALLOC_N(uchar, len + 1); is_read_bytes(is, buffer, len); os_write_bytes(os, buffer, len); is_close(is); os_close(os); free(buffer); }
static int server_close( u8 *p ) { int fd; log_msg( "server_close: request handler starting\n" ); if( remotefs_close_read_request( p, &fd ) == ELUARPC_ERR ) { log_msg( "server_close: unable to read request\n" ); return SERVER_ERR; } log_msg( "server_close: fd = %d\n", fd ); fd = os_close( fd ); log_msg( "server_close: OS response is %d\n", fd ); remotefs_close_write_response( p, fd ); return SERVER_OK; }
/* * util_tmpfile -- create a temporary file */ int util_tmpfile(const char *dir, const char *templ) { LOG(3, "dir \"%s\" template \"%s\"", dir, templ); int oerrno; int fd = -1; char fullname[MAX_PATH]; int ret = _snprintf(fullname, MAX_PATH, "%s%s", dir, templ); if (ret < 0 || ret >= MAX_PATH) { ERR("!snprintf"); goto err; } LOG(4, "fullname \"%s\"", fullname); /* * XXX - block signals and modify file creation mask for the time * of mkstmep() execution. Restore previous settings once the file * is created. */ fd = os_mkstemp(fullname); if (fd < 0) { ERR("!os_mkstemp"); goto err; } /* * There is no point to use unlink() here. First, because it does not * work on open files. Second, because the file is created with * O_TEMPORARY flag, and it looks like such temp files cannot be open * from another process, even though they are visible on * the filesystem. */ return fd; err: oerrno = errno; if (fd != -1) (void) os_close(fd); errno = oerrno; return -1; }
/* * NAME: vol->close() * DESCRIPTION: close access path to volume source */ int v_close(hfsvol *vol) { int result = 0; if (vol->flags & HFS_VOL_OPEN) { if (vol->flags & HFS_VOL_USECACHE) result = b_finish(vol); vol->flags &= ~HFS_VOL_OPEN; if (os_close(&vol->priv) == -1) result = -1; } return result; }
s32 DI_Config_Save(void) { s32 fd, ret; /* Open /dev/di */ fd = os_open("/dev/di", 0); if (fd < 0) return fd; /* Save config */ inbuf[0] = IOCTL_DI_SAVE_CONFIG << 24; ret = os_ioctl(fd, IOCTL_DI_SAVE_CONFIG, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); /* Close /dev/di */ os_close(fd); return ret; }
void kstat_exit() { if (!DYNAMO_OPTION(kstats)) return; /* report merged process statistics */ mutex_lock(&process_kstats_lock); print_file(process_kstats_outfile, "Process KSTATS:\n"); kstat_report(process_kstats_outfile, &process_kstats); mutex_unlock(&process_kstats_lock); DELETE_LOCK(process_kstats_lock); #ifndef DEBUG os_close(process_kstats_outfile); #endif }
/* * Make a test fdt * * @param fdt Device tree pointer * @param size Size of device tree blob * @param aliases Specifies alias assignments. Format is a list of items * separated by space. Items are #a where * # is the alias number * a is the node to point to * @param nodes Specifies nodes to generate (a=0, b=1), upper case * means to create a disabled node */ static int make_fdt(void *fdt, int size, const char *aliases, const char *nodes) { char name[20], value[20]; const char *s; int fd; CHECK(fdt_create(fdt, size)); CHECK(fdt_finish_reservemap(fdt)); CHECK(fdt_begin_node(fdt, "")); CHECK(fdt_begin_node(fdt, "aliases")); for (s = aliases; *s;) { sprintf(name, "i2c%c", *s); sprintf(value, "/i2c%d@0", s[1] - 'a'); CHECK(fdt_property_string(fdt, name, value)); s += 2 + (s[2] != '\0'); } CHECK(fdt_end_node(fdt)); for (s = nodes; *s; s++) { sprintf(value, "i2c%d@0", (*s & 0xdf) - 'A'); CHECK(fdt_begin_node(fdt, value)); CHECK(fdt_property_string(fdt, "compatible", fdtdec_get_compatible(COMPAT_UNKNOWN))); if (*s <= 'Z') CHECK(fdt_property_string(fdt, "status", "disabled")); CHECK(fdt_end_node(fdt)); } CHECK(fdt_end_node(fdt)); CHECK(fdt_finish(fdt)); CHECK(fdt_pack(fdt)); #if defined(DEBUG) && defined(CONFIG_SANDBOX) fd = os_open("/tmp/fdtdec-text.dtb", OS_O_CREAT | OS_O_WRONLY); if (fd == -1) { printf("Could not open .dtb file to write\n"); return -1; } os_write(fd, fdt, size); os_close(fd); #endif return 0; }
int os_write_file(const char *name, const void *buf, int size) { char fname[256]; int fd; fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT | OS_O_TRUNC); if (fd < 0) { printf("Cannot open file '%s'\n", fname); return -EIO; } if (os_write(fd, buf, size) != size) { printf("Cannot write to file '%s'\n", fname); return -EIO; } os_close(fd); printf("Write '%s', size %#x (%d)\n", name, size, size); return 0; }
/* * os_badblocks_clear_file -- clear the given bad blocks in the regular file * (not in a dax device) */ static int os_badblocks_clear_file(const char *file, struct badblocks *bbs) { LOG(3, "file %s badblocks %p", file, bbs); ASSERTne(bbs, NULL); int ret = 0; int fd; if ((fd = os_open(file, O_RDWR)) < 0) { ERR("!open: %s", file); return -1; } for (unsigned b = 0; b < bbs->bb_cnt; b++) { off_t offset = (off_t)bbs->bbv[b].offset; off_t length = (off_t)bbs->bbv[b].length; LOG(10, "clearing bad block: logical offset %li length %li (in 512B sectors) -- '%s'", B2SEC(offset), B2SEC(length), file); /* deallocate bad blocks */ if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, length)) { ERR("!fallocate"); ret = -1; break; } /* allocate new blocks */ if (fallocate(fd, FALLOC_FL_KEEP_SIZE, offset, length)) { ERR("!fallocate"); ret = -1; break; } } os_close(fd); return ret; }
static int server_readdir( u8 *p ) { const char* name; u32 fsize = 0, d; int fd; char separator[ 2 ] = { PLATFORM_PATH_SEPARATOR, 0 }; log_msg( "server_readdir: request handler starting\n" ); if( remotefs_readdir_read_request( p, &d ) == ELUARPC_ERR ) { log_msg( "server_readdir: unable to read request\n" ); return SERVER_ERR; } log_msg( "server_readdir: DIR = %08X\n", d ); os_readdir( d, &name ); if( name ) { // Need to compute size now // Get real filename server_fullname[ 0 ] = server_fullname[ PLATFORM_MAX_FNAME_LEN ] = 0; strncpy( server_fullname, server_basedir, PLATFORM_MAX_FNAME_LEN ); if( name && strlen( name ) > 0 ) { if( server_fullname[ strlen( server_fullname ) - 1 ] != PLATFORM_PATH_SEPARATOR ) strncat( server_fullname, separator, PLATFORM_MAX_FNAME_LEN ); strncat( server_fullname, name, PLATFORM_MAX_FNAME_LEN ); } fd = os_open( server_fullname, RFS_OPEN_FLAG_RDONLY, 0 ); if( fd ) { fsize = os_lseek( fd, 0, RFS_LSEEK_END ); os_close( fd ); } else { log_msg( "server_readdir: unable to open file %s\n", server_fullname ); name = NULL; } } log_msg( "server_readdir: OS response is fname = %s, fsize = %u\n", name, ( unsigned )fsize ); remotefs_readdir_write_response( p, name, fsize, 0 ); return SERVER_OK; }
void cw_close(CompoundWriter *cw) { OutStream *os = NULL; int i; if (cw->ids->size <= 0) { RAISE(STATE_ERROR, "Tried to merge compound file with no entries"); } os = cw->store->new_output(cw->store, cw->name); os_write_vint(os, ary_size(cw->file_entries)); /* Write the directory with all offsets at 0. * Remember the positions of directory entries so that we can adjust the * offsets later */ for (i = 0; i < ary_size(cw->file_entries); i++) { cw->file_entries[i].dir_offset = os_pos(os); os_write_u64(os, 0); /* for now */ os_write_string(os, cw->file_entries[i].name); } /* Open the files and copy their data into the stream. Remember the * locations of each file's data section. */ for (i = 0; i < ary_size(cw->file_entries); i++) { cw->file_entries[i].data_offset = os_pos(os); cw_copy_file(cw, &cw->file_entries[i], os); } /* Write the data offsets into the directory of the compound stream */ for (i = 0; i < ary_size(cw->file_entries); i++) { os_seek(os, cw->file_entries[i].dir_offset); os_write_u64(os, cw->file_entries[i].data_offset); } if (os) { os_close(os); } hs_destroy(cw->ids); ary_free(cw->file_entries); free(cw); }
/* Read a file into memory and return a pointer to it */ static int read_file(struct unit_test_state *uts, const char *fname, ulong *addrp) { int buf_size = 100000; ulong addr = 0; int size, fd; char *buf; buf = map_sysmem(addr, 0); ut_assert(buf != NULL); fd = os_open(fname, OS_O_RDONLY); ut_assert(fd >= 0); size = os_read(fd, buf, buf_size); ut_assert(size >= 0); ut_assert(size < buf_size); os_close(fd); *addrp = addr; return 0; }
/* * pool_set_parse -- parse poolset file */ int pool_set_parse(struct pool_set **setp, const char *path) { LOG(3, "setp %p path %s", setp, path); int fd = os_open(path, O_RDONLY); int ret = 0; if (fd < 0) return 1; if (util_poolset_parse(setp, path, fd)) { ret = 1; goto err_close; } err_close: os_close(fd); return ret; }
int host_dev_bind(int dev, char *filename) { struct host_block_dev *host_dev = find_host_device(dev); if (!host_dev) return -1; if (host_dev->blk_dev.priv) { os_close(host_dev->fd); host_dev->blk_dev.priv = NULL; } if (host_dev->filename) free(host_dev->filename); if (filename && *filename) { host_dev->filename = strdup(filename); } else { host_dev->filename = NULL; return 0; } host_dev->fd = os_open(host_dev->filename, OS_O_RDWR); if (host_dev->fd == -1) { printf("Failed to access host backing file '%s'\n", host_dev->filename); return 1; } block_dev_desc_t *blk_dev = &host_dev->blk_dev; blk_dev->if_type = IF_TYPE_HOST; blk_dev->priv = host_dev; blk_dev->blksz = 512; blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz; blk_dev->block_read = host_block_read; blk_dev->block_write = host_block_write; blk_dev->dev = dev; blk_dev->part_type = PART_TYPE_UNKNOWN; init_part(blk_dev); return 0; }
s32 FFS_Config_Save(struct ffsConfigState *cfg) { s32 fd, ret; /* Create config file */ __Config_Create(__ffs_cfg_filename); /* Open config file */ fd = os_open(__ffs_cfg_filename, ISFS_OPEN_WRITE); if (fd < 0) return fd; /* Write config */ ret = os_write(fd, cfg, sizeof(*cfg)); if (ret != sizeof(*cfg)) ret = -1; /* Close config */ os_close(fd); return ret; }
s32 FFS_Config_Load(struct ffsConfigState *cfg) { s32 fd, ret; #ifdef DEBUG svc_write("DIP: Config_Load(): Loading config file "); svc_write(__ffs_cfg_filename); svc_write("\n"); #endif /* Open config file */ fd = os_open(__ffs_cfg_filename, ISFS_OPEN_READ); #ifdef DEBUG svc_write("DIP: Config_Load(): Config file "); svc_write(fd < 0 ? "NOT found\n" : "found\n"); #endif if (fd < 0) return fd; /* Read config */ ret = os_read(fd, cfg, sizeof(struct ffsConfigState)); if (ret != sizeof(struct ffsConfigState)) { #ifdef DEBUG svc_write("DIP: Config_Load(): Config file has unexpected size!!!\n"); #endif ret = -1; } /* Close config */ os_close(fd); /* Delete config file */ __Config_Delete(__ffs_cfg_filename); return ret; }
/* * blk_exit -- function for de-initialization benchmark */ static int blk_exit(struct benchmark *bench, struct benchmark_args *args) { struct blk_bench *bb = (struct blk_bench *)pmembench_get_priv(bench); struct blk_args *ba = (struct blk_args *)args->opts; if (ba->file_io) { os_close(bb->fd); } else { pmemblk_close(bb->pbp); int result = pmemblk_check(args->fname, args->dsize); if (result < 0) { perror("pmemblk_check error"); return -1; } else if (result == 0) { perror("pmemblk_check: not consistent"); return -1; } } free(bb); return 0; }
int mdns_cleanup(struct mdns_ctx *ctx) { if (ctx != NULL) { if (ctx->sock != INVALID_SOCKET) { os_close(ctx->sock); ctx->sock = INVALID_SOCKET; } if (ctx->services) { struct mdns_svc *svc; while ((svc = ctx->services)) { ctx->services = ctx->services->next; if (svc->name) free(svc->name); free(svc); } } free(ctx); } if (os_cleanup() < 0) return (MDNS_NETERR); return (0); }
/* * replica_remove_part -- unlink part from replica */ int replica_remove_part(struct pool_set *set, unsigned repn, unsigned partn) { LOG(3, "set %p, repn %u, partn %u", set, repn, partn); struct pool_set_part *part = &PART(REP(set, repn), partn); if (part->fd != -1) { os_close(part->fd); part->fd = -1; } int olderrno = errno; if (util_unlink(part->path)) { if (errno != ENOENT) { ERR("!removing part %u from replica %u failed", partn, repn); return -1; } } errno = olderrno; LOG(4, "Removed part %s number %u from replica %u", part->path, partn, repn); return 0; }
int sandbox_write_state(struct sandbox_state *state, const char *fname) { struct sandbox_state_io *io; bool got_err; int size; int ret; int fd; /* Create a state FDT if we don't have one */ if (!state->state_fdt) { size = 0x4000; state->state_fdt = os_malloc(size); if (!state->state_fdt) { puts("No memory to create FDT\n"); return -ENOMEM; } ret = fdt_create_empty_tree(state->state_fdt, size); if (ret < 0) { printf("Cannot create empty state FDT: %s\n", fdt_strerror(ret)); ret = -EIO; goto err_create; } } /* Call all the state write funtcions */ got_err = false; io = ll_entry_start(struct sandbox_state_io, state_io); ret = 0; for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { ret = sandbox_write_state_node(state, io); if (ret == -EIO) break; else if (ret) got_err = true; } if (ret == -EIO) { printf("Could not write sandbox state\n"); goto err_create; } ret = fdt_pack(state->state_fdt); if (ret < 0) { printf("Cannot pack state FDT: %s\n", fdt_strerror(ret)); ret = -EINVAL; goto err_create; } size = fdt_totalsize(state->state_fdt); fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT); if (fd < 0) { printf("Cannot open sandbox state file '%s'\n", fname); ret = -EIO; goto err_create; } if (os_write(fd, state->state_fdt, size) != size) { printf("Cannot write sandbox state file '%s'\n", fname); ret = -EIO; goto err_write; } os_close(fd); debug("Wrote sandbox state to '%s'%s\n", fname, got_err ? " (with errors)" : ""); return 0; err_write: os_close(fd); err_create: os_free(state->state_fdt); return ret; }
static inline #endif int pmempool_syncU(const char *poolset, unsigned flags) { LOG(3, "poolset %s, flags %u", poolset, flags); ASSERTne(poolset, NULL); /* check if poolset has correct signature */ if (util_is_poolset_file(poolset) != 1) { ERR("file is not a poolset file"); goto err; } /* check if flags are supported */ if (check_flags_sync(flags)) { ERR("unsupported flags"); errno = EINVAL; goto err; } /* open poolset file */ int fd = util_file_open(poolset, NULL, 0, O_RDONLY); if (fd < 0) { ERR("cannot open a poolset file"); goto err; } /* fill up pool_set structure */ struct pool_set *set = NULL; if (util_poolset_parse(&set, poolset, fd)) { ERR("parsing input poolset failed"); goto err_close_file; } if (set->remote && util_remote_load()) { ERR("remote replication not available"); goto err_close_file; } /* sync all replicas */ if (replica_sync(set, NULL, flags)) { LOG(1, "synchronization failed"); goto err_close_all; } util_poolset_close(set, DO_NOT_DELETE_PARTS); os_close(fd); return 0; err_close_all: util_poolset_close(set, DO_NOT_DELETE_PARTS); err_close_file: os_close(fd); err: if (errno == 0) errno = EINVAL; return -1; }
static inline #endif int pmempool_transformU(const char *poolset_src, const char *poolset_dst, unsigned flags) { LOG(3, "poolset_src %s, poolset_dst %s, flags %u", poolset_src, poolset_dst, flags); ASSERTne(poolset_src, NULL); ASSERTne(poolset_dst, NULL); /* check if the source poolset has correct signature */ if (util_is_poolset_file(poolset_src) != 1) { ERR("source file is not a poolset file"); goto err; } /* check if the destination poolset has correct signature */ if (util_is_poolset_file(poolset_dst) != 1) { ERR("destination file is not a poolset file"); goto err; } /* check if flags are supported */ if (check_flags_transform(flags)) { ERR("unsupported flags"); errno = EINVAL; goto err; } /* open the source poolset file */ int fd_in = util_file_open(poolset_src, NULL, 0, O_RDONLY); if (fd_in < 0) { ERR("cannot open source poolset file"); goto err; } /* parse the source poolset file */ struct pool_set *set_in = NULL; if (util_poolset_parse(&set_in, poolset_src, fd_in)) { ERR("parsing source poolset failed"); os_close(fd_in); goto err; } os_close(fd_in); /* open the destination poolset file */ int fd_out = util_file_open(poolset_dst, NULL, 0, O_RDONLY); if (fd_out < 0) { ERR("cannot open destination poolset file"); goto err; } enum del_parts_mode del = DO_NOT_DELETE_PARTS; /* parse the destination poolset file */ struct pool_set *set_out = NULL; if (util_poolset_parse(&set_out, poolset_dst, fd_out)) { ERR("parsing destination poolset failed"); os_close(fd_out); goto err_free_poolin; } os_close(fd_out); /* check if the source poolset is of a correct type */ if (pool_set_type(set_in) != POOL_TYPE_OBJ) { ERR("source poolset is of a wrong type"); goto err_free_poolout; } /* load remote library if needed */ if (set_in->remote && util_remote_load()) { ERR("remote replication not available"); goto err_free_poolout; } if (set_out->remote && util_remote_load()) { ERR("remote replication not available"); goto err_free_poolout; } del = is_dry_run(flags) ? DO_NOT_DELETE_PARTS : DELETE_CREATED_PARTS; /* transform poolset */ if (replica_transform(set_in, set_out, flags)) { ERR("transformation failed"); goto err_free_poolout; } util_poolset_close(set_in, DO_NOT_DELETE_PARTS); util_poolset_close(set_out, DO_NOT_DELETE_PARTS); return 0; err_free_poolout: util_poolset_close(set_out, del); err_free_poolin: util_poolset_close(set_in, DO_NOT_DELETE_PARTS); err: if (errno == 0) errno = EINVAL; return -1; }
/* * 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; }
/* * pool_parse_params -- parse pool type, file size and block size */ static int pool_params_parse(const PMEMpoolcheck *ppc, struct pool_params *params, int check) { LOG(3, NULL); int is_btt = ppc->args.pool_type == PMEMPOOL_POOL_TYPE_BTT; params->type = POOL_TYPE_UNKNOWN; params->is_poolset = util_is_poolset_file(ppc->path) == 1; int fd = util_file_open(ppc->path, NULL, 0, O_RDONLY); if (fd < 0) return -1; int ret = 0; os_stat_t stat_buf; ret = os_fstat(fd, &stat_buf); if (ret) goto out_close; ASSERT(stat_buf.st_size >= 0); params->mode = stat_buf.st_mode; struct pool_set *set; void *addr; if (params->is_poolset) { /* * Need to close the poolset because it will be opened with * flock in the following instructions. */ os_close(fd); fd = -1; if (check) { if (pool_set_map(ppc->path, &set, 0)) return -1; } else { ret = util_poolset_create_set(&set, ppc->path, 0, 0); if (ret < 0) { LOG(2, "cannot open pool set -- '%s'", ppc->path); return -1; } if (set->remote) { ERR("poolsets with remote replicas are not " "supported"); return -1; } if (util_pool_open_nocheck(set, 0)) return -1; } params->size = set->poolsize; addr = set->replica[0]->part[0].addr; /* * XXX mprotect for device dax with length not aligned to its * page granularity causes SIGBUS on the next page fault. * The length argument of this call should be changed to * set->poolsize once the kernel issue is solved. */ if (mprotect(addr, set->replica[0]->repsize, PROT_READ) < 0) { ERR("!mprotect"); goto out_unmap; } params->is_dev_dax = set->replica[0]->part[0].is_dev_dax; } else if (is_btt) { params->size = (size_t)stat_buf.st_size; #ifndef _WIN32 if (params->mode & S_IFBLK) if (ioctl(fd, BLKGETSIZE64, ¶ms->size)) { ERR("!ioctl"); goto out_close; } #endif addr = NULL; } else { ssize_t s = util_file_get_size(ppc->path); if (s < 0) { ret = -1; goto out_close; } params->size = (size_t)s; addr = util_map(fd, params->size, MAP_SHARED, 1, 0); if (addr == NULL) { ret = -1; goto out_close; } params->is_dev_dax = util_file_is_device_dax(ppc->path); } /* stop processing for BTT device */ if (is_btt) { params->type = POOL_TYPE_BTT; params->is_part = false; goto out_close; } struct pool_hdr hdr; memcpy(&hdr, addr, sizeof(hdr)); util_convert2h_hdr_nocheck(&hdr); pool_params_from_header(params, &hdr); if (ppc->args.pool_type != PMEMPOOL_POOL_TYPE_DETECT) { enum pool_type declared_type = pool_check_type_to_pool_type(ppc->args.pool_type); if ((params->type & ~declared_type) != 0) { ERR("declared pool type does not match"); ret = 1; goto out_unmap; } } if (params->type == POOL_TYPE_BLK) { struct pmemblk pbp; memcpy(&pbp, addr, sizeof(pbp)); params->blk.bsize = le32toh(pbp.bsize); } else if (params->type == POOL_TYPE_OBJ) { struct pmemobjpool *pop = addr; memcpy(params->obj.layout, pop->layout, PMEMOBJ_MAX_LAYOUT); } out_unmap: if (params->is_poolset) { ASSERTeq(fd, -1); ASSERTne(addr, NULL); util_poolset_close(set, DO_NOT_DELETE_PARTS); } else if (!is_btt) { ASSERTne(fd, -1); ASSERTne(addr, NULL); munmap(addr, params->size); } out_close: if (fd != -1) os_close(fd); return ret; }