int fs_create(lsm_plugin_ptr c, lsm_pool *pool, const char *name, uint64_t size_bytes, lsm_fs **fs, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 4 /* argument count */, pool, name, fs, job), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); _good(_fs_create_internal(err_msg, db, name, size_bytes, _db_lsm_id_to_sim_id(lsm_pool_id_get(pool))), rc, out); _good(_job_create(err_msg, db, LSM_DATA_TYPE_FS, _db_last_rowid(db), job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: if (fs != NULL) *fs = NULL; if (rc != LSM_ERR_OK) { _db_sql_trans_rollback(db); if (job != NULL) *job = NULL; lsm_log_error_basic(c, rc, err_msg); } if (rc == LSM_ERR_OK) rc = LSM_ERR_JOB_STARTED; return rc; }
int fs_child_dependency_rm(lsm_plugin_ptr c, lsm_fs *fs, lsm_string_list *files, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; uint8_t yes = 0; char err_msg[_LSM_ERR_MSG_LEN]; uint64_t sim_fs_id = 0; char condition[_BUFF_SIZE]; sqlite3 *db = NULL; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 2 /* argument count */, fs, job), rc, out); _good(fs_child_dependency(c, fs, files, &yes), rc, out); if (yes == 0) { rc = LSM_ERR_NO_STATE_CHANGE; _lsm_err_msg_set(err_msg, "Specified file system does not have child " "dependency"); goto out; } _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); /* * Assuming API definition is break all clone relationship and remove * all snapshot of this source file system. */ /* Previous fs_child_dependency() call already checked the fs existence */ sim_fs_id = _db_lsm_id_to_sim_id(lsm_fs_id_get(fs)); _snprintf_buff(err_msg, rc, out, condition, "src_fs_id = %" PRIu64, sim_fs_id); _good(_db_data_delete_condition(err_msg, db, _DB_TABLE_FS_CLONES, condition), rc, out); _snprintf_buff(err_msg, rc, out, condition, "fs_id = %" PRIu64, sim_fs_id); _good(_db_data_delete_condition(err_msg, db, _DB_TABLE_FS_SNAPS, condition), rc, out); _good(_job_create(err_msg, db, LSM_DATA_TYPE_NONE, _DB_SIM_ID_NONE, job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: _db_sql_trans_rollback(db); if (rc != LSM_ERR_OK) { lsm_log_error_basic(c, rc, err_msg); } else { rc = LSM_ERR_JOB_STARTED; } return rc; }
int fs_child_dependency(lsm_plugin_ptr c, lsm_fs *fs, lsm_string_list *files, uint8_t *yes) { int rc = LSM_ERR_OK; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; lsm_hash *sim_fs = NULL; uint64_t sim_fs_id = 0; char sql_cmd[_BUFF_SIZE]; struct _vector *vec = NULL; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 2 /* argument count */, fs, yes), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); sim_fs_id = _db_lsm_id_to_sim_id(lsm_fs_id_get(fs)); _good(_db_sim_fs_of_sim_id(err_msg, db, sim_fs_id, &sim_fs), rc, out); /* Check fs snapshot status */ _snprintf_buff(err_msg, rc, out, sql_cmd, "SELECT * FROM " _DB_TABLE_FS_SNAPS_VIEW " WHERE fs_id=%" PRIu64 ";", sim_fs_id); _good(_db_sql_exec(err_msg, db, sql_cmd, &vec), rc, out); if (_vector_size(vec) != 0) { *yes = 1; goto out; } _db_sql_exec_vec_free(vec); vec = NULL; /* Check fs clone(clone here means read and writeable snapshot) */ _snprintf_buff(err_msg, rc, out, sql_cmd, "SELECT * FROM " _DB_TABLE_FS_CLONES " WHERE src_fs_id = %" PRIu64 ";", sim_fs_id); _good(_db_sql_exec(err_msg, db, sql_cmd, &vec), rc, out); if (_vector_size(vec) != 0) *yes = 1; out: _db_sql_exec_vec_free(vec); if (sim_fs != NULL) lsm_hash_free(sim_fs); _db_sql_trans_rollback(db); if (rc != LSM_ERR_OK) { if (yes != NULL) *yes = 0; lsm_log_error_basic(c, rc, err_msg); } return rc; }
int fs_snapshot_list(lsm_plugin_ptr c, lsm_fs *fs, lsm_fs_ss **ss[], uint32_t *ss_count, lsm_flag flags) { int rc = LSM_ERR_OK; struct _vector *vec = NULL; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; char sql_cmd[_BUFF_SIZE]; lsm_hash *sim_fs = NULL; uint64_t sim_fs_id = 0; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 2 /* argument count */, ss, ss_count), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); /* Check fs existence */ sim_fs_id = _db_lsm_id_to_sim_id(lsm_fs_id_get(fs)); _good(_db_sim_fs_of_sim_id(err_msg, db, sim_fs_id, &sim_fs), rc, out); _snprintf_buff(err_msg, rc, out, sql_cmd, "SELECT * from " _DB_TABLE_FS_SNAPS_VIEW " WHERE fs_id=%" PRIu64 ";", sim_fs_id); _good(_db_sql_exec(err_msg, db, sql_cmd, &vec), rc, out); if (_vector_size(vec) == 0) { *ss = NULL; *ss_count = 0; goto out; } _vec_to_lsm_xxx_array(err_msg, vec, lsm_fs_ss, _sim_fs_snap_to_lsm, ss, ss_count, rc, out); out: _db_sql_trans_rollback(db); _db_sql_exec_vec_free(vec); if (sim_fs != NULL) lsm_hash_free(sim_fs); if (rc != LSM_ERR_OK) { if ((ss != NULL) && (ss_count != NULL)) { if (*ss != NULL) lsm_fs_ss_record_array_free(*ss , *ss_count); } if (ss != NULL) *ss = NULL; if (ss_count != NULL) *ss_count = 0; lsm_log_error_basic(c, rc, err_msg); } return rc; }
int fs_file_clone(lsm_plugin_ptr c, lsm_fs *fs, const char *src_file_name, const char *dest_file_name, lsm_fs_ss *snapshot, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; lsm_hash *sim_fs = NULL; lsm_hash *sim_fs_snap = NULL; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 4 /* argument count */, fs, src_file_name, dest_file_name, job), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); /* Check fs existence */ _good(_db_sim_fs_of_sim_id(err_msg, db, _db_lsm_id_to_sim_id(lsm_fs_id_get(fs)), &sim_fs), rc, out); if (snapshot != NULL) _good(_db_sim_fs_snap_of_sim_id(err_msg, db, _db_lsm_id_to_sim_id (lsm_fs_ss_id_get(snapshot)), &sim_fs_snap), rc, out); /* We don't have API to query file level clone. So do nothing here */ _good(_job_create(err_msg, db, LSM_DATA_TYPE_NONE, _DB_SIM_ID_NONE, job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: if (sim_fs != NULL) lsm_hash_free(sim_fs); if (sim_fs_snap != NULL) lsm_hash_free(sim_fs_snap); if (rc != LSM_ERR_OK) { _db_sql_trans_rollback(db); if (job != NULL) *job = NULL; lsm_log_error_basic(c, rc, err_msg); } else { rc = LSM_ERR_JOB_STARTED; } return rc; }
int fs_snapshot_delete(lsm_plugin_ptr c, lsm_fs *fs, lsm_fs_ss *ss, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; lsm_hash *sim_fs_snap = NULL; uint64_t sim_fs_snap_id = 0; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 3 /* argument count */, fs, ss, job), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); sim_fs_snap_id = _db_lsm_id_to_sim_id(lsm_fs_ss_id_get(ss)); /* The existence of fs snapshot indicate the fs is exist due to the sqlite * REFERENCES and PRAGMA foreign_keys = ON */ _good(_db_sim_fs_snap_of_sim_id(err_msg, db, sim_fs_snap_id, &sim_fs_snap), rc, out); _good(_db_data_delete(err_msg, db, _DB_TABLE_FS_SNAPS, sim_fs_snap_id), rc, out); _good(_job_create(err_msg, db, LSM_DATA_TYPE_NONE, _DB_SIM_ID_NONE, job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: if (sim_fs_snap != NULL) lsm_hash_free(sim_fs_snap); if (rc != LSM_ERR_OK) { _db_sql_trans_rollback(db); lsm_log_error_basic(c, rc, err_msg); if (job != NULL) *job = NULL; } else { rc = LSM_ERR_JOB_STARTED; } return rc; }
int fs_snapshot_create(lsm_plugin_ptr c, lsm_fs *fs, const char *name, lsm_fs_ss **snapshot, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; struct _vector *vec = NULL; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; lsm_hash *sim_fs = NULL; uint64_t sim_fs_id = 0; char ts_str[_BUFF_SIZE]; struct timespec ts; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 4 /* argument count */, fs, name, snapshot, job), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); /* Check fs existence */ sim_fs_id = _db_lsm_id_to_sim_id(lsm_fs_id_get(fs)); _good(_db_sim_fs_of_sim_id(err_msg, db, sim_fs_id, &sim_fs), rc, out); if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { rc = LSM_ERR_PLUGIN_BUG; _lsm_err_msg_set(err_msg, "BUG: clock_gettime(CLOCK_REALTIME, &ts) " "failed"); goto out; } _snprintf_buff(err_msg, rc, out, ts_str, "%" PRIu64, (uint64_t) difftime(ts.tv_sec, 0)); rc = _db_data_add(err_msg, db, _DB_TABLE_FS_SNAPS, "name", name, "fs_id", _db_lsm_id_to_sim_id_str(lsm_fs_id_get(fs)), "timestamp", ts_str, NULL); if (rc != LSM_ERR_OK) { if (sqlite3_errcode(db) == SQLITE_CONSTRAINT) { rc = LSM_ERR_NAME_CONFLICT; _lsm_err_msg_set(err_msg, "FS snapshot name '%s' in use", name); } goto out; } _good(_job_create(err_msg, db, LSM_DATA_TYPE_SS, _db_last_rowid(db), job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: _db_sql_exec_vec_free(vec); if (snapshot != NULL) *snapshot = NULL; if (sim_fs != NULL) lsm_hash_free(sim_fs); if (rc != LSM_ERR_OK) { lsm_log_error_basic(c, rc, err_msg); } else { rc = LSM_ERR_JOB_STARTED; } return rc; }
int fs_resize(lsm_plugin_ptr c, lsm_fs *fs, uint64_t new_size, lsm_fs ** rfs, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; char err_msg[_LSM_ERR_MSG_LEN]; uint64_t sim_fs_id = 0; lsm_hash *sim_fs = NULL; uint64_t increment_size = 0; uint64_t cur_size = 0; uint64_t sim_pool_id = 0; char new_size_str[_BUFF_SIZE]; sqlite3 *db = NULL; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 3 /* argument count */, fs, rfs, job), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); sim_fs_id = _db_lsm_id_to_sim_id(lsm_fs_id_get(fs)); _good(_db_sim_fs_of_sim_id(err_msg, db, sim_fs_id, &sim_fs), rc, out); _good(_str_to_uint64(err_msg, lsm_hash_string_get(sim_fs, "total_space"), &cur_size), rc, out); new_size = _db_blk_size_rounding(new_size); if (cur_size == new_size) { rc = LSM_ERR_NO_STATE_CHANGE; _lsm_err_msg_set(err_msg, "Specified new size is identical to " "current fs size"); goto out; } if (new_size > cur_size) { increment_size = new_size - cur_size; sim_pool_id = _db_lsm_id_to_sim_id(lsm_fs_pool_id_get(fs)); if (_pool_has_enough_free_size(db, sim_pool_id, increment_size) == false) { rc = LSM_ERR_NOT_ENOUGH_SPACE; _lsm_err_msg_set(err_msg, "Insufficient space in pool"); goto out; } } _snprintf_buff(err_msg, rc, out, new_size_str, "%" PRIu64, new_size); _good(_db_data_update(err_msg, db, _DB_TABLE_FSS, sim_fs_id, "total_space", new_size_str), rc, out); _good(_db_data_update(err_msg, db, _DB_TABLE_FSS, sim_fs_id, "consumed_size", new_size_str), rc, out); _good(_db_data_update(err_msg, db, _DB_TABLE_FSS, sim_fs_id, "free_space", new_size_str), rc, out); _good(_job_create(err_msg, db, LSM_DATA_TYPE_FS, sim_fs_id, job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: if (rfs != NULL) *rfs = NULL; if (sim_fs != NULL) lsm_hash_free(sim_fs); if (rc != LSM_ERR_OK) { _db_sql_trans_rollback(db); if (job != NULL) *job = NULL; lsm_log_error_basic(c, rc, err_msg); } else { rc = LSM_ERR_JOB_STARTED; } return rc; }
int fs_clone(lsm_plugin_ptr c, lsm_fs *src_fs, const char *dest_fs_name, lsm_fs **cloned_fs, lsm_fs_ss *optional_snapshot, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; lsm_hash *sim_fs = NULL; lsm_hash *sim_fs_snap = NULL; uint64_t sim_fs_id = 0; uint64_t dst_sim_fs_id = 0; char dst_sim_fs_id_str[_BUFF_SIZE]; uint64_t sim_fs_snap_id = 0; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 4 /* argument count */, src_fs, dest_fs_name, cloned_fs, job), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); sim_fs_id = _db_lsm_id_to_sim_id(lsm_fs_id_get(src_fs)); /* Check fs existence */ _good(_db_sim_fs_of_sim_id(err_msg, db, sim_fs_id, &sim_fs), rc, out); if (optional_snapshot != NULL) { sim_fs_snap_id = _db_lsm_id_to_sim_id (lsm_fs_ss_id_get(optional_snapshot)); /* No need to trace state of snap id here due to lack of query method. * We just check snapshot existence */ _good(_db_sim_fs_snap_of_sim_id(err_msg, db, sim_fs_snap_id, &sim_fs_snap), rc, out); lsm_hash_free(sim_fs_snap); } _good(_fs_create_internal(err_msg, db, dest_fs_name, lsm_fs_total_space_get(src_fs), _db_lsm_id_to_sim_id(lsm_fs_pool_id_get(src_fs))), rc, out); dst_sim_fs_id = _db_last_rowid(db); _snprintf_buff(err_msg, rc, out, dst_sim_fs_id_str, "%" PRIu64, dst_sim_fs_id); _good(_db_data_add(err_msg, db, _DB_TABLE_FS_CLONES, "src_fs_id", _db_lsm_id_to_sim_id_str(lsm_fs_id_get(src_fs)), "dst_fs_id", dst_sim_fs_id_str, NULL), rc, out); _good(_job_create(err_msg, db, LSM_DATA_TYPE_FS, dst_sim_fs_id, job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: if (sim_fs != NULL) lsm_hash_free(sim_fs); if (cloned_fs != NULL) *cloned_fs = NULL; if (rc != LSM_ERR_OK) { _db_sql_trans_rollback(db); if (job != NULL) *job = NULL; lsm_log_error_basic(c, rc, err_msg); } else { rc = LSM_ERR_JOB_STARTED; } return rc; }
int fs_delete(lsm_plugin_ptr c, lsm_fs *fs, char **job, lsm_flag flags) { int rc = LSM_ERR_OK; sqlite3 *db = NULL; char err_msg[_LSM_ERR_MSG_LEN]; lsm_hash *sim_fs = NULL; uint64_t sim_fs_id = 0; char sql_cmd[_BUFF_SIZE]; struct _vector *vec = NULL; _lsm_err_msg_clear(err_msg); _good(_check_null_ptr(err_msg, 2 /* argument count */, fs, job), rc, out); _good(_get_db_from_plugin_ptr(err_msg, c, &db), rc, out); _good(_db_sql_trans_begin(err_msg, db), rc, out); sim_fs_id = _db_lsm_id_to_sim_id(lsm_fs_id_get(fs)); /* Check fs existence */ _good(_db_sim_fs_of_sim_id(err_msg, db, sim_fs_id, &sim_fs), rc, out); /* Check fs snapshot status */ _snprintf_buff(err_msg, rc, out, sql_cmd, "SELECT * FROM " _DB_TABLE_FS_SNAPS_VIEW " WHERE fs_id=%" PRIu64 ";", sim_fs_id); _good(_db_sql_exec(err_msg, db, sql_cmd, &vec), rc, out); if (_vector_size(vec) != 0) { rc = LSM_ERR_PLUGIN_BUG; /* TODO(Gris Ge): API does not have dedicate error for this scenario.*/ _lsm_err_msg_set(err_msg, "Specified filesystem has snapshot"); goto out; } _db_sql_exec_vec_free(vec); vec = NULL; /* Check fs clone(clone here means read and writeable snapshot) */ _snprintf_buff(err_msg, rc, out, sql_cmd, "SELECT * FROM " _DB_TABLE_FS_CLONES " WHERE src_fs_id = %" PRIu64 ";", sim_fs_id); _good(_db_sql_exec(err_msg, db, sql_cmd, &vec), rc, out); if (_vector_size(vec) != 0) { rc = LSM_ERR_PLUGIN_BUG; /* We don't have error number for this yet */ _lsm_err_msg_set(err_msg, "Specified fs is a clone source"); goto out; } _good(_db_data_delete(err_msg, db, _DB_TABLE_FSS, sim_fs_id), rc, out); _good(_job_create(err_msg, db, LSM_DATA_TYPE_NONE, _DB_SIM_ID_NONE, job), rc, out); _good(_db_sql_trans_commit(err_msg, db), rc, out); out: _db_sql_exec_vec_free(vec); if (sim_fs != NULL) lsm_hash_free(sim_fs); if (rc != LSM_ERR_OK) { _db_sql_trans_rollback(db); lsm_log_error_basic(c, rc, err_msg); if (job != NULL) *job = NULL; } else { rc = LSM_ERR_JOB_STARTED; } return rc; }
int lsm_scsi_vpd83_of_disk_path(const char *sd_path, const char **vpd83, lsm_error **lsm_err) { char tmp_vpd83[_MAX_VPD83_NAA_ID_LEN]; const char *sd_name = NULL; int rc = LSM_ERR_OK; char err_msg[_LSM_ERR_MSG_LEN]; _lsm_err_msg_clear(err_msg); rc = _check_null_ptr(err_msg, 3 /* arg_count */, sd_path, vpd83, lsm_err); if (rc != LSM_ERR_OK) { if (vpd83 != NULL) *vpd83 = NULL; goto out; } if ((strlen(sd_path) <= strlen("/dev/")) || (strncmp(sd_path, "/dev/", strlen("/dev/")) != 0)) { _lsm_err_msg_set(err_msg, "Invalid sd_path, should start with /dev/"); rc = LSM_ERR_INVALID_ARGUMENT; goto out; } sd_name = sd_path + strlen("/dev/"); if (strlen(sd_name) > _MAX_SD_NAME_STR_LEN) { rc = LSM_ERR_INVALID_ARGUMENT; _lsm_err_msg_set(err_msg, "Illegal sd_path string, the SCSI disk name " "part(sdX) exceeded the max length %d, current %d", _MAX_SD_NAME_STR_LEN - 1, strlen(sd_name)); goto out; } *vpd83 = NULL; *lsm_err = NULL; rc = _sysfs_vpd83_naa_of_sd_name(err_msg, sd_name, tmp_vpd83); if (rc == LSM_ERR_NO_SUPPORT) /* Try udev if kernel does not expose vpd83 */ rc = _udev_vpd83_of_sd_name(err_msg, sd_name, tmp_vpd83); if (rc != LSM_ERR_OK) goto out; if (tmp_vpd83[0] != '\0') { *vpd83 = strdup(tmp_vpd83); if (*vpd83 == NULL) rc = LSM_ERR_NO_MEMORY; } out: if (rc != LSM_ERR_OK) { if (lsm_err != NULL) *lsm_err = LSM_ERROR_CREATE_PLUGIN_MSG(rc, err_msg); if (vpd83 != NULL) { free((char *) *vpd83); *vpd83= NULL; } } return rc; }
int lsm_scsi_disk_paths_of_vpd83(const char *vpd83, lsm_string_list **sd_path_list, lsm_error **lsm_err) { int rc = LSM_ERR_OK; lsm_string_list *sd_name_list = NULL; uint32_t i = 0; const char *sd_name = NULL; char tmp_vpd83[_MAX_VPD83_NAA_ID_LEN]; char sd_path[_MAX_SD_PATH_STR_LEN]; bool sysfs_support = true; char err_msg[_LSM_ERR_MSG_LEN]; _lsm_err_msg_clear(err_msg); rc = _check_null_ptr(err_msg, 3 /* argument count */, vpd83, sd_path_list, lsm_err); if (rc != LSM_ERR_OK) { /* set output pointers to NULL if possible when facing error in case * application use output memory. */ if (sd_path_list != NULL) *sd_path_list = NULL; goto out; } if (strlen(vpd83) >= _MAX_VPD83_NAA_ID_LEN) { _lsm_err_msg_set(err_msg, "Provided vpd83 string exceeded the maximum " "string length for SCSI VPD83 NAA ID %d, current %zd", _MAX_VPD83_NAA_ID_LEN - 1, strlen(vpd83)); rc = LSM_ERR_INVALID_ARGUMENT; goto out; } *lsm_err = NULL; *sd_path_list = lsm_string_list_alloc(0 /* no pre-allocation */); if (*sd_path_list == NULL) { rc = LSM_ERR_NO_MEMORY; goto out; } rc = _sysfs_get_all_sd_names(err_msg, &sd_name_list); if (rc != LSM_ERR_OK) goto out; _lsm_string_list_foreach(sd_name_list, i, sd_name) { if (sd_name == NULL) continue; if (sysfs_support == true) { rc = _sysfs_vpd83_naa_of_sd_name(err_msg, sd_name, tmp_vpd83); if (rc == LSM_ERR_NO_SUPPORT) { sysfs_support = false; } else if (rc == LSM_ERR_NOT_FOUND_DISK) { /* In case disk got removed after _sysfs_get_all_sd_names() */ continue; } else if (rc != LSM_ERR_OK) break; } /* Try udev way if got NO_SUPPORT from sysfs way. */ if (sysfs_support == false) { rc = _udev_vpd83_of_sd_name(err_msg, sd_name, tmp_vpd83); if (rc == LSM_ERR_NOT_FOUND_DISK) /* In case disk got removed after _sysfs_get_all_sd_names() */ continue; else if (rc != LSM_ERR_OK) break; } if (strncmp(vpd83, tmp_vpd83, _MAX_VPD83_NAA_ID_LEN) == 0) { snprintf(sd_path, _MAX_SD_PATH_STR_LEN, _SD_PATH_FORMAT, sd_name); if (lsm_string_list_append(*sd_path_list, sd_path) != 0) { rc = LSM_ERR_NO_MEMORY; goto out; } } } out: if (sd_name_list != NULL) lsm_string_list_free(sd_name_list); if (rc == LSM_ERR_OK) { /* clean sd_path_list if nothing found */ if (lsm_string_list_size(*sd_path_list) == 0) { lsm_string_list_free(*sd_path_list); *sd_path_list = NULL; } } else { /* Error found, clean up */ if (lsm_err != NULL) *lsm_err = LSM_ERROR_CREATE_PLUGIN_MSG(rc, err_msg); if ((sd_path_list != NULL) && (*sd_path_list != NULL)) { lsm_string_list_free(*sd_path_list); *sd_path_list = NULL; } } return rc; }