Make the nbd mounter respect CONF.max_nbd_devices.
We need to wait for the config parser to have been run before we query the value of the max_nbd_devices flag. We will always get the default value with the previous implementation. Based on a conversation with Robert Collins. Resolves bug 1088073. Change-Id: If7b5d6a5c7d8153530e97532aad67c42e744ffec
This commit is contained in:
parent
0e6d3a8826
commit
260dd4f1c7
|
@ -0,0 +1,16 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 Michael Still
|
||||
# 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.
|
|
@ -0,0 +1,87 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 Michael Still
|
||||
# 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 fixtures
|
||||
import os
|
||||
|
||||
from nova import test
|
||||
|
||||
from nova.openstack.common import cfg
|
||||
from nova.virt.disk.mount import nbd
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('max_nbd_devices', 'nova.virt.disk.mount.nbd')
|
||||
|
||||
|
||||
class NbdTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(NbdTestCase, self).setUp()
|
||||
self.flags(max_nbd_devices=2)
|
||||
nbd.NbdMount._DEVICES_INITIALIZED = False
|
||||
nbd.NbdMount._DEVICES = []
|
||||
|
||||
def test_nbd_initialize(self):
|
||||
tempdir = self.useFixture(fixtures.TempDir()).path
|
||||
n = nbd.NbdMount(None, tempdir)
|
||||
self.assertTrue(n._DEVICES_INITIALIZED)
|
||||
self.assertEquals(['/dev/nbd0', '/dev/nbd1'], nbd.NbdMount._DEVICES)
|
||||
|
||||
def test_nbd_not_loaded(self):
|
||||
orig_exists = os.path.exists
|
||||
tempdir = self.useFixture(fixtures.TempDir()).path
|
||||
n = nbd.NbdMount(None, tempdir)
|
||||
|
||||
# Fake out os.path.exists
|
||||
def fake_exists(path):
|
||||
if path.startswith('/sys/block/nbd'):
|
||||
return False
|
||||
return orig_exists(path)
|
||||
self.useFixture(fixtures.MonkeyPatch('os.path.exists', fake_exists))
|
||||
|
||||
# This should fail, as we don't have the module "loaded"
|
||||
# TODO(mikal): work out how to force english as the gettext language
|
||||
# so that the error check always passes
|
||||
self.assertEquals(None, n._allocate_nbd())
|
||||
self.assertEquals('nbd unavailable: module not loaded', n.error)
|
||||
|
||||
# And no device should be consumed
|
||||
self.assertEquals(['/dev/nbd0', '/dev/nbd1'], nbd.NbdMount._DEVICES)
|
||||
|
||||
def test_nbd_allocation(self):
|
||||
orig_exists = os.path.exists
|
||||
tempdir = self.useFixture(fixtures.TempDir()).path
|
||||
n = nbd.NbdMount(None, tempdir)
|
||||
|
||||
# Fake out os.path.exists
|
||||
def fake_exists(path):
|
||||
if path.startswith('/sys/block/nbd'):
|
||||
if path.endswith('pid'):
|
||||
return False
|
||||
return True
|
||||
return orig_exists(path)
|
||||
self.useFixture(fixtures.MonkeyPatch('os.path.exists', fake_exists))
|
||||
|
||||
# Allocate a nbd device
|
||||
d = n._allocate_nbd()
|
||||
self.assertEquals('/dev/nbd1', d)
|
||||
self.assertEquals(1, len(nbd.NbdMount._DEVICES))
|
||||
|
||||
# Allocate another
|
||||
d = n._allocate_nbd()
|
||||
self.assertEquals('/dev/nbd0', d)
|
||||
self.assertEquals([], nbd.NbdMount._DEVICES)
|
|
@ -52,17 +52,33 @@ class NbdMount(api.Mount):
|
|||
# are no free devices. Note that patch currently hardcodes 16 devices.
|
||||
# We might be able to alleviate problem 2. by scanning /proc/partitions
|
||||
# like the aformentioned patch does.
|
||||
_DEVICES = ['/dev/nbd%s' % i for i in range(CONF.max_nbd_devices)]
|
||||
|
||||
_DEVICES_INITIALIZED = False
|
||||
_DEVICES = None
|
||||
|
||||
def __init__(self, image, mount_dir, partition=None, device=None):
|
||||
super(NbdMount, self).__init__(image, mount_dir, partition=partition,
|
||||
device=device)
|
||||
|
||||
# NOTE(mikal): this must be done here, because we need configuration
|
||||
# to have been parsed before we initialize. Note the scoping to ensure
|
||||
# we're updating the class scoped variables.
|
||||
if not self._DEVICES_INITIALIZED:
|
||||
NbdMount._DEVICES = ['/dev/nbd%s' % i for
|
||||
i in range(CONF.max_nbd_devices)]
|
||||
NbdMount._DEVICES_INITIALIZED = True
|
||||
|
||||
def _allocate_nbd(self):
|
||||
if not os.path.exists("/sys/block/nbd0"):
|
||||
self.error = _('nbd unavailable: module not loaded')
|
||||
return None
|
||||
|
||||
while True:
|
||||
if not self._DEVICES:
|
||||
# really want to log this info, not raise
|
||||
self.error = _('No free nbd devices')
|
||||
return None
|
||||
|
||||
device = self._DEVICES.pop()
|
||||
if not os.path.exists("/sys/block/%s/pid" %
|
||||
os.path.basename(device)):
|
||||
|
@ -80,6 +96,7 @@ class NbdMount(api.Mount):
|
|||
device = self._allocate_nbd()
|
||||
if not device:
|
||||
return False
|
||||
|
||||
LOG.debug(_("Get nbd device %(dev)s for %(imgfile)s") %
|
||||
{'dev': device, 'imgfile': self.image})
|
||||
_out, err = utils.trycmd('qemu-nbd', '-c', device, self.image,
|
||||
|
|
Loading…
Reference in New Issue