static int init_vdi_copy_number(uint64_t oid) { char path[PATH_MAX]; int fd, flags = get_open_flags(oid, false), ret; struct sheepdog_inode *inode = xzalloc(sizeof(*inode)); snprintf(path, sizeof(path), "%s%016" PRIx64, obj_path, oid); fd = open(path, flags); if (fd < 0) { eprintf("failed to open %s, %m\n", path); ret = SD_RES_EIO; goto out; } ret = xpread(fd, inode, SD_INODE_HEADER_SIZE, 0); if (ret != SD_INODE_HEADER_SIZE) { eprintf("failed to read inode header, path=%s, %m\n", path); ret = SD_RES_EIO; goto out; } add_vdi_copy_number(oid_to_vid(oid), inode->nr_copies); ret = SD_RES_SUCCESS; out: free(inode); return SD_RES_SUCCESS; }
int default_write(uint64_t oid, struct siocb *iocb) { int flags = get_open_flags(oid, false), fd, ret = SD_RES_SUCCESS; char path[PATH_MAX]; ssize_t size; if (iocb->epoch < sys_epoch()) { dprintf("%"PRIu32" sys %"PRIu32"\n", iocb->epoch, sys_epoch()); return SD_RES_OLD_NODE_VER; } get_obj_path(oid, path); if (iocb->flags & SD_FLAG_CMD_CACHE && is_disk_cache_enabled()) flags &= ~O_DSYNC; fd = open(path, flags, def_fmode); if (fd < 0) return err_to_sderr(oid, errno); size = xpwrite(fd, iocb->buf, iocb->length, iocb->offset); if (size != iocb->length) { eprintf("failed to write object %"PRIx64", path=%s, offset=%" PRId64", size=%"PRId32", result=%zd, %m\n", oid, path, iocb->offset, iocb->length, size); ret = err_to_sderr(oid, errno); goto out; } out: close(fd); return ret; }
void DistributedLock::do_open() { /* If there is no persistence, then there is no contention for distributed locks and we can just return immediately. */ if (!object_.get_persistence_enabled()) return; #ifdef P4P_CLUSTER std::string lockfile = object_.get_file().string() + ".lock"; /* open the file */ fd_ = open(lockfile.c_str(), get_open_flags(), 0600); if (fd_ < 0) throw bfs::filesystem_error("open failed", lockfile, bs::error_code(errno, boost::system::posix_category)); /* acquire the lock */ struct flock lock; memset(&lock, 0, sizeof(lock)); lock.l_type = get_lock_type(); lock.l_whence = SEEK_SET; if (fcntl(fd_, F_SETLKW, &lock) < 0) throw bfs::filesystem_error("lock failed", lockfile, bs::error_code(errno, boost::system::posix_category)); /* ensure the local object is up to date */ try { UpgradableReadLock local_lock(object_); object_.update(*this, local_lock); } catch (distributed_object_error& e) { /* ignore exceptions */ } #else throw std::runtime_error("Persistence support not enabled"); #endif }
int default_create_and_write(uint64_t oid, struct siocb *iocb) { char path[PATH_MAX], tmp_path[PATH_MAX]; int flags = get_open_flags(oid, true); int ret, fd; uint32_t len = iocb->length; get_obj_path(oid, path); get_tmp_obj_path(oid, tmp_path); fd = open(tmp_path, flags, def_fmode); if (fd < 0) { if (errno == EEXIST) /* This happens if node membership changes during object * creation; while gateway retries a CREATE request, * recovery process could also recover the object at the * same time. They should try to write the same date, * so it is okay to simply return success here. */ dprintf("%s exists\n", tmp_path); return SD_RES_SUCCESS; eprintf("failed to open %s: %m\n", tmp_path); return err_to_sderr(oid, errno); } if (iocb->offset != 0 || iocb->length != get_objsize(oid)) { ret = prealloc(fd, get_objsize(oid)); if (ret != SD_RES_SUCCESS) goto out; } ret = xpwrite(fd, iocb->buf, len, iocb->offset); if (ret != len) { eprintf("failed to write object. %m\n"); ret = err_to_sderr(oid, errno); goto out; } ret = rename(tmp_path, path); if (ret < 0) { eprintf("failed to rename %s to %s: %m\n", tmp_path, path); ret = err_to_sderr(oid, errno); goto out; } dprintf("%"PRIx64"\n", oid); ret = SD_RES_SUCCESS; out: if (ret != SD_RES_SUCCESS) unlink(tmp_path); close(fd); return ret; }
int default_write(uint64_t oid, const struct siocb *iocb) { int flags = get_open_flags(oid, false, iocb->flags), fd, ret = SD_RES_SUCCESS; char path[PATH_MAX]; ssize_t size; if (iocb->epoch < sys_epoch()) { sd_dprintf("%"PRIu32" sys %"PRIu32"\n", iocb->epoch, sys_epoch()); return SD_RES_OLD_NODE_VER; } get_obj_path(oid, path); if (uatomic_is_true(&sys->use_journal) && journal_file_write(oid, iocb->buf, iocb->length, iocb->offset, false) != SD_RES_SUCCESS) { sd_eprintf("turn off journaling\n"); uatomic_set_false(&sys->use_journal); flags |= O_DSYNC; sync(); } fd = open(path, flags, def_fmode); if (fd < 0) return err_to_sderr(oid, errno); size = xpwrite(fd, iocb->buf, iocb->length, iocb->offset); if (size != iocb->length) { sd_eprintf("failed to write object %"PRIx64", path=%s, offset=%" PRId64", size=%"PRId32", result=%zd, %m\n", oid, path, iocb->offset, iocb->length, size); ret = err_to_sderr(oid, errno); goto out; } out: close(fd); return ret; }
static int default_read_from_path(uint64_t oid, char *path, struct siocb *iocb) { int flags = get_open_flags(oid, false), fd, ret = SD_RES_SUCCESS; ssize_t size; fd = open(path, flags); if (fd < 0) return err_to_sderr(oid, errno); size = xpread(fd, iocb->buf, iocb->length, iocb->offset); if (size != iocb->length) { eprintf("failed to read object %"PRIx64", path=%s, offset=%" PRId64", size=%"PRId32", result=%zd, %m\n", oid, path, iocb->offset, iocb->length, size); ret = err_to_sderr(oid, errno); } close(fd); return ret; }
CAMLprim value caml_sqlite3_open( value v_mode, value v_mutex, value v_cache, value v_vfs_opt, value v_file) { sqlite3 *db; int res; #ifdef SQLITE_HAS_OPEN_V2 int flags = get_open_flags(v_mode, v_mutex, v_cache); char *vfs; #endif int file_len = caml_string_length(v_file) + 1; char *file; #ifdef SQLITE_HAS_OPEN_V2 if (v_vfs_opt == Val_None) vfs = NULL; else { value v_vfs = Field(v_vfs_opt, 0); int vfs_len = caml_string_length(v_vfs) + 1; vfs = caml_stat_alloc(vfs_len); memcpy(vfs, String_val(v_vfs), vfs_len); } #else if (Int_val(v_mode) || Int_val(v_mutex) || Int_val(v_cache)) caml_failwith("SQlite3 version < 3.5 does not support open flags"); if (v_vfs_opt != Val_None) caml_failwith("SQLite3 version < 3.5 does not support VFS modules"); #endif file = caml_stat_alloc(file_len); memcpy(file, String_val(v_file), file_len); caml_enter_blocking_section(); #ifdef SQLITE_HAS_OPEN_V2 res = sqlite3_open_v2(file, &db, flags, vfs); free(vfs); #else res = sqlite3_open(file, &db); #endif free(file); caml_leave_blocking_section(); if (res) { const char *msg; if (db) { msg = sqlite3_errmsg(db); sqlite3_close(db); } else msg = "<unknown_error>"; raise_sqlite3_Error("error opening database: %s", msg); } else if (db == NULL) raise_sqlite3_InternalError( "open returned neither a database nor an error"); /* "open" succeded */ { db_wrap *dbw; value v_res = caml_alloc_final(2, dbw_finalize_gc, 1, 100); Sqlite3_val(v_res) = NULL; dbw = caml_stat_alloc(sizeof(db_wrap)); dbw->db = db; dbw->rc = SQLITE_OK; dbw->ref_count = 1; dbw->user_functions = NULL; Sqlite3_val(v_res) = dbw; return v_res; } }
int default_create_and_write(uint64_t oid, const struct siocb *iocb) { char path[PATH_MAX], tmp_path[PATH_MAX]; int flags = get_open_flags(oid, true, iocb->flags); int ret, fd; uint32_t len = iocb->length; get_obj_path(oid, path); get_tmp_obj_path(oid, tmp_path); if (uatomic_is_true(&sys->use_journal) && journal_file_write(oid, iocb->buf, iocb->length, iocb->offset, true) != SD_RES_SUCCESS) { sd_eprintf("turn off journaling"); uatomic_set_false(&sys->use_journal); flags |= O_DSYNC; sync(); } fd = open(tmp_path, flags, def_fmode); if (fd < 0) { if (errno == EEXIST) { /* * This happens if node membership changes during object * creation; while gateway retries a CREATE request, * recovery process could also recover the object at the * same time. They should try to write the same date, * so it is okay to simply return success here. */ sd_dprintf("%s exists", tmp_path); return SD_RES_SUCCESS; } sd_eprintf("failed to open %s: %m", tmp_path); return err_to_sderr(oid, errno); } if (iocb->offset != 0 || iocb->length != get_objsize(oid)) { ret = prealloc(fd, get_objsize(oid)); if (ret < 0) { ret = err_to_sderr(oid, errno); goto out; } } ret = xpwrite(fd, iocb->buf, len, iocb->offset); if (ret != len) { sd_eprintf("failed to write object. %m"); ret = err_to_sderr(oid, errno); goto out; } ret = rename(tmp_path, path); if (ret < 0) { sd_eprintf("failed to rename %s to %s: %m", tmp_path, path); ret = err_to_sderr(oid, errno); goto out; } sd_dprintf("%"PRIx64, oid); ret = SD_RES_SUCCESS; out: if (ret != SD_RES_SUCCESS) unlink(tmp_path); close(fd); return ret; }