// TODO Copyright #ifndef _BTRFS_MGR_H_ #define _BTRFS_MGR_H_ #include #include #include #include #include #include #include "uuid/linux_uuid.h" #include "smagent/sma_interface.h" #include "mtdt_store.h" #define MAX_VOLID_SIZE 256 #define MAX_SNAPID_SIZE sizeof(uint64_t) #define UUID_SIZE (sizeof(uuid_t)) #define MAX_NO_SNAPS 32 #define ERR_UUID "{Failed to generate UUID}" #define ROOT_INODE_NUM 64 #define ROOT_GEN_NUM 64 /* The vol location config file is expected to be in the format - * * * Example: * $ cat vol_location.conf * 133 172.19.208.47 * 134 172.19.208.48 * * Note: Currently the volname from Ontap is the Btrfs VolId */ #define VOL_LOC_CONF_FILE "vol_location.conf" #define BTRFS_UUID_PRINT(uuid_in, fmt, ...) \ do { \ char* _uuid_str = NULL; \ uint32_t _st = 0; \ uuid_to_string(uuid_in, &_uuid_str, &_st); \ if (_st != uuid_s_ok) { \ _uuid_str = (char *)ERR_UUID; \ } \ char __msg[SMA_MAX_LOGSIZE] = {0}; \ snprintf(__msg, SMA_MAX_LOGSIZE, \ "Btrfs: %s():%d: UUID: %s "fmt, \ __func__, __LINE__, _uuid_str, \ ##__VA_ARGS__); \ btrfs_log_message(NULL, 0, SMALOG_INFO, __msg); \ if (_st == uuid_s_ok) { \ free( _uuid_str ); \ } \ } while(0) #define BTRFS_PRINT(fmt, ...) \ do { \ char __msg[SMA_MAX_LOGSIZE] = {0}; \ snprintf(__msg, SMA_MAX_LOGSIZE, \ "Btrfs: %s():%d: "fmt, \ __func__, __LINE__, \ ##__VA_ARGS__); \ btrfs_log_message(NULL, 0, SMALOG_INFO, __msg); \ } while(0) #define BTRFS_ERR_PRINT(fmt, ...) \ do { \ char __msg[SMA_MAX_LOGSIZE] = {0}; \ snprintf(__msg, SMA_MAX_LOGSIZE, \ "Btrfs: %s():%d: "fmt, \ __func__, __LINE__, \ ##__VA_ARGS__); \ btrfs_log_message(NULL, 0, SMALOG_ERROR, __msg);\ } while(0) #ifdef DEBUG #define BTRFS_DEBUG_PRINT(fmt, ...) \ do { \ char __msg[SMA_MAX_LOGSIZE] = {0}; \ snprintf(__msg, SMA_MAX_LOGSIZE, \ "Btrfs: %s():%d: "fmt, \ __func__, __LINE__, \ ##__VA_ARGS__); \ btrfs_log_message(NULL, 0, SMALOG_DEBUG, __msg);\ } while(0) #else /* DEBUG */ #define BTRFS_DEBUG_PRINT(fmt, ...) #endif /* DEBUG */ void btrfs_log_message(void *plat_ctx, uint32_t id, uint8_t sev, const char *msg); class BtrfsMgr { private: // singleton Btrfs Mgr instance static BtrfsMgr *instance_; // btrfs mount path static std::string btrfs_mount_path_; // make default constructors private BtrfsMgr(std::string btrfs_mount_path); BtrfsMgr(BtrfsMgr const&); BtrfsMgr& operator=(BtrfsMgr const&); // MtdtStore MtdtStore *mtds_; // data subvolume path std::string base_vol_path_; // metadata subvolume path std::string mtdt_vol_path_; // snapshot dir path std::string snap_vol_path_; // uuid subvolume path std::string vol_uuid_path_; // VOL dir name std::string vol_dir_; // SNAP dir name std::string snap_dir_; // TAG dir name std::string tag_dir_; // opaque file name std::string opaque_fn_; // routine to create a dir, if it doesnt exist SmaStatus create_dir(const char *path); // get the mtdt_vol path for a given vol_id std::string get_mtdt_vol_path(void *vol_id); // get the snap vol path std::string get_snapvol_path(void *vol_id); // get the file size uint32_t get_file_size(std::string file_path); // write to file SmaStatus write_to_file(std::string dir_path, std::string file_name, char *buffer, uint32_t len); SmaStatus fill_user_snap_info(std::string vol_id, uint64_t snap_id, std::string snap_name, SmaSnapshotInfo **snap); SmaStatus isDifferent(const char *base_snap_, const char *incr_snap_, uint64_t starting_offset_, uint64_t cur_length_, bool& hole, bool &isDiff); SmaStatus isHoleBaseline(const char *incr_snap, uint64_t starting_offset, uint64_t cur_length, bool &hole); bool anyDiff(uint8_t *buff1, uint8_t *buff2, uint64_t length1, uint64_t length2); bool isHole(uint8_t *buff, uint64_t length); public: // Translate a snap_id to snapshot version_uuid bool snap_id_to_uuid(std::string vol_name, uint64_t snap_id, uuid_t &version_uuid); // populate snapshot information for a given volume SmaStatus populate_snap_list(SmaSnapListInput *input, SmaSnapListOutput *output, std::vector snap_names, std::vector snap_ids, std::string vol_name); SmaOpaqueVolumeInfo * btrfs_read_vol_info(void *vol_id, uint32_t type_no, SmaStatus *status); // get the base subvolume path std::string get_base_path(); // btrfs configuration parameters SmaEndpointConfig btrfs_config_; std::string logging_file_; static void set_btrfs_mount_path(char *mount_path) { btrfs_mount_path_ = mount_path; } static BtrfsMgr *instance() { if (!instance_) { assert(btrfs_mount_path_.length()); instance_ = new BtrfsMgr(btrfs_mount_path_); } return instance_; } static void free_instance() { if (instance_) { delete instance_; instance_ = NULL; } } ~BtrfsMgr() { delete mtds_; } MtdtStore* get_mtdt_store() { if (!mtds_) { // Should never happen. assert(!"Store not initialized."); } return mtds_; } // get absolute path for a given vol_id std::string get_full_path(void *vol_id); // check if the volume dir exists or not bool is_dir_present(std::string dir_path); // check if the volume is read_write bool is_rw_volume(std::string vol_path); // update the volume status SmaStatus btrfs_update_volume_status(std::string vol_path, SmaContainerStatus status); // check if the volume is offline or online bool is_volume_offline(std::string vol_path); // Read and initialize config bool config_init(); // check if we are emulating a SF endpoint bool is_sf_emulation(); bool check_volume_existance(const std::string& vol_id, std::string& vol_name); // store uuid to volume name mapping SmaStatus store_vol_name(uuid_t *uuid, const std::string& vol_name); // Remove uuid to volume name mapping file SmaStatus remove_vol_name(uuid_t *uuid, const std::string &vol_name); // fetch volume name for a given uuid SmaStatus get_vol_name(uuid_t *uuid, std::string& vol_name); // store vol_info record SmaStatus store_vol_info(void *vol_id, uint32_t type_no, SmaOpaqueVolumeInfo *vol_info); // delete vol_info record SmaStatus remove_vol_info(void *vol_id, uint32_t type_no, SmaOpaqueVolumeInfo *vol_info); // read vol_info record SmaStatus read_vol_info(void *vol_id, uint32_t type_no, SmaOpaqueVolumeInfo *vol_info); // create snapshot for given subvolume SmaStatus create_snapshot(void *vol_id, //IN SmaSnapCreateInput *input, //IN SmaSnapCreateOutput *output, //OUT void *snap_id); //OUT // Store snap_uuid to snap_id mapping SmaStatus store_snap_id(void *vol_id, //IN void *snap_id, //IN uuid_t *snap_uuid); //IN // Get snap_id from snap_uuid SmaStatus get_snap_id(void *vol_id, //IN uuid_t *snap_uuid, //IN void *snap_id); //OUT // delete snapshot for given subvolume and snap id SmaStatus delete_snapshot(void *vol_id, void *snap_id); SmaStatus rename_snapshot(void *vol_id, void *snap_id, char *new_name); #if 0 // store snapshot create specific data SmaStatus store_snap_create_info(void *vol_id, SmaSnapInfo *snap_info); #endif // SNAP ops SmaStatus store_snap_info(std::string vol_name, uint64_t snap_id, std::string snap_name, SmaSnapshotInfo *version_info, SmaSnapshotInfo *instance_info); // get snapshot list SmaStatus get_snap_list(void *vol_id, std::vector &snap_name_list, std::vector &snap_id_list); // get snapshot subvolume id uint64_t get_snapvol_id(void *vol_id, std::string snapvol_name); // get the snapshot subvolume name for a given vol_id, snap_id std::string get_snapvol_name(void *vol_id, void *snap_id); // get the location of the node a specified volume is on SmaStatus get_vol_location(std::string vol_name, //IN std::string &vol_addr); //OUT SmaStatus get_diffs(const char *base, const char *incr, uint64_t starting_offset_, uint64_t length_, uint32_t max_count, bool isBaseline, SmaGetObjectRangesOutput *output); SmaStatus get_data(const char *incr, uint64_t starting_offset_, uint64_t cur_length_, SmaGetObjectDataOutput *output); SmaStatus write_data(const char *file, SmaUpdateObjectDataInput *input, char *hole_buf); SmaStatus walkTree(std::string dirname, std::map &pathList); SmaPlatformType getCurrentPlatformType(std::string vol_name); }; // class BtrfsMgr #endif // _BTRFS_MGR_H_