from cinder.brick.initiator import host_driver
from cinder.brick.initiator import linuxfc
from cinder.brick.initiator import linuxscsi
+from cinder.brick.remotefs import remotefs
from cinder.openstack.common.gettextutils import _
from cinder.openstack.common import lockutils
from cinder.openstack.common import log as logging
return AoEConnector(execute=execute,
driver=driver,
root_helper=root_helper)
+ elif protocol == "NFS" or protocol == "GLUSTERFS":
+ return RemoteFsConnector(mount_type=protocol.lower(),
+ execute=execute,
+ driver=driver,
+ root_helper=root_helper)
else:
msg = (_("Invalid InitiatorConnector protocol "
"specified %(protocol)s") %
check_exit_code=0)
LOG.debug(_('aoe-flush %(dev)s: stdout=%(out)s stderr%(err)s') %
{'dev': aoe_device, 'out': out, 'err': err})
+
+
+class RemoteFsConnector(InitiatorConnector):
+ """Connector class to attach/detach NFS and GlusterFS volumes."""
+
+ def __init__(self, mount_type, root_helper, driver=None,
+ execute=putils.execute, *args, **kwargs):
+ self._remotefsclient = remotefs.RemoteFsClient(mount_type,
+ execute, root_helper)
+ super(RemoteFsConnector, self).__init__(driver, execute, root_helper,
+ *args, **kwargs)
+
+ def set_execute(self, execute):
+ super(RemoteFsConnector, self).set_execute(execute)
+ self._remotefsclient.set_execute(execute)
+
+ def connect_volume(self, connection_properties):
+ """Ensure that the filesystem containing the volume is mounted.
+
+ connection_properties must include:
+ export - remote filesystem device (e.g. '172.18.194.100:/var/nfs')
+ name - file name within the filesystem
+
+ connection_properties may optionally include:
+ options - options to pass to mount
+ """
+
+ mnt_flags = []
+ if 'options' in connection_properties:
+ mnt_flags = connection_properties['options'].split()
+
+ nfs_share = connection_properties['export']
+ self._remotefsclient.mount(nfs_share, mnt_flags)
+ mount_point = self._remotefsclient.get_mount_point(nfs_share)
+
+ path = mount_point + '/' + connection_properties['name']
+
+ return {'path': path}
+
+ def disconnect_volume(self, connection_properties, device_info):
+ """No need to do anything to disconnect a volume in a filesystem."""
+ pass
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2013 OpenStack Foundation
+# 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.
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2013 OpenStack Foundation
+# 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.
+
+"""Remote filesystem client utilities."""
+
+import hashlib
+import os
+
+from oslo.config import cfg
+
+from cinder import exception
+from cinder.openstack.common.gettextutils import _
+from cinder.openstack.common import log as logging
+from cinder.openstack.common import processutils as putils
+
+LOG = logging.getLogger(__name__)
+
+remotefs_client_opts = [
+ cfg.StrOpt('nfs_mount_point_base',
+ default='$state_path/mnt',
+ help='Base dir containing mount points for nfs shares'),
+ cfg.StrOpt('nfs_mount_options',
+ default=None,
+ help='Mount options passed to the nfs client. See section '
+ 'of the nfs man page for details'),
+ cfg.StrOpt('glusterfs_mount_point_base',
+ default='$state_path/mnt',
+ help='Base dir containing mount points for gluster shares'),
+]
+
+CONF = cfg.CONF
+CONF.register_opts(remotefs_client_opts)
+
+
+class RemoteFsClient(object):
+
+ def __init__(self, mount_type, execute=putils.execute,
+ root_helper="sudo", *args, **kwargs):
+
+ self._mount_type = mount_type
+ if mount_type == "nfs":
+ self._mount_base = CONF.nfs_mount_point_base
+ self._mount_options = CONF.nfs_mount_options
+ elif mount_type == "glusterfs":
+ self._mount_base = CONF.glusterfs_mount_point_base
+ self._mount_options = None
+ else:
+ raise exception.ProtocolNotSupported(protocol=mount_type)
+ self.root_helper = root_helper
+ self.set_execute(execute)
+
+ def set_execute(self, execute):
+ self._execute = execute
+
+ def _get_hash_str(self, base_str):
+ """Return a string that represents hash of base_str
+ (in a hex format).
+ """
+ return hashlib.md5(base_str).hexdigest()
+
+ def get_mount_point(self, device_name):
+ """
+ :param device_name: example 172.18.194.100:/var/nfs
+ """
+ return os.path.join(self._mount_base,
+ self._get_hash_str(device_name))
+
+ def _read_mounts(self):
+ (out, err) = self._execute('mount', check_exit_code=0)
+ lines = out.split('\n')
+ mounts = {}
+ for line in lines:
+ tokens = line.split()
+ if 2 < len(tokens):
+ device = tokens[0]
+ mnt_point = tokens[2]
+ mounts[mnt_point] = device
+ return mounts
+
+ def mount(self, nfs_share, flags=None):
+ """Mount NFS share."""
+ mount_path = self.get_mount_point(nfs_share)
+
+ if mount_path in self._read_mounts():
+ LOG.info(_('Already mounted: %s') % mount_path)
+ return
+
+ self._execute('mkdir', '-p', mount_path, check_exit_code=0)
+
+ mnt_cmd = ['mount', '-t', self._mount_type]
+ if self._mount_options is not None:
+ mnt_cmd.extend(['-o', self._mount_options])
+ if flags is not None:
+ mnt_cmd.extend(flags)
+ mnt_cmd.extend([nfs_share, mount_path])
+
+ self._execute(*mnt_cmd, root_helper=self.root_helper,
+ run_as_root=True, check_exit_code=0)
from cinder.brick.initiator import host_driver
from cinder.brick.initiator import linuxfc
from cinder.brick.initiator import linuxscsi
+from cinder.brick.remotefs import remotefs
from cinder.openstack.common import log as logging
from cinder.openstack.common import loopingcall
from cinder.openstack.common import processutils as putils
self.assertTrue(obj.__class__.__name__,
"AoEConnector")
+ obj = connector.InitiatorConnector.factory('nfs', None)
+ self.assertTrue(obj.__class__.__name__,
+ "RemoteFsConnector")
+
+ obj = connector.InitiatorConnector.factory('glusterfs', None)
+ self.assertTrue(obj.__class__.__name__,
+ "RemoteFsConnector")
+
self.assertRaises(ValueError,
connector.InitiatorConnector.factory,
"bogus", None)
self.mox.ReplayAll()
self.connector.disconnect_volume(self.connection_properties, {})
+
+
+class RemoteFsConnectorTestCase(ConnectorTestCase):
+ """Test cases for Remote FS initiator class."""
+ TEST_DEV = '172.18.194.100:/var/nfs'
+ TEST_PATH = '/mnt/test/df0808229363aad55c27da50c38d6328'
+
+ def setUp(self):
+ super(RemoteFsConnectorTestCase, self).setUp()
+ self.mox = mox.Mox()
+ self.connection_properties = {
+ 'export': self.TEST_DEV,
+ 'name': '9c592d52-ce47-4263-8c21-4ecf3c029cdb'}
+ self.connector = connector.RemoteFsConnector('nfs', root_helper='sudo')
+ self.connector._remotefsclient._mount_options = None
+ self.connector._remotefsclient._mount_base = '/mnt/test'
+
+ def tearDown(self):
+ self.mox.VerifyAll()
+ self.mox.UnsetStubs()
+ super(RemoteFsConnectorTestCase, self).tearDown()
+
+ def test_connect_volume(self):
+ """Test the basic connect volume case."""
+ client = self.connector._remotefsclient
+ self.mox.StubOutWithMock(client, '_execute')
+ client._execute('mount',
+ check_exit_code=0).AndReturn(("", ""))
+ client._execute('mkdir', '-p', self.TEST_PATH,
+ check_exit_code=0).AndReturn(("", ""))
+ client._execute('mount', '-t', 'nfs',
+ self.TEST_DEV, self.TEST_PATH,
+ root_helper='sudo', run_as_root=True,
+ check_exit_code=0).AndReturn(("", ""))
+ self.mox.ReplayAll()
+
+ self.connector.connect_volume(self.connection_properties)
+
+ def test_disconnect_volume(self):
+ """Nothing should happen here -- make sure it doesn't blow up."""
+ self.connector.disconnect_volume(self.connection_properties, {})
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# (c) Copyright 2013 OpenStack Foundation
+# 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 mox
+
+from cinder.brick.remotefs import remotefs
+from cinder.openstack.common import log as logging
+from cinder.openstack.common import processutils as putils
+from cinder import test
+
+LOG = logging.getLogger(__name__)
+
+
+class BrickRemoteFsTestCase(test.TestCase):
+ TEST_EXPORT = '1.2.3.4/export1'
+ TEST_MNT_BASE = '/mnt/test'
+ TEST_HASH = '4d664fd43b6ff86d80a4ea969c07b3b9'
+ TEST_MNT_POINT = TEST_MNT_BASE + '/' + TEST_HASH
+
+ def setUp(self):
+ super(BrickRemoteFsTestCase, self).setUp()
+ self._mox = mox.Mox()
+ self._nfsclient = remotefs.RemoteFsClient('nfs')
+ self._nfsclient._mount_options = None
+ self._nfsclient._mount_base = self.TEST_MNT_BASE
+ self.addCleanup(self._mox.UnsetStubs)
+
+ def test_get_hash_str(self):
+ """_get_hash_str should calculation correct value."""
+
+ self.assertEqual(self.TEST_HASH,
+ self._nfsclient._get_hash_str(self.TEST_EXPORT))
+
+ def test_get_mount_point(self):
+ mnt_point = self._nfsclient.get_mount_point(self.TEST_EXPORT)
+ self.assertEqual(mnt_point, self.TEST_MNT_POINT)
+
+ def test_mount_nfs_should_mount_correctly(self):
+ mox = self._mox
+ client = self._nfsclient
+
+ mox.StubOutWithMock(client, '_execute')
+ client._execute('mount', check_exit_code=0).AndReturn(("", ""))
+ client._execute('mkdir', '-p', self.TEST_MNT_POINT,
+ check_exit_code=0).AndReturn(("", ""))
+ client._execute('mount', '-t', 'nfs', self.TEST_EXPORT,
+ self.TEST_MNT_POINT,
+ root_helper='sudo', run_as_root=True,
+ check_exit_code=0).AndReturn(("", ""))
+ mox.ReplayAll()
+
+ client.mount(self.TEST_EXPORT)
+
+ mox.VerifyAll()
+
+ def test_mount_nfs_should_not_remount(self):
+ mox = self._mox
+ client = self._nfsclient
+
+ line = "%s on %s type nfs (rw)\n" % (self.TEST_EXPORT,
+ self.TEST_MNT_POINT)
+ mox.StubOutWithMock(client, '_execute')
+ client._execute('mount', check_exit_code=0).AndReturn((line, ""))
+ mox.ReplayAll()
+
+ client.mount(self.TEST_EXPORT)
+
+ mox.VerifyAll()
class RemoteFsDriverTestCase(test.TestCase):
- TEST_EXPORT = '1.2.3.4/export1'
TEST_FILE_NAME = 'test.txt'
def setUp(self):
mox.VerifyAll()
- def test_get_hash_str(self):
- """_get_hash_str should calculation correct value."""
- drv = self._driver
-
- self.assertEqual('4d664fd43b6ff86d80a4ea969c07b3b9',
- drv._get_hash_str(self.TEST_EXPORT))
-
class NfsDriverTestCase(test.TestCase):
"""Test case for NFS driver."""
self.configuration = mox_lib.MockObject(conf.Configuration)
self.configuration.append_config_values(mox_lib.IgnoreArg())
self.configuration.nfs_shares_config = None
- self.configuration.nfs_mount_options = None
- self.configuration.nfs_mount_point_base = '$state_path/mnt'
self.configuration.nfs_sparsed_volumes = True
self.configuration.nfs_used_ratio = 0.95
self.configuration.nfs_oversub_ratio = 1.0
self._driver = nfs.NfsDriver(configuration=self.configuration)
self._driver.shares = {}
+ self._driver._remotefsclient._mount_options = None
+ self._driver._remotefsclient._mount_base = self.TEST_MNT_POINT_BASE
self.addCleanup(self.stubs.UnsetAll)
self.addCleanup(self._mox.UnsetStubs)
'/mnt/test/2f4f60214cf43c595666dd815f0360a4/volume-123',
drv.local_path(volume))
- def test_mount_nfs_should_mount_correctly(self):
- """_mount_nfs common case usage."""
- mox = self._mox
- drv = self._driver
-
- mox.StubOutWithMock(drv, '_execute')
- drv._execute('mkdir', '-p', self.TEST_MNT_POINT)
- drv._execute('mount', '-t', 'nfs', self.TEST_NFS_EXPORT1,
- self.TEST_MNT_POINT, run_as_root=True)
-
- mox.ReplayAll()
-
- drv._mount_nfs(self.TEST_NFS_EXPORT1, self.TEST_MNT_POINT)
-
- mox.VerifyAll()
-
def test_copy_image_to_volume(self):
"""resize_image common case usage."""
mox = self._mox
mox.VerifyAll()
- def test_mount_nfs_should_suppress_already_mounted_error(self):
- """_mount_nfs should suppress already mounted error if ensure=True
- """
- mox = self._mox
- drv = self._driver
-
- mox.StubOutWithMock(drv, '_execute')
- drv._execute('mkdir', '-p', self.TEST_MNT_POINT)
- drv._execute('mount', '-t', 'nfs', self.TEST_NFS_EXPORT1,
- self.TEST_MNT_POINT, run_as_root=True).\
- AndRaise(putils.ProcessExecutionError(
- stderr='is busy or already mounted'))
-
- mox.ReplayAll()
-
- drv._mount_nfs(self.TEST_NFS_EXPORT1, self.TEST_MNT_POINT, ensure=True)
-
- mox.VerifyAll()
-
- def test_mount_nfs_should_reraise_already_mounted_error(self):
- """_mount_nfs should not suppress already mounted error if ensure=False
- """
- mox = self._mox
- drv = self._driver
-
- mox.StubOutWithMock(drv, '_execute')
- drv._execute('mkdir', '-p', self.TEST_MNT_POINT)
- drv._execute(
- 'mount',
- '-t',
- 'nfs',
- self.TEST_NFS_EXPORT1, self.TEST_MNT_POINT, run_as_root=True).\
- AndRaise(putils.ProcessExecutionError(stderr='is busy or '
- 'already mounted'))
-
- mox.ReplayAll()
-
- self.assertRaises(putils.ProcessExecutionError, drv._mount_nfs,
- self.TEST_NFS_EXPORT1, self.TEST_MNT_POINT,
- ensure=False)
-
- mox.VerifyAll()
-
- def test_mount_nfs_should_create_mountpoint_if_not_yet(self):
- """_mount_nfs should create mountpoint if it doesn't exist."""
- mox = self._mox
- drv = self._driver
-
- mox.StubOutWithMock(drv, '_execute')
- drv._execute('mkdir', '-p', self.TEST_MNT_POINT)
- drv._execute(*([IgnoreArg()] * 5), run_as_root=IgnoreArg())
-
- mox.ReplayAll()
-
- drv._mount_nfs(self.TEST_NFS_EXPORT1, self.TEST_MNT_POINT)
-
- mox.VerifyAll()
-
- def test_mount_nfs_should_not_create_mountpoint_if_already(self):
- """_mount_nfs should not create mountpoint if it already exists."""
- mox = self._mox
- drv = self._driver
-
- mox.StubOutWithMock(drv, '_execute')
- drv._execute('mkdir', '-p', self.TEST_MNT_POINT)
- drv._execute(*([IgnoreArg()] * 5), run_as_root=IgnoreArg())
-
- mox.ReplayAll()
-
- drv._mount_nfs(self.TEST_NFS_EXPORT1, self.TEST_MNT_POINT)
-
- mox.VerifyAll()
-
- def test_get_hash_str(self):
- """_get_hash_str should calculation correct value."""
- drv = self._driver
-
- self.assertEqual('2f4f60214cf43c595666dd815f0360a4',
- drv._get_hash_str(self.TEST_NFS_EXPORT1))
-
def test_get_mount_point_for_share(self):
"""_get_mount_point_for_share should calculate correct value."""
drv = self._driver
mox.VerifyAll()
- def test_ensure_share_mounted(self):
- """_ensure_share_mounted simple use case."""
- mox = self._mox
- drv = self._driver
-
- mox.StubOutWithMock(drv, '_get_mount_point_for_share')
- drv._get_mount_point_for_share(self.TEST_NFS_EXPORT1).\
- AndReturn(self.TEST_MNT_POINT)
-
- mox.StubOutWithMock(drv, '_mount_nfs')
- drv._mount_nfs(self.TEST_NFS_EXPORT1, self.TEST_MNT_POINT, ensure=True)
-
- mox.ReplayAll()
-
- drv._ensure_share_mounted(self.TEST_NFS_EXPORT1)
-
- mox.VerifyAll()
-
def test_ensure_shares_mounted_should_save_mounting_successfully(self):
"""_ensure_shares_mounted should save share if mounted with success."""
mox = self._mox
# under the License.
import errno
+import hashlib
import json
import os
import re
from oslo.config import cfg
+from cinder.brick.remotefs import remotefs
from cinder import db
from cinder import exception
from cinder.image import image_utils
cfg.StrOpt('glusterfs_shares_config',
default='/etc/cinder/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'),
def __init__(self, *args, **kwargs):
super(GlusterfsDriver, self).__init__(*args, **kwargs)
self.configuration.append_config_values(volume_opts)
+ self.configuration.append_config_values(remotefs.remotefs_client_opts)
def do_setup(self, context):
"""Any initialization the volume driver does while starting."""
volume_size=volume_size_for)
return greatest_share
+ def _get_hash_str(self, base_str):
+ """Return a string that represents hash of base_str
+ (in a hex format).
+ """
+ return hashlib.md5(base_str).hexdigest()
+
def _get_mount_point_for_share(self, glusterfs_share):
"""Return mount point for share.
:param glusterfs_share: example 172.18.194.100:/var/glusterfs
# under the License.
import errno
-import hashlib
import os
from oslo.config import cfg
+from cinder.brick.remotefs import remotefs
from cinder import exception
from cinder.image import image_utils
from cinder.openstack.common import log as logging
-from cinder.openstack.common import processutils
+from cinder.openstack.common import processutils as putils
from cinder import units
from cinder.volume import driver
cfg.StrOpt('nfs_shares_config',
default='/etc/cinder/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.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'),
cfg.FloatOpt('nfs_used_ratio',
default=0.95,
help=('Percent of ACTUAL usage of the underlying volume '
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,
"""
try:
self._execute(*cmd, run_as_root=True)
- except processutils.ProcessExecutionError as exc:
+ except putils.ProcessExecutionError as exc:
if ensure and 'already mounted' in exc.stderr:
LOG.warn(_("%s is already mounted"), share)
else:
volume_backend_name = 'Generic_NFS'
VERSION = VERSION
- def __init__(self, *args, **kwargs):
+ def __init__(self, execute=putils.execute, *args, **kwargs):
+ self._remotefsclient = None
super(NfsDriver, self).__init__(*args, **kwargs)
self.configuration.append_config_values(volume_opts)
+ self._remotefsclient = remotefs.RemoteFsClient('nfs', execute)
+
+ def set_execute(self, execute):
+ super(NfsDriver, self).set_execute(execute)
+ if self._remotefsclient:
+ self._remotefsclient.set_execute(execute)
def do_setup(self, context):
"""Any initialization the volume driver does while starting"""
raise
def _ensure_share_mounted(self, nfs_share):
- mount_path = self._get_mount_point_for_share(nfs_share)
- self._mount_nfs(nfs_share, mount_path, ensure=True)
+ mnt_flags = []
+ if self.shares.get(nfs_share) is not None:
+ mnt_flags = self.shares[nfs_share].split()
+ self._remotefsclient.mount(nfs_share, mnt_flags)
def _find_share(self, volume_size_in_gib):
"""Choose NFS share among available ones for given volume size.
return target_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))
+ """Needed by parent class."""
+ return self._remotefsclient.get_mount_point(nfs_share)
def _get_capacity_info(self, nfs_share):
"""Calculate available space on the NFS share.
'*snapshot*', mount_point, run_as_root=True)
total_allocated = float(du.split()[0])
return total_size, total_available, total_allocated
-
- 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])
- if self.shares.get(nfs_share) is not None:
- nfs_cmd.extend(self.shares[nfs_share].split())
- nfs_cmd.extend([nfs_share, mount_path])
-
- self._do_mount(nfs_cmd, ensure, nfs_share)
#volumes_dir=$state_path/volumes
+#
+# Options defined in cinder.brick.remotefs.remotefs
+#
+
+# Base dir containing mount points for nfs shares (string
+# value)
+#nfs_mount_point_base=$state_path/mnt
+
+# Mount options passed to the nfs client. See section of the
+# nfs man page for details (string value)
+#nfs_mount_options=<None>
+
+# Base dir containing mount points for gluster shares (string
+# value)
+#glusterfs_mount_point_base=$state_path/mnt
+
+
#
# Options defined in cinder.common.config
#
# value)
#glusterfs_shares_config=/etc/cinder/glusterfs_shares
-# Base dir containing mount points for gluster shares (string
-# value)
-#glusterfs_mount_point_base=$state_path/mnt
-
# Use du or df for free space calculation (string value)
#glusterfs_disk_util=df
# File with the list of available nfs shares (string value)
#nfs_shares_config=/etc/cinder/nfs_shares
-# Base dir containing mount points for nfs shares (string
-# value)
-#nfs_mount_point_base=$state_path/mnt
-
# 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. (boolean value)
#nfs_sparsed_volumes=true
-# Mount options passed to the nfs client. See section of the
-# nfs man page for details (string value)
-#nfs_mount_options=<None>
-
# Percent of ACTUAL usage of the underlying volume before no
# new volumes can be allocated to the volume destination.
# (floating point value)