Discussion:
[Libstoragemgmt-devel] [PATCH 1/2] C and Python Library: Updates for volume_create errors
Gris Ge
2014-08-29 14:32:45 UTC
Permalink
* Rename SIZE_LIMIT_REACHED to SYS_LIMIT_MAX_SIZE_EXCEEDED
* Add:
SYS_LIMIT_MAX_COUNT_EXCEEDED
# For example, ONTAP only allow 8192 LUNs per controller, if user try to
# create more, this error should be raised.

POOL_NOT_READY
# Error when trying to create volume on offlined pool.
* SYS_LIMIT_MAX_SIZE_EXCEEDED and POOL_NOT_READY is supported by ONTAP plugin
in next patch.

* SYS_LIMIT_MAX_COUNT_EXCEEDED is not supported yet but soon in ONTAP plugin.

Signed-off-by: Gris Ge <***@redhat.com>
---
c_binding/include/libstoragemgmt/libstoragemgmt_error.h | 4 +++-
python_binding/lsm/_common.py | 5 ++++-
2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_error.h b/c_binding/include/libstoragemgmt/libstoragemgmt_error.h
index 42e5547..c72c433 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_error.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_error.h
@@ -81,7 +81,9 @@ typedef enum {
LSM_ERR_NOT_ENOUGH_SPACE = 350, /**< Insufficient space */

LSM_ERR_SIZE_TOO_SMALL = 353, /**< Size specified is too small */
- LSM_ERR_SIZE_LIMIT_REACHED = 354, /**< Limit has been reached */
+ LSM_ERR_SYS_LIMIT_MAX_SIZE_EXCEEDED = 354, /**< System limit max size has been reached */
+ LSM_ERR_SYS_LIMIT_MAX_COUNT_EXCEEDED = 355, /**< System limit max count has been reached */
+ LSM_ERR_POOL_NOT_READY = 356, /**< Pool is not read for action requsted*/

LSM_ERR_TRANSPORT_COMMUNICATION = 400, /**< Error comunicating with plug-in */
LSM_ERR_TRANSPORT_SERIALIZATION = 401, /**< Transport serialization error */
diff --git a/python_binding/lsm/_common.py b/python_binding/lsm/_common.py
index 5089565..913f380 100644
--- a/python_binding/lsm/_common.py
+++ b/python_binding/lsm/_common.py
@@ -465,7 +465,10 @@ class ErrorNumber(object):

NOT_ENOUGH_SPACE = 350
SIZE_TOO_SMALL = 353
- SIZE_LIMIT_REACHED = 354
+
+ SYS_LIMIT_MAX_SIZE_EXCEEDED = 354
+ SYS_LIMIT_MAX_COUNT_EXCEEDED = 355
+ POOL_NOT_READY = 356

TRANSPORT_COMMUNICATION = 400
TRANSPORT_SERIALIZATION = 401
--
2.1.0
Gris Ge
2014-08-29 14:32:46 UTC
Permalink
* Improve volume_create() in these ways:
1. Performance improved by checking pool existence.
# Check if fail.
2. Handle offline pool: POOL_NOT_READY.
3. Handle volume smaller than 4MiB(Current ONTAP minimum LUN size).
Use lun_min_size() size and try again.
4. Handle system size limitation. A bad hack, check code comments for
detail reason.

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/ontap/na.py | 11 +++++++++--
plugin/ontap/ontap.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/plugin/ontap/na.py b/plugin/ontap/na.py
index 4fd1bc2..19cdba1 100644
--- a/plugin/ontap/na.py
+++ b/plugin/ontap/na.py
@@ -139,11 +139,15 @@ class FilerError(Exception):
NO_SUCH_IGROUP = 9003

# Using the name from NetApp SDK netapp_errno.h
+ EVDISK_ERROR_VDISK_EXISTS = 9012 # LUN name already in use
EVDISK_ERROR_VDISK_EXPORTED = 9013 # LUN is currently mapped
- EVDISK_ERROR_INITGROUP_MAPS_EXIST = 9029 # LUN maps for this initiator
- # group exist
EVDISK_ERROR_VDISK_NOT_ENABLED = 9014 # LUN is not online
EVDISK_ERROR_VDISK_NOT_DISABLED = 9015 # LUN is not offline
+ EVDISK_ERROR_INITGROUP_MAPS_EXIST = 9029 # LUN maps for this initiator
+ # group exist
+ EVDISK_ERROR_SIZE_TOO_LARGE = 9034 # LUN size too large.
+ EVDISK_ERROR_NO_SUCH_VOLUME = 9036 # NetApp Volume not exists.
+ EVDISK_ERROR_SIZE_TOO_SMALL = 9041 # Specified too small a size

def __init__(self, errno, reason, *args, **kwargs):
Exception.__init__(self, *args, **kwargs)
@@ -284,6 +288,9 @@ class Filer(object):
# No LUN found.
return []

+ def lun_min_size(self):
+ return self._invoke('lun-get-minsize', {'type': 'image'})['min-size']
+
def lun_create(self, full_path_name, size_bytes):
"""
Creates a lun
diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index 6e18c47..c9116c7 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -446,6 +446,10 @@ class Ontap(IStorageAreaNetwork, INfs):
% na_aggr['name']
break

+ if status & Pool.STATUS_OK and na_vol['state'] == 'offline':
+ status = Pool.STATUS_STOPPED
+ status_info = 'Disabled by admin'
+
# This volume should be noted that it is reserved for system
# and thus cannot be removed.
if pool_name == '/vol/vol0':
@@ -545,13 +549,51 @@ class Ontap(IStorageAreaNetwork, INfs):
"Pool not suitable for creating volumes")

na_vol_name = pool.name
- v = self.f.volume_names()
- if na_vol_name not in v:
- raise LsmError(ErrorNumber.NOT_FOUND_POOL, "Pool not found")

lun_name = self.f.lun_build_name(na_vol_name, volume_name)

- self.f.lun_create(lun_name, size_bytes)
+ try:
+ self.f.lun_create(lun_name, size_bytes)
+ except na.FilerError as fe:
+ if fe.errno == na.FilerError.EVDISK_ERROR_SIZE_TOO_LARGE:
+ # NetApp documented system limit on size in 16TiB. But in
+ # practise, it's a value between 15.97TiB and 15.96TiB.
+ # So we check on error reason:
+ # 'Requested LUN size is too large' -> system limit
+ # 'No space left on device' -> pool no free space
+ if fe.reason == 'Requested LUN size is too large':
+ raise LsmError(ErrorNumber.SYS_LIMIT_MAX_SIZE_EXCEEDED,
+ "Requeted size exceeded system limitation")
+ else:
+ raise LsmError(ErrorNumber.NOT_ENOUGH_SPACE,
+ "No enough requested free size in pool")
+ elif fe.errno == na.FilerError.EVDISK_ERROR_VDISK_EXISTS:
+ raise LsmError(ErrorNumber.NAME_CONFLICT,
+ "Requested volume name is already used by "
+ "other volume")
+ elif fe.errno == na.FilerError.EVDISK_ERROR_SIZE_TOO_SMALL:
+ # Size too small should not be raised. By API defination,
+ # we should create a LUN with mimun size.
+ min_size = self.f.lun_min_size()
+ return self.volume_create(
+ pool, volume_name, min_size, provisioning, flags)
+ elif fe.errno == na.FilerError.EVDISK_ERROR_NO_SUCH_VOLUME:
+ # When NetApp volume is offline, we will get this error also.
+ na_vols = self.f.volumes(volume_name=na_vol_name)
+ if len(na_vols) == 0:
+ raise LsmError(ErrorNumber.NOT_FOUND_POOL,
+ "Pool not found")
+ elif len(na_vols) == 1:
+ # NetApp Volume is disabled.
+ if na_vols[0]['state'] == 'offline':
+ raise LsmError(ErrorNumber.POOL_NOT_READY,
+ "Pool not ready for volume creation")
+ else:
+ raise LsmError(ErrorNumber.PLUGIN_BUG,
+ "volume_create(): "
+ "Got 2 or more na_vols: %s" % na_vols)
+ else:
+ raise

#Get the information about the newly created LUN
return None, self._get_volume(lun_name, pool.id)
--
2.1.0
Tony Asleson
2014-09-02 19:47:57 UTC
Permalink
Post by Gris Ge
1. Performance improved by checking pool existence.
# Check if fail.
2. Handle offline pool: POOL_NOT_READY.
3. Handle volume smaller than 4MiB(Current ONTAP minimum LUN size).
Use lun_min_size() size and try again.
Not a bad approach for handling a user specifying too small of a volume.
However, can we duplicate this behavior for SMI-S and nstor?
Post by Gris Ge
4. Handle system size limitation. A bad hack, check code comments for
detail reason.
Perhaps it would be better to return generic error code with vendor
specific code and text? Otherwise, this code will break every time the
vendor makes a text change. Also if NetApp supports localization WRT
the API text then this would be broken too.

Regards,
Tony

Tony Asleson
2014-09-02 19:39:10 UTC
Permalink
Post by Gris Ge
* Rename SIZE_LIMIT_REACHED to SYS_LIMIT_MAX_SIZE_EXCEEDED
SYS_LIMIT_MAX_COUNT_EXCEEDED
# For example, ONTAP only allow 8192 LUNs per controller, if user try to
# create more, this error should be raised.
POOL_NOT_READY
# Error when trying to create volume on offlined pool.
* SYS_LIMIT_MAX_SIZE_EXCEEDED and POOL_NOT_READY is supported by ONTAP plugin
in next patch.
Do we need these specific error codes? Can we support these on other
arrays? Without these error codes the user would get a generic error
code and the vendor code and text in the message which should give them
info on how to resolve.
Post by Gris Ge
* SYS_LIMIT_MAX_COUNT_EXCEEDED is not supported yet but soon in ONTAP plugin.
Please put related changes in the same patch. This way when they are
introduced we can see where they are being used.

Thanks,
Tony
Loading...