#pragma once #include "cluster_client.h" #include "epoll_manager.h" #include "nfs_portmap.h" #include "nfs/xdr_impl.h" #include "kv_db.h" #define RPC_INIT_BUF_SIZE 32768 #define MAX_REQUEST_SIZE 128*1024*1024 #define TRUE 1 #define FALSE 0 class cli_tool_t; struct list_cookie_t { uint64_t dir_ino, cookieverf, cookie; }; inline bool operator < (const list_cookie_t & a, const list_cookie_t & b) { return a.dir_ino < b.dir_ino || a.dir_ino == b.dir_ino && (a.cookieverf < b.cookieverf || a.cookieverf == b.cookieverf && a.cookie < b.cookie); }; struct list_cookie_val_t { std::string key; }; class nfs_proxy_t { public: std::string bind_address; std::string name_prefix; uint64_t fsid = 1; uint64_t server_id = 0; std::string default_pool; std::string export_root; bool portmap_enabled; unsigned nfs_port; uint64_t fs_kv_inode = 0; uint64_t fs_base_inode = 0; uint64_t fs_inode_count = 0; int readdir_getattr_parallel = 8, id_alloc_batch_size = 200; int trace = 0; pool_id_t default_pool_id; portmap_service_t pmap; ring_loop_t *ringloop = NULL; epoll_manager_t *epmgr = NULL; cluster_client_t *cli = NULL; cli_tool_t *cmd = NULL; kv_dbw_t *db = NULL; std::map list_cookies; uint64_t fs_next_id = 0, fs_allocated_id = 0; std::vector unallocated_ids; std::vector xdr_pool; // inode ID => statistics std::map inode_stats; // pool ID => statistics std::map pool_stats; ~nfs_proxy_t(); static json11::Json::object parse_args(int narg, const char *args[]); void run(json11::Json cfg); void watch_stats(); void parse_stats(etcd_kv_t & kv); void check_default_pool(); void do_accept(int listen_fd); void daemonize(); }; struct rpc_cur_buffer_t { uint8_t *buf; unsigned size; unsigned read_pos; unsigned parsed_pos; int refs; }; struct rpc_used_buffer_t { unsigned size; int refs; }; struct rpc_free_buffer_t { uint8_t *buf; unsigned size; }; struct extend_size_t { inode_t inode; uint64_t new_size; }; inline bool operator < (const extend_size_t &a, const extend_size_t &b) { return a.inode < b.inode || a.inode == b.inode && a.new_size < b.new_size; } struct extend_write_t { rpc_op_t *rop; int resize_res, write_res; // 1 = started, 0 = completed OK, -errno = completed with error }; struct extend_inode_t { uint64_t cur_extend = 0, next_extend = 0; std::string old_ientry; json11::Json::object attrs; }; class nfs_client_t { public: nfs_proxy_t *parent = NULL; int nfs_fd; int epoll_events = 0; int refs = 0; bool stopped = false; std::set proc_table; // Read state rpc_cur_buffer_t cur_buffer = { 0 }; std::map used_buffers; std::vector free_buffers; std::map extends; std::multimap extend_writes; iovec read_iov; msghdr read_msg = { 0 }; // Write state msghdr write_msg = { 0 }; std::vector send_list, next_send_list; std::vector outbox, next_outbox; nfs_client_t(); ~nfs_client_t(); void select_read_buffer(unsigned wanted_size); void submit_read(unsigned wanted_size); void handle_read(int result); void submit_send(); void handle_send(int result); int handle_rpc_message(void *base_buf, void *msg_buf, uint32_t msg_len); bool deref(); void stop(); }; // FIXME: Move to "impl" #include "nfs/nfs.h" #define KV_ROOT_INODE 1 #define KV_NEXT_ID_KEY "id" #define KV_ROOT_HANDLE "R" nfsstat3 vitastor_nfs_map_err(int err); nfstime3 nfstime_from_str(const std::string & s); std::string nfstime_to_str(nfstime3 t); int kv_map_type(const std::string & type); fattr3 get_kv_attributes(nfs_client_t *self, uint64_t ino, json11::Json attrs); std::string kv_direntry_key(uint64_t dir_ino, const std::string & filename); std::string kv_direntry_filename(const std::string & key); std::string kv_inode_key(uint64_t ino); std::string kv_fh(uint64_t ino); uint64_t kv_fh_inode(const std::string & fh); bool kv_fh_valid(const std::string & fh); void allocate_new_id(nfs_client_t *self, std::function cb); void kv_read_inode(nfs_client_t *self, uint64_t ino, std::function cb, bool allow_cache = false); int kv_nfs3_getattr_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_setattr_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_lookup_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_readlink_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_read_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_write_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_create_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_mkdir_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_symlink_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_mknod_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_remove_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_rmdir_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_rename_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_link_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_readdir_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_readdirplus_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_fsstat_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_fsinfo_proc(void *opaque, rpc_op_t *rop); int kv_nfs3_pathconf_proc(void *opaque, rpc_op_t *rop); int nfs3_access_proc(void *opaque, rpc_op_t *rop); int nfs3_null_proc(void *opaque, rpc_op_t *rop); int nfs3_commit_proc(void *opaque, rpc_op_t *rop); int mount3_mnt_proc(void *opaque, rpc_op_t *rop); int mount3_dump_proc(void *opaque, rpc_op_t *rop); int mount3_umnt_proc(void *opaque, rpc_op_t *rop); int mount3_umntall_proc(void *opaque, rpc_op_t *rop); int mount3_export_proc(void *opaque, rpc_op_t *rop);