1use std::fmt;
29use std::result;
30
31#[derive(Debug)]
32pub enum LsmError {
33 LibBug(String),
34 PluginBug(String),
35 TimeOut(String),
36 DaemonNotRunning(String),
37 PermissionDenied(String),
38 NameConflict(String),
39 ExistsInitiator(String),
40 InvalidArgument(String),
41 NoStateChange(String),
42 NetworkConRefused(String),
43 NetworkHostDown(String),
44 NetworkError(String),
45 NoMemory(String),
46 NoSupport(String),
47 IsMasked(String),
48 HasChildDependency(String),
49 NotFoundAccessGroup(String),
50 NotFoundFs(String),
51 NotFoundJob(String),
52 NotFoundPool(String),
53 NotFoundFsSnapshot(String),
54 NotFoundVolume(String),
55 NotFoundNfsExport(String),
56 NotFoundSystem(String),
57 NotFoundDisk(String),
58 NotLicensed(String),
59 NoSupportOnlineChange(String),
60 NoSupportOfflineChange(String),
61 PluginAuthFailed(String),
62 PluginIpcFail(String),
63 PluginSocketPermission(String),
64 PluginNotExist(String),
65 NoEnoughSpace(String),
66 TransportCommunication(String),
67 TransportSerialization(String),
68 TransportInvalidArg(String),
69 LastInitInAccessGroup(String),
70 UnSupportedSearchKey(String),
71 EmptyAccessGroup(String),
72 PoolNotReady(String),
73 DiskNotFree(String),
74}
75
76impl ::std::error::Error for LsmError {
77 fn description(&self) -> &str {
78 match *self {
79 LsmError::LibBug(_) => "Library bug",
80 LsmError::PluginBug(_) => "Plugin bug",
81 LsmError::TimeOut(_) => "Timeout",
82 LsmError::DaemonNotRunning(_) => "LibStoragemgmt daemon is not running",
83 LsmError::PermissionDenied(_) => "Permission denied",
84 LsmError::NameConflict(_) => "Name conflict",
85 LsmError::ExistsInitiator(_) => "Initiator exists and in use",
86 LsmError::InvalidArgument(_) => "Invalid argument",
87 LsmError::NoStateChange(_) => "No state change",
88 LsmError::NetworkConRefused(_) => "Network connection refused",
89 LsmError::NetworkHostDown(_) => "Network host down",
90 LsmError::NetworkError(_) => "Network error",
91 LsmError::NoMemory(_) => "Plugin ran out of memory",
92 LsmError::NoSupport(_) => "Not supported",
93 LsmError::IsMasked(_) => "Volume masked to access group",
94 LsmError::HasChildDependency(_) => "Volume or file system has child dependency",
95 LsmError::NotFoundAccessGroup(_) => "Access group not found",
96 LsmError::NotFoundFs(_) => "File system not found",
97 LsmError::NotFoundJob(_) => "Job not found",
98 LsmError::NotFoundPool(_) => "Pool not found",
99 LsmError::NotFoundFsSnapshot(_) => "File system snapshot not found",
100 LsmError::NotFoundVolume(_) => "Volume not found",
101 LsmError::NotFoundNfsExport(_) => "NFS export not found",
102 LsmError::NotFoundSystem(_) => "System not found",
103 LsmError::NotFoundDisk(_) => "Disk not found",
104 LsmError::NotLicensed(_) => "Specified feature is not licensed in storage system",
105 LsmError::NoSupportOnlineChange(_) => "Specified action require item in offline mode",
106 LsmError::NoSupportOfflineChange(_) => "Specified action require item in online mode",
107 LsmError::PluginAuthFailed(_) => "Authentication failed in plugin",
108 LsmError::PluginIpcFail(_) => "IPC communication to plugin failed",
109 LsmError::PluginSocketPermission(_) => "Permission deny on IPC communication to plugin",
110 LsmError::PluginNotExist(_) => "Specified plugin does not exist",
111 LsmError::NoEnoughSpace(_) => "No enough space",
112 LsmError::TransportCommunication(_) => "Error when communicating with plug-in",
113 LsmError::TransportSerialization(_) => "Incorrect transport serialization",
114 LsmError::TransportInvalidArg(_) => "Invalid transport argument",
115 LsmError::LastInitInAccessGroup(_) => {
116 "Refused to remove the last initiator from access group"
117 }
118 LsmError::UnSupportedSearchKey(_) => "Specified search key is not supported",
119 LsmError::EmptyAccessGroup(_) => "Refused to mask volume to empty access group",
120 LsmError::PoolNotReady(_) => "Pool is not ready for specified action",
121 LsmError::DiskNotFree(_) => "Disk is not free for specified action",
122 }
123 }
124}
125
126impl fmt::Display for LsmError {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 write!(
129 f,
130 "{}",
131 match *self {
132 LsmError::LibBug(ref x)
133 | LsmError::PluginBug(ref x)
134 | LsmError::TimeOut(ref x)
135 | LsmError::DaemonNotRunning(ref x)
136 | LsmError::PermissionDenied(ref x)
137 | LsmError::NameConflict(ref x)
138 | LsmError::ExistsInitiator(ref x)
139 | LsmError::InvalidArgument(ref x)
140 | LsmError::NoStateChange(ref x)
141 | LsmError::NetworkConRefused(ref x)
142 | LsmError::NetworkHostDown(ref x)
143 | LsmError::NetworkError(ref x)
144 | LsmError::NoMemory(ref x)
145 | LsmError::NoSupport(ref x)
146 | LsmError::IsMasked(ref x)
147 | LsmError::HasChildDependency(ref x)
148 | LsmError::NotFoundAccessGroup(ref x)
149 | LsmError::NotFoundFs(ref x)
150 | LsmError::NotFoundJob(ref x)
151 | LsmError::NotFoundPool(ref x)
152 | LsmError::NotFoundFsSnapshot(ref x)
153 | LsmError::NotFoundVolume(ref x)
154 | LsmError::NotFoundNfsExport(ref x)
155 | LsmError::NotFoundSystem(ref x)
156 | LsmError::NotFoundDisk(ref x)
157 | LsmError::NotLicensed(ref x)
158 | LsmError::NoSupportOnlineChange(ref x)
159 | LsmError::NoSupportOfflineChange(ref x)
160 | LsmError::PluginAuthFailed(ref x)
161 | LsmError::PluginIpcFail(ref x)
162 | LsmError::PluginSocketPermission(ref x)
163 | LsmError::PluginNotExist(ref x)
164 | LsmError::NoEnoughSpace(ref x)
165 | LsmError::TransportCommunication(ref x)
166 | LsmError::TransportSerialization(ref x)
167 | LsmError::TransportInvalidArg(ref x)
168 | LsmError::LastInitInAccessGroup(ref x)
169 | LsmError::UnSupportedSearchKey(ref x)
170 | LsmError::EmptyAccessGroup(ref x)
171 | LsmError::PoolNotReady(ref x)
172 | LsmError::DiskNotFree(ref x) => x,
173 }
174 )
175 }
176}
177
178pub type Result<T> = result::Result<T, LsmError>;
179
180impl From<::std::string::FromUtf8Error> for LsmError {
181 fn from(e: ::std::string::FromUtf8Error) -> Self {
182 LsmError::TransportSerialization(format!(
183 "Failed to convert IPC message to UTF-8 string: {}",
184 e
185 ))
186 }
187}
188
189impl From<::std::num::ParseIntError> for LsmError {
190 fn from(e: ::std::num::ParseIntError) -> Self {
191 LsmError::TransportSerialization(format!(
192 "Failed to convert IPC message to UTF-8 integer: {}",
193 e
194 ))
195 }
196}
197
198impl From<::std::str::Utf8Error> for LsmError {
199 fn from(e: ::std::str::Utf8Error) -> Self {
200 LsmError::TransportSerialization(format!(
201 "Failed to convert IPC message to UTF-8 string: {}",
202 e
203 ))
204 }
205}
206
207impl From<::serde_json::Error> for LsmError {
208 fn from(e: ::serde_json::Error) -> Self {
209 LsmError::TransportSerialization(format!(
210 "Failed to convert IPC message to libstoragemgmt \
211 struct: {}",
212 e
213 ))
214 }
215}
216
217impl From<::std::io::Error> for LsmError {
218 fn from(e: ::std::io::Error) -> Self {
219 LsmError::TransportCommunication(format!("{}", e))
220 }
221}
222
223impl From<::regex::Error> for LsmError {
224 fn from(e: ::regex::Error) -> Self {
225 LsmError::LibBug(format!("Regex error: {}", e))
226 }
227}
228
229const ERROR_NUMBER_LIB_BUG: i32 = 1;
231const ERROR_NUMBER_PLUGIN_BUG: i32 = 2;
232const ERROR_NUMBER_TIMEOUT: i32 = 11;
234const ERROR_NUMBER_NAME_CONFLICT: i32 = 50;
237const ERROR_NUMBER_EXISTS_INITIATOR: i32 = 52;
238const ERROR_NUMBER_INVALID_ARGUMENT: i32 = 101;
239const ERROR_NUMBER_NO_STATE_CHANGE: i32 = 125;
240const ERROR_NUMBER_NETWORK_CONNREFUSED: i32 = 140;
241const ERROR_NUMBER_NETWORK_HOSTDOWN: i32 = 141;
242const ERROR_NUMBER_NETWORK_ERROR: i32 = 142;
243const ERROR_NUMBER_NO_MEMORY: i32 = 152;
244const ERROR_NUMBER_NO_SUPPORT: i32 = 153;
245const ERROR_NUMBER_IS_MASKED: i32 = 160;
246const ERROR_NUMBER_HAS_CHILD_DEPENDENCY: i32 = 161;
247const ERROR_NUMBER_NOT_FOUND_ACCESS_GROUP: i32 = 200;
248const ERROR_NUMBER_NOT_FOUND_FS: i32 = 201;
249const ERROR_NUMBER_NOT_FOUND_JOB: i32 = 202;
250const ERROR_NUMBER_NOT_FOUND_POOL: i32 = 203;
251const ERROR_NUMBER_NOT_FOUND_FS_SS: i32 = 204;
252const ERROR_NUMBER_NOT_FOUND_VOLUME: i32 = 205;
253const ERROR_NUMBER_NOT_FOUND_NFS_EXPORT: i32 = 206;
254const ERROR_NUMBER_NOT_FOUND_SYSTEM: i32 = 208;
255const ERROR_NUMBER_NOT_FOUND_DISK: i32 = 209;
256const ERROR_NUMBER_NOT_LICENSED: i32 = 226;
257const ERROR_NUMBER_NO_SUPPORT_ONLINE_CHANGE: i32 = 250;
258const ERROR_NUMBER_NO_SUPPORT_OFFLINE_CHANGE: i32 = 251;
259const ERROR_NUMBER_PLUGIN_AUTH_FAILED: i32 = 300;
260const ERROR_NUMBER_PLUGIN_IPC_FAIL: i32 = 301;
261const ERROR_NUMBER_PLUGIN_SOCKET_PERMISSION: i32 = 307;
262const ERROR_NUMBER_PLUGIN_NOT_EXIST: i32 = 311;
263const ERROR_NUMBER_NOT_ENOUGH_SPACE: i32 = 350;
264const ERROR_NUMBER_TRANSPORT_COMMUNICATION: i32 = 400;
265const ERROR_NUMBER_TRANSPORT_SERIALIZATION: i32 = 401;
266const ERROR_NUMBER_TRANSPORT_INVALID_ARG: i32 = 402;
267const ERROR_NUMBER_LAST_INIT_IN_ACCESS_GROUP: i32 = 502;
268const ERROR_NUMBER_UNSUPPORTED_SEARCH_KEY: i32 = 510;
269const ERROR_NUMBER_EMPTY_ACCESS_GROUP: i32 = 511;
270const ERROR_NUMBER_POOL_NOT_READY: i32 = 512;
271const ERROR_NUMBER_DISK_NOT_FREE: i32 = 513;
272
273#[allow(dead_code)]
274#[derive(Deserialize, Debug)]
275pub(crate) struct LsmErrorIpc {
276 pub(crate) code: i32,
277 pub(crate) message: String,
278 pub(crate) data: Option<String>,
279}
280
281pub(crate) fn lsm_error_code_to_lsm_error(code: i32, message: String) -> LsmError {
282 match code {
283 ERROR_NUMBER_LIB_BUG => LsmError::LibBug(message),
284 ERROR_NUMBER_PLUGIN_BUG => LsmError::PluginBug(message),
285 ERROR_NUMBER_TIMEOUT => LsmError::TimeOut(message),
286 ERROR_NUMBER_NAME_CONFLICT => LsmError::NameConflict(message),
287 ERROR_NUMBER_EXISTS_INITIATOR => LsmError::ExistsInitiator(message),
288 ERROR_NUMBER_INVALID_ARGUMENT => LsmError::InvalidArgument(message),
289 ERROR_NUMBER_NO_STATE_CHANGE => LsmError::NoStateChange(message),
290 ERROR_NUMBER_NETWORK_CONNREFUSED => LsmError::NetworkConRefused(message),
291 ERROR_NUMBER_NETWORK_HOSTDOWN => LsmError::NetworkHostDown(message),
292 ERROR_NUMBER_NETWORK_ERROR => LsmError::NetworkError(message),
293 ERROR_NUMBER_NO_MEMORY => LsmError::NoMemory(message),
294 ERROR_NUMBER_NO_SUPPORT => LsmError::NoSupport(message),
295 ERROR_NUMBER_IS_MASKED => LsmError::IsMasked(message),
296 ERROR_NUMBER_HAS_CHILD_DEPENDENCY => LsmError::HasChildDependency(message),
297 ERROR_NUMBER_NOT_FOUND_ACCESS_GROUP => LsmError::NotFoundAccessGroup(message),
298 ERROR_NUMBER_NOT_FOUND_FS => LsmError::NotFoundFs(message),
299 ERROR_NUMBER_NOT_FOUND_JOB => LsmError::NotFoundJob(message),
300 ERROR_NUMBER_NOT_FOUND_POOL => LsmError::NotFoundPool(message),
301 ERROR_NUMBER_NOT_FOUND_FS_SS => LsmError::NotFoundFsSnapshot(message),
302 ERROR_NUMBER_NOT_FOUND_VOLUME => LsmError::NotFoundVolume(message),
303 ERROR_NUMBER_NOT_FOUND_NFS_EXPORT => LsmError::NotFoundNfsExport(message),
304 ERROR_NUMBER_NOT_FOUND_SYSTEM => LsmError::NotFoundSystem(message),
305 ERROR_NUMBER_NOT_FOUND_DISK => LsmError::NotFoundDisk(message),
306 ERROR_NUMBER_NOT_LICENSED => LsmError::NotLicensed(message),
307 ERROR_NUMBER_NO_SUPPORT_ONLINE_CHANGE => LsmError::NoSupportOnlineChange(message),
308 ERROR_NUMBER_NO_SUPPORT_OFFLINE_CHANGE => LsmError::NoSupportOfflineChange(message),
309 ERROR_NUMBER_PLUGIN_AUTH_FAILED => LsmError::PluginAuthFailed(message),
310 ERROR_NUMBER_PLUGIN_IPC_FAIL => LsmError::PluginIpcFail(message),
311 ERROR_NUMBER_PLUGIN_SOCKET_PERMISSION => LsmError::PluginSocketPermission(message),
312 ERROR_NUMBER_PLUGIN_NOT_EXIST => LsmError::PluginNotExist(message),
313 ERROR_NUMBER_NOT_ENOUGH_SPACE => LsmError::NoEnoughSpace(message),
314 ERROR_NUMBER_TRANSPORT_COMMUNICATION => LsmError::TransportCommunication(message),
315 ERROR_NUMBER_TRANSPORT_SERIALIZATION => LsmError::TransportSerialization(message),
316 ERROR_NUMBER_TRANSPORT_INVALID_ARG => LsmError::TransportInvalidArg(message),
317 ERROR_NUMBER_LAST_INIT_IN_ACCESS_GROUP => LsmError::LastInitInAccessGroup(message),
318 ERROR_NUMBER_UNSUPPORTED_SEARCH_KEY => LsmError::UnSupportedSearchKey(message),
319 ERROR_NUMBER_EMPTY_ACCESS_GROUP => LsmError::EmptyAccessGroup(message),
320 ERROR_NUMBER_POOL_NOT_READY => LsmError::PoolNotReady(message),
321 ERROR_NUMBER_DISK_NOT_FREE => LsmError::DiskNotFree(message),
322 _ => LsmError::LibBug(format!("Invalid error code: {} msg: {}", code, message)),
323 }
324}
325
326impl From<LsmErrorIpc> for LsmError {
327 fn from(e: LsmErrorIpc) -> Self {
328 lsm_error_code_to_lsm_error(e.code, e.message)
329 }
330}