lsm/
error.rs

1// Copyright (C) 2017-2018 Red Hat, Inc.
2//
3// Permission is hereby granted, free of charge, to any
4// person obtaining a copy of this software and associated
5// documentation files (the "Software"), to deal in the
6// Software without restriction, including without
7// limitation the rights to use, copy, modify, merge,
8// publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software
10// is furnished to do so, subject to the following
11// conditions:
12//
13// The above copyright notice and this permission notice
14// shall be included in all copies or substantial portions
15// of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25// DEALINGS IN THE SOFTWARE.
26//
27// Author: Gris Ge <fge@redhat.com>
28use 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
229//const ERROR_NUMBER_OK: i32 = 0; // will never used in IPC
230const ERROR_NUMBER_LIB_BUG: i32 = 1;
231const ERROR_NUMBER_PLUGIN_BUG: i32 = 2;
232//const ERROR_NUMBER_JOB_STARTED: i32 = 7; // will never used in IPC
233const ERROR_NUMBER_TIMEOUT: i32 = 11;
234//const ERROR_NUMBER_DAEMON_NOT_RUNNING: i32 = 12; // will never used in IPC
235//const ERROR_NUMBER_PERMISSION_DENIED: i32 = 13; // will never used in IPC
236const 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}