Gris Ge
2015-02-12 14:53:43 UTC
* Please don't commit. This is patch is purely based on guess and
simple test.
* NetApp is using(not changeable) 4KiB strip size. Some document of NetApp
mentioned it, but not explicitly.
* From Linux kernel sysfs optimal I/O size, which is 64KiB,
it's not base on RAID group disks count. This test indicate so:
# 24 disks RAID6(RAID-DP).
[***@storageqe-05 ~]# dd if=./test1.img of=/dev/mapper/mpathda bs=65536 oflag=direct
16000+0 records in
16000+0 records out
1048576000 bytes (1.0 GB) copied, 12.0671 s, 86.9 MB/s
[***@storageqe-05 ~]# dd if=./test2.img of=/dev/mapper/mpathf bs=90112 oflag=direct
11636+1 records in
11636+1 records out
1048576000 bytes (1.0 GB) copied, 14.2884 s, 73.4 MB/s
[***@storageqe-05 ~]# dd if=./test1.img of=/dev/mapper/mpathda bs=90112 oflag=direct
11636+1 records in
11636+1 records out
1048576000 bytes (1.0 GB) copied, 14.2517 s, 73.6 MB/s
[***@storageqe-05 ~]# dd if=./test2.img of=/dev/mapper/mpathf bs=65536 oflag=direct
16000+0 records in
16000+0 records out
1048576000 bytes (1.0 GB) copied, 12.7136 s, 82.5 MB/s
* No document explained why optimal I/O size is always 64KiB.
It might be caused by WAFL.
* Still waiting NetApp's reply on this.
Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/ontap/na.py | 8 ++++++--
plugin/ontap/ontap.py | 55 +++++++++++++++++++++++++++++++++++++++------------
2 files changed, 48 insertions(+), 15 deletions(-)
diff --git a/plugin/ontap/na.py b/plugin/ontap/na.py
index 1e015ba..b68577c 100644
--- a/plugin/ontap/na.py
+++ b/plugin/ontap/na.py
@@ -231,11 +231,15 @@ class Filer(object):
disks = self._invoke('disk-list-info')
return disks['disk-details']['disk-detail-info']
- def aggregates(self):
+ def aggregates(self, aggr_name=None):
"""
Return a list of aggregates
+ If aggr_name provided, return [na_aggr]
"""
- pools = self._invoke('aggr-list-info')
+ if aggr_name:
+ pools = self._invoke('aggr-list-info', {'aggregate': aggr_name})
+ else:
+ pools = self._invoke('aggr-list-info')
tmp = pools['aggregates']['aggr-info']
return to_list(tmp)
diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index c2a2c58..e175a71 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -121,6 +121,10 @@ class Ontap(IStorageAreaNetwork, INfs):
'restricted': 'volume is restricted to protocol accesses',
}
+ # strip size: http://www.netapp.com/us/media/tr-3001.pdf
+ _STRIP_SIZE = 4096
+ _OPT_IO_SIZE = 65536
+
def __init__(self):
self.f = None
self.sys_info = None
@@ -310,19 +314,6 @@ class Ontap(IStorageAreaNetwork, INfs):
return search_property(
[self._lun(l) for l in luns], search_key, search_value)
-# @staticmethod
-# def _raid_type_of_na_aggr(na_aggr):
-# na_raid_statuses = na_aggr['raid-status'].split(',')
-# if 'raid0' in na_raid_statuses:
-# return Pool.RAID_TYPE_RAID0
-# if 'raid4' in na_raid_statuses:
-# return Pool.RAID_TYPE_RAID4
-# if 'raid_dp' in na_raid_statuses:
-# return Pool.RAID_TYPE_RAID6
-# if 'mixed_raid_type' in na_raid_statuses:
-# return Pool.RAID_TYPE_MIXED
-# return Pool.RAID_TYPE_UNKNOWN
-
# This is based on NetApp ONTAP Manual pages:
# https://library.netapp.com/ecmdocs/ECMP1196890/html/man1/na_aggr.1.html
_AGGR_RAID_STATUS_CONV = {
@@ -1290,3 +1281,41 @@ class Ontap(IStorageAreaNetwork, INfs):
self.sys_info.id))
return search_property(tp, search_key, search_value)
+
+ @staticmethod
+ def _raid_type_of_na_aggr(na_aggr):
+ na_raid_statuses = na_aggr['raid-status'].split(',')
+ if 'mixed_raid_type' in na_raid_statuses:
+ return Volume.RAID_TYPE_MIXED
+ elif 'raid0' in na_raid_statuses:
+ return Volume.RAID_TYPE_RAID0
+ elif 'raid4' in na_raid_statuses:
+ return Volume.RAID_TYPE_RAID4
+ elif 'raid_dp' in na_raid_statuses:
+ return Volume.RAID_TYPE_RAID6
+ return Pool.RAID_TYPE_UNKNOWN
+
+ @handle_ontap_errors
+ def volume_raid_info(self, volume, flags=0):
+ na_vol_name = Ontap._get_volume_from_path(volume.pool_id)
+ na_vol = self.f.volumes(volume_name=na_vol_name)
+ if len(na_vol) == 0:
+ # If parent pool not found, then this LSM volume should not exist.
+ raise LsmError(
+ ErrorNumber.NOT_FOUND_VOLUME,
+ "Volume not found")
+ if len(na_vol) != 1:
+ raise LsmError(
+ ErrorNumber.PLUGIN_BUG,
+ "volume_raid_info(): Got 2+ na_vols from self.f.volumes() "
+ "%s" % na_vol)
+
+ na_vol = na_vol[0]
+ na_aggr_name = na_vol['containing-aggregate']
+ na_aggr = self.f.aggregates(aggr_name=na_aggr_name)[0]
+ raid_type = Ontap._raid_type_of_na_aggr(na_aggr)
+ extent_count = int(na_aggr['disk-count'])
+
+ return [
+ raid_type, Ontap._STRIP_SIZE, extent_count, Ontap._STRIP_SIZE,
+ Ontap._OPT_IO_SIZE]
simple test.
* NetApp is using(not changeable) 4KiB strip size. Some document of NetApp
mentioned it, but not explicitly.
* From Linux kernel sysfs optimal I/O size, which is 64KiB,
it's not base on RAID group disks count. This test indicate so:
# 24 disks RAID6(RAID-DP).
[***@storageqe-05 ~]# dd if=./test1.img of=/dev/mapper/mpathda bs=65536 oflag=direct
16000+0 records in
16000+0 records out
1048576000 bytes (1.0 GB) copied, 12.0671 s, 86.9 MB/s
[***@storageqe-05 ~]# dd if=./test2.img of=/dev/mapper/mpathf bs=90112 oflag=direct
11636+1 records in
11636+1 records out
1048576000 bytes (1.0 GB) copied, 14.2884 s, 73.4 MB/s
[***@storageqe-05 ~]# dd if=./test1.img of=/dev/mapper/mpathda bs=90112 oflag=direct
11636+1 records in
11636+1 records out
1048576000 bytes (1.0 GB) copied, 14.2517 s, 73.6 MB/s
[***@storageqe-05 ~]# dd if=./test2.img of=/dev/mapper/mpathf bs=65536 oflag=direct
16000+0 records in
16000+0 records out
1048576000 bytes (1.0 GB) copied, 12.7136 s, 82.5 MB/s
* No document explained why optimal I/O size is always 64KiB.
It might be caused by WAFL.
* Still waiting NetApp's reply on this.
Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/ontap/na.py | 8 ++++++--
plugin/ontap/ontap.py | 55 +++++++++++++++++++++++++++++++++++++++------------
2 files changed, 48 insertions(+), 15 deletions(-)
diff --git a/plugin/ontap/na.py b/plugin/ontap/na.py
index 1e015ba..b68577c 100644
--- a/plugin/ontap/na.py
+++ b/plugin/ontap/na.py
@@ -231,11 +231,15 @@ class Filer(object):
disks = self._invoke('disk-list-info')
return disks['disk-details']['disk-detail-info']
- def aggregates(self):
+ def aggregates(self, aggr_name=None):
"""
Return a list of aggregates
+ If aggr_name provided, return [na_aggr]
"""
- pools = self._invoke('aggr-list-info')
+ if aggr_name:
+ pools = self._invoke('aggr-list-info', {'aggregate': aggr_name})
+ else:
+ pools = self._invoke('aggr-list-info')
tmp = pools['aggregates']['aggr-info']
return to_list(tmp)
diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index c2a2c58..e175a71 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -121,6 +121,10 @@ class Ontap(IStorageAreaNetwork, INfs):
'restricted': 'volume is restricted to protocol accesses',
}
+ # strip size: http://www.netapp.com/us/media/tr-3001.pdf
+ _STRIP_SIZE = 4096
+ _OPT_IO_SIZE = 65536
+
def __init__(self):
self.f = None
self.sys_info = None
@@ -310,19 +314,6 @@ class Ontap(IStorageAreaNetwork, INfs):
return search_property(
[self._lun(l) for l in luns], search_key, search_value)
-# @staticmethod
-# def _raid_type_of_na_aggr(na_aggr):
-# na_raid_statuses = na_aggr['raid-status'].split(',')
-# if 'raid0' in na_raid_statuses:
-# return Pool.RAID_TYPE_RAID0
-# if 'raid4' in na_raid_statuses:
-# return Pool.RAID_TYPE_RAID4
-# if 'raid_dp' in na_raid_statuses:
-# return Pool.RAID_TYPE_RAID6
-# if 'mixed_raid_type' in na_raid_statuses:
-# return Pool.RAID_TYPE_MIXED
-# return Pool.RAID_TYPE_UNKNOWN
-
# This is based on NetApp ONTAP Manual pages:
# https://library.netapp.com/ecmdocs/ECMP1196890/html/man1/na_aggr.1.html
_AGGR_RAID_STATUS_CONV = {
@@ -1290,3 +1281,41 @@ class Ontap(IStorageAreaNetwork, INfs):
self.sys_info.id))
return search_property(tp, search_key, search_value)
+
+ @staticmethod
+ def _raid_type_of_na_aggr(na_aggr):
+ na_raid_statuses = na_aggr['raid-status'].split(',')
+ if 'mixed_raid_type' in na_raid_statuses:
+ return Volume.RAID_TYPE_MIXED
+ elif 'raid0' in na_raid_statuses:
+ return Volume.RAID_TYPE_RAID0
+ elif 'raid4' in na_raid_statuses:
+ return Volume.RAID_TYPE_RAID4
+ elif 'raid_dp' in na_raid_statuses:
+ return Volume.RAID_TYPE_RAID6
+ return Pool.RAID_TYPE_UNKNOWN
+
+ @handle_ontap_errors
+ def volume_raid_info(self, volume, flags=0):
+ na_vol_name = Ontap._get_volume_from_path(volume.pool_id)
+ na_vol = self.f.volumes(volume_name=na_vol_name)
+ if len(na_vol) == 0:
+ # If parent pool not found, then this LSM volume should not exist.
+ raise LsmError(
+ ErrorNumber.NOT_FOUND_VOLUME,
+ "Volume not found")
+ if len(na_vol) != 1:
+ raise LsmError(
+ ErrorNumber.PLUGIN_BUG,
+ "volume_raid_info(): Got 2+ na_vols from self.f.volumes() "
+ "%s" % na_vol)
+
+ na_vol = na_vol[0]
+ na_aggr_name = na_vol['containing-aggregate']
+ na_aggr = self.f.aggregates(aggr_name=na_aggr_name)[0]
+ raid_type = Ontap._raid_type_of_na_aggr(na_aggr)
+ extent_count = int(na_aggr['disk-count'])
+
+ return [
+ raid_type, Ontap._STRIP_SIZE, extent_count, Ontap._STRIP_SIZE,
+ Ontap._OPT_IO_SIZE]
--
1.8.3.1
1.8.3.1