From 9b20ae70ce4760f8a46f7b0ff9c78b508db2cc75 Mon Sep 17 00:00:00 2001
From: Yulia Portnova <yportnova>
Date: Mon, 2 Sep 2013 10:43:46 +0300
Subject: [PATCH] Deleted manila.volume

---
 manila/volume/__init__.py                     |   25 -
 manila/volume/api.py                          |  765 -----
 manila/volume/configuration.py                |   83 -
 manila/volume/driver.py                       |  551 ----
 manila/volume/drivers/__init__.py             |   22 -
 manila/volume/drivers/coraid.py               |  424 ---
 manila/volume/drivers/emc/__init__.py         |    0
 .../drivers/emc/cinder_emc_config.xml.sample  |   12 -
 manila/volume/drivers/emc/emc_smis_common.py  | 1564 ----------
 manila/volume/drivers/emc/emc_smis_iscsi.py   |  246 --
 manila/volume/drivers/glusterfs.py            |  283 --
 manila/volume/drivers/huawei/__init__.py      |   15 -
 .../huawei/cinder_huawei_conf.xml.sample      |   34 -
 manila/volume/drivers/huawei/huawei_iscsi.py  | 1547 ----------
 manila/volume/drivers/lvm.py                  |  688 -----
 manila/volume/drivers/netapp/__init__.py      |    0
 manila/volume/drivers/netapp/api.py           |  410 ---
 manila/volume/drivers/netapp/iscsi.py         | 2528 -----------------
 manila/volume/drivers/netapp/nfs.py           |  624 ----
 manila/volume/drivers/nexenta/__init__.py     |   33 -
 manila/volume/drivers/nexenta/jsonrpc.py      |   84 -
 manila/volume/drivers/nexenta/volume.py       |  353 ---
 manila/volume/drivers/nfs.py                  |  357 ---
 manila/volume/drivers/rbd.py                  |  306 --
 manila/volume/drivers/san/__init__.py         |   27 -
 manila/volume/drivers/san/hp/__init__.py      |    0
 .../volume/drivers/san/hp/hp_3par_common.py   |  742 -----
 manila/volume/drivers/san/hp/hp_3par_fc.py    |  259 --
 manila/volume/drivers/san/hp/hp_3par_iscsi.py |  279 --
 manila/volume/drivers/san/hp_lefthand.py      |  314 --
 manila/volume/drivers/san/san.py              |  177 --
 manila/volume/drivers/san/solaris.py          |  285 --
 manila/volume/drivers/scality.py              |  261 --
 manila/volume/drivers/sheepdog.py             |  141 -
 manila/volume/drivers/solidfire.py            |  590 ----
 manila/volume/drivers/storwize_svc.py         | 1627 -----------
 manila/volume/drivers/windows.py              |  246 --
 manila/volume/drivers/xenapi/__init__.py      |   13 -
 manila/volume/drivers/xenapi/lib.py           |  542 ----
 manila/volume/drivers/xenapi/sm.py            |  272 --
 manila/volume/drivers/xenapi/tools.py         |    7 -
 manila/volume/drivers/xiv.py                  |  122 -
 manila/volume/drivers/zadara.py               |  491 ----
 manila/volume/manager.py                      |  725 -----
 manila/volume/rpcapi.py                       |  130 -
 manila/volume/utils.py                        |  131 -
 manila/volume/volume_types.py                 |  158 --
 47 files changed, 18493 deletions(-)
 delete mode 100644 manila/volume/__init__.py
 delete mode 100644 manila/volume/api.py
 delete mode 100644 manila/volume/configuration.py
 delete mode 100644 manila/volume/driver.py
 delete mode 100644 manila/volume/drivers/__init__.py
 delete mode 100644 manila/volume/drivers/coraid.py
 delete mode 100644 manila/volume/drivers/emc/__init__.py
 delete mode 100644 manila/volume/drivers/emc/cinder_emc_config.xml.sample
 delete mode 100644 manila/volume/drivers/emc/emc_smis_common.py
 delete mode 100644 manila/volume/drivers/emc/emc_smis_iscsi.py
 delete mode 100644 manila/volume/drivers/glusterfs.py
 delete mode 100644 manila/volume/drivers/huawei/__init__.py
 delete mode 100644 manila/volume/drivers/huawei/cinder_huawei_conf.xml.sample
 delete mode 100644 manila/volume/drivers/huawei/huawei_iscsi.py
 delete mode 100644 manila/volume/drivers/lvm.py
 delete mode 100644 manila/volume/drivers/netapp/__init__.py
 delete mode 100644 manila/volume/drivers/netapp/api.py
 delete mode 100644 manila/volume/drivers/netapp/iscsi.py
 delete mode 100644 manila/volume/drivers/netapp/nfs.py
 delete mode 100644 manila/volume/drivers/nexenta/__init__.py
 delete mode 100644 manila/volume/drivers/nexenta/jsonrpc.py
 delete mode 100644 manila/volume/drivers/nexenta/volume.py
 delete mode 100755 manila/volume/drivers/nfs.py
 delete mode 100644 manila/volume/drivers/rbd.py
 delete mode 100644 manila/volume/drivers/san/__init__.py
 delete mode 100644 manila/volume/drivers/san/hp/__init__.py
 delete mode 100644 manila/volume/drivers/san/hp/hp_3par_common.py
 delete mode 100644 manila/volume/drivers/san/hp/hp_3par_fc.py
 delete mode 100644 manila/volume/drivers/san/hp/hp_3par_iscsi.py
 delete mode 100644 manila/volume/drivers/san/hp_lefthand.py
 delete mode 100644 manila/volume/drivers/san/san.py
 delete mode 100644 manila/volume/drivers/san/solaris.py
 delete mode 100644 manila/volume/drivers/scality.py
 delete mode 100644 manila/volume/drivers/sheepdog.py
 delete mode 100644 manila/volume/drivers/solidfire.py
 delete mode 100755 manila/volume/drivers/storwize_svc.py
 delete mode 100644 manila/volume/drivers/windows.py
 delete mode 100644 manila/volume/drivers/xenapi/__init__.py
 delete mode 100644 manila/volume/drivers/xenapi/lib.py
 delete mode 100644 manila/volume/drivers/xenapi/sm.py
 delete mode 100644 manila/volume/drivers/xenapi/tools.py
 delete mode 100644 manila/volume/drivers/xiv.py
 delete mode 100644 manila/volume/drivers/zadara.py
 delete mode 100644 manila/volume/manager.py
 delete mode 100644 manila/volume/rpcapi.py
 delete mode 100644 manila/volume/utils.py
 delete mode 100644 manila/volume/volume_types.py

diff --git a/manila/volume/__init__.py b/manila/volume/__init__.py
deleted file mode 100644
index 4f2558595f..0000000000
--- a/manila/volume/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-# Importing full names to not pollute the namespace and cause possible
-# collisions with use of 'from manila.volume import <foo>' elsewhere.
-import manila.flags
-import manila.openstack.common.importutils
-
-API = manila.openstack.common.importutils.import_class(
-        manila.flags.FLAGS.volume_api_class)
diff --git a/manila/volume/api.py b/manila/volume/api.py
deleted file mode 100644
index ec7bfdf7be..0000000000
--- a/manila/volume/api.py
+++ /dev/null
@@ -1,765 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-Handles all requests relating to volumes.
-"""
-
-import functools
-
-from oslo.config import cfg
-
-from manila.db import base
-from manila import exception
-from manila import flags
-from manila.image import glance
-from manila.openstack.common import excutils
-from manila.openstack.common import log as logging
-from manila.openstack.common import timeutils
-import manila.policy
-from manila import quota
-from manila.scheduler import rpcapi as scheduler_rpcapi
-from manila.volume import rpcapi as volume_rpcapi
-from manila.volume import volume_types
-
-volume_host_opt = cfg.BoolOpt('snapshot_same_host',
-                              default=True,
-                              help='Create volume from snapshot at the host '
-                                   'where snapshot resides')
-
-FLAGS = flags.FLAGS
-FLAGS.register_opt(volume_host_opt)
-flags.DECLARE('storage_availability_zone', 'manila.volume.manager')
-
-LOG = logging.getLogger(__name__)
-GB = 1048576 * 1024
-QUOTAS = quota.QUOTAS
-
-
-def wrap_check_policy(func):
-    """Check policy corresponding to the wrapped methods prior to execution
-
-    This decorator requires the first 3 args of the wrapped function
-    to be (self, context, volume)
-    """
-    @functools.wraps(func)
-    def wrapped(self, context, target_obj, *args, **kwargs):
-        check_policy(context, func.__name__, target_obj)
-        return func(self, context, target_obj, *args, **kwargs)
-
-    return wrapped
-
-
-def check_policy(context, action, target_obj=None):
-    target = {
-        'project_id': context.project_id,
-        'user_id': context.user_id,
-    }
-    target.update(target_obj or {})
-    _action = 'volume:%s' % action
-    manila.policy.enforce(context, _action, target)
-
-
-class API(base.Base):
-    """API for interacting with the volume manager."""
-
-    def __init__(self, db_driver=None, image_service=None):
-        self.image_service = (image_service or
-                              glance.get_default_image_service())
-        self.scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI()
-        self.volume_rpcapi = volume_rpcapi.VolumeAPI()
-        super(API, self).__init__(db_driver)
-
-    def create(self, context, size, name, description, snapshot=None,
-               image_id=None, volume_type=None, metadata=None,
-               availability_zone=None, source_volume=None):
-
-        exclusive_options = (snapshot, image_id, source_volume)
-        exclusive_options_set = sum(1 for option in
-                                    exclusive_options if option is not None)
-        if exclusive_options_set > 1:
-            msg = (_("May specify only one of snapshot, imageRef "
-                     "or source volume"))
-            raise exception.InvalidInput(reason=msg)
-
-        check_policy(context, 'create')
-        if snapshot is not None:
-            if snapshot['status'] != "available":
-                msg = _("status must be available")
-                raise exception.InvalidSnapshot(reason=msg)
-            if not size:
-                size = snapshot['volume_size']
-            elif size < snapshot['volume_size']:
-                msg = _("Volume size cannot be lesser than"
-                        " the Snapshot size")
-                raise exception.InvalidInput(reason=msg)
-            snapshot_id = snapshot['id']
-        else:
-            snapshot_id = None
-
-        if source_volume is not None:
-            if source_volume['status'] == "error":
-                msg = _("Unable to clone volumes that are in an error state")
-                raise exception.InvalidSourceVolume(reason=msg)
-            if not size:
-                size = source_volume['size']
-            else:
-                if size < source_volume['size']:
-                    msg = _("Clones currently must be "
-                            ">= original volume size.")
-                    raise exception.InvalidInput(reason=msg)
-            source_volid = source_volume['id']
-        else:
-            source_volid = None
-
-        def as_int(s):
-            try:
-                return int(s)
-            except (ValueError, TypeError):
-                return s
-
-        # tolerate size as stringified int
-        size = as_int(size)
-
-        if not isinstance(size, int) or size <= 0:
-            msg = (_("Volume size '%s' must be an integer and greater than 0")
-                   % size)
-            raise exception.InvalidInput(reason=msg)
-
-        if (image_id and not (source_volume or snapshot)):
-            # check image existence
-            image_meta = self.image_service.show(context, image_id)
-            image_size_in_gb = (int(image_meta['size']) + GB - 1) / GB
-            #check image size is not larger than volume size.
-            if image_size_in_gb > size:
-                msg = _('Size of specified image is larger than volume size.')
-                raise exception.InvalidInput(reason=msg)
-            # Check image minDisk requirement is met for the particular volume
-            if size < image_meta.get('min_disk', 0):
-                msg = _('Image minDisk size is larger than the volume size.')
-                raise exception.InvalidInput(reason=msg)
-
-        try:
-            reservations = QUOTAS.reserve(context, volumes=1, gigabytes=size)
-        except exception.OverQuota as e:
-            overs = e.kwargs['overs']
-            usages = e.kwargs['usages']
-            quotas = e.kwargs['quotas']
-
-            def _consumed(name):
-                return (usages[name]['reserved'] + usages[name]['in_use'])
-
-            if 'gigabytes' in overs:
-                msg = _("Quota exceeded for %(s_pid)s, tried to create "
-                        "%(s_size)sG volume (%(d_consumed)dG of %(d_quota)dG "
-                        "already consumed)")
-                LOG.warn(msg % {'s_pid': context.project_id,
-                                's_size': size,
-                                'd_consumed': _consumed('gigabytes'),
-                                'd_quota': quotas['gigabytes']})
-                raise exception.VolumeSizeExceedsAvailableQuota()
-            elif 'volumes' in overs:
-                msg = _("Quota exceeded for %(s_pid)s, tried to create "
-                        "volume (%(d_consumed)d volumes "
-                        "already consumed)")
-                LOG.warn(msg % {'s_pid': context.project_id,
-                                'd_consumed': _consumed('volumes')})
-                raise exception.VolumeLimitExceeded(allowed=quotas['volumes'])
-
-        if availability_zone is None:
-            availability_zone = FLAGS.storage_availability_zone
-
-        if not volume_type and not source_volume:
-            volume_type = volume_types.get_default_volume_type()
-
-        if not volume_type and source_volume:
-            volume_type_id = source_volume['volume_type_id']
-        else:
-            volume_type_id = volume_type.get('id')
-
-        self._check_metadata_properties(context, metadata)
-        options = {'size': size,
-                   'user_id': context.user_id,
-                   'project_id': context.project_id,
-                   'snapshot_id': snapshot_id,
-                   'availability_zone': availability_zone,
-                   'status': "creating",
-                   'attach_status': "detached",
-                   'display_name': name,
-                   'display_description': description,
-                   'volume_type_id': volume_type_id,
-                   'metadata': metadata,
-                   'source_volid': source_volid}
-
-        try:
-            volume = self.db.volume_create(context, options)
-            QUOTAS.commit(context, reservations)
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                try:
-                    self.db.volume_destroy(context, volume['id'])
-                finally:
-                    QUOTAS.rollback(context, reservations)
-
-        request_spec = {'volume_properties': options,
-                        'volume_type': volume_type,
-                        'volume_id': volume['id'],
-                        'snapshot_id': volume['snapshot_id'],
-                        'image_id': image_id,
-                        'source_volid': volume['source_volid']}
-
-        filter_properties = {}
-
-        self._cast_create_volume(context, request_spec, filter_properties)
-
-        return volume
-
-    def _cast_create_volume(self, context, request_spec, filter_properties):
-
-        # NOTE(Rongze Zhu): It is a simple solution for bug 1008866
-        # If snapshot_id is set, make the call create volume directly to
-        # the volume host where the snapshot resides instead of passing it
-        # through the scheduler. So snapshot can be copy to new volume.
-
-        source_volid = request_spec['source_volid']
-        volume_id = request_spec['volume_id']
-        snapshot_id = request_spec['snapshot_id']
-        image_id = request_spec['image_id']
-
-        if snapshot_id and FLAGS.snapshot_same_host:
-            snapshot_ref = self.db.snapshot_get(context, snapshot_id)
-            source_volume_ref = self.db.volume_get(context,
-                                                   snapshot_ref['volume_id'])
-            now = timeutils.utcnow()
-            values = {'host': source_volume_ref['host'], 'scheduled_at': now}
-            volume_ref = self.db.volume_update(context, volume_id, values)
-
-            # bypass scheduler and send request directly to volume
-            self.volume_rpcapi.create_volume(
-                context,
-                volume_ref,
-                volume_ref['host'],
-                request_spec=request_spec,
-                filter_properties=filter_properties,
-                allow_reschedule=False,
-                snapshot_id=snapshot_id,
-                image_id=image_id)
-        elif source_volid:
-            source_volume_ref = self.db.volume_get(context,
-                                                   source_volid)
-            now = timeutils.utcnow()
-            values = {'host': source_volume_ref['host'], 'scheduled_at': now}
-            volume_ref = self.db.volume_update(context, volume_id, values)
-
-            # bypass scheduler and send request directly to volume
-            self.volume_rpcapi.create_volume(
-                context,
-                volume_ref,
-                volume_ref['host'],
-                request_spec=request_spec,
-                filter_properties=filter_properties,
-                allow_reschedule=False,
-                snapshot_id=snapshot_id,
-                image_id=image_id,
-                source_volid=source_volid)
-        else:
-            self.scheduler_rpcapi.create_volume(
-                context,
-                FLAGS.volume_topic,
-                volume_id,
-                snapshot_id,
-                image_id,
-                request_spec=request_spec,
-                filter_properties=filter_properties)
-
-    @wrap_check_policy
-    def delete(self, context, volume, force=False):
-        if context.is_admin and context.project_id != volume['project_id']:
-            project_id = volume['project_id']
-        else:
-            project_id = context.project_id
-
-        volume_id = volume['id']
-        if not volume['host']:
-            # NOTE(vish): scheduling failed, so delete it
-            # Note(zhiteng): update volume quota reservation
-            try:
-                reservations = QUOTAS.reserve(context,
-                                              project_id=project_id,
-                                              volumes=-1,
-                                              gigabytes=-volume['size'])
-            except Exception:
-                reservations = None
-                LOG.exception(_("Failed to update quota for deleting volume"))
-            self.db.volume_destroy(context.elevated(), volume_id)
-
-            if reservations:
-                QUOTAS.commit(context, reservations, project_id=project_id)
-            return
-        if not force and volume['status'] not in ["available", "error",
-                                                  "error_restoring"]:
-            msg = _("Volume status must be available or error")
-            raise exception.InvalidVolume(reason=msg)
-
-        snapshots = self.db.snapshot_get_all_for_volume(context, volume_id)
-        if len(snapshots):
-            msg = _("Volume still has %d dependent snapshots") % len(snapshots)
-            raise exception.InvalidVolume(reason=msg)
-
-        now = timeutils.utcnow()
-        self.db.volume_update(context, volume_id, {'status': 'deleting',
-                                                   'terminated_at': now})
-
-        self.volume_rpcapi.delete_volume(context, volume)
-
-    @wrap_check_policy
-    def update(self, context, volume, fields):
-        self.db.volume_update(context, volume['id'], fields)
-
-    def get(self, context, volume_id):
-        rv = self.db.volume_get(context, volume_id)
-        glance_meta = rv.get('volume_glance_metadata', None)
-        volume = dict(rv.iteritems())
-        check_policy(context, 'get', volume)
-
-        # NOTE(jdg): As per bug 1115629 iteritems doesn't pick
-        # up the glance_meta dependency, add it explicitly if
-        # it exists in the rv
-        if glance_meta:
-            volume['volume_glance_metadata'] = glance_meta
-
-        return volume
-
-    def get_all(self, context, marker=None, limit=None, sort_key='created_at',
-                sort_dir='desc', filters={}):
-        check_policy(context, 'get_all')
-
-        try:
-            if limit is not None:
-                limit = int(limit)
-                if limit < 0:
-                    msg = _('limit param must be positive')
-                    raise exception.InvalidInput(reason=msg)
-        except ValueError:
-            msg = _('limit param must be an integer')
-            raise exception.InvalidInput(reason=msg)
-
-        if (context.is_admin and 'all_tenants' in filters):
-            # Need to remove all_tenants to pass the filtering below.
-            del filters['all_tenants']
-            volumes = self.db.volume_get_all(context, marker, limit, sort_key,
-                                             sort_dir)
-        else:
-            volumes = self.db.volume_get_all_by_project(context,
-                                                        context.project_id,
-                                                        marker, limit,
-                                                        sort_key, sort_dir)
-
-        if filters:
-            LOG.debug(_("Searching by: %s") % str(filters))
-
-            def _check_metadata_match(volume, searchdict):
-                volume_metadata = {}
-                for i in volume.get('volume_metadata'):
-                    volume_metadata[i['key']] = i['value']
-
-                for k, v in searchdict.iteritems():
-                    if (k not in volume_metadata.keys() or
-                            volume_metadata[k] != v):
-                        return False
-                return True
-
-            # search_option to filter_name mapping.
-            filter_mapping = {'metadata': _check_metadata_match}
-
-            result = []
-            not_found = object()
-            for volume in volumes:
-                # go over all filters in the list
-                for opt, values in filters.iteritems():
-                    try:
-                        filter_func = filter_mapping[opt]
-                    except KeyError:
-                        def filter_func(volume, value):
-                            return volume.get(opt, not_found) == value
-                    if not filter_func(volume, values):
-                        break  # volume doesn't match this filter
-                else:  # did not break out loop
-                    result.append(volume)  # volume matches all filters
-            volumes = result
-
-        return volumes
-
-    def get_snapshot(self, context, snapshot_id):
-        check_policy(context, 'get_snapshot')
-        rv = self.db.snapshot_get(context, snapshot_id)
-        return dict(rv.iteritems())
-
-    def get_volume(self, context, volume_id):
-        check_policy(context, 'get_volume')
-        rv = self.db.volume_get(context, volume_id)
-        return dict(rv.iteritems())
-
-    def get_all_snapshots(self, context, search_opts=None):
-        check_policy(context, 'get_all_snapshots')
-
-        search_opts = search_opts or {}
-
-        if (context.is_admin and 'all_tenants' in search_opts):
-            # Need to remove all_tenants to pass the filtering below.
-            del search_opts['all_tenants']
-            snapshots = self.db.snapshot_get_all(context)
-        else:
-            snapshots = self.db.snapshot_get_all_by_project(
-                context, context.project_id)
-
-        if search_opts:
-            LOG.debug(_("Searching by: %s") % str(search_opts))
-
-            results = []
-            not_found = object()
-            for snapshot in snapshots:
-                for opt, value in search_opts.iteritems():
-                    if snapshot.get(opt, not_found) != value:
-                        break
-                else:
-                    results.append(snapshot)
-            snapshots = results
-        return snapshots
-
-    @wrap_check_policy
-    def check_attach(self, context, volume):
-        # TODO(vish): abstract status checking?
-        if volume['status'] != "available":
-            msg = _("status must be available")
-            raise exception.InvalidVolume(reason=msg)
-        if volume['attach_status'] == "attached":
-            msg = _("already attached")
-            raise exception.InvalidVolume(reason=msg)
-
-    @wrap_check_policy
-    def check_detach(self, context, volume):
-        # TODO(vish): abstract status checking?
-        if volume['status'] == "available":
-            msg = _("already detached")
-            raise exception.InvalidVolume(reason=msg)
-
-    @wrap_check_policy
-    def reserve_volume(self, context, volume):
-        #NOTE(jdg): check for Race condition bug 1096983
-        #explicitly get updated ref and check
-        volume = self.db.volume_get(context, volume['id'])
-        if volume['status'] == 'available':
-            self.update(context, volume, {"status": "attaching"})
-        else:
-            msg = _("Volume status must be available to reserve")
-            LOG.error(msg)
-            raise exception.InvalidVolume(reason=msg)
-
-    @wrap_check_policy
-    def unreserve_volume(self, context, volume):
-        if volume['status'] == "attaching":
-            self.update(context, volume, {"status": "available"})
-
-    @wrap_check_policy
-    def begin_detaching(self, context, volume):
-        self.update(context, volume, {"status": "detaching"})
-
-    @wrap_check_policy
-    def roll_detaching(self, context, volume):
-        if volume['status'] == "detaching":
-            self.update(context, volume, {"status": "in-use"})
-
-    @wrap_check_policy
-    def attach(self, context, volume, instance_uuid, mountpoint):
-        return self.volume_rpcapi.attach_volume(context,
-                                                volume,
-                                                instance_uuid,
-                                                mountpoint)
-
-    @wrap_check_policy
-    def detach(self, context, volume):
-        return self.volume_rpcapi.detach_volume(context, volume)
-
-    @wrap_check_policy
-    def initialize_connection(self, context, volume, connector):
-        return self.volume_rpcapi.initialize_connection(context,
-                                                        volume,
-                                                        connector)
-
-    @wrap_check_policy
-    def terminate_connection(self, context, volume, connector, force=False):
-        self.unreserve_volume(context, volume)
-        return self.volume_rpcapi.terminate_connection(context,
-                                                       volume,
-                                                       connector,
-                                                       force)
-
-    def _create_snapshot(self, context,
-                         volume, name, description,
-                         force=False, metadata=None):
-        check_policy(context, 'create_snapshot', volume)
-
-        if ((not force) and (volume['status'] != "available")):
-            msg = _("must be available")
-            raise exception.InvalidVolume(reason=msg)
-
-        try:
-            if FLAGS.no_snapshot_gb_quota:
-                reservations = QUOTAS.reserve(context, snapshots=1)
-            else:
-                reservations = QUOTAS.reserve(context, snapshots=1,
-                                              gigabytes=volume['size'])
-        except exception.OverQuota as e:
-            overs = e.kwargs['overs']
-            usages = e.kwargs['usages']
-            quotas = e.kwargs['quotas']
-
-            def _consumed(name):
-                return (usages[name]['reserved'] + usages[name]['in_use'])
-
-            if 'gigabytes' in overs:
-                msg = _("Quota exceeded for %(s_pid)s, tried to create "
-                        "%(s_size)sG snapshot (%(d_consumed)dG of "
-                        "%(d_quota)dG already consumed)")
-                LOG.warn(msg % {'s_pid': context.project_id,
-                                's_size': volume['size'],
-                                'd_consumed': _consumed('gigabytes'),
-                                'd_quota': quotas['gigabytes']})
-                raise exception.VolumeSizeExceedsAvailableQuota()
-            elif 'snapshots' in overs:
-                msg = _("Quota exceeded for %(s_pid)s, tried to create "
-                        "snapshot (%(d_consumed)d snapshots "
-                        "already consumed)")
-
-                LOG.warn(msg % {'s_pid': context.project_id,
-                                'd_consumed': _consumed('snapshots')})
-                raise exception.SnapshotLimitExceeded(
-                    allowed=quotas['snapshots'])
-
-        self._check_metadata_properties(context, metadata)
-        options = {'volume_id': volume['id'],
-                   'user_id': context.user_id,
-                   'project_id': context.project_id,
-                   'status': "creating",
-                   'progress': '0%',
-                   'volume_size': volume['size'],
-                   'display_name': name,
-                   'display_description': description,
-                   'metadata': metadata}
-
-        try:
-            snapshot = self.db.snapshot_create(context, options)
-            QUOTAS.commit(context, reservations)
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                try:
-                    self.db.snapshot_destroy(context, volume['id'])
-                finally:
-                    QUOTAS.rollback(context, reservations)
-
-        self.volume_rpcapi.create_snapshot(context, volume, snapshot)
-
-        return snapshot
-
-    def create_snapshot(self, context,
-                        volume, name,
-                        description, metadata=None):
-        return self._create_snapshot(context, volume, name, description,
-                                     False, metadata)
-
-    def create_snapshot_force(self, context,
-                              volume, name,
-                              description, metadata=None):
-        return self._create_snapshot(context, volume, name, description,
-                                     True, metadata)
-
-    @wrap_check_policy
-    def delete_snapshot(self, context, snapshot, force=False):
-        if not force and snapshot['status'] not in ["available", "error"]:
-            msg = _("Volume Snapshot status must be available or error")
-            raise exception.InvalidSnapshot(reason=msg)
-        self.db.snapshot_update(context, snapshot['id'],
-                                {'status': 'deleting'})
-        volume = self.db.volume_get(context, snapshot['volume_id'])
-        self.volume_rpcapi.delete_snapshot(context, snapshot, volume['host'])
-
-    @wrap_check_policy
-    def update_snapshot(self, context, snapshot, fields):
-        self.db.snapshot_update(context, snapshot['id'], fields)
-
-    @wrap_check_policy
-    def get_volume_metadata(self, context, volume):
-        """Get all metadata associated with a volume."""
-        rv = self.db.volume_metadata_get(context, volume['id'])
-        return dict(rv.iteritems())
-
-    @wrap_check_policy
-    def delete_volume_metadata(self, context, volume, key):
-        """Delete the given metadata item from a volume."""
-        self.db.volume_metadata_delete(context, volume['id'], key)
-
-    def _check_metadata_properties(self, context, metadata=None):
-        if not metadata:
-            metadata = {}
-
-        for k, v in metadata.iteritems():
-            if len(k) == 0:
-                msg = _("Metadata property key blank")
-                LOG.warn(msg)
-                raise exception.InvalidVolumeMetadata(reason=msg)
-            if len(k) > 255:
-                msg = _("Metadata property key greater than 255 characters")
-                LOG.warn(msg)
-                raise exception.InvalidVolumeMetadataSize(reason=msg)
-            if len(v) > 255:
-                msg = _("Metadata property value greater than 255 characters")
-                LOG.warn(msg)
-                raise exception.InvalidVolumeMetadataSize(reason=msg)
-
-    @wrap_check_policy
-    def update_volume_metadata(self, context, volume, metadata, delete=False):
-        """Updates or creates volume metadata.
-
-        If delete is True, metadata items that are not specified in the
-        `metadata` argument will be deleted.
-
-        """
-        orig_meta = self.get_volume_metadata(context, volume)
-        if delete:
-            _metadata = metadata
-        else:
-            _metadata = orig_meta.copy()
-            _metadata.update(metadata)
-
-        self._check_metadata_properties(context, _metadata)
-
-        self.db.volume_metadata_update(context, volume['id'], _metadata, True)
-
-        # TODO(jdg): Implement an RPC call for drivers that may use this info
-
-        return _metadata
-
-    def get_volume_metadata_value(self, volume, key):
-        """Get value of particular metadata key."""
-        metadata = volume.get('volume_metadata')
-        if metadata:
-            for i in volume['volume_metadata']:
-                if i['key'] == key:
-                    return i['value']
-        return None
-
-    def get_snapshot_metadata(self, context, snapshot):
-        """Get all metadata associated with a snapshot."""
-        rv = self.db.snapshot_metadata_get(context, snapshot['id'])
-        return dict(rv.iteritems())
-
-    def delete_snapshot_metadata(self, context, snapshot, key):
-        """Delete the given metadata item from a snapshot."""
-        self.db.snapshot_metadata_delete(context, snapshot['id'], key)
-
-    def update_snapshot_metadata(self, context,
-                                 snapshot, metadata,
-                                 delete=False):
-        """Updates or creates snapshot metadata.
-
-        If delete is True, metadata items that are not specified in the
-        `metadata` argument will be deleted.
-
-        """
-        orig_meta = self.get_snapshot_metadata(context, snapshot)
-        if delete:
-            _metadata = metadata
-        else:
-            _metadata = orig_meta.copy()
-            _metadata.update(metadata)
-
-        self._check_metadata_properties(context, _metadata)
-
-        self.db.snapshot_metadata_update(context,
-                                         snapshot['id'],
-                                         _metadata,
-                                         True)
-
-        # TODO(jdg): Implement an RPC call for drivers that may use this info
-
-        return _metadata
-
-    def get_snapshot_metadata_value(self, snapshot, key):
-        pass
-
-    @wrap_check_policy
-    def get_volume_image_metadata(self, context, volume):
-        db_data = self.db.volume_glance_metadata_get(context, volume['id'])
-        return dict(
-            (meta_entry.key, meta_entry.value) for meta_entry in db_data
-        )
-
-    def _check_volume_availability(self, context, volume, force):
-        """Check if the volume can be used."""
-        if volume['status'] not in ['available', 'in-use']:
-            msg = _('Volume status must be available/in-use.')
-            raise exception.InvalidVolume(reason=msg)
-        if not force and 'in-use' == volume['status']:
-            msg = _('Volume status is in-use.')
-            raise exception.InvalidVolume(reason=msg)
-
-    @wrap_check_policy
-    def copy_volume_to_image(self, context, volume, metadata, force):
-        """Create a new image from the specified volume."""
-        self._check_volume_availability(context, volume, force)
-
-        recv_metadata = self.image_service.create(context, metadata)
-        self.update(context, volume, {'status': 'uploading'})
-        self.volume_rpcapi.copy_volume_to_image(context,
-                                                volume,
-                                                recv_metadata)
-
-        response = {"id": volume['id'],
-                    "updated_at": volume['updated_at'],
-                    "status": 'uploading',
-                    "display_description": volume['display_description'],
-                    "size": volume['size'],
-                    "volume_type": volume['volume_type'],
-                    "image_id": recv_metadata['id'],
-                    "container_format": recv_metadata['container_format'],
-                    "disk_format": recv_metadata['disk_format'],
-                    "image_name": recv_metadata.get('name', None)}
-        return response
-
-
-class HostAPI(base.Base):
-    def __init__(self):
-        super(HostAPI, self).__init__()
-
-    """Sub-set of the Volume Manager API for managing host operations."""
-    def set_host_enabled(self, context, host, enabled):
-        """Sets the specified host's ability to accept new volumes."""
-        raise NotImplementedError()
-
-    def get_host_uptime(self, context, host):
-        """Returns the result of calling "uptime" on the target host."""
-        raise NotImplementedError()
-
-    def host_power_action(self, context, host, action):
-        raise NotImplementedError()
-
-    def set_host_maintenance(self, context, host, mode):
-        """Start/Stop host maintenance window. On start, it triggers
-        volume evacuation."""
-        raise NotImplementedError()
diff --git a/manila/volume/configuration.py b/manila/volume/configuration.py
deleted file mode 100644
index 38fdf49d6b..0000000000
--- a/manila/volume/configuration.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright (c) 2012 Rackspace Hosting
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-Configuration support for all drivers.
-
-This module allows support for setting configurations either from default
-or from a particular FLAGS group, to be able to set multiple configurations
-for a given set of values.
-
-For instance, two lvm configurations can be set by naming them in groups as
-
- [lvm1]
- volume_group=lvm-group-1
- ...
-
- [lvm2]
- volume_group=lvm-group-2
- ...
-
-And the configuration group name will be passed in so that all calls to
-configuration.volume_group within that instance will be mapped to the proper
-named group.
-
-This class also ensures the implementation's configuration is grafted into the
-option group. This is due to the way cfg works. All cfg options must be defined
-and registered in the group in which they are used.
-"""
-
-from oslo.config import cfg
-
-from manila import flags
-from manila.openstack.common import log as logging
-
-
-FLAGS = flags.FLAGS
-LOG = logging.getLogger(__name__)
-
-
-class Configuration(object):
-
-    def __init__(self, volume_opts, config_group=None):
-        """This takes care of grafting the implementation's config
-           values into the config group"""
-        self.config_group = config_group
-
-        # set the local conf so that __call__'s know what to use
-        if self.config_group:
-            self._ensure_config_values(volume_opts)
-            self.local_conf = FLAGS._get(self.config_group)
-        else:
-            self.local_conf = FLAGS
-
-    def _ensure_config_values(self, volume_opts):
-            FLAGS.register_opts(volume_opts,
-                                group=self.config_group)
-
-    def append_config_values(self, volume_opts):
-        self._ensure_config_values(volume_opts)
-
-    def safe_get(self, value):
-        try:
-            return self.__getattr__(value)
-        except cfg.NoSuchOptError:
-            return None
-
-    def __getattr__(self, value):
-        return getattr(self.local_conf, value)
diff --git a/manila/volume/driver.py b/manila/volume/driver.py
deleted file mode 100644
index 53fb898ec5..0000000000
--- a/manila/volume/driver.py
+++ /dev/null
@@ -1,551 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Drivers for volumes.
-
-"""
-
-import os
-import socket
-import time
-
-from oslo.config import cfg
-
-from manila import exception
-from manila.image import image_utils
-from manila.openstack.common import log as logging
-from manila import utils
-
-LOG = logging.getLogger(__name__)
-
-volume_opts = [
-    cfg.IntOpt('num_shell_tries',
-               default=3,
-               help='number of times to attempt to run flakey shell commands'),
-    cfg.IntOpt('reserved_percentage',
-               default=0,
-               help='The percentage of backend capacity is reserved'),
-    cfg.IntOpt('num_iscsi_scan_tries',
-               default=3,
-               help='number of times to rescan iSCSI target to find volume'),
-    cfg.IntOpt('iscsi_num_targets',
-               default=100,
-               help='Number of iscsi target ids per host'),
-    cfg.StrOpt('iscsi_target_prefix',
-               default='iqn.2010-10.org.openstack:',
-               help='prefix for iscsi volumes'),
-    cfg.StrOpt('iscsi_ip_address',
-               default='$my_ip',
-               help='The port that the iSCSI daemon is listening on'),
-    cfg.IntOpt('iscsi_port',
-               default=3260,
-               help='The port that the iSCSI daemon is listening on'),
-    cfg.StrOpt('volume_backend_name',
-               default=None,
-               help='The backend name for a given driver implementation'), ]
-
-CONF = cfg.CONF
-CONF.register_opts(volume_opts)
-CONF.import_opt('iscsi_helper', 'manila.brick.iscsi.iscsi')
-
-
-class VolumeDriver(object):
-    """Executes commands relating to Volumes."""
-    def __init__(self, execute=utils.execute, *args, **kwargs):
-        # NOTE(vish): db is set by Manager
-        self.db = None
-        self.configuration = kwargs.get('configuration', None)
-        if self.configuration:
-            self.configuration.append_config_values(volume_opts)
-        self.set_execute(execute)
-        self._stats = {}
-
-    def set_execute(self, execute):
-        self._execute = execute
-
-    def _try_execute(self, *command, **kwargs):
-        # NOTE(vish): Volume commands can partially fail due to timing, but
-        #             running them a second time on failure will usually
-        #             recover nicely.
-        tries = 0
-        while True:
-            try:
-                self._execute(*command, **kwargs)
-                return True
-            except exception.ProcessExecutionError:
-                tries = tries + 1
-                if tries >= self.configuration.num_shell_tries:
-                    raise
-                LOG.exception(_("Recovering from a failed execute.  "
-                                "Try number %s"), tries)
-                time.sleep(tries ** 2)
-
-    def check_for_setup_error(self):
-        raise NotImplementedError()
-
-    def create_volume(self, volume):
-        """Creates a volume. Can optionally return a Dictionary of
-        changes to the volume object to be persisted."""
-        raise NotImplementedError()
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-        raise NotImplementedError()
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        raise NotImplementedError()
-
-    def delete_volume(self, volume):
-        """Deletes a volume."""
-        raise NotImplementedError()
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        raise NotImplementedError()
-
-    def delete_snapshot(self, snapshot):
-        """Deletes a snapshot."""
-        raise NotImplementedError()
-
-    def local_path(self, volume):
-        raise NotImplementedError()
-
-    def ensure_export(self, context, volume):
-        """Synchronously recreates an export for a volume."""
-        raise NotImplementedError()
-
-    def create_export(self, context, volume):
-        """Exports the volume. Can optionally return a Dictionary of changes
-        to the volume object to be persisted."""
-        raise NotImplementedError()
-
-    def remove_export(self, context, volume):
-        """Removes an export for a volume."""
-        raise NotImplementedError()
-
-    def initialize_connection(self, volume, connector):
-        """Allow connection to connector and return connection info."""
-        raise NotImplementedError()
-
-    def terminate_connection(self, volume, connector, force=False, **kwargs):
-        """Disallow connection from connector"""
-        raise NotImplementedError()
-
-    def attach_volume(self, context, volume_id, instance_uuid, mountpoint):
-        """ Callback for volume attached to instance."""
-        pass
-
-    def detach_volume(self, context, volume_id):
-        """ Callback for volume detached."""
-        pass
-
-    def get_volume_stats(self, refresh=False):
-        """Return the current state of the volume service. If 'refresh' is
-           True, run the update first."""
-        return None
-
-    def do_setup(self, context):
-        """Any initialization the volume driver does while starting"""
-        pass
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        raise NotImplementedError()
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        raise NotImplementedError()
-
-    def clone_image(self, volume, image_location):
-        """Create a volume efficiently from an existing image.
-
-        image_location is a string whose format depends on the
-        image service backend in use. The driver should use it
-        to determine whether cloning is possible.
-
-        Returns a boolean indicating whether cloning occurred
-        """
-        return False
-
-    def backup_volume(self, context, backup, backup_service):
-        """Create a new backup from an existing volume."""
-        raise NotImplementedError()
-
-    def restore_backup(self, context, backup, volume, backup_service):
-        """Restore an existing backup to a new or existing volume."""
-        raise NotImplementedError()
-
-    def clear_download(self, context, volume):
-        """Clean up after an interrupted image copy."""
-        pass
-
-
-class ISCSIDriver(VolumeDriver):
-    """Executes commands relating to ISCSI volumes.
-
-    We make use of model provider properties as follows:
-
-    ``provider_location``
-      if present, contains the iSCSI target information in the same
-      format as an ietadm discovery
-      i.e. '<ip>:<port>,<portal> <target IQN>'
-
-    ``provider_auth``
-      if present, contains a space-separated triple:
-      '<auth method> <auth username> <auth password>'.
-      `CHAP` is the only auth_method in use at the moment.
-    """
-
-    def __init__(self, *args, **kwargs):
-        super(ISCSIDriver, self).__init__(*args, **kwargs)
-
-    def _do_iscsi_discovery(self, volume):
-        #TODO(justinsb): Deprecate discovery and use stored info
-        #NOTE(justinsb): Discovery won't work with CHAP-secured targets (?)
-        LOG.warn(_("ISCSI provider_location not stored, using discovery"))
-
-        volume_name = volume['name']
-
-        (out, _err) = self._execute('iscsiadm', '-m', 'discovery',
-                                    '-t', 'sendtargets', '-p', volume['host'],
-                                    run_as_root=True)
-        for target in out.splitlines():
-            if (self.configuration.iscsi_ip_address in target
-                and volume_name in target):
-                return target
-        return None
-
-    def _get_iscsi_properties(self, volume):
-        """Gets iscsi configuration
-
-        We ideally get saved information in the volume entity, but fall back
-        to discovery if need be. Discovery may be completely removed in future
-        The properties are:
-
-        :target_discovered:    boolean indicating whether discovery was used
-
-        :target_iqn:    the IQN of the iSCSI target
-
-        :target_portal:    the portal of the iSCSI target
-
-        :target_lun:    the lun of the iSCSI target
-
-        :volume_id:    the id of the volume (currently used by xen)
-
-        :auth_method:, :auth_username:, :auth_password:
-
-            the authentication details. Right now, either auth_method is not
-            present meaning no authentication, or auth_method == `CHAP`
-            meaning use CHAP with the specified credentials.
-        """
-
-        properties = {}
-
-        location = volume['provider_location']
-
-        if location:
-            # provider_location is the same format as iSCSI discovery output
-            properties['target_discovered'] = False
-        else:
-            location = self._do_iscsi_discovery(volume)
-
-            if not location:
-                msg = (_("Could not find iSCSI export for volume %s") %
-                        (volume['name']))
-                raise exception.InvalidVolume(reason=msg)
-
-            LOG.debug(_("ISCSI Discovery: Found %s") % (location))
-            properties['target_discovered'] = True
-
-        results = location.split(" ")
-        properties['target_portal'] = results[0].split(",")[0]
-        properties['target_iqn'] = results[1]
-        try:
-            properties['target_lun'] = int(results[2])
-        except (IndexError, ValueError):
-            if (self.configuration.volume_driver in
-                    ['manila.volume.drivers.lvm.LVMISCSIDriver',
-                     'manila.volume.drivers.lvm.ThinLVMVolumeDriver'] and
-                    self.configuration.iscsi_helper == 'tgtadm'):
-                properties['target_lun'] = 1
-            else:
-                properties['target_lun'] = 0
-
-        properties['volume_id'] = volume['id']
-
-        auth = volume['provider_auth']
-        if auth:
-            (auth_method, auth_username, auth_secret) = auth.split()
-
-            properties['auth_method'] = auth_method
-            properties['auth_username'] = auth_username
-            properties['auth_password'] = auth_secret
-
-        return properties
-
-    def _run_iscsiadm(self, iscsi_properties, iscsi_command, **kwargs):
-        check_exit_code = kwargs.pop('check_exit_code', 0)
-        (out, err) = self._execute('iscsiadm', '-m', 'node', '-T',
-                                   iscsi_properties['target_iqn'],
-                                   '-p', iscsi_properties['target_portal'],
-                                   *iscsi_command, run_as_root=True,
-                                   check_exit_code=check_exit_code)
-        LOG.debug("iscsiadm %s: stdout=%s stderr=%s" %
-                  (iscsi_command, out, err))
-        return (out, err)
-
-    def _iscsiadm_update(self, iscsi_properties, property_key, property_value,
-                         **kwargs):
-        iscsi_command = ('--op', 'update', '-n', property_key,
-                         '-v', property_value)
-        return self._run_iscsiadm(iscsi_properties, iscsi_command, **kwargs)
-
-    def initialize_connection(self, volume, connector):
-        """Initializes the connection and returns connection info.
-
-        The iscsi driver returns a driver_volume_type of 'iscsi'.
-        The format of the driver data is defined in _get_iscsi_properties.
-        Example return value::
-
-            {
-                'driver_volume_type': 'iscsi'
-                'data': {
-                    'target_discovered': True,
-                    'target_iqn': 'iqn.2010-10.org.openstack:volume-00000001',
-                    'target_portal': '127.0.0.0.1:3260',
-                    'volume_id': 1,
-                }
-            }
-
-        """
-
-        if CONF.iscsi_helper == 'lioadm':
-            self.tgtadm.initialize_connection(volume, connector)
-
-        iscsi_properties = self._get_iscsi_properties(volume)
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': iscsi_properties
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        pass
-
-    def _get_iscsi_initiator(self):
-        """Get iscsi initiator name for this machine"""
-        # NOTE openiscsi stores initiator name in a file that
-        #      needs root permission to read.
-        contents = utils.read_file_as_root('/etc/iscsi/initiatorname.iscsi')
-        for l in contents.split('\n'):
-            if l.startswith('InitiatorName='):
-                return l[l.index('=') + 1:].strip()
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        LOG.debug(_('copy_image_to_volume %s.') % volume['name'])
-        connector = {'initiator': self._get_iscsi_initiator(),
-                     'host': socket.gethostname()}
-
-        iscsi_properties, volume_path = self._attach_volume(
-            context, volume, connector)
-
-        try:
-            image_utils.fetch_to_raw(context,
-                                     image_service,
-                                     image_id,
-                                     volume_path)
-        finally:
-            self.terminate_connection(volume, connector)
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        LOG.debug(_('copy_volume_to_image %s.') % volume['name'])
-        connector = {'initiator': self._get_iscsi_initiator(),
-                     'host': socket.gethostname()}
-
-        iscsi_properties, volume_path = self._attach_volume(
-            context, volume, connector)
-
-        try:
-            image_utils.upload_volume(context,
-                                      image_service,
-                                      image_meta,
-                                      volume_path)
-        finally:
-            self.terminate_connection(volume, connector)
-
-    def _attach_volume(self, context, volume, connector):
-        """Attach the volume."""
-        iscsi_properties = None
-        host_device = None
-        init_conn = self.initialize_connection(volume, connector)
-        iscsi_properties = init_conn['data']
-
-        # code "inspired by" nova/virt/libvirt/volume.py
-        try:
-            self._run_iscsiadm(iscsi_properties, ())
-        except exception.ProcessExecutionError as exc:
-            # iscsiadm returns 21 for "No records found" after version 2.0-871
-            if exc.exit_code in [21, 255]:
-                self._run_iscsiadm(iscsi_properties, ('--op', 'new'))
-            else:
-                raise
-
-        if iscsi_properties.get('auth_method'):
-            self._iscsiadm_update(iscsi_properties,
-                                  "node.session.auth.authmethod",
-                                  iscsi_properties['auth_method'])
-            self._iscsiadm_update(iscsi_properties,
-                                  "node.session.auth.username",
-                                  iscsi_properties['auth_username'])
-            self._iscsiadm_update(iscsi_properties,
-                                  "node.session.auth.password",
-                                  iscsi_properties['auth_password'])
-
-        # NOTE(vish): If we have another lun on the same target, we may
-        #             have a duplicate login
-        self._run_iscsiadm(iscsi_properties, ("--login",),
-                           check_exit_code=[0, 255])
-
-        self._iscsiadm_update(iscsi_properties, "node.startup", "automatic")
-
-        host_device = ("/dev/disk/by-path/ip-%s-iscsi-%s-lun-%s" %
-                       (iscsi_properties['target_portal'],
-                        iscsi_properties['target_iqn'],
-                        iscsi_properties.get('target_lun', 0)))
-
-        tries = 0
-        while not os.path.exists(host_device):
-            if tries >= self.configuration.num_iscsi_scan_tries:
-                raise exception.CinderException(
-                    _("iSCSI device not found at %s") % (host_device))
-
-            LOG.warn(_("ISCSI volume not yet found at: %(host_device)s. "
-                     "Will rescan & retry.  Try number: %(tries)s") %
-                     locals())
-
-            # The rescan isn't documented as being necessary(?), but it helps
-            self._run_iscsiadm(iscsi_properties, ("--rescan",))
-
-            tries = tries + 1
-            if not os.path.exists(host_device):
-                time.sleep(tries ** 2)
-
-        if tries != 0:
-            LOG.debug(_("Found iSCSI node %(host_device)s "
-                      "(after %(tries)s rescans)") %
-                      locals())
-
-        return iscsi_properties, host_device
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'Generic_iSCSI'
-        data["vendor_name"] = 'Open Source'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'iSCSI'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
-
-
-class FakeISCSIDriver(ISCSIDriver):
-    """Logs calls instead of executing."""
-    def __init__(self, *args, **kwargs):
-        super(FakeISCSIDriver, self).__init__(execute=self.fake_execute,
-                                              *args, **kwargs)
-
-    def check_for_setup_error(self):
-        """No setup necessary in fake mode."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': {}
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        pass
-
-    @staticmethod
-    def fake_execute(cmd, *_args, **_kwargs):
-        """Execute that simply logs the command."""
-        LOG.debug(_("FAKE ISCSI: %s"), cmd)
-        return (None, None)
-
-
-class FibreChannelDriver(VolumeDriver):
-    """Executes commands relating to Fibre Channel volumes."""
-    def __init__(self, *args, **kwargs):
-        super(FibreChannelDriver, self).__init__(*args, **kwargs)
-
-    def initialize_connection(self, volume, connector):
-        """Initializes the connection and returns connection info.
-
-        The  driver returns a driver_volume_type of 'fibre_channel'.
-        The target_wwn can be a single entry or a list of wwns that
-        correspond to the list of remote wwn(s) that will export the volume.
-        Example return values:
-
-            {
-                'driver_volume_type': 'fibre_channel'
-                'data': {
-                    'target_discovered': True,
-                    'target_lun': 1,
-                    'target_wwn': '1234567890123',
-                }
-            }
-
-            or
-
-             {
-                'driver_volume_type': 'fibre_channel'
-                'data': {
-                    'target_discovered': True,
-                    'target_lun': 1,
-                    'target_wwn': ['1234567890123', '0987654321321'],
-                }
-            }
-
-        """
-        msg = _("Driver must implement initialize_connection")
-        raise NotImplementedError(msg)
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        raise NotImplementedError()
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        raise NotImplementedError()
diff --git a/manila/volume/drivers/__init__.py b/manila/volume/drivers/__init__.py
deleted file mode 100644
index 387a1b9a9d..0000000000
--- a/manila/volume/drivers/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-:mod:`manila.volume.driver` -- Cinder Drivers
-=====================================================
-
-.. automodule:: manila.volume.driver
-   :platform: Unix
-   :synopsis: Module containing all the Cinder drivers.
-"""
diff --git a/manila/volume/drivers/coraid.py b/manila/volume/drivers/coraid.py
deleted file mode 100644
index c9f3bfd304..0000000000
--- a/manila/volume/drivers/coraid.py
+++ /dev/null
@@ -1,424 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2012 Alyseo.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Desc    : Driver to store volumes on Coraid Appliances.
-Require : Coraid EtherCloud ESM, Coraid VSX and Coraid SRX.
-Author  : Jean-Baptiste RANSY <openstack@alyseo.com>
-Contrib : Larry Matter <support@coraid.com>
-"""
-
-import cookielib
-import os
-import time
-import urllib2
-
-from oslo.config import cfg
-
-from manila import context
-from manila import exception
-from manila import flags
-from manila.openstack.common import jsonutils
-from manila.openstack.common import log as logging
-from manila.volume import driver
-from manila.volume import volume_types
-
-LOG = logging.getLogger(__name__)
-
-FLAGS = flags.FLAGS
-coraid_opts = [
-    cfg.StrOpt('coraid_esm_address',
-               default='',
-               help='IP address of Coraid ESM'),
-    cfg.StrOpt('coraid_user',
-               default='admin',
-               help='User name to connect to Coraid ESM'),
-    cfg.StrOpt('coraid_group',
-               default='admin',
-               help='Name of group on Coraid ESM to which coraid_user belongs'
-               ' (must have admin privilege)'),
-    cfg.StrOpt('coraid_password',
-               default='password',
-               help='Password to connect to Coraid ESM'),
-    cfg.StrOpt('coraid_repository_key',
-               default='coraid_repository',
-               help='Volume Type key name to store ESM Repository Name'),
-]
-FLAGS.register_opts(coraid_opts)
-
-
-class CoraidException(Exception):
-    def __init__(self, message=None, error=None):
-        super(CoraidException, self).__init__(message, error)
-
-    def __str__(self):
-        return '%s: %s' % self.args
-
-
-class CoraidRESTException(CoraidException):
-    pass
-
-
-class CoraidESMException(CoraidException):
-    pass
-
-
-class CoraidRESTClient(object):
-    """Executes volume driver commands on Coraid ESM EtherCloud Appliance."""
-
-    def __init__(self, ipaddress, user, group, password):
-        self.url = "https://%s:8443/" % ipaddress
-        self.user = user
-        self.group = group
-        self.password = password
-        self.session = False
-        self.cookiejar = cookielib.CookieJar()
-        self.urlOpener = urllib2.build_opener(
-            urllib2.HTTPCookieProcessor(self.cookiejar))
-        LOG.debug(_('Running with CoraidDriver for ESM EtherCLoud'))
-
-    def _login(self):
-        """Login and Session Handler."""
-        if not self.session or self.session < time.time():
-            url = ('admin?op=login&username=%s&password=%s' %
-                   (self.user, self.password))
-            data = 'Login'
-            reply = self._admin_esm_cmd(url, data)
-            if reply.get('state') == 'adminSucceed':
-                self.session = time.time() + 1100
-                msg = _('Update session cookie %(session)s')
-                LOG.debug(msg % dict(session=self.session))
-                self._set_group(reply)
-                return True
-            else:
-                errmsg = reply.get('message', '')
-                msg = _('Message : %(message)s')
-                raise CoraidESMException(msg % dict(message=errmsg))
-        return True
-
-    def _set_group(self, reply):
-        """Set effective group."""
-        if self.group:
-            group = self.group
-            groupId = self._get_group_id(group, reply)
-            if groupId:
-                url = ('admin?op=setRbacGroup&groupId=%s' % (groupId))
-                data = 'Group'
-                reply = self._admin_esm_cmd(url, data)
-                if reply.get('state') == 'adminSucceed':
-                    return True
-                else:
-                    errmsg = reply.get('message', '')
-                    msg = _('Error while trying to set group: %(message)s')
-                    raise CoraidRESTException(msg % dict(message=errmsg))
-            else:
-                msg = _('Unable to find group: %(group)s')
-                raise CoraidESMException(msg % dict(group=group))
-        return True
-
-    def _get_group_id(self, groupName, loginResult):
-        """Map group name to group ID."""
-        # NOTE(lmatter): All other groups are under the admin group
-        fullName = "admin group:%s" % groupName
-        groupId = False
-        for kid in loginResult['values']:
-            fullPath = kid['fullPath']
-            if fullPath == fullName:
-                return kid['groupId']
-        return False
-
-    def _esm_cmd(self, url=False, data=None):
-        self._login()
-        return self._admin_esm_cmd(url, data)
-
-    def _admin_esm_cmd(self, url=False, data=None):
-        """
-        _admin_esm_cmd represent the entry point to send requests to ESM
-        Appliance.  Send the HTTPS call, get response in JSON
-        convert response into Python Object and return it.
-        """
-        if url:
-            url = self.url + url
-
-            req = urllib2.Request(url, data)
-
-            try:
-                res = self.urlOpener.open(req).read()
-            except Exception:
-                raise CoraidRESTException(_('ESM urlOpen error'))
-
-            try:
-                res_json = jsonutils.loads(res)
-            except Exception:
-                raise CoraidRESTException(_('JSON Error'))
-
-            return res_json
-        else:
-            raise CoraidRESTException(_('Request without URL'))
-
-    def _configure(self, data):
-        """In charge of all commands into 'configure'."""
-        url = 'configure'
-        LOG.debug(_('Configure data : %s'), data)
-        response = self._esm_cmd(url, data)
-        LOG.debug(_("Configure response : %s"), response)
-        if response:
-            if response.get('configState') == 'completedSuccessfully':
-                return True
-            else:
-                errmsg = response.get('message', '')
-                msg = _('Message : %(message)s')
-                raise CoraidESMException(msg % dict(message=errmsg))
-        return False
-
-    def _get_volume_info(self, volume_name):
-        """Retrive volume informations for a given volume name."""
-        url = 'fetch?shelf=cms&orchStrRepo&lv=%s' % (volume_name)
-        try:
-            response = self._esm_cmd(url)
-            info = response[0][1]['reply'][0]
-            return {"pool": info['lv']['containingPool'],
-                    "repo": info['repoName'],
-                    "vsxidx": info['lv']['lunIndex'],
-                    "index": info['lv']['lvStatus']['exportedLun']['lun'],
-                    "shelf": info['lv']['lvStatus']['exportedLun']['shelf']}
-        except Exception:
-            msg = _('Unable to retrive volume infos for volume %(volname)s')
-            raise CoraidESMException(msg % dict(volname=volume_name))
-
-    def _get_lun_address(self, volume_name):
-        """Return AoE Address for a given Volume."""
-        volume_info = self._get_volume_info(volume_name)
-        shelf = volume_info['shelf']
-        lun = volume_info['index']
-        return {'shelf': shelf, 'lun': lun}
-
-    def create_lun(self, volume_name, volume_size, repository):
-        """Create LUN on Coraid Backend Storage."""
-        data = '[{"addr":"cms","data":"{' \
-               '\\"servers\\":[\\"\\"],' \
-               '\\"repoName\\":\\"%s\\",' \
-               '\\"size\\":\\"%sG\\",' \
-               '\\"lvName\\":\\"%s\\"}",' \
-               '"op":"orchStrLun",' \
-               '"args":"add"}]' % (repository, volume_size,
-                                   volume_name)
-        return self._configure(data)
-
-    def delete_lun(self, volume_name):
-        """Delete LUN."""
-        volume_info = self._get_volume_info(volume_name)
-        repository = volume_info['repo']
-        data = '[{"addr":"cms","data":"{' \
-               '\\"repoName\\":\\"%s\\",' \
-               '\\"lvName\\":\\"%s\\"}",' \
-               '"op":"orchStrLun/verified",' \
-               '"args":"delete"}]' % (repository, volume_name)
-        return self._configure(data)
-
-    def create_snapshot(self, volume_name, snapshot_name):
-        """Create Snapshot."""
-        volume_info = self._get_volume_info(volume_name)
-        repository = volume_info['repo']
-        data = '[{"addr":"cms","data":"{' \
-               '\\"repoName\\":\\"%s\\",' \
-               '\\"lvName\\":\\"%s\\",' \
-               '\\"newLvName\\":\\"%s\\"}",' \
-               '"op":"orchStrLunMods",' \
-               '"args":"addClSnap"}]' % (repository, volume_name,
-                                         snapshot_name)
-        return self._configure(data)
-
-    def delete_snapshot(self, snapshot_name):
-        """Delete Snapshot."""
-        snapshot_info = self._get_volume_info(snapshot_name)
-        repository = snapshot_info['repo']
-        data = '[{"addr":"cms","data":"{' \
-               '\\"repoName\\":\\"%s\\",' \
-               '\\"lvName\\":\\"%s\\"}",' \
-               '"op":"orchStrLunMods",' \
-               '"args":"delClSnap"}]' % (repository, snapshot_name)
-        return self._configure(data)
-
-    def create_volume_from_snapshot(self, snapshot_name,
-                                    volume_name, repository):
-        """Create a LUN from a Snapshot."""
-        snapshot_info = self._get_volume_info(snapshot_name)
-        snapshot_repo = snapshot_info['repo']
-        data = '[{"addr":"cms","data":"{' \
-               '\\"lvName\\":\\"%s\\",' \
-               '\\"repoName\\":\\"%s\\",' \
-               '\\"newLvName\\":\\"%s\\",' \
-               '\\"newRepoName\\":\\"%s\\"}",' \
-               '"op":"orchStrLunMods",' \
-               '"args":"addClone"}]' % (snapshot_name, snapshot_repo,
-                                        volume_name, repository)
-        return self._configure(data)
-
-
-class CoraidDriver(driver.VolumeDriver):
-    """This is the Class to set in manila.conf (volume_driver)."""
-
-    def __init__(self, *args, **kwargs):
-        super(CoraidDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(coraid_opts)
-
-    def do_setup(self, context):
-        """Initialize the volume driver."""
-        self.esm = CoraidRESTClient(self.configuration.coraid_esm_address,
-                                    self.configuration.coraid_user,
-                                    self.configuration.coraid_group,
-                                    self.configuration.coraid_password)
-
-    def check_for_setup_error(self):
-        """Return an error if prerequisites aren't met."""
-        if not self.esm._login():
-            raise LookupError(_("Cannot login on Coraid ESM"))
-
-    def _get_repository(self, volume_type):
-        """
-        Return the ESM Repository from the Volume Type.
-        The ESM Repository is stored into a volume_type_extra_specs key.
-        """
-        volume_type_id = volume_type['id']
-        repository_key_name = self.configuration.coraid_repository_key
-        repository = volume_types.get_volume_type_extra_specs(
-            volume_type_id, repository_key_name)
-        return repository
-
-    def create_volume(self, volume):
-        """Create a Volume."""
-        try:
-            repository = self._get_repository(volume['volume_type'])
-            self.esm.create_lun(volume['name'], volume['size'], repository)
-        except Exception:
-            msg = _('Fail to create volume %(volname)s')
-            LOG.debug(msg % dict(volname=volume['name']))
-            raise
-        # NOTE(jbr_): The manager currently interprets any return as
-        # being the model_update for provider location.
-        # return None to not break it (thank to jgriffith and DuncanT)
-        return
-
-    def delete_volume(self, volume):
-        """Delete a Volume."""
-        try:
-            self.esm.delete_lun(volume['name'])
-        except Exception:
-            msg = _('Failed to delete volume %(volname)s')
-            LOG.debug(msg % dict(volname=volume['name']))
-            raise
-        return
-
-    def create_snapshot(self, snapshot):
-        """Create a Snapshot."""
-        try:
-            volume_name = (FLAGS.volume_name_template
-                           % snapshot['volume_id'])
-            snapshot_name = (FLAGS.snapshot_name_template
-                             % snapshot['id'])
-            self.esm.create_snapshot(volume_name, snapshot_name)
-        except Exception, e:
-            msg = _('Failed to Create Snapshot %(snapname)s')
-            LOG.debug(msg % dict(snapname=snapshot_name))
-            raise
-        return
-
-    def delete_snapshot(self, snapshot):
-        """Delete a Snapshot."""
-        try:
-            snapshot_name = (FLAGS.snapshot_name_template
-                             % snapshot['id'])
-            self.esm.delete_snapshot(snapshot_name)
-        except Exception:
-            msg = _('Failed to Delete Snapshot %(snapname)s')
-            LOG.debug(msg % dict(snapname=snapshot_name))
-            raise
-        return
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Create a Volume from a Snapshot."""
-        try:
-            snapshot_name = (FLAGS.snapshot_name_template
-                             % snapshot['id'])
-            repository = self._get_repository(volume['volume_type'])
-            self.esm.create_volume_from_snapshot(snapshot_name,
-                                                 volume['name'],
-                                                 repository)
-        except Exception:
-            msg = _('Failed to Create Volume from Snapshot %(snapname)s')
-            LOG.debug(msg % dict(snapname=snapshot_name))
-            raise
-        return
-
-    def initialize_connection(self, volume, connector):
-        """Return connection information."""
-        try:
-            infos = self.esm._get_lun_address(volume['name'])
-            shelf = infos['shelf']
-            lun = infos['lun']
-
-            aoe_properties = {
-                'target_shelf': shelf,
-                'target_lun': lun,
-            }
-            return {
-                'driver_volume_type': 'aoe',
-                'data': aoe_properties,
-            }
-        except Exception:
-            msg = _('Failed to Initialize Connection. '
-                    'Volume Name: %(volname)s '
-                    'Shelf: %(shelf)s, '
-                    'Lun: %(lun)s')
-            LOG.debug(msg % dict(volname=volume['name'],
-                                 shelf=shelf,
-                                 lun=lun))
-            raise
-        return
-
-    def get_volume_stats(self, refresh=False):
-        """Return Volume Stats."""
-        data = {'driver_version': '1.0',
-                'free_capacity_gb': 'unknown',
-                'reserved_percentage': 0,
-                'storage_protocol': 'aoe',
-                'total_capacity_gb': 'unknown',
-                'vendor_name': 'Coraid'}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data['volume_backend_name'] = backend_name or 'EtherCloud ESM'
-        return data
-
-    def local_path(self, volume):
-        pass
-
-    def create_export(self, context, volume):
-        pass
-
-    def remove_export(self, context, volume):
-        pass
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        pass
-
-    def ensure_export(self, context, volume):
-        pass
-
-    def attach_volume(self, context, volume, instance_uuid, mountpoint):
-        pass
-
-    def detach_volume(self, context, volume):
-        pass
diff --git a/manila/volume/drivers/emc/__init__.py b/manila/volume/drivers/emc/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/manila/volume/drivers/emc/cinder_emc_config.xml.sample b/manila/volume/drivers/emc/cinder_emc_config.xml.sample
deleted file mode 100644
index d67ff37df6..0000000000
--- a/manila/volume/drivers/emc/cinder_emc_config.xml.sample
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<EMC>
-<!--StorageType is a thin pool name-->
-<StorageType>gold</StorageType>
-<!--MaskingView is needed only for VMAX/VMAXe-->
-<MaskingView>openstack</MaskingView>
-<!--Credentials of ECOM packaged with SMI-S-->
-<EcomServerIp>x.x.x.x</EcomServerIp>
-<EcomServerPort>xxxx</EcomServerPort>
-<EcomUserName>xxxxxxxx</EcomUserName>
-<EcomPassword>xxxxxxxx</EcomPassword>
-</EMC>
diff --git a/manila/volume/drivers/emc/emc_smis_common.py b/manila/volume/drivers/emc/emc_smis_common.py
deleted file mode 100644
index 7ccdfee3d1..0000000000
--- a/manila/volume/drivers/emc/emc_smis_common.py
+++ /dev/null
@@ -1,1564 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 EMC Corporation.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Common class for SMI-S based EMC volume drivers.
-
-This common class is for EMC volume drivers based on SMI-S.
-It supports VNX and VMAX arrays.
-
-"""
-
-import time
-
-from oslo.config import cfg
-from xml.dom.minidom import parseString
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-
-LOG = logging.getLogger(__name__)
-
-FLAGS = flags.FLAGS
-
-try:
-    import pywbem
-except ImportError:
-    LOG.info(_('Module PyWBEM not installed.  '
-               'Install PyWBEM using the python-pywbem package.'))
-
-CINDER_EMC_CONFIG_FILE = '/etc/manila/cinder_emc_config.xml'
-
-
-class EMCSMISCommon():
-    """Common code that can be used by ISCSI and FC drivers."""
-
-    stats = {'driver_version': '1.0',
-             'free_capacity_gb': 0,
-             'reserved_percentage': 0,
-             'storage_protocol': None,
-             'total_capacity_gb': 0,
-             'vendor_name': 'EMC',
-             'volume_backend_name': None}
-
-    def __init__(self, prtcl, configuration=None):
-
-        opt = cfg.StrOpt('cinder_emc_config_file',
-                         default=CINDER_EMC_CONFIG_FILE,
-                         help='use this file for manila emc plugin '
-                         'config data')
-        FLAGS.register_opt(opt)
-        self.protocol = prtcl
-        self.configuration = configuration
-        self.configuration.append_config_values([opt])
-
-        ip, port = self._get_ecom_server()
-        self.user, self.passwd = self._get_ecom_cred()
-        self.url = 'http://' + ip + ':' + port
-        self.conn = self._get_ecom_connection()
-
-    def create_volume(self, volume):
-        """Creates a EMC(VMAX/VNX) volume."""
-
-        LOG.debug(_('Entering create_volume.'))
-        volumesize = int(volume['size']) * 1073741824
-        volumename = volume['name']
-
-        LOG.info(_('Create Volume: %(volume)s  Size: %(size)lu')
-                 % {'volume': volumename,
-                    'size': volumesize})
-
-        self.conn = self._get_ecom_connection()
-
-        storage_type = self._get_storage_type()
-
-        LOG.debug(_('Create Volume: %(volume)s  '
-                  'Storage type: %(storage_type)s')
-                  % {'volume': volumename,
-                     'storage_type': storage_type})
-
-        pool, storage_system = self._find_pool(storage_type)
-
-        LOG.debug(_('Create Volume: %(volume)s  Pool: %(pool)s  '
-                  'Storage System: %(storage_system)s')
-                  % {'volume': volumename,
-                     'pool': str(pool),
-                     'storage_system': storage_system})
-
-        configservice = self._find_storage_configuration_service(
-                            storage_system)
-        if configservice is None:
-            exception_message = (_("Error Create Volume: %(volumename)s. "
-                                 "Storage Configuration Service not found for "
-                                 "pool %(storage_type)s.")
-                                 % {'volumename': volumename,
-                                    'storage_type': storage_type})
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        LOG.debug(_('Create Volume: %(name)s  Method: '
-                  'CreateOrModifyElementFromStoragePool  ConfigServicie: '
-                  '%(service)s  ElementName: %(name)s  InPool: %(pool)s  '
-                  'ElementType: 5  Size: %(size)lu')
-                  % {'service': str(configservice),
-                     'name': volumename,
-                     'pool': str(pool),
-                     'size': volumesize})
-
-        rc, job = self.conn.InvokeMethod(
-                    'CreateOrModifyElementFromStoragePool',
-                    configservice, ElementName=volumename, InPool=pool,
-                    ElementType=self._getnum(5, '16'),
-                    Size=self._getnum(volumesize, '64'))
-
-        LOG.debug(_('Create Volume: %(volumename)s  Return code: %(rc)lu')
-                  % {'volumename': volumename,
-                     'rc': rc})
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                LOG.error(_('Error Create Volume: %(volumename)s.  '
-                          'Return code: %(rc)lu.  Error: %(error)s')
-                          % {'volumename': volumename,
-                             'rc': rc,
-                             'error': errordesc})
-                raise exception.VolumeBackendAPIException(data=errordesc)
-
-        LOG.debug(_('Leaving create_volume: %(volumename)s  '
-                  'Return code: %(rc)lu')
-                  % {'volumename': volumename,
-                     'rc': rc})
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-
-        LOG.debug(_('Entering create_volume_from_snapshot.'))
-
-        snapshotname = snapshot['name']
-        volumename = volume['name']
-
-        LOG.info(_('Create Volume from Snapshot: Volume: %(volumename)s  '
-                 'Snapshot: %(snapshotname)s')
-                 % {'volumename': volumename,
-                    'snapshotname': snapshotname})
-
-        self.conn = self._get_ecom_connection()
-
-        snapshot_instance = self._find_lun(snapshot)
-        storage_system = snapshot_instance['SystemName']
-
-        LOG.debug(_('Create Volume from Snapshot: Volume: %(volumename)s  '
-                  'Snapshot: %(snapshotname)s  Snapshot Instance: '
-                  '%(snapshotinstance)s  Storage System: %(storage_system)s.')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'snapshotinstance': str(snapshot_instance.path),
-                     'storage_system': storage_system})
-
-        isVMAX = storage_system.find('SYMMETRIX')
-        if isVMAX > -1:
-            exception_message = (_('Error Create Volume from Snapshot: '
-                                 'Volume: %(volumename)s  Snapshot: '
-                                 '%(snapshotname)s. Create Volume '
-                                 'from Snapshot is NOT supported on VMAX.')
-                                 % {'volumename': volumename,
-                                    'snapshotname': snapshotname})
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        repservice = self._find_replication_service(storage_system)
-        if repservice is None:
-            exception_message = (_('Error Create Volume from Snapshot: '
-                                 'Volume: %(volumename)s  Snapshot: '
-                                 '%(snapshotname)s. Cannot find Replication '
-                                 'Service to create volume from snapshot.')
-                                 % {'volumename': volumename,
-                                    'snapshotname': snapshotname})
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        LOG.debug(_('Create Volume from Snapshot: Volume: %(volumename)s  '
-                  'Snapshot: %(snapshotname)s  Method: CreateElementReplica  '
-                  'ReplicationService: %(service)s  ElementName: '
-                  '%(elementname)s  SyncType: 8  SourceElement: '
-                  '%(sourceelement)s')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'service': str(repservice),
-                     'elementname': volumename,
-                     'sourceelement': str(snapshot_instance.path)})
-
-        # Create a Clone from snapshot
-        rc, job = self.conn.InvokeMethod(
-                    'CreateElementReplica', repservice,
-                    ElementName=volumename,
-                    SyncType=self._getnum(8, '16'),
-                    SourceElement=snapshot_instance.path)
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                exception_message = (_('Error Create Volume from Snapshot: '
-                                     'Volume: %(volumename)s  Snapshot:'
-                                     '%(snapshotname)s.  Return code: %(rc)lu.'
-                                     'Error: %(error)s')
-                                     % {'volumename': volumename,
-                                        'snapshotname': snapshotname,
-                                        'rc': rc,
-                                        'error': errordesc})
-                LOG.error(exception_message)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        LOG.debug(_('Create Volume from Snapshot: Volume: %(volumename)s  '
-                  'Snapshot: %(snapshotname)s.  Successfully clone volume '
-                  'from snapshot.  Finding the clone relationship.')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname})
-
-        sync_name, storage_system = self._find_storage_sync_sv_sv(
-            volumename, snapshotname)
-
-        # Remove the Clone relationshop so it can be used as a regular lun
-        # 8 - Detach operation
-        LOG.debug(_('Create Volume from Snapshot: Volume: %(volumename)s  '
-                  'Snapshot: %(snapshotname)s.  Remove the clone '
-                  'relationship. Method: ModifyReplicaSynchronization '
-                  'ReplicationService: %(service)s  Operation: 8  '
-                  'Synchronization: %(sync_name)s')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'service': str(repservice),
-                     'sync_name': str(sync_name)})
-
-        rc, job = self.conn.InvokeMethod(
-                    'ModifyReplicaSynchronization',
-                    repservice,
-                    Operation=self._getnum(8, '16'),
-                    Synchronization=sync_name)
-
-        LOG.debug(_('Create Volume from Snapshot: Volume: %(volumename)s  '
-                  'Snapshot: %(snapshotname)s  Return code: %(rc)lu')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'rc': rc})
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                exception_message = (_('Error Create Volume from Snapshot: '
-                                     'Volume: %(volumename)s  '
-                                     'Snapshot: %(snapshotname)s.  '
-                                     'Return code: %(rc)lu.  Error: %(error)s')
-                                     % {'volumename': volumename,
-                                        'snapshotname': snapshotname,
-                                        'rc': rc,
-                                        'error': errordesc})
-                LOG.error(exception_message)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        LOG.debug(_('Leaving create_volume_from_snapshot: Volume: '
-                  '%(volumename)s Snapshot: %(snapshotname)s  '
-                  'Return code: %(rc)lu.')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'rc': rc})
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        LOG.debug(_('Entering create_cloned_volume.'))
-
-        srcname = src_vref['name']
-        volumename = volume['name']
-
-        LOG.info(_('Create a Clone from Volume: Volume: %(volumename)s  '
-                 'Source Volume: %(srcname)s')
-                 % {'volumename': volumename,
-                    'srcname': srcname})
-
-        self.conn = self._get_ecom_connection()
-
-        src_instance = self._find_lun(src_vref)
-        storage_system = src_instance['SystemName']
-
-        LOG.debug(_('Create Cloned Volume: Volume: %(volumename)s  '
-                  'Source Volume: %(srcname)s  Source Instance: '
-                  '%(src_instance)s  Storage System: %(storage_system)s.')
-                  % {'volumename': volumename,
-                     'srcname': srcname,
-                     'src_instance': str(src_instance.path),
-                     'storage_system': storage_system})
-
-        repservice = self._find_replication_service(storage_system)
-        if repservice is None:
-            exception_message = (_('Error Create Cloned Volume: '
-                                 'Volume: %(volumename)s  Source Volume: '
-                                 '%(srcname)s. Cannot find Replication '
-                                 'Service to create cloned volume.')
-                                 % {'volumename': volumename,
-                                    'srcname': srcname})
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        LOG.debug(_('Create Cloned Volume: Volume: %(volumename)s  '
-                  'Source Volume: %(srcname)s  Method: CreateElementReplica  '
-                  'ReplicationService: %(service)s  ElementName: '
-                  '%(elementname)s  SyncType: 8  SourceElement: '
-                  '%(sourceelement)s')
-                  % {'volumename': volumename,
-                     'srcname': srcname,
-                     'service': str(repservice),
-                     'elementname': volumename,
-                     'sourceelement': str(src_instance.path)})
-
-        # Create a Clone from source volume
-        rc, job = self.conn.InvokeMethod(
-                    'CreateElementReplica', repservice,
-                    ElementName=volumename,
-                    SyncType=self._getnum(8, '16'),
-                    SourceElement=src_instance.path)
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                exception_message = (_('Error Create Cloned Volume: '
-                                     'Volume: %(volumename)s  Source Volume:'
-                                     '%(srcname)s.  Return code: %(rc)lu.'
-                                     'Error: %(error)s')
-                                     % {'volumename': volumename,
-                                        'srcname': srcname,
-                                        'rc': rc,
-                                        'error': errordesc})
-                LOG.error(exception_message)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        LOG.debug(_('Create Cloned Volume: Volume: %(volumename)s  '
-                  'Source Volume: %(srcname)s.  Successfully cloned volume '
-                  'from source volume.  Finding the clone relationship.')
-                  % {'volumename': volumename,
-                     'srcname': srcname})
-
-        sync_name, storage_system = self._find_storage_sync_sv_sv(
-            volumename, srcname)
-
-        # Remove the Clone relationshop so it can be used as a regular lun
-        # 8 - Detach operation
-        LOG.debug(_('Create Cloned Volume: Volume: %(volumename)s  '
-                  'Source Volume: %(srcname)s.  Remove the clone '
-                  'relationship. Method: ModifyReplicaSynchronization '
-                  'ReplicationService: %(service)s  Operation: 8  '
-                  'Synchronization: %(sync_name)s')
-                  % {'volumename': volumename,
-                     'srcname': srcname,
-                     'service': str(repservice),
-                     'sync_name': str(sync_name)})
-
-        rc, job = self.conn.InvokeMethod(
-                    'ModifyReplicaSynchronization',
-                    repservice,
-                    Operation=self._getnum(8, '16'),
-                    Synchronization=sync_name)
-
-        LOG.debug(_('Create Cloned Volume: Volume: %(volumename)s  '
-                  'Source Volume: %(srcname)s  Return code: %(rc)lu')
-                  % {'volumename': volumename,
-                     'srcname': srcname,
-                     'rc': rc})
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                exception_message = (_('Error Create Cloned Volume: '
-                                     'Volume: %(volumename)s  '
-                                     'Source Volume: %(srcname)s.  '
-                                     'Return code: %(rc)lu.  Error: %(error)s')
-                                     % {'volumename': volumename,
-                                        'srcname': srcname,
-                                        'rc': rc,
-                                        'error': errordesc})
-                LOG.error(exception_message)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        LOG.debug(_('Leaving create_cloned_volume: Volume: '
-                  '%(volumename)s Source Volume: %(srcname)s  '
-                  'Return code: %(rc)lu.')
-                  % {'volumename': volumename,
-                     'srcname': srcname,
-                     'rc': rc})
-
-    def delete_volume(self, volume):
-        """Deletes an EMC volume."""
-        LOG.debug(_('Entering delete_volume.'))
-        volumename = volume['name']
-        LOG.info(_('Delete Volume: %(volume)s')
-                 % {'volume': volumename})
-
-        self.conn = self._get_ecom_connection()
-
-        vol_instance = self._find_lun(volume)
-        if vol_instance is None:
-            LOG.error(_('Volume %(name)s not found on the array. '
-                      'No volume to delete.')
-                      % {'name': volumename})
-            return
-
-        storage_system = vol_instance['SystemName']
-
-        configservice = self._find_storage_configuration_service(
-                        storage_system)
-        if configservice is None:
-            exception_message = (_("Error Delete Volume: %(volumename)s. "
-                                 "Storage Configuration Service not found.")
-                                 % {'volumename': volumename})
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        device_id = vol_instance['DeviceID']
-
-        LOG.debug(_('Delete Volume: %(name)s  DeviceID: %(deviceid)s')
-                  % {'name': volumename,
-                     'deviceid': device_id})
-
-        LOG.debug(_('Delete Volume: %(name)s  Method: EMCReturnToStoragePool '
-                  'ConfigServic: %(service)s  TheElement: %(vol_instance)s')
-                  % {'service': str(configservice),
-                     'name': volumename,
-                     'vol_instance': str(vol_instance.path)})
-
-        rc, job = self.conn.InvokeMethod(
-                    'EMCReturnToStoragePool',
-                    configservice, TheElements=[vol_instance.path])
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                exception_message = (_('Error Delete Volume: %(volumename)s.  '
-                                     'Return code: %(rc)lu.  Error: %(error)s')
-                                     % {'volumename': volumename,
-                                        'rc': rc,
-                                        'error': errordesc})
-                LOG.error(exception_message)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        LOG.debug(_('Leaving delete_volume: %(volumename)s  Return code: '
-                  '%(rc)lu')
-                  % {'volumename': volumename,
-                     'rc': rc})
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        LOG.debug(_('Entering create_snapshot.'))
-
-        snapshotname = snapshot['name']
-        volumename = snapshot['volume_name']
-        LOG.info(_('Create snapshot: %(snapshot)s: volume: %(volume)s')
-                 % {'snapshot': snapshotname,
-                    'volume': volumename})
-
-        self.conn = self._get_ecom_connection()
-
-        volume = {}
-        volume['name'] = volumename
-        volume['provider_location'] = None
-        vol_instance = self._find_lun(volume)
-        device_id = vol_instance['DeviceID']
-        storage_system = vol_instance['SystemName']
-        LOG.debug(_('Device ID: %(deviceid)s: Storage System: '
-                  '%(storagesystem)s')
-                  % {'deviceid': device_id,
-                     'storagesystem': storage_system})
-
-        repservice = self._find_replication_service(storage_system)
-        if repservice is None:
-            LOG.error(_("Cannot find Replication Service to create snapshot "
-                      "for volume %s.") % volumename)
-            exception_message = (_("Cannot find Replication Service to "
-                                 "create snapshot for volume %s.")
-                                 % volumename)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        LOG.debug(_("Create Snapshot:  Method: CreateElementReplica: "
-                  "Target: %(snapshot)s  Source: %(volume)s  Replication "
-                  "Service: %(service)s  ElementName: %(elementname)s  Sync "
-                  "Type: 7  SourceElement: %(sourceelement)s.")
-                  % {'snapshot': snapshotname,
-                     'volume': volumename,
-                     'service': str(repservice),
-                     'elementname': snapshotname,
-                     'sourceelement': str(vol_instance.path)})
-
-        rc, job = self.conn.InvokeMethod(
-                    'CreateElementReplica', repservice,
-                    ElementName=snapshotname,
-                    SyncType=self._getnum(7, '16'),
-                    SourceElement=vol_instance.path)
-
-        LOG.debug(_('Create Snapshot: Volume: %(volumename)s  '
-                  'Snapshot: %(snapshotname)s  Return code: %(rc)lu')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'rc': rc})
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                exception_message = (_('Error Create Snapshot: (snapshot)s '
-                                     'Volume: %(volume)s Error: %(errordesc)s')
-                                     % {'snapshot': snapshotname, 'volume':
-                                        volumename, 'errordesc': errordesc})
-                LOG.error(exception_message)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        LOG.debug(_('Leaving create_snapshot: Snapshot: %(snapshot)s '
-                  'Volume: %(volume)s  Return code: %(rc)lu.') %
-                  {'snapshot': snapshotname, 'volume': volumename, 'rc': rc})
-
-    def delete_snapshot(self, snapshot):
-        """Deletes a snapshot."""
-        LOG.debug(_('Entering delete_snapshot.'))
-
-        snapshotname = snapshot['name']
-        volumename = snapshot['volume_name']
-        LOG.info(_('Delete Snapshot: %(snapshot)s: volume: %(volume)s')
-                 % {'snapshot': snapshotname,
-                    'volume': volumename})
-
-        self.conn = self._get_ecom_connection()
-
-        LOG.debug(_('Delete Snapshot: %(snapshot)s: volume: %(volume)s. '
-                  'Finding StorageSychronization_SV_SV.')
-                  % {'snapshot': snapshotname,
-                     'volume': volumename})
-
-        sync_name, storage_system = self._find_storage_sync_sv_sv(
-                                    snapshotname, volumename, False)
-        if sync_name is None:
-            LOG.error(_('Snapshot: %(snapshot)s: volume: %(volume)s '
-                      'not found on the array. No snapshot to delete.')
-                      % {'snapshot': snapshotname,
-                         'volume': volumename})
-            return
-
-        repservice = self._find_replication_service(storage_system)
-        if repservice is None:
-            exception_message = (_("Cannot find Replication Service to "
-                                 "create snapshot for volume %s.")
-                                 % volumename)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        # Delete snapshot - deletes both the target element
-        # and the snap session
-        LOG.debug(_("Delete Snapshot: Target: %(snapshot)s  "
-                  "Source: %(volume)s.  Method: "
-                  "ModifyReplicaSynchronization:  "
-                  "Replication Service: %(service)s  Operation: 19  "
-                  "Synchronization: %(sync_name)s.")
-                  % {'snapshot': snapshotname,
-                     'volume': volumename,
-                     'service': str(repservice),
-                     'sync_name': str(sync_name)})
-
-        rc, job = self.conn.InvokeMethod(
-                    'ModifyReplicaSynchronization',
-                    repservice,
-                    Operation=self._getnum(19, '16'),
-                    Synchronization=sync_name)
-
-        LOG.debug(_('Delete Snapshot: Volume: %(volumename)s  Snapshot: '
-                  '%(snapshotname)s  Return code: %(rc)lu')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'rc': rc})
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                exception_message = (_('Error Delete Snapshot: Volume: '
-                                     '%(volumename)s  Snapshot: '
-                                     '%(snapshotname)s. Return code: %(rc)lu.'
-                                     ' Error: %(error)s')
-                                     % {'volumename': volumename,
-                                        'snapshotname': snapshotname,
-                                        'rc': rc,
-                                        'error': errordesc})
-                LOG.error(exception_message)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        LOG.debug(_('Leaving delete_snapshot: Volume: %(volumename)s  '
-                  'Snapshot: %(snapshotname)s  Return code: %(rc)lu.')
-                  % {'volumename': volumename,
-                     'snapshotname': snapshotname,
-                     'rc': rc})
-
-    def create_export(self, context, volume):
-        """Driver entry point to get the export info for a new volume."""
-        self.conn = self._get_ecom_connection()
-        volumename = volume['name']
-        LOG.info(_('Create export: %(volume)s')
-                 % {'volume': volumename})
-        vol_instance = self._find_lun(volume)
-        device_id = vol_instance['DeviceID']
-
-        LOG.debug(_('create_export: Volume: %(volume)s  Device ID: '
-                  '%(device_id)s')
-                  % {'volume': volumename,
-                     'device_id': device_id})
-
-        return {'provider_location': device_id}
-
-    # Mapping method for VNX
-    def _expose_paths(self, configservice, vol_instance,
-                      connector):
-        """This method maps a volume to a host.
-
-        It adds a volume and initiator to a Storage Group
-        and therefore maps the volume to the host.
-        """
-        volumename = vol_instance['ElementName']
-        lun_name = vol_instance['DeviceID']
-        initiators = self._find_initiator_names(connector)
-        storage_system = vol_instance['SystemName']
-        lunmask_ctrl = self._find_lunmasking_scsi_protocol_controller(
-            storage_system, connector)
-
-        LOG.debug(_('ExposePaths: %(vol)s  ConfigServicie: %(service)s  '
-                  'LUNames: %(lun_name)s  InitiatorPortIDs: %(initiator)s  '
-                  'DeviceAccesses: 2')
-                  % {'vol': str(vol_instance.path),
-                     'service': str(configservice),
-                     'lun_name': lun_name,
-                     'initiator': initiators})
-
-        if lunmask_ctrl is None:
-            rc, controller = self.conn.InvokeMethod(
-                                'ExposePaths',
-                                configservice, LUNames=[lun_name],
-                                InitiatorPortIDs=initiators,
-                                DeviceAccesses=[self._getnum(2, '16')])
-        else:
-            LOG.debug(_('ExposePaths parameter '
-                      'LunMaskingSCSIProtocolController: '
-                      '%(lunmasking)s')
-                      % {'lunmasking': str(lunmask_ctrl)})
-            rc, controller = self.conn.InvokeMethod(
-                                'ExposePaths',
-                                configservice, LUNames=[lun_name],
-                                DeviceAccesses=[self._getnum(2, '16')],
-                                ProtocolControllers=[lunmask_ctrl])
-
-        if rc != 0L:
-            msg = (_('Error mapping volume %s.') % volumename)
-            LOG.error(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        LOG.debug(_('ExposePaths for volume %s completed successfully.')
-                  % volumename)
-
-    # Unmapping method for VNX
-    def _hide_paths(self, configservice, vol_instance,
-                    connector):
-        """This method unmaps a volume from the host.
-
-        Removes a volume from the Storage Group
-        and therefore unmaps the volume from the host.
-        """
-        volumename = vol_instance['ElementName']
-        device_id = vol_instance['DeviceID']
-        lunmask_ctrl = self._find_lunmasking_scsi_protocol_controller_for_vol(
-            vol_instance, connector)
-
-        LOG.debug(_('HidePaths: %(vol)s  ConfigServicie: %(service)s  '
-                  'LUNames: %(device_id)s  LunMaskingSCSIProtocolController: '
-                  '%(lunmasking)s')
-                  % {'vol': str(vol_instance.path),
-                     'service': str(configservice),
-                     'device_id': device_id,
-                     'lunmasking': str(lunmask_ctrl)})
-
-        rc, controller = self.conn.InvokeMethod(
-            'HidePaths', configservice,
-            LUNames=[device_id], ProtocolControllers=[lunmask_ctrl])
-
-        if rc != 0L:
-            msg = (_('Error unmapping volume %s.') % volumename)
-            LOG.error(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        LOG.debug(_('HidePaths for volume %s completed successfully.')
-                  % volumename)
-
-    # Mapping method for VMAX
-    def _add_members(self, configservice, vol_instance):
-        """This method maps a volume to a host.
-
-        Add volume to the Device Masking Group that belongs to
-        a Masking View.
-        """
-        volumename = vol_instance['ElementName']
-        masking_group = self._find_device_masking_group()
-
-        LOG.debug(_('AddMembers: ConfigServicie: %(service)s  MaskingGroup: '
-                  '%(masking_group)s  Members: %(vol)s')
-                  % {'service': str(configservice),
-                     'masking_group': str(masking_group),
-                     'vol': str(vol_instance.path)})
-
-        rc, job = self.conn.InvokeMethod(
-                    'AddMembers', configservice,
-                    MaskingGroup=masking_group, Members=[vol_instance.path])
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                msg = (_('Error mapping volume %(vol)s. %(error)s') %
-                       {'vol': volumename, 'error': errordesc})
-                LOG.error(msg)
-                raise exception.VolumeBackendAPIException(data=msg)
-
-        LOG.debug(_('AddMembers for volume %s completed successfully.')
-                  % volumename)
-
-    # Unmapping method for VMAX
-    def _remove_members(self, configservice, vol_instance):
-        """This method unmaps a volume from a host.
-
-        Removes volume from the Device Masking Group that belongs to
-        a Masking View.
-        """
-        volumename = vol_instance['ElementName']
-        masking_group = self._find_device_masking_group()
-
-        LOG.debug(_('RemoveMembers: ConfigServicie: %(service)s  '
-                  'MaskingGroup: %(masking_group)s  Members: %(vol)s')
-                  % {'service': str(configservice),
-                     'masking_group': str(masking_group),
-                     'vol': str(vol_instance.path)})
-
-        rc, job = self.conn.InvokeMethod('RemoveMembers', configservice,
-                                         MaskingGroup=masking_group,
-                                         Members=[vol_instance.path])
-
-        if rc != 0L:
-            rc, errordesc = self._wait_for_job_complete(job)
-            if rc != 0L:
-                msg = (_('Error unmapping volume %(vol)s. %(error)s')
-                       % {'vol': volumename, 'error': errordesc})
-                LOG.error(msg)
-                raise exception.VolumeBackendAPIException(data=msg)
-
-        LOG.debug(_('RemoveMembers for volume %s completed successfully.')
-                  % volumename)
-
-    def _map_lun(self, volume, connector):
-        """Maps a volume to the host."""
-        volumename = volume['name']
-        LOG.info(_('Map volume: %(volume)s')
-                 % {'volume': volumename})
-
-        vol_instance = self._find_lun(volume)
-        storage_system = vol_instance['SystemName']
-
-        configservice = self._find_controller_configuration_service(
-            storage_system)
-        if configservice is None:
-            exception_message = (_("Cannot find Controller Configuration "
-                                 "Service for storage system %s")
-                                 % storage_system)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        isVMAX = storage_system.find('SYMMETRIX')
-        if isVMAX > -1:
-            self._add_members(configservice, vol_instance)
-        else:
-            self._expose_paths(configservice, vol_instance, connector)
-
-    def _unmap_lun(self, volume, connector):
-        """Unmaps a volume from the host."""
-        volumename = volume['name']
-        LOG.info(_('Unmap volume: %(volume)s')
-                 % {'volume': volumename})
-
-        device_info = self.find_device_number(volume)
-        device_number = device_info['hostlunid']
-        if device_number is None:
-            LOG.info(_("Volume %s is not mapped. No volume to unmap.")
-                     % (volumename))
-            return
-
-        vol_instance = self._find_lun(volume)
-        storage_system = vol_instance['SystemName']
-
-        configservice = self._find_controller_configuration_service(
-            storage_system)
-        if configservice is None:
-            exception_message = (_("Cannot find Controller Configuration "
-                                 "Service for storage system %s")
-                                 % storage_system)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        isVMAX = storage_system.find('SYMMETRIX')
-        if isVMAX > -1:
-            self._remove_members(configservice, vol_instance)
-        else:
-            self._hide_paths(configservice, vol_instance, connector)
-
-    def initialize_connection(self, volume, connector):
-        """Initializes the connection and returns connection info."""
-        volumename = volume['name']
-        LOG.info(_('Initialize connection: %(volume)s')
-                 % {'volume': volumename})
-        self.conn = self._get_ecom_connection()
-        device_info = self.find_device_number(volume)
-        device_number = device_info['hostlunid']
-        if device_number is not None:
-            LOG.info(_("Volume %s is already mapped.")
-                     % (volumename))
-        else:
-            self._map_lun(volume, connector)
-            # Find host lun id again after the volume is exported to the host
-            device_info = self.find_device_number(volume)
-
-        return device_info
-
-    def terminate_connection(self, volume, connector):
-        """Disallow connection from connector."""
-        volumename = volume['name']
-        LOG.info(_('Terminate connection: %(volume)s')
-                 % {'volume': volumename})
-        self.conn = self._get_ecom_connection()
-        self._unmap_lun(volume, connector)
-
-    def update_volume_status(self):
-        """Retrieve status info."""
-        LOG.debug(_("Updating volume status"))
-        self.conn = self._get_ecom_connection()
-        storage_type = self._get_storage_type()
-
-        pool, storagesystem = self._find_pool(storage_type, True)
-
-        self.stats['total_capacity_gb'] = pool['TotalManagedSpace']
-        self.stats['free_capacity_gb'] = pool['RemainingManagedSpace']
-
-        return self.stats
-
-    def _get_storage_type(self, filename=None):
-        """Get the storage type from the config file."""
-        if filename == None:
-            filename = self.configuration.cinder_emc_config_file
-
-        file = open(filename, 'r')
-        data = file.read()
-        file.close()
-        dom = parseString(data)
-        storageTypes = dom.getElementsByTagName('StorageType')
-        if storageTypes is not None and len(storageTypes) > 0:
-            storageType = storageTypes[0].toxml()
-            storageType = storageType.replace('<StorageType>', '')
-            storageType = storageType.replace('</StorageType>', '')
-            LOG.debug(_("Found Storage Type: %s") % (storageType))
-            return storageType
-        else:
-            exception_message = (_("Storage type not found."))
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-    def _get_masking_view(self, filename=None):
-        if filename == None:
-            filename = self.configuration.cinder_emc_config_file
-
-        file = open(filename, 'r')
-        data = file.read()
-        file.close()
-        dom = parseString(data)
-        views = dom.getElementsByTagName('MaskingView')
-        if views is not None and len(views) > 0:
-            view = views[0].toxml().replace('<MaskingView>', '')
-            view = view.replace('</MaskingView>', '')
-            LOG.debug(_("Found Masking View: %s") % (view))
-            return view
-        else:
-            LOG.debug(_("Masking View not found."))
-            return None
-
-    def _get_ecom_cred(self, filename=None):
-        if filename == None:
-            filename = self.configuration.cinder_emc_config_file
-
-        file = open(filename, 'r')
-        data = file.read()
-        file.close()
-        dom = parseString(data)
-        ecomUsers = dom.getElementsByTagName('EcomUserName')
-        if ecomUsers is not None and len(ecomUsers) > 0:
-            ecomUser = ecomUsers[0].toxml().replace('<EcomUserName>', '')
-            ecomUser = ecomUser.replace('</EcomUserName>', '')
-        ecomPasswds = dom.getElementsByTagName('EcomPassword')
-        if ecomPasswds is not None and len(ecomPasswds) > 0:
-            ecomPasswd = ecomPasswds[0].toxml().replace('<EcomPassword>', '')
-            ecomPasswd = ecomPasswd.replace('</EcomPassword>', '')
-        if ecomUser is not None and ecomPasswd is not None:
-            return ecomUser, ecomPasswd
-        else:
-            LOG.debug(_("Ecom user not found."))
-            return None
-
-    def _get_ecom_server(self, filename=None):
-        if filename == None:
-            filename = self.configuration.cinder_emc_config_file
-
-        file = open(filename, 'r')
-        data = file.read()
-        file.close()
-        dom = parseString(data)
-        ecomIps = dom.getElementsByTagName('EcomServerIp')
-        if ecomIps is not None and len(ecomIps) > 0:
-            ecomIp = ecomIps[0].toxml().replace('<EcomServerIp>', '')
-            ecomIp = ecomIp.replace('</EcomServerIp>', '')
-        ecomPorts = dom.getElementsByTagName('EcomServerPort')
-        if ecomPorts is not None and len(ecomPorts) > 0:
-            ecomPort = ecomPorts[0].toxml().replace('<EcomServerPort>', '')
-            ecomPort = ecomPort.replace('</EcomServerPort>', '')
-        if ecomIp is not None and ecomPort is not None:
-            LOG.debug(_("Ecom IP: %(ecomIp)s Port: %(ecomPort)s") % (locals()))
-            return ecomIp, ecomPort
-        else:
-            LOG.debug(_("Ecom server not found."))
-            return None
-
-    def _get_ecom_connection(self, filename=None):
-        conn = pywbem.WBEMConnection(self.url, (self.user, self.passwd),
-                                     default_namespace='root/emc')
-        if conn is None:
-            exception_message = (_("Cannot connect to ECOM server"))
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        return conn
-
-    def _find_replication_service(self, storage_system):
-        foundRepService = None
-        repservices = self.conn.EnumerateInstanceNames(
-            'EMC_ReplicationService')
-        for repservice in repservices:
-            if storage_system == repservice['SystemName']:
-                foundRepService = repservice
-                LOG.debug(_("Found Replication Service: %s")
-                          % (str(repservice)))
-                break
-
-        return foundRepService
-
-    def _find_storage_configuration_service(self, storage_system):
-        foundConfigService = None
-        configservices = self.conn.EnumerateInstanceNames(
-            'EMC_StorageConfigurationService')
-        for configservice in configservices:
-            if storage_system == configservice['SystemName']:
-                foundConfigService = configservice
-                LOG.debug(_("Found Storage Configuration Service: %s")
-                          % (str(configservice)))
-                break
-
-        return foundConfigService
-
-    def _find_controller_configuration_service(self, storage_system):
-        foundConfigService = None
-        configservices = self.conn.EnumerateInstanceNames(
-            'EMC_ControllerConfigurationService')
-        for configservice in configservices:
-            if storage_system == configservice['SystemName']:
-                foundConfigService = configservice
-                LOG.debug(_("Found Controller Configuration Service: %s")
-                          % (str(configservice)))
-                break
-
-        return foundConfigService
-
-    def _find_storage_hardwareid_service(self, storage_system):
-        foundConfigService = None
-        configservices = self.conn.EnumerateInstanceNames(
-            'EMC_StorageHardwareIDManagementService')
-        for configservice in configservices:
-            if storage_system == configservice['SystemName']:
-                foundConfigService = configservice
-                LOG.debug(_("Found Storage Hardware ID Management Service: %s")
-                          % (str(configservice)))
-                break
-
-        return foundConfigService
-
-    # Find pool based on storage_type
-    def _find_pool(self, storage_type, details=False):
-        foundPool = None
-        systemname = None
-        # Only get instance names if details flag is False;
-        # Otherwise get the whole instances
-        if details is False:
-            vpools = self.conn.EnumerateInstanceNames(
-                'EMC_VirtualProvisioningPool')
-            upools = self.conn.EnumerateInstanceNames(
-                'EMC_UnifiedStoragePool')
-        else:
-            vpools = self.conn.EnumerateInstances(
-                'EMC_VirtualProvisioningPool')
-            upools = self.conn.EnumerateInstances(
-                'EMC_UnifiedStoragePool')
-
-        for upool in upools:
-            poolinstance = upool['InstanceID']
-            # Example: CLARiiON+APM00115204878+U+Pool 0
-            poolname, systemname = self._parse_pool_instance_id(poolinstance)
-            if poolname is not None and systemname is not None:
-                if str(storage_type) == str(poolname):
-                    foundPool = upool
-                    break
-
-        if foundPool is None:
-            for vpool in vpools:
-                poolinstance = vpool['InstanceID']
-                # Example: SYMMETRIX+000195900551+TP+Sol_Innov
-                poolname, systemname = self._parse_pool_instance_id(
-                    poolinstance)
-                if poolname is not None and systemname is not None:
-                    if str(storage_type) == str(poolname):
-                        foundPool = vpool
-                        break
-
-        if foundPool is None:
-            exception_message = (_("Pool %(storage_type)s is not found.")
-                                 % {'storage_type': storage_type})
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        if systemname is None:
-            exception_message = (_("Storage system not found for pool "
-                                 "%(storage_type)s.")
-                                 % {'storage_type': storage_type})
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        LOG.debug(_("Pool: %(pool)s  SystemName: %(systemname)s.")
-                  % {'pool': str(foundPool), 'systemname': systemname})
-        return foundPool, systemname
-
-    def _parse_pool_instance_id(self, instanceid):
-        # Example of pool InstanceId: CLARiiON+APM00115204878+U+Pool 0
-        poolname = None
-        systemname = None
-        endp = instanceid.rfind('+')
-        if endp > -1:
-            poolname = instanceid[endp + 1:]
-
-        idarray = instanceid.split('+')
-        if len(idarray) > 2:
-            systemname = idarray[0] + '+' + idarray[1]
-
-        LOG.debug(_("Pool name: %(poolname)s  System name: %(systemname)s.")
-                  % {'poolname': poolname, 'systemname': systemname})
-        return poolname, systemname
-
-    def _find_lun(self, volume):
-        foundinstance = None
-        try:
-            device_id = volume['provider_location']
-        except Exception:
-            device_id = None
-
-        volumename = volume['name']
-
-        names = self.conn.EnumerateInstanceNames('EMC_StorageVolume')
-
-        for n in names:
-            if device_id is not None:
-                if n['DeviceID'] == device_id:
-                    vol_instance = self.conn.GetInstance(n)
-                    foundinstance = vol_instance
-                    break
-                else:
-                    continue
-
-            else:
-                vol_instance = self.conn.GetInstance(n)
-                if vol_instance['ElementName'] == volumename:
-                    foundinstance = vol_instance
-                    volume['provider_location'] = foundinstance['DeviceID']
-                    break
-
-        if foundinstance is None:
-            LOG.debug(_("Volume %(volumename)s not found on the array.")
-                      % {'volumename': volumename})
-        else:
-            LOG.debug(_("Volume name: %(volumename)s  Volume instance: "
-                      "%(vol_instance)s.")
-                      % {'volumename': volumename,
-                         'vol_instance': str(foundinstance.path)})
-
-        return foundinstance
-
-    def _find_storage_sync_sv_sv(self, snapshotname, volumename,
-                                 waitforsync=True):
-        foundsyncname = None
-        storage_system = None
-        percent_synced = 0
-
-        LOG.debug(_("Source: %(volumename)s  Target: %(snapshotname)s.")
-                  % {'volumename': volumename, 'snapshotname': snapshotname})
-
-        names = self.conn.EnumerateInstanceNames(
-            'SE_StorageSynchronized_SV_SV')
-
-        for n in names:
-            snapshot_instance = self.conn.GetInstance(n['SyncedElement'],
-                                                      LocalOnly=False)
-            if snapshotname != snapshot_instance['ElementName']:
-                continue
-
-            vol_instance = self.conn.GetInstance(n['SystemElement'],
-                                                 LocalOnly=False)
-            if vol_instance['ElementName'] == volumename:
-                foundsyncname = n
-                storage_system = vol_instance['SystemName']
-                if waitforsync:
-                    sync_instance = self.conn.GetInstance(n, LocalOnly=False)
-                    percent_synced = sync_instance['PercentSynced']
-                break
-
-        if foundsyncname is None:
-            LOG.debug(_("Source: %(volumename)s  Target: %(snapshotname)s. "
-                      "Storage Synchronized not found. ")
-                      % {'volumename': volumename,
-                         'snapshotname': snapshotname})
-        else:
-            LOG.debug(_("Storage system: %(storage_system)s  "
-                      "Storage Synchronized instance: %(sync)s.")
-                      % {'storage_system': storage_system,
-                         'sync': str(foundsyncname)})
-            # Wait for SE_StorageSynchronized_SV_SV to be fully synced
-            while waitforsync and percent_synced < 100:
-                time.sleep(10)
-                sync_instance = self.conn.GetInstance(foundsyncname,
-                                                      LocalOnly=False)
-                percent_synced = sync_instance['PercentSynced']
-
-        return foundsyncname, storage_system
-
-    def _find_initiator_names(self, connector):
-        foundinitiatornames = []
-        iscsi = 'iscsi'
-        fc = 'fc'
-        name = 'initiator name'
-        if self.protocol.lower() == iscsi and connector['initiator']:
-            foundinitiatornames.append(connector['initiator'])
-        elif self.protocol.lower() == fc and connector['wwpns']:
-            for wwn in connector['wwpns']:
-                foundinitiatornames.append(wwn)
-            name = 'world wide port names'
-
-        if foundinitiatornames is None or len(foundinitiatornames) == 0:
-            msg = (_('Error finding %s.') % name)
-            LOG.error(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        LOG.debug(_("Found %(name)s: %(initiator)s.")
-                  % {'name': name,
-                     'initiator': foundinitiatornames})
-        return foundinitiatornames
-
-    def _wait_for_job_complete(self, job):
-        jobinstancename = job['Job']
-
-        while True:
-            jobinstance = self.conn.GetInstance(jobinstancename,
-                                                LocalOnly=False)
-            jobstate = jobinstance['JobState']
-            # From ValueMap of JobState in CIM_ConcreteJob
-            # 2L=New, 3L=Starting, 4L=Running, 32767L=Queue Pending
-            # ValueMap("2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13..32767,
-            # 32768..65535"),
-            # Values("New, Starting, Running, Suspended, Shutting Down,
-            # Completed, Terminated, Killed, Exception, Service,
-            # Query Pending, DMTF Reserved, Vendor Reserved")]
-            if jobstate in [2L, 3L, 4L, 32767L]:
-                time.sleep(10)
-            else:
-                break
-
-        rc = jobinstance['ErrorCode']
-        errordesc = jobinstance['ErrorDescription']
-
-        return rc, errordesc
-
-    # Find LunMaskingSCSIProtocolController for the local host on the
-    # specified storage system
-    def _find_lunmasking_scsi_protocol_controller(self, storage_system,
-                                                  connector):
-        foundCtrl = None
-        initiators = self._find_initiator_names(connector)
-        controllers = self.conn.EnumerateInstanceNames(
-            'EMC_LunMaskingSCSIProtocolController')
-        for ctrl in controllers:
-            if storage_system != ctrl['SystemName']:
-                continue
-            associators = self.conn.Associators(
-                            ctrl,
-                            resultClass='EMC_StorageHardwareID')
-            for assoc in associators:
-                # if EMC_StorageHardwareID matches the initiator,
-                # we found the existing EMC_LunMaskingSCSIProtocolController
-                # (Storage Group for VNX)
-                # we can use for masking a new LUN
-                hardwareid = assoc['StorageID']
-                for initiator in initiators:
-                    if hardwareid.lower() == initiator.lower():
-                        foundCtrl = ctrl
-                        break
-
-                if foundCtrl is not None:
-                    break
-
-            if foundCtrl is not None:
-                break
-
-        LOG.debug(_("LunMaskingSCSIProtocolController for storage system "
-                  "%(storage_system)s and initiator %(initiator)s is  "
-                  "%(ctrl)s.")
-                  % {'storage_system': storage_system,
-                     'initiator': initiators,
-                     'ctrl': str(foundCtrl)})
-        return foundCtrl
-
-    # Find LunMaskingSCSIProtocolController for the local host and the
-    # specified storage volume
-    def _find_lunmasking_scsi_protocol_controller_for_vol(self, vol_instance,
-                                                          connector):
-        foundCtrl = None
-        initiators = self._find_initiator_names(connector)
-        controllers = self.conn.AssociatorNames(
-                        vol_instance.path,
-                        resultClass='EMC_LunMaskingSCSIProtocolController')
-
-        for ctrl in controllers:
-            associators = self.conn.Associators(
-                            ctrl,
-                            resultClass='EMC_StorageHardwareID')
-            for assoc in associators:
-                # if EMC_StorageHardwareID matches the initiator,
-                # we found the existing EMC_LunMaskingSCSIProtocolController
-                # (Storage Group for VNX)
-                # we can use for masking a new LUN
-                hardwareid = assoc['StorageID']
-                for initiator in initiators:
-                    if hardwareid.lower() == initiator.lower():
-                        foundCtrl = ctrl
-                        break
-
-                if foundCtrl is not None:
-                    break
-
-            if foundCtrl is not None:
-                break
-
-        LOG.debug(_("LunMaskingSCSIProtocolController for storage volume "
-                  "%(vol)s and initiator %(initiator)s is  %(ctrl)s.")
-                  % {'vol': str(vol_instance.path), 'initiator': initiators,
-                     'ctrl': str(foundCtrl)})
-        return foundCtrl
-
-    # Find out how many volumes are mapped to a host
-    # assoociated to the LunMaskingSCSIProtocolController
-    def get_num_volumes_mapped(self, volume, connector):
-        numVolumesMapped = 0
-        volumename = volume['name']
-        vol_instance = self._find_lun(volume)
-        if vol_instance is None:
-            msg = (_('Volume %(name)s not found on the array. '
-                   'Cannot determine if there are volumes mapped.')
-                   % {'name': volumename})
-            LOG.error(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        storage_system = vol_instance['SystemName']
-
-        ctrl = self._find_lunmasking_scsi_protocol_controller(
-            storage_system,
-            connector)
-
-        LOG.debug(_("LunMaskingSCSIProtocolController for storage system "
-                  "%(storage)s and %(connector)s is %(ctrl)s.")
-                  % {'storage': storage_system,
-                     'connector': connector,
-                     'ctrl': str(ctrl)})
-
-        associators = conn.Associators(
-            ctrl,
-            resultClass='EMC_StorageVolume')
-
-        numVolumesMapped = len(associators)
-
-        LOG.debug(_("Found %(numVolumesMapped)d volumes on storage system "
-                  "%(storage)s mapped to %(initiator)s.")
-                  % {'numVolumesMapped': numVolumesMapped,
-                     'storage': storage_system,
-                     'connector': connector})
-
-        return numVolumesMapped
-
-    # Find an available device number that a host can see
-    def _find_avail_device_number(self, storage_system):
-        out_device_number = '000000'
-        out_num_device_number = 0
-        numlist = []
-        myunitnames = []
-
-        unitnames = self.conn.EnumerateInstanceNames(
-            'CIM_ProtocolControllerForUnit')
-        for unitname in unitnames:
-            controller = unitname['Antecedent']
-            if storage_system != controller['SystemName']:
-                continue
-            classname = controller['CreationClassName']
-            index = classname.find('LunMaskingSCSIProtocolController')
-            if index > -1:
-                unitinstance = self.conn.GetInstance(unitname,
-                                                     LocalOnly=False)
-                numDeviceNumber = int(unitinstance['DeviceNumber'])
-                numlist.append(numDeviceNumber)
-                myunitnames.append(unitname)
-
-        maxnum = max(numlist)
-        out_num_device_number = maxnum + 1
-
-        out_device_number = '%06d' % out_num_device_number
-
-        LOG.debug(_("Available device number on %(storage)s: %(device)s.")
-                  % {'storage': storage_system, 'device': out_device_number})
-        return out_device_number
-
-    # Find a device number that a host can see for a volume
-    def find_device_number(self, volume):
-        out_num_device_number = None
-
-        volumename = volume['name']
-        vol_instance = self._find_lun(volume)
-        storage_system = vol_instance['SystemName']
-        sp = None
-        try:
-            sp = vol_instance['EMCCurrentOwningStorageProcessor']
-        except KeyError:
-            # VMAX LUN doesn't have this property
-            pass
-
-        unitnames = self.conn.ReferenceNames(
-                        vol_instance.path,
-                        ResultClass='CIM_ProtocolControllerForUnit')
-
-        for unitname in unitnames:
-            controller = unitname['Antecedent']
-            classname = controller['CreationClassName']
-            index = classname.find('LunMaskingSCSIProtocolController')
-            if index > -1:  # VNX
-                # Get an instance of CIM_ProtocolControllerForUnit
-                unitinstance = self.conn.GetInstance(unitname,
-                                                     LocalOnly=False)
-                numDeviceNumber = int(unitinstance['DeviceNumber'], 16)
-                out_num_device_number = numDeviceNumber
-                break
-            else:
-                index = classname.find('Symm_LunMaskingView')
-                if index > -1:  # VMAX
-                    unitinstance = self.conn.GetInstance(unitname,
-                                                         LocalOnly=False)
-                    numDeviceNumber = int(unitinstance['DeviceNumber'], 16)
-                    out_num_device_number = numDeviceNumber
-                    break
-
-        if out_num_device_number is None:
-            LOG.info(_("Device number not found for volume "
-                     "%(volumename)s %(vol_instance)s.") %
-                     {'volumename': volumename,
-                      'vol_instance': str(vol_instance.path)})
-        else:
-            LOG.debug(_("Found device number %(device)d for volume "
-                      "%(volumename)s %(vol_instance)s.") %
-                      {'device': out_num_device_number,
-                       'volumename': volumename,
-                       'vol_instance': str(vol_instance.path)})
-
-        data = {'hostlunid': out_num_device_number,
-                'storagesystem': storage_system,
-                'owningsp': sp}
-
-        LOG.debug(_("Device info: %(data)s.") % {'data': data})
-
-        return data
-
-    def _find_device_masking_group(self):
-        """Finds the Device Masking Group in a masking view."""
-        foundMaskingGroup = None
-        maskingview_name = self._get_masking_view()
-
-        maskingviews = self.conn.EnumerateInstanceNames(
-            'EMC_LunMaskingSCSIProtocolController')
-        for view in maskingviews:
-            instance = self.conn.GetInstance(view, LocalOnly=False)
-            if maskingview_name == instance['ElementName']:
-                foundView = view
-                break
-
-        groups = self.conn.AssociatorNames(
-            foundView,
-            ResultClass='SE_DeviceMaskingGroup')
-        foundMaskingGroup = groups[0]
-
-        LOG.debug(_("Masking view: %(view)s DeviceMaskingGroup: %(masking)s.")
-                  % {'view': maskingview_name,
-                     'masking': str(foundMaskingGroup)})
-
-        return foundMaskingGroup
-
-    # Find a StorageProcessorSystem given sp and storage system
-    def _find_storage_processor_system(self, owningsp, storage_system):
-        foundSystem = None
-        systems = self.conn.EnumerateInstanceNames(
-            'EMC_StorageProcessorSystem')
-        for system in systems:
-            # Clar_StorageProcessorSystem.CreationClassName=
-            # "Clar_StorageProcessorSystem",Name="CLARiiON+APM00123907237+SP_A"
-            idarray = system['Name'].split('+')
-            if len(idarray) > 2:
-                storsystemname = idarray[0] + '+' + idarray[1]
-                sp = idarray[2]
-
-            if (storage_system == storsystemname and
-                owningsp == sp):
-                foundSystem = system
-                LOG.debug(_("Found Storage Processor System: %s")
-                          % (str(system)))
-                break
-
-        return foundSystem
-
-    # Find EMC_iSCSIProtocolEndpoint for the specified sp
-    def _find_iscsi_protocol_endpoints(self, owningsp, storage_system):
-        foundEndpoints = []
-
-        processor = self._find_storage_processor_system(
-            owningsp,
-            storage_system)
-
-        associators = self.conn.Associators(
-            processor,
-            resultClass='EMC_iSCSIProtocolEndpoint')
-        for assoc in associators:
-            # Name = iqn.1992-04.com.emc:cx.apm00123907237.a8,t,0x0001
-            # SystemName = CLARiiON+APM00123907237+SP_A+8
-            arr = assoc['SystemName'].split('+')
-            if len(arr) > 2:
-                processor_name = arr[0] + '+' + arr[1] + '+' + arr[2]
-                if processor_name == processor['Name']:
-                    arr2 = assoc['Name'].split(',')
-                    if len(arr2) > 1:
-                        foundEndpoints.append(arr2[0])
-
-        LOG.debug(_("iSCSIProtocolEndpoint for storage system "
-                  "%(storage_system)s and SP %(sp)s is  "
-                  "%(endpoint)s.")
-                  % {'storage_system': storage_system,
-                     'sp': owningsp,
-                     'endpoint': str(foundEndpoints)})
-        return foundEndpoints
-
-    def _getnum(self, num, datatype):
-        try:
-            result = {
-                '8': pywbem.Uint8(num),
-                '16': pywbem.Uint16(num),
-                '32': pywbem.Uint32(num),
-                '64': pywbem.Uint64(num)
-            }
-            result = result.get(datatype, num)
-        except NameError:
-            result = num
-
-        return result
-
-    # Find target WWNs
-    def get_target_wwns(self, storage_system, connector):
-        target_wwns = []
-
-        configservice = self._find_storage_hardwareid_service(
-            storage_system)
-        if configservice is None:
-            exception_msg = (_("Error finding Storage Hardware ID Service."))
-            LOG.error(exception_msg)
-            raise exception.VolumeBackendAPIException(data=exception_msg)
-
-        hardwareids = self._find_storage_hardwareids(connector)
-
-        LOG.debug(_('EMCGetTargetEndpoints: Service: %(service)s  '
-                  'Storage HardwareIDs: %(hardwareids)s.')
-                  % {'service': str(configservice),
-                     'hardwareids': str(hardwareids)})
-
-        for hardwareid in hardwareids:
-            rc, targetendpoints = self.conn.InvokeMethod(
-                'EMCGetTargetEndpoints',
-                configservice,
-                HardwareId=hardwareid)
-
-            if rc != 0L:
-                msg = (_('Error finding Target WWNs.'))
-                LOG.error(msg)
-                raise exception.VolumeBackendAPIException(data=msg)
-
-            endpoints = targetendpoints['TargetEndpoints']
-            for targetendpoint in endpoints:
-                wwn = targetendpoint['Name']
-                # Add target wwn to the list if it is not already there
-                if not any(d.get('wwn', None) == wwn for d in target_wwns):
-                    target_wwns.append({'wwn': wwn})
-                LOG.debug(_('Add target WWN: %s.') % wwn)
-
-        LOG.debug(_('Target WWNs: %s.') % target_wwns)
-
-        return target_wwns
-
-    # Find Storage Hardware IDs
-    def _find_storage_hardwareids(self, connector):
-        foundInstances = []
-        wwpns = self._find_initiator_names(connector)
-        hardwareids = self.conn.EnumerateInstances(
-            'SE_StorageHardwareID')
-        for hardwareid in hardwareids:
-            storid = hardwareid['StorageID']
-            for wwpn in wwpns:
-                if wwpn.lower() == storid.lower():
-                    foundInstances.append(hardwareid.path)
-
-        LOG.debug(_("Storage Hardware IDs for %(wwpns)s is "
-                  "%(foundInstances)s.")
-                  % {'wwpns': str(wwpns),
-                     'foundInstances': str(foundInstances)})
-
-        return foundInstances
diff --git a/manila/volume/drivers/emc/emc_smis_iscsi.py b/manila/volume/drivers/emc/emc_smis_iscsi.py
deleted file mode 100644
index 6c63f21170..0000000000
--- a/manila/volume/drivers/emc/emc_smis_iscsi.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 EMC Corporation.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-ISCSI Drivers for EMC VNX and VMAX arrays based on SMI-S.
-
-"""
-
-import os
-import time
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume import driver
-from manila.volume.drivers.emc import emc_smis_common
-
-LOG = logging.getLogger(__name__)
-
-FLAGS = flags.FLAGS
-
-
-class EMCSMISISCSIDriver(driver.ISCSIDriver):
-    """EMC ISCSI Drivers for VMAX and VNX using SMI-S."""
-
-    def __init__(self, *args, **kwargs):
-
-        super(EMCSMISISCSIDriver, self).__init__(*args, **kwargs)
-        self.common = emc_smis_common.EMCSMISCommon(
-                                        'iSCSI',
-                                        configuration=self.configuration)
-
-    def check_for_setup_error(self):
-        pass
-
-    def create_volume(self, volume):
-        """Creates a EMC(VMAX/VNX) volume."""
-        self.common.create_volume(volume)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-        self.common.create_volume_from_snapshot(volume, snapshot)
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a cloned volume."""
-        self.common.create_cloned_volume(volume, src_vref)
-
-    def delete_volume(self, volume):
-        """Deletes an EMC volume."""
-        self.common.delete_volume(volume)
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        self.common.create_snapshot(snapshot)
-
-    def delete_snapshot(self, snapshot):
-        """Deletes a snapshot."""
-        self.common.delete_snapshot(snapshot)
-
-    def ensure_export(self, context, volume):
-        """Driver entry point to get the export info for an existing volume."""
-        pass
-
-    def create_export(self, context, volume):
-        """Driver entry point to get the export info for a new volume."""
-        return self.common.create_export(context, volume)
-
-    def remove_export(self, context, volume):
-        """Driver entry point to remove an export for a volume."""
-        pass
-
-    def check_for_export(self, context, volume_id):
-        """Make sure volume is exported."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Initializes the connection and returns connection info.
-
-        The iscsi driver returns a driver_volume_type of 'iscsi'.
-        the format of the driver data is defined in _get_iscsi_properties.
-        Example return value::
-
-            {
-                'driver_volume_type': 'iscsi'
-                'data': {
-                    'target_discovered': True,
-                    'target_iqn': 'iqn.2010-10.org.openstack:volume-00000001',
-                    'target_portal': '127.0.0.0.1:3260',
-                    'volume_id': 1,
-                }
-            }
-
-        """
-        self.common.initialize_connection(volume, connector)
-
-        iscsi_properties = self._get_iscsi_properties(volume)
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': iscsi_properties
-        }
-
-    def _do_iscsi_discovery(self, volume):
-
-        LOG.warn(_("ISCSI provider_location not stored, using discovery"))
-
-        (out, _err) = self._execute('iscsiadm', '-m', 'discovery',
-                                    '-t', 'sendtargets', '-p',
-                                    self.configuration.iscsi_ip_address,
-                                    run_as_root=True)
-        targets = []
-        for target in out.splitlines():
-            targets.append(target)
-
-        return targets
-
-    def _get_iscsi_properties(self, volume):
-        """Gets iscsi configuration.
-
-        We ideally get saved information in the volume entity, but fall back
-        to discovery if need be. Discovery may be completely removed in future
-        The properties are:
-
-        :target_discovered:    boolean indicating whether discovery was used
-
-        :target_iqn:    the IQN of the iSCSI target
-
-        :target_portal:    the portal of the iSCSI target
-
-        :target_lun:    the lun of the iSCSI target
-
-        :volume_id:    the id of the volume (currently used by xen)
-
-        :auth_method:, :auth_username:, :auth_password:
-
-            the authentication details. Right now, either auth_method is not
-            present meaning no authentication, or auth_method == `CHAP`
-            meaning use CHAP with the specified credentials.
-        """
-        properties = {}
-
-        location = self._do_iscsi_discovery(volume)
-        if not location:
-            raise exception.InvalidVolume(_("Could not find iSCSI export "
-                                          " for volume %s") %
-                                          (volume['name']))
-
-        LOG.debug(_("ISCSI Discovery: Found %s") % (location))
-        properties['target_discovered'] = True
-
-        device_info = self.common.find_device_number(volume)
-        if device_info is None or device_info['hostlunid'] is None:
-            exception_message = (_("Cannot find device number for volume %s")
-                                 % volume['name'])
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        device_number = device_info['hostlunid']
-        storage_system = device_info['storagesystem']
-
-        # sp is "SP_A" or "SP_B"
-        sp = device_info['owningsp']
-        endpoints = []
-        if sp:
-            # endpointss example:
-            # [iqn.1992-04.com.emc:cx.apm00123907237.a8,
-            # iqn.1992-04.com.emc:cx.apm00123907237.a9]
-            endpoints = self.common._find_iscsi_protocol_endpoints(
-                sp, storage_system)
-
-        foundEndpoint = False
-        for loc in location:
-            results = loc.split(" ")
-            properties['target_portal'] = results[0].split(",")[0]
-            properties['target_iqn'] = results[1]
-            # owning sp is None for VMAX
-            # for VNX, find the target_iqn that matches the endpoint
-            # target_iqn example: iqn.1992-04.com.emc:cx.apm00123907237.a8
-            # or iqn.1992-04.com.emc:cx.apm00123907237.b8
-            if not sp:
-                break
-            for endpoint in endpoints:
-                if properties['target_iqn'] == endpoint:
-                    LOG.debug(_("Found iSCSI endpoint: %s") % endpoint)
-                    foundEndpoint = True
-                    break
-            if foundEndpoint:
-                break
-
-        if sp and not foundEndpoint:
-            LOG.warn(_("ISCSI endpoint not found for SP %(sp)s on "
-                     "storage system %(storage)s.")
-                     % {'sp': sp,
-                        'storage': storage_system})
-
-        properties['target_lun'] = device_number
-
-        properties['volume_id'] = volume['id']
-
-        auth = volume['provider_auth']
-        if auth:
-            (auth_method, auth_username, auth_secret) = auth.split()
-
-            properties['auth_method'] = auth_method
-            properties['auth_username'] = auth_username
-            properties['auth_password'] = auth_secret
-
-        LOG.debug(_("ISCSI properties: %s") % (properties))
-
-        return properties
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Disallow connection from connector."""
-        self.common.terminate_connection(volume, connector)
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first.
-        """
-        if refresh:
-            self.update_volume_status()
-
-        return self._stats
-
-    def update_volume_status(self):
-        """Retrieve status info from volume group."""
-        LOG.debug(_("Updating volume status"))
-        data = self.common.update_volume_status()
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data['volume_backend_name'] = backend_name or 'EMCSMISISCSIDriver'
-        data['storage_protocol'] = 'iSCSI'
-        self._stats = data
diff --git a/manila/volume/drivers/glusterfs.py b/manila/volume/drivers/glusterfs.py
deleted file mode 100644
index c804a6cebd..0000000000
--- a/manila/volume/drivers/glusterfs.py
+++ /dev/null
@@ -1,283 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2013 Red Hat, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import errno
-import os
-
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila.volume.drivers import nfs
-
-LOG = logging.getLogger(__name__)
-
-volume_opts = [
-    cfg.StrOpt('glusterfs_shares_config',
-               default='/etc/manila/glusterfs_shares',
-               help='File with the list of available gluster shares'),
-    cfg.StrOpt('glusterfs_mount_point_base',
-               default='$state_path/mnt',
-               help='Base dir containing mount points for gluster shares'),
-    cfg.StrOpt('glusterfs_disk_util',
-               default='df',
-               help='Use du or df for free space calculation'),
-    cfg.BoolOpt('glusterfs_sparsed_volumes',
-                default=True,
-                help=('Create volumes as sparsed files which take no space.'
-                      'If set to False volume is created as regular file.'
-                      'In such case volume creation takes a lot of time.'))]
-VERSION = '1.0'
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(volume_opts)
-
-
-class GlusterfsDriver(nfs.RemoteFsDriver):
-    """Gluster based manila driver. Creates file on Gluster share for using it
-    as block device on hypervisor."""
-
-    def __init__(self, *args, **kwargs):
-        super(GlusterfsDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(volume_opts)
-
-    def do_setup(self, context):
-        """Any initialization the volume driver does while starting."""
-        super(GlusterfsDriver, self).do_setup(context)
-
-        config = self.configuration.glusterfs_shares_config
-        if not config:
-            msg = (_("There's no Gluster config file configured (%s)") %
-                   'glusterfs_shares_config')
-            LOG.warn(msg)
-            raise exception.GlusterfsException(msg)
-        if not os.path.exists(config):
-            msg = (_("Gluster config file at %(config)s doesn't exist") %
-                   locals())
-            LOG.warn(msg)
-            raise exception.GlusterfsException(msg)
-
-        try:
-            self._execute('mount.glusterfs', check_exit_code=False)
-        except OSError as exc:
-            if exc.errno == errno.ENOENT:
-                raise exception.GlusterfsException(
-                    _('mount.glusterfs is not installed'))
-            else:
-                raise
-
-    def check_for_setup_error(self):
-        """Just to override parent behavior."""
-        pass
-
-    def create_cloned_volume(self, volume, src_vref):
-        raise NotImplementedError()
-
-    def create_volume(self, volume):
-        """Creates a volume."""
-
-        self._ensure_shares_mounted()
-
-        volume['provider_location'] = self._find_share(volume['size'])
-
-        LOG.info(_('casted to %s') % volume['provider_location'])
-
-        self._do_create_volume(volume)
-
-        return {'provider_location': volume['provider_location']}
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-
-        if not volume['provider_location']:
-            LOG.warn(_('Volume %s does not have provider_location specified, '
-                     'skipping'), volume['name'])
-            return
-
-        self._ensure_share_mounted(volume['provider_location'])
-
-        mounted_path = self.local_path(volume)
-
-        self._execute('rm', '-f', mounted_path, run_as_root=True)
-
-    def ensure_export(self, ctx, volume):
-        """Synchronously recreates an export for a logical volume."""
-        self._ensure_share_mounted(volume['provider_location'])
-
-    def create_export(self, ctx, volume):
-        """Exports the volume. Can optionally return a Dictionary of changes
-        to the volume object to be persisted."""
-        pass
-
-    def remove_export(self, ctx, volume):
-        """Removes an export for a logical volume."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Allow connection to connector and return connection info."""
-        data = {'export': volume['provider_location'],
-                'name': volume['name']}
-        return {
-            'driver_volume_type': 'glusterfs',
-            'data': data
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Disallow connection from connector."""
-        pass
-
-    def _do_create_volume(self, volume):
-        """Create a volume on given glusterfs_share.
-        :param volume: volume reference
-        """
-        volume_path = self.local_path(volume)
-        volume_size = volume['size']
-
-        if self.configuration.glusterfs_sparsed_volumes:
-            self._create_sparsed_file(volume_path, volume_size)
-        else:
-            self._create_regular_file(volume_path, volume_size)
-
-        self._set_rw_permissions_for_all(volume_path)
-
-    def _ensure_shares_mounted(self):
-        """Look for GlusterFS shares in the flags and try to mount them
-           locally."""
-        self._mounted_shares = []
-
-        for share in self._load_shares_config():
-            try:
-                self._ensure_share_mounted(share)
-                self._mounted_shares.append(share)
-            except Exception, exc:
-                LOG.warning(_('Exception during mounting %s') % (exc,))
-
-        LOG.debug('Available shares %s' % str(self._mounted_shares))
-
-    def _load_shares_config(self):
-        return [share.strip() for share
-                in open(self.configuration.glusterfs_shares_config)
-                if share and not share.startswith('#')]
-
-    def _ensure_share_mounted(self, glusterfs_share):
-        """Mount GlusterFS share.
-        :param glusterfs_share:
-        """
-        mount_path = self._get_mount_point_for_share(glusterfs_share)
-        self._mount_glusterfs(glusterfs_share, mount_path, ensure=True)
-
-    def _find_share(self, volume_size_for):
-        """Choose GlusterFS share among available ones for given volume size.
-        Current implementation looks for greatest capacity.
-        :param volume_size_for: int size in GB
-        """
-
-        if not self._mounted_shares:
-            raise exception.GlusterfsNoSharesMounted()
-
-        greatest_size = 0
-        greatest_share = None
-
-        for glusterfs_share in self._mounted_shares:
-            capacity = self._get_available_capacity(glusterfs_share)[0]
-            if capacity > greatest_size:
-                greatest_share = glusterfs_share
-                greatest_size = capacity
-
-        if volume_size_for * 1024 * 1024 * 1024 > greatest_size:
-            raise exception.GlusterfsNoSuitableShareFound(
-                volume_size=volume_size_for)
-        return greatest_share
-
-    def _get_mount_point_for_share(self, glusterfs_share):
-        """Return mount point for share.
-        :param glusterfs_share: example 172.18.194.100:/var/glusterfs
-        """
-        return os.path.join(self.configuration.glusterfs_mount_point_base,
-                            self._get_hash_str(glusterfs_share))
-
-    def _get_available_capacity(self, glusterfs_share):
-        """Calculate available space on the GlusterFS share.
-        :param glusterfs_share: example 172.18.194.100:/var/glusterfs
-        """
-        mount_point = self._get_mount_point_for_share(glusterfs_share)
-
-        out, _ = self._execute('df', '--portability', '--block-size', '1',
-                               mount_point, run_as_root=True)
-        out = out.splitlines()[1]
-
-        available = 0
-
-        size = int(out.split()[1])
-        if self.configuration.glusterfs_disk_util == 'df':
-            available = int(out.split()[3])
-        else:
-            out, _ = self._execute('du', '-sb', '--apparent-size',
-                                   '--exclude', '*snapshot*', mount_point,
-                                   run_as_root=True)
-            used = int(out.split()[0])
-            available = size - used
-
-        return available, size
-
-    def _mount_glusterfs(self, glusterfs_share, mount_path, ensure=False):
-        """Mount GlusterFS share to mount path."""
-        self._execute('mkdir', '-p', mount_path)
-
-        try:
-            self._execute('mount', '-t', 'glusterfs', glusterfs_share,
-                          mount_path, run_as_root=True)
-        except exception.ProcessExecutionError as exc:
-            if ensure and 'already mounted' in exc.stderr:
-                LOG.warn(_("%s is already mounted"), glusterfs_share)
-            else:
-                raise
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume stats.
-
-        If 'refresh' is True, update the stats first."""
-        if refresh or not self._stats:
-            self._update_volume_stats()
-
-        return self._stats
-
-    def _update_volume_stats(self):
-        """Retrieve stats info from volume group."""
-
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data['volume_backend_name'] = backend_name or 'GlusterFS'
-        data['vendor_name'] = 'Open Source'
-        data['driver_version'] = VERSION
-        data['storage_protocol'] = 'glusterfs'
-
-        self._ensure_shares_mounted()
-
-        global_capacity = 0
-        global_free = 0
-        for nfs_share in self._mounted_shares:
-            free, capacity = self._get_available_capacity(nfs_share)
-            global_capacity += capacity
-            global_free += free
-
-        data['total_capacity_gb'] = global_capacity / 1024.0 ** 3
-        data['free_capacity_gb'] = global_free / 1024.0 ** 3
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = False
-        self._stats = data
diff --git a/manila/volume/drivers/huawei/__init__.py b/manila/volume/drivers/huawei/__init__.py
deleted file mode 100644
index 0f4b6d394e..0000000000
--- a/manila/volume/drivers/huawei/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2012 Huawei Technologies Co., Ltd.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
diff --git a/manila/volume/drivers/huawei/cinder_huawei_conf.xml.sample b/manila/volume/drivers/huawei/cinder_huawei_conf.xml.sample
deleted file mode 100644
index 8d5a577bf8..0000000000
--- a/manila/volume/drivers/huawei/cinder_huawei_conf.xml.sample
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<config>
-    <Storage>
-        <ControllerIP0>x.x.x.x</ControllerIP0>
-        <ControllerIP1>x.x.x.x</ControllerIP1>
-        <UserName>xxxxxx</UserName>
-        <UserPassword>xxxxxx</UserPassword>
-    </Storage>
-    <LUN>
-        <!--LUN Type: Thick, or Thin. Default: Thick-->
-        <LUNType>Thick</LUNType>
-        <!--The stripe size can be 4, 8, 16, 32, 64, 128, 256, and 512 in the unit of KB.Default: 64-->
-        <StripUnitSize>64</StripUnitSize>
-        <!--The write cache policy of the LUN:-->
-        <!--1 specifies write back, 2 specifies write through, 3 specifies write back mandatorily.Default: 1-->
-        <WriteType>1</WriteType>
-        <!--Enables or disbles cahce mirroring: 0 Disable, or 1 Enable. Default: Enable-->
-        <MirrorSwitch>1</MirrorSwitch>
-        <!--The prefetch policy of the reading cache:-->
-        <!--prefetch type 0 specifies non-preftch and prefetch value is 0,-->
-        <!--prefetch type 1 specifies constant prefetch and  prefetch value ranges from 0 to 1024 in the unit of KB,-->
-        <!--prefetch type 2 specifies variable prefetch and value specifies cache prefetch multiple ranges from 0 to 65535,-->
-        <!--prefetch type 3 specifies intelligent prefetch Intelligent and Vaule is 0,-->
-        <!--Default:  prefetch type 0 and prefetch value 0-->
-        <Prefetch Type="0" Value="0"/>
-        <StoragePool Name="xxxxxx"/>
-        <StoragePool Name="xxxxxx"/>
-    </LUN>
-    <iSCSI>
-        <DefaultTargetIP>x.x.x.x</DefaultTargetIP>
-        <Initiator Name="xxxxxx" TargetIP="x.x.x.x"/>
-        <Initiator Name="xxxxxx" TargetIP="x.x.x.x"/>
-    </iSCSI>
-</config>
diff --git a/manila/volume/drivers/huawei/huawei_iscsi.py b/manila/volume/drivers/huawei/huawei_iscsi.py
deleted file mode 100644
index 3f13fbc76d..0000000000
--- a/manila/volume/drivers/huawei/huawei_iscsi.py
+++ /dev/null
@@ -1,1547 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2012 Huawei Technologies Co., Ltd.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Volume driver for HUAWEI T series and Dorado storage systems.
-"""
-import base64
-import os
-import paramiko
-import re
-import socket
-import threading
-import time
-
-from oslo.config import cfg
-from xml.etree import ElementTree as ET
-
-from manila import exception
-from manila.openstack.common import excutils
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume import driver
-
-LOG = logging.getLogger(__name__)
-
-huawei_opt = [
-    cfg.StrOpt('cinder_huawei_conf_file',
-               default='/etc/manila/cinder_huawei_conf.xml',
-               help='config data for manila huawei plugin')]
-
-HOST_GROUP_NAME = 'HostGroup_OpenStack'
-HOST_NAME_PREFIX = 'Host_'
-HOST_PORT_PREFIX = 'HostPort_'
-VOL_AND_SNAP_NAME_PREFIX = 'OpenStack_'
-READBUFFERSIZE = 8192
-
-
-class SSHConn(utils.SSHPool):
-    """Define a new class inherited to SSHPool.
-
-    This class rewrites method create() and defines a private method
-    ssh_read() which reads results of ssh commands.
-    """
-
-    def __init__(self, ip, port, conn_timeout, login, password,
-                 privatekey=None, *args, **kwargs):
-
-        super(SSHConn, self).__init__(ip, port, conn_timeout, login,
-                                      password, privatekey=None,
-                                      *args, **kwargs)
-        self.lock = threading.Lock()
-
-    def create(self):
-        """Create an SSH client.
-
-        Because seting socket timeout to be None will cause client.close()
-        blocking, here we have to rewrite method create() and use default
-        socket timeout value 0.1.
-        """
-        try:
-            ssh = paramiko.SSHClient()
-            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-            if self.password:
-                ssh.connect(self.ip,
-                            port=self.port,
-                            username=self.login,
-                            password=self.password,
-                            timeout=self.conn_timeout)
-            elif self.privatekey:
-                pkfile = os.path.expanduser(self.privatekey)
-                privatekey = paramiko.RSAKey.from_private_key_file(pkfile)
-                ssh.connect(self.ip,
-                            port=self.port,
-                            username=self.login,
-                            pkey=privatekey,
-                            timeout=self.conn_timeout)
-            else:
-                msg = _("Specify a password or private_key")
-                raise exception.CinderException(msg)
-
-            if self.conn_timeout:
-                transport = ssh.get_transport()
-                transport.set_keepalive(self.conn_timeout)
-            return ssh
-        except Exception as e:
-            msg = _("Error connecting via ssh: %s") % e
-            LOG.error(msg)
-            raise paramiko.SSHException(msg)
-
-    def ssh_read(self, channel, cmd, timeout):
-        """Get results of CLI commands."""
-        result = ''
-        user = self.login
-        user_flg = user + ':/>$'
-        channel.settimeout(timeout)
-        while True:
-            try:
-                result = result + channel.recv(READBUFFERSIZE)
-            except socket.timeout:
-                raise exception.VolumeBackendAPIException(_('read timed out'))
-            else:
-                if re.search(cmd, result) and re.search(user_flg, result):
-                    if not re.search('Welcome', result):
-                        break
-                    elif re.search(user + ':/>' + cmd, result):
-                        break
-                elif re.search('(y/n)', result):
-                    break
-        return '\r\n'.join(result.split('\r\n')[:-1])
-
-
-class HuaweiISCSIDriver(driver.ISCSIDriver):
-    """Huawei T series and Dorado iSCSI volume driver."""
-
-    def __init__(self, *args, **kwargs):
-        super(HuaweiISCSIDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(huawei_opt)
-        self.device_type = {}
-        self.login_info = {}
-        self.hostgroup_id = None
-        self.ssh_pool = None
-
-    def do_setup(self, context):
-        """Check config file."""
-        LOG.debug(_('do_setup.'))
-
-        self._check_conf_file()
-
-    def check_for_setup_error(self):
-        """Try to connect with device and get device type."""
-        LOG.debug(_('check_for_setup_error.'))
-
-        self.login_info = self._get_login_info()
-        self.device_type = self._get_device_type()
-        if not self.device_type['type']:
-            err_msg = (_('check_for_setup_error: Can not get device type.'))
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        LOG.debug(_('check_for_setup_error: Device type is:%(type)s, '
-                    'version is:%(version)s.')
-                  % {'type': self.device_type['type'],
-                     'version': self.device_type['version']})
-
-        # Now only version V1 is supported.
-        if self.device_type['version'] != 'V100R':
-            err_msg = (_('check_for_setup_error: Product version not right. '
-                         'Please make sure the product version is V1.'))
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        # Check whether storage pools are configured.
-        # Dorado2100 G2 needn't to configure this.
-        if self.device_type['type'] != 'Dorado2100 G2':
-            root = self._read_xml()
-            pool_node = root.findall('LUN/StoragePool')
-            if not pool_node:
-                err_msg = (_('_get_device_type: Storage Pool must be '
-                             'configured.'))
-                LOG.error(err_msg)
-                raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def create_volume(self, volume):
-        """Create a new volume."""
-        volume_name = self._name_translate(volume['name'])
-
-        LOG.debug(_('create_volume:volume name: %s.') % volume_name)
-
-        self.login_info = self._get_login_info()
-        if int(volume['size']) == 0:
-            volume_size = '100M'
-        else:
-            volume_size = '%sG' % volume['size']
-
-        self._create_volume(volume_name, volume_size)
-
-    def delete_volume(self, volume):
-        """Delete a volume."""
-        volume_name = self._name_translate(volume['name'])
-
-        LOG.debug(_('delete_volume: volume name: %s.') % volume_name)
-
-        self.login_info = self._get_login_info()
-        volume_id = self._find_lun(volume_name)
-        if volume_id is not None:
-            self._delete_volume(volume_name, volume_id)
-        else:
-            err_msg = (_('delete_volume:No need to delete volume. '
-                         'Volume %(name)s does not exist.')
-                       % {'name': volume['name']})
-            LOG.error(err_msg)
-
-    def create_export(self, context, volume):
-        """Driver entry point to get the  export info for a new volume."""
-        volume_name = self._name_translate(volume['name'])
-
-        LOG.debug(_('create_export: volume name:%s') % volume['name'])
-
-        lun_id = self._find_lun(volume_name)
-        if lun_id is None:
-            err_msg = (_('create_export:Volume %(name)s does not exist.')
-                       % {'name': volume_name})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        return {'provider_location': lun_id}
-
-    def ensure_export(self, context, volume):
-        """Driver entry point to get the export info for a existing volume."""
-        pass
-
-    def remove_export(self, context, volume_id):
-        """Driver entry point to remove an export for a volume."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Map a volume to a host and return target iSCSI information."""
-        initiator_name = connector['initiator']
-        volume_name = self._name_translate(volume['name'])
-
-        LOG.debug(_('initialize_connection: volume name: %(volume)s. '
-                    'initiator name: %(ini)s.')
-                  % {'volume': volume_name,
-                     'ini': initiator_name})
-
-        self.login_info = self._get_login_info()
-        # Get target iSCSI iqn.
-        iscsi_conf = self._get_iscsi_info()
-        target_ip = None
-        for ini in iscsi_conf['Initiator']:
-            if ini['Name'] == initiator_name:
-                target_ip = ini['TargetIP']
-                break
-        if not target_ip:
-            if not iscsi_conf['DefaultTargetIP']:
-                err_msg = (_('initialize_connection:Failed to find target ip '
-                             'for initiator:%(initiatorname)s, '
-                             'please check config file.')
-                           % {'initiatorname': initiator_name})
-                LOG.error(err_msg)
-                raise exception.VolumeBackendAPIException(data=err_msg)
-            target_ip = iscsi_conf['DefaultTargetIP']
-
-        (target_iqn, controller) = self._get_tgt_iqn(target_ip)
-        if not target_iqn:
-            err_msg = (_('initialize_connection:Failed to find target iSCSI '
-                         'iqn. Target IP:%(ip)s')
-                       % {'ip': target_ip})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        # Create hostgroup and host.
-        hostgroup_name = HOST_GROUP_NAME
-        self.hostgroup_id = self._find_hostgroup(hostgroup_name)
-        if self.hostgroup_id is None:
-            self._create_hostgroup(hostgroup_name)
-            self.hostgroup_id = self._find_hostgroup(hostgroup_name)
-
-        host_name = HOST_NAME_PREFIX + str(hash(initiator_name))
-        host_id = self._find_host_in_hostgroup(host_name, self.hostgroup_id)
-        if host_id is None:
-            self._add_host(host_name, self.hostgroup_id)
-            host_id = self._find_host_in_hostgroup(host_name,
-                                                   self.hostgroup_id)
-
-        # Create an initiator.
-        added = self._check_initiator(initiator_name)
-        if not added:
-            self._add_initiator(initiator_name)
-
-        # Add the initiator to host.
-        port_name = HOST_PORT_PREFIX + str(hash(initiator_name))
-        port_info = initiator_name
-        portadded = False
-        hostport_info = self._get_hostport_info(host_id)
-        if hostport_info:
-            for hostport in hostport_info:
-                if hostport['info'] == initiator_name:
-                    portadded = True
-                    break
-        if not portadded:
-            self._add_hostport(port_name, host_id, port_info)
-
-        LOG.debug(_('initialize_connection:host name: %(host)s, '
-                    'initiator name: %(ini)s, '
-                    'hostport name: %(port)s')
-                  % {'host': host_name,
-                     'ini': initiator_name,
-                     'port': port_name})
-
-        # Map a LUN to a host if not mapped.
-        lun_id = self._find_lun(volume_name)
-        if lun_id is None:
-            err_msg = (_('initialize_connection:Failed to find the '
-                         'given volume. '
-                         'volume name:%(volume)s.')
-                       % {'volume': volume_name})
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        hostlun_id = None
-        map_info = self._get_map_info(host_id)
-        # Make sure the hostLUN ID starts from 1.
-        new_hostlun_id = 1
-        new_hostlunid_found = False
-        if map_info:
-            for map in map_info:
-                if map['devlunid'] == lun_id:
-                    hostlun_id = map['hostlunid']
-                    break
-                elif not new_hostlunid_found:
-                    if new_hostlun_id < int(map['hostlunid']):
-                        new_hostlunid_found = True
-                    else:
-                        new_hostlun_id = int(map['hostlunid']) + 1
-        # The LUN is not mapped to the host.
-        if not hostlun_id:
-            self._map_lun(lun_id, host_id, new_hostlun_id)
-            hostlun_id = self._get_hostlunid(host_id, lun_id)
-
-        # Change lun ownning controller for better performance.
-        if self._get_lun_controller(lun_id) != controller:
-            self._change_lun_controller(lun_id, controller)
-
-        # Return iSCSI properties.
-        properties = {}
-        properties['target_discovered'] = False
-        properties['target_portal'] = ('%s:%s' % (target_ip, '3260'))
-        properties['target_iqn'] = target_iqn
-        properties['target_lun'] = int(hostlun_id)
-        properties['volume_id'] = volume['id']
-        auth = volume['provider_auth']
-        if auth:
-            (auth_method, auth_username, auth_secret) = auth.split()
-
-            properties['auth_method'] = auth_method
-            properties['auth_username'] = auth_username
-            properties['auth_password'] = auth_secret
-
-        return {'driver_volume_type': 'iscsi', 'data': properties}
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Delete map between a volume and a host."""
-        initiator_name = connector['initiator']
-        volume_name = self._name_translate(volume['name'])
-
-        LOG.debug(_('terminate_connection:volume name: %(volume)s, '
-                    'initiator name: %(ini)s.')
-                  % {'volume': volume_name,
-                     'ini': initiator_name})
-
-        self.login_info = self._get_login_info()
-        host_name = HOST_NAME_PREFIX + str(hash(initiator_name))
-        host_id = self._find_host_in_hostgroup(host_name, self.hostgroup_id)
-        if host_id is None:
-            err_msg = (_('terminate_connection:Host does not exist. '
-                         'Host name:%(host)s.')
-                       % {'host': host_name})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        # Delete host map.
-        lun_id = self._find_lun(volume_name)
-        if lun_id is None:
-            err_msg = (_('terminate_connection:volume does not exist. '
-                         'volume name:%(volume)s')
-                       % {'volume': volume_name})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        map_id = None
-        mapnum = 0
-        map_info = self._get_map_info(host_id)
-        if map_info:
-            mapnum = len(map_info)
-            for map in map_info:
-                if map['devlunid'] == lun_id:
-                    map_id = map['mapid']
-                    break
-        if map_id is not None:
-            self._delete_map(map_id)
-            mapnum = mapnum - 1
-        else:
-            LOG.error(_('terminate_connection:No map between host '
-                        'and volume. Host name:%(hostname)s, '
-                        'volume name:%(volumename)s.')
-                      % {'hostname': host_name,
-                         'volumename': volume_name})
-
-        # Delete host initiator when no LUN mapped to it.
-        portnum = 0
-        hostportinfo = self._get_hostport_info(host_id)
-        if hostportinfo:
-            portnum = len(hostportinfo)
-            for hostport in hostportinfo:
-                if hostport['info'] == initiator_name and mapnum == 0:
-                    self._delete_hostport(hostport['id'])
-                    self._delete_initiator(initiator_name)
-                    portnum = portnum - 1
-                    break
-        else:
-            LOG.error(_('terminate_connection:No initiator is added '
-                        'to the host. Host name:%(hostname)s')
-                      % {'hostname': host_name})
-
-        # Delete host when no initiator added to it.
-        if portnum == 0:
-            self._delete_host(host_id)
-
-    def create_snapshot(self, snapshot):
-        """Create a snapshot."""
-        snapshot_name = self._name_translate(snapshot['name'])
-        volume_name = self._name_translate(snapshot['volume_name'])
-
-        LOG.debug(_('create_snapshot:snapshot name:%(snapshot)s, '
-                    'volume name:%(volume)s.')
-                  % {'snapshot': snapshot_name,
-                     'volume': volume_name})
-
-        self.login_info = self._get_login_info()
-        if self.device_type['type'] == 'Dorado2100 G2':
-            err_msg = (_('create_snapshot:Device does not support snapshot.'))
-
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        if self._is_resource_pool_enough() is False:
-            err_msg = (_('create_snapshot:'
-                         'Resource pool needs 1GB valid size at least.'))
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        lun_id = self._find_lun(volume_name)
-        if lun_id is None:
-            err_msg = (_('create_snapshot:Volume does not exist. '
-                         'Volume name:%(name)s')
-                       % {'name': volume_name})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        self._create_snapshot(snapshot_name, lun_id)
-        snapshot_id = self._find_snapshot(snapshot_name)
-        if not snapshot_id:
-            err_msg = (_('create_snapshot:Snapshot does not exist. '
-                         'Snapshot name:%(name)s')
-                       % {'name': snapshot_name})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-        self._active_snapshot(snapshot_id)
-
-    def delete_snapshot(self, snapshot):
-        """Delete a snapshot."""
-        snapshot_name = self._name_translate(snapshot['name'])
-        volume_name = self._name_translate(snapshot['volume_name'])
-
-        LOG.debug(_('delete_snapshot:snapshot name:%(snapshot)s, '
-                    'volume name:%(volume)s.')
-                  % {'snapshot': snapshot_name,
-                     'volume': volume_name})
-
-        self.login_info = self._get_login_info()
-        if self.device_type['type'] == 'Dorado2100 G2':
-            err_msg = (_('delete_snapshot:Device does not support snapshot.'))
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        snapshot_id = self._find_snapshot(snapshot_name)
-        if snapshot_id is not None:
-            self._disable_snapshot(snapshot_id)
-            self._delete_snapshot(snapshot_id)
-        else:
-            err_msg = (_('delete_snapshot:Snapshot does not exist. '
-                         'snapshot name:%(snap)s')
-                       % {'snap': snapshot_name})
-            LOG.debug(err_msg)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Create a volume from a snapshot.
-
-        We use LUNcopy to create a new LUN from snapshot.
-        """
-        snapshot_name = self._name_translate(snapshot['name'])
-        volume_name = self._name_translate(volume['name'])
-
-        LOG.debug(_('create_volume_from_snapshot:snapshot '
-                    'name:%(snapshot)s, '
-                    'volume name:%(volume)s.')
-                  % {'snapshot': snapshot_name,
-                     'volume': volume_name})
-
-        self.login_info = self._get_login_info()
-        if self.device_type['type'].find('Dorado') > -1:
-            err_msg = (_('create_volume_from_snapshot:Device does '
-                         'not support create volume from snapshot. '
-                         'Volume name:%(volume)s, '
-                         'snapshot name:%(snapshot)s.')
-                       % {'volume': volume_name,
-                          'snapshot': snapshot_name})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        snapshot_id = self._find_snapshot(snapshot_name)
-        if snapshot_id is None:
-            err_msg = (_('create_volume_from_snapshot:Snapshot '
-                         'does not exist. Snapshot name:%(name)s')
-                       % {'name': snapshot_name})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-        # Create a target LUN.
-        if int(volume['size']) == 0:
-            volume_size = '%sG' % snapshot['volume_size']
-        else:
-            volume_size = '%sG' % volume['size']
-
-        self._create_volume(volume_name, volume_size)
-        volume_id = self._find_lun(volume_name)
-        luncopy_name = volume_name
-        try:
-            self._create_luncopy(luncopy_name, snapshot_id, volume_id)
-            luncopy_id = self._find_luncopy(luncopy_name)
-            self._start_luncopy(luncopy_id)
-            self._wait_for_luncopy(luncopy_name)
-        # If LUNcopy failed,we should delete the target volume.
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self._delete_luncopy(luncopy_id)
-                self._delete_volume(volume_name, volume_id)
-
-        self._delete_luncopy(luncopy_id)
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first.
-        """
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _check_conf_file(self):
-        """Check the config file, make sure the key elements are set."""
-        root = self._read_xml()
-        try:
-            IP1 = root.findtext('Storage/ControllerIP0')
-            IP2 = root.findtext('Storage/ControllerIP1')
-            username = root.findtext('Storage/UserName')
-            pwd = root.findtext('Storage/UserPassword')
-
-            isconfwrong = False
-            if ((not IP1 and not IP2) or
-                    (not username) or
-                    (not pwd)):
-                err_msg = (_('Config file is wrong. Controler IP, '
-                             'UserName and UserPassword must be set.'))
-                LOG.error(err_msg)
-                raise exception.InvalidInput(reason=err_msg)
-
-        except Exception as err:
-            LOG.error(_('_check_conf_file: %s') % str(err))
-            raise exception.VolumeBackendAPIException(data=err)
-
-    def _read_xml(self):
-        """Open xml file."""
-        filename = self.configuration.cinder_huawei_conf_file
-        try:
-            tree = ET.parse(filename)
-            root = tree.getroot()
-
-        except Exception as err:
-            LOG.error(_('_read_xml:%s') % err)
-            raise exception.VolumeBackendAPIException(data=err)
-        return root
-
-    def _get_login_info(self):
-        """Get login IP, username and password from config file."""
-        logininfo = {}
-        try:
-            filename = self.configuration.cinder_huawei_conf_file
-            tree = ET.parse(filename)
-            root = tree.getroot()
-            logininfo['ControllerIP0'] = root.findtext('Storage/ControllerIP0')
-            logininfo['ControllerIP1'] = root.findtext('Storage/ControllerIP1')
-
-            need_encode = False
-            for key in ['UserName', 'UserPassword']:
-                node = root.find('Storage/%s' % key)
-                node_text = node.text
-                if node_text.find('!$$$') == 0:
-                    logininfo[key] = base64.b64decode(node_text[4:])
-                else:
-                    logininfo[key] = node_text
-                    node.text = '!$$$' + base64.b64encode(node_text)
-                    need_encode = True
-            if need_encode:
-                try:
-                    tree.write(filename, 'UTF-8')
-                except Exception as err:
-                    LOG.error(_('Write login information to xml error. %s')
-                              % err)
-
-        except Exception as err:
-            LOG.error(_('_get_login_info error. %s') % err)
-            raise exception.VolumeBackendAPIException(data=err)
-        return logininfo
-
-    def _get_lun_set_info(self):
-        """Get parameters from config file for creating LUN."""
-        # Default LUN set information
-        lunsetinfo = {'LUNType': 'Thick',
-                      'StripUnitSize': '64',
-                      'WriteType': '1',
-                      'MirrorSwitch': '1',
-                      'PrefetchType': '3',
-                      'PrefetchValue': '0',
-                      'PrefetchTimes': '0',
-                      'StoragePool': 'RAID_001'}
-
-        root = self._read_xml()
-        try:
-            luntype = root.findtext('LUN/LUNType')
-            if luntype in ['Thick', 'Thin']:
-                lunsetinfo['LUNType'] = luntype
-            elif luntype:
-                err_msg = (_('Config file is wrong. LUNType must be "Thin" '
-                             ' or "Thick". LUNType:%(type)s')
-                           % {'type': luntype})
-                raise exception.VolumeBackendAPIException(data=err_msg)
-
-            # Here we do not judge whether the parameters are right.
-            # CLI will return error responses if the parameters not right.
-            stripunitsize = root.findtext('LUN/StripUnitSize')
-            if stripunitsize:
-                lunsetinfo['StripUnitSize'] = stripunitsize
-            writetype = root.findtext('LUN/WriteType')
-            if writetype:
-                lunsetinfo['WriteType'] = writetype
-            mirrorswitch = root.findtext('LUN/MirrorSwitch')
-            if mirrorswitch:
-                lunsetinfo['MirrorSwitch'] = mirrorswitch
-
-            if self.device_type['type'] == 'Tseries':
-                pooltype = lunsetinfo['LUNType']
-                prefetch = root.find('LUN/Prefetch')
-                if prefetch and prefetch.attrib['Type']:
-                    lunsetinfo['PrefetchType'] = prefetch.attrib['Type']
-                    if lunsetinfo['PrefetchType'] == '1':
-                        lunsetinfo['PrefetchValue'] = prefetch.attrib['Value']
-                    elif lunsetinfo['PrefetchType'] == '2':
-                        lunsetinfo['PrefetchTimes'] = prefetch.attrib['Value']
-                else:
-                    LOG.debug(_('_get_lun_set_info:Use default prefetch type. '
-                                'Prefetch type:Intelligent.'))
-
-            # No need to set Prefetch type for Dorado.
-            elif self.device_type['type'] == 'Dorado5100':
-                pooltype = 'Thick'
-            elif self.device_type['type'] == 'Dorado2100 G2':
-                return lunsetinfo
-
-            poolsinfo = self._find_pool_info(pooltype)
-            if not poolsinfo:
-                err_msg = (_('_get_lun_set_info:No available pools! '
-                             'Please check whether storage pool is created.'))
-                LOG.error(err_msg)
-                raise exception.VolumeBackendAPIException(data=err_msg)
-
-            pools = root.findall('LUN/StoragePool')
-            lunsetinfo['StoragePool'] = \
-                self._get_maximum_pool(pools, poolsinfo, luntype)
-
-        except Exception as err:
-            LOG.error(_('_get_lun_set_info:%s') % err)
-            raise exception.VolumeBackendAPIException(data=err)
-
-        return lunsetinfo
-
-    def _find_pool_info(self, pooltype):
-        """Return pools information created in storage device."""
-        if pooltype == 'Thick':
-            cli_cmd = ('showrg')
-        else:
-            cli_cmd = ('showpool')
-
-        out = self._execute_cli(cli_cmd)
-
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        pools_list = []
-        for i in range(6, len(en) - 2):
-            r = en[i].split()
-            pools_list.append(r)
-        return pools_list
-
-    def _get_maximum_pool(self, poolinconf, poolindev, luntype):
-        """Get the maximum pool from config file.
-
-        According to the given pools' name in config file,
-        we select the pool of maximum free capacity.
-        """
-        maxpoolid = None
-        maxpoolsize = 0
-        if luntype == 'Thin':
-            nameindex = 1
-            sizeindex = 4
-        else:
-            nameindex = 5
-            sizeindex = 3
-
-        for pool in poolinconf:
-            poolname = pool.attrib['Name']
-            for pooldetail in poolindev:
-                if pooldetail[nameindex] == poolname:
-                    if int(float(pooldetail[sizeindex])) > maxpoolsize:
-                        maxpoolid = pooldetail[0]
-                        maxpoolsize = int(float(pooldetail[sizeindex]))
-                    break
-        if maxpoolid is not None:
-            return maxpoolid
-        else:
-            err_msg = (_('_get_maximum_pool:maxpoolid is None. '
-                         'Please check config file and make sure '
-                         'the "Name" in "StoragePool" is right.'))
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _get_iscsi_info(self):
-        """Get iSCSI info from config file."""
-        iscsiinfo = {}
-        root = self._read_xml()
-        try:
-            iscsiinfo['DefaultTargetIP'] = \
-                root.findtext('iSCSI/DefaultTargetIP')
-            initiator_list = []
-            for dic in root.findall('iSCSI/Initiator'):
-                initiator_list.append(dic.attrib)
-            iscsiinfo['Initiator'] = initiator_list
-
-        except Exception as err:
-            LOG.error(_('_get_iscsi_info:%s') % str(err))
-
-        return iscsiinfo
-
-    def _execute_cli(self, cmd):
-        """Build SSH connection to execute CLI commands.
-
-        If the connection to first controller time out,
-        try to connect to the other controller.
-        """
-        LOG.debug(_('CLI command:%s') % cmd)
-        connect_times = 0
-        ip0 = self.login_info['ControllerIP0']
-        ip1 = self.login_info['ControllerIP1']
-        user = self.login_info['UserName']
-        pwd = self.login_info['UserPassword']
-        if not self.ssh_pool:
-            self.ssh_pool = SSHConn(ip0, 22, 30, user, pwd)
-        ssh_client = None
-        while True:
-            if connect_times == 1:
-                # Switch to the other controller.
-                self.ssh_pool.lock.acquire()
-                if ssh_client:
-                    if ssh_client.server_ip == self.ssh_pool.ip:
-                        if self.ssh_pool.ip == ip0:
-                            self.ssh_pool.ip = ip1
-                        else:
-                            self.ssh_pool.ip = ip0
-                    # Create a new client.
-                    if ssh_client.chan:
-                        ssh_client.chan.close()
-                        ssh_client.chan = None
-                        ssh_client.server_ip = None
-                        ssh_client.close()
-                        ssh_client = None
-                        ssh_client = self.ssh_pool.create()
-                else:
-                    self.ssh_pool.ip = ip1
-                self.ssh_pool.lock.release()
-            try:
-                if not ssh_client:
-                    ssh_client = self.ssh_pool.get()
-                # "server_ip" shows controller connecting with the ssh client.
-                if ('server_ip' not in ssh_client.__dict__ or
-                        not ssh_client.server_ip):
-                    self.ssh_pool.lock.acquire()
-                    ssh_client.server_ip = self.ssh_pool.ip
-                    self.ssh_pool.lock.release()
-                # An SSH client owns one "chan".
-                if ('chan' not in ssh_client.__dict__ or
-                        not ssh_client.chan):
-                    ssh_client.chan =\
-                        utils.create_channel(ssh_client, 600, 800)
-
-                while True:
-                    ssh_client.chan.send(cmd + '\n')
-                    out = self.ssh_pool.ssh_read(ssh_client.chan, cmd, 20)
-                    if out.find('(y/n)') > -1:
-                        cmd = 'y'
-                    else:
-                        break
-                self.ssh_pool.put(ssh_client)
-
-                index = out.find(user + ':/>')
-                if index > -1:
-                    return out[index:]
-                else:
-                    return out
-
-            except Exception as err:
-                if connect_times < 1:
-                    connect_times += 1
-                    continue
-                else:
-                    if ssh_client:
-                        self.ssh_pool.remove(ssh_client)
-                    LOG.error(_('_execute_cli:%s') % err)
-                    raise exception.VolumeBackendAPIException(data=err)
-
-    def _name_translate(self, name):
-        """Form new names because of the 32-character limit on names."""
-        newname = VOL_AND_SNAP_NAME_PREFIX + str(hash(name))
-
-        LOG.debug(_('_name_translate:Name in manila: %(old)s, '
-                    'new name in storage system: %(new)s')
-                  % {'old': name,
-                     'new': newname})
-
-        return newname
-
-    def _find_lun(self, name):
-        """Get the ID of a LUN with the given LUN name."""
-        cli_cmd = ('showlun')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        if 'Dorado2100 G2' == self.device_type['type']:
-            d = 2
-        elif 'Dorado5100' == self.device_type['type']:
-            d = 1
-        else:
-            d = 0
-
-        for i in range(6, len(en) - 2):
-            r = en[i].replace('Not format', 'Notformat').split()
-            if r[6 - d] == name:
-                return r[0]
-        return None
-
-    def _create_hostgroup(self, hostgroupname):
-        """Create a host group."""
-        cli_cmd = ('createhostgroup -n %(name)s'
-                   % {'name': hostgroupname})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_create_hostgroup:Failed to Create hostgroup. '
-                         'Hostgroup name: %(name)s. '
-                         'out:%(out)s.')
-                       % {'name': hostgroupname,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _find_hostgroup(self, groupname):
-        """Get the given hostgroup ID."""
-        cli_cmd = ('showhostgroup')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        for i in range(6, len(en) - 2):
-            r = en[i].split()
-            if r[1] == groupname:
-                return r[0]
-        return None
-
-    def _add_host(self, hostname, hostgroupid):
-        """Add a new host."""
-        cli_cmd = ('addhost -group %(groupid)s -n %(hostname)s -t 0'
-                   % {'groupid': hostgroupid,
-                      'hostname': hostname})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_add_host:Failed to add host to hostgroup. '
-                         'host name:%(host)s '
-                         'hostgroup id:%(hostgroup)s '
-                         'out:%(out)s')
-                       % {'host': hostname,
-                          'hostgroup': hostgroupid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _check_initiator(self, ininame):
-        """Check whether the initiator is already added."""
-        cli_cmd = ('showiscsiini -ini %(name)s'
-                   % {'name': ininame})
-        out = self._execute_cli(cli_cmd)
-        if out.find('Initiator Information') > -1:
-            return True
-        else:
-            return False
-
-    def _add_initiator(self, ininame):
-        """Add a new initiator to storage device."""
-        cli_cmd = ('addiscsiini -n %(name)s'
-                   % {'name': ininame})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_add_initiator:Failed to add initiator. '
-                         'initiator name:%(name)s '
-                         'out:%(out)s')
-                       % {'name': ininame,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _delete_initiator(self, ininame):
-        """Delete an initiator."""
-        cli_cmd = ('deliscsiini -n %(name)s'
-                   % {'name': ininame})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_delete_initiator:ERROE:Failed to delete initiator. '
-                         'initiator name:%(name)s '
-                         'out:%(out)s')
-                       % {'name': ininame,
-                          'out': out})
-            LOG.error(err_msg)
-
-    def _find_host_in_hostgroup(self, hostname, hostgroupid):
-        """Get the given host ID."""
-        cli_cmd = ('showhost -group %(groupid)s'
-                   % {'groupid': hostgroupid})
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) < 6:
-            return None
-
-        for i in range(6, len(en) - 2):
-            r = en[i].split()
-            if r[1] == hostname:
-                return r[0]
-        return None
-
-    def _get_hostport_info(self, hostid):
-        """Get hostports details of the given host."""
-        cli_cmd = ('showhostport -host %(hostid)s'
-                   % {'hostid': hostid})
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) < 6:
-            return None
-
-        hostportinfo = []
-        list_key = ['id', 'name', 'info', 'type', 'hostid',
-                    'linkstatus', 'multioathtype']
-        for i in range(6, len(en) - 2):
-            list_val = en[i].split()
-            hostport_dic = dict(map(None, list_key, list_val))
-            hostportinfo.append(hostport_dic)
-        return hostportinfo
-
-    def _add_hostport(self, portname, hostid, portinfo, multipathtype=0):
-        """Add a host port."""
-        cli_cmd = ('addhostport -host %(id)s -type 5 '
-                   '-info %(info)s -n %(name)s -mtype %(mtype)s'
-                   % {'id': hostid,
-                      'info': portinfo,
-                      'name': portname,
-                      'mtype': multipathtype})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_add_hostport:Failed to add hostport. '
-                         'port name:%(port)s '
-                         'port information:%(info)s '
-                         'host id:%(host)s '
-                         'out:%(out)s')
-                       % {'port': portname,
-                          'info': portinfo,
-                          'host': hostid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _delete_hostport(self, portid):
-        """Delete a host port."""
-        cli_cmd = ('delhostport -force -p %(portid)s'
-                   % {'portid': portid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_delete_hostport:Failed to delete host port. '
-                         'port id:%(portid)s')
-                       % {'portid': portid})
-            LOG.error(err_msg)
-
-    def _get_tgt_iqn(self, iscsiip):
-        """Get target iSCSI iqn."""
-        LOG.debug(_('_get_tgt_iqn:iSCSI IP is %s.') % iscsiip)
-        cli_cmd = ('showiscsitgtname')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) < 4:
-            return (None, None)
-
-        index = en[4].find('iqn')
-        iqn_prefix = en[4][index:]
-        iqn_prefix.strip()
-        iscsiip_info = self._get_iscsi_ip_info(iscsiip)
-        if iscsiip_info:
-            if iscsiip_info['ctrid'] == 'A':
-                ctr = '0'
-            elif iscsiip_info['ctrid'] == 'B':
-                ctr = '1'
-
-            interface = '0' + iscsiip_info['interfaceid']
-            port = iscsiip_info['portid'].replace('P', '0')
-            iqn_suffix = ctr + '02' + interface + port
-            for i in range(0, len(iqn_suffix)):
-                if iqn_suffix[i] != '0':
-                    iqn_suffix = iqn_suffix[i:]
-                    break
-            if self.device_type['type'] == 'Tseries':
-                iqn = iqn_prefix + ':' + iqn_suffix + ':' \
-                    + iscsiip_info['ipaddress']
-            elif self.device_type['type'] == "Dorado2100 G2":
-                iqn = iqn_prefix + ":" + iscsiip_info['ipaddress'] + "-" \
-                    + iqn_suffix
-            else:
-                iqn = iqn_prefix + ':' + iscsiip_info['ipaddress']
-
-            LOG.debug(_('_get_tgt_iqn:iSCSI target iqn is:%s') % iqn)
-
-            return (iqn, iscsiip_info['ctrid'])
-        else:
-            return (None, None)
-
-    def _get_iscsi_ip_info(self, iscsiip):
-        """Get iSCSI IP infomation of storage device."""
-        cli_cmd = ('showiscsiip')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) < 6:
-            return None
-
-        iscsiIPinfo = {}
-        for i in range(6, len(en) - 2):
-            r = en[i].split()
-            if r[3] == iscsiip:
-                iscsiIPinfo['ctrid'] = r[0]
-                iscsiIPinfo['interfaceid'] = r[1]
-                iscsiIPinfo['portid'] = r[2]
-                iscsiIPinfo['ipaddress'] = r[3]
-                return iscsiIPinfo
-        return None
-
-    def _map_lun(self, lunid, hostid, new_hostlun_id):
-        """Map a lun to a host.
-
-        Here we give the hostlun ID which starts from 1.
-        """
-        cli_cmd = ('addhostmap -host %(hostid)s -devlun %(lunid)s '
-                   '-hostlun %(hostlunid)s'
-                   % {'hostid': hostid,
-                      'lunid': lunid,
-                      'hostlunid': new_hostlun_id})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_map_lun:Failed to add hostmap. '
-                         'hostid:%(host)s '
-                         'lunid:%(lun)s '
-                         'hostlunid:%(hostlunid)s '
-                         'out:%(out)s')
-                       % {'host': hostid,
-                          'lun': lunid,
-                          'hostlunid': new_hostlun_id,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _get_hostlunid(self, hostid, lunid):
-        """Get the hostLUN ID of a LUN according host ID and LUN ID."""
-        mapinfo = self._get_map_info(hostid)
-        if mapinfo:
-            for map in mapinfo:
-                if map['devlunid'] == lunid:
-                    return map['hostlunid']
-        return None
-
-    def _delete_map(self, mapid, attempts=1):
-        """Remove the map."""
-        cli_cmd = ('delhostmap -force -map %(mapid)s'
-                   % {'mapid': mapid})
-        while attempts >= 0:
-            attempts -= 1
-            out = self._execute_cli(cli_cmd)
-
-            # We retry to delete host map 10s later if there are
-            # IOs accessing the system.
-            if re.search('command operates successfully', out):
-                break
-            else:
-                if re.search('there are IOs accessing the system', out):
-                    time.sleep(10)
-                    LOG.debug(_('_delete_map:There are IOs accessing '
-                                'the system. Retry to delete host map. '
-                                'map id:%(mapid)s')
-                              % {'mapid': mapid})
-                    continue
-                else:
-                    err_msg = (_('_delete_map:Failed to delete host map.'
-                                 ' mapid:%(mapid)s '
-                                 'out:%(out)s')
-                               % {'mapid': mapid,
-                                  'out': out})
-                    LOG.error(err_msg)
-                    raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _delete_host(self, hostid):
-        """Delete a host."""
-        cli_cmd = ('delhost -force -host %(hostid)s'
-                   % {'hostid': hostid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_delete_host: Failed delete host. '
-                         'host id:%(hostid)s '
-                         'out:%(out)s')
-                       % {'hostid': hostid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _get_map_info(self, hostid):
-        """Get map infomation of the given host.
-
-        This method return a map information list. Every item in the list
-        is a dictionary. The dictionary includes three keys: mapid,
-        devlunid, hostlunid. These items are sorted by hostlunid value
-        from small to large.
-        """
-        cli_cmd = ('showhostmap -host %(hostid)s'
-                   % {'hostid': hostid})
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        mapinfo = []
-        list_tmp = []
-        list_key = ['mapid', 'devlunid', 'hostlunid']
-        for i in range(6, len(en) - 2):
-            list_tmp = en[i].split()
-            list_val = [list_tmp[0], list_tmp[2], list_tmp[4]]
-            dic = dict(map(None, list_key, list_val))
-            inserted = False
-            mapinfo_length = len(mapinfo)
-            if mapinfo_length == 0:
-                mapinfo.append(dic)
-                continue
-            for index in range(0, mapinfo_length):
-                if (int(mapinfo[mapinfo_length - index - 1]['hostlunid']) <
-                        int(dic['hostlunid'])):
-                    mapinfo.insert(mapinfo_length - index, dic)
-                    inserted = True
-                    break
-            if not inserted:
-                mapinfo.insert(0, dic)
-        return mapinfo
-
-    def _get_device_type(self):
-        """Get the storage device type and product version."""
-        cli_cmd = ('showsys')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        for line in en:
-            if re.search('Device Type', line):
-                if re.search('T$', line):
-                    device_type = 'Tseries'
-                elif re.search('Dorado2100 G2$', line):
-                    device_type = 'Dorado2100 G2'
-                elif re.search('Dorado5100$', line):
-                    device_type = 'Dorado5100'
-                else:
-                    device_type = None
-                continue
-
-            if re.search('Product Version', line):
-                if re.search('V100R+', line):
-                    product_version = 'V100R'
-                else:
-                    product_version = None
-                break
-
-        r = {'type': device_type, 'version': product_version}
-        return r
-
-    def _active_snapshot(self, snapshotid):
-        """Active a snapshot."""
-        cli_cmd = ('actvsnapshot -snapshot %(snapshotid)s'
-                   % {'snapshotid': snapshotid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_active_snapshot:Failed to active snapshot. '
-                         'snapshot id:%(name)s. '
-                         'out:%(out)s')
-                       % {'name': snapshotid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _disable_snapshot(self, snapshotid):
-        """Disable a snapshot."""
-        cli_cmd = ('disablesnapshot -snapshot %(snapshotid)s'
-                   % {'snapshotid': snapshotid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_disable_snapshot:Failed to disable snapshot. '
-                         'snapshot id:%(id)s. '
-                         'out:%(out)s')
-                       % {'id': snapshotid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _delete_snapshot(self, snapshotid):
-        """Delete a snapshot."""
-        cli_cmd = ('delsnapshot -snapshot %(snapshotid)s'
-                   % {'snapshotid': snapshotid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_delete_snapshot:Failed to delete snapshot. '
-                         'snapshot id:%(id)s. '
-                         'out:%(out)s')
-                       % {'id': snapshotid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _create_volume(self, name, size):
-        """Create a new volume with the given name and size."""
-        lunsetinfo = self._get_lun_set_info()
-        cli_cmd = ('createlun -n %(name)s -lunsize %(size)s '
-                   '-wrtype %(wrtype)s '
-                   % {'name': name,
-                      'size': size,
-                      'wrtype': lunsetinfo['WriteType']})
-
-        # If write type is "write through", no need to set mirror switch.
-        if lunsetinfo['WriteType'] != '2':
-            cli_cmd = cli_cmd + ('-mirrorsw %(mirrorsw)s '
-                                 % {'mirrorsw': lunsetinfo['MirrorSwitch']})
-
-        # Differences exist between "Thin" and "thick" LUN for CLI commands.
-        luntype = lunsetinfo['LUNType']
-        if luntype == 'Thin':
-            dorado2100g2_luntype = '2'
-            Tseries = ('-pool %(pool)s '
-                       % {'pool': lunsetinfo['StoragePool']})
-        else:
-            dorado2100g2_luntype = '3'
-            Tseries = ('-rg %(raidgroup)s -susize %(susize)s '
-                       % {'raidgroup': lunsetinfo['StoragePool'],
-                          'susize': lunsetinfo['StripUnitSize']})
-
-        prefetch_value_or_times = ''
-        pretype = '-pretype %s ' % lunsetinfo['PrefetchType']
-        # If constant prefetch, we should set prefetch value.
-        if lunsetinfo['PrefetchType'] == '1':
-            prefetch_value_or_times = '-value %s' % lunsetinfo['PrefetchValue']
-        # If variable prefetch, we should set prefetch mutiple.
-        elif lunsetinfo['PrefetchType'] == '2':
-            prefetch_value_or_times = '-times %s' % lunsetinfo['PrefetchTimes']
-
-        if self.device_type['type'] == 'Tseries':
-            cli_cmd = cli_cmd + Tseries + pretype + prefetch_value_or_times
-
-        elif self.device_type['type'] == 'Dorado5100':
-            cli_cmd = cli_cmd + ('-rg %(raidgroup)s -susize %(susize)s'
-                                 % {'raidgroup': lunsetinfo['StoragePool'],
-                                    'susize': lunsetinfo['StripUnitSize']})
-
-        elif self.device_type['type'] == 'Dorado2100 G2':
-            cli_cmd = cli_cmd + ('-type %(type)s'
-                                 % {'type': dorado2100g2_luntype})
-
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_create_volume:Failed to Create volume. '
-                         'volume name:%(name)s. '
-                         'out:%(out)s')
-                       % {'name': name,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _delete_volume(self, name, lunid):
-        """Delete a volume."""
-        cli_cmd = ('dellun -force -lun %s' % (lunid))
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_delete_volume:Failed to delete volume. '
-                         'Volume name:%(name)s '
-                         'out:%(out)s')
-                       % {'name': name,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _create_luncopy(self, luncopyname, srclunid, tgtlunid):
-        """Create a LUNcopy."""
-        cli_cmd = ('createluncopy -n %(name)s -l 4 -slun %(srclunid)s '
-                   '-tlun %(tgtlunid)s'
-                   % {'name': luncopyname,
-                      'srclunid': srclunid,
-                      'tgtlunid': tgtlunid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_create_luncopy:Failed to Create LUNcopy. '
-                         'LUNcopy name:%(name)s '
-                         'out:%(out)s')
-                       % {'name': luncopyname,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _start_luncopy(self, luncopyid):
-        """Starte a LUNcopy."""
-        cli_cmd = ('chgluncopystatus -luncopy %(luncopyid)s -start'
-                   % {'luncopyid': luncopyid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_start_luncopy:Failed to start LUNcopy. '
-                         'LUNcopy id:%(luncopyid)s '
-                         'out:%(out)s')
-                       % {'luncopyid': luncopyid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _find_luncopy(self, luncopyname):
-        """Get the given LUNcopy's ID."""
-        cli_cmd = ('showluncopy')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        for i in range(6, len(en) - 2):
-            r = en[i].split()
-            if r[0] == luncopyname:
-                luncopyid = r[1]
-                return luncopyid
-        return None
-
-    def _wait_for_luncopy(self, luncopyname):
-        """Wait for LUNcopy to complete."""
-        while True:
-            luncopy_info = self._get_luncopy_info(luncopyname)
-            if luncopy_info['state'] == 'Complete':
-                break
-            elif luncopy_info['status'] != 'Normal':
-                err_msg = (_('_wait_for_luncopy:LUNcopy status is not normal. '
-                             'LUNcopy name:%(luncopyname)s')
-                           % {'luncopyname': luncopyname})
-                LOG.error(err_msg)
-                raise exception.VolumeBackendAPIException(data=err_msg)
-
-            time.sleep(10)
-
-    def _get_luncopy_info(self, luncopyname):
-        """Get LUNcopy information."""
-        cli_cmd = ('showluncopy')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        luncopyinfo = {}
-        for i in range(6, len(en) - 2):
-            r = en[i].split()
-            if r[0] == luncopyname:
-                luncopyinfo['name'] = r[0]
-                luncopyinfo['id'] = r[1]
-                luncopyinfo['state'] = r[3]
-                luncopyinfo['status'] = r[4]
-                return luncopyinfo
-        return None
-
-    def _delete_luncopy(self, luncopyid):
-        """Delete a LUNcopy."""
-        cli_cmd = ('delluncopy -luncopy %(id)s'
-                   % {'id': luncopyid})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_delete_luncopy:Failed to delete LUNcopy. '
-                         'LUNcopy id:%(luncopyid)s '
-                         'out:%(out)s')
-                       % {'luncopyid': luncopyid,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _create_snapshot(self, snapshotname, srclunid):
-        """Create a snapshot with snapshot name and source LUN ID."""
-        cli_cmd = ('createsnapshot -lun %(lunid)s -n %(snapname)s'
-                   % {'lunid': srclunid,
-                      'snapname': snapshotname})
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_create_snapshot:Failed to Create snapshot. '
-                         'Snapshot name:%(name)s '
-                         'out:%(out)s')
-                       % {'name': snapshotname,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _find_snapshot(self, snapshotname):
-        """Get the given snapshot ID."""
-        cli_cmd = ('showsnapshot')
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 6:
-            return None
-
-        for i in range(6, len(en) - 2):
-            r = en[i].split()
-            if r[0] == snapshotname:
-                return r[1]
-        return None
-
-    def _get_lun_controller(self, lun_id):
-        cli_cmd = ('showlun -lun %s' % lun_id)
-        out = self._execute_cli(cli_cmd)
-        en = out.split('\r\n')
-        if len(en) <= 4:
-            return None
-
-        if "Dorado2100 G2" == self.device_type['type']:
-            return en[10].split()[3]
-        else:
-            return en[12].split()[3]
-
-    def _change_lun_controller(self, lun_id, controller):
-        cli_cmd = ('chglun -lun %s -c %s' % (lun_id, controller))
-        out = self._execute_cli(cli_cmd)
-        if not re.search('command operates successfully', out):
-            err_msg = (_('_change_lun_controller:Failed to change lun owning '
-                         'controller. lun id:%(lunid)s. '
-                         'new controller:%(controller)s. '
-                         'out:%(out)s')
-                       % {'lunid': lun_id,
-                          'controller': controller,
-                          'out': out})
-            LOG.error(err_msg)
-            raise exception.VolumeBackendAPIException(data=err_msg)
-
-    def _is_resource_pool_enough(self):
-        """Check whether resource pools' valid size is more than 1G."""
-        cli_cmd = ('showrespool')
-        out = self._execute_cli(cli_cmd)
-        en = re.split('\r\n', out)
-        if len(en) <= 6:
-            LOG.error(_('_is_resource_pool_enough:Resource pool for snapshot '
-                        'not be added.'))
-            return False
-        resource_pools = []
-        list_key = ['pool id', 'size', 'usage', 'valid size',
-                    'alarm threshold']
-        for i in range(6, len(en) - 2):
-            list_val = en[i].split()
-            dic = dict(map(None, list_key, list_val))
-            resource_pools.append(dic)
-
-        for pool in resource_pools:
-            if float(pool['valid size']) < 1024.0:
-                return False
-        return True
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'HuaweiISCSIDriver'
-        data['vendor_name'] = 'Huawei'
-        data['driver_version'] = '1.0'
-        data['storage_protocol'] = 'iSCSI'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = self._get_free_capacity()
-        data['reserved_percentage'] = 0
-
-        self._stats = data
-
-    def _get_free_capacity(self):
-        """Get total free capacity of pools."""
-        self.login_info = self._get_login_info()
-        root = self._read_xml()
-        lun_type = root.findtext('LUN/LUNType')
-        if self.device_type['type'] == 'Dorado2100 G2':
-            lun_type = 'Thin'
-        elif (self.device_type['type'] == 'Dorado5100' or not lun_type):
-            lun_type = 'Thick'
-        poolinfo_dev = self._find_pool_info(lun_type)
-        pools_conf = root.findall('LUN/StoragePool')
-        total_free_capacity = 0.0
-        for poolinfo in poolinfo_dev:
-            if self.device_type['type'] == 'Dorado2100 G2':
-                total_free_capacity += float(poolinfo[2])
-                continue
-            for pool in pools_conf:
-                if ((self.device_type['type'] == 'Dorado5100') and
-                        (poolinfo[5] == pool.attrib['Name'])):
-                    total_free_capacity += float(poolinfo[3])
-                    break
-                else:
-                    if ((lun_type == 'Thick') and
-                            (poolinfo[5] == pool.attrib['Name'])):
-                        total_free_capacity += float(poolinfo[3])
-                        break
-                    elif poolinfo[1] == pool.attrib['Name']:
-                        total_free_capacity += float(poolinfo[4])
-                        break
-
-        return total_free_capacity / 1024
diff --git a/manila/volume/drivers/lvm.py b/manila/volume/drivers/lvm.py
deleted file mode 100644
index e7d24bd065..0000000000
--- a/manila/volume/drivers/lvm.py
+++ /dev/null
@@ -1,688 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Driver for Linux servers running LVM.
-
-"""
-
-import math
-import os
-import re
-
-from oslo.config import cfg
-
-from manila.brick.iscsi import iscsi
-from manila import exception
-from manila import flags
-from manila.image import image_utils
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume import driver
-
-LOG = logging.getLogger(__name__)
-
-volume_opts = [
-    cfg.StrOpt('volume_group',
-               default='manila-volumes',
-               help='Name for the VG that will contain exported volumes'),
-    cfg.StrOpt('volume_clear',
-               default='zero',
-               help='Method used to wipe old volumes (valid options are: '
-                    'none, zero, shred)'),
-    cfg.IntOpt('volume_clear_size',
-               default=0,
-               help='Size in MiB to wipe at start of old volumes. 0 => all'),
-    cfg.StrOpt('volume_dd_blocksize',
-               default='1M',
-               help='The default block size used when clearing volumes'),
-    cfg.StrOpt('pool_size',
-               default=None,
-               help='Size of thin provisioning pool '
-                    '(None uses entire manila VG)'),
-    cfg.IntOpt('lvm_mirrors',
-               default=0,
-               help='If set, create lvms with multiple mirrors. Note that '
-                    'this requires lvm_mirrors + 2 pvs with available space'),
-]
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(volume_opts)
-
-
-class LVMVolumeDriver(driver.VolumeDriver):
-    """Executes commands relating to Volumes."""
-
-    VERSION = '1.0'
-
-    def __init__(self, *args, **kwargs):
-        super(LVMVolumeDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(volume_opts)
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met"""
-        out, err = self._execute('vgs', '--noheadings', '-o', 'name',
-                                 run_as_root=True)
-        volume_groups = out.split()
-        if self.configuration.volume_group not in volume_groups:
-            exception_message = (_("volume group %s doesn't exist")
-                                 % self.configuration.volume_group)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-    def _create_volume(self, volume_name, sizestr):
-        cmd = ['lvcreate', '-L', sizestr, '-n', volume_name,
-               self.configuration.volume_group]
-        if self.configuration.lvm_mirrors:
-            cmd += ['-m', self.configuration.lvm_mirrors, '--nosync']
-            terras = int(sizestr[:-1]) / 1024.0
-            if terras >= 1.5:
-                rsize = int(2 ** math.ceil(math.log(terras) / math.log(2)))
-                # NOTE(vish): Next power of two for region size. See:
-                #             http://red.ht/U2BPOD
-                cmd += ['-R', str(rsize)]
-
-        self._try_execute(*cmd, run_as_root=True)
-
-    def _copy_volume(self, srcstr, deststr, size_in_g, clearing=False):
-        # Use O_DIRECT to avoid thrashing the system buffer cache
-        extra_flags = ['iflag=direct', 'oflag=direct']
-
-        # Check whether O_DIRECT is supported
-        try:
-            self._execute('dd', 'count=0', 'if=%s' % srcstr, 'of=%s' % deststr,
-                          *extra_flags, run_as_root=True)
-        except exception.ProcessExecutionError:
-            extra_flags = []
-
-        # If the volume is being unprovisioned then
-        # request the data is persisted before returning,
-        # so that it's not discarded from the cache.
-        if clearing and not extra_flags:
-            extra_flags.append('conv=fdatasync')
-
-        # Perform the copy
-        self._execute('dd', 'if=%s' % srcstr, 'of=%s' % deststr,
-                      'count=%d' % (size_in_g * 1024),
-                      'bs=%s' % self.configuration.volume_dd_blocksize,
-                      *extra_flags, run_as_root=True)
-
-    def _volume_not_present(self, volume_name):
-        path_name = '%s/%s' % (self.configuration.volume_group, volume_name)
-        try:
-            self._try_execute('lvdisplay', path_name, run_as_root=True)
-        except Exception as e:
-            # If the volume isn't present
-            return True
-        return False
-
-    def _delete_volume(self, volume, size_in_g):
-        """Deletes a logical volume."""
-        # zero out old volumes to prevent data leaking between users
-        # TODO(ja): reclaiming space should be done lazy and low priority
-        dev_path = self.local_path(volume)
-        if os.path.exists(dev_path):
-            self.clear_volume(volume)
-
-        self._try_execute('lvremove', '-f', "%s/%s" %
-                          (self.configuration.volume_group,
-                           self._escape_snapshot(volume['name'])),
-                          run_as_root=True)
-
-    def _sizestr(self, size_in_g):
-        if int(size_in_g) == 0:
-            return '100M'
-        return '%sG' % size_in_g
-
-    # Linux LVM reserves name that starts with snapshot, so that
-    # such volume name can't be created. Mangle it.
-    def _escape_snapshot(self, snapshot_name):
-        if not snapshot_name.startswith('snapshot'):
-            return snapshot_name
-        return '_' + snapshot_name
-
-    def create_volume(self, volume):
-        """Creates a logical volume. Can optionally return a Dictionary of
-        changes to the volume object to be persisted."""
-        self._create_volume(volume['name'], self._sizestr(volume['size']))
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-        self._create_volume(volume['name'], self._sizestr(volume['size']))
-        self._copy_volume(self.local_path(snapshot), self.local_path(volume),
-                          snapshot['volume_size'])
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-        if self._volume_not_present(volume['name']):
-            # If the volume isn't present, then don't attempt to delete
-            return True
-
-        # TODO(yamahata): lvm can't delete origin volume only without
-        # deleting derived snapshots. Can we do something fancy?
-        out, err = self._execute('lvdisplay', '--noheading',
-                                 '-C', '-o', 'Attr',
-                                 '%s/%s' % (self.configuration.volume_group,
-                                            volume['name']),
-                                 run_as_root=True)
-        # fake_execute returns None resulting unit test error
-        if out:
-            out = out.strip()
-            if (out[0] == 'o') or (out[0] == 'O'):
-                raise exception.VolumeIsBusy(volume_name=volume['name'])
-
-        self._delete_volume(volume, volume['size'])
-
-    def clear_volume(self, volume):
-        """unprovision old volumes to prevent data leaking between users."""
-
-        vol_path = self.local_path(volume)
-        size_in_g = volume.get('size')
-        size_in_m = self.configuration.volume_clear_size
-
-        if not size_in_g:
-            LOG.warning(_("Size for volume: %s not found, "
-                          "skipping secure delete.") % volume['name'])
-            return
-
-        if self.configuration.volume_clear == 'none':
-            return
-
-        LOG.info(_("Performing secure delete on volume: %s") % volume['id'])
-
-        if self.configuration.volume_clear == 'zero':
-            if size_in_m == 0:
-                return self._copy_volume('/dev/zero',
-                                         vol_path, size_in_g,
-                                         clearing=True)
-            else:
-                clear_cmd = ['shred', '-n0', '-z', '-s%dMiB' % size_in_m]
-        elif self.configuration.volume_clear == 'shred':
-            clear_cmd = ['shred', '-n3']
-            if size_in_m:
-                clear_cmd.append('-s%dMiB' % size_in_m)
-        else:
-            LOG.error(_("Error unrecognized volume_clear option: %s"),
-                      self.configuration.volume_clear)
-            return
-
-        clear_cmd.append(vol_path)
-        self._execute(*clear_cmd, run_as_root=True)
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        orig_lv_name = "%s/%s" % (self.configuration.volume_group,
-                                  snapshot['volume_name'])
-        self._try_execute('lvcreate', '-L',
-                          self._sizestr(snapshot['volume_size']),
-                          '--name', self._escape_snapshot(snapshot['name']),
-                          '--snapshot', orig_lv_name, run_as_root=True)
-
-    def delete_snapshot(self, snapshot):
-        """Deletes a snapshot."""
-        if self._volume_not_present(self._escape_snapshot(snapshot['name'])):
-            # If the snapshot isn't present, then don't attempt to delete
-            LOG.warning(_("snapshot: %s not found, "
-                          "skipping delete operations") % snapshot['name'])
-            return True
-
-        # TODO(yamahata): zeroing out the whole snapshot triggers COW.
-        # it's quite slow.
-        self._delete_volume(snapshot, snapshot['volume_size'])
-
-    def local_path(self, volume):
-        # NOTE(vish): stops deprecation warning
-        escaped_group = self.configuration.volume_group.replace('-', '--')
-        escaped_name = self._escape_snapshot(volume['name']).replace('-', '--')
-        return "/dev/mapper/%s-%s" % (escaped_group, escaped_name)
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        image_utils.fetch_to_raw(context,
-                                 image_service,
-                                 image_id,
-                                 self.local_path(volume))
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        image_utils.upload_volume(context,
-                                  image_service,
-                                  image_meta,
-                                  self.local_path(volume))
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        LOG.info(_('Creating clone of volume: %s') % src_vref['id'])
-        volume_name = FLAGS.volume_name_template % src_vref['id']
-        temp_id = 'tmp-snap-%s' % src_vref['id']
-        temp_snapshot = {'volume_name': volume_name,
-                         'size': src_vref['size'],
-                         'volume_size': src_vref['size'],
-                         'name': 'clone-snap-%s' % src_vref['id'],
-                         'id': temp_id}
-        self.create_snapshot(temp_snapshot)
-        self._create_volume(volume['name'], self._sizestr(volume['size']))
-        try:
-            self._copy_volume(self.local_path(temp_snapshot),
-                              self.local_path(volume),
-                              src_vref['size'])
-        finally:
-            self.delete_snapshot(temp_snapshot)
-
-    def clone_image(self, volume, image_location):
-        return False
-
-    def backup_volume(self, context, backup, backup_service):
-        """Create a new backup from an existing volume."""
-        volume = self.db.volume_get(context, backup['volume_id'])
-        volume_path = self.local_path(volume)
-        with utils.temporary_chown(volume_path):
-            with utils.file_open(volume_path) as volume_file:
-                backup_service.backup(backup, volume_file)
-
-    def restore_backup(self, context, backup, volume, backup_service):
-        """Restore an existing backup to a new or existing volume."""
-        volume_path = self.local_path(volume)
-        with utils.temporary_chown(volume_path):
-            with utils.file_open(volume_path, 'wb') as volume_file:
-                backup_service.restore(backup, volume['id'], volume_file)
-
-
-class LVMISCSIDriver(LVMVolumeDriver, driver.ISCSIDriver):
-    """Executes commands relating to ISCSI volumes.
-
-    We make use of model provider properties as follows:
-
-    ``provider_location``
-      if present, contains the iSCSI target information in the same
-      format as an ietadm discovery
-      i.e. '<ip>:<port>,<portal> <target IQN>'
-
-    ``provider_auth``
-      if present, contains a space-separated triple:
-      '<auth method> <auth username> <auth password>'.
-      `CHAP` is the only auth_method in use at the moment.
-    """
-
-    def __init__(self, *args, **kwargs):
-        self.tgtadm = iscsi.get_target_admin()
-        super(LVMISCSIDriver, self).__init__(*args, **kwargs)
-
-    def set_execute(self, execute):
-        super(LVMISCSIDriver, self).set_execute(execute)
-        self.tgtadm.set_execute(execute)
-
-    def ensure_export(self, context, volume):
-        """Synchronously recreates an export for a logical volume."""
-        # NOTE(jdg): tgtadm doesn't use the iscsi_targets table
-        # TODO(jdg): In the future move all of the dependent stuff into the
-        # cooresponding target admin class
-
-        if isinstance(self.tgtadm, iscsi.LioAdm):
-            try:
-                volume_info = self.db.volume_get(context, volume['id'])
-                (auth_method,
-                 auth_user,
-                 auth_pass) = volume_info['provider_auth'].split(' ', 3)
-                chap_auth = self._iscsi_authentication(auth_method,
-                                                       auth_user,
-                                                       auth_pass)
-            except exception.NotFound:
-                LOG.debug("volume_info:", volume_info)
-                LOG.info(_("Skipping ensure_export. No iscsi_target "
-                           "provision for volume: %s"), volume['id'])
-                return
-
-            iscsi_name = "%s%s" % (FLAGS.iscsi_target_prefix, volume['name'])
-            volume_path = "/dev/%s/%s" % (FLAGS.volume_group, volume['name'])
-            iscsi_target = 1
-
-            self.tgtadm.create_iscsi_target(iscsi_name, iscsi_target,
-                                            0, volume_path, chap_auth,
-                                            check_exit_code=False)
-            return
-
-        if not isinstance(self.tgtadm, iscsi.TgtAdm):
-            try:
-                iscsi_target = self.db.volume_get_iscsi_target_num(
-                    context,
-                    volume['id'])
-            except exception.NotFound:
-                LOG.info(_("Skipping ensure_export. No iscsi_target "
-                           "provisioned for volume: %s"), volume['id'])
-                return
-        else:
-            iscsi_target = 1  # dummy value when using TgtAdm
-
-        chap_auth = None
-
-        # Check for https://bugs.launchpad.net/manila/+bug/1065702
-        old_name = None
-        volume_name = volume['name']
-        if (volume['provider_location'] is not None and
-                volume['name'] not in volume['provider_location']):
-
-            msg = _('Detected inconsistency in provider_location id')
-            LOG.debug(msg)
-            old_name = self._fix_id_migration(context, volume)
-            if 'in-use' in volume['status']:
-                volume_name = old_name
-                old_name = None
-
-        iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
-                               volume_name)
-        volume_path = "/dev/%s/%s" % (self.configuration.volume_group,
-                                      volume_name)
-
-        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
-        # should clean this all up at some point in the future
-        self.tgtadm.create_iscsi_target(iscsi_name, iscsi_target,
-                                        0, volume_path, chap_auth,
-                                        check_exit_code=False,
-                                        old_name=old_name)
-
-    def _fix_id_migration(self, context, volume):
-        """Fix provider_location and dev files to address bug 1065702.
-
-        For volumes that the provider_location has NOT been updated
-        and are not currently in-use we'll create a new iscsi target
-        and remove the persist file.
-
-        If the volume is in-use, we'll just stick with the old name
-        and when detach is called we'll feed back into ensure_export
-        again if necessary and fix things up then.
-
-        Details at: https://bugs.launchpad.net/manila/+bug/1065702
-        """
-
-        model_update = {}
-        pattern = re.compile(r":|\s")
-        fields = pattern.split(volume['provider_location'])
-        old_name = fields[3]
-
-        volume['provider_location'] = \
-            volume['provider_location'].replace(old_name, volume['name'])
-        model_update['provider_location'] = volume['provider_location']
-
-        self.db.volume_update(context, volume['id'], model_update)
-
-        start = os.getcwd()
-        os.chdir('/dev/%s' % self.configuration.volume_group)
-
-        try:
-            (out, err) = self._execute('readlink', old_name)
-        except exception.ProcessExecutionError:
-            link_path = '/dev/%s/%s' % (self.configuration.volume_group,
-                                        old_name)
-            LOG.debug(_('Symbolic link %s not found') % link_path)
-            os.chdir(start)
-            return
-
-        rel_path = out.rstrip()
-        self._execute('ln',
-                      '-s',
-                      rel_path, volume['name'],
-                      run_as_root=True)
-        os.chdir(start)
-        return old_name
-
-    def _ensure_iscsi_targets(self, context, host):
-        """Ensure that target ids have been created in datastore."""
-        # NOTE(jdg): tgtadm doesn't use the iscsi_targets table
-        # TODO(jdg): In the future move all of the dependent stuff into the
-        # cooresponding target admin class
-        if not isinstance(self.tgtadm, iscsi.TgtAdm):
-            host_iscsi_targets = self.db.iscsi_target_count_by_host(context,
-                                                                    host)
-            if host_iscsi_targets >= self.configuration.iscsi_num_targets:
-                return
-
-            # NOTE(vish): Target ids start at 1, not 0.
-            target_end = self.configuration.iscsi_num_targets + 1
-            for target_num in xrange(1, target_end):
-                target = {'host': host, 'target_num': target_num}
-                self.db.iscsi_target_create_safe(context, target)
-
-    def create_export(self, context, volume):
-        """Creates an export for a logical volume."""
-
-        iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
-                               volume['name'])
-        volume_path = "/dev/%s/%s" % (self.configuration.volume_group,
-                                      volume['name'])
-        model_update = {}
-
-        # TODO(jdg): In the future move all of the dependent stuff into the
-        # cooresponding target admin class
-        if not isinstance(self.tgtadm, iscsi.TgtAdm):
-            lun = 0
-            self._ensure_iscsi_targets(context, volume['host'])
-            iscsi_target = self.db.volume_allocate_iscsi_target(context,
-                                                                volume['id'],
-                                                                volume['host'])
-        else:
-            lun = 1  # For tgtadm the controller is lun 0, dev starts at lun 1
-            iscsi_target = 0  # NOTE(jdg): Not used by tgtadm
-
-        # Use the same method to generate the username and the password.
-        chap_username = utils.generate_username()
-        chap_password = utils.generate_password()
-        chap_auth = self._iscsi_authentication('IncomingUser', chap_username,
-                                               chap_password)
-        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
-        # should clean this all up at some point in the future
-        tid = self.tgtadm.create_iscsi_target(iscsi_name,
-                                              iscsi_target,
-                                              0,
-                                              volume_path,
-                                              chap_auth)
-        model_update['provider_location'] = self._iscsi_location(
-            self.configuration.iscsi_ip_address, tid, iscsi_name, lun)
-        model_update['provider_auth'] = self._iscsi_authentication(
-            'CHAP', chap_username, chap_password)
-        return model_update
-
-    def remove_export(self, context, volume):
-        """Removes an export for a logical volume."""
-        # NOTE(jdg): tgtadm doesn't use the iscsi_targets table
-        # TODO(jdg): In the future move all of the dependent stuff into the
-        # cooresponding target admin class
-
-        if isinstance(self.tgtadm, iscsi.LioAdm):
-            try:
-                iscsi_target = self.db.volume_get_iscsi_target_num(
-                    context,
-                    volume['id'])
-            except exception.NotFound:
-                LOG.info(_("Skipping remove_export. No iscsi_target "
-                           "provisioned for volume: %s"), volume['id'])
-                return
-
-            self.tgtadm.remove_iscsi_target(iscsi_target, 0, volume['id'])
-
-            return
-
-        elif not isinstance(self.tgtadm, iscsi.TgtAdm):
-            try:
-                iscsi_target = self.db.volume_get_iscsi_target_num(
-                    context,
-                    volume['id'])
-            except exception.NotFound:
-                LOG.info(_("Skipping remove_export. No iscsi_target "
-                           "provisioned for volume: %s"), volume['id'])
-                return
-        else:
-            iscsi_target = 0
-
-        try:
-
-            # NOTE: provider_location may be unset if the volume hasn't
-            # been exported
-            location = volume['provider_location'].split(' ')
-            iqn = location[1]
-
-            # ietadm show will exit with an error
-            # this export has already been removed
-            self.tgtadm.show_target(iscsi_target, iqn=iqn)
-
-        except Exception as e:
-            LOG.info(_("Skipping remove_export. No iscsi_target "
-                       "is presently exported for volume: %s"), volume['id'])
-            return
-
-        self.tgtadm.remove_iscsi_target(iscsi_target, 0, volume['id'])
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-
-        # Note(zhiteng): These information are driver/backend specific,
-        # each driver may define these values in its own config options
-        # or fetch from driver specific configuration file.
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'LVM_iSCSI'
-        data["vendor_name"] = 'Open Source'
-        data["driver_version"] = self.VERSION
-        data["storage_protocol"] = 'iSCSI'
-
-        data['total_capacity_gb'] = 0
-        data['free_capacity_gb'] = 0
-        data['reserved_percentage'] = self.configuration.reserved_percentage
-        data['QoS_support'] = False
-
-        try:
-            out, err = self._execute('vgs', '--noheadings', '--nosuffix',
-                                     '--unit=G', '-o', 'name,size,free',
-                                     self.configuration.volume_group,
-                                     run_as_root=True)
-        except exception.ProcessExecutionError as exc:
-            LOG.error(_("Error retrieving volume status: "), exc.stderr)
-            out = False
-
-        if out:
-            volume = out.split()
-            data['total_capacity_gb'] = float(volume[1].replace(',', '.'))
-            data['free_capacity_gb'] = float(volume[2].replace(',', '.'))
-
-        self._stats = data
-
-    def _iscsi_location(self, ip, target, iqn, lun=None):
-        return "%s:%s,%s %s %s" % (ip, self.configuration.iscsi_port,
-                                   target, iqn, lun)
-
-    def _iscsi_authentication(self, chap, name, password):
-        return "%s %s %s" % (chap, name, password)
-
-
-class ThinLVMVolumeDriver(LVMISCSIDriver):
-    """Subclass for thin provisioned LVM's."""
-
-    VERSION = '1.0'
-
-    def __init__(self, *args, **kwargs):
-        super(ThinLVMVolumeDriver, self).__init__(*args, **kwargs)
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met"""
-        out, err = self._execute('lvs', '--option',
-                                 'name', '--noheadings',
-                                 run_as_root=True)
-        pool_name = "%s-pool" % FLAGS.volume_group
-        if pool_name not in out:
-            if not FLAGS.pool_size:
-                out, err = self._execute('vgs', FLAGS.volume_group,
-                                         '--noheadings', '--options',
-                                         'name,size', run_as_root=True)
-                size = re.sub(r'[\.][\d][\d]', '', out.split()[1])
-            else:
-                size = "%s" % FLAGS.pool_size
-
-            pool_path = '%s/%s' % (FLAGS.volume_group, pool_name)
-            out, err = self._execute('lvcreate', '-T', '-L', size,
-                                     pool_path, run_as_root=True)
-
-    def _do_lvm_snapshot(self, src_lvm_name, dest_vref, is_cinder_snap=True):
-            if is_cinder_snap:
-                new_name = self._escape_snapshot(dest_vref['name'])
-            else:
-                new_name = dest_vref['name']
-
-            self._try_execute('lvcreate', '-s', '-n', new_name,
-                              src_lvm_name, run_as_root=True)
-
-    def create_volume(self, volume):
-        """Creates a logical volume. Can optionally return a Dictionary of
-        changes to the volume object to be persisted."""
-        sizestr = self._sizestr(volume['size'])
-        vg_name = ("%s/%s-pool" % (FLAGS.volume_group, FLAGS.volume_group))
-        self._try_execute('lvcreate', '-T', '-V', sizestr, '-n',
-                          volume['name'], vg_name, run_as_root=True)
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-        if self._volume_not_present(volume['name']):
-            return True
-        self._try_execute('lvremove', '-f', "%s/%s" %
-                          (FLAGS.volume_group,
-                           self._escape_snapshot(volume['name'])),
-                          run_as_root=True)
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        LOG.info(_('Creating clone of volume: %s') % src_vref['id'])
-        orig_lv_name = "%s/%s" % (FLAGS.volume_group, src_vref['name'])
-        self._do_lvm_snapshot(orig_lv_name, volume, False)
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot of a volume."""
-        orig_lv_name = "%s/%s" % (FLAGS.volume_group, snapshot['volume_name'])
-        self._do_lvm_snapshot(orig_lv_name, snapshot)
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or self.__class__.__name__
-        data["vendor_name"] = 'Open Source'
-        data["driver_version"] = self.VERSION
-        data["storage_protocol"] = 'iSCSI'
-        data['reserved_percentage'] = self.configuration.reserved_percentage
-        data['QoS_support'] = False
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        self._stats = data
diff --git a/manila/volume/drivers/netapp/__init__.py b/manila/volume/drivers/netapp/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/manila/volume/drivers/netapp/api.py b/manila/volume/drivers/netapp/api.py
deleted file mode 100644
index 94b84b7b26..0000000000
--- a/manila/volume/drivers/netapp/api.py
+++ /dev/null
@@ -1,410 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 NetApp, Inc.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-NetApp api for ONTAP and OnCommand DFM.
-
-Contains classes required to issue api calls to ONTAP and OnCommand DFM.
-"""
-
-from lxml import etree
-import urllib2
-
-from manila.openstack.common import log as logging
-
-LOG = logging.getLogger(__name__)
-
-
-class NaServer(object):
-    """Encapsulates server connection logic."""
-
-    TRANSPORT_TYPE_HTTP = 'http'
-    TRANSPORT_TYPE_HTTPS = 'https'
-    SERVER_TYPE_FILER = 'filer'
-    SERVER_TYPE_DFM = 'dfm'
-    URL_FILER = 'servlets/netapp.servlets.admin.XMLrequest_filer'
-    URL_DFM = 'apis/XMLrequest'
-    NETAPP_NS = 'http://www.netapp.com/filer/admin'
-    STYLE_LOGIN_PASSWORD = 'basic_auth'
-    STYLE_CERTIFICATE = 'certificate_auth'
-
-    def __init__(self, host, server_type=SERVER_TYPE_FILER,
-                 transport_type=TRANSPORT_TYPE_HTTP,
-                 style=STYLE_LOGIN_PASSWORD, username=None,
-                 password=None):
-        self._host = host
-        self.set_server_type(server_type)
-        self.set_transport_type(transport_type)
-        self.set_style(style)
-        self._username = username
-        self._password = password
-        self._refresh_conn = True
-
-    def get_transport_type(self):
-        """Get the transport type protocol."""
-        return self._protocol
-
-    def set_transport_type(self, transport_type):
-        """Set the transport type protocol for api.
-
-        Supports http and https transport types.
-        """
-        if transport_type.lower() not in (
-                NaServer.TRANSPORT_TYPE_HTTP,
-                NaServer.TRANSPORT_TYPE_HTTPS):
-            raise ValueError('Unsupported transport type')
-        self._protocol = transport_type.lower()
-        if self._protocol == NaServer.TRANSPORT_TYPE_HTTP:
-            if self._server_type == NaServer.SERVER_TYPE_FILER:
-                self.set_port(80)
-            else:
-                self.set_port(8088)
-        else:
-            if self._server_type == NaServer.SERVER_TYPE_FILER:
-                self.set_port(443)
-            else:
-                self.set_port(8488)
-        self._refresh_conn = True
-
-    def get_style(self):
-        """Get the authorization style for communicating with the server."""
-        return self._auth_style
-
-    def set_style(self, style):
-        """Set the authorization style for communicating with the server.
-
-        Supports basic_auth for now. Certificate_auth mode to be done.
-        """
-        if style.lower() not in (NaServer.STYLE_LOGIN_PASSWORD,
-                                 NaServer.STYLE_CERTIFICATE):
-            raise ValueError('Unsupported authentication style')
-        self._auth_style = style.lower()
-
-    def get_server_type(self):
-        """Get the target server type."""
-        return self._server_type
-
-    def set_server_type(self, server_type):
-        """Set the target server type.
-
-        Supports filer and dfm server types.
-        """
-        if server_type.lower() not in (NaServer.SERVER_TYPE_FILER,
-                                       NaServer.SERVER_TYPE_DFM):
-            raise ValueError('Unsupported server type')
-        self._server_type = server_type.lower()
-        if self._server_type == NaServer.SERVER_TYPE_FILER:
-            self._url = NaServer.URL_FILER
-        else:
-            self._url = NaServer.URL_DFM
-        self._ns = NaServer.NETAPP_NS
-        self._refresh_conn = True
-
-    def set_api_version(self, major, minor):
-        """Set the api version."""
-        try:
-            self._api_major_version = int(major)
-            self._api_minor_version = int(minor)
-            self._api_version = str(major) + "." + str(minor)
-        except ValueError:
-            raise ValueError('Major and minor versions must be integers')
-        self._refresh_conn = True
-
-    def get_api_version(self):
-        """Gets the api version."""
-        if hasattr(self, '_api_version'):
-            return self._api_version
-        return self._api_version
-
-    def set_port(self, port):
-        """Set the server communication port."""
-        try:
-            int(port)
-        except ValueError:
-            raise ValueError('Port must be integer')
-        self._port = str(port)
-        self._refresh_conn = True
-
-    def get_port(self):
-        """Get the server communication port."""
-        return self._port
-
-    def set_timeout(self, seconds):
-        """Sets the timeout in seconds."""
-        try:
-            self._timeout = int(seconds)
-        except ValueError:
-            raise ValueError('timeout in seconds must be integer')
-
-    def get_timeout(self):
-        """Gets the timeout in seconds if set."""
-        if hasattr(self, '_timeout'):
-            return self._timeout
-        return None
-
-    def get_vfiler(self):
-        """Get the vfiler to use in tunneling."""
-        return self._vfiler
-
-    def set_vfiler(self, vfiler):
-        """Set the vfiler to use if tunneling gets enabled."""
-        self._vfiler = vfiler
-
-    def get_vserver(self):
-        """Get the vserver to use in tunneling."""
-        return self._vserver
-
-    def set_vserver(self, vserver):
-        """Set the vserver to use if tunneling gets enabled."""
-        self._vserver = vserver
-
-    def set_username(self, username):
-        """Set the user name for authentication."""
-        self._username = username
-        self._refresh_conn = True
-
-    def set_password(self, password):
-        """Set the password for authentication."""
-        self._password = password
-        self._refresh_conn = True
-
-    def invoke_elem(self, na_element, enable_tunneling=False):
-        """Invoke the api on the server."""
-        if na_element and not isinstance(na_element, NaElement):
-            ValueError('NaElement must be supplied to invoke api')
-        request = self._create_request(na_element, enable_tunneling)
-        if not hasattr(self, '_opener') or not self._opener \
-                or self._refresh_conn:
-            self._build_opener()
-        try:
-            if hasattr(self, '_timeout'):
-                response = self._opener.open(request, timeout=self._timeout)
-            else:
-                response = self._opener.open(request)
-        except urllib2.HTTPError as e:
-            raise NaApiError(e.code, e.msg)
-        except Exception as e:
-            raise NaApiError('Unexpected error', e)
-        xml = response.read()
-        return self._get_result(xml)
-
-    def invoke_successfully(self, na_element, enable_tunneling=False):
-        """Invokes api and checks execution status as success.
-
-        Need to set enable_tunneling to True explicitly to achieve it.
-        This helps to use same connection instance to enable or disable
-        tunneling. The vserver or vfiler should be set before this call
-        otherwise tunneling remains disabled.
-        """
-        result = self.invoke_elem(na_element, enable_tunneling)
-        if result.has_attr('status') and result.get_attr('status') == 'passed':
-            return result
-        code = result.get_attr('errno')\
-            or result.get_child_content('errorno')\
-            or 'ESTATUSFAILED'
-        msg = result.get_attr('reason')\
-            or result.get_child_content('reason')\
-            or 'Execution status is failed due to unknown reason'
-        raise NaApiError(code, msg)
-
-    def _create_request(self, na_element, enable_tunneling=False):
-        """Creates request in the desired format."""
-        netapp_elem = NaElement('netapp')
-        netapp_elem.add_attr('xmlns', self._ns)
-        if hasattr(self, '_api_version'):
-            netapp_elem.add_attr('version', self._api_version)
-        if enable_tunneling:
-            self._enable_tunnel_request(netapp_elem)
-        netapp_elem.add_child_elem(na_element)
-        request_d = netapp_elem.to_string()
-        request = urllib2.Request(
-            self._get_url(), data=request_d,
-            headers={'Content-Type': 'text/xml', 'charset': 'utf-8'})
-        return request
-
-    def _enable_tunnel_request(self, netapp_elem):
-        """Enables vserver or vfiler tunneling."""
-        if hasattr(self, '_vfiler') and self._vfiler:
-            if hasattr(self, '_api_major_version') and \
-                    hasattr(self, '_api_minor_version') and \
-                    self._api_major_version >= 1 and \
-                    self._api_minor_version >= 7:
-                netapp_elem.add_attr('vfiler', self._vfiler)
-            else:
-                raise ValueError('ontapi version has to be atleast 1.7'
-                                 ' to send request to vfiler')
-        if hasattr(self, '_vserver') and self._vserver:
-            if hasattr(self, '_api_major_version') and \
-                    hasattr(self, '_api_minor_version') and \
-                    self._api_major_version >= 1 and \
-                    self._api_minor_version >= 15:
-                netapp_elem.add_attr('vfiler', self._vserver)
-            else:
-                raise ValueError('ontapi version has to be atleast 1.15'
-                                 ' to send request to vserver')
-
-    def _parse_response(self, response):
-        """Get the NaElement for the response."""
-        if not response:
-            raise NaApiError('No response received')
-        xml = etree.XML(response)
-        return NaElement(xml)
-
-    def _get_result(self, response):
-        """Gets the call result."""
-        processed_response = self._parse_response(response)
-        return processed_response.get_child_by_name('results')
-
-    def _get_url(self):
-        return '%s://%s:%s/%s' % (self._protocol, self._host, self._port,
-                                  self._url)
-
-    def _build_opener(self):
-        if self._auth_style == NaServer.STYLE_LOGIN_PASSWORD:
-            auth_handler = self._create_basic_auth_handler()
-        else:
-            auth_handler = self._create_certificate_auth_handler()
-        opener = urllib2.build_opener(auth_handler)
-        self._opener = opener
-
-    def _create_basic_auth_handler(self):
-        password_man = urllib2.HTTPPasswordMgrWithDefaultRealm()
-        password_man.add_password(None, self._get_url(), self._username,
-                                  self._password)
-        auth_handler = urllib2.HTTPBasicAuthHandler(password_man)
-        return auth_handler
-
-    def _create_certificate_auth_handler(self):
-        raise NotImplementedError()
-
-
-class NaElement(object):
-    """Class wraps basic building block for NetApp api request."""
-
-    def __init__(self, name):
-        """Name of the element or etree.Element."""
-        if isinstance(name, etree._Element):
-            self._element = name
-        else:
-            self._element = etree.Element(name)
-
-    def get_name(self):
-        """Returns the tag name of the element."""
-        return self._element.tag
-
-    def set_content(self, text):
-        """Set the text for the element."""
-        self._element.text = text
-
-    def get_content(self):
-        """Get the text for the element."""
-        return self._element.text
-
-    def add_attr(self, name, value):
-        """Add the attribute to the element."""
-        self._element.set(name, value)
-
-    def add_attrs(self, **attrs):
-        """Add multiple attributes to the element."""
-        for attr in attrs.keys():
-            self._element.set(attr, attrs.get(attr))
-
-    def add_child_elem(self, na_element):
-        """Add the child element to the element."""
-        if isinstance(na_element, NaElement):
-            self._element.append(na_element._element)
-            return
-        raise
-
-    def get_child_by_name(self, name):
-        """Get the child element by the tag name."""
-        for child in self._element.iterchildren():
-            if child.tag == name or etree.QName(child.tag).localname == name:
-                return NaElement(child)
-        return None
-
-    def get_child_content(self, name):
-        """Get the content of the child."""
-        for child in self._element.iterchildren():
-            if child.tag == name or etree.QName(child.tag).localname == name:
-                return child.text
-        return None
-
-    def get_children(self):
-        """Get the children for the element."""
-        return [NaElement(el) for el in self._element.iterchildren()]
-
-    def has_attr(self, name):
-        """Checks whether element has attribute."""
-        attributes = self._element.attrib or {}
-        return name in attributes.keys()
-
-    def get_attr(self, name):
-        """Get the attribute with the given name."""
-        attributes = self._element.attrib or {}
-        return attributes.get(name)
-
-    def get_attr_names(self):
-        """Returns the list of attribute names."""
-        attributes = self._element.attrib or {}
-        return attributes.keys()
-
-    def add_new_child(self, name, content, convert=False):
-        """Add child with tag name and context.
-
-           Convert replaces entity refs to chars."""
-        child = NaElement(name)
-        if convert:
-            content = NaElement._convert_entity_refs(content)
-        child.set_content(content)
-        self.add_child_elem(child)
-
-    @staticmethod
-    def _convert_entity_refs(text):
-        """Converts entity refs to chars to handle etree auto conversions."""
-        text = text.replace("&lt;", "<")
-        text = text.replace("&gt;", ">")
-        return text
-
-    @staticmethod
-    def create_node_with_children(node, **children):
-        """Creates and returns named node with children."""
-        parent = NaElement(node)
-        for child in children.keys():
-            parent.add_new_child(child, children.get(child, None))
-        return parent
-
-    def add_node_with_children(self, node, **children):
-        """Creates named node with children."""
-        parent = NaElement.create_node_with_children(node, **children)
-        self.add_child_elem(parent)
-
-    def to_string(self, pretty=False, method='xml', encoding='UTF-8'):
-        """Prints the element to string."""
-        return etree.tostring(self._element, method=method, encoding=encoding,
-                              pretty_print=pretty)
-
-
-class NaApiError(Exception):
-    """Base exception class for NetApp api errors."""
-
-    def __init__(self, code='unknown', message='unknown'):
-        self.code = code
-        self.message = message
-
-    def __str__(self, *args, **kwargs):
-        return 'NetApp api failed. Reason - %s:%s' % (self.code, self.message)
diff --git a/manila/volume/drivers/netapp/iscsi.py b/manila/volume/drivers/netapp/iscsi.py
deleted file mode 100644
index 4e4613e35e..0000000000
--- a/manila/volume/drivers/netapp/iscsi.py
+++ /dev/null
@@ -1,2528 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 NetApp, Inc.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Volume driver for NetApp storage systems.
-
-This driver requires NetApp OnCommand 5.0 and one or more Data
-ONTAP 7-mode storage systems with installed iSCSI licenses.
-
-"""
-
-import time
-import uuid
-
-from oslo.config import cfg
-import suds
-from suds import client
-from suds.sax import text
-
-from manila import exception
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume import driver
-from manila.volume.drivers.netapp.api import NaApiError
-from manila.volume.drivers.netapp.api import NaElement
-from manila.volume.drivers.netapp.api import NaServer
-from manila.volume import volume_types
-
-LOG = logging.getLogger(__name__)
-
-netapp_opts = [
-    cfg.StrOpt('netapp_wsdl_url',
-               default=None,
-               help='URL of the WSDL file for the DFM/Webservice server'),
-    cfg.StrOpt('netapp_login',
-               default=None,
-               help='User name for the DFM/Controller server'),
-    cfg.StrOpt('netapp_password',
-               default=None,
-               help='Password for the DFM/Controller server',
-               secret=True),
-    cfg.StrOpt('netapp_server_hostname',
-               default=None,
-               help='Hostname for the DFM/Controller server'),
-    cfg.IntOpt('netapp_server_port',
-               default=8088,
-               help='Port number for the DFM/Controller server'),
-    cfg.StrOpt('netapp_storage_service',
-               default=None,
-               help=('Storage service to use for provisioning '
-                     '(when volume_type=None)')),
-    cfg.StrOpt('netapp_storage_service_prefix',
-               default=None,
-               help=('Prefix of storage service name to use for '
-                     'provisioning (volume_type name will be appended)')),
-    cfg.StrOpt('netapp_vfiler',
-               default=None,
-               help='Vfiler to use for provisioning'),
-    cfg.StrOpt('netapp_transport_type',
-               default='http',
-               help='Transport type protocol'),
-    cfg.StrOpt('netapp_vserver',
-               default='openstack',
-               help='Cluster vserver to use for provisioning'),
-    cfg.FloatOpt('netapp_size_multiplier',
-                 default=1.2,
-                 help='Volume size multiplier to ensure while creation'),
-    cfg.StrOpt('netapp_volume_list',
-               default='',
-               help='Comma separated eligible volumes for provisioning on'
-                    ' 7 mode'), ]
-
-
-class DfmDataset(object):
-    def __init__(self, id, name, project, type):
-        self.id = id
-        self.name = name
-        self.project = project
-        self.type = type
-
-
-class DfmLun(object):
-    def __init__(self, dataset, lunpath, id):
-        self.dataset = dataset
-        self.lunpath = lunpath
-        self.id = id
-
-
-class NetAppISCSIDriver(driver.ISCSIDriver):
-    """NetApp iSCSI volume driver."""
-
-    IGROUP_PREFIX = 'openstack-'
-    DATASET_PREFIX = 'OpenStack_'
-    DATASET_METADATA_PROJECT_KEY = 'OpenStackProject'
-    DATASET_METADATA_VOL_TYPE_KEY = 'OpenStackVolType'
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppISCSIDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(netapp_opts)
-        self.discovered_luns = []
-        self.discovered_datasets = []
-        self.lun_table = {}
-
-    def _check_fail(self, request, response):
-        """Utility routine to handle checking ZAPI failures."""
-        if 'failed' == response.Status:
-            name = request.Name
-            reason = response.Reason
-            msg = _('API %(name)s failed: %(reason)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-
-    def _create_client(self, **kwargs):
-        """Instantiate a web services client.
-
-        This method creates a "suds" client to make web services calls to the
-        DFM server. Note that the WSDL file is quite large and may take
-        a few seconds to parse.
-        """
-        wsdl_url = kwargs['wsdl_url']
-        LOG.debug(_('Using WSDL: %s') % wsdl_url)
-        if kwargs['cache']:
-            self.client = client.Client(wsdl_url, username=kwargs['login'],
-                                        password=kwargs['password'])
-        else:
-            self.client = client.Client(wsdl_url, username=kwargs['login'],
-                                        password=kwargs['password'],
-                                        cache=None)
-        soap_url = 'http://%s:%s/apis/soap/v1' % (kwargs['hostname'],
-                                                  kwargs['port'])
-        LOG.debug(_('Using DFM server: %s') % soap_url)
-        self.client.set_options(location=soap_url)
-
-    def _set_storage_service(self, storage_service):
-        """Set the storage service to use for provisioning."""
-        LOG.debug(_('Using storage service: %s') % storage_service)
-        self.storage_service = storage_service
-
-    def _set_storage_service_prefix(self, storage_service_prefix):
-        """Set the storage service prefix to use for provisioning."""
-        LOG.debug(_('Using storage service prefix: %s') %
-                  storage_service_prefix)
-        self.storage_service_prefix = storage_service_prefix
-
-    def _set_vfiler(self, vfiler):
-        """Set the vfiler to use for provisioning."""
-        LOG.debug(_('Using vfiler: %s') % vfiler)
-        self.vfiler = vfiler
-
-    def _check_flags(self):
-        """Ensure that the flags we care about are set."""
-        required_flags = ['netapp_wsdl_url', 'netapp_login', 'netapp_password',
-                          'netapp_server_hostname', 'netapp_server_port']
-        for flag in required_flags:
-            if not getattr(self.configuration, flag, None):
-                raise exception.InvalidInput(reason=_('%s is not set') % flag)
-        if not (self.configuration.netapp_storage_service or
-                self.configuration.netapp_storage_service_prefix):
-            raise exception.InvalidInput(
-                reason=_('Either '
-                         'netapp_storage_service or '
-                         'netapp_storage_service_prefix must '
-                         'be set'))
-
-    def do_setup(self, context):
-        """Setup the NetApp Volume driver.
-
-        Called one time by the manager after the driver is loaded.
-        Validate the flags we care about and setup the suds (web services)
-        client.
-        """
-        self._check_flags()
-        self._create_client(
-            wsdl_url=self.configuration.netapp_wsdl_url,
-            login=self.configuration.netapp_login,
-            password=self.configuration.netapp_password,
-            hostname=self.configuration.netapp_server_hostname,
-            port=self.configuration.netapp_server_port, cache=True)
-        self._set_storage_service(self.configuration.netapp_storage_service)
-        self._set_storage_service_prefix(
-            self.configuration.netapp_storage_service_prefix)
-        self._set_vfiler(self.configuration.netapp_vfiler)
-
-    def check_for_setup_error(self):
-        """Check that the driver is working and can communicate.
-
-        Invoke a web services API to make sure we can talk to the server.
-        Also perform the discovery of datasets and LUNs from DFM.
-        """
-        self.client.service.DfmAbout()
-        LOG.debug(_("Connected to DFM server"))
-        self._discover_luns()
-
-    def _get_datasets(self):
-        """Get the list of datasets from DFM."""
-        server = self.client.service
-        res = server.DatasetListInfoIterStart(IncludeMetadata=True)
-        tag = res.Tag
-        datasets = []
-        try:
-            while True:
-                res = server.DatasetListInfoIterNext(Tag=tag, Maximum=100)
-                if not res.Datasets:
-                    break
-                datasets.extend(res.Datasets.DatasetInfo)
-        finally:
-            server.DatasetListInfoIterEnd(Tag=tag)
-        return datasets
-
-    def _discover_dataset_luns(self, dataset, volume):
-        """Discover all of the LUNs in a dataset."""
-        server = self.client.service
-        res = server.DatasetMemberListInfoIterStart(
-            DatasetNameOrId=dataset.id,
-            IncludeExportsInfo=True,
-            IncludeIndirect=True,
-            MemberType='lun_path')
-        tag = res.Tag
-        suffix = None
-        if volume:
-            suffix = '/' + volume
-        try:
-            while True:
-                res = server.DatasetMemberListInfoIterNext(Tag=tag,
-                                                           Maximum=100)
-                if (not hasattr(res, 'DatasetMembers') or
-                        not res.DatasetMembers):
-                    break
-                for member in res.DatasetMembers.DatasetMemberInfo:
-                    if suffix and not member.MemberName.endswith(suffix):
-                        continue
-                    # MemberName is the full LUN path in this format:
-                    # host:/volume/qtree/lun
-                    lun = DfmLun(dataset, member.MemberName, member.MemberId)
-                    self.discovered_luns.append(lun)
-        finally:
-            server.DatasetMemberListInfoIterEnd(Tag=tag)
-
-    def _discover_luns(self):
-        """Discover the LUNs from DFM.
-
-        Discover all of the OpenStack-created datasets and LUNs in the DFM
-        database.
-        """
-        datasets = self._get_datasets()
-        self.discovered_datasets = []
-        self.discovered_luns = []
-        for dataset in datasets:
-            if not dataset.DatasetName.startswith(self.DATASET_PREFIX):
-                continue
-            if (not hasattr(dataset, 'DatasetMetadata') or
-                    not dataset.DatasetMetadata):
-                continue
-            project = None
-            type = None
-            for field in dataset.DatasetMetadata.DfmMetadataField:
-                if field.FieldName == self.DATASET_METADATA_PROJECT_KEY:
-                    project = field.FieldValue
-                elif field.FieldName == self.DATASET_METADATA_VOL_TYPE_KEY:
-                    type = field.FieldValue
-            if not project:
-                continue
-            ds = DfmDataset(dataset.DatasetId, dataset.DatasetName,
-                            project, type)
-            self.discovered_datasets.append(ds)
-            self._discover_dataset_luns(ds, None)
-        dataset_count = len(self.discovered_datasets)
-        lun_count = len(self.discovered_luns)
-        msg = _("Discovered %(dataset_count)s datasets and %(lun_count)s LUNs")
-        LOG.debug(msg % locals())
-        self.lun_table = {}
-
-    def _get_job_progress(self, job_id):
-        """Get progress of one running DFM job.
-
-        Obtain the latest progress report for the job and return the
-        list of progress events.
-        """
-        server = self.client.service
-        res = server.DpJobProgressEventListIterStart(JobId=job_id)
-        tag = res.Tag
-        event_list = []
-        try:
-            while True:
-                res = server.DpJobProgressEventListIterNext(Tag=tag,
-                                                            Maximum=100)
-                if not hasattr(res, 'ProgressEvents'):
-                    break
-                event_list += res.ProgressEvents.DpJobProgressEventInfo
-        finally:
-            server.DpJobProgressEventListIterEnd(Tag=tag)
-        return event_list
-
-    def _wait_for_job(self, job_id):
-        """Wait until a job terminates.
-
-        Poll the job until it completes or an error is detected. Return the
-        final list of progress events if it completes successfully.
-        """
-        while True:
-            events = self._get_job_progress(job_id)
-            for event in events:
-                if event.EventStatus == 'error':
-                    msg = _('Job failed: %s') % (event.ErrorMessage)
-                    raise exception.VolumeBackendAPIException(data=msg)
-                if event.EventType == 'job-end':
-                    return events
-            time.sleep(5)
-
-    def _dataset_name(self, project, ss_type):
-        """Return the dataset name for a given project and volume type."""
-        _project = project.replace(' ', '_').replace('-', '_')
-        dataset_name = self.DATASET_PREFIX + _project
-        if not ss_type:
-            return dataset_name
-        _type = ss_type.replace(' ', '_').replace('-', '_')
-        return dataset_name + '_' + _type
-
-    def _get_dataset(self, dataset_name):
-        """Lookup a dataset by name in the list of discovered datasets."""
-        for dataset in self.discovered_datasets:
-            if dataset.name == dataset_name:
-                return dataset
-        return None
-
-    def _create_dataset(self, dataset_name, project, ss_type):
-        """Create a new dataset using the storage service.
-
-        The export settings are set to create iSCSI LUNs aligned for Linux.
-        Returns the ID of the new dataset.
-        """
-        if ss_type and not self.storage_service_prefix:
-            msg = _('Attempt to use volume_type without specifying '
-                    'netapp_storage_service_prefix flag.')
-            raise exception.VolumeBackendAPIException(data=msg)
-        if not (ss_type or self.storage_service):
-            msg = _('You must set the netapp_storage_service flag in order to '
-                    'create volumes with no volume_type.')
-            raise exception.VolumeBackendAPIException(data=msg)
-        storage_service = self.storage_service
-        if ss_type:
-            storage_service = self.storage_service_prefix + ss_type
-
-        factory = self.client.factory
-
-        lunmap = factory.create('DatasetLunMappingInfo')
-        lunmap.IgroupOsType = 'linux'
-        export = factory.create('DatasetExportInfo')
-        export.DatasetExportProtocol = 'iscsi'
-        export.DatasetLunMappingInfo = lunmap
-        detail = factory.create('StorageSetInfo')
-        detail.DpNodeName = 'Primary data'
-        detail.DatasetExportInfo = export
-        if hasattr(self, 'vfiler') and self.vfiler:
-            detail.ServerNameOrId = self.vfiler
-        details = factory.create('ArrayOfStorageSetInfo')
-        details.StorageSetInfo = [detail]
-        field1 = factory.create('DfmMetadataField')
-        field1.FieldName = self.DATASET_METADATA_PROJECT_KEY
-        field1.FieldValue = project
-        field2 = factory.create('DfmMetadataField')
-        field2.FieldName = self.DATASET_METADATA_VOL_TYPE_KEY
-        field2.FieldValue = ss_type
-        metadata = factory.create('ArrayOfDfmMetadataField')
-        metadata.DfmMetadataField = [field1, field2]
-
-        res = self.client.service.StorageServiceDatasetProvision(
-            StorageServiceNameOrId=storage_service,
-            DatasetName=dataset_name,
-            AssumeConfirmation=True,
-            StorageSetDetails=details,
-            DatasetMetadata=metadata)
-
-        ds = DfmDataset(res.DatasetId, dataset_name, project, ss_type)
-        self.discovered_datasets.append(ds)
-        return ds
-
-    @utils.synchronized('netapp_dfm', external=True)
-    def _provision(self, name, description, project, ss_type, size):
-        """Provision a LUN through provisioning manager.
-
-        The LUN will be created inside a dataset associated with the project.
-        If the dataset doesn't already exist, we create it using the storage
-        service specified in the manila conf.
-        """
-        dataset_name = self._dataset_name(project, ss_type)
-        dataset = self._get_dataset(dataset_name)
-        if not dataset:
-            dataset = self._create_dataset(dataset_name, project, ss_type)
-
-        info = self.client.factory.create('ProvisionMemberRequestInfo')
-        info.Name = name
-        if description:
-            info.Description = description
-        info.Size = size
-        info.MaximumSnapshotSpace = 2 * long(size)
-
-        server = self.client.service
-        lock_id = server.DatasetEditBegin(DatasetNameOrId=dataset.id)
-        try:
-            server.DatasetProvisionMember(EditLockId=lock_id,
-                                          ProvisionMemberRequestInfo=info)
-            res = server.DatasetEditCommit(EditLockId=lock_id,
-                                           AssumeConfirmation=True)
-        except (suds.WebFault, Exception):
-            server.DatasetEditRollback(EditLockId=lock_id)
-            msg = _('Failed to provision dataset member')
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        lun_id = None
-        lunpath = None
-
-        for info in res.JobIds.JobInfo:
-            events = self._wait_for_job(info.JobId)
-            for event in events:
-                if event.EventType != 'lun-create':
-                    continue
-                lunpath = event.ProgressLunInfo.LunName
-                lun_id = event.ProgressLunInfo.LunPathId
-
-        if not lun_id:
-            msg = _('No LUN was created by the provision job')
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        lun = DfmLun(dataset, lunpath, lun_id)
-        self.discovered_luns.append(lun)
-        self.lun_table[name] = lun
-
-    def _get_ss_type(self, volume):
-        """Get the storage service type for a volume."""
-        id = volume['volume_type_id']
-        if not id:
-            return None
-        volume_type = volume_types.get_volume_type(None, id)
-        if not volume_type:
-            return None
-        return volume_type['name']
-
-    @utils.synchronized('netapp_dfm', external=True)
-    def _remove_destroy(self, name, project):
-        """Remove the LUN from the dataset, also destroying it.
-
-        Remove the LUN from the dataset and destroy the actual LUN and Qtree
-        on the storage system.
-        """
-        try:
-            lun = self._lookup_lun_for_volume(name, project)
-            lun_details = self._get_lun_details(lun.id)
-        except exception.VolumeBackendAPIException:
-            msg = _("No entry in LUN table for volume %(name)s.")
-            LOG.debug(msg % locals())
-            return
-
-        member = self.client.factory.create('DatasetMemberParameter')
-        member.ObjectNameOrId = lun.id
-        members = self.client.factory.create('ArrayOfDatasetMemberParameter')
-        members.DatasetMemberParameter = [member]
-
-        server = self.client.service
-        lock_id = server.DatasetEditBegin(DatasetNameOrId=lun.dataset.id)
-        try:
-            server.DatasetRemoveMember(EditLockId=lock_id, Destroy=True,
-                                       DatasetMemberParameters=members)
-            res = server.DatasetEditCommit(EditLockId=lock_id,
-                                           AssumeConfirmation=True)
-        except (suds.WebFault, Exception):
-            server.DatasetEditRollback(EditLockId=lock_id)
-            msg = _('Failed to remove and delete dataset LUN member')
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        for info in res.JobIds.JobInfo:
-            self._wait_for_job(info.JobId)
-
-        # Note: it's not possible to delete Qtree & his LUN in one transaction
-        member.ObjectNameOrId = lun_details.QtreeId
-        lock_id = server.DatasetEditBegin(DatasetNameOrId=lun.dataset.id)
-        try:
-            server.DatasetRemoveMember(EditLockId=lock_id, Destroy=True,
-                                       DatasetMemberParameters=members)
-            server.DatasetEditCommit(EditLockId=lock_id,
-                                     AssumeConfirmation=True)
-        except (suds.WebFault, Exception):
-            server.DatasetEditRollback(EditLockId=lock_id)
-            msg = _('Failed to remove and delete dataset Qtree member')
-            raise exception.VolumeBackendAPIException(data=msg)
-
-    def create_volume(self, volume):
-        """Driver entry point for creating a new volume."""
-        default_size = '104857600'  # 100 MB
-        gigabytes = 1073741824L  # 2^30
-        name = volume['name']
-        project = volume['project_id']
-        display_name = volume['display_name']
-        display_description = volume['display_description']
-        description = None
-        if display_name:
-            if display_description:
-                description = display_name + "\n" + display_description
-            else:
-                description = display_name
-        elif display_description:
-            description = display_description
-        if int(volume['size']) == 0:
-            size = default_size
-        else:
-            size = str(int(volume['size']) * gigabytes)
-        ss_type = self._get_ss_type(volume)
-        self._provision(name, description, project, ss_type, size)
-
-    def _lookup_lun_for_volume(self, name, project):
-        """Lookup the LUN that corresponds to the give volume.
-
-        Initial lookups involve a table scan of all of the discovered LUNs,
-        but later lookups are done instantly from the hashtable.
-        """
-        if name in self.lun_table:
-            return self.lun_table[name]
-        lunpath_suffix = '/' + name
-        for lun in self.discovered_luns:
-            if lun.dataset.project != project:
-                continue
-            if lun.lunpath.endswith(lunpath_suffix):
-                self.lun_table[name] = lun
-                return lun
-        msg = _("No entry in LUN table for volume %s") % (name)
-        raise exception.VolumeBackendAPIException(data=msg)
-
-    def delete_volume(self, volume):
-        """Driver entry point for destroying existing volumes."""
-        name = volume['name']
-        project = volume['project_id']
-        self._remove_destroy(name, project)
-
-    def _get_lun_details(self, lun_id):
-        """Given the ID of a LUN, get the details about that LUN."""
-        server = self.client.service
-        res = server.LunListInfoIterStart(ObjectNameOrId=lun_id)
-        tag = res.Tag
-        try:
-            res = server.LunListInfoIterNext(Tag=tag, Maximum=1)
-            if hasattr(res, 'Luns') and res.Luns.LunInfo:
-                return res.Luns.LunInfo[0]
-        finally:
-            server.LunListInfoIterEnd(Tag=tag)
-        msg = _('Failed to get LUN details for LUN ID %s')
-        raise exception.VolumeBackendAPIException(data=msg % lun_id)
-
-    def _get_host_details(self, host_id):
-        """Given the ID of a host, get the details about it.
-
-        A "host" is a storage system here.
-        """
-        server = self.client.service
-        res = server.HostListInfoIterStart(ObjectNameOrId=host_id)
-        tag = res.Tag
-        try:
-            res = server.HostListInfoIterNext(Tag=tag, Maximum=1)
-            if hasattr(res, 'Hosts') and res.Hosts.HostInfo:
-                return res.Hosts.HostInfo[0]
-        finally:
-            server.HostListInfoIterEnd(Tag=tag)
-        msg = _('Failed to get host details for host ID %s')
-        raise exception.VolumeBackendAPIException(data=msg % host_id)
-
-    def _get_iqn_for_host(self, host_id):
-        """Get the iSCSI Target Name for a storage system."""
-        request = self.client.factory.create('Request')
-        request.Name = 'iscsi-node-get-name'
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        return response.Results['node-name'][0]
-
-    def _api_elem_is_empty(self, elem):
-        """Return true if the API element should be considered empty.
-
-        Helper routine to figure out if a list returned from a proxy API
-        is empty. This is necessary because the API proxy produces nasty
-        looking XML.
-        """
-        if type(elem) is not list:
-            return True
-        if 0 == len(elem):
-            return True
-        child = elem[0]
-        if isinstance(child, text.Text):
-            return True
-        if type(child) is str:
-            return True
-        return False
-
-    def _get_target_portal_for_host(self, host_id, host_address):
-        """Get iSCSI target portal for a storage system.
-
-        Get the iSCSI Target Portal details for a particular IP address
-        on a storage system.
-        """
-        request = self.client.factory.create('Request')
-        request.Name = 'iscsi-portal-list-info'
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        portal = {}
-        portals = response.Results['iscsi-portal-list-entries']
-        if self._api_elem_is_empty(portals):
-            return portal
-        portal_infos = portals[0]['iscsi-portal-list-entry-info']
-        for portal_info in portal_infos:
-            portal['address'] = portal_info['ip-address'][0]
-            portal['port'] = portal_info['ip-port'][0]
-            portal['portal'] = portal_info['tpgroup-tag'][0]
-            if host_address == portal['address']:
-                break
-        return portal
-
-    def _get_export(self, volume):
-        """Get the iSCSI export details for a volume.
-
-        Looks up the LUN in DFM based on the volume and project name, then get
-        the LUN's ID. We store that value in the database instead of the iSCSI
-        details because we will not have the true iSCSI details until masking
-        time (when initialize_connection() is called).
-        """
-        name = volume['name']
-        project = volume['project_id']
-        lun = self._lookup_lun_for_volume(name, project)
-        return {'provider_location': lun.id}
-
-    def ensure_export(self, context, volume):
-        """Driver entry point to get the export info for an existing volume."""
-        return self._get_export(volume)
-
-    def create_export(self, context, volume):
-        """Driver entry point to get the export info for a new volume."""
-        return self._get_export(volume)
-
-    def remove_export(self, context, volume):
-        """Driver exntry point to remove an export for a volume.
-
-        Since exporting is idempotent in this driver, we have nothing
-        to do for unexporting.
-        """
-        pass
-
-    def _find_igroup_for_initiator(self, host_id, initiator_name):
-        """Get the igroup for an initiator.
-
-        Look for an existing igroup (initiator group) on the storage system
-        containing a given iSCSI initiator and return the name of the igroup.
-        """
-        request = self.client.factory.create('Request')
-        request.Name = 'igroup-list-info'
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        igroups = response.Results['initiator-groups']
-        if self._api_elem_is_empty(igroups):
-            return None
-        igroup_infos = igroups[0]['initiator-group-info']
-        for igroup_info in igroup_infos:
-            if ('iscsi' != igroup_info['initiator-group-type'][0] or
-                    'linux' != igroup_info['initiator-group-os-type'][0]):
-                continue
-            igroup_name = igroup_info['initiator-group-name'][0]
-            if not igroup_name.startswith(self.IGROUP_PREFIX):
-                continue
-            initiators = igroup_info['initiators'][0]['initiator-info']
-            for initiator in initiators:
-                if initiator_name == initiator['initiator-name'][0]:
-                    return igroup_name
-        return None
-
-    def _create_igroup(self, host_id, initiator_name):
-        """Create a new igroup.
-
-        Create a new igroup (initiator group) on the storage system to hold
-        the given iSCSI initiator. The group will only have 1 member and will
-        be named "openstack-${initiator_name}".
-        """
-        igroup_name = self.IGROUP_PREFIX + initiator_name
-        request = self.client.factory.create('Request')
-        request.Name = 'igroup-create'
-        igroup_create_xml = (
-            '<initiator-group-name>%s</initiator-group-name>'
-            '<initiator-group-type>iscsi</initiator-group-type>'
-            '<os-type>linux</os-type><ostype>linux</ostype>')
-        request.Args = text.Raw(igroup_create_xml % igroup_name)
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        request = self.client.factory.create('Request')
-        request.Name = 'igroup-add'
-        igroup_add_xml = (
-            '<initiator-group-name>%s</initiator-group-name>'
-            '<initiator>%s</initiator>')
-        request.Args = text.Raw(igroup_add_xml % (igroup_name, initiator_name))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        return igroup_name
-
-    def _get_lun_mappping(self, host_id, lunpath, igroup_name):
-        """Get the mapping between a LUN and an igroup.
-
-        Check if a given LUN is already mapped to the given igroup (initiator
-        group). If the LUN is mapped, also return the LUN number for the
-        mapping.
-        """
-        request = self.client.factory.create('Request')
-        request.Name = 'lun-map-list-info'
-        request.Args = text.Raw('<path>%s</path>' % (lunpath))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        igroups = response.Results['initiator-groups']
-        if self._api_elem_is_empty(igroups):
-            return {'mapped': False}
-        igroup_infos = igroups[0]['initiator-group-info']
-        for igroup_info in igroup_infos:
-            if igroup_name == igroup_info['initiator-group-name'][0]:
-                return {'mapped': True, 'lun_num': igroup_info['lun-id'][0]}
-        return {'mapped': False}
-
-    def _map_initiator(self, host_id, lunpath, igroup_name):
-        """Map a LUN to an igroup.
-
-        Map the given LUN to the given igroup (initiator group). Return the LUN
-        number that the LUN was mapped to (the filer will choose the lowest
-        available number).
-        """
-        request = self.client.factory.create('Request')
-        request.Name = 'lun-map'
-        lun_map_xml = ('<initiator-group>%s</initiator-group>'
-                       '<path>%s</path>')
-        request.Args = text.Raw(lun_map_xml % (igroup_name, lunpath))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        return response.Results['lun-id-assigned'][0]
-
-    def _unmap_initiator(self, host_id, lunpath, igroup_name):
-        """Unmap the given LUN from the given igroup (initiator group)."""
-        request = self.client.factory.create('Request')
-        request.Name = 'lun-unmap'
-        lun_unmap_xml = ('<initiator-group>%s</initiator-group>'
-                         '<path>%s</path>')
-        request.Args = text.Raw(lun_unmap_xml % (igroup_name, lunpath))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-
-    def _ensure_initiator_mapped(self, host_id, lunpath, initiator_name):
-        """Ensure that a LUN is mapped to a particular initiator.
-
-        Check if a LUN is mapped to a given initiator already and create
-        the mapping if it is not. A new igroup will be created if needed.
-        Returns the LUN number for the mapping between the LUN and initiator
-        in both cases.
-        """
-        lunpath = '/vol/' + lunpath
-        igroup_name = self._find_igroup_for_initiator(host_id, initiator_name)
-        if not igroup_name:
-            igroup_name = self._create_igroup(host_id, initiator_name)
-
-        mapping = self._get_lun_mappping(host_id, lunpath, igroup_name)
-        if mapping['mapped']:
-            return mapping['lun_num']
-        return self._map_initiator(host_id, lunpath, igroup_name)
-
-    def _ensure_initiator_unmapped(self, host_id, lunpath, initiator_name):
-        """Ensure that a LUN is not mapped to a particular initiator.
-
-        Check if a LUN is mapped to a given initiator and remove the
-        mapping if it is. This does not destroy the igroup.
-        """
-        lunpath = '/vol/' + lunpath
-        igroup_name = self._find_igroup_for_initiator(host_id, initiator_name)
-        if not igroup_name:
-            return
-
-        mapping = self._get_lun_mappping(host_id, lunpath, igroup_name)
-        if mapping['mapped']:
-            self._unmap_initiator(host_id, lunpath, igroup_name)
-
-    def initialize_connection(self, volume, connector):
-        """Driver entry point to attach a volume to an instance.
-
-        Do the LUN masking on the storage system so the initiator can access
-        the LUN on the target. Also return the iSCSI properties so the
-        initiator can find the LUN. This implementation does not call
-        _get_iscsi_properties() to get the properties because cannot store the
-        LUN number in the database. We only find out what the LUN number will
-        be during this method call so we construct the properties dictionary
-        ourselves.
-        """
-        initiator_name = connector['initiator']
-        lun_id = volume['provider_location']
-        if not lun_id:
-            msg = _("No LUN ID for volume %s") % volume['name']
-            raise exception.VolumeBackendAPIException(data=msg)
-        lun = self._get_lun_details(lun_id)
-        lun_num = self._ensure_initiator_mapped(lun.HostId, lun.LunPath,
-                                                initiator_name)
-        host = self._get_host_details(lun.HostId)
-        portal = self._get_target_portal_for_host(host.HostId,
-                                                  host.HostAddress)
-        if not portal:
-            msg = _('Failed to get target portal for filer: %s')
-            raise exception.VolumeBackendAPIException(data=msg % host.HostName)
-
-        iqn = self._get_iqn_for_host(host.HostId)
-        if not iqn:
-            msg = _('Failed to get target IQN for filer: %s')
-            raise exception.VolumeBackendAPIException(data=msg % host.HostName)
-
-        properties = {}
-        properties['target_discovered'] = False
-        (address, port) = (portal['address'], portal['port'])
-        properties['target_portal'] = '%s:%s' % (address, port)
-        properties['target_iqn'] = iqn
-        properties['target_lun'] = lun_num
-        properties['volume_id'] = volume['id']
-
-        auth = volume['provider_auth']
-        if auth:
-            (auth_method, auth_username, auth_secret) = auth.split()
-
-            properties['auth_method'] = auth_method
-            properties['auth_username'] = auth_username
-            properties['auth_password'] = auth_secret
-
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': properties,
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Driver entry point to unattach a volume from an instance.
-
-        Unmask the LUN on the storage system so the given intiator can no
-        longer access it.
-        """
-        initiator_name = connector['initiator']
-        lun_id = volume['provider_location']
-        if not lun_id:
-            msg = _('No LUN ID for volume %s') % volume['name']
-            raise exception.VolumeBackendAPIException(data=msg)
-        lun = self._get_lun_details(lun_id)
-        self._ensure_initiator_unmapped(lun.HostId, lun.LunPath,
-                                        initiator_name)
-
-    def _is_clone_done(self, host_id, clone_op_id, volume_uuid):
-        """Check the status of a clone operation.
-
-        Return True if done, False otherwise.
-        """
-        request = self.client.factory.create('Request')
-        request.Name = 'clone-list-status'
-        clone_list_status_xml = (
-            '<clone-id><clone-id-info>'
-            '<clone-op-id>%s</clone-op-id>'
-            '<volume-uuid>%s</volume-uuid>'
-            '</clone-id-info></clone-id>')
-        request.Args = text.Raw(clone_list_status_xml % (clone_op_id,
-                                                         volume_uuid))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        if isinstance(response.Results, text.Text):
-            return False
-        status = response.Results['status']
-        if self._api_elem_is_empty(status):
-            return False
-        ops_info = status[0]['ops-info'][0]
-        state = ops_info['clone-state'][0]
-        return 'completed' == state
-
-    def _clone_lun(self, host_id, src_path, dest_path, snap):
-        """Create a clone of a NetApp LUN.
-
-        The clone initially consumes no space and is not space reserved.
-        """
-        request = self.client.factory.create('Request')
-        request.Name = 'clone-start'
-        clone_start_xml = (
-            '<source-path>%s</source-path><no-snap>%s</no-snap>'
-            '<destination-path>%s</destination-path>')
-        if snap:
-            no_snap = 'false'
-        else:
-            no_snap = 'true'
-        request.Args = text.Raw(clone_start_xml % (src_path, no_snap,
-                                                   dest_path))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        clone_id = response.Results['clone-id'][0]
-        clone_id_info = clone_id['clone-id-info'][0]
-        clone_op_id = clone_id_info['clone-op-id'][0]
-        volume_uuid = clone_id_info['volume-uuid'][0]
-        while not self._is_clone_done(host_id, clone_op_id, volume_uuid):
-            time.sleep(5)
-
-    def _refresh_dfm_luns(self, host_id):
-        """Refresh the LUN list for one filer in DFM."""
-        server = self.client.service
-        refresh_started_at = time.time()
-        monitor_names = self.client.factory.create('ArrayOfMonitorName')
-        monitor_names.MonitorName = ['file_system', 'lun']
-        server.DfmObjectRefresh(ObjectNameOrId=host_id,
-                                MonitorNames=monitor_names)
-
-        max_wait = 10 * 60   # 10 minutes
-
-        while True:
-            if time.time() - refresh_started_at > max_wait:
-                msg = _('Failed to get LUN list. Is the DFM host'
-                        ' time-synchronized with Cinder host?')
-                raise exception.VolumeBackendAPIException(msg)
-
-            LOG.info('Refreshing LUN list on DFM...')
-            time.sleep(15)
-            res = server.DfmMonitorTimestampList(HostNameOrId=host_id)
-            timestamps = dict((t.MonitorName, t.LastMonitoringTimestamp)
-                              for t in res.DfmMonitoringTimestamp)
-            ts_fs = timestamps['file_system']
-            ts_lun = timestamps['lun']
-
-            if ts_fs > refresh_started_at and ts_lun > refresh_started_at:
-                return          # both monitor jobs finished
-            elif ts_fs == 0 or ts_lun == 0:
-                pass            # lun or file_system is still in progress, wait
-            else:
-                monitor_names.MonitorName = []
-                if ts_fs <= refresh_started_at:
-                    monitor_names.MonitorName.append('file_system')
-                if ts_lun <= refresh_started_at:
-                    monitor_names.MonitorName.append('lun')
-                LOG.debug('Rerunning refresh for monitors: ' +
-                          str(monitor_names.MonitorName))
-                server.DfmObjectRefresh(ObjectNameOrId=host_id,
-                                        MonitorNames=monitor_names)
-
-    def _destroy_lun(self, host_id, lun_path):
-        """Destroy a LUN on the filer."""
-        request = self.client.factory.create('Request')
-        request.Name = 'lun-offline'
-        path_xml = '<path>%s</path>'
-        request.Args = text.Raw(path_xml % lun_path)
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-        request = self.client.factory.create('Request')
-        request.Name = 'lun-destroy'
-        request.Args = text.Raw(path_xml % lun_path)
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-
-    def _resize_volume(self, host_id, vol_name, new_size):
-        """Resize the volume by the amount requested."""
-        request = self.client.factory.create('Request')
-        request.Name = 'volume-size'
-        volume_size_xml = (
-            '<volume>%s</volume><new-size>%s</new-size>')
-        request.Args = text.Raw(volume_size_xml % (vol_name, new_size))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-
-    def _create_qtree(self, host_id, vol_name, qtree_name):
-        """Create a qtree the filer."""
-        request = self.client.factory.create('Request')
-        request.Name = 'qtree-create'
-        qtree_create_xml = (
-            '<mode>0755</mode><volume>%s</volume><qtree>%s</qtree>')
-        request.Args = text.Raw(qtree_create_xml % (vol_name, qtree_name))
-        response = self.client.service.ApiProxy(Target=host_id,
-                                                Request=request)
-        self._check_fail(request, response)
-
-    def create_snapshot(self, snapshot):
-        """Driver entry point for creating a snapshot.
-
-        This driver implements snapshots by using efficient single-file
-        (LUN) cloning.
-        """
-        vol_name = snapshot['volume_name']
-        snapshot_name = snapshot['name']
-        project = snapshot['project_id']
-        lun = self._lookup_lun_for_volume(vol_name, project)
-        lun_id = lun.id
-        lun = self._get_lun_details(lun_id)
-        extra_gb = snapshot['volume_size']
-        new_size = '+%dg' % extra_gb
-        self._resize_volume(lun.HostId, lun.VolumeName, new_size)
-        # LunPath is the partial LUN path in this format: volume/qtree/lun
-        lun_path = str(lun.LunPath)
-        lun_name = lun_path[lun_path.rfind('/') + 1:]
-        qtree_path = '/vol/%s/%s' % (lun.VolumeName, lun.QtreeName)
-        src_path = '%s/%s' % (qtree_path, lun_name)
-        dest_path = '%s/%s' % (qtree_path, snapshot_name)
-        self._clone_lun(lun.HostId, src_path, dest_path, True)
-
-    def delete_snapshot(self, snapshot):
-        """Driver entry point for deleting a snapshot."""
-        vol_name = snapshot['volume_name']
-        snapshot_name = snapshot['name']
-        project = snapshot['project_id']
-        lun = self._lookup_lun_for_volume(vol_name, project)
-        lun_id = lun.id
-        lun = self._get_lun_details(lun_id)
-        lun_path = '/vol/%s/%s/%s' % (lun.VolumeName, lun.QtreeName,
-                                      snapshot_name)
-        self._destroy_lun(lun.HostId, lun_path)
-        extra_gb = snapshot['volume_size']
-        new_size = '-%dg' % extra_gb
-        self._resize_volume(lun.HostId, lun.VolumeName, new_size)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Driver entry point for creating a new volume from a snapshot.
-
-        Many would call this "cloning" and in fact we use cloning to implement
-        this feature.
-        """
-        vol_size = volume['size']
-        snap_size = snapshot['volume_size']
-        if vol_size != snap_size:
-            msg = _('Cannot create volume of size %(vol_size)s from '
-                    'snapshot of size %(snap_size)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        vol_name = snapshot['volume_name']
-        snapshot_name = snapshot['name']
-        project = snapshot['project_id']
-        lun = self._lookup_lun_for_volume(vol_name, project)
-        lun_id = lun.id
-        dataset = lun.dataset
-        old_type = dataset.type
-        new_type = self._get_ss_type(volume)
-        if new_type != old_type:
-            msg = _('Cannot create volume of type %(new_type)s from '
-                    'snapshot of type %(old_type)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        lun = self._get_lun_details(lun_id)
-        extra_gb = vol_size
-        new_size = '+%dg' % extra_gb
-        self._resize_volume(lun.HostId, lun.VolumeName, new_size)
-        clone_name = volume['name']
-        self._create_qtree(lun.HostId, lun.VolumeName, clone_name)
-        src_path = '/vol/%s/%s/%s' % (lun.VolumeName, lun.QtreeName,
-                                      snapshot_name)
-        dest_path = '/vol/%s/%s/%s' % (lun.VolumeName, clone_name, clone_name)
-        self._clone_lun(lun.HostId, src_path, dest_path, False)
-        self._refresh_dfm_luns(lun.HostId)
-        self._discover_dataset_luns(dataset, clone_name)
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        vol_size = volume['size']
-        src_vol_size = src_vref['size']
-        if vol_size != src_vol_size:
-            msg = _('Cannot create clone of size %(vol_size)s from '
-                    'volume of size %(src_vol_size)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        src_vol_name = src_vref['name']
-        project = src_vref['project_id']
-        lun = self._lookup_lun_for_volume(src_vol_name, project)
-        lun_id = lun.id
-        dataset = lun.dataset
-        old_type = dataset.type
-        new_type = self._get_ss_type(volume)
-        if new_type != old_type:
-            msg = _('Cannot create clone of type %(new_type)s from '
-                    'volume of type %(old_type)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        lun = self._get_lun_details(lun_id)
-        extra_gb = vol_size
-        new_size = '+%dg' % extra_gb
-        self._resize_volume(lun.HostId, lun.VolumeName, new_size)
-        clone_name = volume['name']
-        self._create_qtree(lun.HostId, lun.VolumeName, clone_name)
-        src_path = '/vol/%s/%s/%s' % (lun.VolumeName, lun.QtreeName,
-                                      src_vol_name)
-        dest_path = '/vol/%s/%s/%s' % (lun.VolumeName, clone_name, clone_name)
-        self._clone_lun(lun.HostId, src_path, dest_path, False)
-        self._refresh_dfm_luns(lun.HostId)
-        self._discover_dataset_luns(dataset, clone_name)
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'NetApp_iSCSI_7mode'
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'iSCSI'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = False
-        self._stats = data
-
-
-class NetAppLun(object):
-    """Represents a LUN on NetApp storage."""
-
-    def __init__(self, handle, name, size, metadata_dict):
-        self.handle = handle
-        self.name = name
-        self.size = size
-        self.metadata = metadata_dict or {}
-
-    def get_metadata_property(self, prop):
-        """Get the metadata property of a LUN."""
-        if prop in self.metadata:
-            return self.metadata[prop]
-        name = self.name
-        msg = _("No metadata property %(prop)s defined for the LUN %(name)s")
-        LOG.debug(msg % locals())
-
-    def __str__(self, *args, **kwargs):
-        return 'NetApp Lun[handle:%s, name:%s, size:%s, metadata:%s]'\
-               % (self.handle, self.name, self.size, self.metadata)
-
-
-class NetAppCmodeISCSIDriver(driver.ISCSIDriver):
-    """NetApp C-mode iSCSI volume driver."""
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppCmodeISCSIDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(netapp_opts)
-        self.lun_table = {}
-
-    def _create_client(self, **kwargs):
-        """Instantiate a web services client.
-
-        This method creates a "suds" client to make web services calls to the
-        DFM server. Note that the WSDL file is quite large and may take
-        a few seconds to parse.
-        """
-        wsdl_url = kwargs['wsdl_url']
-        LOG.debug(_('Using WSDL: %s') % wsdl_url)
-        if kwargs['cache']:
-            self.client = client.Client(wsdl_url, username=kwargs['login'],
-                                        password=kwargs['password'])
-        else:
-            self.client = client.Client(wsdl_url, username=kwargs['login'],
-                                        password=kwargs['password'],
-                                        cache=None)
-
-    def _check_flags(self):
-        """Ensure that the flags we care about are set."""
-        required_flags = ['netapp_wsdl_url', 'netapp_login', 'netapp_password',
-                          'netapp_server_hostname', 'netapp_server_port']
-        for flag in required_flags:
-            if not getattr(self.configuration, flag, None):
-                msg = _('%s is not set') % flag
-                raise exception.InvalidInput(data=msg)
-
-    def do_setup(self, context):
-        """Setup the NetApp Volume driver.
-
-        Called one time by the manager after the driver is loaded.
-        Validate the flags we care about and setup the suds (web services)
-        client.
-        """
-        self._check_flags()
-        self._create_client(
-            wsdl_url=self.configuration.netapp_wsdl_url,
-            login=self.configuration.netapp_login,
-            password=self.configuration.netapp_password,
-            hostname=self.configuration.netapp_server_hostname,
-            port=self.configuration.netapp_server_port, cache=True)
-
-    def check_for_setup_error(self):
-        """Check that the driver is working and can communicate.
-
-        Discovers the LUNs on the NetApp server.
-        """
-        self.lun_table = {}
-        luns = self.client.service.ListLuns()
-        for lun in luns:
-            meta_dict = {}
-            if hasattr(lun, 'Metadata'):
-                meta_dict = self._create_dict_from_meta(lun.Metadata)
-            discovered_lun = NetAppLun(lun.Handle,
-                                       lun.Name,
-                                       lun.Size,
-                                       meta_dict)
-            self._add_lun_to_table(discovered_lun)
-        LOG.debug(_("Success getting LUN list from server"))
-
-    def create_volume(self, volume):
-        """Driver entry point for creating a new volume."""
-        default_size = '104857600'  # 100 MB
-        gigabytes = 1073741824L  # 2^30
-        name = volume['name']
-        if int(volume['size']) == 0:
-            size = default_size
-        else:
-            size = str(int(volume['size']) * gigabytes)
-        extra_args = {}
-        extra_args['OsType'] = 'linux'
-        extra_args['QosType'] = self._get_qos_type(volume)
-        extra_args['Container'] = volume['project_id']
-        extra_args['Display'] = volume['display_name']
-        extra_args['Description'] = volume['display_description']
-        extra_args['SpaceReserved'] = True
-        server = self.client.service
-        metadata = self._create_metadata_list(extra_args)
-        lun = server.ProvisionLun(Name=name, Size=size,
-                                  Metadata=metadata)
-        LOG.debug(_("Created LUN with name %s") % name)
-        self._add_lun_to_table(
-            NetAppLun(lun.Handle,
-                      lun.Name,
-                      lun.Size,
-                      self._create_dict_from_meta(lun.Metadata)))
-
-    def delete_volume(self, volume):
-        """Driver entry point for destroying existing volumes."""
-        name = volume['name']
-        handle = self._get_lun_handle(name)
-        if not handle:
-            msg = _("No entry in LUN table for volume %(name)s.")
-            LOG.warn(msg % locals())
-            return
-        self.client.service.DestroyLun(Handle=handle)
-        LOG.debug(_("Destroyed LUN %s") % handle)
-        self.lun_table.pop(name)
-
-    def ensure_export(self, context, volume):
-        """Driver entry point to get the export info for an existing volume."""
-        handle = self._get_lun_handle(volume['name'])
-        return {'provider_location': handle}
-
-    def create_export(self, context, volume):
-        """Driver entry point to get the export info for a new volume."""
-        handle = self._get_lun_handle(volume['name'])
-        return {'provider_location': handle}
-
-    def remove_export(self, context, volume):
-        """Driver exntry point to remove an export for a volume.
-
-        Since exporting is idempotent in this driver, we have nothing
-        to do for unexporting.
-        """
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Driver entry point to attach a volume to an instance.
-
-        Do the LUN masking on the storage system so the initiator can access
-        the LUN on the target. Also return the iSCSI properties so the
-        initiator can find the LUN. This implementation does not call
-        _get_iscsi_properties() to get the properties because cannot store the
-        LUN number in the database. We only find out what the LUN number will
-        be during this method call so we construct the properties dictionary
-        ourselves.
-        """
-        initiator_name = connector['initiator']
-        handle = volume['provider_location']
-        server = self.client.service
-        server.MapLun(Handle=handle, InitiatorType="iscsi",
-                      InitiatorName=initiator_name)
-        msg = _("Mapped LUN %(handle)s to the initiator %(initiator_name)s")
-        LOG.debug(msg % locals())
-
-        target_details_list = server.GetLunTargetDetails(
-            Handle=handle,
-            InitiatorType="iscsi",
-            InitiatorName=initiator_name)
-        msg = _("Succesfully fetched target details for LUN %(handle)s and "
-                "initiator %(initiator_name)s")
-        LOG.debug(msg % locals())
-
-        if not target_details_list:
-            msg = _('Failed to get LUN target details for the LUN %s')
-            raise exception.VolumeBackendAPIException(data=msg % handle)
-        target_details = target_details_list[0]
-        if not target_details.Address and target_details.Port:
-            msg = _('Failed to get target portal for the LUN %s')
-            raise exception.VolumeBackendAPIException(data=msg % handle)
-        iqn = target_details.Iqn
-        if not iqn:
-            msg = _('Failed to get target IQN for the LUN %s')
-            raise exception.VolumeBackendAPIException(data=msg % handle)
-
-        properties = {}
-        properties['target_discovered'] = False
-        (address, port) = (target_details.Address, target_details.Port)
-        properties['target_portal'] = '%s:%s' % (address, port)
-        properties['target_iqn'] = iqn
-        properties['target_lun'] = target_details.LunNumber
-        properties['volume_id'] = volume['id']
-
-        auth = volume['provider_auth']
-        if auth:
-            (auth_method, auth_username, auth_secret) = auth.split()
-            properties['auth_method'] = auth_method
-            properties['auth_username'] = auth_username
-            properties['auth_password'] = auth_secret
-
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': properties,
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Driver entry point to unattach a volume from an instance.
-
-        Unmask the LUN on the storage system so the given intiator can no
-        longer access it.
-        """
-        initiator_name = connector['initiator']
-        handle = volume['provider_location']
-        self.client.service.UnmapLun(Handle=handle, InitiatorType="iscsi",
-                                     InitiatorName=initiator_name)
-        msg = _("Unmapped LUN %(handle)s from the initiator "
-                "%(initiator_name)s")
-        LOG.debug(msg % locals())
-
-    def create_snapshot(self, snapshot):
-        """Driver entry point for creating a snapshot.
-
-        This driver implements snapshots by using efficient single-file
-        (LUN) cloning.
-        """
-        vol_name = snapshot['volume_name']
-        snapshot_name = snapshot['name']
-        lun = self.lun_table[vol_name]
-        extra_args = {'SpaceReserved': False}
-        self._clone_lun(lun.handle, snapshot_name, extra_args)
-
-    def delete_snapshot(self, snapshot):
-        """Driver entry point for deleting a snapshot."""
-        name = snapshot['name']
-        handle = self._get_lun_handle(name)
-        if not handle:
-            msg = _("No entry in LUN table for snapshot %(name)s.")
-            LOG.warn(msg % locals())
-            return
-        self.client.service.DestroyLun(Handle=handle)
-        LOG.debug(_("Destroyed LUN %s") % handle)
-        self.lun_table.pop(snapshot['name'])
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Driver entry point for creating a new volume from a snapshot.
-
-        Many would call this "cloning" and in fact we use cloning to implement
-        this feature.
-        """
-        vol_size = volume['size']
-        snap_size = snapshot['volume_size']
-        if vol_size != snap_size:
-            msg = _('Cannot create volume of size %(vol_size)s from '
-                    'snapshot of size %(snap_size)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        snapshot_name = snapshot['name']
-        lun = self.lun_table[snapshot_name]
-        new_name = volume['name']
-        extra_args = {}
-        extra_args['OsType'] = 'linux'
-        extra_args['QosType'] = self._get_qos_type(volume)
-        extra_args['Container'] = volume['project_id']
-        extra_args['Display'] = volume['display_name']
-        extra_args['Description'] = volume['display_description']
-        extra_args['SpaceReserved'] = True
-        self._clone_lun(lun.handle, new_name, extra_args)
-
-    def _get_qos_type(self, volume):
-        """Get the storage service type for a volume."""
-        type_id = volume['volume_type_id']
-        if not type_id:
-            return None
-        volume_type = volume_types.get_volume_type(None, type_id)
-        if not volume_type:
-            return None
-        return volume_type['name']
-
-    def _add_lun_to_table(self, lun):
-        """Adds LUN to cache table."""
-        if not isinstance(lun, NetAppLun):
-            msg = _("Object is not a NetApp LUN.")
-            raise exception.VolumeBackendAPIException(data=msg)
-        self.lun_table[lun.name] = lun
-
-    def _clone_lun(self, handle, new_name, extra_args):
-        """Clone LUN with the given handle to the new name."""
-        server = self.client.service
-        metadata = self._create_metadata_list(extra_args)
-        lun = server.CloneLun(Handle=handle, NewName=new_name,
-                              Metadata=metadata)
-        LOG.debug(_("Cloned LUN with new name %s") % new_name)
-        self._add_lun_to_table(
-            NetAppLun(lun.Handle,
-                      lun.Name,
-                      lun.Size,
-                      self._create_dict_from_meta(lun.Metadata)))
-
-    def _create_metadata_list(self, extra_args):
-        """Creates metadata from kwargs."""
-        metadata = []
-        for key in extra_args.keys():
-            meta = self.client.factory.create("Metadata")
-            meta.Key = key
-            meta.Value = extra_args[key]
-            metadata.append(meta)
-        return metadata
-
-    def _get_lun_handle(self, name):
-        """Get the details for a LUN from our cache table."""
-        if name not in self.lun_table:
-            LOG.warn(_("Could not find handle for LUN named %s") % name)
-            return None
-        return self.lun_table[name].handle
-
-    def _create_dict_from_meta(self, metadata):
-        """Creates dictionary from metadata array."""
-        meta_dict = {}
-        if not metadata:
-            return meta_dict
-        for meta in metadata:
-            meta_dict[meta.Key] = meta.Value
-        return meta_dict
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        vol_size = volume['size']
-        src_vol = self.lun_table[src_vref['name']]
-        src_vol_size = src_vref['size']
-        if vol_size != src_vol_size:
-            msg = _('Cannot clone volume of size %(vol_size)s from '
-                    'src volume of size %(src_vol_size)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        new_name = volume['name']
-        extra_args = {}
-        extra_args['OsType'] = 'linux'
-        extra_args['QosType'] = self._get_qos_type(volume)
-        extra_args['Container'] = volume['project_id']
-        extra_args['Display'] = volume['display_name']
-        extra_args['Description'] = volume['display_description']
-        extra_args['SpaceReserved'] = True
-        self._clone_lun(src_vol.handle, new_name, extra_args)
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first.
-        """
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'NetApp_iSCSI_Cluster'
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'iSCSI'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
-
-
-class NetAppDirectISCSIDriver(driver.ISCSIDriver):
-    """NetApp Direct iSCSI volume driver."""
-
-    IGROUP_PREFIX = 'openstack-'
-    required_flags = ['netapp_transport_type', 'netapp_login',
-                      'netapp_password', 'netapp_server_hostname',
-                      'netapp_server_port']
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppDirectISCSIDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(netapp_opts)
-        self.lun_table = {}
-
-    def _create_client(self, **kwargs):
-        """Instantiate a client for NetApp server.
-
-        This method creates NetApp server client for api communication.
-        """
-        host_filer = kwargs['hostname']
-        LOG.debug(_('Using NetApp filer: %s') % host_filer)
-        self.client = NaServer(host=host_filer,
-                               server_type=NaServer.SERVER_TYPE_FILER,
-                               transport_type=kwargs['transport_type'],
-                               style=NaServer.STYLE_LOGIN_PASSWORD,
-                               username=kwargs['login'],
-                               password=kwargs['password'])
-
-    def _do_custom_setup(self):
-        """Does custom setup depending on the type of filer."""
-        raise NotImplementedError()
-
-    def _check_flags(self):
-        """Ensure that the flags we care about are set."""
-        required_flags = self.required_flags
-        for flag in required_flags:
-            if not getattr(self.configuration, flag, None):
-                msg = _('%s is not set') % flag
-                raise exception.InvalidInput(data=msg)
-
-    def do_setup(self, context):
-        """Setup the NetApp Volume driver.
-
-        Called one time by the manager after the driver is loaded.
-        Validate the flags we care about and setup NetApp
-        client.
-        """
-        self._check_flags()
-        self._create_client(
-            transport_type=self.configuration.netapp_transport_type,
-            login=self.configuration.netapp_login,
-            password=self.configuration.netapp_password,
-            hostname=self.configuration.netapp_server_hostname,
-            port=self.configuration.netapp_server_port)
-        self._do_custom_setup()
-
-    def check_for_setup_error(self):
-        """Check that the driver is working and can communicate.
-
-        Discovers the LUNs on the NetApp server.
-        """
-        self.lun_table = {}
-        self._get_lun_list()
-        LOG.debug(_("Success getting LUN list from server"))
-
-    def create_volume(self, volume):
-        """Driver entry point for creating a new volume."""
-        default_size = '104857600'  # 100 MB
-        gigabytes = 1073741824L  # 2^30
-        name = volume['name']
-        if int(volume['size']) == 0:
-            size = default_size
-        else:
-            size = str(int(volume['size']) * gigabytes)
-        metadata = {}
-        metadata['OsType'] = 'linux'
-        metadata['SpaceReserved'] = 'true'
-        self._create_lun_on_eligible_vol(name, size, metadata)
-        LOG.debug(_("Created LUN with name %s") % name)
-        handle = self._create_lun_handle(metadata)
-        self._add_lun_to_table(NetAppLun(handle, name, size, metadata))
-
-    def delete_volume(self, volume):
-        """Driver entry point for destroying existing volumes."""
-        name = volume['name']
-        metadata = self._get_lun_attr(name, 'metadata')
-        if not metadata:
-            msg = _("No entry in LUN table for volume/snapshot %(name)s.")
-            LOG.warn(msg % locals())
-            return
-        lun_destroy = NaElement.create_node_with_children(
-            'lun-destroy',
-            **{'path': metadata['Path'],
-            'force': 'true'})
-        self.client.invoke_successfully(lun_destroy, True)
-        LOG.debug(_("Destroyed LUN %s") % name)
-        self.lun_table.pop(name)
-
-    def ensure_export(self, context, volume):
-        """Driver entry point to get the export info for an existing volume."""
-        handle = self._get_lun_attr(volume['name'], 'handle')
-        return {'provider_location': handle}
-
-    def create_export(self, context, volume):
-        """Driver entry point to get the export info for a new volume."""
-        handle = self._get_lun_attr(volume['name'], 'handle')
-        return {'provider_location': handle}
-
-    def remove_export(self, context, volume):
-        """Driver exntry point to remove an export for a volume.
-
-        Since exporting is idempotent in this driver, we have nothing
-        to do for unexporting.
-        """
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Driver entry point to attach a volume to an instance.
-
-        Do the LUN masking on the storage system so the initiator can access
-        the LUN on the target. Also return the iSCSI properties so the
-        initiator can find the LUN. This implementation does not call
-        _get_iscsi_properties() to get the properties because cannot store the
-        LUN number in the database. We only find out what the LUN number will
-        be during this method call so we construct the properties dictionary
-        ourselves.
-        """
-        initiator_name = connector['initiator']
-        name = volume['name']
-        lun_id = self._map_lun(name, initiator_name, 'iscsi', None)
-        msg = _("Mapped LUN %(name)s to the initiator %(initiator_name)s")
-        LOG.debug(msg % locals())
-        iqn = self._get_iscsi_service_details()
-        target_details_list = self._get_target_details()
-        msg = _("Succesfully fetched target details for LUN %(name)s and "
-                "initiator %(initiator_name)s")
-        LOG.debug(msg % locals())
-
-        if not target_details_list:
-            msg = _('Failed to get LUN target details for the LUN %s')
-            raise exception.VolumeBackendAPIException(data=msg % name)
-        target_details = None
-        for tgt_detail in target_details_list:
-            if tgt_detail.get('interface-enabled', 'true') == 'true':
-                target_details = tgt_detail
-                break
-        if not target_details:
-            target_details = target_details_list[0]
-
-        if not target_details['address'] and target_details['port']:
-            msg = _('Failed to get target portal for the LUN %s')
-            raise exception.VolumeBackendAPIException(data=msg % name)
-        if not iqn:
-            msg = _('Failed to get target IQN for the LUN %s')
-            raise exception.VolumeBackendAPIException(data=msg % name)
-
-        properties = {}
-        properties['target_discovered'] = False
-        (address, port) = (target_details['address'], target_details['port'])
-        properties['target_portal'] = '%s:%s' % (address, port)
-        properties['target_iqn'] = iqn
-        properties['target_lun'] = lun_id
-        properties['volume_id'] = volume['id']
-
-        auth = volume['provider_auth']
-        if auth:
-            (auth_method, auth_username, auth_secret) = auth.split()
-            properties['auth_method'] = auth_method
-            properties['auth_username'] = auth_username
-            properties['auth_password'] = auth_secret
-
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': properties,
-        }
-
-    def create_snapshot(self, snapshot):
-        """Driver entry point for creating a snapshot.
-
-        This driver implements snapshots by using efficient single-file
-        (LUN) cloning.
-        """
-        vol_name = snapshot['volume_name']
-        snapshot_name = snapshot['name']
-        lun = self.lun_table[vol_name]
-        self._clone_lun(lun.name, snapshot_name, 'false')
-
-    def delete_snapshot(self, snapshot):
-        """Driver entry point for deleting a snapshot."""
-        self.delete_volume(snapshot)
-        LOG.debug(_("Snapshot %s deletion successful") % snapshot['name'])
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Driver entry point for creating a new volume from a snapshot.
-
-        Many would call this "cloning" and in fact we use cloning to implement
-        this feature.
-        """
-        vol_size = volume['size']
-        snap_size = snapshot['volume_size']
-        if vol_size != snap_size:
-            msg = _('Cannot create volume of size %(vol_size)s from '
-                    'snapshot of size %(snap_size)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        snapshot_name = snapshot['name']
-        new_name = volume['name']
-        self._clone_lun(snapshot_name, new_name, 'true')
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Driver entry point to unattach a volume from an instance.
-
-        Unmask the LUN on the storage system so the given intiator can no
-        longer access it.
-        """
-        initiator_name = connector['initiator']
-        name = volume['name']
-        metadata = self._get_lun_attr(name, 'metadata')
-        path = metadata['Path']
-        self._unmap_lun(path, initiator_name)
-        msg = _("Unmapped LUN %(name)s from the initiator "
-                "%(initiator_name)s")
-        LOG.debug(msg % locals())
-
-    def _get_ontapi_version(self):
-        """Gets the supported ontapi version."""
-        ontapi_version = NaElement('system-get-ontapi-version')
-        res = self.client.invoke_successfully(ontapi_version, False)
-        major = res.get_child_content('major-version')
-        minor = res.get_child_content('minor-version')
-        return (major, minor)
-
-    def _create_lun_on_eligible_vol(self, name, size, metadata):
-        """Creates an actual lun on filer."""
-        req_size = float(size) *\
-            float(self.configuration.netapp_size_multiplier)
-        volume = self._get_avl_volume_by_size(req_size)
-        if not volume:
-            msg = _('Failed to get vol with required size for volume: %s')
-            raise exception.VolumeBackendAPIException(data=msg % name)
-        path = '/vol/%s/%s' % (volume['name'], name)
-        lun_create = NaElement.create_node_with_children(
-            'lun-create-by-size',
-            **{'path': path, 'size': size,
-            'ostype': metadata['OsType'],
-            'space-reservation-enabled':
-            metadata['SpaceReserved']})
-        self.client.invoke_successfully(lun_create, True)
-        metadata['Path'] = '/vol/%s/%s' % (volume['name'], name)
-        metadata['Volume'] = volume['name']
-        metadata['Qtree'] = None
-
-    def _get_avl_volume_by_size(self, size):
-        """Get the available volume by size."""
-        raise NotImplementedError()
-
-    def _get_iscsi_service_details(self):
-        """Returns iscsi iqn."""
-        raise NotImplementedError()
-
-    def _get_target_details(self):
-        """Gets the target portal details."""
-        raise NotImplementedError()
-
-    def _create_lun_handle(self, metadata):
-        """Returns lun handle based on filer type."""
-        raise NotImplementedError()
-
-    def _get_lun_list(self):
-        """Gets the list of luns on filer."""
-        raise NotImplementedError()
-
-    def _extract_and_populate_luns(self, api_luns):
-        """Extracts the luns from api.
-
-        Populates in the lun table.
-        """
-        for lun in api_luns:
-            meta_dict = self._create_lun_meta(lun)
-            path = lun.get_child_content('path')
-            (rest, splitter, name) = path.rpartition('/')
-            handle = self._create_lun_handle(meta_dict)
-            size = lun.get_child_content('size')
-            discovered_lun = NetAppLun(handle, name,
-                                       size, meta_dict)
-            self._add_lun_to_table(discovered_lun)
-
-    def _is_naelement(self, elem):
-        """Checks if element is NetApp element."""
-        if not isinstance(elem, NaElement):
-            raise ValueError('Expects NaElement')
-
-    def _map_lun(self, name, initiator, initiator_type='iscsi', lun_id=None):
-        """Maps lun to the initiator and returns lun id assigned."""
-        metadata = self._get_lun_attr(name, 'metadata')
-        os = metadata['OsType']
-        path = metadata['Path']
-        if self._check_allowed_os(os):
-            os = os
-        else:
-            os = 'default'
-        igroup_name = self._get_or_create_igroup(initiator,
-                                                 initiator_type, os)
-        lun_map = NaElement.create_node_with_children(
-            'lun-map', **{'path': path,
-            'initiator-group': igroup_name})
-        if lun_id:
-            lun_map.add_new_child('lun-id', lun_id)
-        try:
-            result = self.client.invoke_successfully(lun_map, True)
-            return result.get_child_content('lun-id-assigned')
-        except NaApiError as e:
-            code = e.code
-            message = e.message
-            msg = _('Error mapping lun. Code :%(code)s, Message:%(message)s')
-            LOG.warn(msg % locals())
-            (igroup, lun_id) = self._find_mapped_lun_igroup(path, initiator)
-            if lun_id is not None:
-                return lun_id
-            else:
-                raise e
-
-    def _unmap_lun(self, path, initiator):
-        """Unmaps a lun from given initiator."""
-        (igroup_name, lun_id) = self._find_mapped_lun_igroup(path, initiator)
-        lun_unmap = NaElement.create_node_with_children(
-            'lun-unmap',
-            **{'path': path,
-            'initiator-group': igroup_name})
-        try:
-            self.client.invoke_successfully(lun_unmap, True)
-        except NaApiError as e:
-            msg = _("Error unmapping lun. Code :%(code)s, Message:%(message)s")
-            code = e.code
-            message = e.message
-            LOG.warn(msg % locals())
-            # if the lun is already unmapped
-            if e.code == '13115' or e.code == '9016':
-                pass
-            else:
-                raise e
-
-    def _find_mapped_lun_igroup(self, path, initiator, os=None):
-        """Find the igroup for mapped lun with initiator."""
-        raise NotImplementedError()
-
-    def _get_or_create_igroup(self, initiator, initiator_type='iscsi',
-                              os='default'):
-        """Checks for an igroup for an initiator.
-
-        Creates igroup if not found.
-        """
-        igroups = self._get_igroup_by_initiator(initiator=initiator)
-        igroup_name = None
-        for igroup in igroups:
-            if igroup['initiator-group-os-type'] == os:
-                if igroup['initiator-group-type'] == initiator_type or \
-                        igroup['initiator-group-type'] == 'mixed':
-                    if igroup['initiator-group-name'].startswith(
-                            self.IGROUP_PREFIX):
-                        igroup_name = igroup['initiator-group-name']
-                        break
-        if not igroup_name:
-            igroup_name = self.IGROUP_PREFIX + str(uuid.uuid4())
-            self._create_igroup(igroup_name, initiator_type, os)
-            self._add_igroup_initiator(igroup_name, initiator)
-        return igroup_name
-
-    def _get_igroup_by_initiator(self, initiator):
-        """Get igroups by initiator."""
-        raise NotImplementedError()
-
-    def _check_allowed_os(self, os):
-        """Checks if the os type supplied is NetApp supported."""
-        if os in ['linux', 'aix', 'hpux', 'windows', 'solaris',
-                  'netware', 'vmware', 'openvms', 'xen', 'hyper_v']:
-            return True
-        else:
-            return False
-
-    def _create_igroup(self, igroup, igroup_type='iscsi', os_type='default'):
-        """Creates igoup with specified args."""
-        igroup_create = NaElement.create_node_with_children(
-            'igroup-create',
-            **{'initiator-group-name': igroup,
-            'initiator-group-type': igroup_type,
-            'os-type': os_type})
-        self.client.invoke_successfully(igroup_create, True)
-
-    def _add_igroup_initiator(self, igroup, initiator):
-        """Adds initiators to the specified igroup."""
-        igroup_add = NaElement.create_node_with_children(
-            'igroup-add',
-            **{'initiator-group-name': igroup,
-            'initiator': initiator})
-        self.client.invoke_successfully(igroup_add, True)
-
-    def _get_qos_type(self, volume):
-        """Get the storage service type for a volume."""
-        type_id = volume['volume_type_id']
-        if not type_id:
-            return None
-        volume_type = volume_types.get_volume_type(None, type_id)
-        if not volume_type:
-            return None
-        return volume_type['name']
-
-    def _add_lun_to_table(self, lun):
-        """Adds LUN to cache table."""
-        if not isinstance(lun, NetAppLun):
-            msg = _("Object is not a NetApp LUN.")
-            raise exception.VolumeBackendAPIException(data=msg)
-        self.lun_table[lun.name] = lun
-
-    def _clone_lun(self, name, new_name, space_reserved):
-        """Clone LUN with the given name to the new name."""
-        raise NotImplementedError()
-
-    def _get_lun_by_args(self, **args):
-        """Retrives lun with specified args."""
-        raise NotImplementedError()
-
-    def _get_lun_attr(self, name, attr):
-        """Get the attributes for a LUN from our cache table."""
-        if not name in self.lun_table or not hasattr(
-                self.lun_table[name], attr):
-            LOG.warn(_("Could not find attribute for LUN named %s") % name)
-            return None
-        return getattr(self.lun_table[name], attr)
-
-    def _create_lun_meta(self, lun):
-        raise NotImplementedError()
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        vol_size = volume['size']
-        src_vol = self.lun_table[src_vref['name']]
-        src_vol_size = src_vref['size']
-        if vol_size != src_vol_size:
-            msg = _('Cannot clone volume of size %(vol_size)s from '
-                    'src volume of size %(src_vol_size)s')
-            raise exception.VolumeBackendAPIException(data=msg % locals())
-        new_name = volume['name']
-        self._clone_lun(src_vol.name, new_name, 'true')
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-        raise NotImplementedError()
-
-
-class NetAppDirectCmodeISCSIDriver(NetAppDirectISCSIDriver):
-    """NetApp C-mode iSCSI volume driver."""
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppDirectCmodeISCSIDriver, self).__init__(*args, **kwargs)
-
-    def _do_custom_setup(self):
-        """Does custom setup for ontap cluster."""
-        self.vserver = self.configuration.netapp_vserver
-        # We set vserver in client permanently.
-        # To use tunneling enable_tunneling while invoking api
-        self.client.set_vserver(self.vserver)
-        # Default values to run first api
-        self.client.set_api_version(1, 15)
-        (major, minor) = self._get_ontapi_version()
-        self.client.set_api_version(major, minor)
-
-    def _get_avl_volume_by_size(self, size):
-        """Get the available volume by size."""
-        tag = None
-        while True:
-            vol_request = self._create_avl_vol_request(self.vserver, tag)
-            res = self.client.invoke_successfully(vol_request)
-            tag = res.get_child_content('next-tag')
-            attr_list = res.get_child_by_name('attributes-list')
-            vols = attr_list.get_children()
-            for vol in vols:
-                vol_space = vol.get_child_by_name('volume-space-attributes')
-                avl_size = vol_space.get_child_content('size-available')
-                if float(avl_size) >= float(size):
-                    avl_vol = dict()
-                    vol_id = vol.get_child_by_name('volume-id-attributes')
-                    avl_vol['name'] = vol_id.get_child_content('name')
-                    avl_vol['vserver'] = vol_id.get_child_content(
-                        'owning-vserver-name')
-                    avl_vol['size-available'] = avl_size
-                    return avl_vol
-            if tag is None:
-                break
-        return None
-
-    def _create_avl_vol_request(self, vserver, tag=None):
-        vol_get_iter = NaElement('volume-get-iter')
-        vol_get_iter.add_new_child('max-records', '100')
-        if tag:
-            vol_get_iter.add_new_child('tag', tag, True)
-        query = NaElement('query')
-        vol_get_iter.add_child_elem(query)
-        vol_attrs = NaElement('volume-attributes')
-        query.add_child_elem(vol_attrs)
-        if vserver:
-            vol_attrs.add_node_with_children(
-                'volume-id-attributes',
-                **{"owning-vserver-name": vserver})
-        vol_attrs.add_node_with_children(
-            'volume-state-attributes',
-            **{"is-vserver-root": "false", "state": "online"})
-        desired_attrs = NaElement('desired-attributes')
-        vol_get_iter.add_child_elem(desired_attrs)
-        des_vol_attrs = NaElement('volume-attributes')
-        desired_attrs.add_child_elem(des_vol_attrs)
-        des_vol_attrs.add_node_with_children(
-            'volume-id-attributes',
-            **{"name": None, "owning-vserver-name": None})
-        des_vol_attrs.add_node_with_children(
-            'volume-space-attributes',
-            **{"size-available": None})
-        des_vol_attrs.add_node_with_children('volume-state-attributes',
-                                             **{"is-cluster-volume": None,
-                                             "is-vserver-root": None,
-                                             "state": None})
-        return vol_get_iter
-
-    def _get_target_details(self):
-        """Gets the target portal details."""
-        iscsi_if_iter = NaElement('iscsi-interface-get-iter')
-        result = self.client.invoke_successfully(iscsi_if_iter, True)
-        tgt_list = []
-        if result.get_child_content('num-records')\
-                and int(result.get_child_content('num-records')) >= 1:
-            attr_list = result.get_child_by_name('attributes-list')
-            iscsi_if_list = attr_list.get_children()
-            for iscsi_if in iscsi_if_list:
-                d = dict()
-                d['address'] = iscsi_if.get_child_content('ip-address')
-                d['port'] = iscsi_if.get_child_content('ip-port')
-                d['tpgroup-tag'] = iscsi_if.get_child_content('tpgroup-tag')
-                d['interface-enabled'] = iscsi_if.get_child_content(
-                    'is-interface-enabled')
-                tgt_list.append(d)
-        return tgt_list
-
-    def _get_iscsi_service_details(self):
-        """Returns iscsi iqn."""
-        iscsi_service_iter = NaElement('iscsi-service-get-iter')
-        result = self.client.invoke_successfully(iscsi_service_iter, True)
-        if result.get_child_content('num-records') and\
-                int(result.get_child_content('num-records')) >= 1:
-            attr_list = result.get_child_by_name('attributes-list')
-            iscsi_service = attr_list.get_child_by_name('iscsi-service-info')
-            return iscsi_service.get_child_content('node-name')
-        LOG.debug(_('No iscsi service found for vserver %s') % (self.vserver))
-        return None
-
-    def _create_lun_handle(self, metadata):
-        """Returns lun handle based on filer type."""
-        return '%s:%s' % (self.vserver, metadata['Path'])
-
-    def _get_lun_list(self):
-        """Gets the list of luns on filer.
-
-        Gets the luns from cluster with vserver.
-        """
-        tag = None
-        while True:
-            api = NaElement('lun-get-iter')
-            api.add_new_child('max-records', '100')
-            if tag:
-                api.add_new_child('tag', tag, True)
-            lun_info = NaElement('lun-info')
-            lun_info.add_new_child('vserver', self.vserver)
-            query = NaElement('query')
-            query.add_child_elem(lun_info)
-            api.add_child_elem(query)
-            result = self.client.invoke_successfully(api)
-            if result.get_child_by_name('num-records') and\
-                    int(result.get_child_content('num-records')) >= 1:
-                attr_list = result.get_child_by_name('attributes-list')
-                self._extract_and_populate_luns(attr_list.get_children())
-            tag = result.get_child_content('next-tag')
-            if tag is None:
-                break
-
-    def _find_mapped_lun_igroup(self, path, initiator, os=None):
-        """Find the igroup for mapped lun with initiator."""
-        initiator_igroups = self._get_igroup_by_initiator(initiator=initiator)
-        lun_maps = self._get_lun_map(path)
-        if initiator_igroups and lun_maps:
-            for igroup in initiator_igroups:
-                igroup_name = igroup['initiator-group-name']
-                if igroup_name.startswith(self.IGROUP_PREFIX):
-                    for lun_map in lun_maps:
-                        if lun_map['initiator-group'] == igroup_name:
-                            return (igroup_name, lun_map['lun-id'])
-        return (None, None)
-
-    def _get_lun_map(self, path):
-        """Gets the lun map by lun path."""
-        tag = None
-        map_list = []
-        while True:
-            lun_map_iter = NaElement('lun-map-get-iter')
-            lun_map_iter.add_new_child('max-records', '100')
-            if tag:
-                lun_map_iter.add_new_child('tag', tag, True)
-            query = NaElement('query')
-            lun_map_iter.add_child_elem(query)
-            query.add_node_with_children('lun-map-info', **{'path': path})
-            result = self.client.invoke_successfully(lun_map_iter, True)
-            tag = result.get_child_content('next-tag')
-            if result.get_child_content('num-records') and \
-                    int(result.get_child_content('num-records')) >= 1:
-                attr_list = result.get_child_by_name('attributes-list')
-                lun_maps = attr_list.get_children()
-                for lun_map in lun_maps:
-                    lun_m = dict()
-                    lun_m['initiator-group'] = lun_map.get_child_content(
-                        'initiator-group')
-                    lun_m['lun-id'] = lun_map.get_child_content('lun-id')
-                    lun_m['vserver'] = lun_map.get_child_content('vserver')
-                    map_list.append(lun_m)
-            if tag is None:
-                break
-        return map_list
-
-    def _get_igroup_by_initiator(self, initiator):
-        """Get igroups by initiator."""
-        tag = None
-        igroup_list = []
-        while True:
-            igroup_iter = NaElement('igroup-get-iter')
-            igroup_iter.add_new_child('max-records', '100')
-            if tag:
-                igroup_iter.add_new_child('tag', tag, True)
-            query = NaElement('query')
-            igroup_iter.add_child_elem(query)
-            igroup_info = NaElement('initiator-group-info')
-            query.add_child_elem(igroup_info)
-            igroup_info.add_new_child('vserver', self.vserver)
-            initiators = NaElement('initiators')
-            igroup_info.add_child_elem(initiators)
-            initiators.add_node_with_children('initiator-info',
-                                              **{'initiator-name': initiator})
-            des_attrs = NaElement('desired-attributes')
-            des_ig_info = NaElement('initiator-group-info')
-            des_attrs.add_child_elem(des_ig_info)
-            des_ig_info.add_node_with_children('initiators',
-                                               **{'initiator-info': None})
-            des_ig_info.add_new_child('vserver', None)
-            des_ig_info.add_new_child('initiator-group-name', None)
-            des_ig_info.add_new_child('initiator-group-type', None)
-            des_ig_info.add_new_child('initiator-group-os-type', None)
-            igroup_iter.add_child_elem(des_attrs)
-            result = self.client.invoke_successfully(igroup_iter, False)
-            tag = result.get_child_content('next-tag')
-            if result.get_child_content('num-records') and\
-                    int(result.get_child_content('num-records')) > 0:
-                attr_list = result.get_child_by_name('attributes-list')
-                igroups = attr_list.get_children()
-                for igroup in igroups:
-                    ig = dict()
-                    ig['initiator-group-os-type'] = igroup.get_child_content(
-                        'initiator-group-os-type')
-                    ig['initiator-group-type'] = igroup.get_child_content(
-                        'initiator-group-type')
-                    ig['initiator-group-name'] = igroup.get_child_content(
-                        'initiator-group-name')
-                    igroup_list.append(ig)
-            if tag is None:
-                break
-        return igroup_list
-
-    def _clone_lun(self, name, new_name, space_reserved):
-        """Clone LUN with the given handle to the new name."""
-        metadata = self._get_lun_attr(name, 'metadata')
-        volume = metadata['Volume']
-        clone_create = NaElement.create_node_with_children(
-            'clone-create',
-            **{'volume': volume, 'source-path': name,
-            'destination-path': new_name,
-            'space-reserve': space_reserved})
-        self.client.invoke_successfully(clone_create, True)
-        LOG.debug(_("Cloned LUN with new name %s") % new_name)
-        lun = self._get_lun_by_args(vserver=self.vserver, path='/vol/%s/%s'
-                                    % (volume, new_name))
-        if len(lun) == 0:
-            msg = _("No clonned lun named %s found on the filer")
-            raise exception.VolumeBackendAPIException(data=msg % (new_name))
-        clone_meta = self._create_lun_meta(lun[0])
-        self._add_lun_to_table(NetAppLun('%s:%s' % (clone_meta['Vserver'],
-                                                    clone_meta['Path']),
-                                         new_name,
-                                         lun[0].get_child_content('size'),
-                                         clone_meta))
-
-    def _get_lun_by_args(self, **args):
-        """Retrives lun with specified args."""
-        lun_iter = NaElement('lun-get-iter')
-        lun_iter.add_new_child('max-records', '100')
-        query = NaElement('query')
-        lun_iter.add_child_elem(query)
-        query.add_node_with_children('lun-info', **args)
-        luns = self.client.invoke_successfully(lun_iter)
-        attr_list = luns.get_child_by_name('attributes-list')
-        return attr_list.get_children()
-
-    def _create_lun_meta(self, lun):
-        """Creates lun metadata dictionary."""
-        self._is_naelement(lun)
-        meta_dict = {}
-        self._is_naelement(lun)
-        meta_dict['Vserver'] = lun.get_child_content('vserver')
-        meta_dict['Volume'] = lun.get_child_content('volume')
-        meta_dict['Qtree'] = lun.get_child_content('qtree')
-        meta_dict['Path'] = lun.get_child_content('path')
-        meta_dict['OsType'] = lun.get_child_content('multiprotocol-type')
-        meta_dict['SpaceReserved'] = \
-            lun.get_child_content('is-space-reservation-enabled')
-        return meta_dict
-
-    def _configure_tunneling(self, do_tunneling=False):
-        """Configures tunneling for ontap cluster."""
-        if do_tunneling:
-            self.client.set_vserver(self.vserver)
-        else:
-            self.client.set_vserver(None)
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = (backend_name
-                                       or 'NetApp_iSCSI_Cluster_direct')
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'iSCSI'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
-
-
-class NetAppDirect7modeISCSIDriver(NetAppDirectISCSIDriver):
-    """NetApp 7-mode iSCSI volume driver."""
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppDirect7modeISCSIDriver, self).__init__(*args, **kwargs)
-
-    def _do_custom_setup(self):
-        """Does custom setup depending on the type of filer."""
-        self.vfiler = self.configuration.netapp_vfiler
-        self.volume_list = self.configuration.netapp_volume_list
-        if self.volume_list:
-            self.volume_list = self.volume_list.split(',')
-            self.volume_list = [el.strip() for el in self.volume_list]
-        if self.vfiler:
-            (major, minor) = self._get_ontapi_version()
-            self.client.set_api_version(major, minor)
-            self.client.set_vfiler(self.vfiler)
-
-    def _get_avl_volume_by_size(self, size):
-        """Get the available volume by size."""
-        vol_request = NaElement('volume-list-info')
-        res = self.client.invoke_successfully(vol_request, True)
-        volumes = res.get_child_by_name('volumes')
-        vols = volumes.get_children()
-        for vol in vols:
-            avl_size = vol.get_child_content('size-available')
-            state = vol.get_child_content('state')
-            if float(avl_size) >= float(size) and state == 'online':
-                avl_vol = dict()
-                avl_vol['name'] = vol.get_child_content('name')
-                avl_vol['block-type'] = vol.get_child_content('block-type')
-                avl_vol['type'] = vol.get_child_content('type')
-                avl_vol['size-available'] = avl_size
-                if self.volume_list:
-                    if avl_vol['name'] in self.volume_list:
-                        return avl_vol
-                else:
-                    if self._check_vol_not_root(avl_vol):
-                        return avl_vol
-        return None
-
-    def _check_vol_not_root(self, vol):
-        """Checks if a volume is not root."""
-        vol_options = NaElement.create_node_with_children(
-            'volume-options-list-info', **{'volume': vol['name']})
-        result = self.client.invoke_successfully(vol_options, True)
-        options = result.get_child_by_name('options')
-        ops = options.get_children()
-        for op in ops:
-            if op.get_child_content('name') == 'root' and\
-                    op.get_child_content('value') == 'true':
-                return False
-        return True
-
-    def _get_igroup_by_initiator(self, initiator):
-        """Get igroups by initiator."""
-        igroup_list = NaElement('igroup-list-info')
-        result = self.client.invoke_successfully(igroup_list, True)
-        igroups = []
-        igs = result.get_child_by_name('initiator-groups')
-        if igs:
-            ig_infos = igs.get_children()
-            if ig_infos:
-                for info in ig_infos:
-                    initiators = info.get_child_by_name('initiators')
-                    init_infos = initiators.get_children()
-                    if init_infos:
-                        for init in init_infos:
-                            if init.get_child_content('initiator-name')\
-                                    == initiator:
-                                d = dict()
-                                d['initiator-group-os-type'] = \
-                                    info.get_child_content(
-                                        'initiator-group-os-type')
-                                d['initiator-group-type'] = \
-                                    info.get_child_content(
-                                        'initiator-group-type')
-                                d['initiator-group-name'] = \
-                                    info.get_child_content(
-                                        'initiator-group-name')
-                                igroups.append(d)
-        return igroups
-
-    def _get_target_details(self):
-        """Gets the target portal details."""
-        iscsi_if_iter = NaElement('iscsi-portal-list-info')
-        result = self.client.invoke_successfully(iscsi_if_iter, True)
-        tgt_list = []
-        portal_list_entries = result.get_child_by_name(
-            'iscsi-portal-list-entries')
-        if portal_list_entries:
-            portal_list = portal_list_entries.get_children()
-            for iscsi_if in portal_list:
-                d = dict()
-                d['address'] = iscsi_if.get_child_content('ip-address')
-                d['port'] = iscsi_if.get_child_content('ip-port')
-                d['tpgroup-tag'] = iscsi_if.get_child_content('tpgroup-tag')
-                tgt_list.append(d)
-        return tgt_list
-
-    def _get_iscsi_service_details(self):
-        """Returns iscsi iqn."""
-        iscsi_service_iter = NaElement('iscsi-node-get-name')
-        result = self.client.invoke_successfully(iscsi_service_iter, True)
-        return result.get_child_content('node-name')
-
-    def _create_lun_handle(self, metadata):
-        """Returns lun handle based on filer type."""
-        if self.vfiler:
-            owner = '%s:%s' % (self.configuration.netapp_server_hostname,
-                               self.vfiler)
-        else:
-            owner = self.configuration.netapp_server_hostname
-        return '%s:%s' % (owner, metadata['Path'])
-
-    def _get_lun_list(self):
-        """Gets the list of luns on filer."""
-        lun_list = []
-        if self.volume_list:
-            for vol in self.volume_list:
-                try:
-                    luns = self._get_vol_luns(vol)
-                    if luns:
-                        lun_list.extend(luns)
-                except NaApiError:
-                    LOG.warn(_("Error finding luns for volume %(vol)s."
-                               " Verify volume exists.") % locals())
-        else:
-            luns = self._get_vol_luns(None)
-            lun_list.extend(luns)
-        self._extract_and_populate_luns(lun_list)
-
-    def _get_vol_luns(self, vol_name):
-        """Gets the luns for a volume."""
-        api = NaElement('lun-list-info')
-        if vol_name:
-            api.add_new_child('volume-name', vol_name)
-        result = self.client.invoke_successfully(api, True)
-        luns = result.get_child_by_name('luns')
-        return luns.get_children()
-
-    def _find_mapped_lun_igroup(self, path, initiator, os=None):
-        """Find the igroup for mapped lun with initiator."""
-        lun_map_list = NaElement.create_node_with_children(
-            'lun-map-list-info',
-            **{'path': path})
-        result = self.client.invoke_successfully(lun_map_list, True)
-        igroups = result.get_child_by_name('initiator-groups')
-        if igroups:
-            igroup = None
-            lun_id = None
-            found = False
-            igroup_infs = igroups.get_children()
-            for ig in igroup_infs:
-                initiators = ig.get_child_by_name('initiators')
-                init_infs = initiators.get_children()
-                for info in init_infs:
-                    if info.get_child_content('initiator-name') == initiator:
-                        found = True
-                        igroup = ig.get_child_content('initiator-group-name')
-                        lun_id = ig.get_child_content('lun-id')
-                        break
-                if found:
-                    break
-        return (igroup, lun_id)
-
-    def _clone_lun(self, name, new_name, space_reserved):
-        """Clone LUN with the given handle to the new name."""
-        metadata = self._get_lun_attr(name, 'metadata')
-        path = metadata['Path']
-        (parent, splitter, name) = path.rpartition('/')
-        clone_path = '%s/%s' % (parent, new_name)
-        clone_start = NaElement.create_node_with_children(
-            'clone-start',
-            **{'source-path': path, 'destination-path': clone_path,
-            'no-snap': 'true'})
-        result = self.client.invoke_successfully(clone_start, True)
-        clone_id_el = result.get_child_by_name('clone-id')
-        cl_id_info = clone_id_el.get_child_by_name('clone-id-info')
-        vol_uuid = cl_id_info.get_child_content('volume-uuid')
-        clone_id = cl_id_info.get_child_content('clone-op-id')
-        if vol_uuid:
-            self._check_clone_status(clone_id, vol_uuid, name, new_name)
-        cloned_lun = self._get_lun_by_args(path=clone_path)
-        if cloned_lun:
-            self._set_space_reserve(clone_path, space_reserved)
-            clone_meta = self._create_lun_meta(cloned_lun)
-            handle = self._create_lun_handle(clone_meta)
-            self._add_lun_to_table(
-                NetAppLun(handle, new_name,
-                          cloned_lun.get_child_content('size'),
-                          clone_meta))
-        else:
-            raise NaApiError('ENOLUNENTRY', 'No Lun entry found on the filer')
-
-    def _set_space_reserve(self, path, enable):
-        """Sets the space reserve info."""
-        space_res = NaElement.create_node_with_children(
-            'lun-set-space-reservation-info',
-            **{'path': path, 'enable': enable})
-        self.client.invoke_successfully(space_res, True)
-
-    def _check_clone_status(self, clone_id, vol_uuid, name, new_name):
-        """Checks for the job till completed."""
-        clone_status = NaElement('clone-list-status')
-        cl_id = NaElement('clone-id')
-        clone_status.add_child_elem(cl_id)
-        cl_id.add_node_with_children(
-            'clone-id-info',
-            **{'clone-op-id': clone_id, 'volume-uuid': vol_uuid})
-        running = True
-        clone_ops_info = None
-        while running:
-            result = self.client.invoke_successfully(clone_status, True)
-            status = result.get_child_by_name('status')
-            ops_info = status.get_children()
-            if ops_info:
-                for info in ops_info:
-                    if info.get_child_content('clone-state') == 'running':
-                        time.sleep(1)
-                        break
-                    else:
-                        running = False
-                        clone_ops_info = info
-                        break
-        else:
-            if clone_ops_info:
-                if clone_ops_info.get_child_content('clone-state')\
-                        == 'completed':
-                    LOG.debug(_("Clone operation with src %(name)s"
-                                " and dest %(new_name)s completed") % locals())
-                else:
-                    LOG.debug(_("Clone operation with src %(name)s"
-                                " and dest %(new_name)s failed") % locals())
-                    raise NaApiError(
-                        clone_ops_info.get_child_content('error'),
-                        clone_ops_info.get_child_content('reason'))
-
-    def _get_lun_by_args(self, **args):
-        """Retrives lun with specified args."""
-        lun_info = NaElement.create_node_with_children('lun-list-info', **args)
-        result = self.client.invoke_successfully(lun_info, True)
-        luns = result.get_child_by_name('luns')
-        if luns:
-            infos = luns.get_children()
-            if infos:
-                return infos[0]
-        return None
-
-    def _create_lun_meta(self, lun):
-        """Creates lun metadata dictionary."""
-        self._is_naelement(lun)
-        meta_dict = {}
-        self._is_naelement(lun)
-        meta_dict['Path'] = lun.get_child_content('path')
-        meta_dict['OsType'] = lun.get_child_content('multiprotocol-type')
-        meta_dict['SpaceReserved'] = lun.get_child_content(
-            'is-space-reservation-enabled')
-        return meta_dict
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = (backend_name
-                                       or 'NetApp_iSCSI_7mode_direct')
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'iSCSI'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
diff --git a/manila/volume/drivers/netapp/nfs.py b/manila/volume/drivers/netapp/nfs.py
deleted file mode 100644
index 80acf83d12..0000000000
--- a/manila/volume/drivers/netapp/nfs.py
+++ /dev/null
@@ -1,624 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 NetApp, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Volume driver for NetApp NFS storage.
-"""
-
-import copy
-import os
-import time
-
-from oslo.config import cfg
-import suds
-from suds.sax import text
-
-from manila import exception
-from manila.openstack.common import log as logging
-from manila.volume.drivers.netapp.api import NaApiError
-from manila.volume.drivers.netapp.api import NaElement
-from manila.volume.drivers.netapp.api import NaServer
-from manila.volume.drivers.netapp.iscsi import netapp_opts
-from manila.volume.drivers import nfs
-
-LOG = logging.getLogger(__name__)
-
-netapp_nfs_opts = [
-    cfg.IntOpt('synchronous_snapshot_create',
-               default=0,
-               help='Does snapshot creation call returns immediately')]
-
-
-class NetAppNFSDriver(nfs.NfsDriver):
-    """Executes commands relating to Volumes."""
-    def __init__(self, *args, **kwargs):
-        # NOTE(vish): db is set by Manager
-        self._execute = None
-        self._context = None
-        super(NetAppNFSDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(netapp_opts)
-        self.configuration.append_config_values(netapp_nfs_opts)
-
-    def set_execute(self, execute):
-        self._execute = execute
-
-    def do_setup(self, context):
-        self._context = context
-        self.check_for_setup_error()
-        self._client = self._get_client()
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_dfm_flags()
-        super(NetAppNFSDriver, self).check_for_setup_error()
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-        vol_size = volume.size
-        snap_size = snapshot.volume_size
-
-        if vol_size != snap_size:
-            msg = _('Cannot create volume of size %(vol_size)s from '
-                    'snapshot of size %(snap_size)s')
-            raise exception.CinderException(msg % locals())
-
-        self._clone_volume(snapshot.name, volume.name, snapshot.volume_id)
-        share = self._get_volume_location(snapshot.volume_id)
-
-        return {'provider_location': share}
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        self._clone_volume(snapshot['volume_name'],
-                           snapshot['name'],
-                           snapshot['volume_id'])
-
-    def delete_snapshot(self, snapshot):
-        """Deletes a snapshot."""
-        nfs_mount = self._get_provider_location(snapshot.volume_id)
-
-        if self._volume_not_present(nfs_mount, snapshot.name):
-            return True
-
-        self._execute('rm', self._get_volume_path(nfs_mount, snapshot.name),
-                      run_as_root=True)
-
-    def _check_dfm_flags(self):
-        """Raises error if any required configuration flag for OnCommand proxy
-        is missing."""
-        required_flags = ['netapp_wsdl_url',
-                          'netapp_login',
-                          'netapp_password',
-                          'netapp_server_hostname',
-                          'netapp_server_port']
-        for flag in required_flags:
-            if not getattr(self.configuration, flag, None):
-                raise exception.CinderException(_('%s is not set') % flag)
-
-    def _get_client(self):
-        """Creates SOAP _client for ONTAP-7 DataFabric Service."""
-        client = suds.client.Client(
-            self.configuration.netapp_wsdl_url,
-            username=self.configuration.netapp_login,
-            password=self.configuration.netapp_password)
-        soap_url = 'http://%s:%s/apis/soap/v1' % (
-            self.configuration.netapp_server_hostname,
-            self.configuration.netapp_server_port)
-        client.set_options(location=soap_url)
-
-        return client
-
-    def _get_volume_location(self, volume_id):
-        """Returns NFS mount address as <nfs_ip_address>:<nfs_mount_dir>"""
-        nfs_server_ip = self._get_host_ip(volume_id)
-        export_path = self._get_export_path(volume_id)
-        return (nfs_server_ip + ':' + export_path)
-
-    def _clone_volume(self, volume_name, clone_name, volume_id):
-        """Clones mounted volume with OnCommand proxy API."""
-        host_id = self._get_host_id(volume_id)
-        export_path = self._get_full_export_path(volume_id, host_id)
-
-        request = self._client.factory.create('Request')
-        request.Name = 'clone-start'
-
-        clone_start_args = ('<source-path>%s/%s</source-path>'
-                            '<destination-path>%s/%s</destination-path>')
-
-        request.Args = text.Raw(clone_start_args % (export_path,
-                                                    volume_name,
-                                                    export_path,
-                                                    clone_name))
-
-        resp = self._client.service.ApiProxy(Target=host_id,
-                                             Request=request)
-
-        if (resp.Status == 'passed' and
-                self.configuration.synchronous_snapshot_create):
-            clone_id = resp.Results['clone-id'][0]
-            clone_id_info = clone_id['clone-id-info'][0]
-            clone_operation_id = int(clone_id_info['clone-op-id'][0])
-
-            self._wait_for_clone_finished(clone_operation_id, host_id)
-        elif resp.Status == 'failed':
-            raise exception.CinderException(resp.Reason)
-
-    def _wait_for_clone_finished(self, clone_operation_id, host_id):
-        """
-        Polls ONTAP7 for clone status. Returns once clone is finished.
-        :param clone_operation_id: Identifier of ONTAP clone operation
-        """
-        clone_list_options = ('<clone-id>'
-                              '<clone-id-info>'
-                              '<clone-op-id>%d</clone-op-id>'
-                              '<volume-uuid></volume-uuid>'
-                              '</clone-id>'
-                              '</clone-id-info>')
-
-        request = self._client.factory.create('Request')
-        request.Name = 'clone-list-status'
-        request.Args = text.Raw(clone_list_options % clone_operation_id)
-
-        resp = self._client.service.ApiProxy(Target=host_id, Request=request)
-
-        while resp.Status != 'passed':
-            time.sleep(1)
-            resp = self._client.service.ApiProxy(Target=host_id,
-                                                 Request=request)
-
-    def _get_provider_location(self, volume_id):
-        """
-        Returns provider location for given volume
-        :param volume_id:
-        """
-        volume = self.db.volume_get(self._context, volume_id)
-        return volume.provider_location
-
-    def _get_host_ip(self, volume_id):
-        """Returns IP address for the given volume."""
-        return self._get_provider_location(volume_id).split(':')[0]
-
-    def _get_export_path(self, volume_id):
-        """Returns NFS export path for the given volume."""
-        return self._get_provider_location(volume_id).split(':')[1]
-
-    def _get_host_id(self, volume_id):
-        """Returns ID of the ONTAP-7 host."""
-        host_ip = self._get_host_ip(volume_id)
-        server = self._client.service
-
-        resp = server.HostListInfoIterStart(ObjectNameOrId=host_ip)
-        tag = resp.Tag
-
-        try:
-            res = server.HostListInfoIterNext(Tag=tag, Maximum=1)
-            if hasattr(res, 'Hosts') and res.Hosts.HostInfo:
-                return res.Hosts.HostInfo[0].HostId
-        finally:
-            server.HostListInfoIterEnd(Tag=tag)
-
-    def _get_full_export_path(self, volume_id, host_id):
-        """Returns full path to the NFS share, e.g. /vol/vol0/home."""
-        export_path = self._get_export_path(volume_id)
-        command_args = '<pathname>%s</pathname>'
-
-        request = self._client.factory.create('Request')
-        request.Name = 'nfs-exportfs-storage-path'
-        request.Args = text.Raw(command_args % export_path)
-
-        resp = self._client.service.ApiProxy(Target=host_id,
-                                             Request=request)
-
-        if resp.Status == 'passed':
-            return resp.Results['actual-pathname'][0]
-        elif resp.Status == 'failed':
-            raise exception.CinderException(resp.Reason)
-
-    def _volume_not_present(self, nfs_mount, volume_name):
-        """Check if volume exists."""
-        try:
-            self._try_execute('ls', self._get_volume_path(nfs_mount,
-                                                          volume_name))
-        except exception.ProcessExecutionError:
-            # If the volume isn't present
-            return True
-        return False
-
-    def _try_execute(self, *command, **kwargs):
-        # NOTE(vish): Volume commands can partially fail due to timing, but
-        #             running them a second time on failure will usually
-        #             recover nicely.
-        tries = 0
-        while True:
-            try:
-                self._execute(*command, **kwargs)
-                return True
-            except exception.ProcessExecutionError:
-                tries = tries + 1
-                if tries >= self.configuration.num_shell_tries:
-                    raise
-                LOG.exception(_("Recovering from a failed execute.  "
-                                "Try number %s"), tries)
-                time.sleep(tries ** 2)
-
-    def _get_volume_path(self, nfs_share, volume_name):
-        """Get volume path (local fs path) for given volume name on given nfs
-        share
-        @param nfs_share string, example 172.18.194.100:/var/nfs
-        @param volume_name string,
-            example volume-91ee65ec-c473-4391-8c09-162b00c68a8c
-        """
-        return os.path.join(self._get_mount_point_for_share(nfs_share),
-                            volume_name)
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        vol_size = volume.size
-        src_vol_size = src_vref.size
-
-        if vol_size != src_vol_size:
-            msg = _('Cannot create clone of size %(vol_size)s from '
-                    'volume of size %(src_vol_size)s')
-            raise exception.CinderException(msg % locals())
-
-        self._clone_volume(src_vref.name, volume.name, src_vref.id)
-        share = self._get_volume_location(src_vref.id)
-
-        return {'provider_location': share}
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-        super(NetAppNFSDriver, self)._update_volume_status()
-
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        self._stats["volume_backend_name"] = (backend_name or
-                                              'NetApp_NFS_7mode')
-        self._stats["vendor_name"] = 'NetApp'
-        self._stats["driver_version"] = '1.0'
-
-
-class NetAppCmodeNfsDriver (NetAppNFSDriver):
-    """Executes commands related to volumes on c mode."""
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppCmodeNfsDriver, self).__init__(*args, **kwargs)
-
-    def do_setup(self, context):
-        self._context = context
-        self.check_for_setup_error()
-        self._client = self._get_client()
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_flags()
-
-    def _clone_volume(self, volume_name, clone_name, volume_id):
-        """Clones mounted volume with NetApp Cloud Services."""
-        host_ip = self._get_host_ip(volume_id)
-        export_path = self._get_export_path(volume_id)
-        LOG.debug(_("""Cloning with params ip %(host_ip)s, exp_path
-                    %(export_path)s, vol %(volume_name)s,
-                    clone_name %(clone_name)s""") % locals())
-        self._client.service.CloneNasFile(host_ip, export_path,
-                                          volume_name, clone_name)
-
-    def _check_flags(self):
-        """Raises error if any required configuration flag for NetApp Cloud
-        Webservices is missing."""
-        required_flags = ['netapp_wsdl_url',
-                          'netapp_login',
-                          'netapp_password',
-                          'netapp_server_hostname',
-                          'netapp_server_port']
-        for flag in required_flags:
-            if not getattr(self.configuration, flag, None):
-                raise exception.CinderException(_('%s is not set') % flag)
-
-    def _get_client(self):
-        """Creates SOAP _client for NetApp Cloud service."""
-        client = suds.client.Client(
-            self.configuration.netapp_wsdl_url,
-            username=self.configuration.netapp_login,
-            password=self.configuration.netapp_password)
-        return client
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-        super(NetAppCmodeNfsDriver, self)._update_volume_status()
-
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        self._stats["volume_backend_name"] = (backend_name or
-                                              'NetApp_NFS_Cluster')
-        self._stats["vendor_name"] = 'NetApp'
-        self._stats["driver_version"] = '1.0'
-
-
-class NetAppDirectNfsDriver (NetAppNFSDriver):
-    """Executes commands related to volumes on NetApp filer."""
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppDirectNfsDriver, self).__init__(*args, **kwargs)
-
-    def do_setup(self, context):
-        self._context = context
-        self.check_for_setup_error()
-        self._client = self._get_client()
-        self._do_custom_setup(self._client)
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_flags()
-
-    def _clone_volume(self, volume_name, clone_name, volume_id):
-        """Clones mounted volume on NetApp filer."""
-        raise NotImplementedError()
-
-    def _check_flags(self):
-        """Raises error if any required configuration flag for NetApp
-        filer is missing."""
-        required_flags = ['netapp_login',
-                          'netapp_password',
-                          'netapp_server_hostname',
-                          'netapp_server_port',
-                          'netapp_transport_type']
-        for flag in required_flags:
-            if not getattr(self.configuration, flag, None):
-                raise exception.CinderException(_('%s is not set') % flag)
-
-    def _get_client(self):
-        """Creates NetApp api client."""
-        client = NaServer(
-            host=self.configuration.netapp_server_hostname,
-            server_type=NaServer.SERVER_TYPE_FILER,
-            transport_type=self.configuration.netapp_transport_type,
-            style=NaServer.STYLE_LOGIN_PASSWORD,
-            username=self.configuration.netapp_login,
-            password=self.configuration.netapp_password)
-        return client
-
-    def _do_custom_setup(self, client):
-        """Do the customized set up on client if any for different types."""
-        raise NotImplementedError()
-
-    def _is_naelement(self, elem):
-        """Checks if element is NetApp element."""
-        if not isinstance(elem, NaElement):
-            raise ValueError('Expects NaElement')
-
-    def _invoke_successfully(self, na_element, vserver=None):
-        """Invoke the api for successful result.
-
-        If vserver is present then invokes vserver/vfiler api
-        else filer/Cluster api.
-        :param vserver: vserver/vfiler name.
-        """
-        self._is_naelement(na_element)
-        server = copy.copy(self._client)
-        if vserver:
-            server.set_vserver(vserver)
-        else:
-            server.set_vserver(None)
-        result = server.invoke_successfully(na_element, True)
-        return result
-
-    def _get_ontapi_version(self):
-        """Gets the supported ontapi version."""
-        ontapi_version = NaElement('system-get-ontapi-version')
-        res = self._invoke_successfully(ontapi_version, False)
-        major = res.get_child_content('major-version')
-        minor = res.get_child_content('minor-version')
-        return (major, minor)
-
-
-class NetAppDirectCmodeNfsDriver (NetAppDirectNfsDriver):
-    """Executes commands related to volumes on c mode."""
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppDirectCmodeNfsDriver, self).__init__(*args, **kwargs)
-
-    def _do_custom_setup(self, client):
-        """Do the customized set up on client for cluster mode."""
-        # Default values to run first api
-        client.set_api_version(1, 15)
-        (major, minor) = self._get_ontapi_version()
-        client.set_api_version(major, minor)
-
-    def _clone_volume(self, volume_name, clone_name, volume_id):
-        """Clones mounted volume on NetApp Cluster."""
-        host_ip = self._get_host_ip(volume_id)
-        export_path = self._get_export_path(volume_id)
-        ifs = self._get_if_info_by_ip(host_ip)
-        vserver = ifs[0].get_child_content('vserver')
-        exp_volume = self._get_vol_by_junc_vserver(vserver, export_path)
-        self._clone_file(exp_volume, volume_name, clone_name, vserver)
-
-    def _get_if_info_by_ip(self, ip):
-        """Gets the network interface info by ip."""
-        net_if_iter = NaElement('net-interface-get-iter')
-        net_if_iter.add_new_child('max-records', '10')
-        query = NaElement('query')
-        net_if_iter.add_child_elem(query)
-        query.add_node_with_children('net-interface-info', **{'address': ip})
-        result = self._invoke_successfully(net_if_iter)
-        if result.get_child_content('num-records') and\
-                int(result.get_child_content('num-records')) >= 1:
-            attr_list = result.get_child_by_name('attributes-list')
-            return attr_list.get_children()
-        raise exception.NotFound(
-            _('No interface found on cluster for ip %s')
-            % (ip))
-
-    def _get_vol_by_junc_vserver(self, vserver, junction):
-        """Gets the volume by junction path and vserver."""
-        vol_iter = NaElement('volume-get-iter')
-        vol_iter.add_new_child('max-records', '10')
-        query = NaElement('query')
-        vol_iter.add_child_elem(query)
-        vol_attrs = NaElement('volume-attributes')
-        query.add_child_elem(vol_attrs)
-        vol_attrs.add_node_with_children(
-            'volume-id-attributes',
-            **{'junction-path': junction,
-            'owning-vserver-name': vserver})
-        des_attrs = NaElement('desired-attributes')
-        des_attrs.add_node_with_children('volume-attributes',
-                                         **{'volume-id-attributes': None})
-        vol_iter.add_child_elem(des_attrs)
-        result = self._invoke_successfully(vol_iter, vserver)
-        if result.get_child_content('num-records') and\
-                int(result.get_child_content('num-records')) >= 1:
-            attr_list = result.get_child_by_name('attributes-list')
-            vols = attr_list.get_children()
-            vol_id = vols[0].get_child_by_name('volume-id-attributes')
-            return vol_id.get_child_content('name')
-        raise exception.NotFound(_("""No volume on cluster with vserver
-                                   %(vserver)s and junction path %(junction)s
-                                   """) % locals())
-
-    def _clone_file(self, volume, src_path, dest_path, vserver=None):
-        """Clones file on vserver."""
-        LOG.debug(_("""Cloning with params volume %(volume)s,src %(src_path)s,
-                    dest %(dest_path)s, vserver %(vserver)s""")
-                  % locals())
-        clone_create = NaElement.create_node_with_children(
-            'clone-create',
-            **{'volume': volume, 'source-path': src_path,
-            'destination-path': dest_path})
-        self._invoke_successfully(clone_create, vserver)
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-        super(NetAppDirectCmodeNfsDriver, self)._update_volume_status()
-
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        self._stats["volume_backend_name"] = (backend_name or
-                                              'NetApp_NFS_cluster_direct')
-        self._stats["vendor_name"] = 'NetApp'
-        self._stats["driver_version"] = '1.0'
-
-
-class NetAppDirect7modeNfsDriver (NetAppDirectNfsDriver):
-    """Executes commands related to volumes on 7 mode."""
-
-    def __init__(self, *args, **kwargs):
-        super(NetAppDirect7modeNfsDriver, self).__init__(*args, **kwargs)
-
-    def _do_custom_setup(self, client):
-        """Do the customized set up on client if any for 7 mode."""
-        (major, minor) = self._get_ontapi_version()
-        client.set_api_version(major, minor)
-
-    def _clone_volume(self, volume_name, clone_name, volume_id):
-        """Clones mounted volume with NetApp filer."""
-        export_path = self._get_export_path(volume_id)
-        storage_path = self._get_actual_path_for_export(export_path)
-        target_path = '%s/%s' % (storage_path, clone_name)
-        (clone_id, vol_uuid) = self._start_clone('%s/%s' % (storage_path,
-                                                            volume_name),
-                                                 target_path)
-        if vol_uuid:
-            try:
-                self._wait_for_clone_finish(clone_id, vol_uuid)
-            except NaApiError as e:
-                if e.code != 'UnknownCloneId':
-                    self._clear_clone(clone_id)
-                raise e
-
-    def _get_actual_path_for_export(self, export_path):
-        """Gets the actual path on the filer for export path."""
-        storage_path = NaElement.create_node_with_children(
-            'nfs-exportfs-storage-path', **{'pathname': export_path})
-        result = self._invoke_successfully(storage_path, None)
-        if result.get_child_content('actual-pathname'):
-            return result.get_child_content('actual-pathname')
-        raise exception.NotFound(_('No storage path found for export path %s')
-                                 % (export_path))
-
-    def _start_clone(self, src_path, dest_path):
-        """Starts the clone operation.
-
-        :returns: clone-id
-        """
-        LOG.debug(_("""Cloning with src %(src_path)s, dest %(dest_path)s""")
-                  % locals())
-        clone_start = NaElement.create_node_with_children(
-            'clone-start',
-            **{'source-path': src_path,
-            'destination-path': dest_path,
-            'no-snap': 'true'})
-        result = self._invoke_successfully(clone_start, None)
-        clone_id_el = result.get_child_by_name('clone-id')
-        cl_id_info = clone_id_el.get_child_by_name('clone-id-info')
-        vol_uuid = cl_id_info.get_child_content('volume-uuid')
-        clone_id = cl_id_info.get_child_content('clone-op-id')
-        return (clone_id, vol_uuid)
-
-    def _wait_for_clone_finish(self, clone_op_id, vol_uuid):
-        """Waits till a clone operation is complete or errored out."""
-        clone_ls_st = NaElement('clone-list-status')
-        clone_id = NaElement('clone-id')
-        clone_ls_st.add_child_elem(clone_id)
-        clone_id.add_node_with_children('clone-id-info',
-                                        **{'clone-op-id': clone_op_id,
-                                        'volume-uuid': vol_uuid})
-        task_running = True
-        while task_running:
-            result = self._invoke_successfully(clone_ls_st, None)
-            status = result.get_child_by_name('status')
-            ops_info = status.get_children()
-            if ops_info:
-                state = ops_info[0].get_child_content('clone-state')
-                if state == 'completed':
-                    task_running = False
-                elif state == 'failed':
-                    code = ops_info[0].get_child_content('error')
-                    reason = ops_info[0].get_child_content('reason')
-                    raise NaApiError(code, reason)
-                else:
-                    time.sleep(1)
-            else:
-                raise NaApiError(
-                    'UnknownCloneId',
-                    'No clone operation for clone id %s found on the filer'
-                    % (clone_id))
-
-    def _clear_clone(self, clone_id):
-        """Clear the clone information.
-
-        Invoke this in case of failed clone.
-        """
-        clone_clear = NaElement.create_node_with_children(
-            'clone-clear',
-            **{'clone-id': clone_id})
-        retry = 3
-        while retry:
-            try:
-                self._invoke_successfully(clone_clear, None)
-                break
-            except Exception as e:
-                # Filer might be rebooting
-                time.sleep(5)
-            retry = retry - 1
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-        super(NetAppDirect7modeNfsDriver, self)._update_volume_status()
-
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        self._stats["volume_backend_name"] = (backend_name or
-                                              'NetApp_NFS_7mode_direct')
-        self._stats["vendor_name"] = 'NetApp'
-        self._stats["driver_version"] = '1.0'
diff --git a/manila/volume/drivers/nexenta/__init__.py b/manila/volume/drivers/nexenta/__init__.py
deleted file mode 100644
index 3050df8f66..0000000000
--- a/manila/volume/drivers/nexenta/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2011 Nexenta Systems, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-:mod:`nexenta` -- Package contains Nexenta-specific modules
-=====================================================================
-
-.. automodule:: nexenta
-.. moduleauthor:: Yuriy Taraday <yorik.sar@gmail.com>
-"""
-
-
-class NexentaException(Exception):
-    MESSAGE = _('Nexenta SA returned the error')
-
-    def __init__(self, error=None):
-        super(NexentaException, self).__init__(self.message, error)
-
-    def __str__(self):
-        return '%s: %s' % self.args
diff --git a/manila/volume/drivers/nexenta/jsonrpc.py b/manila/volume/drivers/nexenta/jsonrpc.py
deleted file mode 100644
index 4663c7044b..0000000000
--- a/manila/volume/drivers/nexenta/jsonrpc.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2011 Nexenta Systems, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-:mod:`nexenta.jsonrpc` -- Nexenta-specific JSON RPC client
-=====================================================================
-
-.. automodule:: nexenta.jsonrpc
-.. moduleauthor:: Yuriy Taraday <yorik.sar@gmail.com>
-"""
-
-import urllib2
-
-from manila.openstack.common import jsonutils
-from manila.openstack.common import log as logging
-from manila.volume.drivers import nexenta
-
-LOG = logging.getLogger(__name__)
-
-
-class NexentaJSONException(nexenta.NexentaException):
-    pass
-
-
-class NexentaJSONProxy(object):
-    def __init__(self, url, user, password, auto=False, obj=None, method=None):
-        self.url = url
-        self.user = user
-        self.password = password
-        self.auto = auto
-        self.obj = obj
-        self.method = method
-
-    def __getattr__(self, name):
-        if not self.obj:
-            obj, method = name, None
-        elif not self.method:
-            obj, method = self.obj, name
-        else:
-            obj, method = '%s.%s' % (self.obj, self.method), name
-        return NexentaJSONProxy(self.url, self.user, self.password, self.auto,
-                                obj, method)
-
-    def __call__(self, *args):
-        data = jsonutils.dumps({'object': self.obj,
-                                'method': self.method,
-                                'params': args})
-        auth = ('%s:%s' % (self.user, self.password)).encode('base64')[:-1]
-        headers = {'Content-Type': 'application/json',
-                   'Authorization': 'Basic %s' % (auth,)}
-        LOG.debug(_('Sending JSON data: %s'), data)
-        request = urllib2.Request(self.url, data, headers)
-        response_obj = urllib2.urlopen(request)
-        if response_obj.info().status == 'EOF in headers':
-            if self.auto and self.url.startswith('http://'):
-                LOG.info(_('Auto switching to HTTPS connection to %s'),
-                         self.url)
-                self.url = 'https' + self.url[4:]
-                request = urllib2.Request(self.url, data, headers)
-                response_obj = urllib2.urlopen(request)
-            else:
-                LOG.error(_('No headers in server response'))
-                raise NexentaJSONException(_('Bad response from server'))
-
-        response_data = response_obj.read()
-        LOG.debug(_('Got response: %s'), response_data)
-        response = jsonutils.loads(response_data)
-        if response.get('error') is not None:
-            raise NexentaJSONException(response['error'].get('message', ''))
-        else:
-            return response.get('result')
diff --git a/manila/volume/drivers/nexenta/volume.py b/manila/volume/drivers/nexenta/volume.py
deleted file mode 100644
index 89fd5e71ea..0000000000
--- a/manila/volume/drivers/nexenta/volume.py
+++ /dev/null
@@ -1,353 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2011 Nexenta Systems, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-:mod:`nexenta.volume` -- Driver to store volumes on Nexenta Appliance
-=====================================================================
-
-.. automodule:: nexenta.volume
-.. moduleauthor:: Yuriy Taraday <yorik.sar@gmail.com>
-"""
-
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila.volume import driver
-from manila.volume.drivers import nexenta
-from manila.volume.drivers.nexenta import jsonrpc
-
-VERSION = '1.0'
-LOG = logging.getLogger(__name__)
-FLAGS = flags.FLAGS
-
-nexenta_opts = [
-    cfg.StrOpt('nexenta_host',
-               default='',
-               help='IP address of Nexenta SA'),
-    cfg.IntOpt('nexenta_rest_port',
-               default=2000,
-               help='HTTP port to connect to Nexenta REST API server'),
-    cfg.StrOpt('nexenta_rest_protocol',
-               default='auto',
-               help='Use http or https for REST connection (default auto)'),
-    cfg.StrOpt('nexenta_user',
-               default='admin',
-               help='User name to connect to Nexenta SA'),
-    cfg.StrOpt('nexenta_password',
-               default='nexenta',
-               help='Password to connect to Nexenta SA',
-               secret=True),
-    cfg.IntOpt('nexenta_iscsi_target_portal_port',
-               default=3260,
-               help='Nexenta target portal port'),
-    cfg.StrOpt('nexenta_volume',
-               default='manila',
-               help='pool on SA that will hold all volumes'),
-    cfg.StrOpt('nexenta_target_prefix',
-               default='iqn.1986-03.com.sun:02:manila-',
-               help='IQN prefix for iSCSI targets'),
-    cfg.StrOpt('nexenta_target_group_prefix',
-               default='manila/',
-               help='prefix for iSCSI target groups on SA'),
-    cfg.StrOpt('nexenta_blocksize',
-               default='',
-               help='block size for volumes (blank=default,8KB)'),
-    cfg.BoolOpt('nexenta_sparse',
-                default=False,
-                help='flag to create sparse volumes'),
-]
-FLAGS.register_opts(nexenta_opts)
-
-
-class NexentaDriver(driver.ISCSIDriver):  # pylint: disable=R0921
-    """Executes volume driver commands on Nexenta Appliance."""
-
-    def __init__(self, *args, **kwargs):
-        super(NexentaDriver, self).__init__(*args, **kwargs)
-
-    def do_setup(self, context):
-        protocol = FLAGS.nexenta_rest_protocol
-        auto = protocol == 'auto'
-        if auto:
-            protocol = 'http'
-        self.nms = jsonrpc.NexentaJSONProxy(
-            '%s://%s:%s/rest/nms/' % (protocol, FLAGS.nexenta_host,
-                                      FLAGS.nexenta_rest_port),
-            FLAGS.nexenta_user, FLAGS.nexenta_password, auto=auto)
-
-    def check_for_setup_error(self):
-        """Verify that the volume for our zvols exists.
-
-        :raise: :py:exc:`LookupError`
-        """
-        if not self.nms.volume.object_exists(FLAGS.nexenta_volume):
-            raise LookupError(_("Volume %s does not exist in Nexenta SA"),
-                              FLAGS.nexenta_volume)
-
-    @staticmethod
-    def _get_zvol_name(volume_name):
-        """Return zvol name that corresponds given volume name."""
-        return '%s/%s' % (FLAGS.nexenta_volume, volume_name)
-
-    @staticmethod
-    def _get_target_name(volume_name):
-        """Return iSCSI target name to access volume."""
-        return '%s%s' % (FLAGS.nexenta_target_prefix, volume_name)
-
-    @staticmethod
-    def _get_target_group_name(volume_name):
-        """Return Nexenta iSCSI target group name for volume."""
-        return '%s%s' % (FLAGS.nexenta_target_group_prefix, volume_name)
-
-    def create_volume(self, volume):
-        """Create a zvol on appliance.
-
-        :param volume: volume reference
-        """
-        self.nms.zvol.create(
-            self._get_zvol_name(volume['name']),
-            '%sG' % (volume['size'],),
-            FLAGS.nexenta_blocksize, FLAGS.nexenta_sparse)
-
-    def delete_volume(self, volume):
-        """Destroy a zvol on appliance.
-
-        :param volume: volume reference
-        """
-        try:
-            self.nms.zvol.destroy(self._get_zvol_name(volume['name']), '')
-        except nexenta.NexentaException as exc:
-            if "zvol has children" in exc.args[1]:
-                raise exception.VolumeIsBusy(volume_name=volume['name'])
-            else:
-                raise
-
-    def create_snapshot(self, snapshot):
-        """Create snapshot of existing zvol on appliance.
-
-        :param snapshot: shapshot reference
-        """
-        self.nms.zvol.create_snapshot(
-            self._get_zvol_name(snapshot['volume_name']),
-            snapshot['name'], '')
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Create new volume from other's snapshot on appliance.
-
-        :param volume: reference of volume to be created
-        :param snapshot: reference of source snapshot
-        """
-        self.nms.zvol.clone(
-            '%s@%s' % (self._get_zvol_name(snapshot['volume_name']),
-                       snapshot['name']),
-            self._get_zvol_name(volume['name']))
-
-    def delete_snapshot(self, snapshot):
-        """Delete volume's snapshot on appliance.
-
-        :param snapshot: shapshot reference
-        """
-        try:
-            self.nms.snapshot.destroy(
-                '%s@%s' % (self._get_zvol_name(snapshot['volume_name']),
-                           snapshot['name']),
-                '')
-        except nexenta.NexentaException as exc:
-            if "snapshot has dependent clones" in exc.args[1]:
-                raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
-            else:
-                raise
-
-    def local_path(self, volume):
-        """Return local path to existing local volume.
-
-        We never have local volumes, so it raises NotImplementedError.
-
-        :raise: :py:exc:`NotImplementedError`
-        """
-        raise NotImplementedError
-
-    def _do_export(self, _ctx, volume, ensure=False):
-        """Do all steps to get zvol exported as LUN 0 at separate target.
-
-        :param volume: reference of volume to be exported
-        :param ensure: if True, ignore errors caused by already existing
-            resources
-        :return: iscsiadm-formatted provider location string
-        """
-        zvol_name = self._get_zvol_name(volume['name'])
-        target_name = self._get_target_name(volume['name'])
-        target_group_name = self._get_target_group_name(volume['name'])
-
-        try:
-            self.nms.iscsitarget.create_target({'target_name': target_name})
-        except nexenta.NexentaException as exc:
-            if not ensure or 'already configured' not in exc.args[1]:
-                raise
-            else:
-                LOG.info(_('Ignored target creation error "%s"'
-                           ' while ensuring export'), exc)
-        try:
-            self.nms.stmf.create_targetgroup(target_group_name)
-        except nexenta.NexentaException as exc:
-            if not ensure or 'already exists' not in exc.args[1]:
-                raise
-            else:
-                LOG.info(_('Ignored target group creation error "%s"'
-                           ' while ensuring export'), exc)
-        try:
-            self.nms.stmf.add_targetgroup_member(target_group_name,
-                                                 target_name)
-        except nexenta.NexentaException as exc:
-            if not ensure or 'already exists' not in exc.args[1]:
-                raise
-            else:
-                LOG.info(_('Ignored target group member addition error "%s"'
-                           ' while ensuring export'), exc)
-        try:
-            self.nms.scsidisk.create_lu(zvol_name, {})
-        except nexenta.NexentaException as exc:
-            if not ensure or 'in use' not in exc.args[1]:
-                raise
-            else:
-                LOG.info(_('Ignored LU creation error "%s"'
-                           ' while ensuring export'), exc)
-        try:
-            self.nms.scsidisk.add_lun_mapping_entry(zvol_name, {
-                'target_group': target_group_name,
-                'lun': '0'})
-        except nexenta.NexentaException as exc:
-            if not ensure or 'view entry exists' not in exc.args[1]:
-                raise
-            else:
-                LOG.info(_('Ignored LUN mapping entry addition error "%s"'
-                           ' while ensuring export'), exc)
-        return '%s:%s,1 %s 0' % (FLAGS.nexenta_host,
-                                 FLAGS.nexenta_iscsi_target_portal_port,
-                                 target_name)
-
-    def create_export(self, _ctx, volume):
-        """Create new export for zvol.
-
-        :param volume: reference of volume to be exported
-        :return: iscsiadm-formatted provider location string
-        """
-        loc = self._do_export(_ctx, volume, ensure=False)
-        return {'provider_location': loc}
-
-    def ensure_export(self, _ctx, volume):
-        """Recreate parts of export if necessary.
-
-        :param volume: reference of volume to be exported
-        """
-        self._do_export(_ctx, volume, ensure=True)
-
-    def remove_export(self, _ctx, volume):
-        """Destroy all resources created to export zvol.
-
-        :param volume: reference of volume to be unexported
-        """
-        zvol_name = self._get_zvol_name(volume['name'])
-        target_name = self._get_target_name(volume['name'])
-        target_group_name = self._get_target_group_name(volume['name'])
-        self.nms.scsidisk.delete_lu(zvol_name)
-
-        try:
-            self.nms.stmf.destroy_targetgroup(target_group_name)
-        except nexenta.NexentaException as exc:
-            # We assume that target group is already gone
-            LOG.warn(_('Got error trying to destroy target group'
-                       ' %(target_group)s, assuming it is '
-                       'already gone: %(exc)s'),
-                     {'target_group': target_group_name, 'exc': exc})
-        try:
-            self.nms.iscsitarget.delete_target(target_name)
-        except nexenta.NexentaException as exc:
-            # We assume that target is gone as well
-            LOG.warn(_('Got error trying to delete target %(target)s,'
-                       ' assuming it is already gone: %(exc)s'),
-                     {'target': target_name, 'exc': exc})
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        raise NotImplementedError()
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        raise NotImplementedError()
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        raise NotImplementedError()
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info for Nexenta device."""
-
-        # NOTE(jdg): Aimon Bustardo was kind enough to point out the
-        # info he had regarding Nexenta Capabilities, ideally it would
-        # be great if somebody from Nexenta looked this over at some point
-
-        KB = 1024
-        MB = KB ** 2
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-        backend_name = self.__class__.__name__
-        if self.configuration:
-            backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or self.__class__.__name__
-        data["vendor_name"] = 'Nexenta'
-        data["driver_version"] = VERSION
-        data["storage_protocol"] = 'iSCSI'
-
-        stats = self.nms.volume.get_child_props(FLAGS.nexenta_volume,
-                                                'health|size|used|available')
-        total_unit = stats['size'][-1]
-        total_amount = float(stats['size'][:-1])
-        free_unit = stats['available'][-1]
-        free_amount = float(stats['available'][:-1])
-
-        if total_unit == "T":
-                total_amount = total_amount * KB
-        elif total_unit == "M":
-                total_amount = total_amount / KB
-        elif total_unit == "B":
-                total_amount = total_amount / MB
-
-        if free_unit == "T":
-                free_amount = free_amount * KB
-        elif free_unit == "M":
-                free_amount = free_amount / KB
-        elif free_unit == "B":
-                free_amount = free_amount / MB
-
-        data['total_capacity_gb'] = total_amount
-        data['free_capacity_gb'] = free_amount
-
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = False
-        self._stats = data
diff --git a/manila/volume/drivers/nfs.py b/manila/volume/drivers/nfs.py
deleted file mode 100755
index 53b9c3ff73..0000000000
--- a/manila/volume/drivers/nfs.py
+++ /dev/null
@@ -1,357 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 NetApp, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import errno
-import hashlib
-import os
-
-from oslo.config import cfg
-
-from manila import exception
-from manila.image import image_utils
-from manila.openstack.common import log as logging
-from manila.volume import driver
-
-LOG = logging.getLogger(__name__)
-
-volume_opts = [
-    cfg.StrOpt('nfs_shares_config',
-               default='/etc/manila/nfs_shares',
-               help='File with the list of available nfs shares'),
-    cfg.StrOpt('nfs_mount_point_base',
-               default='$state_path/mnt',
-               help='Base dir containing mount points for nfs shares'),
-    cfg.StrOpt('nfs_disk_util',
-               default='df',
-               help='Use du or df for free space calculation'),
-    cfg.BoolOpt('nfs_sparsed_volumes',
-                default=True,
-                help=('Create volumes as sparsed files which take no space.'
-                      'If set to False volume is created as regular file.'
-                      'In such case volume creation takes a lot of time.')),
-    cfg.StrOpt('nfs_mount_options',
-               default=None,
-               help='Mount options passed to the nfs client. See section '
-                    'of the nfs man page for details'),
-]
-
-VERSION = '1.0'
-
-
-class RemoteFsDriver(driver.VolumeDriver):
-    """Common base for drivers that work like NFS."""
-
-    def check_for_setup_error(self):
-        """Just to override parent behavior."""
-        pass
-
-    def create_volume(self, volume):
-        raise NotImplementedError()
-
-    def delete_volume(self, volume):
-        raise NotImplementedError()
-
-    def delete_snapshot(self, snapshot):
-        """Do nothing for this driver, but allow manager to handle deletion
-           of snapshot in error state."""
-        pass
-
-    def ensure_export(self, ctx, volume):
-        raise NotImplementedError()
-
-    def _create_sparsed_file(self, path, size):
-        """Creates file with 0 disk usage."""
-        self._execute('truncate', '-s', '%sG' % size,
-                      path, run_as_root=True)
-
-    def _create_regular_file(self, path, size):
-        """Creates regular file of given size. Takes a lot of time for large
-        files."""
-        KB = 1024
-        MB = KB * 1024
-        GB = MB * 1024
-
-        block_size_mb = 1
-        block_count = size * GB / (block_size_mb * MB)
-
-        self._execute('dd', 'if=/dev/zero', 'of=%s' % path,
-                      'bs=%dM' % block_size_mb,
-                      'count=%d' % block_count,
-                      run_as_root=True)
-
-    def _set_rw_permissions_for_all(self, path):
-        """Sets 666 permissions for the path."""
-        self._execute('chmod', 'ugo+rw', path, run_as_root=True)
-
-    def local_path(self, volume):
-        """Get volume path (mounted locally fs path) for given volume
-        :param volume: volume reference
-        """
-        nfs_share = volume['provider_location']
-        return os.path.join(self._get_mount_point_for_share(nfs_share),
-                            volume['name'])
-
-    def _get_hash_str(self, base_str):
-        """returns string that represents hash of base_str
-        (in a hex format)."""
-        return hashlib.md5(base_str).hexdigest()
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        image_utils.fetch_to_raw(context,
-                                 image_service,
-                                 image_id,
-                                 self.local_path(volume))
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        image_utils.upload_volume(context,
-                                  image_service,
-                                  image_meta,
-                                  self.local_path(volume))
-
-
-class NfsDriver(RemoteFsDriver):
-    """NFS based manila driver. Creates file on NFS share for using it
-    as block device on hypervisor."""
-    def __init__(self, *args, **kwargs):
-        super(NfsDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(volume_opts)
-
-    def do_setup(self, context):
-        """Any initialization the volume driver does while starting"""
-        super(NfsDriver, self).do_setup(context)
-
-        config = self.configuration.nfs_shares_config
-        if not config:
-            msg = (_("There's no NFS config file configured (%s)") %
-                   'nfs_shares_config')
-            LOG.warn(msg)
-            raise exception.NfsException(msg)
-        if not os.path.exists(config):
-            msg = _("NFS config file at %(config)s doesn't exist") % locals()
-            LOG.warn(msg)
-            raise exception.NfsException(msg)
-
-        try:
-            self._execute('mount.nfs', check_exit_code=False)
-        except OSError as exc:
-            if exc.errno == errno.ENOENT:
-                raise exception.NfsException('mount.nfs is not installed')
-            else:
-                raise
-
-    def create_cloned_volume(self, volume, src_vref):
-        raise NotImplementedError()
-
-    def create_volume(self, volume):
-        """Creates a volume"""
-
-        self._ensure_shares_mounted()
-
-        volume['provider_location'] = self._find_share(volume['size'])
-
-        LOG.info(_('casted to %s') % volume['provider_location'])
-
-        self._do_create_volume(volume)
-
-        return {'provider_location': volume['provider_location']}
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-
-        if not volume['provider_location']:
-            LOG.warn(_('Volume %s does not have provider_location specified, '
-                     'skipping'), volume['name'])
-            return
-
-        self._ensure_share_mounted(volume['provider_location'])
-
-        mounted_path = self.local_path(volume)
-
-        self._execute('rm', '-f', mounted_path, run_as_root=True)
-
-    def ensure_export(self, ctx, volume):
-        """Synchronously recreates an export for a logical volume."""
-        self._ensure_share_mounted(volume['provider_location'])
-
-    def create_export(self, ctx, volume):
-        """Exports the volume. Can optionally return a Dictionary of changes
-        to the volume object to be persisted."""
-        pass
-
-    def remove_export(self, ctx, volume):
-        """Removes an export for a logical volume."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Allow connection to connector and return connection info."""
-        data = {'export': volume['provider_location'],
-                'name': volume['name']}
-        return {
-            'driver_volume_type': 'nfs',
-            'data': data
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Disallow connection from connector"""
-        pass
-
-    def _do_create_volume(self, volume):
-        """Create a volume on given nfs_share
-        :param volume: volume reference
-        """
-        volume_path = self.local_path(volume)
-        volume_size = volume['size']
-
-        if self.configuration.nfs_sparsed_volumes:
-            self._create_sparsed_file(volume_path, volume_size)
-        else:
-            self._create_regular_file(volume_path, volume_size)
-
-        self._set_rw_permissions_for_all(volume_path)
-
-    def _ensure_shares_mounted(self):
-        """Look for NFS shares in the flags and tries to mount them locally"""
-        self._mounted_shares = []
-
-        for share in self._load_shares_config():
-            try:
-                self._ensure_share_mounted(share)
-                self._mounted_shares.append(share)
-            except Exception, exc:
-                LOG.warning(_('Exception during mounting %s') % (exc,))
-
-        LOG.debug('Available shares %s' % str(self._mounted_shares))
-
-    def _load_shares_config(self):
-        return [share.strip() for share in
-                open(self.configuration.nfs_shares_config)
-                if share and not share.startswith('#')]
-
-    def _ensure_share_mounted(self, nfs_share):
-        """Mount NFS share
-        :param nfs_share:
-        """
-        mount_path = self._get_mount_point_for_share(nfs_share)
-        self._mount_nfs(nfs_share, mount_path, ensure=True)
-
-    def _find_share(self, volume_size_for):
-        """Choose NFS share among available ones for given volume size. Current
-        implementation looks for greatest capacity
-        :param volume_size_for: int size in Gb
-        """
-
-        if not self._mounted_shares:
-            raise exception.NfsNoSharesMounted()
-
-        greatest_size = 0
-        greatest_share = None
-
-        for nfs_share in self._mounted_shares:
-            capacity = self._get_available_capacity(nfs_share)[0]
-            if capacity > greatest_size:
-                greatest_share = nfs_share
-                greatest_size = capacity
-
-        if volume_size_for * 1024 * 1024 * 1024 > greatest_size:
-            raise exception.NfsNoSuitableShareFound(
-                volume_size=volume_size_for)
-        return greatest_share
-
-    def _get_mount_point_for_share(self, nfs_share):
-        """
-        :param nfs_share: example 172.18.194.100:/var/nfs
-        """
-        return os.path.join(self.configuration.nfs_mount_point_base,
-                            self._get_hash_str(nfs_share))
-
-    def _get_available_capacity(self, nfs_share):
-        """Calculate available space on the NFS share
-        :param nfs_share: example 172.18.194.100:/var/nfs
-        """
-        mount_point = self._get_mount_point_for_share(nfs_share)
-
-        out, _ = self._execute('df', '-P', '-B', '1', mount_point,
-                               run_as_root=True)
-        out = out.splitlines()[1]
-
-        available = 0
-
-        size = int(out.split()[1])
-        if self.configuration.nfs_disk_util == 'df':
-            available = int(out.split()[3])
-        else:
-            out, _ = self._execute('du', '-sb', '--apparent-size',
-                                   '--exclude', '*snapshot*', mount_point,
-                                   run_as_root=True)
-            used = int(out.split()[0])
-            available = size - used
-
-        return available, size
-
-    def _mount_nfs(self, nfs_share, mount_path, ensure=False):
-        """Mount NFS share to mount path"""
-        self._execute('mkdir', '-p', mount_path)
-
-        # Construct the NFS mount command.
-        nfs_cmd = ['mount', '-t', 'nfs']
-        if self.configuration.nfs_mount_options is not None:
-            nfs_cmd.extend(['-o', self.configuration.nfs_mount_options])
-        nfs_cmd.extend([nfs_share, mount_path])
-
-        try:
-            self._execute(*nfs_cmd, run_as_root=True)
-        except exception.ProcessExecutionError as exc:
-            if ensure and 'already mounted' in exc.stderr:
-                LOG.warn(_("%s is already mounted"), nfs_share)
-            else:
-                raise
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh or not self._stats:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'Generic_NFS'
-        data["vendor_name"] = 'Open Source'
-        data["driver_version"] = VERSION
-        data["storage_protocol"] = 'nfs'
-
-        self._ensure_shares_mounted()
-
-        global_capacity = 0
-        global_free = 0
-        for nfs_share in self._mounted_shares:
-            free, capacity = self._get_available_capacity(nfs_share)
-            global_capacity += capacity
-            global_free += free
-
-        data['total_capacity_gb'] = global_capacity / 1024.0 ** 3
-        data['free_capacity_gb'] = global_free / 1024.0 ** 3
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = False
-        self._stats = data
diff --git a/manila/volume/drivers/rbd.py b/manila/volume/drivers/rbd.py
deleted file mode 100644
index b7b3dee075..0000000000
--- a/manila/volume/drivers/rbd.py
+++ /dev/null
@@ -1,306 +0,0 @@
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-RADOS Block Device Driver
-"""
-
-import json
-import os
-import tempfile
-import urllib
-
-from oslo.config import cfg
-
-from manila import exception
-from manila.image import image_utils
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume import driver
-
-LOG = logging.getLogger(__name__)
-
-rbd_opts = [
-    cfg.StrOpt('rbd_pool',
-               default='rbd',
-               help='the RADOS pool in which rbd volumes are stored'),
-    cfg.StrOpt('rbd_user',
-               default=None,
-               help='the RADOS client name for accessing rbd volumes'),
-    cfg.StrOpt('rbd_secret_uuid',
-               default=None,
-               help='the libvirt uuid of the secret for the rbd_user'
-                    'volumes'),
-    cfg.StrOpt('volume_tmp_dir',
-               default=None,
-               help='where to store temporary image files if the volume '
-                    'driver does not write them directly to the volume'), ]
-
-VERSION = '1.0'
-
-
-class RBDDriver(driver.VolumeDriver):
-    """Implements RADOS block device (RBD) volume commands"""
-    def __init__(self, *args, **kwargs):
-        super(RBDDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(rbd_opts)
-        self._stats = {}
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met"""
-        (stdout, stderr) = self._execute('rados', 'lspools')
-        pools = stdout.split("\n")
-        if self.configuration.rbd_pool not in pools:
-            exception_message = (_("rbd has no pool %s") %
-                                 self.configuration.rbd_pool)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-    def _update_volume_stats(self):
-        stats = {'vendor_name': 'Open Source',
-                 'driver_version': VERSION,
-                 'storage_protocol': 'ceph',
-                 'total_capacity_gb': 'unknown',
-                 'free_capacity_gb': 'unknown',
-                 'reserved_percentage': 0}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        stats['volume_backend_name'] = backend_name or 'RBD'
-
-        try:
-            stdout, _err = self._execute('rados', 'df', '--format', 'json')
-            new_stats = json.loads(stdout)
-            total = int(new_stats['total_space']) / 1024 ** 2
-            free = int(new_stats['total_avail']) / 1024 ** 2
-            stats['total_capacity_gb'] = total
-            stats['free_capacity_gb'] = free
-        except exception.ProcessExecutionError:
-            # just log and return unknown capacities
-            LOG.exception(_('error refreshing volume stats'))
-        self._stats = stats
-
-    def get_volume_stats(self, refresh=False):
-        """Return the current state of the volume service. If 'refresh' is
-           True, run the update first."""
-        if refresh:
-            self._update_volume_stats()
-        return self._stats
-
-    def _supports_layering(self):
-        stdout, _ = self._execute('rbd', '--help')
-        return 'clone' in stdout
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Clone a logical volume"""
-        self._try_execute('rbd', 'cp',
-                          '--pool', self.configuration.rbd_pool,
-                          '--image', src_vref['name'],
-                          '--dest-pool', self.configuration.rbd_pool,
-                          '--dest', volume['name'])
-
-    def create_volume(self, volume):
-        """Creates a logical volume."""
-        if int(volume['size']) == 0:
-            size = 100
-        else:
-            size = int(volume['size']) * 1024
-        args = ['rbd', 'create',
-                '--pool', self.configuration.rbd_pool,
-                '--size', size,
-                volume['name']]
-        if self._supports_layering():
-            args += ['--new-format']
-        self._try_execute(*args)
-
-    def _clone(self, volume, src_pool, src_image, src_snap):
-        self._try_execute('rbd', 'clone',
-                          '--pool', src_pool,
-                          '--image', src_image,
-                          '--snap', src_snap,
-                          '--dest-pool', self.configuration.rbd_pool,
-                          '--dest', volume['name'])
-
-    def _resize(self, volume):
-        size = int(volume['size']) * 1024
-        self._try_execute('rbd', 'resize',
-                          '--pool', self.configuration.rbd_pool,
-                          '--image', volume['name'],
-                          '--size', size)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-        self._clone(volume, self.configuration.rbd_pool,
-                    snapshot['volume_name'], snapshot['name'])
-        if int(volume['size']):
-            self._resize(volume)
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-        stdout, _ = self._execute('rbd', 'snap', 'ls',
-                                  '--pool', self.configuration.rbd_pool,
-                                  volume['name'])
-        if stdout.count('\n') > 1:
-            raise exception.VolumeIsBusy(volume_name=volume['name'])
-        self._try_execute('rbd', 'rm',
-                          '--pool', self.configuration.rbd_pool,
-                          volume['name'])
-
-    def create_snapshot(self, snapshot):
-        """Creates an rbd snapshot"""
-        self._try_execute('rbd', 'snap', 'create',
-                          '--pool', self.configuration.rbd_pool,
-                          '--snap', snapshot['name'],
-                          snapshot['volume_name'])
-        if self._supports_layering():
-            self._try_execute('rbd', 'snap', 'protect',
-                              '--pool', self.configuration.rbd_pool,
-                              '--snap', snapshot['name'],
-                              snapshot['volume_name'])
-
-    def delete_snapshot(self, snapshot):
-        """Deletes an rbd snapshot"""
-        if self._supports_layering():
-            try:
-                self._try_execute('rbd', 'snap', 'unprotect',
-                                  '--pool', self.configuration.rbd_pool,
-                                  '--snap', snapshot['name'],
-                                  snapshot['volume_name'])
-            except exception.ProcessExecutionError:
-                raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
-        self._try_execute('rbd', 'snap', 'rm',
-                          '--pool', self.configuration.rbd_pool,
-                          '--snap', snapshot['name'],
-                          snapshot['volume_name'])
-
-    def local_path(self, volume):
-        """Returns the path of the rbd volume."""
-        # This is the same as the remote path
-        # since qemu accesses it directly.
-        return "rbd:%s/%s" % (self.configuration.rbd_pool, volume['name'])
-
-    def ensure_export(self, context, volume):
-        """Synchronously recreates an export for a logical volume."""
-        pass
-
-    def create_export(self, context, volume):
-        """Exports the volume"""
-        pass
-
-    def remove_export(self, context, volume):
-        """Removes an export for a logical volume"""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        return {
-            'driver_volume_type': 'rbd',
-            'data': {
-                'name': '%s/%s' % (self.configuration.rbd_pool,
-                                   volume['name']),
-                'auth_enabled': (self.configuration.rbd_secret_uuid
-                                 is not None),
-                'auth_username': self.configuration.rbd_user,
-                'secret_type': 'ceph',
-                'secret_uuid': self.configuration.rbd_secret_uuid, }
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        pass
-
-    def _parse_location(self, location):
-        prefix = 'rbd://'
-        if not location.startswith(prefix):
-            reason = _('Not stored in rbd')
-            raise exception.ImageUnacceptable(image_id=location, reason=reason)
-        pieces = map(urllib.unquote, location[len(prefix):].split('/'))
-        if any(map(lambda p: p == '', pieces)):
-            reason = _('Blank components')
-            raise exception.ImageUnacceptable(image_id=location, reason=reason)
-        if len(pieces) != 4:
-            reason = _('Not an rbd snapshot')
-            raise exception.ImageUnacceptable(image_id=location, reason=reason)
-        return pieces
-
-    def _get_fsid(self):
-        stdout, _ = self._execute('ceph', 'fsid')
-        return stdout.rstrip('\n')
-
-    def _is_cloneable(self, image_location):
-        try:
-            fsid, pool, image, snapshot = self._parse_location(image_location)
-        except exception.ImageUnacceptable:
-            return False
-
-        if self._get_fsid() != fsid:
-            reason = _('%s is in a different ceph cluster') % image_location
-            LOG.debug(reason)
-            return False
-
-        # check that we can read the image
-        try:
-            self._execute('rbd', 'info',
-                          '--pool', pool,
-                          '--image', image,
-                          '--snap', snapshot)
-        except exception.ProcessExecutionError:
-            LOG.debug(_('Unable to read image %s') % image_location)
-            return False
-
-        return True
-
-    def clone_image(self, volume, image_location):
-        if image_location is None or not self._is_cloneable(image_location):
-            return False
-        _, pool, image, snapshot = self._parse_location(image_location)
-        self._clone(volume, pool, image, snapshot)
-        self._resize(volume)
-        return True
-
-    def _ensure_tmp_exists(self):
-        tmp_dir = self.configuration.volume_tmp_dir
-        if tmp_dir and not os.path.exists(tmp_dir):
-            os.makedirs(tmp_dir)
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        # TODO(jdurgin): replace with librbd
-        # this is a temporary hack, since rewriting this driver
-        # to use librbd would take too long
-        self._ensure_tmp_exists()
-        tmp_dir = self.configuration.volume_tmp_dir
-
-        with tempfile.NamedTemporaryFile(dir=tmp_dir) as tmp:
-            image_utils.fetch_to_raw(context, image_service, image_id,
-                                     tmp.name)
-            # import creates the image, so we must remove it first
-            self._try_execute('rbd', 'rm',
-                              '--pool', self.configuration.rbd_pool,
-                              volume['name'])
-
-            args = ['rbd', 'import',
-                    '--pool', self.configuration.rbd_pool,
-                    tmp.name, volume['name']]
-            if self._supports_layering():
-                args += ['--new-format']
-            self._try_execute(*args)
-        self._resize(volume)
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        self._ensure_tmp_exists()
-
-        tmp_dir = self.configuration.volume_tmp_dir or '/tmp'
-        tmp_file = os.path.join(tmp_dir,
-                                volume['name'] + '-' + image_meta['id'])
-        with utils.remove_path_on_error(tmp_file):
-            self._try_execute('rbd', 'export',
-                              '--pool', self.configuration.rbd_pool,
-                              volume['name'], tmp_file)
-            image_utils.upload_volume(context, image_service,
-                                      image_meta, tmp_file)
-        os.unlink(tmp_file)
diff --git a/manila/volume/drivers/san/__init__.py b/manila/volume/drivers/san/__init__.py
deleted file mode 100644
index 949a3ec182..0000000000
--- a/manila/volume/drivers/san/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) 2012 OpenStack, LLC.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-:mod:`manila.volume.san` -- Cinder San Drivers
-=====================================================
-
-.. automodule:: manila.volume.san
-   :platform: Unix
-   :synopsis: Module containing all the Cinder San drivers.
-"""
-
-# Adding imports for backwards compatibility in loading volume_driver.
-from hp_lefthand import HpSanISCSIDriver
-from san import SanISCSIDriver
-from solaris import SolarisISCSIDriver
diff --git a/manila/volume/drivers/san/hp/__init__.py b/manila/volume/drivers/san/hp/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/manila/volume/drivers/san/hp/hp_3par_common.py b/manila/volume/drivers/san/hp/hp_3par_common.py
deleted file mode 100644
index 2df5bf08d9..0000000000
--- a/manila/volume/drivers/san/hp/hp_3par_common.py
+++ /dev/null
@@ -1,742 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-#    (c) Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
-#    All Rights Reserved.
-#
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-#
-"""
-Volume driver common utilities for HP 3PAR Storage array
-The 3PAR drivers requires 3.1.2 firmware on the 3PAR array.
-
-You will need to install the python hp3parclient.
-sudo pip install hp3parclient
-
-The drivers uses both the REST service and the SSH
-command line to correctly operate.  Since the
-ssh credentials and the REST credentials can be different
-we need to have settings for both.
-
-The drivers requires the use of the san_ip, san_login,
-san_password settings for ssh connections into the 3PAR
-array.   It also requires the setting of
-hp3par_api_url, hp3par_username, hp3par_password
-for credentials to talk to the REST service on the 3PAR
-array.
-"""
-import base64
-import json
-import paramiko
-import pprint
-from random import randint
-import time
-import uuid
-
-from eventlet import greenthread
-from hp3parclient import exceptions as hpexceptions
-from oslo.config import cfg
-
-from manila import context
-from manila import exception
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume import volume_types
-
-LOG = logging.getLogger(__name__)
-
-hp3par_opts = [
-    cfg.StrOpt('hp3par_api_url',
-               default='',
-               help="3PAR WSAPI Server Url like "
-                    "https://<3par ip>:8080/api/v1"),
-    cfg.StrOpt('hp3par_username',
-               default='',
-               help="3PAR Super user username"),
-    cfg.StrOpt('hp3par_password',
-               default='',
-               help="3PAR Super user password",
-               secret=True),
-    cfg.StrOpt('hp3par_domain',
-               default="OpenStack",
-               help="The 3par domain name to use"),
-    cfg.StrOpt('hp3par_cpg',
-               default="OpenStack",
-               help="The CPG to use for volume creation"),
-    cfg.StrOpt('hp3par_cpg_snap',
-               default="",
-               help="The CPG to use for Snapshots for volumes. "
-                    "If empty hp3par_cpg will be used"),
-    cfg.StrOpt('hp3par_snapshot_retention',
-               default="",
-               help="The time in hours to retain a snapshot.  "
-                    "You can't delete it before this expires."),
-    cfg.StrOpt('hp3par_snapshot_expiration',
-               default="",
-               help="The time in hours when a snapshot expires "
-                    " and is deleted.  This must be larger than expiration"),
-    cfg.BoolOpt('hp3par_debug',
-                default=False,
-                help="Enable HTTP debugging to 3PAR")
-]
-
-
-class HP3PARCommon():
-
-    stats = {}
-
-    # Valid values for volume type extra specs
-    # The first value in the list is the default value
-    valid_prov_values = ['thin', 'full']
-    valid_persona_values = ['1 - Generic',
-                            '2 - Generic-ALUA',
-                            '6 - Generic-legacy',
-                            '7 - HPUX-legacy',
-                            '8 - AIX-legacy',
-                            '9 - EGENERA',
-                            '10 - ONTAP-legacy',
-                            '11 - VMware']
-
-    def __init__(self, config):
-        self.sshpool = None
-        self.config = config
-
-    def check_flags(self, options, required_flags):
-        for flag in required_flags:
-            if not getattr(options, flag, None):
-                raise exception.InvalidInput(reason=_('%s is not set') % flag)
-
-    def _get_3par_vol_name(self, volume_id):
-        """
-        Converts the openstack volume id from
-        ecffc30f-98cb-4cf5-85ee-d7309cc17cd2
-        to
-        osv-7P.DD5jLTPWF7tcwnMF80g
-
-        We convert the 128 bits of the uuid into a 24character long
-        base64 encoded string to ensure we don't exceed the maximum
-        allowed 31 character name limit on 3Par
-
-        We strip the padding '=' and replace + with .
-        and / with -
-        """
-        volume_name = self._encode_name(volume_id)
-        return "osv-%s" % volume_name
-
-    def _get_3par_snap_name(self, snapshot_id):
-        snapshot_name = self._encode_name(snapshot_id)
-        return "oss-%s" % snapshot_name
-
-    def _encode_name(self, name):
-        uuid_str = name.replace("-", "")
-        vol_uuid = uuid.UUID('urn:uuid:%s' % uuid_str)
-        vol_encoded = base64.b64encode(vol_uuid.bytes)
-
-        # 3par doesn't allow +, nor /
-        vol_encoded = vol_encoded.replace('+', '.')
-        vol_encoded = vol_encoded.replace('/', '-')
-        # strip off the == as 3par doesn't like those.
-        vol_encoded = vol_encoded.replace('=', '')
-        return vol_encoded
-
-    def _capacity_from_size(self, vol_size):
-
-        # because 3PAR volume sizes are in
-        # Mebibytes, Gigibytes, not Megabytes.
-        MB = 1000L
-        MiB = 1.048576
-
-        if int(vol_size) == 0:
-            capacity = MB  # default: 1GB
-        else:
-            capacity = vol_size * MB
-
-        capacity = int(round(capacity / MiB))
-        return capacity
-
-    def _cli_run(self, verb, cli_args):
-        """ Runs a CLI command over SSH, without doing any result parsing. """
-        cli_arg_strings = []
-        if cli_args:
-            for k, v in cli_args.items():
-                if k == '':
-                    cli_arg_strings.append(" %s" % k)
-                else:
-                    cli_arg_strings.append(" %s=%s" % (k, v))
-
-        cmd = verb + ''.join(cli_arg_strings)
-        LOG.debug("SSH CMD = %s " % cmd)
-
-        (stdout, stderr) = self._run_ssh(cmd, False)
-
-        # we have to strip out the input and exit lines
-        tmp = stdout.split("\r\n")
-        out = tmp[5:len(tmp) - 2]
-        return out
-
-    def _ssh_execute(self, ssh, cmd,
-                     check_exit_code=True):
-        """
-        We have to do this in order to get CSV output
-        from the CLI command.   We first have to issue
-        a command to tell the CLI that we want the output
-        to be formatted in CSV, then we issue the real
-        command.
-        """
-        LOG.debug(_('Running cmd (SSH): %s'), cmd)
-
-        channel = ssh.invoke_shell()
-        stdin_stream = channel.makefile('wb')
-        stdout_stream = channel.makefile('rb')
-        stderr_stream = channel.makefile('rb')
-
-        stdin_stream.write('''setclienv csvtable 1
-%s
-exit
-''' % cmd)
-
-        # stdin.write('process_input would go here')
-        # stdin.flush()
-
-        # NOTE(justinsb): This seems suspicious...
-        # ...other SSH clients have buffering issues with this approach
-        stdout = stdout_stream.read()
-        stderr = stderr_stream.read()
-        stdin_stream.close()
-        stdout_stream.close()
-        stderr_stream.close()
-
-        exit_status = channel.recv_exit_status()
-
-        # exit_status == -1 if no exit code was returned
-        if exit_status != -1:
-            LOG.debug(_('Result was %s') % exit_status)
-            if check_exit_code and exit_status != 0:
-                raise exception.ProcessExecutionError(exit_code=exit_status,
-                                                      stdout=stdout,
-                                                      stderr=stderr,
-                                                      cmd=cmd)
-        channel.close()
-        return (stdout, stderr)
-
-    def _run_ssh(self, command, check_exit=True, attempts=1):
-        if not self.sshpool:
-            self.sshpool = utils.SSHPool(self.config.san_ip,
-                                         self.config.san_ssh_port,
-                                         self.config.ssh_conn_timeout,
-                                         self.config.san_login,
-                                         password=self.config.san_password,
-                                         privatekey=
-                                         self.config.san_private_key,
-                                         min_size=
-                                         self.config.ssh_min_pool_conn,
-                                         max_size=
-                                         self.config.ssh_max_pool_conn)
-        try:
-            total_attempts = attempts
-            with self.sshpool.item() as ssh:
-                while attempts > 0:
-                    attempts -= 1
-                    try:
-                        return self._ssh_execute(ssh, command,
-                                                 check_exit_code=check_exit)
-                    except Exception as e:
-                        LOG.error(e)
-                        greenthread.sleep(randint(20, 500) / 100.0)
-                raise paramiko.SSHException(_("SSH Command failed after "
-                                              "'%(total_attempts)r' attempts"
-                                              ": '%(command)s'"), locals())
-        except Exception as e:
-            LOG.error(_("Error running ssh command: %s") % command)
-            raise e
-
-    def _delete_3par_host(self, hostname):
-        self._cli_run('removehost %s' % hostname, None)
-
-    def _create_3par_vlun(self, volume, hostname):
-        out = self._cli_run('createvlun %s auto %s' % (volume, hostname), None)
-        if out and len(out) > 1:
-            if "must be in the same domain" in out[0]:
-                err = out[0].strip()
-                err = err + " " + out[1].strip()
-                raise exception.Invalid3PARDomain(err=err)
-
-    def _safe_hostname(self, hostname):
-        """
-        We have to use a safe hostname length
-        for 3PAR host names.
-        """
-        try:
-            index = hostname.index('.')
-        except ValueError:
-            # couldn't find it
-            index = len(hostname)
-
-        # we'll just chop this off for now.
-        if index > 23:
-            index = 23
-
-        return hostname[:index]
-
-    def _get_3par_host(self, hostname):
-        out = self._cli_run('showhost -verbose %s' % (hostname), None)
-        LOG.debug("OUTPUT = \n%s" % (pprint.pformat(out)))
-        host = {'id': None, 'name': None,
-                'domain': None,
-                'descriptors': {},
-                'iSCSIPaths': [],
-                'FCPaths': []}
-
-        if out:
-            err = out[0]
-            if err == 'no hosts listed':
-                msg = {'code': 'NON_EXISTENT_HOST',
-                       'desc': "HOST '%s' was not found" % hostname}
-                raise hpexceptions.HTTPNotFound(msg)
-
-            # start parsing the lines after the header line
-            for line in out[1:]:
-                if line == '':
-                    break
-                tmp = line.split(',')
-                paths = {}
-
-                LOG.debug("line = %s" % (pprint.pformat(tmp)))
-                host['id'] = tmp[0]
-                host['name'] = tmp[1]
-
-                portPos = tmp[4]
-                LOG.debug("portPos = %s" % (pprint.pformat(portPos)))
-                if portPos == '---':
-                    portPos = None
-                else:
-                    port = portPos.split(':')
-                    portPos = {'node': int(port[0]), 'slot': int(port[1]),
-                               'cardPort': int(port[2])}
-
-                paths['portPos'] = portPos
-
-                # If FC entry
-                if tmp[5] == 'n/a':
-                    paths['wwn'] = tmp[3]
-                    host['FCPaths'].append(paths)
-                # else iSCSI entry
-                else:
-                    paths['name'] = tmp[3]
-                    paths['ipAddr'] = tmp[5]
-                    host['iSCSIPaths'].append(paths)
-
-            # find the offset to the description stuff
-            offset = 0
-            for line in out:
-                if line[:15] == '---------- Host':
-                    break
-                else:
-                    offset += 1
-
-            info = out[offset + 2]
-            tmp = info.split(':')
-            host['domain'] = tmp[1]
-
-            info = out[offset + 4]
-            tmp = info.split(':')
-            host['descriptors']['location'] = tmp[1]
-
-            info = out[offset + 5]
-            tmp = info.split(':')
-            host['descriptors']['ipAddr'] = tmp[1]
-
-            info = out[offset + 6]
-            tmp = info.split(':')
-            host['descriptors']['os'] = tmp[1]
-
-            info = out[offset + 7]
-            tmp = info.split(':')
-            host['descriptors']['model'] = tmp[1]
-
-            info = out[offset + 8]
-            tmp = info.split(':')
-            host['descriptors']['contact'] = tmp[1]
-
-            info = out[offset + 9]
-            tmp = info.split(':')
-            host['descriptors']['comment'] = tmp[1]
-
-        return host
-
-    def get_ports(self):
-        # First get the active FC ports
-        out = self._cli_run('showport', None)
-
-        # strip out header
-        # N:S:P,Mode,State,----Node_WWN----,-Port_WWN/HW_Addr-,Type,
-        # Protocol,Label,Partner,FailoverState
-        out = out[1:len(out) - 2]
-
-        ports = {'FC': [], 'iSCSI': []}
-        for line in out:
-            tmp = line.split(',')
-
-            if tmp:
-                if tmp[1] == 'target' and tmp[2] == 'ready':
-                    if tmp[6] == 'FC':
-                        ports['FC'].append(tmp[4])
-
-        # now get the active iSCSI ports
-        out = self._cli_run('showport -iscsi', None)
-
-        # strip out header
-        # N:S:P,State,IPAddr,Netmask,Gateway,
-        # TPGT,MTU,Rate,DHCP,iSNS_Addr,iSNS_Port
-        out = out[1:len(out) - 2]
-        for line in out:
-            tmp = line.split(',')
-
-            if tmp:
-                if tmp[1] == 'ready':
-                    ports['iSCSI'].append(tmp[2])
-
-        LOG.debug("PORTS = %s" % pprint.pformat(ports))
-        return ports
-
-    def get_volume_stats(self, refresh, client):
-        if refresh:
-            self._update_volume_stats(client)
-
-        return self.stats
-
-    def _update_volume_stats(self, client):
-        # const to convert MiB to GB
-        const = 0.0009765625
-
-        # storage_protocol and volume_backend_name are
-        # set in the child classes
-        stats = {'driver_version': '1.0',
-                 'free_capacity_gb': 'unknown',
-                 'reserved_percentage': 0,
-                 'storage_protocol': None,
-                 'total_capacity_gb': 'unknown',
-                 'vendor_name': 'Hewlett-Packard',
-                 'volume_backend_name': None}
-
-        try:
-            cpg = client.getCPG(self.config.hp3par_cpg)
-            if 'limitMiB' not in cpg['SDGrowth']:
-                total_capacity = 'infinite'
-                free_capacity = 'infinite'
-            else:
-                total_capacity = int(cpg['SDGrowth']['limitMiB'] * const)
-                free_capacity = int((cpg['SDGrowth']['limitMiB'] -
-                                    cpg['UsrUsage']['usedMiB']) * const)
-
-            stats['total_capacity_gb'] = total_capacity
-            stats['free_capacity_gb'] = free_capacity
-        except hpexceptions.HTTPNotFound:
-            err = (_("CPG (%s) doesn't exist on array")
-                   % self.config.hp3par_cpg)
-            LOG.error(err)
-            raise exception.InvalidInput(reason=err)
-
-        self.stats = stats
-
-    def create_vlun(self, volume, host, client):
-        """
-        In order to export a volume on a 3PAR box, we have to
-        create a VLUN.
-        """
-        volume_name = self._get_3par_vol_name(volume['id'])
-        self._create_3par_vlun(volume_name, host['name'])
-        return client.getVLUN(volume_name)
-
-    def delete_vlun(self, volume, connector, client):
-        hostname = self._safe_hostname(connector['host'])
-
-        volume_name = self._get_3par_vol_name(volume['id'])
-        vlun = client.getVLUN(volume_name)
-        client.deleteVLUN(volume_name, vlun['lun'], hostname)
-        self._delete_3par_host(hostname)
-
-    def _get_volume_type(self, type_id):
-        ctxt = context.get_admin_context()
-        return volume_types.get_volume_type(ctxt, type_id)
-
-    def _get_volume_type_value(self, volume_type, key, default=None):
-        if volume_type is not None:
-            specs = volume_type.get('extra_specs')
-            if key in specs:
-                return specs[key]
-            else:
-                return default
-        else:
-            return default
-
-    def get_persona_type(self, volume):
-        default_persona = self.valid_persona_values[0]
-        type_id = volume.get('volume_type_id', None)
-        volume_type = None
-        if type_id is not None:
-            volume_type = self._get_volume_type(type_id)
-        persona_value = self._get_volume_type_value(volume_type, 'persona',
-                                                    default_persona)
-        if persona_value not in self.valid_persona_values:
-            err = _("Must specify a valid persona %(valid)s, "
-                    "value '%(persona)s' is invalid.") % \
-                   ({'valid': self.valid_persona_values,
-                     'persona': persona_value})
-            raise exception.InvalidInput(reason=err)
-        # persona is set by the id so remove the text and return the id
-        # i.e for persona '1 - Generic' returns 1
-        persona_id = persona_value.split(' ')
-        return persona_id[0]
-
-    def create_volume(self, volume, client):
-        LOG.debug("CREATE VOLUME (%s : %s %s)" %
-                  (volume['display_name'], volume['name'],
-                   self._get_3par_vol_name(volume['id'])))
-        try:
-            comments = {'volume_id': volume['id'],
-                        'name': volume['name'],
-                        'type': 'OpenStack'}
-
-            name = volume.get('display_name', None)
-            if name:
-                comments['display_name'] = name
-
-            # get the options supported by volume types
-            volume_type = None
-            type_id = volume.get('volume_type_id', None)
-            if type_id is not None:
-                volume_type = self._get_volume_type(type_id)
-
-            cpg = self._get_volume_type_value(volume_type, 'cpg',
-                                              self.config.hp3par_cpg)
-
-            # if provisioning is not set use thin
-            default_prov = self.valid_prov_values[0]
-            prov_value = self._get_volume_type_value(volume_type,
-                                                     'provisioning',
-                                                     default_prov)
-            # check for valid provisioning type
-            if prov_value not in self.valid_prov_values:
-                err = _("Must specify a valid provisioning type %(valid)s, "
-                        "value '%(prov)s' is invalid.") % \
-                       ({'valid': self.valid_prov_values,
-                         'prov': prov_value})
-                raise exception.InvalidInput(reason=err)
-
-            ttpv = True
-            if prov_value == "full":
-                ttpv = False
-
-            # default to hp3par_cpg if hp3par_cpg_snap is not set.
-            if self.config.hp3par_cpg_snap == "":
-                snap_default = self.config.hp3par_cpg
-            else:
-                snap_default = self.config.hp3par_cpg_snap
-            snap_cpg = self._get_volume_type_value(volume_type,
-                                                   'snap_cpg',
-                                                   snap_default)
-
-            # check for valid persona even if we don't use it until
-            # attach time, this will given end user notice that the
-            # persona type is invalid at volume creation time
-            self.get_persona_type(volume)
-
-            if type_id is not None:
-                comments['volume_type_name'] = volume_type.get('name')
-                comments['volume_type_id'] = type_id
-
-            extras = {'comment': json.dumps(comments),
-                      'snapCPG': snap_cpg,
-                      'tpvv': ttpv}
-
-            capacity = self._capacity_from_size(volume['size'])
-            volume_name = self._get_3par_vol_name(volume['id'])
-            client.createVolume(volume_name, cpg, capacity, extras)
-
-        except hpexceptions.HTTPConflict:
-            raise exception.Duplicate(_("Volume (%s) already exists on array")
-                                      % volume_name)
-        except hpexceptions.HTTPBadRequest as ex:
-            LOG.error(str(ex))
-            raise exception.Invalid(ex.get_description())
-        except exception.InvalidInput as ex:
-            LOG.error(str(ex))
-            raise ex
-        except Exception as ex:
-            LOG.error(str(ex))
-            raise exception.CinderException(ex.get_description())
-
-        metadata = {'3ParName': volume_name, 'CPG': self.config.hp3par_cpg,
-                    'snapCPG': extras['snapCPG']}
-        return metadata
-
-    def _copy_volume(self, src_name, dest_name):
-        self._cli_run('createvvcopy -p %s %s' % (src_name, dest_name), None)
-
-    def _get_volume_state(self, vol_name):
-        out = self._cli_run('showvv -state %s' % vol_name, None)
-        status = None
-        if out:
-            # out[0] is the header
-            info = out[1].split(',')
-            status = info[5]
-
-        return status
-
-    @utils.synchronized('3parclone', external=True)
-    def create_cloned_volume(self, volume, src_vref, client):
-
-        try:
-            orig_name = self._get_3par_vol_name(volume['source_volid'])
-            vol_name = self._get_3par_vol_name(volume['id'])
-            # We need to create a new volume first.  Otherwise you
-            # can't delete the original
-            new_vol = self.create_volume(volume, client)
-
-            # make the 3PAR copy the contents.
-            # can't delete the original until the copy is done.
-            self._copy_volume(orig_name, vol_name)
-
-            # this can take a long time to complete
-            done = False
-            while not done:
-                status = self._get_volume_state(vol_name)
-                if status == 'normal':
-                    done = True
-                elif status == 'copy_target':
-                    LOG.debug("3Par still copying %s => %s"
-                              % (orig_name, vol_name))
-                else:
-                    msg = _("Unexpected state while cloning %s") % status
-                    LOG.warn(msg)
-                    raise exception.CinderException(msg)
-
-                if not done:
-                    # wait 5 seconds between tests
-                    time.sleep(5)
-
-            return new_vol
-        except hpexceptions.HTTPForbidden:
-            raise exception.NotAuthorized()
-        except hpexceptions.HTTPNotFound:
-            raise exception.NotFound()
-        except Exception as ex:
-            LOG.error(str(ex))
-            raise exception.CinderException(ex)
-
-        return None
-
-    def delete_volume(self, volume, client):
-        try:
-            volume_name = self._get_3par_vol_name(volume['id'])
-            client.deleteVolume(volume_name)
-        except hpexceptions.HTTPNotFound as ex:
-            # We'll let this act as if it worked
-            # it helps clean up the manila entries.
-            LOG.error(str(ex))
-        except hpexceptions.HTTPForbidden as ex:
-            LOG.error(str(ex))
-            raise exception.NotAuthorized(ex.get_description())
-        except Exception as ex:
-            LOG.error(str(ex))
-            raise exception.CinderException(ex.get_description())
-
-    def create_volume_from_snapshot(self, volume, snapshot, client):
-        """
-        Creates a volume from a snapshot.
-
-        TODO: support using the size from the user.
-        """
-        LOG.debug("Create Volume from Snapshot\n%s\n%s" %
-                  (pprint.pformat(volume['display_name']),
-                   pprint.pformat(snapshot['display_name'])))
-
-        if snapshot['volume_size'] != volume['size']:
-            err = "You cannot change size of the volume.  It must "
-            "be the same as the snapshot."
-            LOG.error(err)
-            raise exception.InvalidInput(reason=err)
-
-        try:
-            snap_name = self._get_3par_snap_name(snapshot['id'])
-            vol_name = self._get_3par_vol_name(volume['id'])
-
-            extra = {'volume_id': volume['id'],
-                     'snapshot_id': snapshot['id']}
-            name = snapshot.get('display_name', None)
-            if name:
-                extra['name'] = name
-
-            description = snapshot.get('display_description', None)
-            if description:
-                extra['description'] = description
-
-            optional = {'comment': json.dumps(extra),
-                        'readOnly': False}
-
-            client.createSnapshot(vol_name, snap_name, optional)
-        except hpexceptions.HTTPForbidden:
-            raise exception.NotAuthorized()
-        except hpexceptions.HTTPNotFound:
-            raise exception.NotFound()
-
-    def create_snapshot(self, snapshot, client):
-        LOG.debug("Create Snapshot\n%s" % pprint.pformat(snapshot))
-
-        try:
-            snap_name = self._get_3par_snap_name(snapshot['id'])
-            vol_name = self._get_3par_vol_name(snapshot['volume_id'])
-
-            extra = {'volume_name': snapshot['volume_name']}
-            vol_id = snapshot.get('volume_id', None)
-            if vol_id:
-                extra['volume_id'] = vol_id
-
-            try:
-                extra['name'] = snapshot['display_name']
-            except AttribteError:
-                pass
-
-            try:
-                extra['description'] = snapshot['display_description']
-            except AttribteError:
-                pass
-
-            optional = {'comment': json.dumps(extra),
-                        'readOnly': True}
-            if self.config.hp3par_snapshot_expiration:
-                optional['expirationHours'] = (
-                    self.config.hp3par_snapshot_expiration)
-
-            if self.config.hp3par_snapshot_retention:
-                optional['retentionHours'] = (
-                    self.config.hp3par_snapshot_retention)
-
-            client.createSnapshot(snap_name, vol_name, optional)
-        except hpexceptions.HTTPForbidden:
-            raise exception.NotAuthorized()
-        except hpexceptions.HTTPNotFound:
-            raise exception.NotFound()
-
-    def delete_snapshot(self, snapshot, client):
-        LOG.debug("Delete Snapshot\n%s" % pprint.pformat(snapshot))
-
-        try:
-            snap_name = self._get_3par_snap_name(snapshot['id'])
-            client.deleteVolume(snap_name)
-        except hpexceptions.HTTPForbidden:
-            raise exception.NotAuthorized()
-        except hpexceptions.HTTPNotFound as ex:
-            LOG.error(str(ex))
diff --git a/manila/volume/drivers/san/hp/hp_3par_fc.py b/manila/volume/drivers/san/hp/hp_3par_fc.py
deleted file mode 100644
index a69606c54d..0000000000
--- a/manila/volume/drivers/san/hp/hp_3par_fc.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-#    (c) Copyright 2013 Hewlett-Packard Development Company, L.P.
-#    All Rights Reserved.
-#
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-#
-"""
-Volume driver for HP 3PAR Storage array. This driver requires 3.1.2 firmware
-on the 3PAR array.
-
-You will need to install the python hp3parclient.
-sudo pip install hp3parclient
-
-Set the following in the manila.conf file to enable the
-3PAR Fibre Channel Driver along with the required flags:
-
-volume_driver=manila.volume.drivers.san.hp.hp_3par_fc.HP3PARFCDriver
-"""
-
-from hp3parclient import client
-from hp3parclient import exceptions as hpexceptions
-from oslo.config import cfg
-
-from manila import exception
-from manila.openstack.common import log as logging
-from manila import utils
-import manila.volume.driver
-from manila.volume.drivers.san.hp import hp_3par_common as hpcommon
-from manila.volume.drivers.san import san
-
-VERSION = 1.0
-LOG = logging.getLogger(__name__)
-
-
-class HP3PARFCDriver(manila.volume.driver.FibreChannelDriver):
-    """OpenStack Fibre Channel driver to enable 3PAR storage array.
-
-    Version history:
-        1.0 - Initial driver
-
-    """
-
-    def __init__(self, *args, **kwargs):
-        super(HP3PARFCDriver, self).__init__(*args, **kwargs)
-        self.client = None
-        self.common = None
-        self.configuration.append_config_values(hpcommon.hp3par_opts)
-        self.configuration.append_config_values(san.san_opts)
-
-    def _init_common(self):
-        return hpcommon.HP3PARCommon(self.configuration)
-
-    def _check_flags(self):
-        """Sanity check to ensure we have required options set."""
-        required_flags = ['hp3par_api_url', 'hp3par_username',
-                          'hp3par_password',
-                          'san_ip', 'san_login', 'san_password']
-        self.common.check_flags(self.configuration, required_flags)
-
-    def _create_client(self):
-        return client.HP3ParClient(self.configuration.hp3par_api_url)
-
-    def get_volume_stats(self, refresh):
-        stats = self.common.get_volume_stats(refresh, self.client)
-        stats['storage_protocol'] = 'FC'
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        stats['volume_backend_name'] = backend_name or self.__class__.__name__
-        return stats
-
-    def do_setup(self, context):
-        self.common = self._init_common()
-        self._check_flags()
-        self.client = self._create_client()
-        if self.configuration.hp3par_debug:
-            self.client.debug_rest(True)
-
-        try:
-            LOG.debug("Connecting to 3PAR")
-            self.client.login(self.configuration.hp3par_username,
-                              self.configuration.hp3par_password)
-        except hpexceptions.HTTPUnauthorized as ex:
-            LOG.warning("Failed to connect to 3PAR (%s) because %s" %
-                       (self.configuration.hp3par_api_url, str(ex)))
-            msg = _("Login to 3PAR array invalid")
-            raise exception.InvalidInput(reason=msg)
-
-        # make sure the CPG exists
-        try:
-            cpg = self.client.getCPG(self.configuration.hp3par_cpg)
-        except hpexceptions.HTTPNotFound as ex:
-            err = (_("CPG (%s) doesn't exist on array")
-                   % self.configuration.hp3par_cpg)
-            LOG.error(err)
-            raise exception.InvalidInput(reason=err)
-
-        if ('domain' not in cpg
-            and cpg['domain'] != self.configuration.hp3par_domain):
-            err = "CPG's domain '%s' and config option hp3par_domain '%s' \
-must be the same" % (cpg['domain'], self.configuration.hp3par_domain)
-            LOG.error(err)
-            raise exception.InvalidInput(reason=err)
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_flags()
-
-    @utils.synchronized('3par-vol', external=True)
-    def create_volume(self, volume):
-        metadata = self.common.create_volume(volume, self.client)
-        return {'metadata': metadata}
-
-    def create_cloned_volume(self, volume, src_vref):
-        new_vol = self.common.create_cloned_volume(volume, src_vref,
-                                                   self.client)
-        return {'metadata': new_vol}
-
-    @utils.synchronized('3par-vol', external=True)
-    def delete_volume(self, volume):
-        self.common.delete_volume(volume, self.client)
-
-    @utils.synchronized('3par-vol', external=True)
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """
-        Creates a volume from a snapshot.
-
-        TODO: support using the size from the user.
-        """
-        self.common.create_volume_from_snapshot(volume, snapshot, self.client)
-
-    @utils.synchronized('3par-snap', external=True)
-    def create_snapshot(self, snapshot):
-        self.common.create_snapshot(snapshot, self.client)
-
-    @utils.synchronized('3par-snap', external=True)
-    def delete_snapshot(self, snapshot):
-        self.common.delete_snapshot(snapshot, self.client)
-
-    @utils.synchronized('3par-attach', external=True)
-    def initialize_connection(self, volume, connector):
-        """Assigns the volume to a server.
-
-        Assign any created volume to a compute node/host so that it can be
-        used from that host.
-
-        The  driver returns a driver_volume_type of 'fibre_channel'.
-        The target_wwn can be a single entry or a list of wwns that
-        correspond to the list of remote wwn(s) that will export the volume.
-        Example return values:
-
-            {
-                'driver_volume_type': 'fibre_channel'
-                'data': {
-                    'target_discovered': True,
-                    'target_lun': 1,
-                    'target_wwn': '1234567890123',
-                }
-            }
-
-            or
-
-             {
-                'driver_volume_type': 'fibre_channel'
-                'data': {
-                    'target_discovered': True,
-                    'target_lun': 1,
-                    'target_wwn': ['1234567890123', '0987654321321'],
-                }
-            }
-
-
-        Steps to export a volume on 3PAR
-          * Create a host on the 3par with the target wwn
-          * Create a VLUN for that HOST with the volume we want to export.
-
-        """
-        # we have to make sure we have a host
-        host = self._create_host(volume, connector)
-
-        # now that we have a host, create the VLUN
-        vlun = self.common.create_vlun(volume, host, self.client)
-
-        ports = self.common.get_ports()
-
-        info = {'driver_volume_type': 'fibre_channel',
-                'data': {'target_lun': vlun['lun'],
-                         'target_discovered': True,
-                         'target_wwn': ports['FC']}}
-        return info
-
-    @utils.synchronized('3par-attach', external=True)
-    def terminate_connection(self, volume, connector, force):
-        """
-        Driver entry point to unattach a volume from an instance.
-        """
-        self.common.delete_vlun(volume, connector, self.client)
-        pass
-
-    def _create_3par_fibrechan_host(self, hostname, wwn, domain, persona_id):
-        out = self.common._cli_run('createhost -persona %s -domain %s %s %s'
-                                   % (persona_id, domain,
-                                      hostname, " ".join(wwn)), None)
-        if out and len(out) > 1:
-            if "already used by host" in out[1]:
-                err = out[1].strip()
-                info = _("The hostname must be called '%s'") % hostname
-                raise exception.Duplicate3PARHost(err=err, info=info)
-
-    def _modify_3par_fibrechan_host(self, hostname, wwn):
-        # when using -add, you can not send the persona or domain options
-        out = self.common._cli_run('createhost -add %s %s'
-                                   % (hostname, " ".join(wwn)), None)
-
-    def _create_host(self, volume, connector):
-        """
-        This is a 3PAR host entry for exporting volumes
-        via active VLUNs.
-        """
-        host = None
-        hostname = self.common._safe_hostname(connector['host'])
-        try:
-            host = self.common._get_3par_host(hostname)
-            if not host['FCPaths']:
-                self._modify_3par_fibrechan_host(hostname, connector['wwpns'])
-                host = self.common._get_3par_host(hostname)
-        except hpexceptions.HTTPNotFound as ex:
-            # get persona from the volume type extra specs
-            persona_id = self.common.get_persona_type(volume)
-            # host doesn't exist, we have to create it
-            self._create_3par_fibrechan_host(hostname, connector['wwpns'],
-                                             self.configuration.hp3par_domain,
-                                             persona_id)
-            host = self.common._get_3par_host(hostname)
-
-        return host
-
-    @utils.synchronized('3par-exp', external=True)
-    def create_export(self, context, volume):
-        pass
-
-    @utils.synchronized('3par-exp', external=True)
-    def ensure_export(self, context, volume):
-        pass
-
-    @utils.synchronized('3par-exp', external=True)
-    def remove_export(self, context, volume):
-        pass
diff --git a/manila/volume/drivers/san/hp/hp_3par_iscsi.py b/manila/volume/drivers/san/hp/hp_3par_iscsi.py
deleted file mode 100644
index 025e715091..0000000000
--- a/manila/volume/drivers/san/hp/hp_3par_iscsi.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-#    (c) Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
-#    All Rights Reserved.
-#
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-#
-"""
-Volume driver for HP 3PAR Storage array. This driver requires 3.1.2 firmware
-on the 3PAR array.
-
-You will need to install the python hp3parclient.
-sudo pip install hp3parclient
-
-Set the following in the manila.conf file to enable the
-3PAR iSCSI Driver along with the required flags:
-
-volume_driver=manila.volume.drivers.san.hp.hp_3par_iscsi.HP3PARISCSIDriver
-"""
-
-from hp3parclient import client
-from hp3parclient import exceptions as hpexceptions
-
-from manila import exception
-from manila.openstack.common import log as logging
-from manila import utils
-import manila.volume.driver
-from manila.volume.drivers.san.hp import hp_3par_common as hpcommon
-from manila.volume.drivers.san import san
-
-VERSION = 1.0
-LOG = logging.getLogger(__name__)
-
-
-class HP3PARISCSIDriver(manila.volume.driver.ISCSIDriver):
-    """OpenStack iSCSI driver to enable 3PAR storage array.
-
-    Version history:
-        1.0 - Initial driver
-
-    """
-    def __init__(self, *args, **kwargs):
-        super(HP3PARISCSIDriver, self).__init__(*args, **kwargs)
-        self.client = None
-        self.common = None
-        self.configuration.append_config_values(hpcommon.hp3par_opts)
-        self.configuration.append_config_values(san.san_opts)
-
-    def _init_common(self):
-        return hpcommon.HP3PARCommon(self.configuration)
-
-    def _check_flags(self):
-        """Sanity check to ensure we have required options set."""
-        required_flags = ['hp3par_api_url', 'hp3par_username',
-                          'hp3par_password', 'iscsi_ip_address',
-                          'iscsi_port', 'san_ip', 'san_login',
-                          'san_password']
-        self.common.check_flags(self.configuration, required_flags)
-
-    def _create_client(self):
-        return client.HP3ParClient(self.configuration.hp3par_api_url)
-
-    def get_volume_stats(self, refresh):
-        stats = self.common.get_volume_stats(refresh, self.client)
-        stats['storage_protocol'] = 'iSCSI'
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        stats['volume_backend_name'] = backend_name or self.__class__.__name__
-        return stats
-
-    def do_setup(self, context):
-        self.common = self._init_common()
-        self._check_flags()
-        self.client = self._create_client()
-        if self.configuration.hp3par_debug:
-            self.client.debug_rest(True)
-
-        try:
-            LOG.debug("Connecting to 3PAR")
-            self.client.login(self.configuration.hp3par_username,
-                              self.configuration.hp3par_password)
-        except hpexceptions.HTTPUnauthorized as ex:
-            LOG.warning("Failed to connect to 3PAR (%s) because %s" %
-                       (self.configuration.hp3par_api_url, str(ex)))
-            msg = _("Login to 3PAR array invalid")
-            raise exception.InvalidInput(reason=msg)
-
-        # make sure the CPG exists
-        try:
-            cpg = self.client.getCPG(self.configuration.hp3par_cpg)
-        except hpexceptions.HTTPNotFound as ex:
-            err = (_("CPG (%s) doesn't exist on array")
-                   % self.configuration.hp3par_cpg)
-            LOG.error(err)
-            raise exception.InvalidInput(reason=err)
-
-        if ('domain' not in cpg and
-            cpg['domain'] != self.configuration.hp3par_domain):
-            err = "CPG's domain '%s' and config option hp3par_domain '%s' \
-must be the same" % (cpg['domain'], self.configuration.hp3par_domain)
-            LOG.error(err)
-            raise exception.InvalidInput(reason=err)
-
-        # make sure ssh works.
-        self._iscsi_discover_target_iqn(self.configuration.iscsi_ip_address)
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_flags()
-
-    @utils.synchronized('3par-vol', external=True)
-    def create_volume(self, volume):
-        metadata = self.common.create_volume(volume, self.client)
-
-        return {'provider_location': "%s:%s" %
-                (self.configuration.iscsi_ip_address,
-                 self.configuration.iscsi_port),
-                'metadata': metadata}
-
-    def create_cloned_volume(self, volume, src_vref):
-        """ Clone an existing volume. """
-        new_vol = self.common.create_cloned_volume(volume, src_vref,
-                                                   self.client)
-        return {'provider_location': "%s:%s" %
-                (self.configuration.iscsi_ip_address,
-                 self.configuration.iscsi_port),
-                'metadata': new_vol}
-
-    @utils.synchronized('3par-vol', external=True)
-    def delete_volume(self, volume):
-        self.common.delete_volume(volume, self.client)
-
-    @utils.synchronized('3par-vol', external=True)
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """
-        Creates a volume from a snapshot.
-
-        TODO: support using the size from the user.
-        """
-        self.common.create_volume_from_snapshot(volume, snapshot, self.client)
-
-    @utils.synchronized('3par-snap', external=True)
-    def create_snapshot(self, snapshot):
-        self.common.create_snapshot(snapshot, self.client)
-
-    @utils.synchronized('3par-snap', external=True)
-    def delete_snapshot(self, snapshot):
-        self.common.delete_snapshot(snapshot, self.client)
-
-    @utils.synchronized('3par-attach', external=True)
-    def initialize_connection(self, volume, connector):
-        """Assigns the volume to a server.
-
-        Assign any created volume to a compute node/host so that it can be
-        used from that host.
-
-        This driver returns a driver_volume_type of 'iscsi'.
-        The format of the driver data is defined in _get_iscsi_properties.
-        Example return value:
-
-            {
-                'driver_volume_type': 'iscsi'
-                'data': {
-                    'target_discovered': True,
-                    'target_iqn': 'iqn.2010-10.org.openstack:volume-00000001',
-                    'target_protal': '127.0.0.1:3260',
-                    'volume_id': 1,
-                }
-            }
-
-        Steps to export a volume on 3PAR
-          * Get the 3PAR iSCSI iqn
-          * Create a host on the 3par
-          * create vlun on the 3par
-        """
-        # get the target_iqn on the 3par interface.
-        target_iqn = self._iscsi_discover_target_iqn(
-            self.configuration.iscsi_ip_address)
-
-        # we have to make sure we have a host
-        host = self._create_host(volume, connector)
-
-        # now that we have a host, create the VLUN
-        vlun = self.common.create_vlun(volume, host, self.client)
-
-        info = {'driver_volume_type': 'iscsi',
-                'data': {'target_portal': "%s:%s" %
-                         (self.configuration.iscsi_ip_address,
-                          self.configuration.iscsi_port),
-                         'target_iqn': target_iqn,
-                         'target_lun': vlun['lun'],
-                         'target_discovered': True
-                         }
-                }
-        return info
-
-    @utils.synchronized('3par-attach', external=True)
-    def terminate_connection(self, volume, connector, force):
-        """
-        Driver entry point to unattach a volume from an instance.
-        """
-        self.common.delete_vlun(volume, connector, self.client)
-
-    def _iscsi_discover_target_iqn(self, remote_ip):
-        result = self.common._cli_run('showport -ids', None)
-
-        iqn = None
-        if result:
-            # first line is header
-            result = result[1:]
-            for line in result:
-                info = line.split(",")
-                if info and len(info) > 2:
-                    if info[1] == remote_ip:
-                        iqn = info[2]
-
-        return iqn
-
-    def _create_3par_iscsi_host(self, hostname, iscsi_iqn, domain, persona_id):
-        cmd = 'createhost -iscsi -persona %s -domain %s %s %s' % \
-              (persona_id, domain, hostname, iscsi_iqn)
-        out = self.common._cli_run(cmd, None)
-        if out and len(out) > 1:
-            if "already used by host" in out[1]:
-                err = out[1].strip()
-                info = _("The hostname must be called '%s'") % hostname
-                raise exception.Duplicate3PARHost(err=err, info=info)
-
-    def _modify_3par_iscsi_host(self, hostname, iscsi_iqn):
-        # when using -add, you can not send the persona or domain options
-        self.common._cli_run('createhost -iscsi -add %s %s'
-                             % (hostname, iscsi_iqn), None)
-
-    def _create_host(self, volume, connector):
-        """
-        This is a 3PAR host entry for exporting volumes
-        via active VLUNs.
-        """
-        # make sure we don't have the host already
-        host = None
-        hostname = self.common._safe_hostname(connector['host'])
-        try:
-            host = self.common._get_3par_host(hostname)
-            if not host['iSCSIPaths']:
-                self._modify_3par_iscsi_host(hostname, connector['initiator'])
-                host = self.common._get_3par_host(hostname)
-        except hpexceptions.HTTPNotFound:
-            # get persona from the volume type extra specs
-            persona_id = self.common.get_persona_type(volume)
-            # host doesn't exist, we have to create it
-            self._create_3par_iscsi_host(hostname, connector['initiator'],
-                                         self.configuration.hp3par_domain,
-                                         persona_id)
-            host = self.common._get_3par_host(hostname)
-
-        return host
-
-    @utils.synchronized('3par-exp', external=True)
-    def create_export(self, context, volume):
-        pass
-
-    @utils.synchronized('3par-exp', external=True)
-    def ensure_export(self, context, volume):
-        pass
-
-    @utils.synchronized('3par-exp', external=True)
-    def remove_export(self, context, volume):
-        pass
diff --git a/manila/volume/drivers/san/hp_lefthand.py b/manila/volume/drivers/san/hp_lefthand.py
deleted file mode 100644
index f4c82a6ccc..0000000000
--- a/manila/volume/drivers/san/hp_lefthand.py
+++ /dev/null
@@ -1,314 +0,0 @@
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-HP Lefthand SAN ISCSI Driver.
-
-The driver communicates to the backend aka Cliq via SSH to perform all the
-operations on the SAN.
-"""
-from lxml import etree
-
-from manila import exception
-from manila.openstack.common import log as logging
-from manila.volume.drivers.san.san import SanISCSIDriver
-
-
-LOG = logging.getLogger(__name__)
-
-
-class HpSanISCSIDriver(SanISCSIDriver):
-    """Executes commands relating to HP/Lefthand SAN ISCSI volumes.
-
-    We use the CLIQ interface, over SSH.
-
-    Rough overview of CLIQ commands used:
-
-    :createVolume:    (creates the volume)
-
-    :getVolumeInfo:    (to discover the IQN etc)
-
-    :getClusterInfo:    (to discover the iSCSI target IP address)
-
-    :assignVolumeChap:    (exports it with CHAP security)
-
-    The 'trick' here is that the HP SAN enforces security by default, so
-    normally a volume mount would need both to configure the SAN in the volume
-    layer and do the mount on the compute layer.  Multi-layer operations are
-    not catered for at the moment in the manila architecture, so instead we
-    share the volume using CHAP at volume creation time.  Then the mount need
-    only use those CHAP credentials, so can take place exclusively in the
-    compute layer.
-    """
-
-    device_stats = {}
-
-    def __init__(self, *args, **kwargs):
-        super(HpSanISCSIDriver, self).__init__(*args, **kwargs)
-        self.cluster_vip = None
-
-    def _cliq_run(self, verb, cliq_args, check_exit_code=True):
-        """Runs a CLIQ command over SSH, without doing any result parsing"""
-        cliq_arg_strings = []
-        for k, v in cliq_args.items():
-            cliq_arg_strings.append(" %s=%s" % (k, v))
-        cmd = verb + ''.join(cliq_arg_strings)
-
-        return self._run_ssh(cmd, check_exit_code)
-
-    def _cliq_run_xml(self, verb, cliq_args, check_cliq_result=True):
-        """Runs a CLIQ command over SSH, parsing and checking the output"""
-        cliq_args['output'] = 'XML'
-        (out, _err) = self._cliq_run(verb, cliq_args, check_cliq_result)
-
-        LOG.debug(_("CLIQ command returned %s"), out)
-
-        result_xml = etree.fromstring(out)
-        if check_cliq_result:
-            response_node = result_xml.find("response")
-            if response_node is None:
-                msg = (_("Malformed response to CLIQ command "
-                         "%(verb)s %(cliq_args)s. Result=%(out)s") %
-                       locals())
-                raise exception.VolumeBackendAPIException(data=msg)
-
-            result_code = response_node.attrib.get("result")
-
-            if result_code != "0":
-                msg = (_("Error running CLIQ command %(verb)s %(cliq_args)s. "
-                         " Result=%(out)s") %
-                       locals())
-                raise exception.VolumeBackendAPIException(data=msg)
-
-        return result_xml
-
-    def _cliq_get_cluster_info(self, cluster_name):
-        """Queries for info about the cluster (including IP)"""
-        cliq_args = {}
-        cliq_args['clusterName'] = cluster_name
-        cliq_args['searchDepth'] = '1'
-        cliq_args['verbose'] = '0'
-
-        result_xml = self._cliq_run_xml("getClusterInfo", cliq_args)
-
-        return result_xml
-
-    def _cliq_get_cluster_vip(self, cluster_name):
-        """Gets the IP on which a cluster shares iSCSI volumes"""
-        cluster_xml = self._cliq_get_cluster_info(cluster_name)
-
-        vips = []
-        for vip in cluster_xml.findall("response/cluster/vip"):
-            vips.append(vip.attrib.get('ipAddress'))
-
-        if len(vips) == 1:
-            return vips[0]
-
-        _xml = etree.tostring(cluster_xml)
-        msg = (_("Unexpected number of virtual ips for cluster "
-                 " %(cluster_name)s. Result=%(_xml)s") %
-               locals())
-        raise exception.VolumeBackendAPIException(data=msg)
-
-    def _cliq_get_volume_info(self, volume_name):
-        """Gets the volume info, including IQN"""
-        cliq_args = {}
-        cliq_args['volumeName'] = volume_name
-        result_xml = self._cliq_run_xml("getVolumeInfo", cliq_args)
-
-        # Result looks like this:
-        #<gauche version="1.0">
-        #  <response description="Operation succeeded." name="CliqSuccess"
-        #            processingTime="87" result="0">
-        #    <volume autogrowPages="4" availability="online" blockSize="1024"
-        #       bytesWritten="0" checkSum="false" clusterName="Cluster01"
-        #       created="2011-02-08T19:56:53Z" deleting="false" description=""
-        #       groupName="Group01" initialQuota="536870912" isPrimary="true"
-        #       iscsiIqn="iqn.2003-10.com.lefthandnetworks:group01:25366:vol-b"
-        #       maxSize="6865387257856" md5="9fa5c8b2cca54b2948a63d833097e1ca"
-        #       minReplication="1" name="vol-b" parity="0" replication="2"
-        #       reserveQuota="536870912" scratchQuota="4194304"
-        #       serialNumber="9fa5c8b2cca54b2948a63d833097e1ca0000000000006316"
-        #       size="1073741824" stridePages="32" thinProvision="true">
-        #      <status description="OK" value="2"/>
-        #      <permission access="rw"
-        #            authGroup="api-34281B815713B78-(trimmed)51ADD4B7030853AA7"
-        #            chapName="chapusername" chapRequired="true" id="25369"
-        #            initiatorSecret="" iqn="" iscsiEnabled="true"
-        #            loadBalance="true" targetSecret="supersecret"/>
-        #    </volume>
-        #  </response>
-        #</gauche>
-
-        # Flatten the nodes into a dictionary; use prefixes to avoid collisions
-        volume_attributes = {}
-
-        volume_node = result_xml.find("response/volume")
-        for k, v in volume_node.attrib.items():
-            volume_attributes["volume." + k] = v
-
-        status_node = volume_node.find("status")
-        if status_node is not None:
-            for k, v in status_node.attrib.items():
-                volume_attributes["status." + k] = v
-
-        # We only consider the first permission node
-        permission_node = volume_node.find("permission")
-        if permission_node is not None:
-            for k, v in status_node.attrib.items():
-                volume_attributes["permission." + k] = v
-
-        LOG.debug(_("Volume info: %(volume_name)s => %(volume_attributes)s") %
-                  locals())
-        return volume_attributes
-
-    def create_volume(self, volume):
-        """Creates a volume."""
-        cliq_args = {}
-        cliq_args['clusterName'] = self.configuration.san_clustername
-
-        if self.configuration.san_thin_provision:
-            cliq_args['thinProvision'] = '1'
-        else:
-            cliq_args['thinProvision'] = '0'
-
-        cliq_args['volumeName'] = volume['name']
-        if int(volume['size']) == 0:
-            cliq_args['size'] = '100MB'
-        else:
-            cliq_args['size'] = '%sGB' % volume['size']
-
-        self._cliq_run_xml("createVolume", cliq_args)
-
-        volume_info = self._cliq_get_volume_info(volume['name'])
-        cluster_name = volume_info['volume.clusterName']
-        iscsi_iqn = volume_info['volume.iscsiIqn']
-
-        #TODO(justinsb): Is this always 1? Does it matter?
-        cluster_interface = '1'
-
-        if not self.cluster_vip:
-            self.cluster_vip = self._cliq_get_cluster_vip(cluster_name)
-        iscsi_portal = self.cluster_vip + ":3260," + cluster_interface
-
-        model_update = {}
-
-        # NOTE(jdg): LH volumes always at lun 0 ?
-        model_update['provider_location'] = ("%s %s %s" %
-                                             (iscsi_portal,
-                                              iscsi_iqn,
-                                              0))
-
-        return model_update
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-        raise NotImplementedError()
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        raise NotImplementedError()
-
-    def delete_volume(self, volume):
-        """Deletes a volume."""
-        cliq_args = {}
-        cliq_args['volumeName'] = volume['name']
-        cliq_args['prompt'] = 'false'  # Don't confirm
-        try:
-            volume_info = self._cliq_get_volume_info(volume['name'])
-        except exception.ProcessExecutionError:
-            LOG.error("Volume did not exist. It will not be deleted")
-            return
-        self._cliq_run_xml("deleteVolume", cliq_args)
-
-    def local_path(self, volume):
-        msg = _("local_path not supported")
-        raise exception.VolumeBackendAPIException(data=msg)
-
-    def initialize_connection(self, volume, connector):
-        """Assigns the volume to a server.
-
-        Assign any created volume to a compute node/host so that it can be
-        used from that host. HP VSA requires a volume to be assigned
-        to a server.
-
-        This driver returns a driver_volume_type of 'iscsi'.
-        The format of the driver data is defined in _get_iscsi_properties.
-        Example return value:
-
-            {
-                'driver_volume_type': 'iscsi'
-                'data': {
-                    'target_discovered': True,
-                    'target_iqn': 'iqn.2010-10.org.openstack:volume-00000001',
-                    'target_protal': '127.0.0.1:3260',
-                    'volume_id': 1,
-                }
-            }
-
-        """
-        self._create_server(connector)
-        cliq_args = {}
-        cliq_args['volumeName'] = volume['name']
-        cliq_args['serverName'] = connector['host']
-        self._cliq_run_xml("assignVolumeToServer", cliq_args)
-
-        iscsi_properties = self._get_iscsi_properties(volume)
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': iscsi_properties
-        }
-
-    def _create_server(self, connector):
-        cliq_args = {}
-        cliq_args['serverName'] = connector['host']
-        out = self._cliq_run_xml("getServerInfo", cliq_args, False)
-        response = out.find("response")
-        result = response.attrib.get("result")
-        if result != '0':
-            cliq_args = {}
-            cliq_args['serverName'] = connector['host']
-            cliq_args['initiator'] = connector['initiator']
-            self._cliq_run_xml("createServer", cliq_args)
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Unassign the volume from the host."""
-        cliq_args = {}
-        cliq_args['volumeName'] = volume['name']
-        cliq_args['serverName'] = connector['host']
-        self._cliq_run_xml("unassignVolumeToServer", cliq_args)
-
-    def get_volume_stats(self, refresh):
-        if refresh:
-            self._update_backend_status()
-
-        return self.device_stats
-
-    def _update_backend_status(self):
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data['volume_backend_name'] = backend_name or self.__class__.__name__
-        data['driver_version'] = '1.0'
-        data['reserved_percentage'] = 0
-        data['storage_protocol'] = 'iSCSI'
-        data['vendor_name'] = 'Hewlett-Packard'
-
-        result_xml = self._cliq_run_xml("getClusterInfo", {})
-        cluster_node = result_xml.find("response/cluster")
-        total_capacity = cluster_node.attrib.get("spaceTotal")
-        free_capacity = cluster_node.attrib.get("unprovisionedSpace")
-        GB = 1073741824
-
-        data['total_capacity_gb'] = int(total_capacity) / GB
-        data['free_capacity_gb'] = int(free_capacity) / GB
-        self.device_stats = data
diff --git a/manila/volume/drivers/san/san.py b/manila/volume/drivers/san/san.py
deleted file mode 100644
index 851daf7c46..0000000000
--- a/manila/volume/drivers/san/san.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 Justin Santa Barbara
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Default Driver for san-stored volumes.
-
-The unique thing about a SAN is that we don't expect that we can run the volume
-controller on the SAN hardware.  We expect to access it over SSH or some API.
-"""
-
-import random
-
-from eventlet import greenthread
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume.driver import ISCSIDriver
-
-LOG = logging.getLogger(__name__)
-
-san_opts = [
-    cfg.BoolOpt('san_thin_provision',
-                default=True,
-                help='Use thin provisioning for SAN volumes?'),
-    cfg.StrOpt('san_ip',
-               default='',
-               help='IP address of SAN controller'),
-    cfg.StrOpt('san_login',
-               default='admin',
-               help='Username for SAN controller'),
-    cfg.StrOpt('san_password',
-               default='',
-               help='Password for SAN controller',
-               secret=True),
-    cfg.StrOpt('san_private_key',
-               default='',
-               help='Filename of private key to use for SSH authentication'),
-    cfg.StrOpt('san_clustername',
-               default='',
-               help='Cluster name to use for creating volumes'),
-    cfg.IntOpt('san_ssh_port',
-               default=22,
-               help='SSH port to use with SAN'),
-    cfg.BoolOpt('san_is_local',
-                default=False,
-                help='Execute commands locally instead of over SSH; '
-                     'use if the volume service is running on the SAN device'),
-    cfg.IntOpt('ssh_conn_timeout',
-               default=30,
-               help="SSH connection timeout in seconds"),
-    cfg.IntOpt('ssh_min_pool_conn',
-               default=1,
-               help='Minimum ssh connections in the pool'),
-    cfg.IntOpt('ssh_max_pool_conn',
-               default=5,
-               help='Maximum ssh connections in the pool'),
-]
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(san_opts)
-
-
-class SanISCSIDriver(ISCSIDriver):
-    """Base class for SAN-style storage volumes
-
-    A SAN-style storage value is 'different' because the volume controller
-    probably won't run on it, so we need to access is over SSH or another
-    remote protocol.
-    """
-
-    def __init__(self, *args, **kwargs):
-        super(SanISCSIDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(san_opts)
-        self.run_local = self.configuration.san_is_local
-        self.sshpool = None
-
-    def _build_iscsi_target_name(self, volume):
-        return "%s%s" % (self.configuration.iscsi_target_prefix,
-                         volume['name'])
-
-    def _execute(self, *cmd, **kwargs):
-        if self.run_local:
-            return utils.execute(*cmd, **kwargs)
-        else:
-            check_exit_code = kwargs.pop('check_exit_code', None)
-            command = ' '.join(cmd)
-            return self._run_ssh(command, check_exit_code)
-
-    def _run_ssh(self, command, check_exit_code=True, attempts=1):
-        if not self.sshpool:
-            password = self.configuration.san_password
-            privatekey = self.configuration.san_private_key
-            min_size = self.configuration.ssh_min_pool_conn
-            max_size = self.configuration.ssh_max_pool_conn
-            self.sshpool = utils.SSHPool(self.configuration.san_ip,
-                                         self.configuration.san_ssh_port,
-                                         self.configuration.ssh_conn_timeout,
-                                         self.configuration.san_login,
-                                         password=password,
-                                         privatekey=privatekey,
-                                         min_size=min_size,
-                                         max_size=max_size)
-        last_exception = None
-        try:
-            total_attempts = attempts
-            with self.sshpool.item() as ssh:
-                while attempts > 0:
-                    attempts -= 1
-                    try:
-                        return utils.ssh_execute(
-                            ssh,
-                            command,
-                            check_exit_code=check_exit_code)
-                    except Exception as e:
-                        LOG.error(e)
-                        last_exception = e
-                        greenthread.sleep(random.randint(20, 500) / 100.0)
-                try:
-                    raise exception.ProcessExecutionError(
-                            exit_code=last_exception.exit_code,
-                            stdout=last_exception.stdout,
-                            stderr=last_exception.stderr,
-                            cmd=last_exception.cmd)
-                except AttributeError:
-                    raise exception.ProcessExecutionError(
-                            exit_code=-1,
-                            stdout="",
-                            stderr="Error running SSH command",
-                            cmd=command)
-
-        except Exception as e:
-            LOG.error(_("Error running SSH command: %s") % command)
-            raise e
-
-    def ensure_export(self, context, volume):
-        """Synchronously recreates an export for a logical volume."""
-        pass
-
-    def create_export(self, context, volume):
-        """Exports the volume."""
-        pass
-
-    def remove_export(self, context, volume):
-        """Removes an export for a logical volume."""
-        pass
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        if not self.run_local:
-            if not (self.configuration.san_password or
-                    self.configuration.san_private_key):
-                raise exception.InvalidInput(
-                    reason=_('Specify san_password or san_private_key'))
-
-        # The san_ip must always be set, because we use it for the target
-        if not self.configuration.san_ip:
-            raise exception.InvalidInput(reason=_("san_ip must be set"))
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Create a cloen of the specified volume."""
-        raise NotImplementedError()
diff --git a/manila/volume/drivers/san/solaris.py b/manila/volume/drivers/san/solaris.py
deleted file mode 100644
index f56a4302b9..0000000000
--- a/manila/volume/drivers/san/solaris.py
+++ /dev/null
@@ -1,285 +0,0 @@
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila.volume.drivers.san.san import SanISCSIDriver
-
-LOG = logging.getLogger(__name__)
-
-solaris_opts = [
-    cfg.StrOpt('san_zfs_volume_base',
-               default='rpool/',
-               help='The ZFS path under which to create zvols for volumes.'), ]
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(solaris_opts)
-
-
-class SolarisISCSIDriver(SanISCSIDriver):
-    """Executes commands relating to Solaris-hosted ISCSI volumes.
-
-    Basic setup for a Solaris iSCSI server:
-
-    pkg install storage-server SUNWiscsit
-
-    svcadm enable stmf
-
-    svcadm enable -r svc:/network/iscsi/target:default
-
-    pfexec itadm create-tpg e1000g0 ${MYIP}
-
-    pfexec itadm create-target -t e1000g0
-
-
-    Then grant the user that will be logging on lots of permissions.
-    I'm not sure exactly which though:
-
-    zfs allow justinsb create,mount,destroy rpool
-
-    usermod -P'File System Management' justinsb
-
-    usermod -P'Primary Administrator' justinsb
-
-    Also make sure you can login using san_login & san_password/san_private_key
-    """
-    def __init__(self, *cmd, **kwargs):
-        super(SolarisISCSIDriver, self).__init__(*cmd,
-                                                 execute=self._execute,
-                                                 **kwargs)
-
-    def _execute(self, *cmd, **kwargs):
-        new_cmd = ['pfexec']
-        new_cmd.extend(cmd)
-        return super(SolarisISCSIDriver, self)._execute(*new_cmd,
-                                                        **kwargs)
-
-    def _view_exists(self, luid):
-        (out, _err) = self._execute('/usr/sbin/stmfadm',
-                                    'list-view', '-l', luid,
-                                    check_exit_code=False)
-        if "no views found" in out:
-            return False
-
-        if "View Entry:" in out:
-            return True
-        msg = _("Cannot parse list-view output: %s") % out
-        raise exception.VolumeBackendAPIException(data=msg)
-
-    def _get_target_groups(self):
-        """Gets list of target groups from host."""
-        (out, _err) = self._execute('/usr/sbin/stmfadm', 'list-tg')
-        matches = self._get_prefixed_values(out, 'Target group: ')
-        LOG.debug("target_groups=%s" % matches)
-        return matches
-
-    def _target_group_exists(self, target_group_name):
-        return target_group_name not in self._get_target_groups()
-
-    def _get_target_group_members(self, target_group_name):
-        (out, _err) = self._execute('/usr/sbin/stmfadm',
-                                    'list-tg', '-v', target_group_name)
-        matches = self._get_prefixed_values(out, 'Member: ')
-        LOG.debug("members of %s=%s" % (target_group_name, matches))
-        return matches
-
-    def _is_target_group_member(self, target_group_name, iscsi_target_name):
-        return iscsi_target_name in (
-            self._get_target_group_members(target_group_name))
-
-    def _get_iscsi_targets(self):
-        (out, _err) = self._execute('/usr/sbin/itadm', 'list-target')
-        matches = self._collect_lines(out)
-
-        # Skip header
-        if len(matches) != 0:
-            assert 'TARGET NAME' in matches[0]
-            matches = matches[1:]
-
-        targets = []
-        for line in matches:
-            items = line.split()
-            assert len(items) == 3
-            targets.append(items[0])
-
-        LOG.debug("_get_iscsi_targets=%s" % (targets))
-        return targets
-
-    def _iscsi_target_exists(self, iscsi_target_name):
-        return iscsi_target_name in self._get_iscsi_targets()
-
-    def _build_zfs_poolname(self, volume):
-        zfs_poolname = '%s%s' % (FLAGS.san_zfs_volume_base, volume['name'])
-        return zfs_poolname
-
-    def create_volume(self, volume):
-        """Creates a volume."""
-        if int(volume['size']) == 0:
-            sizestr = '100M'
-        else:
-            sizestr = '%sG' % volume['size']
-
-        zfs_poolname = self._build_zfs_poolname(volume)
-
-        # Create a zfs volume
-        cmd = ['/usr/sbin/zfs', 'create']
-        if FLAGS.san_thin_provision:
-            cmd.append('-s')
-        cmd.extend(['-V', sizestr])
-        cmd.append(zfs_poolname)
-        self._execute(*cmd)
-
-    def _get_luid(self, volume):
-        zfs_poolname = self._build_zfs_poolname(volume)
-        zvol_name = '/dev/zvol/rdsk/%s' % zfs_poolname
-
-        (out, _err) = self._execute('/usr/sbin/sbdadm', 'list-lu')
-
-        lines = self._collect_lines(out)
-
-        # Strip headers
-        if len(lines) >= 1:
-            if lines[0] == '':
-                lines = lines[1:]
-
-        if len(lines) >= 4:
-            assert 'Found' in lines[0]
-            assert '' == lines[1]
-            assert 'GUID' in lines[2]
-            assert '------------------' in lines[3]
-
-            lines = lines[4:]
-
-        for line in lines:
-            items = line.split()
-            assert len(items) == 3
-            if items[2] == zvol_name:
-                luid = items[0].strip()
-                return luid
-
-        msg = _('LUID not found for %(zfs_poolname)s. '
-                'Output=%(out)s') % locals()
-        raise exception.VolumeBackendAPIException(data=msg)
-
-    def _is_lu_created(self, volume):
-        luid = self._get_luid(volume)
-        return luid
-
-    def delete_volume(self, volume):
-        """Deletes a volume."""
-        zfs_poolname = self._build_zfs_poolname(volume)
-        self._execute('/usr/sbin/zfs', 'destroy', zfs_poolname)
-
-    def local_path(self, volume):
-        # TODO(justinsb): Is this needed here?
-        escaped_group = FLAGS.volume_group.replace('-', '--')
-        escaped_name = volume['name'].replace('-', '--')
-        return "/dev/mapper/%s-%s" % (escaped_group, escaped_name)
-
-    def ensure_export(self, context, volume):
-        """Synchronously recreates an export for a logical volume."""
-        #TODO(justinsb): On bootup, this is called for every volume.
-        # It then runs ~5 SSH commands for each volume,
-        # most of which fetch the same info each time
-        # This makes initial start stupid-slow
-        return self._do_export(volume, force_create=False)
-
-    def create_export(self, context, volume):
-        return self._do_export(volume, force_create=True)
-
-    def _do_export(self, volume, force_create):
-        # Create a Logical Unit (LU) backed by the zfs volume
-        zfs_poolname = self._build_zfs_poolname(volume)
-
-        if force_create or not self._is_lu_created(volume):
-            zvol_name = '/dev/zvol/rdsk/%s' % zfs_poolname
-            self._execute('/usr/sbin/sbdadm', 'create-lu', zvol_name)
-
-        luid = self._get_luid(volume)
-        iscsi_name = self._build_iscsi_target_name(volume)
-        target_group_name = 'tg-%s' % volume['name']
-
-        # Create a iSCSI target, mapped to just this volume
-        if force_create or not self._target_group_exists(target_group_name):
-            self._execute('/usr/sbin/stmfadm', 'create-tg', target_group_name)
-
-        # Yes, we add the initiatior before we create it!
-        # Otherwise, it complains that the target is already active
-        if force_create or not self._is_target_group_member(target_group_name,
-                                                            iscsi_name):
-            self._execute('/usr/sbin/stmfadm',
-                          'add-tg-member', '-g', target_group_name, iscsi_name)
-
-        if force_create or not self._iscsi_target_exists(iscsi_name):
-            self._execute('/usr/sbin/itadm', 'create-target', '-n', iscsi_name)
-
-        if force_create or not self._view_exists(luid):
-            self._execute('/usr/sbin/stmfadm',
-                          'add-view', '-t', target_group_name, luid)
-
-        #TODO(justinsb): Is this always 1? Does it matter?
-        iscsi_portal_interface = '1'
-        iscsi_portal = FLAGS.san_ip + ":3260," + iscsi_portal_interface
-
-        db_update = {}
-        db_update['provider_location'] = ("%s %s" %
-                                          (iscsi_portal,
-                                           iscsi_name))
-
-        return db_update
-
-    def remove_export(self, context, volume):
-        """Removes an export for a logical volume."""
-
-        # This is the reverse of _do_export
-        luid = self._get_luid(volume)
-        iscsi_name = self._build_iscsi_target_name(volume)
-        target_group_name = 'tg-%s' % volume['name']
-
-        if self._view_exists(luid):
-            self._execute('/usr/sbin/stmfadm', 'remove-view', '-l', luid, '-a')
-
-        if self._iscsi_target_exists(iscsi_name):
-            self._execute('/usr/sbin/stmfadm', 'offline-target', iscsi_name)
-            self._execute('/usr/sbin/itadm', 'delete-target', iscsi_name)
-
-        # We don't delete the tg-member; we delete the whole tg!
-
-        if self._target_group_exists(target_group_name):
-            self._execute('/usr/sbin/stmfadm', 'delete-tg', target_group_name)
-
-        if self._is_lu_created(volume):
-            self._execute('/usr/sbin/sbdadm', 'delete-lu', luid)
-
-    def _collect_lines(self, data):
-        """Split lines from data into an array, trimming them """
-        matches = []
-        for line in data.splitlines():
-            match = line.strip()
-            matches.append(match)
-        return matches
-
-    def _get_prefixed_values(self, data, prefix):
-        """Collect lines which start with prefix; with trimming"""
-        matches = []
-        for line in data.splitlines():
-            line = line.strip()
-            if line.startswith(prefix):
-                match = line[len(prefix):]
-                match = match.strip()
-                matches.append(match)
-        return matches
diff --git a/manila/volume/drivers/scality.py b/manila/volume/drivers/scality.py
deleted file mode 100644
index bd28fcd802..0000000000
--- a/manila/volume/drivers/scality.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# Copyright (c) 2013 Scality
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-Scality SOFS Volume Driver.
-"""
-
-import errno
-import os
-import urllib2
-import urlparse
-
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.image import image_utils
-from manila.openstack.common import log as logging
-from manila.volume import driver
-
-LOG = logging.getLogger(__name__)
-
-volume_opts = [
-    cfg.StrOpt('scality_sofs_config',
-               default=None,
-               help='Path or URL to Scality SOFS configuration file'),
-    cfg.StrOpt('scality_sofs_mount_point',
-               default='$state_path/scality',
-               help='Base dir where Scality SOFS shall be mounted'),
-    cfg.StrOpt('scality_sofs_volume_dir',
-               default='manila/volumes',
-               help='Path from Scality SOFS root to volume dir'),
-]
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(volume_opts)
-
-
-class ScalityDriver(driver.VolumeDriver):
-    """Scality SOFS manila driver.
-
-    Creates sparse files on SOFS for hypervisors to use as block
-    devices.
-    """
-
-    def _check_prerequisites(self):
-        """Sanity checks before attempting to mount SOFS."""
-
-        # config is mandatory
-        config = FLAGS.scality_sofs_config
-        if not config:
-            msg = _("Value required for 'scality_sofs_config'")
-            LOG.warn(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        # config can be a file path or a URL, check it
-        if urlparse.urlparse(config).scheme == '':
-            # turn local path into URL
-            config = 'file://%s' % config
-        try:
-            urllib2.urlopen(config, timeout=5).close()
-        except urllib2.URLError as e:
-            msg = _("Cannot access 'scality_sofs_config': %s") % e
-            LOG.warn(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-        # mount.sofs must be installed
-        if not os.access('/sbin/mount.sofs', os.X_OK):
-            msg = _("Cannot execute /sbin/mount.sofs")
-            LOG.warn(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-    def _makedirs(self, path):
-        try:
-            os.makedirs(path)
-        except OSError as e:
-            if e.errno != errno.EEXIST:
-                raise e
-
-    def _mount_sofs(self):
-        config = FLAGS.scality_sofs_config
-        mount_path = FLAGS.scality_sofs_mount_point
-        sysdir = os.path.join(mount_path, 'sys')
-
-        self._makedirs(mount_path)
-        if not os.path.isdir(sysdir):
-            self._execute('mount', '-t', 'sofs', config, mount_path,
-                          run_as_root=True)
-        if not os.path.isdir(sysdir):
-            msg = _("Cannot mount Scality SOFS, check syslog for errors")
-            LOG.warn(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-    def _size_bytes(self, size_in_g):
-        if int(size_in_g) == 0:
-            return 100 * 1024 * 1024
-        return int(size_in_g) * 1024 * 1024 * 1024
-
-    def _create_file(self, path, size):
-        with open(path, "ab") as f:
-            f.truncate(size)
-        os.chmod(path, 0666)
-
-    def _copy_file(self, src_path, dest_path):
-        self._execute('dd', 'if=%s' % src_path, 'of=%s' % dest_path,
-                      'bs=1M', 'conv=fsync,nocreat,notrunc',
-                      run_as_root=True)
-
-    def do_setup(self, context):
-        """Any initialization the volume driver does while starting."""
-        self._check_prerequisites()
-        self._mount_sofs()
-        voldir = os.path.join(FLAGS.scality_sofs_mount_point,
-                              FLAGS.scality_sofs_volume_dir)
-        if not os.path.isdir(voldir):
-            self._makedirs(voldir)
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_prerequisites()
-        voldir = os.path.join(FLAGS.scality_sofs_mount_point,
-                              FLAGS.scality_sofs_volume_dir)
-        if not os.path.isdir(voldir):
-            msg = _("Cannot find volume dir for Scality SOFS at '%s'") % voldir
-            LOG.warn(msg)
-            raise exception.VolumeBackendAPIException(data=msg)
-
-    def create_volume(self, volume):
-        """Creates a logical volume.
-
-        Can optionally return a Dictionary of changes to the volume
-        object to be persisted.
-        """
-        self._create_file(self.local_path(volume),
-                          self._size_bytes(volume['size']))
-        volume['provider_location'] = self._sofs_path(volume)
-        return {'provider_location': volume['provider_location']}
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a volume from a snapshot."""
-        changes = self.create_volume(volume)
-        self._copy_file(self.local_path(snapshot),
-                        self.local_path(volume))
-        return changes
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-        os.remove(self.local_path(volume))
-
-    def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        volume_path = os.path.join(FLAGS.scality_sofs_mount_point,
-                                   FLAGS.scality_sofs_volume_dir,
-                                   snapshot['volume_name'])
-        snapshot_path = self.local_path(snapshot)
-        self._create_file(snapshot_path,
-                          self._size_bytes(snapshot['volume_size']))
-        self._copy_file(volume_path, snapshot_path)
-
-    def delete_snapshot(self, snapshot):
-        """Deletes a snapshot."""
-        os.remove(self.local_path(snapshot))
-
-    def _sofs_path(self, volume):
-        return os.path.join(FLAGS.scality_sofs_volume_dir,
-                            volume['name'])
-
-    def local_path(self, volume):
-        return os.path.join(FLAGS.scality_sofs_mount_point,
-                            self._sofs_path(volume))
-
-    def ensure_export(self, context, volume):
-        """Synchronously recreates an export for a logical volume."""
-        pass
-
-    def create_export(self, context, volume):
-        """Exports the volume.
-
-        Can optionally return a Dictionary of changes to the volume
-        object to be persisted.
-        """
-        pass
-
-    def remove_export(self, context, volume):
-        """Removes an export for a logical volume."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Allow connection to connector and return connection info."""
-        return {
-            'driver_volume_type': 'scality',
-            'data': {
-                'sofs_path': self._sofs_path(volume),
-            }
-        }
-
-    def terminate_connection(self, volume, connector, force=False, **kwargs):
-        """Disallow connection from connector."""
-        pass
-
-    def attach_volume(self, context, volume_id, instance_uuid, mountpoint):
-        """ Callback for volume attached to instance."""
-        pass
-
-    def detach_volume(self, context, volume_id):
-        """ Callback for volume detached."""
-        pass
-
-    def get_volume_stats(self, refresh=False):
-        """Return the current state of the volume service.
-
-        If 'refresh' is True, run the update first.
-        """
-        stats = {
-            'vendor_name': 'Scality',
-            'driver_version': '1.0',
-            'storage_protocol': 'scality',
-            'total_capacity_gb': 'infinite',
-            'free_capacity_gb': 'infinite',
-            'reserved_percentage': 0,
-        }
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        stats['volume_backend_name'] = backend_name or 'Scality_SOFS'
-        return stats
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        image_utils.fetch_to_raw(context,
-                                 image_service,
-                                 image_id,
-                                 self.local_path(volume))
-        self.create_volume(volume)
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        image_utils.upload_volume(context,
-                                  image_service,
-                                  image_meta,
-                                  self.local_path(volume))
-
-    def clone_image(self, volume, image_location):
-        """Create a volume efficiently from an existing image.
-
-        image_location is a string whose format depends on the
-        image service backend in use. The driver should use it
-        to determine whether cloning is possible.
-
-        Returns a boolean indicating whether cloning occurred
-        """
-        return False
diff --git a/manila/volume/drivers/sheepdog.py b/manila/volume/drivers/sheepdog.py
deleted file mode 100644
index efa34ccf41..0000000000
--- a/manila/volume/drivers/sheepdog.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-SheepDog Volume Driver.
-
-"""
-import re
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila.volume import driver
-
-
-LOG = logging.getLogger(__name__)
-FLAGS = flags.FLAGS
-
-
-class SheepdogDriver(driver.VolumeDriver):
-    """Executes commands relating to Sheepdog Volumes"""
-
-    def __init__(self, *args, **kwargs):
-        super(SheepdogDriver, self).__init__(*args, **kwargs)
-        self.stats_pattern = re.compile(r'[\w\s%]*Total\s(\d+)\s(\d+)*')
-        self._stats = {}
-
-    def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met"""
-        try:
-            #NOTE(francois-charlier) Since 0.24 'collie cluster info -r'
-            #  gives short output, but for compatibility reason we won't
-            #  use it and just check if 'running' is in the output.
-            (out, err) = self._execute('collie', 'cluster', 'info')
-            if 'running' not in out.split():
-                exception_message = (_("Sheepdog is not working: %s") % out)
-                raise exception.VolumeBackendAPIException(
-                    data=exception_message)
-
-        except exception.ProcessExecutionError:
-            exception_message = _("Sheepdog is not working")
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-    def create_cloned_volume(self, volume, src_vref):
-        raise NotImplementedError()
-
-    def create_volume(self, volume):
-        """Creates a sheepdog volume"""
-        self._try_execute('qemu-img', 'create',
-                          "sheepdog:%s" % volume['name'],
-                          '%sG' % volume['size'])
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Creates a sheepdog volume from a snapshot."""
-        self._try_execute('qemu-img', 'create', '-b',
-                          "sheepdog:%s:%s" % (snapshot['volume_name'],
-                                              snapshot['name']),
-                          "sheepdog:%s" % volume['name'])
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume"""
-        self._try_execute('collie', 'vdi', 'delete', volume['name'])
-
-    def create_snapshot(self, snapshot):
-        """Creates a sheepdog snapshot"""
-        self._try_execute('qemu-img', 'snapshot', '-c', snapshot['name'],
-                          "sheepdog:%s" % snapshot['volume_name'])
-
-    def delete_snapshot(self, snapshot):
-        """Deletes a sheepdog snapshot"""
-        self._try_execute('collie', 'vdi', 'delete', snapshot['volume_name'],
-                          '-s', snapshot['name'])
-
-    def local_path(self, volume):
-        return "sheepdog:%s" % volume['name']
-
-    def ensure_export(self, context, volume):
-        """Safely and synchronously recreates an export for a logical volume"""
-        pass
-
-    def create_export(self, context, volume):
-        """Exports the volume"""
-        pass
-
-    def remove_export(self, context, volume):
-        """Removes an export for a logical volume"""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        return {
-            'driver_volume_type': 'sheepdog',
-            'data': {
-                'name': volume['name']
-            }
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        pass
-
-    def _update_volume_stats(self):
-        stats = {}
-
-        backend_name = "sheepdog"
-        if self.configuration:
-            backend_name = self.configuration.safe_get('volume_backend_name')
-        stats["volume_backend_name"] = backend_name or 'sheepdog'
-        stats['vendor_name'] = 'Open Source'
-        stats['dirver_version'] = '1.0'
-        stats['storage_protocol'] = 'sheepdog'
-        stats['total_capacity_gb'] = 'unknown'
-        stats['free_capacity_gb'] = 'unknown'
-        stats['reserved_percentage'] = 0
-        stats['QoS_support'] = False
-
-        try:
-            stdout, _err = self._execute('collie', 'node', 'info', '-r')
-            m = self.stats_pattern.match(stdout)
-            total = float(m.group(1))
-            used = float(m.group(2))
-            stats['total_capacity_gb'] = total / (1024 ** 3)
-            stats['free_capacity_gb'] = (total - used) / (1024 ** 3)
-        except exception.ProcessExecutionError:
-            LOG.exception(_('error refreshing volume stats'))
-
-        self._stats = stats
-
-    def get_volume_stats(self, refresh=False):
-        if refresh:
-            self._update_volume_stats()
-        return self._stats
diff --git a/manila/volume/drivers/solidfire.py b/manila/volume/drivers/solidfire.py
deleted file mode 100644
index 4c8a9e95b7..0000000000
--- a/manila/volume/drivers/solidfire.py
+++ /dev/null
@@ -1,590 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 Justin Santa Barbara
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import base64
-import httplib
-import json
-import math
-import random
-import socket
-import string
-import time
-import uuid
-
-from oslo.config import cfg
-
-from manila import context
-from manila import exception
-from manila.openstack.common import log as logging
-from manila.volume.drivers.san.san import SanISCSIDriver
-from manila.volume import volume_types
-
-VERSION = '1.2'
-LOG = logging.getLogger(__name__)
-
-sf_opts = [
-    cfg.BoolOpt('sf_emulate_512',
-                default=True,
-                help='Set 512 byte emulation on volume creation; '),
-
-    cfg.BoolOpt('sf_allow_tenant_qos',
-                default=False,
-                help='Allow tenants to specify QOS on create'),
-
-    cfg.StrOpt('sf_account_prefix',
-               default=socket.gethostname(),
-               help='Create SolidFire accounts with this prefix'), ]
-
-
-class SolidFire(SanISCSIDriver):
-    """OpenStack driver to enable SolidFire cluster.
-
-    Version history:
-        1.0 - Initial driver
-        1.1 - Refactor, clone support, qos by type and minor bug fixes
-
-    """
-
-    sf_qos_dict = {'slow': {'minIOPS': 100,
-                            'maxIOPS': 200,
-                            'burstIOPS': 200},
-                   'medium': {'minIOPS': 200,
-                              'maxIOPS': 400,
-                              'burstIOPS': 400},
-                   'fast': {'minIOPS': 500,
-                            'maxIOPS': 1000,
-                            'burstIOPS': 1000},
-                   'performant': {'minIOPS': 2000,
-                                  'maxIOPS': 4000,
-                                  'burstIOPS': 4000},
-                   'off': None}
-
-    sf_qos_keys = ['minIOPS', 'maxIOPS', 'burstIOPS']
-    cluster_stats = {}
-
-    GB = math.pow(2, 30)
-
-    def __init__(self, *args, **kwargs):
-            super(SolidFire, self).__init__(*args, **kwargs)
-            self.configuration.append_config_values(sf_opts)
-            self._update_cluster_status()
-
-    def _issue_api_request(self, method_name, params):
-        """All API requests to SolidFire device go through this method.
-
-        Simple json-rpc web based API calls.
-        each call takes a set of paramaters (dict)
-        and returns results in a dict as well.
-
-        """
-        max_simultaneous_clones = ['xMaxSnapshotsPerVolumeExceeded',
-                                   'xMaxClonesPerVolumeExceeded',
-                                   'xMaxSnapshotsPerNodeExceeded',
-                                   'xMaxClonesPerNodeExceeded']
-        host = self.configuration.san_ip
-        # For now 443 is the only port our server accepts requests on
-        port = 443
-
-        cluster_admin = self.configuration.san_login
-        cluster_password = self.configuration.san_password
-
-        # NOTE(jdg): We're wrapping a retry loop for a know XDB issue
-        # Shows up in very high request rates (ie create 1000 volumes)
-        # we have to wrap the whole sequence because the request_id
-        # can't be re-used
-        retry_count = 5
-        while retry_count > 0:
-            request_id = int(uuid.uuid4())  # just generate a random number
-            command = {'method': method_name,
-                       'id': request_id}
-
-            if params is not None:
-                command['params'] = params
-
-            payload = json.dumps(command, ensure_ascii=False)
-            payload.encode('utf-8')
-            header = {'Content-Type': 'application/json-rpc; charset=utf-8'}
-
-            if cluster_password is not None:
-                # base64.encodestring includes a newline character
-                # in the result, make sure we strip it off
-                auth_key = base64.encodestring('%s:%s' % (cluster_admin,
-                                               cluster_password))[:-1]
-                header['Authorization'] = 'Basic %s' % auth_key
-
-            LOG.debug(_("Payload for SolidFire API call: %s"), payload)
-
-            connection = httplib.HTTPSConnection(host, port)
-            connection.request('POST', '/json-rpc/1.0', payload, header)
-            response = connection.getresponse()
-
-            data = {}
-            if response.status != 200:
-                connection.close()
-                raise exception.SolidFireAPIException(status=response.status)
-
-            else:
-                data = response.read()
-                try:
-                    data = json.loads(data)
-                except (TypeError, ValueError), exc:
-                    connection.close()
-                    msg = _("Call to json.loads() raised "
-                            "an exception: %s") % exc
-                    raise exception.SfJsonEncodeFailure(msg)
-
-                connection.close()
-
-            LOG.debug(_("Results of SolidFire API call: %s"), data)
-
-            if 'error' in data:
-                if data['error']['name'] in max_simultaneous_clones:
-                    LOG.warning(_('Clone operation '
-                                  'encountered: %s') % data['error']['name'])
-                    LOG.warning(_(
-                        'Waiting for outstanding operation '
-                        'before retrying snapshot: %s') % params['name'])
-                    time.sleep(5)
-                    # Don't decrement the retry count for this one
-                elif 'xDBVersionMismatch' in data['error']['name']:
-                    LOG.warning(_('Detected xDBVersionMismatch, '
-                                'retry %s of 5') % (5 - retry_count))
-                    time.sleep(1)
-                    retry_count -= 1
-                elif 'xUnknownAccount' in data['error']['name']:
-                    retry_count = 0
-                else:
-                    msg = _("API response: %s") % data
-                    raise exception.SolidFireAPIException(msg)
-            else:
-                retry_count = 0
-
-        return data
-
-    def _get_volumes_by_sfaccount(self, account_id):
-        """Get all volumes on cluster for specified account."""
-        params = {'accountID': account_id}
-        data = self._issue_api_request('ListVolumesForAccount', params)
-        if 'result' in data:
-            return data['result']['volumes']
-
-    def _get_sfaccount_by_name(self, sf_account_name):
-        """Get SolidFire account object by name."""
-        sfaccount = None
-        params = {'username': sf_account_name}
-        data = self._issue_api_request('GetAccountByName', params)
-        if 'result' in data and 'account' in data['result']:
-            LOG.debug(_('Found solidfire account: %s'), sf_account_name)
-            sfaccount = data['result']['account']
-        return sfaccount
-
-    def _get_sf_account_name(self, project_id):
-        """Build the SolidFire account name to use."""
-        return '%s%s%s' % (self.configuration.sf_account_prefix,
-                           '-' if self.configuration.sf_account_prefix else '',
-                           project_id)
-
-    def _get_sfaccount(self, project_id):
-        sf_account_name = self._get_sf_account_name(project_id)
-        sfaccount = self._get_sfaccount_by_name(sf_account_name)
-        if sfaccount is None:
-            raise exception.SfAccountNotFound(account_name=sf_account_name)
-
-        return sfaccount
-
-    def _create_sfaccount(self, project_id):
-        """Create account on SolidFire device if it doesn't already exist.
-
-        We're first going to check if the account already exits, if it does
-        just return it.  If not, then create it.
-
-        """
-
-        sf_account_name = self._get_sf_account_name(project_id)
-        sfaccount = self._get_sfaccount_by_name(sf_account_name)
-        if sfaccount is None:
-            LOG.debug(_('solidfire account: %s does not exist, create it...'),
-                      sf_account_name)
-            chap_secret = self._generate_random_string(12)
-            params = {'username': sf_account_name,
-                      'initiatorSecret': chap_secret,
-                      'targetSecret': chap_secret,
-                      'attributes': {}}
-            data = self._issue_api_request('AddAccount', params)
-            if 'result' in data:
-                sfaccount = self._get_sfaccount_by_name(sf_account_name)
-
-        return sfaccount
-
-    def _get_cluster_info(self):
-        """Query the SolidFire cluster for some property info."""
-        params = {}
-        data = self._issue_api_request('GetClusterInfo', params)
-        if 'result' not in data:
-            raise exception.SolidFireAPIDataException(data=data)
-
-        return data['result']
-
-    def _do_export(self, volume):
-        """Gets the associated account, retrieves CHAP info and updates."""
-        sfaccount = self._get_sfaccount(volume['project_id'])
-
-        model_update = {}
-        model_update['provider_auth'] = ('CHAP %s %s'
-                                         % (sfaccount['username'],
-                                            sfaccount['targetSecret']))
-
-        return model_update
-
-    def _generate_random_string(self, length):
-        """Generates random_string to use for CHAP password."""
-
-        char_set = string.ascii_uppercase + string.digits
-        return ''.join(random.sample(char_set, length))
-
-    def _get_model_info(self, sfaccount, sf_volume_id):
-        """Gets the connection info for specified account and volume."""
-        cluster_info = self._get_cluster_info()
-        iscsi_portal = cluster_info['clusterInfo']['svip'] + ':3260'
-        chap_secret = sfaccount['targetSecret']
-
-        found_volume = False
-        iteration_count = 0
-        while not found_volume and iteration_count < 10:
-            volume_list = self._get_volumes_by_sfaccount(
-                sfaccount['accountID'])
-            iqn = None
-            for v in volume_list:
-                if v['volumeID'] == sf_volume_id:
-                    iqn = v['iqn']
-                    found_volume = True
-                    break
-            if not found_volume:
-                time.sleep(2)
-            iteration_count += 1
-
-        if not found_volume:
-            LOG.error(_('Failed to retrieve volume SolidFire-'
-                        'ID: %s in get_by_account!') % sf_volume_id)
-            raise exception.VolumeNotFound(volume_id=uuid)
-
-        model_update = {}
-        # NOTE(john-griffith): SF volumes are always at lun 0
-        model_update['provider_location'] = ('%s %s %s'
-                                             % (iscsi_portal, iqn, 0))
-        model_update['provider_auth'] = ('CHAP %s %s'
-                                         % (sfaccount['username'],
-                                         chap_secret))
-        return model_update
-
-    def _do_clone_volume(self, src_uuid, src_project_id, v_ref):
-        """Create a clone of an existing volume.
-
-        Currently snapshots are the same as clones on the SF cluster.
-        Due to the way the SF cluster works there's no loss in efficiency
-        or space usage between the two.  The only thing different right
-        now is the restore snapshot functionality which has not been
-        implemented in the pre-release version of the SolidFire Cluster.
-
-        """
-        attributes = {}
-        qos = {}
-
-        sfaccount = self._get_sfaccount(src_project_id)
-        params = {'accountID': sfaccount['accountID']}
-
-        sf_vol = self._get_sf_volume(src_uuid, params)
-        if sf_vol is None:
-            raise exception.VolumeNotFound(volume_id=uuid)
-
-        if 'qos' in sf_vol:
-            qos = sf_vol['qos']
-
-        attributes = {'uuid': v_ref['id'],
-                      'is_clone': 'True',
-                      'src_uuid': src_uuid}
-
-        if qos:
-            for k, v in qos.items():
-                            attributes[k] = str(v)
-
-        params = {'volumeID': int(sf_vol['volumeID']),
-                  'name': 'UUID-%s' % v_ref['id'],
-                  'attributes': attributes,
-                  'qos': qos}
-
-        data = self._issue_api_request('CloneVolume', params)
-
-        if (('result' not in data) or ('volumeID' not in data['result'])):
-            raise exception.SolidFireAPIDataException(data=data)
-
-        sf_volume_id = data['result']['volumeID']
-        model_update = self._get_model_info(sfaccount, sf_volume_id)
-        if model_update is None:
-            mesg = _('Failed to get model update from clone')
-            raise exception.SolidFireAPIDataException(mesg)
-
-        return (data, sfaccount, model_update)
-
-    def _do_volume_create(self, project_id, params):
-        sfaccount = self._create_sfaccount(project_id)
-
-        params['accountID'] = sfaccount['accountID']
-        data = self._issue_api_request('CreateVolume', params)
-
-        if (('result' not in data) or ('volumeID' not in data['result'])):
-            raise exception.SolidFireAPIDataException(data=data)
-
-        sf_volume_id = data['result']['volumeID']
-        return self._get_model_info(sfaccount, sf_volume_id)
-
-    def _set_qos_presets(self, volume):
-        qos = {}
-        valid_presets = self.sf_qos_dict.keys()
-
-        #First look to see if they included a preset
-        presets = [i.value for i in volume.get('volume_metadata')
-                   if i.key == 'sf-qos' and i.value in valid_presets]
-        if len(presets) > 0:
-            if len(presets) > 1:
-                LOG.warning(_('More than one valid preset was '
-                              'detected, using %s') % presets[0])
-            qos = self.sf_qos_dict[presets[0]]
-        else:
-            #look for explicit settings
-            for i in volume.get('volume_metadata'):
-                if i.key in self.sf_qos_keys:
-                    qos[i.key] = int(i.value)
-        return qos
-
-    def _set_qos_by_volume_type(self, ctxt, type_id):
-        qos = {}
-        volume_type = volume_types.get_volume_type(ctxt, type_id)
-        specs = volume_type.get('extra_specs')
-        for key, value in specs.iteritems():
-            if ':' in key:
-                fields = key.split(':')
-                key = fields[1]
-            if key in self.sf_qos_keys:
-                qos[key] = int(value)
-        return qos
-
-    def _get_sf_volume(self, uuid, params):
-        data = self._issue_api_request('ListVolumesForAccount', params)
-        if 'result' not in data:
-            raise exception.SolidFireAPIDataException(data=data)
-
-        found_count = 0
-        sf_volref = None
-        for v in data['result']['volumes']:
-            if uuid in v['name']:
-                found_count += 1
-                sf_volref = v
-                LOG.debug(_("Mapped SolidFire volumeID %(sfid)s "
-                            "to manila ID %(uuid)s.") %
-                          {'sfid': v['volumeID'],
-                           'uuid': uuid})
-
-        if found_count == 0:
-            # NOTE(jdg): Previously we would raise here, but there are cases
-            # where this might be a cleanup for a failed delete.
-            # Until we get better states we'll just log an error
-            LOG.error(_("Volume %s, not found on SF Cluster."), uuid)
-
-        if found_count > 1:
-            LOG.error(_("Found %(count)s volumes mapped to id: %(uuid)s.") %
-                      {'count': found_count,
-                       'uuid': uuid})
-            raise exception.DuplicateSfVolumeNames(vol_name=uuid)
-
-        return sf_volref
-
-    def create_volume(self, volume):
-        """Create volume on SolidFire device.
-
-        The account is where CHAP settings are derived from, volume is
-        created and exported.  Note that the new volume is immediately ready
-        for use.
-
-        One caveat here is that an existing user account must be specified
-        in the API call to create a new volume.  We use a set algorithm to
-        determine account info based on passed in manila volume object.  First
-        we check to see if the account already exists (and use it), or if it
-        does not already exist, we'll go ahead and create it.
-
-        """
-        slice_count = 1
-        attributes = {}
-        qos = {}
-
-        if (self.configuration.sf_allow_tenant_qos and
-                volume.get('volume_metadata')is not None):
-            qos = self._set_qos_presets(volume)
-
-        ctxt = context.get_admin_context()
-        type_id = volume['volume_type_id']
-        if type_id is not None:
-            qos = self._set_qos_by_volume_type(ctxt, type_id)
-
-        attributes = {'uuid': volume['id'],
-                      'is_clone': 'False'}
-        if qos:
-            for k, v in qos.items():
-                            attributes[k] = str(v)
-
-        params = {'name': 'UUID-%s' % volume['id'],
-                  'accountID': None,
-                  'sliceCount': slice_count,
-                  'totalSize': int(volume['size'] * self.GB),
-                  'enable512e': self.configuration.sf_emulate_512,
-                  'attributes': attributes,
-                  'qos': qos}
-
-        return self._do_volume_create(volume['project_id'], params)
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Create a clone of an existing volume."""
-        (data, sfaccount, model) = self._do_clone_volume(
-            src_vref['id'],
-            src_vref['project_id'],
-            volume)
-
-        return model
-
-    def delete_volume(self, volume):
-        """Delete SolidFire Volume from device.
-
-        SolidFire allows multipe volumes with same name,
-        volumeID is what's guaranteed unique.
-
-        """
-
-        LOG.debug(_("Enter SolidFire delete_volume..."))
-
-        sfaccount = self._get_sfaccount(volume['project_id'])
-        if sfaccount is None:
-            LOG.error(_("Account for Volume ID %s was not found on "
-                        "the SolidFire Cluster!") % volume['id'])
-            LOG.error(_("This usually means the volume was never "
-                        "succesfully created."))
-            return
-
-        params = {'accountID': sfaccount['accountID']}
-
-        sf_vol = self._get_sf_volume(volume['id'], params)
-
-        if sf_vol is not None:
-            params = {'volumeID': sf_vol['volumeID']}
-            data = self._issue_api_request('DeleteVolume', params)
-
-            if 'result' not in data:
-                raise exception.SolidFireAPIDataException(data=data)
-        else:
-            LOG.error(_("Volume ID %s was not found on "
-                        "the SolidFire Cluster!"), volume['id'])
-
-        LOG.debug(_("Leaving SolidFire delete_volume"))
-
-    def ensure_export(self, context, volume):
-        """Verify the iscsi export info."""
-        LOG.debug(_("Executing SolidFire ensure_export..."))
-        return self._do_export(volume)
-
-    def create_export(self, context, volume):
-        """Setup the iscsi export info."""
-        LOG.debug(_("Executing SolidFire create_export..."))
-        return self._do_export(volume)
-
-    def delete_snapshot(self, snapshot):
-        """Delete the specified snapshot from the SolidFire cluster."""
-        self.delete_volume(snapshot)
-
-    def create_snapshot(self, snapshot):
-        """Create a snapshot of a volume on the SolidFire cluster.
-
-        Note that for SolidFire Clusters currently there is no snapshot
-        implementation.  Due to the way SF does cloning there's no performance
-        hit or extra space used.  The only thing that's lacking from this is
-        the abilit to restore snaps.
-
-        After GA a true snapshot implementation will be available with
-        restore at which time we'll rework this appropriately.
-
-        """
-        (data, sfaccount, model) = self._do_clone_volume(
-            snapshot['volume_id'],
-            snapshot['project_id'],
-            snapshot)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Create a volume from the specified snapshot."""
-        (data, sfaccount, model) = self._do_clone_volume(
-            snapshot['id'],
-            snapshot['project_id'],
-            volume)
-
-        return model
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update first.
-        The name is a bit misleading as
-        the majority of the data here is cluster
-        data
-        """
-        if refresh:
-            self._update_cluster_status()
-
-        return self.cluster_stats
-
-    def _update_cluster_status(self):
-        """Retrieve status info for the Cluster."""
-
-        LOG.debug(_("Updating cluster status info"))
-
-        params = {}
-
-        # NOTE(jdg): The SF api provides an UNBELIEVABLE amount
-        # of stats data, this is just one of the calls
-        results = self._issue_api_request('GetClusterCapacity', params)
-        if 'result' not in results:
-            LOG.error(_('Failed to get updated stats'))
-
-        results = results['result']['clusterCapacity']
-        free_capacity =\
-            results['maxProvisionedSpace'] - results['usedSpace']
-
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or self.__class__.__name__
-        data["vendor_name"] = 'SolidFire Inc'
-        data["driver_version"] = VERSION
-        data["storage_protocol"] = 'iSCSI'
-
-        data['total_capacity_gb'] = results['maxProvisionedSpace']
-
-        data['free_capacity_gb'] = float(free_capacity)
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = True
-        data['compression_percent'] =\
-            results['compressionPercent']
-        data['deduplicaton_percent'] =\
-            results['deDuplicationPercent']
-        data['thin_provision_percent'] =\
-            results['thinProvisioningPercent']
-        self.cluster_stats = data
diff --git a/manila/volume/drivers/storwize_svc.py b/manila/volume/drivers/storwize_svc.py
deleted file mode 100755
index e585e1ca2d..0000000000
--- a/manila/volume/drivers/storwize_svc.py
+++ /dev/null
@@ -1,1627 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 IBM Corp.
-# Copyright 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-#
-# Authors:
-#   Ronen Kat <ronenkat@il.ibm.com>
-#   Avishay Traeger <avishay@il.ibm.com>
-
-"""
-Volume driver for IBM Storwize family and SVC storage systems.
-
-Notes:
-1. If you specify both a password and a key file, this driver will use the
-   key file only.
-2. When using a key file for authentication, it is up to the user or
-   system administrator to store the private key in a safe manner.
-3. The defaults for creating volumes are "-rsize 2% -autoexpand
-   -grainsize 256 -warning 0".  These can be changed in the configuration
-   file or by using volume types(recommended only for advanced users).
-
-Limitations:
-1. The driver expects CLI output in English, error messages may be in a
-   localized format.
-2. Clones and creating volumes from snapshots, where the source and target
-   are of different sizes, is not supported.
-
-"""
-
-import random
-import re
-import string
-import time
-
-from oslo.config import cfg
-
-from manila import context
-from manila import exception
-from manila.openstack.common import excutils
-from manila.openstack.common import log as logging
-from manila.openstack.common import strutils
-from manila import utils
-from manila.volume.drivers.san import san
-from manila.volume import volume_types
-
-VERSION = 1.1
-LOG = logging.getLogger(__name__)
-
-storwize_svc_opts = [
-    cfg.StrOpt('storwize_svc_volpool_name',
-               default='volpool',
-               help='Storage system storage pool for volumes'),
-    cfg.IntOpt('storwize_svc_vol_rsize',
-               default=2,
-               help='Storage system space-efficiency parameter for volumes '
-                    '(percentage)'),
-    cfg.IntOpt('storwize_svc_vol_warning',
-               default=0,
-               help='Storage system threshold for volume capacity warnings '
-                    '(percentage)'),
-    cfg.BoolOpt('storwize_svc_vol_autoexpand',
-                default=True,
-                help='Storage system autoexpand parameter for volumes '
-                     '(True/False)'),
-    cfg.IntOpt('storwize_svc_vol_grainsize',
-               default=256,
-               help='Storage system grain size parameter for volumes '
-                    '(32/64/128/256)'),
-    cfg.BoolOpt('storwize_svc_vol_compression',
-                default=False,
-                help='Storage system compression option for volumes'),
-    cfg.BoolOpt('storwize_svc_vol_easytier',
-                default=True,
-                help='Enable Easy Tier for volumes'),
-    cfg.IntOpt('storwize_svc_flashcopy_timeout',
-               default=120,
-               help='Maximum number of seconds to wait for FlashCopy to be '
-                    'prepared. Maximum value is 600 seconds (10 minutes).'),
-    cfg.StrOpt('storwize_svc_connection_protocol',
-               default='iSCSI',
-               help='Connection protocol (iSCSI/FC)'),
-    cfg.BoolOpt('storwize_svc_multipath_enabled',
-                default=False,
-                help='Connect with multipath (currently FC-only)'),
-    cfg.BoolOpt('storwize_svc_multihostmap_enabled',
-                default=True,
-                help='Allows vdisk to multi host mapping'),
-]
-
-
-class StorwizeSVCDriver(san.SanISCSIDriver):
-    """IBM Storwize V7000 and SVC iSCSI/FC volume driver.
-
-    Version history:
-    1.0 - Initial driver
-    1.1 - FC support, create_cloned_volume, volume type support,
-          get_volume_stats, minor bug fixes
-
-    """
-
-    """====================================================================="""
-    """ SETUP                                                               """
-    """====================================================================="""
-
-    def __init__(self, *args, **kwargs):
-        super(StorwizeSVCDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(storwize_svc_opts)
-        self._storage_nodes = {}
-        self._enabled_protocols = set()
-        self._compression_enabled = False
-        self._context = None
-
-        # Build cleanup translation tables for host names
-        invalid_ch_in_host = ''
-        for num in range(0, 128):
-            ch = str(chr(num))
-            if (not ch.isalnum() and ch != ' ' and ch != '.'
-                and ch != '-' and ch != '_'):
-                invalid_ch_in_host = invalid_ch_in_host + ch
-        self._string_host_name_filter = string.maketrans(
-            invalid_ch_in_host, '-' * len(invalid_ch_in_host))
-
-        self._unicode_host_name_filter = dict((ord(unicode(char)), u'-')
-                                              for char in invalid_ch_in_host)
-
-    def _get_iscsi_ip_addrs(self):
-        generator = self._port_conf_generator('svcinfo lsportip')
-        header = next(generator, None)
-        if not header:
-            return
-
-        for port_data in generator:
-            try:
-                port_node_id = port_data['node_id']
-                port_ipv4 = port_data['IP_address']
-                port_ipv6 = port_data['IP_address_6']
-                state = port_data['state']
-            except KeyError:
-                self._handle_keyerror('lsportip', header)
-
-            if port_node_id in self._storage_nodes and (
-                    state == 'configured' or state == 'online'):
-                node = self._storage_nodes[port_node_id]
-                if len(port_ipv4):
-                    node['ipv4'].append(port_ipv4)
-                if len(port_ipv6):
-                    node['ipv6'].append(port_ipv6)
-
-    def _get_fc_wwpns(self):
-        for key in self._storage_nodes:
-            node = self._storage_nodes[key]
-            ssh_cmd = 'svcinfo lsnode -delim ! %s' % node['id']
-            raw = self._run_ssh(ssh_cmd)
-            resp = CLIResponse(raw, delim='!', with_header=False)
-            wwpns = set(node['WWPN'])
-            for i, s in resp.select('port_id', 'port_status'):
-                if 'unconfigured' != s:
-                    wwpns.add(i)
-            node['WWPN'] = list(wwpns)
-            LOG.info(_('WWPN on node %(node)s: %(wwpn)s')
-                     % {'node': node['id'], 'wwpn': node['WWPN']})
-
-    def do_setup(self, ctxt):
-        """Check that we have all configuration details from the storage."""
-
-        LOG.debug(_('enter: do_setup'))
-        self._context = ctxt
-
-        # Validate that the pool exists
-        ssh_cmd = 'svcinfo lsmdiskgrp -delim ! -nohdr'
-        out, err = self._run_ssh(ssh_cmd)
-        self._assert_ssh_return(len(out.strip()), 'do_setup',
-                                ssh_cmd, out, err)
-        search_text = '!%s!' % self.configuration.storwize_svc_volpool_name
-        if search_text not in out:
-            raise exception.InvalidInput(
-                reason=(_('pool %s doesn\'t exist')
-                        % self.configuration.storwize_svc_volpool_name))
-
-        # Check if compression is supported
-        self._compression_enabled = False
-        try:
-            ssh_cmd = 'svcinfo lslicense -delim !'
-            out, err = self._run_ssh(ssh_cmd)
-            license_lines = out.strip().split('\n')
-            for license_line in license_lines:
-                name, foo, value = license_line.partition('!')
-                if name in ('license_compression_enclosures',
-                            'license_compression_capacity') and value != '0':
-                    self._compression_enabled = True
-                    break
-        except exception.ProcessExecutionError:
-            LOG.exception(_('Failed to get license information.'))
-
-        # Get the iSCSI and FC names of the Storwize/SVC nodes
-        ssh_cmd = 'svcinfo lsnode -delim !'
-        out, err = self._run_ssh(ssh_cmd)
-        self._assert_ssh_return(len(out.strip()), 'do_setup',
-                                ssh_cmd, out, err)
-
-        nodes = out.strip().split('\n')
-        self._assert_ssh_return(len(nodes),
-                                'do_setup', ssh_cmd, out, err)
-        header = nodes.pop(0)
-        for node_line in nodes:
-            try:
-                node_data = self._get_hdr_dic(header, node_line, '!')
-            except exception.VolumeBackendAPIException:
-                with excutils.save_and_reraise_exception():
-                    self._log_cli_output_error('do_setup',
-                                               ssh_cmd, out, err)
-            node = {}
-            try:
-                node['id'] = node_data['id']
-                node['name'] = node_data['name']
-                node['IO_group'] = node_data['IO_group_id']
-                node['iscsi_name'] = node_data['iscsi_name']
-                node['WWNN'] = node_data['WWNN']
-                node['status'] = node_data['status']
-                node['WWPN'] = []
-                node['ipv4'] = []
-                node['ipv6'] = []
-                node['enabled_protocols'] = []
-                if node['status'] == 'online':
-                    self._storage_nodes[node['id']] = node
-            except KeyError:
-                self._handle_keyerror('lsnode', header)
-
-        # Get the iSCSI IP addresses and WWPNs of the Storwize/SVC nodes
-        self._get_iscsi_ip_addrs()
-        self._get_fc_wwpns()
-
-        # For each node, check what connection modes it supports.  Delete any
-        # nodes that do not support any types (may be partially configured).
-        to_delete = []
-        for k, node in self._storage_nodes.iteritems():
-            if ((len(node['ipv4']) or len(node['ipv6']))
-                    and len(node['iscsi_name'])):
-                node['enabled_protocols'].append('iSCSI')
-                self._enabled_protocols.add('iSCSI')
-            if len(node['WWPN']):
-                node['enabled_protocols'].append('FC')
-                self._enabled_protocols.add('FC')
-            if not len(node['enabled_protocols']):
-                to_delete.append(k)
-
-        for delkey in to_delete:
-            del self._storage_nodes[delkey]
-
-        # Make sure we have at least one node configured
-        self._driver_assert(len(self._storage_nodes),
-                            _('do_setup: No configured nodes'))
-
-        LOG.debug(_('leave: do_setup'))
-
-    def _build_default_opts(self):
-        # Ignore capitalization
-        protocol = self.configuration.storwize_svc_connection_protocol
-        if protocol.lower() == 'fc':
-            protocol = 'FC'
-        elif protocol.lower() == 'iscsi':
-            protocol = 'iSCSI'
-
-        opt = {'rsize': self.configuration.storwize_svc_vol_rsize,
-               'warning': self.configuration.storwize_svc_vol_warning,
-               'autoexpand': self.configuration.storwize_svc_vol_autoexpand,
-               'grainsize': self.configuration.storwize_svc_vol_grainsize,
-               'compression': self.configuration.storwize_svc_vol_compression,
-               'easytier': self.configuration.storwize_svc_vol_easytier,
-               'protocol': protocol,
-               'multipath': self.configuration.storwize_svc_multipath_enabled}
-        return opt
-
-    def check_for_setup_error(self):
-        """Ensure that the flags are set properly."""
-        LOG.debug(_('enter: check_for_setup_error'))
-
-        required_flags = ['san_ip', 'san_ssh_port', 'san_login',
-                          'storwize_svc_volpool_name']
-        for flag in required_flags:
-            if not self.configuration.safe_get(flag):
-                raise exception.InvalidInput(reason=_('%s is not set') % flag)
-
-        # Ensure that either password or keyfile were set
-        if not (self.configuration.san_password or
-                self.configuration.san_private_key):
-            raise exception.InvalidInput(
-                reason=_('Password or SSH private key is required for '
-                         'authentication: set either san_password or '
-                         'san_private_key option'))
-
-        # Check that flashcopy_timeout is not more than 10 minutes
-        flashcopy_timeout = self.configuration.storwize_svc_flashcopy_timeout
-        if not (flashcopy_timeout > 0 and flashcopy_timeout <= 600):
-            raise exception.InvalidInput(
-                reason=_('Illegal value %d specified for '
-                         'storwize_svc_flashcopy_timeout: '
-                         'valid values are between 0 and 600')
-                % flashcopy_timeout)
-
-        opts = self._build_default_opts()
-        self._check_vdisk_opts(opts)
-
-        LOG.debug(_('leave: check_for_setup_error'))
-
-    """====================================================================="""
-    """ INITIALIZE/TERMINATE CONNECTIONS                                    """
-    """====================================================================="""
-
-    def ensure_export(self, ctxt, volume):
-        """Check that the volume exists on the storage.
-
-        The system does not "export" volumes as a Linux iSCSI target does,
-        and therefore we just check that the volume exists on the storage.
-        """
-        volume_defined = self._is_vdisk_defined(volume['name'])
-        if not volume_defined:
-            LOG.error(_('ensure_export: Volume %s not found on storage')
-                      % volume['name'])
-
-    def create_export(self, ctxt, volume):
-        model_update = None
-        return model_update
-
-    def remove_export(self, ctxt, volume):
-        pass
-
-    def _add_chapsecret_to_host(self, host_name):
-        """Generate and store a randomly-generated CHAP secret for the host."""
-
-        chap_secret = utils.generate_password()
-        ssh_cmd = ('svctask chhost -chapsecret "%(chap_secret)s" %(host_name)s'
-                   % {'chap_secret': chap_secret, 'host_name': host_name})
-        out, err = self._run_ssh(ssh_cmd)
-        # No output should be returned from chhost
-        self._assert_ssh_return(len(out.strip()) == 0,
-                                '_add_chapsecret_to_host', ssh_cmd, out, err)
-        return chap_secret
-
-    def _get_chap_secret_for_host(self, host_name):
-        """Return the CHAP secret for the given host."""
-
-        LOG.debug(_('enter: _get_chap_secret_for_host: host name %s')
-                  % host_name)
-
-        ssh_cmd = 'svcinfo lsiscsiauth -delim !'
-        out, err = self._run_ssh(ssh_cmd)
-
-        if not len(out.strip()):
-            return None
-
-        host_lines = out.strip().split('\n')
-        self._assert_ssh_return(len(host_lines), '_get_chap_secret_for_host',
-                                ssh_cmd, out, err)
-
-        header = host_lines.pop(0).split('!')
-        self._assert_ssh_return('name' in header, '_get_chap_secret_for_host',
-                                ssh_cmd, out, err)
-        self._assert_ssh_return('iscsi_auth_method' in header,
-                                '_get_chap_secret_for_host', ssh_cmd, out, err)
-        self._assert_ssh_return('iscsi_chap_secret' in header,
-                                '_get_chap_secret_for_host', ssh_cmd, out, err)
-        name_index = header.index('name')
-        method_index = header.index('iscsi_auth_method')
-        secret_index = header.index('iscsi_chap_secret')
-
-        chap_secret = None
-        host_found = False
-        for line in host_lines:
-            info = line.split('!')
-            if info[name_index] == host_name:
-                host_found = True
-                if info[method_index] == 'chap':
-                    chap_secret = info[secret_index]
-
-        self._assert_ssh_return(host_found, '_get_chap_secret_for_host',
-                                ssh_cmd, out, err)
-
-        LOG.debug(_('leave: _get_chap_secret_for_host: host name '
-                    '%(host_name)s with secret %(chap_secret)s')
-                  % {'host_name': host_name, 'chap_secret': chap_secret})
-
-        return chap_secret
-
-    def _connector_to_hostname_prefix(self, connector):
-        """Translate connector info to storage system host name.
-
-        Translate a host's name and IP to the prefix of its hostname on the
-        storage subsystem.  We create a host name host name from the host and
-        IP address, replacing any invalid characters (at most 55 characters),
-        and adding a random 8-character suffix to avoid collisions. The total
-        length should be at most 63 characters.
-
-        """
-
-        host_name = connector['host']
-        if isinstance(host_name, unicode):
-            host_name = host_name.translate(self._unicode_host_name_filter)
-        elif isinstance(host_name, str):
-            host_name = host_name.translate(self._string_host_name_filter)
-        else:
-            msg = _('_create_host: Cannot clean host name. Host name '
-                    'is not unicode or string')
-            LOG.error(msg)
-            raise exception.NoValidHost(reason=msg)
-
-        host_name = str(host_name)
-        return host_name[:55]
-
-    def _find_host_from_wwpn(self, connector):
-        for wwpn in connector['wwpns']:
-            ssh_cmd = 'svcinfo lsfabric -wwpn %s -delim !' % wwpn
-            out, err = self._run_ssh(ssh_cmd)
-
-            if not len(out.strip()):
-                # This WWPN is not in use
-                continue
-
-            host_lines = out.strip().split('\n')
-            header = host_lines.pop(0).split('!')
-            self._assert_ssh_return('remote_wwpn' in header and
-                                    'name' in header,
-                                    '_find_host_from_wwpn',
-                                    ssh_cmd, out, err)
-            rmt_wwpn_idx = header.index('remote_wwpn')
-            name_idx = header.index('name')
-
-            wwpns = map(lambda x: x.split('!')[rmt_wwpn_idx], host_lines)
-
-            if wwpn in wwpns:
-                # All the wwpns will be the mapping for the same
-                # host from this WWPN-based query. Just pick
-                # the name from first line.
-                hostname = host_lines[0].split('!')[name_idx]
-                return hostname
-
-        # Didn't find a host
-        return None
-
-    def _find_host_exhaustive(self, connector, hosts):
-        for host in hosts:
-            ssh_cmd = 'svcinfo lshost -delim ! %s' % host
-            out, err = self._run_ssh(ssh_cmd)
-            self._assert_ssh_return(len(out.strip()),
-                                    '_find_host_exhaustive',
-                                    ssh_cmd, out, err)
-            for attr_line in out.split('\n'):
-                # If '!' not found, return the string and two empty strings
-                attr_name, foo, attr_val = attr_line.partition('!')
-                if (attr_name == 'iscsi_name' and
-                    'initiator' in connector and
-                    attr_val == connector['initiator']):
-                        return host
-                elif (attr_name == 'WWPN' and
-                      'wwpns' in connector and
-                      attr_val.lower() in
-                      map(str.lower, map(str, connector['wwpns']))):
-                        return host
-        return None
-
-    def _get_host_from_connector(self, connector):
-        """List the hosts defined in the storage.
-
-        Return the host name with the given connection info, or None if there
-        is no host fitting that information.
-
-        """
-
-        prefix = self._connector_to_hostname_prefix(connector)
-        LOG.debug(_('enter: _get_host_from_connector: prefix %s') % prefix)
-
-        # Get list of host in the storage
-        ssh_cmd = 'svcinfo lshost -delim !'
-        out, err = self._run_ssh(ssh_cmd)
-
-        if not len(out.strip()):
-            return None
-
-        # If we have FC information, we have a faster lookup option
-        hostname = None
-        if 'wwpns' in connector:
-            hostname = self._find_host_from_wwpn(connector)
-
-        # If we don't have a hostname yet, try the long way
-        if not hostname:
-            host_lines = out.strip().split('\n')
-            self._assert_ssh_return(len(host_lines),
-                                    '_get_host_from_connector',
-                                    ssh_cmd, out, err)
-            header = host_lines.pop(0).split('!')
-            self._assert_ssh_return('name' in header,
-                                    '_get_host_from_connector',
-                                    ssh_cmd, out, err)
-            name_index = header.index('name')
-            hosts = map(lambda x: x.split('!')[name_index], host_lines)
-            hostname = self._find_host_exhaustive(connector, hosts)
-
-        LOG.debug(_('leave: _get_host_from_connector: host %s') % hostname)
-
-        return hostname
-
-    def _create_host(self, connector):
-        """Create a new host on the storage system.
-
-        We create a host name and associate it with the given connection
-        information.
-
-        """
-
-        LOG.debug(_('enter: _create_host: host %s') % connector['host'])
-
-        rand_id = str(random.randint(0, 99999999)).zfill(8)
-        host_name = '%s-%s' % (self._connector_to_hostname_prefix(connector),
-                               rand_id)
-
-        # Get all port information from the connector
-        ports = []
-        if 'initiator' in connector:
-            ports.append('-iscsiname %s' % connector['initiator'])
-        if 'wwpns' in connector:
-            for wwpn in connector['wwpns']:
-                ports.append('-hbawwpn %s' % wwpn)
-
-        # When creating a host, we need one port
-        self._driver_assert(len(ports), _('_create_host: No connector ports'))
-        port1 = ports.pop(0)
-        ssh_cmd = ('svctask mkhost -force %(port1)s -name "%(host_name)s"' %
-                   {'port1': port1, 'host_name': host_name})
-        out, err = self._run_ssh(ssh_cmd)
-        self._assert_ssh_return('successfully created' in out,
-                                '_create_host', ssh_cmd, out, err)
-
-        # Add any additional ports to the host
-        for port in ports:
-            ssh_cmd = ('svctask addhostport -force %s %s' % (port, host_name))
-            out, err = self._run_ssh(ssh_cmd)
-
-        LOG.debug(_('leave: _create_host: host %(host)s - %(host_name)s') %
-                  {'host': connector['host'], 'host_name': host_name})
-        return host_name
-
-    def _get_hostvdisk_mappings(self, host_name):
-        """Return the defined storage mappings for a host."""
-
-        return_data = {}
-        ssh_cmd = 'svcinfo lshostvdiskmap -delim ! %s' % host_name
-        out, err = self._run_ssh(ssh_cmd)
-
-        mappings = out.strip().split('\n')
-        if len(mappings):
-            header = mappings.pop(0)
-            for mapping_line in mappings:
-                mapping_data = self._get_hdr_dic(header, mapping_line, '!')
-                return_data[mapping_data['vdisk_name']] = mapping_data
-
-        return return_data
-
-    def _map_vol_to_host(self, volume_name, host_name):
-        """Create a mapping between a volume to a host."""
-
-        LOG.debug(_('enter: _map_vol_to_host: volume %(volume_name)s to '
-                    'host %(host_name)s')
-                  % {'volume_name': volume_name, 'host_name': host_name})
-
-        # Check if this volume is already mapped to this host
-        mapping_data = self._get_hostvdisk_mappings(host_name)
-
-        mapped_flag = False
-        result_lun = '-1'
-        if volume_name in mapping_data:
-            mapped_flag = True
-            result_lun = mapping_data[volume_name]['SCSI_id']
-        else:
-            lun_used = []
-            for k, v in mapping_data.iteritems():
-                lun_used.append(int(v['SCSI_id']))
-            lun_used.sort()
-            # Assume all luns are taken to this point, and then try to find
-            # an unused one
-            result_lun = str(len(lun_used))
-            for index, n in enumerate(lun_used):
-                if n > index:
-                    result_lun = str(index)
-                    break
-
-        # Volume is not mapped to host, create a new LUN
-        if not mapped_flag:
-            ssh_cmd = ('svctask mkvdiskhostmap -host %(host_name)s -scsi '
-                       '%(result_lun)s %(volume_name)s' %
-                       {'host_name': host_name,
-                        'result_lun': result_lun,
-                        'volume_name': volume_name})
-            out, err = self._run_ssh(ssh_cmd, check_exit_code=False)
-            if err and err.startswith('CMMVC6071E'):
-                if not self.configuration.storwize_svc_multihostmap_enabled:
-                    LOG.error(_('storwize_svc_multihostmap_enabled is set '
-                                'to Flase, Not allow multi host mapping'))
-                    exception_msg = 'CMMVC6071E The VDisk-to-host mapping '\
-                                    'was not created because the VDisk is '\
-                                    'already mapped to a host.\n"'
-                    raise exception.CinderException(data=exception_msg)
-                ssh_cmd = ssh_cmd.replace('mkvdiskhostmap',
-                                          'mkvdiskhostmap -force')
-                # try to map one volume to multiple hosts
-                out, err = self._run_ssh(ssh_cmd)
-                LOG.warn(_('volume %s mapping to multi host') % volume_name)
-                self._assert_ssh_return('successfully created' in out,
-                                        '_map_vol_to_host', ssh_cmd, out, err)
-            else:
-                self._assert_ssh_return('successfully created' in out,
-                                        '_map_vol_to_host', ssh_cmd, out, err)
-        LOG.debug(_('leave: _map_vol_to_host: LUN %(result_lun)s, volume '
-                    '%(volume_name)s, host %(host_name)s') %
-                  {'result_lun': result_lun,
-                   'volume_name': volume_name,
-                   'host_name': host_name})
-        return result_lun
-
-    def _delete_host(self, host_name):
-        """Delete a host on the storage system."""
-
-        LOG.debug(_('enter: _delete_host: host %s ') % host_name)
-
-        ssh_cmd = 'svctask rmhost %s ' % host_name
-        out, err = self._run_ssh(ssh_cmd)
-        # No output should be returned from rmhost
-        self._assert_ssh_return(len(out.strip()) == 0,
-                                '_delete_host', ssh_cmd, out, err)
-
-        LOG.debug(_('leave: _delete_host: host %s ') % host_name)
-
-    def _get_conn_fc_wwpns(self, host_name):
-        wwpns = []
-        cmd = 'svcinfo lsfabric -host %s' % host_name
-        generator = self._port_conf_generator(cmd)
-        header = next(generator, None)
-        if not header:
-            return wwpns
-
-        for port_data in generator:
-            try:
-                wwpns.append(port_data['local_wwpn'])
-            except KeyError as e:
-                self._handle_keyerror('lsfabric', header)
-
-        return wwpns
-
-    def initialize_connection(self, volume, connector):
-        """Perform the necessary work so that an iSCSI/FC connection can
-        be made.
-
-        To be able to create an iSCSI/FC connection from a given host to a
-        volume, we must:
-        1. Translate the given iSCSI name or WWNN to a host name
-        2. Create new host on the storage system if it does not yet exist
-        3. Map the volume to the host if it is not already done
-        4. Return the connection information for relevant nodes (in the
-           proper I/O group)
-
-        """
-
-        LOG.debug(_('enter: initialize_connection: volume %(vol)s with '
-                    'connector %(conn)s') % {'vol': str(volume),
-                                             'conn': str(connector)})
-
-        vol_opts = self._get_vdisk_params(volume['volume_type_id'])
-        host_name = connector['host']
-        volume_name = volume['name']
-
-        # Check if a host object is defined for this host name
-        host_name = self._get_host_from_connector(connector)
-        if host_name is None:
-            # Host does not exist - add a new host to Storwize/SVC
-            host_name = self._create_host(connector)
-            # Verify that create_new_host succeeded
-            self._driver_assert(
-                host_name is not None,
-                _('_create_host failed to return the host name.'))
-
-        if vol_opts['protocol'] == 'iSCSI':
-            chap_secret = self._get_chap_secret_for_host(host_name)
-            if chap_secret is None:
-                chap_secret = self._add_chapsecret_to_host(host_name)
-
-        volume_attributes = self._get_vdisk_attributes(volume_name)
-        lun_id = self._map_vol_to_host(volume_name, host_name)
-
-        self._driver_assert(volume_attributes is not None,
-                            _('initialize_connection: Failed to get attributes'
-                              ' for volume %s') % volume_name)
-
-        try:
-            preferred_node = volume_attributes['preferred_node_id']
-            IO_group = volume_attributes['IO_group_id']
-        except KeyError as e:
-                LOG.error(_('Did not find expected column name in '
-                            'lsvdisk: %s') % str(e))
-                exception_msg = (_('initialize_connection: Missing volume '
-                                   'attribute for volume %s') % volume_name)
-                raise exception.VolumeBackendAPIException(data=exception_msg)
-
-        try:
-            # Get preferred node and other nodes in I/O group
-            preferred_node_entry = None
-            io_group_nodes = []
-            for k, node in self._storage_nodes.iteritems():
-                if vol_opts['protocol'] not in node['enabled_protocols']:
-                    continue
-                if node['id'] == preferred_node:
-                    preferred_node_entry = node
-                if node['IO_group'] == IO_group:
-                    io_group_nodes.append(node)
-
-            if not len(io_group_nodes):
-                exception_msg = (_('initialize_connection: No node found in '
-                                   'I/O group %(gid)s for volume %(vol)s') %
-                                 {'gid': IO_group, 'vol': volume_name})
-                raise exception.VolumeBackendAPIException(data=exception_msg)
-
-            if not preferred_node_entry and not vol_opts['multipath']:
-                # Get 1st node in I/O group
-                preferred_node_entry = io_group_nodes[0]
-                LOG.warn(_('initialize_connection: Did not find a preferred '
-                           'node for volume %s') % volume_name)
-
-            properties = {}
-            properties['target_discovered'] = False
-            properties['target_lun'] = lun_id
-            properties['volume_id'] = volume['id']
-            if vol_opts['protocol'] == 'iSCSI':
-                type_str = 'iscsi'
-                # We take the first IP address for now. Ideally, OpenStack will
-                # support iSCSI multipath for improved performance.
-                if len(preferred_node_entry['ipv4']):
-                    ipaddr = preferred_node_entry['ipv4'][0]
-                else:
-                    ipaddr = preferred_node_entry['ipv6'][0]
-                properties['target_portal'] = '%s:%s' % (ipaddr, '3260')
-                properties['target_iqn'] = preferred_node_entry['iscsi_name']
-                properties['auth_method'] = 'CHAP'
-                properties['auth_username'] = connector['initiator']
-                properties['auth_password'] = chap_secret
-            else:
-                type_str = 'fibre_channel'
-                conn_wwpns = self._get_conn_fc_wwpns(host_name)
-                if not vol_opts['multipath']:
-                    if preferred_node_entry['WWPN'] in conn_wwpns:
-                        properties['target_wwn'] = preferred_node_entry['WWPN']
-                    else:
-                        properties['target_wwn'] = conn_wwpns[0]
-                else:
-                    properties['target_wwn'] = conn_wwpns
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self.terminate_connection(volume, connector)
-                LOG.error(_('initialize_connection: Failed to collect return '
-                            'properties for volume %(vol)s and connector '
-                            '%(conn)s.\n') % {'vol': str(volume),
-                                              'conn': str(connector)})
-
-        LOG.debug(_('leave: initialize_connection:\n volume: %(vol)s\n '
-                    'connector %(conn)s\n properties: %(prop)s')
-                  % {'vol': str(volume),
-                     'conn': str(connector),
-                     'prop': str(properties)})
-
-        return {'driver_volume_type': type_str, 'data': properties, }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Cleanup after an iSCSI connection has been terminated.
-
-        When we clean up a terminated connection between a given connector
-        and volume, we:
-        1. Translate the given connector to a host name
-        2. Remove the volume-to-host mapping if it exists
-        3. Delete the host if it has no more mappings (hosts are created
-           automatically by this driver when mappings are created)
-        """
-        LOG.debug(_('enter: terminate_connection: volume %(vol)s with '
-                    'connector %(conn)s') % {'vol': str(volume),
-                                             'conn': str(connector)})
-
-        vol_name = volume['name']
-        host_name = self._get_host_from_connector(connector)
-        # Verify that _get_host_from_connector returned the host.
-        # This should always succeed as we terminate an existing connection.
-        self._driver_assert(
-            host_name is not None,
-            _('_get_host_from_connector failed to return the host name '
-              'for connector'))
-
-        # Check if vdisk-host mapping exists, remove if it does
-        mapping_data = self._get_hostvdisk_mappings(host_name)
-        if vol_name in mapping_data:
-            ssh_cmd = 'svctask rmvdiskhostmap -host %s %s' % \
-                (host_name, vol_name)
-            out, err = self._run_ssh(ssh_cmd)
-            # Verify CLI behaviour - no output is returned from
-            # rmvdiskhostmap
-            self._assert_ssh_return(len(out.strip()) == 0,
-                                    'terminate_connection', ssh_cmd, out, err)
-            del mapping_data[vol_name]
-        else:
-            LOG.error(_('terminate_connection: No mapping of volume '
-                        '%(vol_name)s to host %(host_name)s found') %
-                      {'vol_name': vol_name, 'host_name': host_name})
-
-        # If this host has no more mappings, delete it
-        if not mapping_data:
-            self._delete_host(host_name)
-
-        LOG.debug(_('leave: terminate_connection: volume %(vol)s with '
-                    'connector %(conn)s') % {'vol': str(volume),
-                                             'conn': str(connector)})
-
-    """====================================================================="""
-    """ VOLUMES/SNAPSHOTS                                                   """
-    """====================================================================="""
-
-    def _get_vdisk_attributes(self, vdisk_name):
-        """Return vdisk attributes, or None if vdisk does not exist
-
-        Exception is raised if the information from system can not be
-        parsed/matched to a single vdisk.
-        """
-
-        ssh_cmd = 'svcinfo lsvdisk -bytes -delim ! %s ' % vdisk_name
-        return self._execute_command_and_parse_attributes(ssh_cmd)
-
-    def _get_vdisk_fc_mappings(self, vdisk_name):
-        """Return FlashCopy mappings that this vdisk is associated with."""
-
-        ssh_cmd = 'svcinfo lsvdiskfcmappings -nohdr %s' % vdisk_name
-        out, err = self._run_ssh(ssh_cmd)
-
-        mapping_ids = []
-        if (len(out.strip())):
-            lines = out.strip().split('\n')
-            for line in lines:
-                mapping_ids.append(line.split()[0])
-        return mapping_ids
-
-    def _get_vdisk_params(self, type_id):
-        opts = self._build_default_opts()
-        if type_id:
-            ctxt = context.get_admin_context()
-            volume_type = volume_types.get_volume_type(ctxt, type_id)
-            specs = volume_type.get('extra_specs')
-            for k, value in specs.iteritems():
-                # Get the scope, if using scope format
-                key_split = k.split(':')
-                if len(key_split) == 1:
-                    scope = None
-                    key = key_split[0]
-                else:
-                    scope = key_split[0]
-                    key = key_split[1]
-
-                # We generally do not look at capabilities in the driver, but
-                # protocol is a special case where the user asks for a given
-                # protocol and we want both the scheduler and the driver to act
-                # on the value.
-                if scope == 'capabilities' and key == 'storage_protocol':
-                    scope = None
-                    key = 'protocol'
-                    words = value.split()
-                    self._driver_assert(words and
-                                        len(words) == 2 and
-                                        words[0] == '<in>',
-                                        _('protocol must be specified as '
-                                          '\'<in> iSCSI\' or \'<in> FC\''))
-                    del words[0]
-                    value = words[0]
-
-                # Anything keys that the driver should look at should have the
-                # 'drivers' scope.
-                if scope and scope != "drivers":
-                    continue
-
-                if key in opts:
-                    this_type = type(opts[key]).__name__
-                    if this_type == 'int':
-                        value = int(value)
-                    elif this_type == 'bool':
-                        value = strutils.bool_from_string(value)
-                    opts[key] = value
-
-        self._check_vdisk_opts(opts)
-        return opts
-
-    def _create_vdisk(self, name, size, units, opts):
-        """Create a new vdisk."""
-
-        LOG.debug(_('enter: _create_vdisk: vdisk %s ') % name)
-
-        model_update = None
-        autoex = '-autoexpand' if opts['autoexpand'] else ''
-        easytier = '-easytier on' if opts['easytier'] else '-easytier off'
-
-        # Set space-efficient options
-        if opts['rsize'] == -1:
-            ssh_cmd_se_opt = ''
-        else:
-            ssh_cmd_se_opt = (
-                '-rsize %(rsize)d%% %(autoex)s -warning %(warn)d%%' %
-                {'rsize': opts['rsize'],
-                 'autoex': autoex,
-                 'warn': opts['warning']})
-            if opts['compression']:
-                ssh_cmd_se_opt = ssh_cmd_se_opt + ' -compressed'
-            else:
-                ssh_cmd_se_opt = ssh_cmd_se_opt + (
-                    ' -grainsize %d' % opts['grainsize'])
-
-        ssh_cmd = ('svctask mkvdisk -name %(name)s -mdiskgrp %(mdiskgrp)s '
-                   '-iogrp 0 -size %(size)s -unit '
-                   '%(unit)s %(easytier)s %(ssh_cmd_se_opt)s'
-                   % {'name': name,
-                   'mdiskgrp': self.configuration.storwize_svc_volpool_name,
-                   'size': size, 'unit': units, 'easytier': easytier,
-                   'ssh_cmd_se_opt': ssh_cmd_se_opt})
-        out, err = self._run_ssh(ssh_cmd)
-        self._assert_ssh_return(len(out.strip()), '_create_vdisk',
-                                ssh_cmd, out, err)
-
-        # Ensure that the output is as expected
-        match_obj = re.search('Virtual Disk, id \[([0-9]+)\], '
-                              'successfully created', out)
-        # Make sure we got a "successfully created" message with vdisk id
-        self._driver_assert(
-            match_obj is not None,
-            _('_create_vdisk %(name)s - did not find '
-              'success message in CLI output.\n '
-              'stdout: %(out)s\n stderr: %(err)s')
-            % {'name': name, 'out': str(out), 'err': str(err)})
-
-        LOG.debug(_('leave: _create_vdisk: volume %s ') % name)
-
-    def _make_fc_map(self, source, target, full_copy):
-        copyflag = '' if full_copy else '-copyrate 0'
-        fc_map_cli_cmd = ('svctask mkfcmap -source %(src)s -target %(tgt)s '
-                          '-autodelete %(copyflag)s' %
-                          {'src': source,
-                           'tgt': target,
-                           'copyflag': copyflag})
-        out, err = self._run_ssh(fc_map_cli_cmd)
-        self._driver_assert(
-            len(out.strip()),
-            _('create FC mapping from %(source)s to %(target)s - '
-              'did not find success message in CLI output.\n'
-              ' stdout: %(out)s\n stderr: %(err)s\n')
-            % {'source': source,
-               'target': target,
-               'out': str(out),
-               'err': str(err)})
-
-        # Ensure that the output is as expected
-        match_obj = re.search('FlashCopy Mapping, id \[([0-9]+)\], '
-                              'successfully created', out)
-        # Make sure we got a "successfully created" message with vdisk id
-        self._driver_assert(
-            match_obj is not None,
-            _('create FC mapping from %(source)s to %(target)s - '
-              'did not find success message in CLI output.\n'
-              ' stdout: %(out)s\n stderr: %(err)s\n')
-            % {'source': source,
-               'target': target,
-               'out': str(out),
-               'err': str(err)})
-
-        try:
-            fc_map_id = match_obj.group(1)
-            self._driver_assert(
-                fc_map_id is not None,
-                _('create FC mapping from %(source)s to %(target)s - '
-                  'did not find mapping id in CLI output.\n'
-                  ' stdout: %(out)s\n stderr: %(err)s\n')
-                % {'source': source,
-                   'target': target,
-                   'out': str(out),
-                   'err': str(err)})
-        except IndexError:
-            self._driver_assert(
-                False,
-                _('create FC mapping from %(source)s to %(target)s - '
-                  'did not find mapping id in CLI output.\n'
-                  ' stdout: %(out)s\n stderr: %(err)s\n')
-                % {'source': source,
-                   'target': target,
-                   'out': str(out),
-                   'err': str(err)})
-        return fc_map_id
-
-    def _call_prepare_fc_map(self, fc_map_id, source, target):
-        try:
-            out, err = self._run_ssh('svctask prestartfcmap %s' % fc_map_id)
-        except exception.ProcessExecutionError as e:
-            with excutils.save_and_reraise_exception():
-                LOG.error(_('_prepare_fc_map: Failed to prepare FlashCopy '
-                            'from %(source)s to %(target)s.\n'
-                            'stdout: %(out)s\n stderr: %(err)s')
-                          % {'source': source,
-                             'target': target,
-                             'out': e.stdout,
-                             'err': e.stderr})
-
-    def _prepare_fc_map(self, fc_map_id, source, target):
-        self._call_prepare_fc_map(fc_map_id, source, target)
-        mapping_ready = False
-        wait_time = 5
-        # Allow waiting of up to timeout (set as parameter)
-        timeout = self.configuration.storwize_svc_flashcopy_timeout
-        max_retries = (timeout / wait_time) + 1
-        for try_number in range(1, max_retries):
-            mapping_attrs = self._get_flashcopy_mapping_attributes(fc_map_id)
-            if (mapping_attrs is None or
-                    'status' not in mapping_attrs):
-                break
-            if mapping_attrs['status'] == 'prepared':
-                mapping_ready = True
-                break
-            elif mapping_attrs['status'] == 'stopped':
-                self._call_prepare_fc_map(fc_map_id, source, target)
-            elif mapping_attrs['status'] != 'preparing':
-                # Unexpected mapping status
-                exception_msg = (_('Unexecpted mapping status %(status)s '
-                                   'for mapping %(id)s. Attributes: '
-                                   '%(attr)s')
-                                 % {'status': mapping_attrs['status'],
-                                    'id': fc_map_id,
-                                    'attr': mapping_attrs})
-                raise exception.VolumeBackendAPIException(data=exception_msg)
-            # Need to wait for mapping to be prepared, wait a few seconds
-            time.sleep(wait_time)
-
-        if not mapping_ready:
-            exception_msg = (_('Mapping %(id)s prepare failed to complete '
-                               'within the allotted %(to)d seconds timeout. '
-                               'Terminating.')
-                             % {'id': fc_map_id,
-                                'to': timeout})
-            LOG.error(_('_prepare_fc_map: Failed to start FlashCopy '
-                        'from %(source)s to %(target)s with '
-                        'exception %(ex)s')
-                      % {'source': source,
-                         'target': target,
-                         'ex': exception_msg})
-            raise exception.InvalidSnapshot(
-                reason=_('_prepare_fc_map: %s') % exception_msg)
-
-    def _start_fc_map(self, fc_map_id, source, target):
-        try:
-            out, err = self._run_ssh('svctask startfcmap %s' % fc_map_id)
-        except exception.ProcessExecutionError as e:
-            with excutils.save_and_reraise_exception():
-                LOG.error(_('_start_fc_map: Failed to start FlashCopy '
-                            'from %(source)s to %(target)s.\n'
-                            'stdout: %(out)s\n stderr: %(err)s')
-                          % {'source': source,
-                             'target': target,
-                             'out': e.stdout,
-                             'err': e.stderr})
-
-    def _run_flashcopy(self, source, target, full_copy=True):
-        """Create a FlashCopy mapping from the source to the target."""
-
-        LOG.debug(_('enter: _run_flashcopy: execute FlashCopy from source '
-                    '%(source)s to target %(target)s') %
-                  {'source': source, 'target': target})
-
-        fc_map_id = self._make_fc_map(source, target, full_copy)
-        try:
-            self._prepare_fc_map(fc_map_id, source, target)
-            self._start_fc_map(fc_map_id, source, target)
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self._delete_vdisk(target, True)
-
-        LOG.debug(_('leave: _run_flashcopy: FlashCopy started from '
-                    '%(source)s to %(target)s') %
-                  {'source': source, 'target': target})
-
-    def _create_copy(self, src_vdisk, tgt_vdisk, full_copy, opts, src_id,
-                     from_vol):
-        """Create a new snapshot using FlashCopy."""
-
-        LOG.debug(_('enter: _create_copy: snapshot %(tgt_vdisk)s from '
-                    'vdisk %(src_vdisk)s') %
-                  {'tgt_vdisk': tgt_vdisk, 'src_vdisk': src_vdisk})
-
-        src_vdisk_attributes = self._get_vdisk_attributes(src_vdisk)
-        if src_vdisk_attributes is None:
-            exception_msg = (
-                _('_create_copy: Source vdisk %s does not exist')
-                % src_vdisk)
-            LOG.error(exception_msg)
-            if from_vol:
-                raise exception.VolumeNotFound(exception_msg,
-                                               volume_id=src_id)
-            else:
-                raise exception.SnapshotNotFound(exception_msg,
-                                                 snapshot_id=src_id)
-
-        self._driver_assert(
-            'capacity' in src_vdisk_attributes,
-            _('_create_copy: cannot get source vdisk '
-              '%(src)s capacity from vdisk attributes '
-              '%(attr)s')
-            % {'src': src_vdisk,
-               'attr': src_vdisk_attributes})
-
-        src_vdisk_size = src_vdisk_attributes['capacity']
-        self._create_vdisk(tgt_vdisk, src_vdisk_size, 'b', opts)
-        self._run_flashcopy(src_vdisk, tgt_vdisk, full_copy)
-
-        LOG.debug(_('leave: _create_copy: snapshot %(tgt_vdisk)s from '
-                    'vdisk %(src_vdisk)s') %
-                  {'tgt_vdisk': tgt_vdisk, 'src_vdisk': src_vdisk})
-
-    def _get_flashcopy_mapping_attributes(self, fc_map_id):
-        LOG.debug(_('enter: _get_flashcopy_mapping_attributes: mapping %s')
-                  % fc_map_id)
-
-        fc_ls_map_cmd = 'svcinfo lsfcmap -filtervalue id=%s -delim !' % \
-            fc_map_id
-        out, err = self._run_ssh(fc_ls_map_cmd)
-        if not len(out.strip()):
-            return None
-
-        # Get list of FlashCopy mappings
-        # We expect zero or one line if mapping does not exist,
-        # two lines if it does exist, otherwise error
-        lines = out.strip().split('\n')
-        self._assert_ssh_return(len(lines) <= 2,
-                                '_get_flashcopy_mapping_attributes',
-                                fc_ls_map_cmd, out, err)
-
-        if len(lines) == 2:
-            attributes = self._get_hdr_dic(lines[0], lines[1], '!')
-        else:  # 0 or 1 lines
-            attributes = None
-
-        LOG.debug(_('leave: _get_flashcopy_mapping_attributes: mapping '
-                    '%(fc_map_id)s, attributes %(attributes)s') %
-                  {'fc_map_id': fc_map_id, 'attributes': attributes})
-
-        return attributes
-
-    def _is_vdisk_defined(self, vdisk_name):
-        """Check if vdisk is defined."""
-        LOG.debug(_('enter: _is_vdisk_defined: vdisk %s ') % vdisk_name)
-        vdisk_attributes = self._get_vdisk_attributes(vdisk_name)
-        LOG.debug(_('leave: _is_vdisk_defined: vdisk %(vol)s with %(str)s ')
-                  % {'vol': vdisk_name,
-                     'str': vdisk_attributes is not None})
-        if vdisk_attributes is None:
-            return False
-        else:
-            return True
-
-    def _delete_vdisk(self, name, force):
-        """Deletes existing vdisks.
-
-        It is very important to properly take care of mappings before deleting
-        the disk:
-        1. If no mappings, then it was a vdisk, and can be deleted
-        2. If it is the source of a flashcopy mapping and copy_rate is 0, then
-           it is a vdisk that has a snapshot.  If the force flag is set,
-           delete the mapping and the vdisk, otherwise set the mapping to
-           copy and wait (this will allow users to delete vdisks that have
-           snapshots if/when the upper layers allow it).
-        3. If it is the target of a mapping and copy_rate is 0, it is a
-           snapshot, and we should properly stop the mapping and delete.
-        4. If it is the source/target of a mapping and copy_rate is not 0, it
-           is a clone or vdisk created from a snapshot.  We wait for the copy
-           to complete (the mapping will be autodeleted) and then delete the
-           vdisk.
-
-        """
-
-        LOG.debug(_('enter: _delete_vdisk: vdisk %s') % name)
-
-        # Try to delete volume only if found on the storage
-        vdisk_defined = self._is_vdisk_defined(name)
-        if not vdisk_defined:
-            LOG.info(_('warning: Tried to delete vdisk %s but it does not '
-                       'exist.') % name)
-            return
-
-        # Ensure vdisk has no FlashCopy mappings
-        mapping_ids = self._get_vdisk_fc_mappings(name)
-        while len(mapping_ids):
-            wait_for_copy = False
-            for map_id in mapping_ids:
-                attrs = self._get_flashcopy_mapping_attributes(map_id)
-                if not attrs:
-                    continue
-                source = attrs['source_vdisk_name']
-                target = attrs['target_vdisk_name']
-                copy_rate = attrs['copy_rate']
-                status = attrs['status']
-
-                if copy_rate == '0':
-                    # Case #2: A vdisk that has snapshots
-                    if source == name:
-                            ssh_cmd = ('svctask chfcmap -copyrate 50 '
-                                       '-autodelete on %s' % map_id)
-                            out, err = self._run_ssh(ssh_cmd)
-                            wait_for_copy = True
-                    # Case #3: A snapshot
-                    else:
-                        msg = (_('Vdisk %(name)s not involved in '
-                                 'mapping %(src)s -> %(tgt)s') %
-                               {'name': name, 'src': source, 'tgt': target})
-                        self._driver_assert(target == name, msg)
-                        if status in ['copying', 'prepared']:
-                            self._run_ssh('svctask stopfcmap %s' % map_id)
-                        elif status == 'stopping':
-                            wait_for_copy = True
-                        else:
-                            self._run_ssh('svctask rmfcmap -force %s' % map_id)
-                # Case 4: Copy in progress - wait and will autodelete
-                else:
-                    if status == 'prepared':
-                        self._run_ssh('svctask stopfcmap %s' % map_id)
-                        self._run_ssh('svctask rmfcmap -force %s' % map_id)
-                    elif status == 'idle_or_copied':
-                        # Prepare failed
-                        self._run_ssh('svctask rmfcmap -force %s' % map_id)
-                    else:
-                        wait_for_copy = True
-            if wait_for_copy:
-                time.sleep(5)
-            mapping_ids = self._get_vdisk_fc_mappings(name)
-
-        forceflag = '-force' if force else ''
-        cmd_params = {'frc': forceflag, 'name': name}
-        ssh_cmd = 'svctask rmvdisk %(frc)s %(name)s' % cmd_params
-        out, err = self._run_ssh(ssh_cmd)
-        # No output should be returned from rmvdisk
-        self._assert_ssh_return(len(out.strip()) == 0,
-                                ('_delete_vdisk %(name)s')
-                                % {'name': name},
-                                ssh_cmd, out, err)
-        LOG.debug(_('leave: _delete_vdisk: vdisk %s') % name)
-
-    def create_volume(self, volume):
-        opts = self._get_vdisk_params(volume['volume_type_id'])
-        return self._create_vdisk(volume['name'], str(volume['size']), 'gb',
-                                  opts)
-
-    def delete_volume(self, volume):
-        self._delete_vdisk(volume['name'], False)
-
-    def create_snapshot(self, snapshot):
-        source_vol = self.db.volume_get(self._context, snapshot['volume_id'])
-        opts = self._get_vdisk_params(source_vol['volume_type_id'])
-        self._create_copy(src_vdisk=snapshot['volume_name'],
-                          tgt_vdisk=snapshot['name'],
-                          full_copy=False,
-                          opts=opts,
-                          src_id=snapshot['volume_id'],
-                          from_vol=True)
-
-    def delete_snapshot(self, snapshot):
-        self._delete_vdisk(snapshot['name'], False)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        if volume['size'] != snapshot['volume_size']:
-            exception_message = (_('create_volume_from_snapshot: '
-                                   'Source and destination size differ.'))
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        opts = self._get_vdisk_params(volume['volume_type_id'])
-        self._create_copy(src_vdisk=snapshot['name'],
-                          tgt_vdisk=volume['name'],
-                          full_copy=True,
-                          opts=opts,
-                          src_id=snapshot['id'],
-                          from_vol=False)
-
-    def create_cloned_volume(self, tgt_volume, src_volume):
-        if src_volume['size'] != tgt_volume['size']:
-            exception_message = (_('create_cloned_volume: '
-                                   'Source and destination size differ.'))
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        opts = self._get_vdisk_params(tgt_volume['volume_type_id'])
-        self._create_copy(src_vdisk=src_volume['name'],
-                          tgt_vdisk=tgt_volume['name'],
-                          full_copy=True,
-                          opts=opts,
-                          src_id=src_volume['id'],
-                          from_vol=True)
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        opts = self._get_vdisk_params(volume['volume_type_id'])
-        if opts['protocol'] == 'iSCSI':
-            # Implemented in base iSCSI class
-            return super(StorwizeSVCDriver, self).copy_image_to_volume(
-                    context, volume, image_service, image_id)
-        else:
-            raise NotImplementedError()
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        opts = self._get_vdisk_params(volume['volume_type_id'])
-        if opts['protocol'] == 'iSCSI':
-            # Implemented in base iSCSI class
-            return super(StorwizeSVCDriver, self).copy_volume_to_image(
-                    context, volume, image_service, image_meta)
-        else:
-            raise NotImplementedError()
-
-    """====================================================================="""
-    """ MISC/HELPERS                                                        """
-    """====================================================================="""
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If we haven't gotten stats yet or 'refresh' is True,
-        run update the stats first."""
-        if not self._stats or refresh:
-            self._update_volume_status()
-
-        return self._stats
-
-    def _update_volume_status(self):
-        """Retrieve status info from volume group."""
-
-        LOG.debug(_("Updating volume status"))
-        data = {}
-
-        data['vendor_name'] = 'IBM'
-        data['driver_version'] = '1.1'
-        data['storage_protocol'] = list(self._enabled_protocols)
-
-        data['total_capacity_gb'] = 0  # To be overwritten
-        data['free_capacity_gb'] = 0   # To be overwritten
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = False
-
-        pool = self.configuration.storwize_svc_volpool_name
-        #Get storage system name
-        ssh_cmd = 'svcinfo lssystem -delim !'
-        attributes = self._execute_command_and_parse_attributes(ssh_cmd)
-        if not attributes or not attributes['name']:
-            exception_message = (_('_update_volume_status: '
-                                   'Could not get system name'))
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        if not backend_name:
-            backend_name = '%s_%s' % (attributes['name'], pool)
-        data['volume_backend_name'] = backend_name
-
-        ssh_cmd = 'svcinfo lsmdiskgrp -bytes -delim ! %s' % pool
-        attributes = self._execute_command_and_parse_attributes(ssh_cmd)
-        if not attributes:
-            LOG.error(_('Could not get pool data from the storage'))
-            exception_message = (_('_update_volume_status: '
-                                   'Could not get storage pool data'))
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-        data['total_capacity_gb'] = (float(attributes['capacity']) /
-                                    (1024 ** 3))
-        data['free_capacity_gb'] = (float(attributes['free_capacity']) /
-                                    (1024 ** 3))
-        data['easytier_support'] = attributes['easy_tier'] in ['on', 'auto']
-        data['compression_support'] = self._compression_enabled
-
-        self._stats = data
-
-    def _port_conf_generator(self, cmd):
-        ssh_cmd = '%s -delim !' % cmd
-        out, err = self._run_ssh(ssh_cmd)
-
-        if not len(out.strip()):
-            return
-        port_lines = out.strip().split('\n')
-        if not len(port_lines):
-            return
-
-        header = port_lines.pop(0)
-        yield header
-        for portip_line in port_lines:
-            try:
-                port_data = self._get_hdr_dic(header, portip_line, '!')
-            except exception.VolumeBackendAPIException:
-                with excutils.save_and_reraise_exception():
-                    self._log_cli_output_error('_port_conf_generator',
-                                               ssh_cmd, out, err)
-            yield port_data
-
-    def _check_vdisk_opts(self, opts):
-        # Check that rsize is either -1 or between 0 and 100
-        if not (opts['rsize'] >= -1 and opts['rsize'] <= 100):
-            raise exception.InvalidInput(
-                reason=_('Illegal value specified for storwize_svc_vol_rsize: '
-                         'set to either a percentage (0-100) or -1'))
-
-        # Check that warning is either -1 or between 0 and 100
-        if not (opts['warning'] >= -1 and opts['warning'] <= 100):
-            raise exception.InvalidInput(
-                reason=_('Illegal value specified for '
-                         'storwize_svc_vol_warning: '
-                         'set to a percentage (0-100)'))
-
-        # Check that grainsize is 32/64/128/256
-        if opts['grainsize'] not in [32, 64, 128, 256]:
-            raise exception.InvalidInput(
-                reason=_('Illegal value specified for '
-                         'storwize_svc_vol_grainsize: set to either '
-                         '32, 64, 128, or 256'))
-
-        # Check that compression is supported
-        if opts['compression'] and not self._compression_enabled:
-            raise exception.InvalidInput(
-                reason=_('System does not support compression'))
-
-        # Check that rsize is set if compression is set
-        if opts['compression'] and opts['rsize'] == -1:
-            raise exception.InvalidInput(
-                reason=_('If compression is set to True, rsize must '
-                         'also be set (not equal to -1)'))
-
-        # Check that the requested protocol is enabled
-        if opts['protocol'] not in self._enabled_protocols:
-            raise exception.InvalidInput(
-                reason=_('Illegal value %(prot)s specified for '
-                         'storwize_svc_connection_protocol: '
-                         'valid values are %(enabled)s')
-                % {'prot': opts['protocol'],
-                   'enabled': ','.join(self._enabled_protocols)})
-
-        # Check that multipath is only enabled for fc
-        if opts['protocol'] != 'FC' and opts['multipath']:
-            raise exception.InvalidInput(
-                reason=_('Multipath is currently only supported for FC '
-                         'connections and not iSCSI.  (This is a Nova '
-                         'limitation.)'))
-
-    def _execute_command_and_parse_attributes(self, ssh_cmd):
-        """Execute command on the Storwize/SVC and parse attributes.
-
-        Exception is raised if the information from the system
-        can not be obtained.
-
-        """
-
-        LOG.debug(_('enter: _execute_command_and_parse_attributes: '
-                    ' command %s') % ssh_cmd)
-
-        try:
-            out, err = self._run_ssh(ssh_cmd)
-        except exception.ProcessExecutionError as e:
-            # Didn't get details from the storage, return None
-            LOG.error(_('CLI Exception output:\n command: %(cmd)s\n '
-                        'stdout: %(out)s\n stderr: %(err)s') %
-                      {'cmd': ssh_cmd,
-                       'out': e.stdout,
-                       'err': e.stderr})
-            return None
-
-        self._assert_ssh_return(len(out),
-                                '_execute_command_and_parse_attributes',
-                                ssh_cmd, out, err)
-        attributes = {}
-        for attrib_line in out.split('\n'):
-            # If '!' not found, return the string and two empty strings
-            attrib_name, foo, attrib_value = attrib_line.partition('!')
-            if attrib_name is not None and len(attrib_name.strip()):
-                attributes[attrib_name] = attrib_value
-
-        LOG.debug(_('leave: _execute_command_and_parse_attributes:\n'
-                    'command: %(cmd)s\n'
-                    'attributes: %(attr)s')
-                  % {'cmd': ssh_cmd,
-                     'attr': str(attributes)})
-
-        return attributes
-
-    def _get_hdr_dic(self, header, row, delim):
-        """Return CLI row data as a dictionary indexed by names from header.
-        string. The strings are converted to columns using the delimiter in
-        delim.
-        """
-
-        attributes = header.split(delim)
-        values = row.split(delim)
-        self._driver_assert(
-            len(values) ==
-            len(attributes),
-            _('_get_hdr_dic: attribute headers and values do not match.\n '
-              'Headers: %(header)s\n Values: %(row)s')
-            % {'header': str(header),
-               'row': str(row)})
-        dic = {}
-        for attribute, value in map(None, attributes, values):
-            dic[attribute] = value
-        return dic
-
-    def _log_cli_output_error(self, function, cmd, out, err):
-        LOG.error(_('%(fun)s: Failed with unexpected CLI output.\n '
-                    'Command: %(cmd)s\nstdout: %(out)s\nstderr: %(err)s\n')
-                  % {'fun': function, 'cmd': cmd,
-                     'out': str(out), 'err': str(err)})
-
-    def _driver_assert(self, assert_condition, exception_message):
-        """Internal assertion mechanism for CLI output."""
-        if not assert_condition:
-            LOG.error(exception_message)
-            raise exception.VolumeBackendAPIException(data=exception_message)
-
-    def _assert_ssh_return(self, test, fun, ssh_cmd, out, err):
-        self._driver_assert(
-            test,
-            _('%(fun)s: Failed with unexpected CLI output.\n '
-              'Command: %(cmd)s\n stdout: %(out)s\n stderr: %(err)s')
-            % {'fun': fun,
-               'cmd': ssh_cmd,
-               'out': str(out),
-               'err': str(err)})
-
-    def _handle_keyerror(self, function, header):
-        msg = (_('Did not find expected column in %(fun)s: %(hdr)s') %
-               {'fun': function, 'hdr': header})
-        LOG.error(msg)
-        raise exception.VolumeBackendAPIException(
-            data=msg)
-
-
-class CLIResponse(object):
-    '''Parse SVC CLI output and generate iterable'''
-
-    def __init__(self, raw, delim='!', with_header=True):
-        super(CLIResponse, self).__init__()
-        self.raw = raw
-        self.delim = delim
-        self.with_header = with_header
-        self.result = self._parse()
-
-    def select(self, *keys):
-        for a in self.result:
-            vs = []
-            for k in keys:
-                v = a.get(k, None)
-                if isinstance(v, basestring):
-                    v = [v]
-                if isinstance(v, list):
-                    vs.append(v)
-            for item in zip(*vs):
-                yield item
-
-    def __getitem__(self, key):
-        return self.result[key]
-
-    def __iter__(self):
-        for a in self.result:
-            yield a
-
-    def __len__(self):
-        return len(self.result)
-
-    def _parse(self):
-        def get_reader(content, delim):
-            for line in content.lstrip().splitlines():
-                line = line.strip()
-                if line:
-                    yield line.split(delim)
-                else:
-                    yield []
-
-        if isinstance(self.raw, basestring):
-            stdout, stderr = self.raw, ''
-        else:
-            stdout, stderr = self.raw
-        reader = get_reader(stdout, self.delim)
-        result = []
-
-        if self.with_header:
-            hds = tuple()
-            for row in reader:
-                hds = row
-                break
-            for row in reader:
-                cur = dict()
-                for k, v in zip(hds, row):
-                    CLIResponse.append_dict(cur, k, v)
-                result.append(cur)
-        else:
-            cur = dict()
-            for row in reader:
-                if row:
-                    CLIResponse.append_dict(cur, row[0], ' '.join(row[1:]))
-                elif cur:  # start new section
-                    result.append(cur)
-                    cur = dict()
-            if cur:
-                result.append(cur)
-        return result
-
-    @staticmethod
-    def append_dict(dict_, key, value):
-        key, value = key.strip(), value.strip()
-        obj = dict_.get(key, None)
-        if obj is None:
-            dict_[key] = value
-        elif isinstance(obj, list):
-            obj.append(value)
-            dict_[key] = obj
-        else:
-            dict_[key] = [obj, value]
-        return dict_
diff --git a/manila/volume/drivers/windows.py b/manila/volume/drivers/windows.py
deleted file mode 100644
index b0f49b4503..0000000000
--- a/manila/volume/drivers/windows.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Pedro Navarro Perez
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Volume driver for Windows Server 2012
-
-This driver requires ISCSI target role installed
-
-"""
-import os
-import sys
-
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila.volume import driver
-
-# Check needed for unit testing on Unix
-if os.name == 'nt':
-    import wmi
-
-
-LOG = logging.getLogger(__name__)
-
-FLAGS = flags.FLAGS
-
-windows_opts = [
-    cfg.StrOpt('windows_iscsi_lun_path',
-               default='C:\iSCSIVirtualDisks',
-               help='Path to store VHD backed volumes'),
-]
-
-FLAGS.register_opts(windows_opts)
-
-
-class WindowsDriver(driver.ISCSIDriver):
-    """Executes volume driver commands on Windows Storage server."""
-
-    def __init__(self, *args, **kwargs):
-        super(WindowsDriver, self).__init__(*args, **kwargs)
-
-    def do_setup(self, context):
-        """Setup the Windows Volume driver.
-
-        Called one time by the manager after the driver is loaded.
-        Validate the flags we care about
-        """
-        #Set the flags
-        self._conn_wmi = wmi.WMI(moniker='//./root/wmi')
-        self._conn_cimv2 = wmi.WMI(moniker='//./root/cimv2')
-
-    def check_for_setup_error(self):
-        """Check that the driver is working and can communicate.
-        """
-        #Invoking the portal an checking that is listening
-        wt_portal = self._conn_wmi.WT_Portal()[0]
-        listen = wt_portal.Listen
-        if not listen:
-            raise exception.VolumeBackendAPIException()
-
-    def initialize_connection(self, volume, connector):
-        """Driver entry point to attach a volume to an instance.
-        """
-        initiator_name = connector['initiator']
-        target_name = volume['provider_location']
-
-        cl = self._conn_wmi.__getattr__("WT_IDMethod")
-        wt_idmethod = cl.new()
-        wt_idmethod.HostName = target_name
-        wt_idmethod.Method = 4
-        wt_idmethod.Value = initiator_name
-        wt_idmethod.put()
-        #Getting the portal and port information
-        wt_portal = self._conn_wmi.WT_Portal()[0]
-        (address, port) = (wt_portal.Address, wt_portal.Port)
-        #Getting the host information
-        hosts = self._conn_wmi.WT_Host(Hostname=target_name)
-        host = hosts[0]
-
-        properties = {}
-        properties['target_discovered'] = False
-        properties['target_portal'] = '%s:%s' % (address, port)
-        properties['target_iqn'] = host.TargetIQN
-        properties['target_lun'] = 0
-        properties['volume_id'] = volume['id']
-
-        auth = volume['provider_auth']
-        if auth:
-            (auth_method, auth_username, auth_secret) = auth.split()
-
-            properties['auth_method'] = auth_method
-            properties['auth_username'] = auth_username
-            properties['auth_password'] = auth_secret
-
-        return {
-            'driver_volume_type': 'iscsi',
-            'data': properties,
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Driver entry point to unattach a volume from an instance.
-
-        Unmask the LUN on the storage system so the given intiator can no
-        longer access it.
-        """
-        initiator_name = connector['initiator']
-        provider_location = volume['provider_location']
-        #DesAssigning target to initiators
-        wt_idmethod = self._conn_wmi.WT_IDMethod(HostName=provider_location,
-                                                 Method=4,
-                                                 Value=initiator_name)[0]
-        wt_idmethod.Delete_()
-
-    def create_volume(self, volume):
-        """Driver entry point for creating a new volume."""
-        vhd_path = self._get_vhd_path(volume)
-        vol_name = volume['name']
-        #The WMI procedure returns a Generic failure
-        cl = self._conn_wmi.__getattr__("WT_Disk")
-        cl.NewWTDisk(DevicePath=vhd_path,
-                     Description=vol_name,
-                     SizeInMB=volume['size'] * 1024)
-
-    def _get_vhd_path(self, volume):
-        base_vhd_folder = FLAGS.windows_iscsi_lun_path
-        if not os.path.exists(base_vhd_folder):
-                LOG.debug(_('Creating folder %s '), base_vhd_folder)
-                os.makedirs(base_vhd_folder)
-        return os.path.join(base_vhd_folder, str(volume['name']) + ".vhd")
-
-    def delete_volume(self, volume):
-        """Driver entry point for destroying existing volumes."""
-        vol_name = volume['name']
-        wt_disk = self._conn_wmi.WT_Disk(Description=vol_name)[0]
-        wt_disk.Delete_()
-        vhdfiles = self._conn_cimv2.query(
-            "Select * from CIM_DataFile where Name = '" +
-            self._get_vhd_path(volume) + "'")
-        if len(vhdfiles) > 0:
-            vhdfiles[0].Delete()
-
-    def create_snapshot(self, snapshot):
-        """Driver entry point for creating a snapshot.
-        """
-        #Getting WT_Snapshot class
-        vol_name = snapshot['volume_name']
-        snapshot_name = snapshot['name']
-
-        wt_disk = self._conn_wmi.WT_Disk(Description=vol_name)[0]
-        #API Calls gets Generic Failure
-        cl = self._conn_wmi.__getattr__("WT_Snapshot")
-        disk_id = wt_disk.WTD
-        out = cl.Create(WTD=disk_id)
-        #Setting description since it used as a KEY
-        wt_snapshot_created = self._conn_wmi.WT_Snapshot(Id=out[0])[0]
-        wt_snapshot_created.Description = snapshot_name
-        wt_snapshot_created.put()
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Driver entry point for exporting snapshots as volumes."""
-        snapshot_name = snapshot['name']
-        wt_snapshot = self._conn_wmi.WT_Snapshot(Description=snapshot_name)[0]
-        disk_id = wt_snapshot.Export()[0]
-        wt_disk = self._conn_wmi.WT_Disk(WTD=disk_id)[0]
-        wt_disk.Description = volume['name']
-        wt_disk.put()
-
-    def delete_snapshot(self, snapshot):
-        """Driver entry point for deleting a snapshot."""
-        snapshot_name = snapshot['name']
-        wt_snapshot = self._conn_wmi.WT_Snapshot(Description=snapshot_name)[0]
-        wt_snapshot.Delete_()
-
-    def _do_export(self, _ctx, volume, ensure=False):
-        """Do all steps to get disk exported as LUN 0 at separate target.
-
-        :param volume: reference of volume to be exported
-        :param ensure: if True, ignore errors caused by already existing
-            resources
-        :return: iscsiadm-formatted provider location string
-        """
-        target_name = "%s%s" % (FLAGS.iscsi_target_prefix, volume['name'])
-        #ISCSI target creation
-        try:
-            cl = self._conn_wmi.__getattr__("WT_Host")
-            cl.NewHost(HostName=target_name)
-        except Exception as exc:
-            excep_info = exc.com_error.excepinfo[2]
-            if not ensure or excep_info.find(u'The file exists') == -1:
-                raise
-            else:
-                LOG.info(_('Ignored target creation error "%s"'
-                           ' while ensuring export'), exc)
-        #Get the disk to add
-        vol_name = volume['name']
-        q = self._conn_wmi.WT_Disk(Description=vol_name)
-        if not len(q):
-            LOG.debug(_('Disk not found: %s'), vol_name)
-            return None
-        wt_disk = q[0]
-        wt_host = self._conn_wmi.WT_Host(HostName=target_name)[0]
-        wt_host.AddWTDisk(wt_disk.WTD)
-
-        return target_name
-
-    def ensure_export(self, context, volume):
-        """Driver entry point to get the export info for an existing volume."""
-        self._do_export(context, volume, ensure=True)
-
-    def create_export(self, context, volume):
-        """Driver entry point to get the export info for a new volume."""
-        loc = self._do_export(context, volume, ensure=False)
-        return {'provider_location': loc}
-
-    def remove_export(self, context, volume):
-        """Driver exntry point to remove an export for a volume.
-        """
-        target_name = "%s%s" % (FLAGS.iscsi_target_prefix, volume['name'])
-
-        #Get ISCSI target
-        wt_host = self._conn_wmi.WT_Host(HostName=target_name)[0]
-        wt_host.RemoveAllWTDisks()
-        wt_host.Delete_()
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        raise NotImplementedError()
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        raise NotImplementedError()
diff --git a/manila/volume/drivers/xenapi/__init__.py b/manila/volume/drivers/xenapi/__init__.py
deleted file mode 100644
index 4549abf922..0000000000
--- a/manila/volume/drivers/xenapi/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-#    Copyright 2012 OpenStack LLC
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
diff --git a/manila/volume/drivers/xenapi/lib.py b/manila/volume/drivers/xenapi/lib.py
deleted file mode 100644
index a03985b7d5..0000000000
--- a/manila/volume/drivers/xenapi/lib.py
+++ /dev/null
@@ -1,542 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from manila.volume.drivers.xenapi import tools
-import contextlib
-import os
-import pickle
-
-
-class XenAPIException(Exception):
-    def __init__(self, original_exception):
-        super(XenAPIException, self).__init__(str(original_exception))
-        self.original_exception = original_exception
-
-
-class OperationsBase(object):
-    def __init__(self, xenapi_session):
-        self.session = xenapi_session
-
-    def call_xenapi(self, method, *args):
-        return self.session.call_xenapi(method, *args)
-
-
-class VMOperations(OperationsBase):
-    def get_by_uuid(self, vm_uuid):
-        return self.call_xenapi('VM.get_by_uuid', vm_uuid)
-
-    def get_vbds(self, vm_uuid):
-        return self.call_xenapi('VM.get_VBDs', vm_uuid)
-
-
-class VBDOperations(OperationsBase):
-    def create(self, vm_ref, vdi_ref, userdevice, bootable, mode, type,
-               empty, other_config):
-        vbd_rec = dict(
-            VM=vm_ref,
-            VDI=vdi_ref,
-            userdevice=str(userdevice),
-            bootable=bootable,
-            mode=mode,
-            type=type,
-            empty=empty,
-            other_config=other_config,
-            qos_algorithm_type='',
-            qos_algorithm_params=dict()
-        )
-        return self.call_xenapi('VBD.create', vbd_rec)
-
-    def destroy(self, vbd_ref):
-        self.call_xenapi('VBD.destroy', vbd_ref)
-
-    def get_device(self, vbd_ref):
-        return self.call_xenapi('VBD.get_device', vbd_ref)
-
-    def plug(self, vbd_ref):
-        return self.call_xenapi('VBD.plug', vbd_ref)
-
-    def unplug(self, vbd_ref):
-        return self.call_xenapi('VBD.unplug', vbd_ref)
-
-    def get_vdi(self, vbd_ref):
-        return self.call_xenapi('VBD.get_VDI', vbd_ref)
-
-
-class PoolOperations(OperationsBase):
-    def get_all(self):
-        return self.call_xenapi('pool.get_all')
-
-    def get_default_SR(self, pool_ref):
-        return self.call_xenapi('pool.get_default_SR', pool_ref)
-
-
-class PbdOperations(OperationsBase):
-    def get_all(self):
-        return self.call_xenapi('PBD.get_all')
-
-    def unplug(self, pbd_ref):
-        self.call_xenapi('PBD.unplug', pbd_ref)
-
-    def create(self, host_ref, sr_ref, device_config):
-        return self.call_xenapi(
-            'PBD.create',
-            dict(
-                host=host_ref,
-                SR=sr_ref,
-                device_config=device_config
-            )
-        )
-
-    def plug(self, pbd_ref):
-        self.call_xenapi('PBD.plug', pbd_ref)
-
-
-class SrOperations(OperationsBase):
-    def get_all(self):
-        return self.call_xenapi('SR.get_all')
-
-    def get_record(self, sr_ref):
-        return self.call_xenapi('SR.get_record', sr_ref)
-
-    def forget(self, sr_ref):
-        self.call_xenapi('SR.forget', sr_ref)
-
-    def scan(self, sr_ref):
-        self.call_xenapi('SR.scan', sr_ref)
-
-    def create(self, host_ref, device_config, name_label, name_description,
-               sr_type, physical_size=None, content_type=None,
-               shared=False, sm_config=None):
-        return self.call_xenapi(
-            'SR.create',
-            host_ref,
-            device_config,
-            physical_size or '0',
-            name_label or '',
-            name_description or '',
-            sr_type,
-            content_type or '',
-            shared,
-            sm_config or dict()
-        )
-
-    def introduce(self, sr_uuid, name_label, name_description, sr_type,
-                  content_type=None, shared=False, sm_config=None):
-        return self.call_xenapi(
-            'SR.introduce',
-            sr_uuid,
-            name_label or '',
-            name_description or '',
-            sr_type,
-            content_type or '',
-            shared,
-            sm_config or dict()
-        )
-
-    def get_uuid(self, sr_ref):
-        return self.get_record(sr_ref)['uuid']
-
-    def get_name_label(self, sr_ref):
-        return self.get_record(sr_ref)['name_label']
-
-    def get_name_description(self, sr_ref):
-        return self.get_record(sr_ref)['name_description']
-
-    def destroy(self, sr_ref):
-        self.call_xenapi('SR.destroy', sr_ref)
-
-
-class VdiOperations(OperationsBase):
-    def get_all(self):
-        return self.call_xenapi('VDI.get_all')
-
-    def get_record(self, vdi_ref):
-        return self.call_xenapi('VDI.get_record', vdi_ref)
-
-    def get_by_uuid(self, vdi_uuid):
-        return self.call_xenapi('VDI.get_by_uuid', vdi_uuid)
-
-    def get_uuid(self, vdi_ref):
-        return self.get_record(vdi_ref)['uuid']
-
-    def create(self, sr_ref, size, vdi_type,
-               sharable=False, read_only=False, other_config=None):
-        return self.call_xenapi('VDI.create',
-                                dict(SR=sr_ref,
-                                     virtual_size=str(size),
-                                     type=vdi_type,
-                                     sharable=sharable,
-                                     read_only=read_only,
-                                     other_config=other_config or dict()))
-
-    def destroy(self, vdi_ref):
-        self.call_xenapi('VDI.destroy', vdi_ref)
-
-    def copy(self, vdi_ref, sr_ref):
-        return self.call_xenapi('VDI.copy', vdi_ref, sr_ref)
-
-    def resize(self, vdi_ref, size):
-        return self.call_xenapi('VDI.resize', vdi_ref, str(size))
-
-
-class HostOperations(OperationsBase):
-    def get_record(self, host_ref):
-        return self.call_xenapi('host.get_record', host_ref)
-
-    def get_uuid(self, host_ref):
-        return self.get_record(host_ref)['uuid']
-
-
-class XenAPISession(object):
-    def __init__(self, session, exception_to_convert):
-        self._session = session
-        self._exception_to_convert = exception_to_convert
-        self.handle = self._session.handle
-        self.PBD = PbdOperations(self)
-        self.SR = SrOperations(self)
-        self.VDI = VdiOperations(self)
-        self.host = HostOperations(self)
-        self.pool = PoolOperations(self)
-        self.VBD = VBDOperations(self)
-        self.VM = VMOperations(self)
-
-    def close(self):
-        return self.call_xenapi('logout')
-
-    @contextlib.contextmanager
-    def exception_converter(self):
-        try:
-            yield None
-        except self._exception_to_convert as e:
-            raise XenAPIException(e)
-
-    def call_xenapi(self, method, *args):
-        with self.exception_converter():
-            return self._session.xenapi_request(method, args)
-
-    def call_plugin(self, host_ref, plugin, function, args):
-        with self.exception_converter():
-            return self._session.xenapi.host.call_plugin(
-                host_ref, plugin, function, args)
-
-    def get_pool(self):
-        return self.call_xenapi('session.get_pool', self.handle)
-
-    def get_this_host(self):
-        return self.call_xenapi('session.get_this_host', self.handle)
-
-
-class CompoundOperations(object):
-    def unplug_pbds_from_sr(self, sr_ref):
-        sr_rec = self.SR.get_record(sr_ref)
-        for pbd_ref in sr_rec.get('PBDs', []):
-            self.PBD.unplug(pbd_ref)
-
-    def unplug_pbds_and_forget_sr(self, sr_ref):
-        self.unplug_pbds_from_sr(sr_ref)
-        self.SR.forget(sr_ref)
-
-    def create_new_vdi(self, sr_ref, size_in_gigabytes):
-        return self.VDI.create(sr_ref,
-                               to_bytes(size_in_gigabytes),
-                               'User', )
-
-
-def to_bytes(size_in_gigs):
-    return size_in_gigs * 1024 * 1024 * 1024
-
-
-class NFSOperationsMixIn(CompoundOperations):
-    def is_nfs_sr(self, sr_ref):
-        return self.SR.get_record(sr_ref).get('type') == 'nfs'
-
-    @contextlib.contextmanager
-    def new_sr_on_nfs(self, host_ref, server, serverpath,
-                      name_label=None, name_description=None):
-
-        device_config = dict(
-            server=server,
-            serverpath=serverpath
-        )
-        name_label = name_label or ''
-        name_description = name_description or ''
-        sr_type = 'nfs'
-
-        sr_ref = self.SR.create(
-            host_ref,
-            device_config,
-            name_label,
-            name_description,
-            sr_type,
-        )
-        yield sr_ref
-
-        self.unplug_pbds_and_forget_sr(sr_ref)
-
-    def plug_nfs_sr(self, host_ref, server, serverpath, sr_uuid,
-                    name_label=None, name_description=None):
-
-        device_config = dict(
-            server=server,
-            serverpath=serverpath
-        )
-        sr_type = 'nfs'
-
-        sr_ref = self.SR.introduce(
-            sr_uuid,
-            name_label,
-            name_description,
-            sr_type,
-        )
-
-        pbd_ref = self.PBD.create(
-            host_ref,
-            sr_ref,
-            device_config
-        )
-
-        self.PBD.plug(pbd_ref)
-
-        return sr_ref
-
-    def connect_volume(self, server, serverpath, sr_uuid, vdi_uuid):
-        host_ref = self.get_this_host()
-        sr_ref = self.plug_nfs_sr(
-            host_ref,
-            server,
-            serverpath,
-            sr_uuid
-        )
-        self.SR.scan(sr_ref)
-        vdi_ref = self.VDI.get_by_uuid(vdi_uuid)
-        return dict(sr_ref=sr_ref, vdi_ref=vdi_ref)
-
-    def copy_vdi_to_sr(self, vdi_ref, sr_ref):
-        return self.VDI.copy(vdi_ref, sr_ref)
-
-
-class ContextAwareSession(XenAPISession):
-    def __enter__(self):
-        return self
-
-    def __exit__(self, exc_type, exc_value, traceback):
-        self.close()
-
-
-class OpenStackXenAPISession(ContextAwareSession,
-                             NFSOperationsMixIn):
-    pass
-
-
-def connect(url, user, password):
-    import XenAPI
-    session = XenAPI.Session(url)
-    session.login_with_password(user, password)
-    return OpenStackXenAPISession(session, XenAPI.Failure)
-
-
-class SessionFactory(object):
-    def __init__(self, url, user, password):
-        self.url = url
-        self.user = user
-        self.password = password
-
-    def get_session(self):
-        return connect(self.url, self.user, self.password)
-
-
-class XapiPluginProxy(object):
-    def __init__(self, session_factory, plugin_name):
-        self._session_factory = session_factory
-        self._plugin_name = plugin_name
-
-    def call(self, function, *plugin_args, **plugin_kwargs):
-        plugin_params = dict(args=plugin_args, kwargs=plugin_kwargs)
-        args = dict(params=pickle.dumps(plugin_params))
-
-        with self._session_factory.get_session() as session:
-            host_ref = session.get_this_host()
-            result = session.call_plugin(
-                host_ref, self._plugin_name, function, args)
-
-        return pickle.loads(result)
-
-
-class GlancePluginProxy(XapiPluginProxy):
-    def __init__(self, session_factory):
-        super(GlancePluginProxy, self).__init__(session_factory, 'glance')
-
-    def download_vhd(self, image_id, glance_host, glance_port, glance_use_ssl,
-                     uuid_stack, sr_path, auth_token):
-        return self.call(
-            'download_vhd',
-            image_id=image_id,
-            glance_host=glance_host,
-            glance_port=glance_port,
-            glance_use_ssl=glance_use_ssl,
-            uuid_stack=uuid_stack,
-            sr_path=sr_path,
-            auth_token=auth_token)
-
-    def upload_vhd(self, vdi_uuids, image_id, glance_host, glance_port,
-                   glance_use_ssl, sr_path, auth_token, properties):
-        return self.call(
-            'upload_vhd',
-            vdi_uuids=vdi_uuids,
-            image_id=image_id,
-            glance_host=glance_host,
-            glance_port=glance_port,
-            glance_use_ssl=glance_use_ssl,
-            sr_path=sr_path,
-            auth_token=auth_token,
-            properties=properties)
-
-
-class NFSBasedVolumeOperations(object):
-    def __init__(self, session_factory):
-        self._session_factory = session_factory
-        self.glance_plugin = GlancePluginProxy(session_factory)
-
-    def create_volume(self, server, serverpath, size,
-                      name=None, description=None):
-        with self._session_factory.get_session() as session:
-            host_ref = session.get_this_host()
-            with session.new_sr_on_nfs(host_ref, server, serverpath,
-                                       name, description) as sr_ref:
-                vdi_ref = session.create_new_vdi(sr_ref, size)
-
-                return dict(
-                    sr_uuid=session.SR.get_uuid(sr_ref),
-                    vdi_uuid=session.VDI.get_uuid(vdi_ref)
-                )
-
-    def delete_volume(self, server, serverpath, sr_uuid, vdi_uuid):
-        with self._session_factory.get_session() as session:
-            refs = session.connect_volume(
-                server, serverpath, sr_uuid, vdi_uuid)
-
-            session.VDI.destroy(refs['vdi_ref'])
-            sr_ref = refs['sr_ref']
-            session.unplug_pbds_from_sr(sr_ref)
-            session.SR.destroy(sr_ref)
-
-    def connect_volume(self, server, serverpath, sr_uuid, vdi_uuid):
-        with self._session_factory.get_session() as session:
-            refs = session.connect_volume(
-                server, serverpath, sr_uuid, vdi_uuid)
-
-            return session.VDI.get_uuid(refs['vdi_ref'])
-
-    def disconnect_volume(self, vdi_uuid):
-        with self._session_factory.get_session() as session:
-            vdi_ref = session.VDI.get_by_uuid(vdi_uuid)
-            vdi_rec = session.VDI.get_record(vdi_ref)
-            sr_ref = vdi_rec['SR']
-            session.unplug_pbds_and_forget_sr(sr_ref)
-
-    def copy_volume(self, server, serverpath, sr_uuid, vdi_uuid,
-                    name=None, description=None):
-        with self._session_factory.get_session() as session:
-            src_refs = session.connect_volume(
-                server, serverpath, sr_uuid, vdi_uuid)
-            try:
-                host_ref = session.get_this_host()
-
-                with session.new_sr_on_nfs(host_ref, server, serverpath,
-                                           name, description) as target_sr_ref:
-                    target_vdi_ref = session.copy_vdi_to_sr(
-                        src_refs['vdi_ref'], target_sr_ref)
-
-                    dst_refs = dict(
-                        sr_uuid=session.SR.get_uuid(target_sr_ref),
-                        vdi_uuid=session.VDI.get_uuid(target_vdi_ref)
-                    )
-
-            finally:
-                session.unplug_pbds_and_forget_sr(src_refs['sr_ref'])
-
-            return dst_refs
-
-    def resize_volume(self, server, serverpath, sr_uuid, vdi_uuid,
-                      size_in_gigabytes):
-        self.connect_volume(server, serverpath, sr_uuid, vdi_uuid)
-
-        try:
-            with self._session_factory.get_session() as session:
-                vdi_ref = session.VDI.get_by_uuid(vdi_uuid)
-                session.VDI.resize(vdi_ref, to_bytes(size_in_gigabytes))
-        finally:
-            self.disconnect_volume(vdi_uuid)
-
-    def use_glance_plugin_to_overwrite_volume(self, server, serverpath,
-                                              sr_uuid, vdi_uuid, glance_server,
-                                              image_id, auth_token,
-                                              sr_base_path):
-        self.connect_volume(server, serverpath, sr_uuid, vdi_uuid)
-
-        uuid_stack = [vdi_uuid]
-        glance_host, glance_port, glance_use_ssl = glance_server
-
-        try:
-            result = self.glance_plugin.download_vhd(
-                image_id, glance_host, glance_port, glance_use_ssl, uuid_stack,
-                os.path.join(sr_base_path, sr_uuid), auth_token)
-        finally:
-            self.disconnect_volume(vdi_uuid)
-
-        if len(result) != 1 or result['root']['uuid'] != vdi_uuid:
-            return False
-
-        return True
-
-    def use_glance_plugin_to_upload_volume(self, server, serverpath,
-                                           sr_uuid, vdi_uuid, glance_server,
-                                           image_id, auth_token, sr_base_path):
-        self.connect_volume(server, serverpath, sr_uuid, vdi_uuid)
-
-        vdi_uuids = [vdi_uuid]
-        glance_host, glance_port, glance_use_ssl = glance_server
-
-        try:
-            result = self.glance_plugin.upload_vhd(
-                vdi_uuids, image_id, glance_host, glance_port, glance_use_ssl,
-                os.path.join(sr_base_path, sr_uuid), auth_token, dict())
-        finally:
-            self.disconnect_volume(vdi_uuid)
-
-    @contextlib.contextmanager
-    def volume_attached_here(self, server, serverpath, sr_uuid, vdi_uuid,
-                             readonly=True):
-        self.connect_volume(server, serverpath, sr_uuid, vdi_uuid)
-
-        with self._session_factory.get_session() as session:
-            vm_uuid = tools.get_this_vm_uuid()
-            vm_ref = session.VM.get_by_uuid(vm_uuid)
-            vdi_ref = session.VDI.get_by_uuid(vdi_uuid)
-            vbd_ref = session.VBD.create(
-                vm_ref, vdi_ref, userdevice='autodetect', bootable=False,
-                mode='RO' if readonly else 'RW', type='disk', empty=False,
-                other_config=dict())
-            session.VBD.plug(vbd_ref)
-            device = session.VBD.get_device(vbd_ref)
-            try:
-                yield "/dev/" + device
-            finally:
-                session.VBD.unplug(vbd_ref)
-                session.VBD.destroy(vbd_ref)
-                self.disconnect_volume(vdi_uuid)
diff --git a/manila/volume/drivers/xenapi/sm.py b/manila/volume/drivers/xenapi/sm.py
deleted file mode 100644
index 94ad22dca6..0000000000
--- a/manila/volume/drivers/xenapi/sm.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.image import glance
-from manila.image import image_utils
-from manila.openstack.common import log as logging
-from manila.volume import driver
-from manila.volume.drivers.xenapi import lib as xenapi_lib
-
-LOG = logging.getLogger(__name__)
-
-xenapi_opts = [
-    cfg.StrOpt('xenapi_connection_url',
-               default=None,
-               help='URL for XenAPI connection'),
-    cfg.StrOpt('xenapi_connection_username',
-               default='root',
-               help='Username for XenAPI connection'),
-    cfg.StrOpt('xenapi_connection_password',
-               default=None,
-               help='Password for XenAPI connection',
-               secret=True),
-    cfg.StrOpt('xenapi_sr_base_path',
-               default='/var/run/sr-mount',
-               help='Base path to the storage repository'),
-]
-
-xenapi_nfs_opts = [
-    cfg.StrOpt('xenapi_nfs_server',
-               default=None,
-               help='NFS server to be used by XenAPINFSDriver'),
-    cfg.StrOpt('xenapi_nfs_serverpath',
-               default=None,
-               help='Path of exported NFS, used by XenAPINFSDriver'),
-]
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(xenapi_opts)
-FLAGS.register_opts(xenapi_nfs_opts)
-
-
-class XenAPINFSDriver(driver.VolumeDriver):
-    def __init__(self, *args, **kwargs):
-        super(XenAPINFSDriver, self).__init__(*args, **kwargs)
-        self.configuration.append_config_values(xenapi_opts)
-        self.configuration.append_config_values(xenapi_nfs_opts)
-
-    def do_setup(self, context):
-        session_factory = xenapi_lib.SessionFactory(
-            self.configuration.xenapi_connection_url,
-            self.configuration.xenapi_connection_username,
-            self.configuration.xenapi_connection_password
-        )
-        self.nfs_ops = xenapi_lib.NFSBasedVolumeOperations(session_factory)
-
-    def create_cloned_volume(self, volume, src_vref):
-        raise NotImplementedError()
-
-    def create_volume(self, volume):
-        volume_details = self.nfs_ops.create_volume(
-            self.configuration.xenapi_nfs_server,
-            self.configuration.xenapi_nfs_serverpath,
-            volume['size'],
-            volume['display_name'],
-            volume['display_description']
-        )
-        location = "%(sr_uuid)s/%(vdi_uuid)s" % volume_details
-        return dict(provider_location=location)
-
-    def create_export(self, context, volume):
-        pass
-
-    def delete_volume(self, volume):
-        sr_uuid, vdi_uuid = volume['provider_location'].split('/')
-
-        self.nfs_ops.delete_volume(
-            self.configuration.xenapi_nfs_server,
-            self.configuration.xenapi_nfs_serverpath,
-            sr_uuid,
-            vdi_uuid
-        )
-
-    def remove_export(self, context, volume):
-        pass
-
-    def initialize_connection(self, volume, connector):
-        sr_uuid, vdi_uuid = volume['provider_location'].split('/')
-
-        return dict(
-            driver_volume_type='xensm',
-            data=dict(
-                name_label=volume['display_name'] or '',
-                name_description=volume['display_description'] or '',
-                sr_uuid=sr_uuid,
-                vdi_uuid=vdi_uuid,
-                sr_type='nfs',
-                server=self.configuration.xenapi_nfs_server,
-                serverpath=self.configuration.xenapi_nfs_serverpath,
-                introduce_sr_keys=['sr_type', 'server', 'serverpath']
-            )
-        )
-
-    def terminate_connection(self, volume, connector, force=False, **kwargs):
-        pass
-
-    def check_for_setup_error(self):
-        """To override superclass' method"""
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        return self._copy_volume(
-            snapshot, volume['display_name'], volume['name_description'])
-
-    def create_snapshot(self, snapshot):
-        volume_id = snapshot['volume_id']
-        volume = snapshot['volume']
-        return self._copy_volume(
-            volume, snapshot['display_name'], snapshot['display_description'])
-
-    def _copy_volume(self, volume, target_name, target_desc):
-        sr_uuid, vdi_uuid = volume['provider_location'].split('/')
-
-        volume_details = self.nfs_ops.copy_volume(
-            self.configuration.xenapi_nfs_server,
-            self.configuration.xenapi_nfs_serverpath,
-            sr_uuid,
-            vdi_uuid,
-            target_name,
-            target_desc
-        )
-        location = "%(sr_uuid)s/%(vdi_uuid)s" % volume_details
-        return dict(provider_location=location)
-
-    def delete_snapshot(self, snapshot):
-        self.delete_volume(snapshot)
-
-    def ensure_export(self, context, volume):
-        pass
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        if is_xenserver_image(context, image_service, image_id):
-            return self._use_glance_plugin_to_copy_image_to_volume(
-                context, volume, image_service, image_id)
-
-        return self._use_image_utils_to_pipe_bytes_to_volume(
-            context, volume, image_service, image_id)
-
-    def _use_image_utils_to_pipe_bytes_to_volume(self, context, volume,
-                                                 image_service, image_id):
-        sr_uuid, vdi_uuid = volume['provider_location'].split('/')
-        with self.nfs_ops.volume_attached_here(FLAGS.xenapi_nfs_server,
-                                               FLAGS.xenapi_nfs_serverpath,
-                                               sr_uuid, vdi_uuid,
-                                               False) as device:
-            image_utils.fetch_to_raw(context,
-                                     image_service,
-                                     image_id,
-                                     device)
-
-    def _use_glance_plugin_to_copy_image_to_volume(self, context, volume,
-                                                   image_service, image_id):
-        sr_uuid, vdi_uuid = volume['provider_location'].split('/')
-
-        api_servers = glance.get_api_servers()
-        glance_server = api_servers.next()
-        auth_token = context.auth_token
-
-        overwrite_result = self.nfs_ops.use_glance_plugin_to_overwrite_volume(
-            FLAGS.xenapi_nfs_server,
-            FLAGS.xenapi_nfs_serverpath,
-            sr_uuid,
-            vdi_uuid,
-            glance_server,
-            image_id,
-            auth_token,
-            FLAGS.xenapi_sr_base_path)
-
-        if overwrite_result is False:
-            raise exception.ImageCopyFailure()
-
-        self.nfs_ops.resize_volume(
-            FLAGS.xenapi_nfs_server,
-            FLAGS.xenapi_nfs_serverpath,
-            sr_uuid,
-            vdi_uuid,
-            volume['size'])
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        if is_xenserver_format(image_meta):
-            return self._use_glance_plugin_to_upload_volume(
-                context, volume, image_service, image_meta)
-
-        return self._use_image_utils_to_upload_volume(
-            context, volume, image_service, image_meta)
-
-    def _use_image_utils_to_upload_volume(self, context, volume, image_service,
-                                          image_meta):
-        sr_uuid, vdi_uuid = volume['provider_location'].split('/')
-        with self.nfs_ops.volume_attached_here(FLAGS.xenapi_nfs_server,
-                                               FLAGS.xenapi_nfs_serverpath,
-                                               sr_uuid, vdi_uuid,
-                                               True) as device:
-            image_utils.upload_volume(context,
-                                      image_service,
-                                      image_meta,
-                                      device)
-
-    def _use_glance_plugin_to_upload_volume(self, context, volume,
-                                            image_service, image_meta):
-        image_id = image_meta['id']
-
-        sr_uuid, vdi_uuid = volume['provider_location'].split('/')
-
-        api_servers = glance.get_api_servers()
-        glance_server = api_servers.next()
-        auth_token = context.auth_token
-
-        self.nfs_ops.use_glance_plugin_to_upload_volume(
-            FLAGS.xenapi_nfs_server,
-            FLAGS.xenapi_nfs_serverpath,
-            sr_uuid,
-            vdi_uuid,
-            glance_server,
-            image_id,
-            auth_token,
-            FLAGS.xenapi_sr_base_path)
-
-    def get_volume_stats(self, refresh=False):
-        if refresh or not self._stats:
-            data = {}
-
-            backend_name = self.configuration.safe_get('volume_backend_name')
-            data["volume_backend_name"] = backend_name or 'XenAPINFS',
-            data['vendor_name'] = 'Open Source',
-            data['driver_version'] = '1.0'
-            data['storage_protocol'] = 'xensm'
-            data['total_capacity_gb'] = 'unknown'
-            data['free_capacity_gb'] = 'unknown'
-            data['reserved_percentage'] = 0
-            self._stats = data
-
-        return self._stats
-
-
-def is_xenserver_image(context, image_service, image_id):
-    image_meta = image_service.show(context, image_id)
-    return is_xenserver_format(image_meta)
-
-
-def is_xenserver_format(image_meta):
-    return (
-        image_meta['disk_format'] == 'vhd'
-        and image_meta['container_format'] == 'ovf'
-    )
diff --git a/manila/volume/drivers/xenapi/tools.py b/manila/volume/drivers/xenapi/tools.py
deleted file mode 100644
index d452fbfa77..0000000000
--- a/manila/volume/drivers/xenapi/tools.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def _stripped_first_line_of(filename):
-    with open(filename, 'rb') as f:
-        return f.readline().strip()
-
-
-def get_this_vm_uuid():
-    return _stripped_first_line_of('/sys/hypervisor/uuid')
diff --git a/manila/volume/drivers/xiv.py b/manila/volume/drivers/xiv.py
deleted file mode 100644
index cf5fce570f..0000000000
--- a/manila/volume/drivers/xiv.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 IBM Corp.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-#
-# Authors:
-#   Erik Zaadi <erikz@il.ibm.com>
-#   Avishay Traeger <avishay@il.ibm.com>
-
-"""
-Volume driver for IBM XIV storage systems.
-"""
-
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import importutils
-from manila.openstack.common import log as logging
-from manila.volume.drivers.san import san
-
-ibm_xiv_opts = [
-    cfg.StrOpt('xiv_proxy',
-               default='xiv_openstack.nova_proxy.XIVNovaProxy',
-               help='Proxy driver'),
-]
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(ibm_xiv_opts)
-
-LOG = logging.getLogger('manila.volume.xiv')
-
-
-class XIVDriver(san.SanISCSIDriver):
-    """IBM XIV volume driver."""
-
-    def __init__(self, *args, **kwargs):
-        """Initialize the driver."""
-
-        proxy = importutils.import_class(FLAGS.xiv_proxy)
-
-        self.xiv_proxy = proxy({"xiv_user": FLAGS.san_login,
-                                "xiv_pass": FLAGS.san_password,
-                                "xiv_address": FLAGS.san_ip,
-                                "xiv_vol_pool": FLAGS.san_clustername},
-                               LOG,
-                               exception)
-        san.SanISCSIDriver.__init__(self, *args, **kwargs)
-
-    def do_setup(self, context):
-        """Setup and verify IBM XIV storage connection."""
-
-        self.xiv_proxy.setup(context)
-
-    def ensure_export(self, context, volume):
-        """Ensure an export."""
-
-        return self.xiv_proxy.ensure_export(context, volume)
-
-    def create_export(self, context, volume):
-        """Create an export."""
-
-        return self.xiv_proxy.create_export(context, volume)
-
-    def create_volume(self, volume):
-        """Create a volume on the IBM XIV storage system."""
-
-        return self.xiv_proxy.create_volume(volume)
-
-    def delete_volume(self, volume):
-        """Delete a volume on the IBM XIV storage system."""
-
-        self.xiv_proxy.delete_volume(volume)
-
-    def remove_export(self, context, volume):
-        """Disconnect a volume from an attached instance."""
-
-        return self.xiv_proxy.remove_export(context, volume)
-
-    def initialize_connection(self, volume, connector):
-        """Map the created volume."""
-
-        return self.xiv_proxy.initialize_connection(volume, connector)
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Terminate a connection to a volume."""
-
-        return self.xiv_proxy.terminate_connection(volume, connector)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        """Create a volume from a snapshot."""
-
-        return self.xiv_proxy.create_volume_from_snapshot(volume,
-                                                          snapshot)
-
-    def create_snapshot(self, snapshot):
-        """Create a snapshot."""
-
-        return self.xiv_proxy.create_snapshot(snapshot)
-
-    def delete_snapshot(self, snapshot):
-        """Delete a snapshot."""
-
-        return self.xiv_proxy.delete_snapshot(snapshot)
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume stats."""
-
-        return self.xiv_proxy.get_volume_stats(refresh)
diff --git a/manila/volume/drivers/zadara.py b/manila/volume/drivers/zadara.py
deleted file mode 100644
index 3b7edcd5d1..0000000000
--- a/manila/volume/drivers/zadara.py
+++ /dev/null
@@ -1,491 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 Zadara Storage, Inc.
-# Copyright (c) 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Volume driver for Zadara Virtual Private Storage Array (VPSA).
-
-This driver requires VPSA with API ver.12.06 or higher.
-"""
-
-import httplib
-
-from lxml import etree
-from oslo.config import cfg
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-from manila import utils
-from manila.volume import driver
-
-LOG = logging.getLogger("manila.volume.driver")
-
-zadara_opts = [
-    cfg.StrOpt('zadara_vpsa_ip',
-               default=None,
-               help='Management IP of Zadara VPSA'),
-    cfg.StrOpt('zadara_vpsa_port',
-               default=None,
-               help='Zadara VPSA port number'),
-    cfg.BoolOpt('zadara_vpsa_use_ssl',
-                default=False,
-                help='Use SSL connection'),
-    cfg.StrOpt('zadara_user',
-               default=None,
-               help='User name for the VPSA'),
-    cfg.StrOpt('zadara_password',
-               default=None,
-               help='Password for the VPSA',
-               secret=True),
-
-    cfg.StrOpt('zadara_vpsa_poolname',
-               default=None,
-               help='Name of VPSA storage pool for volumes'),
-
-    cfg.StrOpt('zadara_default_cache_policy',
-               default='write-through',
-               help='Default cache policy for volumes'),
-    cfg.StrOpt('zadara_default_encryption',
-               default='NO',
-               help='Default encryption policy for volumes'),
-    cfg.StrOpt('zadara_default_striping_mode',
-               default='simple',
-               help='Default striping mode for volumes'),
-    cfg.StrOpt('zadara_default_stripesize',
-               default='64',
-               help='Default stripe size for volumes'),
-    cfg.StrOpt('zadara_vol_name_template',
-               default='OS_%s',
-               help='Default template for VPSA volume names'),
-    cfg.BoolOpt('zadara_vpsa_auto_detach_on_delete',
-                default=True,
-                help="Automatically detach from servers on volume delete"),
-    cfg.BoolOpt('zadara_vpsa_allow_nonexistent_delete',
-                default=True,
-                help="Don't halt on deletion of non-existing volumes"), ]
-
-FLAGS = flags.FLAGS
-FLAGS.register_opts(zadara_opts)
-
-
-class ZadaraVPSAConnection(object):
-    """Executes volume driver commands on VPSA."""
-
-    def __init__(self, host, port, ssl, user, password):
-        self.host = host
-        self.port = port
-        self.use_ssl = ssl
-        self.user = user
-        self.password = password
-        self.access_key = None
-
-        self.ensure_connection()
-
-    def _generate_vpsa_cmd(self, cmd, **kwargs):
-        """Generate command to be sent to VPSA."""
-
-        def _joined_params(params):
-            param_str = []
-            for k, v in params.items():
-                param_str.append("%s=%s" % (k, v))
-            return '&'.join(param_str)
-
-        # Dictionary of applicable VPSA commands in the following format:
-        # 'command': (method, API_URL, {optional parameters})
-        vpsa_commands = {
-            'login': ('POST',
-                      '/api/users/login.xml',
-                      {'user': self.user,
-                       'password': self.password}),
-
-            # Volume operations
-            'create_volume': ('POST',
-                              '/api/volumes.xml',
-                              {'display_name': kwargs.get('name'),
-                               'virtual_capacity': kwargs.get('size'),
-                               'raid_group_name[]': FLAGS.zadara_vpsa_poolname,
-                               'quantity': 1,
-                               'cache': FLAGS.zadara_default_cache_policy,
-                               'crypt': FLAGS.zadara_default_encryption,
-                               'mode': FLAGS.zadara_default_striping_mode,
-                               'stripesize': FLAGS.zadara_default_stripesize,
-                               'force': 'NO'}),
-            'delete_volume': ('DELETE',
-                              '/api/volumes/%s.xml' % kwargs.get('vpsa_vol'),
-                              {}),
-
-            # Server operations
-            'create_server': ('POST',
-                              '/api/servers.xml',
-                              {'display_name': kwargs.get('initiator'),
-                               'iqn': kwargs.get('initiator')}),
-
-            # Attach/Detach operations
-            'attach_volume': ('POST',
-                              '/api/servers/%s/volumes.xml'
-                              % kwargs.get('vpsa_srv'),
-                              {'volume_name[]': kwargs.get('vpsa_vol'),
-                               'force': 'NO'}),
-            'detach_volume': ('POST',
-                              '/api/volumes/%s/detach.xml'
-                              % kwargs.get('vpsa_vol'),
-                              {'server_name[]': kwargs.get('vpsa_srv'),
-                               'force': 'NO'}),
-
-            # Get operations
-            'list_volumes': ('GET',
-                             '/api/volumes.xml',
-                             {}),
-            'list_controllers': ('GET',
-                                 '/api/vcontrollers.xml',
-                                 {}),
-            'list_servers': ('GET',
-                             '/api/servers.xml',
-                             {}),
-            'list_vol_attachments': ('GET',
-                                     '/api/volumes/%s/servers.xml'
-                                     % kwargs.get('vpsa_vol'),
-                                     {}), }
-
-        if cmd not in vpsa_commands.keys():
-            raise exception.UnknownCmd(cmd=cmd)
-        else:
-            (method, url, params) = vpsa_commands[cmd]
-
-        if method == 'GET':
-            # For GET commands add parameters to the URL
-            params.update(dict(access_key=self.access_key,
-                               page=1, start=0, limit=0))
-            url += '?' + _joined_params(params)
-            body = ''
-
-        elif method == 'DELETE':
-            # For DELETE commands add parameters to the URL
-            params.update(dict(access_key=self.access_key))
-            url += '?' + _joined_params(params)
-            body = ''
-
-        elif method == 'POST':
-            if self.access_key:
-                params.update(dict(access_key=self.access_key))
-            body = _joined_params(params)
-
-        else:
-            raise exception.UnknownCmd(cmd=method)
-
-        return (method, url, body)
-
-    def ensure_connection(self, cmd=None):
-        """Retrieve access key for VPSA connection."""
-
-        if self.access_key or cmd == 'login':
-            return
-
-        cmd = 'login'
-        xml_tree = self.send_cmd(cmd)
-        user = xml_tree.find('user')
-        if user is None:
-            raise exception.MalformedResponse(cmd=cmd,
-                                              reason='no "user" field')
-
-        access_key = user.findtext('access-key')
-        if access_key is None:
-            raise exception.MalformedResponse(cmd=cmd,
-                                              reason='no "access-key" field')
-
-        self.access_key = access_key
-
-    def send_cmd(self, cmd, **kwargs):
-        """Send command to VPSA Controller."""
-
-        self.ensure_connection(cmd)
-
-        (method, url, body) = self._generate_vpsa_cmd(cmd, **kwargs)
-        LOG.debug(_('Sending %(method)s to %(url)s. Body "%(body)s"')
-                  % locals())
-
-        if self.use_ssl:
-            connection = httplib.HTTPSConnection(self.host, self.port)
-        else:
-            connection = httplib.HTTPConnection(self.host, self.port)
-        connection.request(method, url, body)
-        response = connection.getresponse()
-
-        if response.status != 200:
-            connection.close()
-            raise exception.BadHTTPResponseStatus(status=response.status)
-        data = response.read()
-        connection.close()
-
-        xml_tree = etree.fromstring(data)
-        status = xml_tree.findtext('status')
-        if status != '0':
-            raise exception.FailedCmdWithDump(status=status, data=data)
-
-        if method in ['POST', 'DELETE']:
-            LOG.debug(_('Operation completed. %(data)s') % locals())
-        return xml_tree
-
-
-class ZadaraVPSAISCSIDriver(driver.ISCSIDriver):
-    """Zadara VPSA iSCSI volume driver."""
-
-    def __init__(self, *args, **kwargs):
-        super(ZadaraVPSAISCSIDriver, self).__init__(*args, **kwargs)
-
-    def do_setup(self, context):
-        """
-        Any initialization the volume driver does while starting.
-        Establishes initial connection with VPSA and retrieves access_key.
-        """
-        self.vpsa = ZadaraVPSAConnection(FLAGS.zadara_vpsa_ip,
-                                         FLAGS.zadara_vpsa_port,
-                                         FLAGS.zadara_vpsa_use_ssl,
-                                         FLAGS.zadara_user,
-                                         FLAGS.zadara_password)
-
-    def check_for_setup_error(self):
-        """Returns an error (exception) if prerequisites aren't met."""
-        self.vpsa.ensure_connection()
-
-    def local_path(self, volume):
-        """Return local path to existing local volume."""
-        raise NotImplementedError()
-
-    def _xml_parse_helper(self, xml_tree, first_level, search_tuple,
-                          first=True):
-        """
-        Helper for parsing VPSA's XML output.
-
-        Returns single item if first==True or list for multiple selection.
-        If second argument in search_tuple is None - returns all items with
-        appropriate key.
-        """
-
-        objects = xml_tree.find(first_level)
-        if objects is None:
-            return None
-
-        result_list = []
-        (key, value) = search_tuple
-        for object in objects.getchildren():
-            found_value = object.findtext(key)
-            if found_value and (found_value == value or value is None):
-                if first:
-                    return object
-                else:
-                    result_list.append(object)
-        return result_list if result_list else None
-
-    def _get_vpsa_volume_name(self, name):
-        """Return VPSA's name for the volume."""
-        xml_tree = self.vpsa.send_cmd('list_volumes')
-        volume = self._xml_parse_helper(xml_tree, 'volumes',
-                                        ('display-name', name))
-        if volume is not None:
-            return volume.findtext('name')
-
-        return None
-
-    def _get_active_controller_details(self):
-        """Return details of VPSA's active controller."""
-        xml_tree = self.vpsa.send_cmd('list_controllers')
-        ctrl = self._xml_parse_helper(xml_tree, 'vcontrollers',
-                                      ('state', 'active'))
-        if ctrl is not None:
-            return dict(target=ctrl.findtext('target'),
-                        ip=ctrl.findtext('iscsi-ip'),
-                        chap_user=ctrl.findtext('chap-username'),
-                        chap_passwd=ctrl.findtext('chap-target-secret'))
-        return None
-
-    def _get_server_name(self, initiator):
-        """Return VPSA's name for server object with given IQN."""
-        xml_tree = self.vpsa.send_cmd('list_servers')
-        server = self._xml_parse_helper(xml_tree, 'servers',
-                                        ('iqn', initiator))
-        if server is not None:
-            return server.findtext('name')
-        return None
-
-    def _create_vpsa_server(self, initiator):
-        """Create server object within VPSA (if doesn't exist)."""
-        vpsa_srv = self._get_server_name(initiator)
-        if not vpsa_srv:
-            xml_tree = self.vpsa.send_cmd('create_server', initiator=initiator)
-            vpsa_srv = xml_tree.findtext('server-name')
-        return vpsa_srv
-
-    def create_volume(self, volume):
-        """Create volume."""
-        self.vpsa.send_cmd(
-            'create_volume',
-            name=FLAGS.zadara_vol_name_template % volume['name'],
-            size=volume['size'])
-
-    def delete_volume(self, volume):
-        """
-        Delete volume.
-
-        Return ok if doesn't exist. Auto detach from all servers.
-        """
-        # Get volume name
-        name = FLAGS.zadara_vol_name_template % volume['name']
-        vpsa_vol = self._get_vpsa_volume_name(name)
-        if not vpsa_vol:
-            msg = _('Volume %(name)s could not be found. '
-                    'It might be already deleted') % locals()
-            LOG.warning(msg)
-            if FLAGS.zadara_vpsa_allow_nonexistent_delete:
-                return
-            else:
-                raise exception.VolumeNotFound(volume_id=name)
-
-        # Check attachment info and detach from all
-        xml_tree = self.vpsa.send_cmd('list_vol_attachments',
-                                      vpsa_vol=vpsa_vol)
-        servers = self._xml_parse_helper(xml_tree, 'servers',
-                                         ('iqn', None), first=False)
-        if servers:
-            if not FLAGS.zadara_vpsa_auto_detach_on_delete:
-                raise exception.VolumeAttached(volume_id=name)
-
-            for server in servers:
-                vpsa_srv = server.findtext('name')
-                if vpsa_srv:
-                    self.vpsa.send_cmd('detach_volume',
-                                       vpsa_srv=vpsa_srv,
-                                       vpsa_vol=vpsa_vol)
-
-        # Delete volume
-        self.vpsa.send_cmd('delete_volume', vpsa_vol=vpsa_vol)
-
-    def create_export(self, context, volume):
-        """Irrelevant for VPSA volumes. Export created during attachment."""
-        pass
-
-    def ensure_export(self, context, volume):
-        """Irrelevant for VPSA volumes. Export created during attachment."""
-        pass
-
-    def remove_export(self, context, volume):
-        """Irrelevant for VPSA volumes. Export removed during detach."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """
-        Attach volume to initiator/host.
-
-        During this call VPSA exposes volume to particular Initiator. It also
-        creates a 'server' entity for Initiator (if it was not created before)
-
-        All necessary connection information is returned, including auth data.
-        Connection data (target, LUN) is not stored in the DB.
-        """
-
-        # Get/Create server name for IQN
-        initiator_name = connector['initiator']
-        vpsa_srv = self._create_vpsa_server(initiator_name)
-        if not vpsa_srv:
-            raise exception.ZadaraServerCreateFailure(name=initiator_name)
-
-        # Get volume name
-        name = FLAGS.zadara_vol_name_template % volume['name']
-        vpsa_vol = self._get_vpsa_volume_name(name)
-        if not vpsa_vol:
-            raise exception.VolumeNotFound(volume_id=name)
-
-        # Get Active controller details
-        ctrl = self._get_active_controller_details()
-        if not ctrl:
-            raise exception.ZadaraVPSANoActiveController()
-
-        # Attach volume to server
-        self.vpsa.send_cmd('attach_volume',
-                           vpsa_srv=vpsa_srv,
-                           vpsa_vol=vpsa_vol)
-
-        # Get connection info
-        xml_tree = self.vpsa.send_cmd('list_vol_attachments',
-                                      vpsa_vol=vpsa_vol)
-        server = self._xml_parse_helper(xml_tree, 'servers',
-                                        ('iqn', initiator_name))
-        if server is None:
-            raise exception.ZadaraAttachmentsNotFound(name=name)
-        target = server.findtext('target')
-        lun = server.findtext('lun')
-        if target is None or lun is None:
-            raise exception.ZadaraInvalidAttachmentInfo(
-                name=name,
-                reason='target=%s, lun=%s' % (target, lun))
-
-        properties = {}
-        properties['target_discovered'] = False
-        properties['target_portal'] = '%s:%s' % (ctrl['ip'], '3260')
-        properties['target_iqn'] = target
-        properties['target_lun'] = lun
-        properties['volume_id'] = volume['id']
-
-        properties['auth_method'] = 'CHAP'
-        properties['auth_username'] = ctrl['chap_user']
-        properties['auth_password'] = ctrl['chap_passwd']
-
-        LOG.debug(_('Attach properties: %(properties)s') % locals())
-        return {'driver_volume_type': 'iscsi',
-                'data': properties}
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """
-        Detach volume from the initiator.
-        """
-        # Get server name for IQN
-        initiator_name = connector['initiator']
-        vpsa_srv = self._get_server_name(initiator_name)
-        if not vpsa_srv:
-            raise exception.ZadaraServerNotFound(name=initiator_name)
-
-        # Get volume name
-        name = FLAGS.zadara_vol_name_template % volume['name']
-        vpsa_vol = self._get_vpsa_volume_name(name)
-        if not vpsa_vol:
-            raise exception.VolumeNotFound(volume_id=name)
-
-        # Detach volume from server
-        self.vpsa.send_cmd('detach_volume',
-                           vpsa_srv=vpsa_srv,
-                           vpsa_vol=vpsa_vol)
-
-    def create_volume_from_snapshot(self, volume, snapshot):
-        raise NotImplementedError()
-
-    def create_snapshot(self, snapshot):
-        raise NotImplementedError()
-
-    def delete_snapshot(self, snapshot):
-        raise NotImplementedError()
-
-    def copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Fetch the image from image_service and write it to the volume."""
-        raise NotImplementedError()
-
-    def copy_volume_to_image(self, context, volume, image_service, image_meta):
-        """Copy the volume to the specified image."""
-        raise NotImplementedError()
-
-    def create_cloned_volume(self, volume, src_vref):
-        """Creates a clone of the specified volume."""
-        raise NotImplementedError()
diff --git a/manila/volume/manager.py b/manila/volume/manager.py
deleted file mode 100644
index eec670fdfb..0000000000
--- a/manila/volume/manager.py
+++ /dev/null
@@ -1,725 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""
-Volume manager manages creating, attaching, detaching, and persistent storage.
-
-Persistent storage volumes keep their state independent of instances.  You can
-attach to an instance, terminate the instance, spawn a new instance (even
-one from a different image) and re-attach the volume with the same data
-intact.
-
-**Related Flags**
-
-:volume_topic:  What :mod:`rpc` topic to listen to (default: `manila-volume`).
-:volume_manager:  The module name of a class derived from
-                  :class:`manager.Manager` (default:
-                  :class:`manila.volume.manager.Manager`).
-:volume_driver:  Used by :class:`Manager`.  Defaults to
-                 :class:`manila.volume.drivers.lvm.LVMISCSIDriver`.
-:volume_group:  Name of the group that will contain exported volumes (default:
-                `manila-volumes`)
-:num_shell_tries:  Number of times to attempt to run commands (default: 3)
-
-"""
-
-
-import sys
-import traceback
-
-from oslo.config import cfg
-
-from manila import context
-from manila import exception
-from manila.image import glance
-from manila import manager
-from manila.openstack.common import excutils
-from manila.openstack.common import importutils
-from manila.openstack.common import log as logging
-from manila.openstack.common import timeutils
-from manila.openstack.common import uuidutils
-from manila import quota
-from manila import utils
-from manila.volume.configuration import Configuration
-from manila.volume import utils as volume_utils
-
-LOG = logging.getLogger(__name__)
-
-QUOTAS = quota.QUOTAS
-
-volume_manager_opts = [
-    cfg.StrOpt('volume_driver',
-               default='manila.volume.drivers.lvm.LVMISCSIDriver',
-               help='Driver to use for volume creation'),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(volume_manager_opts)
-
-MAPPING = {
-    'manila.volume.driver.RBDDriver': 'manila.volume.drivers.rbd.RBDDriver',
-    'manila.volume.driver.SheepdogDriver':
-    'manila.volume.drivers.sheepdog.SheepdogDriver',
-    'manila.volume.nexenta.volume.NexentaDriver':
-    'manila.volume.drivers.nexenta.volume.NexentaDriver',
-    'manila.volume.san.SanISCSIDriver':
-    'manila.volume.drivers.san.san.SanISCSIDriver',
-    'manila.volume.san.SolarisISCSIDriver':
-    'manila.volume.drivers.san.solaris.SolarisISCSIDriver',
-    'manila.volume.san.HpSanISCSIDriver':
-    'manila.volume.drivers.san.hp_lefthand.HpSanISCSIDriver',
-    'manila.volume.netapp.NetAppISCSIDriver':
-    'manila.volume.drivers.netapp.iscsi.NetAppISCSIDriver',
-    'manila.volume.netapp.NetAppCmodeISCSIDriver':
-    'manila.volume.drivers.netapp.iscsi.NetAppCmodeISCSIDriver',
-    'manila.volume.netapp_nfs.NetAppNFSDriver':
-    'manila.volume.drivers.netapp.nfs.NetAppNFSDriver',
-    'manila.volume.nfs.NfsDriver':
-    'manila.volume.drivers.nfs.NfsDriver',
-    'manila.volume.solidfire.SolidFire':
-    'manila.volume.drivers.solidfire.SolidFire',
-    'manila.volume.storwize_svc.StorwizeSVCDriver':
-    'manila.volume.drivers.storwize_svc.StorwizeSVCDriver',
-    'manila.volume.windows.WindowsDriver':
-    'manila.volume.drivers.windows.WindowsDriver',
-    'manila.volume.xiv.XIVDriver':
-    'manila.volume.drivers.xiv.XIVDriver',
-    'manila.volume.zadara.ZadaraVPSAISCSIDriver':
-    'manila.volume.drivers.zadara.ZadaraVPSAISCSIDriver',
-    'manila.volume.driver.ISCSIDriver':
-    'manila.volume.drivers.lvm.LVMISCSIDriver'}
-
-
-class VolumeManager(manager.SchedulerDependentManager):
-    """Manages attachable block storage devices."""
-
-    RPC_API_VERSION = '1.4'
-
-    def __init__(self, volume_driver=None, service_name=None,
-                 *args, **kwargs):
-        """Load the driver from the one specified in args, or from flags."""
-        self.configuration = Configuration(volume_manager_opts,
-                                           config_group=service_name)
-        if not volume_driver:
-            # Get from configuration, which will get the default
-            # if its not using the multi backend
-            volume_driver = self.configuration.volume_driver
-        if volume_driver in MAPPING:
-            LOG.warn(_("Driver path %s is deprecated, update your "
-                       "configuration to the new path."), volume_driver)
-            volume_driver = MAPPING[volume_driver]
-        self.driver = importutils.import_object(
-            volume_driver,
-            configuration=self.configuration)
-        # update_service_capabilities needs service_name to be volume
-        super(VolumeManager, self).__init__(service_name='volume',
-                                            *args, **kwargs)
-        # NOTE(vish): Implementation specific db handling is done
-        #             by the driver.
-        self.driver.db = self.db
-
-    def init_host(self):
-        """Do any initialization that needs to be run if this is a
-           standalone service."""
-
-        ctxt = context.get_admin_context()
-        self.driver.do_setup(ctxt)
-        self.driver.check_for_setup_error()
-
-        volumes = self.db.volume_get_all_by_host(ctxt, self.host)
-        LOG.debug(_("Re-exporting %s volumes"), len(volumes))
-        for volume in volumes:
-            if volume['status'] in ['available', 'in-use']:
-                self.driver.ensure_export(ctxt, volume)
-            elif volume['status'] == 'downloading':
-                LOG.info(_("volume %s stuck in a downloading state"),
-                         volume['id'])
-                self.driver.clear_download(ctxt, volume)
-                self.db.volume_update(ctxt, volume['id'], {'status': 'error'})
-            else:
-                LOG.info(_("volume %s: skipping export"), volume['name'])
-
-        LOG.debug(_('Resuming any in progress delete operations'))
-        for volume in volumes:
-            if volume['status'] == 'deleting':
-                LOG.info(_('Resuming delete on volume: %s') % volume['id'])
-                self.delete_volume(ctxt, volume['id'])
-
-        # collect and publish service capabilities
-        self.publish_service_capabilities(ctxt)
-
-    def _create_volume(self, context, volume_ref, snapshot_ref,
-                       srcvol_ref, image_service, image_id, image_location):
-        cloned = None
-        model_update = False
-
-        if all(x is None for x in(snapshot_ref, image_id, srcvol_ref)):
-            model_update = self.driver.create_volume(volume_ref)
-        elif snapshot_ref is not None:
-            model_update = self.driver.create_volume_from_snapshot(
-                volume_ref,
-                snapshot_ref)
-        elif srcvol_ref is not None:
-            model_update = self.driver.create_cloned_volume(volume_ref,
-                                                            srcvol_ref)
-        else:
-            # create the volume from an image
-            cloned = self.driver.clone_image(volume_ref, image_location)
-            if not cloned:
-                model_update = self.driver.create_volume(volume_ref)
-
-                updates = dict(model_update or dict(), status='downloading')
-                volume_ref = self.db.volume_update(context,
-                                                   volume_ref['id'],
-                                                   updates)
-
-                self._copy_image_to_volume(context,
-                                           volume_ref,
-                                           image_service,
-                                           image_id)
-
-        return model_update, cloned
-
-    def create_volume(self, context, volume_id, request_spec=None,
-                      filter_properties=None, allow_reschedule=True,
-                      snapshot_id=None, image_id=None, source_volid=None):
-        """Creates and exports the volume."""
-        context = context.elevated()
-        if filter_properties is None:
-            filter_properties = {}
-        volume_ref = self.db.volume_get(context, volume_id)
-        self._notify_about_volume_usage(context, volume_ref, "create.start")
-
-        # NOTE(vish): so we don't have to get volume from db again
-        #             before passing it to the driver.
-        volume_ref['host'] = self.host
-
-        status = 'available'
-        model_update = False
-        image_meta = None
-        cloned = False
-
-        try:
-            vol_name = volume_ref['name']
-            vol_size = volume_ref['size']
-            LOG.debug(_("volume %(vol_name)s: creating lv of"
-                        " size %(vol_size)sG") % locals())
-            snapshot_ref = None
-            sourcevol_ref = None
-            image_service = None
-            image_location = None
-            image_meta = None
-
-            if snapshot_id is not None:
-                LOG.info(_("volume %s: creating from snapshot"),
-                         volume_ref['name'])
-                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
-            elif source_volid is not None:
-                LOG.info(_("volume %s: creating from existing volume"),
-                         volume_ref['name'])
-                sourcevol_ref = self.db.volume_get(context, source_volid)
-            elif image_id is not None:
-                LOG.info(_("volume %s: creating from image"),
-                         volume_ref['name'])
-                # create the volume from an image
-                image_service, image_id = \
-                    glance.get_remote_image_service(context,
-                                                    image_id)
-                image_location = image_service.get_location(context, image_id)
-                image_meta = image_service.show(context, image_id)
-            else:
-                LOG.info(_("volume %s: creating"), volume_ref['name'])
-
-            try:
-                model_update, cloned = self._create_volume(context,
-                                                           volume_ref,
-                                                           snapshot_ref,
-                                                           sourcevol_ref,
-                                                           image_service,
-                                                           image_id,
-                                                           image_location)
-            except Exception:
-                # restore source volume status before reschedule
-                if sourcevol_ref is not None:
-                    self.db.volume_update(context, sourcevol_ref['id'],
-                                          {'status': sourcevol_ref['status']})
-                exc_info = sys.exc_info()
-                # try to re-schedule volume:
-                self._reschedule_or_reraise(context, volume_id, exc_info,
-                                            snapshot_id, image_id,
-                                            request_spec, filter_properties,
-                                            allow_reschedule)
-                return
-
-            if model_update:
-                volume_ref = self.db.volume_update(
-                    context, volume_ref['id'], model_update)
-            if sourcevol_ref is not None:
-                self.db.volume_glance_metadata_copy_from_volume_to_volume(
-                    context,
-                    source_volid,
-                    volume_id)
-
-            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
-            model_update = self.driver.create_export(context, volume_ref)
-            if model_update:
-                self.db.volume_update(context, volume_ref['id'], model_update)
-
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self.db.volume_update(context,
-                                      volume_ref['id'], {'status': 'error'})
-                LOG.error(_("volume %s: create failed"), volume_ref['name'])
-
-        if snapshot_id:
-            # Copy any Glance metadata from the original volume
-            self.db.volume_glance_metadata_copy_to_volume(context,
-                                                          volume_ref['id'],
-                                                          snapshot_id)
-
-        if image_id and not cloned:
-            if image_meta:
-                # Copy all of the Glance image properties to the
-                # volume_glance_metadata table for future reference.
-                self.db.volume_glance_metadata_create(context,
-                                                      volume_ref['id'],
-                                                      'image_id', image_id)
-                name = image_meta.get('name', None)
-                if name:
-                    self.db.volume_glance_metadata_create(context,
-                                                          volume_ref['id'],
-                                                          'image_name', name)
-                image_properties = image_meta.get('properties', {})
-                for key, value in image_properties.items():
-                    self.db.volume_glance_metadata_create(context,
-                                                          volume_ref['id'],
-                                                          key, value)
-
-        now = timeutils.utcnow()
-        self.db.volume_update(context,
-                              volume_ref['id'], {'status': status,
-                                                 'launched_at': now})
-        LOG.info(_("volume %s: created successfully"), volume_ref['name'])
-        self._reset_stats()
-
-        self._notify_about_volume_usage(context, volume_ref, "create.end")
-        return volume_ref['id']
-
-    def _log_original_error(self, exc_info):
-        type_, value, tb = exc_info
-        LOG.error(_('Error: %s') %
-                  traceback.format_exception(type_, value, tb))
-
-    def _reschedule_or_reraise(self, context, volume_id, exc_info,
-                               snapshot_id, image_id, request_spec,
-                               filter_properties, allow_reschedule):
-        """Try to re-schedule the create or re-raise the original error to
-        error out the volume.
-        """
-        if not allow_reschedule:
-            raise exc_info[0], exc_info[1], exc_info[2]
-
-        rescheduled = False
-
-        try:
-            method_args = (CONF.volume_topic, volume_id, snapshot_id,
-                           image_id, request_spec, filter_properties)
-
-            rescheduled = self._reschedule(context, request_spec,
-                                           filter_properties, volume_id,
-                                           self.scheduler_rpcapi.create_volume,
-                                           method_args,
-                                           exc_info)
-
-        except Exception:
-            rescheduled = False
-            LOG.exception(_("volume %s: Error trying to reschedule create"),
-                          volume_id)
-
-        if rescheduled:
-            # log the original build error
-            self._log_original_error(exc_info)
-        else:
-            # not re-scheduling
-            raise exc_info[0], exc_info[1], exc_info[2]
-
-    def _reschedule(self, context, request_spec, filter_properties,
-                    volume_id, scheduler_method, method_args,
-                    exc_info=None):
-        """Attempt to re-schedule a volume operation."""
-
-        retry = filter_properties.get('retry', None)
-        if not retry:
-            # no retry information, do not reschedule.
-            LOG.debug(_("Retry info not present, will not reschedule"))
-            return
-
-        if not request_spec:
-            LOG.debug(_("No request spec, will not reschedule"))
-            return
-
-        request_spec['volume_id'] = volume_id
-
-        LOG.debug(_("volume %(volume_id)s: re-scheduling %(method)s "
-                    "attempt %(num)d") %
-                  {'volume_id': volume_id,
-                   'method': scheduler_method.func_name,
-                   'num': retry['num_attempts']})
-
-        # reset the volume state:
-        now = timeutils.utcnow()
-        self.db.volume_update(context, volume_id,
-                              {'status': 'creating',
-                               'scheduled_at': now})
-
-        if exc_info:
-            # stringify to avoid circular ref problem in json serialization:
-            retry['exc'] = traceback.format_exception(*exc_info)
-
-        scheduler_method(context, *method_args)
-        return True
-
-    def delete_volume(self, context, volume_id):
-        """Deletes and unexports volume."""
-        context = context.elevated()
-        volume_ref = self.db.volume_get(context, volume_id)
-
-        if context.project_id != volume_ref['project_id']:
-            project_id = volume_ref['project_id']
-        else:
-            project_id = context.project_id
-
-        LOG.info(_("volume %s: deleting"), volume_ref['name'])
-        if volume_ref['attach_status'] == "attached":
-            # Volume is still attached, need to detach first
-            raise exception.VolumeAttached(volume_id=volume_id)
-        if volume_ref['host'] != self.host:
-            raise exception.InvalidVolume(
-                reason=_("volume is not local to this node"))
-
-        self._notify_about_volume_usage(context, volume_ref, "delete.start")
-        self._reset_stats()
-        try:
-            LOG.debug(_("volume %s: removing export"), volume_ref['name'])
-            self.driver.remove_export(context, volume_ref)
-            LOG.debug(_("volume %s: deleting"), volume_ref['name'])
-            self.driver.delete_volume(volume_ref)
-        except exception.VolumeIsBusy:
-            LOG.debug(_("volume %s: volume is busy"), volume_ref['name'])
-            self.driver.ensure_export(context, volume_ref)
-            self.db.volume_update(context, volume_ref['id'],
-                                  {'status': 'available'})
-            return True
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self.db.volume_update(context,
-                                      volume_ref['id'],
-                                      {'status': 'error_deleting'})
-
-        # Get reservations
-        try:
-            reservations = QUOTAS.reserve(context,
-                                          project_id=project_id,
-                                          volumes=-1,
-                                          gigabytes=-volume_ref['size'])
-        except Exception:
-            reservations = None
-            LOG.exception(_("Failed to update usages deleting volume"))
-
-        self.db.volume_glance_metadata_delete_by_volume(context, volume_id)
-        self.db.volume_destroy(context, volume_id)
-        LOG.info(_("volume %s: deleted successfully"), volume_ref['name'])
-        self._notify_about_volume_usage(context, volume_ref, "delete.end")
-
-        # Commit the reservations
-        if reservations:
-            QUOTAS.commit(context, reservations, project_id=project_id)
-
-        self.publish_service_capabilities(context)
-
-        return True
-
-    def create_snapshot(self, context, volume_id, snapshot_id):
-        """Creates and exports the snapshot."""
-        context = context.elevated()
-        snapshot_ref = self.db.snapshot_get(context, snapshot_id)
-        LOG.info(_("snapshot %s: creating"), snapshot_ref['name'])
-        self._notify_about_snapshot_usage(
-            context, snapshot_ref, "create.start")
-
-        try:
-            snap_name = snapshot_ref['name']
-            LOG.debug(_("snapshot %(snap_name)s: creating") % locals())
-            model_update = self.driver.create_snapshot(snapshot_ref)
-            if model_update:
-                self.db.snapshot_update(context, snapshot_ref['id'],
-                                        model_update)
-
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self.db.snapshot_update(context,
-                                        snapshot_ref['id'],
-                                        {'status': 'error'})
-
-        self.db.snapshot_update(context,
-                                snapshot_ref['id'], {'status': 'available',
-                                                     'progress': '100%'})
-        self.db.volume_glance_metadata_copy_to_snapshot(context,
-                                                        snapshot_ref['id'],
-                                                        volume_id)
-        LOG.info(_("snapshot %s: created successfully"), snapshot_ref['name'])
-        self._notify_about_snapshot_usage(context, snapshot_ref, "create.end")
-        return snapshot_id
-
-    def delete_snapshot(self, context, snapshot_id):
-        """Deletes and unexports snapshot."""
-        context = context.elevated()
-        snapshot_ref = self.db.snapshot_get(context, snapshot_id)
-        LOG.info(_("snapshot %s: deleting"), snapshot_ref['name'])
-        self._notify_about_snapshot_usage(
-            context, snapshot_ref, "delete.start")
-
-        if context.project_id != snapshot_ref['project_id']:
-            project_id = snapshot_ref['project_id']
-        else:
-            project_id = context.project_id
-
-        try:
-            LOG.debug(_("snapshot %s: deleting"), snapshot_ref['name'])
-            self.driver.delete_snapshot(snapshot_ref)
-        except exception.SnapshotIsBusy:
-            LOG.debug(_("snapshot %s: snapshot is busy"), snapshot_ref['name'])
-            self.db.snapshot_update(context,
-                                    snapshot_ref['id'],
-                                    {'status': 'available'})
-            return True
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self.db.snapshot_update(context,
-                                        snapshot_ref['id'],
-                                        {'status': 'error_deleting'})
-
-        # Get reservations
-        try:
-            if CONF.no_snapshot_gb_quota:
-                reservations = QUOTAS.reserve(context,
-                                              project_id=project_id,
-                                              snapshots=-1)
-            else:
-                reservations = QUOTAS.reserve(
-                    context,
-                    project_id=project_id,
-                    snapshots=-1,
-                    gigabytes=-snapshot_ref['volume_size'])
-        except Exception:
-            reservations = None
-            LOG.exception(_("Failed to update usages deleting snapshot"))
-        self.db.volume_glance_metadata_delete_by_snapshot(context, snapshot_id)
-        self.db.snapshot_destroy(context, snapshot_id)
-        LOG.info(_("snapshot %s: deleted successfully"), snapshot_ref['name'])
-        self._notify_about_snapshot_usage(context, snapshot_ref, "delete.end")
-
-        # Commit the reservations
-        if reservations:
-            QUOTAS.commit(context, reservations, project_id=project_id)
-        return True
-
-    def attach_volume(self, context, volume_id, instance_uuid, mountpoint):
-        """Updates db to show volume is attached"""
-
-        @utils.synchronized(volume_id, external=True)
-        def do_attach():
-            # check the volume status before attaching
-            volume = self.db.volume_get(context, volume_id)
-            if volume['status'] == 'attaching':
-                if (volume['instance_uuid'] and volume['instance_uuid'] !=
-                        instance_uuid):
-                    msg = _("being attached by another instance")
-                    raise exception.InvalidVolume(reason=msg)
-            elif volume['status'] != "available":
-                msg = _("status must be available")
-                raise exception.InvalidVolume(reason=msg)
-            self.db.volume_update(context, volume_id,
-                                  {"instance_uuid": instance_uuid,
-                                   "status": "attaching"})
-
-            # TODO(vish): refactor this into a more general "reserve"
-            # TODO(sleepsonthefloor): Is this 'elevated' appropriate?
-            if not uuidutils.is_uuid_like(instance_uuid):
-                raise exception.InvalidUUID(uuid=instance_uuid)
-
-            try:
-                self.driver.attach_volume(context,
-                                          volume_id,
-                                          instance_uuid,
-                                          mountpoint)
-            except Exception:
-                with excutils.save_and_reraise_exception():
-                    self.db.volume_update(context,
-                                          volume_id,
-                                          {'status': 'error_attaching'})
-
-            self.db.volume_attached(context.elevated(),
-                                    volume_id,
-                                    instance_uuid,
-                                    mountpoint)
-        return do_attach()
-
-    def detach_volume(self, context, volume_id):
-        """Updates db to show volume is detached"""
-        # TODO(vish): refactor this into a more general "unreserve"
-        # TODO(sleepsonthefloor): Is this 'elevated' appropriate?
-        try:
-            self.driver.detach_volume(context, volume_id)
-        except Exception:
-            with excutils.save_and_reraise_exception():
-                self.db.volume_update(context,
-                                      volume_id,
-                                      {'status': 'error_detaching'})
-
-        self.db.volume_detached(context.elevated(), volume_id)
-
-        # Check for https://bugs.launchpad.net/manila/+bug/1065702
-        volume_ref = self.db.volume_get(context, volume_id)
-        if (volume_ref['provider_location'] and
-                volume_ref['name'] not in volume_ref['provider_location']):
-            self.driver.ensure_export(context, volume_ref)
-
-    def _copy_image_to_volume(self, context, volume, image_service, image_id):
-        """Downloads Glance image to the specified volume. """
-        volume_id = volume['id']
-        self.driver.copy_image_to_volume(context, volume,
-                                         image_service,
-                                         image_id)
-        LOG.debug(_("Downloaded image %(image_id)s to %(volume_id)s "
-                    "successfully") % locals())
-
-    def copy_volume_to_image(self, context, volume_id, image_meta):
-        """Uploads the specified volume to Glance.
-
-        image_meta is a dictionary containing the following keys:
-        'id', 'container_format', 'disk_format'
-
-        """
-        payload = {'volume_id': volume_id, 'image_id': image_meta['id']}
-        try:
-            volume = self.db.volume_get(context, volume_id)
-            self.driver.ensure_export(context.elevated(), volume)
-            image_service, image_id = \
-                glance.get_remote_image_service(context, image_meta['id'])
-            self.driver.copy_volume_to_image(context, volume, image_service,
-                                             image_meta)
-            LOG.debug(_("Uploaded volume %(volume_id)s to "
-                        "image (%(image_id)s) successfully") % locals())
-        except Exception, error:
-            with excutils.save_and_reraise_exception():
-                payload['message'] = unicode(error)
-        finally:
-            if volume['instance_uuid'] is None:
-                self.db.volume_update(context, volume_id,
-                                      {'status': 'available'})
-            else:
-                self.db.volume_update(context, volume_id,
-                                      {'status': 'in-use'})
-
-    def initialize_connection(self, context, volume_id, connector):
-        """Prepare volume for connection from host represented by connector.
-
-        This method calls the driver initialize_connection and returns
-        it to the caller.  The connector parameter is a dictionary with
-        information about the host that will connect to the volume in the
-        following format::
-
-            {
-                'ip': ip,
-                'initiator': initiator,
-            }
-
-        ip: the ip address of the connecting machine
-
-        initiator: the iscsi initiator name of the connecting machine.
-        This can be None if the connecting machine does not support iscsi
-        connections.
-
-        driver is responsible for doing any necessary security setup and
-        returning a connection_info dictionary in the following format::
-
-            {
-                'driver_volume_type': driver_volume_type,
-                'data': data,
-            }
-
-        driver_volume_type: a string to identify the type of volume.  This
-                           can be used by the calling code to determine the
-                           strategy for connecting to the volume. This could
-                           be 'iscsi', 'rbd', 'sheepdog', etc.
-
-        data: this is the data that the calling code will use to connect
-              to the volume. Keep in mind that this will be serialized to
-              json in various places, so it should not contain any non-json
-              data types.
-        """
-        volume_ref = self.db.volume_get(context, volume_id)
-        return self.driver.initialize_connection(volume_ref, connector)
-
-    def terminate_connection(self, context, volume_id, connector, force=False):
-        """Cleanup connection from host represented by connector.
-
-        The format of connector is the same as for initialize_connection.
-        """
-        volume_ref = self.db.volume_get(context, volume_id)
-        self.driver.terminate_connection(volume_ref, connector, force=force)
-
-    @manager.periodic_task
-    def _report_driver_status(self, context):
-        LOG.info(_("Updating volume status"))
-        volume_stats = self.driver.get_volume_stats(refresh=True)
-        if volume_stats:
-            # This will grab info about the host and queue it
-            # to be sent to the Schedulers.
-            self.update_service_capabilities(volume_stats)
-
-    def publish_service_capabilities(self, context):
-        """ Collect driver status and then publish """
-        self._report_driver_status(context)
-        self._publish_service_capabilities(context)
-
-    def _reset_stats(self):
-        LOG.info(_("Clear capabilities"))
-        self._last_volume_stats = []
-
-    def notification(self, context, event):
-        LOG.info(_("Notification {%s} received"), event)
-        self._reset_stats()
-
-    def _notify_about_volume_usage(self,
-                                   context,
-                                   volume,
-                                   event_suffix,
-                                   extra_usage_info=None):
-        volume_utils.notify_about_volume_usage(
-            context, volume, event_suffix,
-            extra_usage_info=extra_usage_info, host=self.host)
-
-    def _notify_about_snapshot_usage(self,
-                                     context,
-                                     snapshot,
-                                     event_suffix,
-                                     extra_usage_info=None):
-        volume_utils.notify_about_snapshot_usage(
-            context, snapshot, event_suffix,
-            extra_usage_info=extra_usage_info, host=self.host)
diff --git a/manila/volume/rpcapi.py b/manila/volume/rpcapi.py
deleted file mode 100644
index c3fdc86ee1..0000000000
--- a/manila/volume/rpcapi.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Intel, Inc.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-Client side of the volume RPC API.
-"""
-
-from manila import exception
-from manila import flags
-from manila.openstack.common import rpc
-import manila.openstack.common.rpc.proxy
-
-
-FLAGS = flags.FLAGS
-
-
-class VolumeAPI(manila.openstack.common.rpc.proxy.RpcProxy):
-    '''Client side of the volume rpc API.
-
-    API version history:
-
-        1.0 - Initial version.
-        1.1 - Adds clone volume option to create_volume.
-        1.2 - Add publish_service_capabilities() method.
-        1.3 - Pass all image metadata (not just ID) in copy_volume_to_image
-        1.4 - Add request_spec, filter_properties and
-              allow_reschedule arguments to create_volume().
-    '''
-
-    BASE_RPC_API_VERSION = '1.0'
-
-    def __init__(self, topic=None):
-        super(VolumeAPI, self).__init__(
-            topic=topic or FLAGS.volume_topic,
-            default_version=self.BASE_RPC_API_VERSION)
-
-    def create_volume(self, ctxt, volume, host,
-                      request_spec, filter_properties,
-                      allow_reschedule=True,
-                      snapshot_id=None, image_id=None,
-                      source_volid=None):
-        self.cast(ctxt,
-                  self.make_msg('create_volume',
-                                volume_id=volume['id'],
-                                request_spec=request_spec,
-                                filter_properties=filter_properties,
-                                allow_reschedule=allow_reschedule,
-                                snapshot_id=snapshot_id,
-                                image_id=image_id,
-                                source_volid=source_volid),
-                  topic=rpc.queue_get_for(ctxt,
-                                          self.topic,
-                                          host),
-                  version='1.4')
-
-    def delete_volume(self, ctxt, volume):
-        self.cast(ctxt,
-                  self.make_msg('delete_volume',
-                                volume_id=volume['id']),
-                  topic=rpc.queue_get_for(ctxt, self.topic, volume['host']))
-
-    def create_snapshot(self, ctxt, volume, snapshot):
-        self.cast(ctxt, self.make_msg('create_snapshot',
-                                      volume_id=volume['id'],
-                                      snapshot_id=snapshot['id']),
-                  topic=rpc.queue_get_for(ctxt, self.topic, volume['host']))
-
-    def delete_snapshot(self, ctxt, snapshot, host):
-        self.cast(ctxt, self.make_msg('delete_snapshot',
-                                      snapshot_id=snapshot['id']),
-                  topic=rpc.queue_get_for(ctxt, self.topic, host))
-
-    def attach_volume(self, ctxt, volume, instance_uuid, mountpoint):
-        return self.call(ctxt, self.make_msg('attach_volume',
-                                             volume_id=volume['id'],
-                                             instance_uuid=instance_uuid,
-                                             mountpoint=mountpoint),
-                         topic=rpc.queue_get_for(ctxt,
-                                                 self.topic,
-                                                 volume['host']))
-
-    def detach_volume(self, ctxt, volume):
-        return self.call(ctxt, self.make_msg('detach_volume',
-                                             volume_id=volume['id']),
-                         topic=rpc.queue_get_for(ctxt,
-                                                 self.topic,
-                                                 volume['host']))
-
-    def copy_volume_to_image(self, ctxt, volume, image_meta):
-        self.cast(ctxt, self.make_msg('copy_volume_to_image',
-                                      volume_id=volume['id'],
-                                      image_meta=image_meta),
-                  topic=rpc.queue_get_for(ctxt,
-                                          self.topic,
-                                          volume['host']),
-                  version='1.3')
-
-    def initialize_connection(self, ctxt, volume, connector):
-        return self.call(ctxt, self.make_msg('initialize_connection',
-                                             volume_id=volume['id'],
-                                             connector=connector),
-                         topic=rpc.queue_get_for(ctxt,
-                                                 self.topic,
-                                                 volume['host']))
-
-    def terminate_connection(self, ctxt, volume, connector, force=False):
-        return self.call(ctxt, self.make_msg('terminate_connection',
-                                             volume_id=volume['id'],
-                                             connector=connector,
-                                             force=force),
-                         topic=rpc.queue_get_for(ctxt,
-                                                 self.topic,
-                                                 volume['host']))
-
-    def publish_service_capabilities(self, ctxt):
-        self.fanout_cast(ctxt, self.make_msg('publish_service_capabilities'),
-                         version='1.2')
diff --git a/manila/volume/utils.py b/manila/volume/utils.py
deleted file mode 100644
index 9e80b71d3b..0000000000
--- a/manila/volume/utils.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 OpenStack, LLC.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""Volume-related Utilities and helpers."""
-
-import os
-import stat
-
-from manila import flags
-from manila.openstack.common import log as logging
-from manila.openstack.common.notifier import api as notifier_api
-from manila.openstack.common import timeutils
-from manila import utils
-
-
-FLAGS = flags.FLAGS
-LOG = logging.getLogger(__name__)
-
-
-def get_host_from_queue(queuename):
-    # This assumes the queue is named something like manila-volume
-    # and does not have dot separators in the queue name
-    return queuename.split('@', 1)[0].split('.', 1)[1]
-
-
-def notify_usage_exists(context, volume_ref, current_period=False):
-    """ Generates 'exists' notification for a volume for usage auditing
-        purposes.
-
-        Generates usage for last completed period, unless 'current_period'
-        is True."""
-    begin, end = utils.last_completed_audit_period()
-    if current_period:
-        audit_start = end
-        audit_end = timeutils.utcnow()
-    else:
-        audit_start = begin
-        audit_end = end
-
-    extra_usage_info = dict(audit_period_beginning=str(audit_start),
-                            audit_period_ending=str(audit_end))
-
-    notify_about_volume_usage(context, volume_ref,
-                              'exists', extra_usage_info=extra_usage_info)
-
-
-def null_safe_str(s):
-    return str(s) if s else ''
-
-
-def _usage_from_volume(context, volume_ref, **kw):
-    usage_info = dict(tenant_id=volume_ref['project_id'],
-                      user_id=volume_ref['user_id'],
-                      availability_zone=volume_ref['availability_zone'],
-                      volume_id=volume_ref['id'],
-                      volume_type=volume_ref['volume_type_id'],
-                      display_name=volume_ref['display_name'],
-                      launched_at=null_safe_str(volume_ref['launched_at']),
-                      created_at=null_safe_str(volume_ref['created_at']),
-                      status=volume_ref['status'],
-                      snapshot_id=volume_ref['snapshot_id'],
-                      size=volume_ref['size'])
-
-    usage_info.update(kw)
-    return usage_info
-
-
-def notify_about_volume_usage(context, volume, event_suffix,
-                              extra_usage_info=None, host=None):
-    if not host:
-        host = FLAGS.host
-
-    if not extra_usage_info:
-        extra_usage_info = {}
-
-    usage_info = _usage_from_volume(context, volume, **extra_usage_info)
-
-    notifier_api.notify(context, 'volume.%s' % host,
-                        'volume.%s' % event_suffix,
-                        notifier_api.INFO, usage_info)
-
-
-def _usage_from_snapshot(context, snapshot_ref, **extra_usage_info):
-    usage_info = {
-        'tenant_id': snapshot_ref['project_id'],
-        'user_id': snapshot_ref['user_id'],
-        'availability_zone': snapshot_ref.volume['availability_zone'],
-        'volume_id': snapshot_ref['volume_id'],
-        'volume_size': snapshot_ref['volume_size'],
-        'snapshot_id': snapshot_ref['id'],
-        'display_name': snapshot_ref['display_name'],
-        'created_at': str(snapshot_ref['created_at']),
-        'status': snapshot_ref['status'],
-        'deleted': null_safe_str(snapshot_ref['deleted'])
-    }
-
-    usage_info.update(extra_usage_info)
-    return usage_info
-
-
-def notify_about_snapshot_usage(context, snapshot, event_suffix,
-                                extra_usage_info=None, host=None):
-    if not host:
-        host = FLAGS.host
-
-    if not extra_usage_info:
-        extra_usage_info = {}
-
-    usage_info = _usage_from_snapshot(context, snapshot, **extra_usage_info)
-
-    notifier_api.notify(context, 'snapshot.%s' % host,
-                        'snapshot.%s' % event_suffix,
-                        notifier_api.INFO, usage_info)
-
-
-def is_block(path):
-    mode = os.stat(path).st_mode
-    return stat.S_ISBLK(mode)
diff --git a/manila/volume/volume_types.py b/manila/volume/volume_types.py
deleted file mode 100644
index 3a4cd86bf5..0000000000
--- a/manila/volume/volume_types.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2011 Zadara Storage Inc.
-# Copyright (c) 2011 OpenStack LLC.
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright (c) 2010 Citrix Systems, Inc.
-# Copyright 2011 Ken Pepple
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""Built-in volume type properties."""
-
-from manila import context
-from manila import db
-from manila import exception
-from manila import flags
-from manila.openstack.common import log as logging
-
-FLAGS = flags.FLAGS
-LOG = logging.getLogger(__name__)
-
-
-def create(context, name, extra_specs={}):
-    """Creates volume types."""
-    try:
-        type_ref = db.volume_type_create(context,
-                                         dict(name=name,
-                                              extra_specs=extra_specs))
-    except exception.DBError, e:
-        LOG.exception(_('DB error: %s') % e)
-        raise exception.VolumeTypeCreateFailed(name=name,
-                                               extra_specs=extra_specs)
-    return type_ref
-
-
-def destroy(context, id):
-    """Marks volume types as deleted."""
-    if id is None:
-        msg = _("id cannot be None")
-        raise exception.InvalidVolumeType(reason=msg)
-    else:
-        db.volume_type_destroy(context, id)
-
-
-def get_all_types(context, inactive=0, search_opts={}):
-    """Get all non-deleted volume_types.
-
-    Pass true as argument if you want deleted volume types returned also.
-
-    """
-    vol_types = db.volume_type_get_all(context, inactive)
-
-    if search_opts:
-        LOG.debug(_("Searching by: %s") % str(search_opts))
-
-        def _check_extra_specs_match(vol_type, searchdict):
-            for k, v in searchdict.iteritems():
-                if (k not in vol_type['extra_specs'].keys()
-                    or vol_type['extra_specs'][k] != v):
-                    return False
-            return True
-
-        # search_option to filter_name mapping.
-        filter_mapping = {'extra_specs': _check_extra_specs_match}
-
-        result = {}
-        for type_name, type_args in vol_types.iteritems():
-            # go over all filters in the list
-            for opt, values in search_opts.iteritems():
-                try:
-                    filter_func = filter_mapping[opt]
-                except KeyError:
-                    # no such filter - ignore it, go to next filter
-                    continue
-                else:
-                    if filter_func(type_args, values):
-                        result[type_name] = type_args
-                        break
-        vol_types = result
-    return vol_types
-
-
-def get_volume_type(ctxt, id):
-    """Retrieves single volume type by id."""
-    if id is None:
-        msg = _("id cannot be None")
-        raise exception.InvalidVolumeType(reason=msg)
-
-    if ctxt is None:
-        ctxt = context.get_admin_context()
-
-    return db.volume_type_get(ctxt, id)
-
-
-def get_volume_type_by_name(context, name):
-    """Retrieves single volume type by name."""
-    if name is None:
-        msg = _("name cannot be None")
-        raise exception.InvalidVolumeType(reason=msg)
-
-    return db.volume_type_get_by_name(context, name)
-
-
-def get_default_volume_type():
-    """Get the default volume type."""
-    name = FLAGS.default_volume_type
-    vol_type = {}
-
-    if name is not None:
-        ctxt = context.get_admin_context()
-        try:
-            vol_type = get_volume_type_by_name(ctxt, name)
-        except exception.VolumeTypeNotFoundByName, e:
-            # Couldn't find volume type with the name in default_volume_type
-            # flag, record this issue and move on
-            #TODO(zhiteng) consider add notification to warn admin
-            LOG.exception(_('Default volume type is not found, '
-                            'please check default_volume_type config: %s'), e)
-
-    return vol_type
-
-
-def is_key_value_present(volume_type_id, key, value, volume_type=None):
-    if volume_type_id is None:
-        return False
-
-    if volume_type is None:
-        volume_type = get_volume_type(context.get_admin_context(),
-                                      volume_type_id)
-    if (volume_type.get('extra_specs') is None or
-        volume_type['extra_specs'].get(key) != value):
-        return False
-    else:
-        return True
-
-
-def get_volume_type_extra_specs(volume_type_id, key=False):
-    volume_type = get_volume_type(context.get_admin_context(),
-                                  volume_type_id)
-    extra_specs = volume_type['extra_specs']
-    if key:
-        if extra_specs.get(key):
-            return extra_specs.get(key)
-        else:
-            return False
-    else:
-        return extra_specs