From: Philipp Marek Date: Thu, 1 Oct 2015 07:58:34 +0000 (+0200) Subject: DRBD: new option "drbdmanage_devs_on_controller". X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=241cba42be31b12c549fe16434199e82f331b20c;p=openstack-build%2Fcinder-build.git DRBD: new option "drbdmanage_devs_on_controller". With this option set the c-vol node will have all volumes accessible, via DRBD-client if no local copy already exists anyway. This is handy for a) debugging b) maintenance c) iSCSI exports and other use cases. Change-Id: Ib347777d2f4bb8b46990d76e138e1dbf13ff95bb --- diff --git a/cinder/tests/unit/test_drbdmanagedrv.py b/cinder/tests/unit/test_drbdmanagedrv.py index c5e82b219..9b964b736 100644 --- a/cinder/tests/unit/test_drbdmanagedrv.py +++ b/cinder/tests/unit/test_drbdmanagedrv.py @@ -161,6 +161,10 @@ class DrbdManageFakeDriver(object): self.calls.append(["restore_snapshot", res, snap, new, rprop, vprops]) return [[mock_dm_exc.DM_SUCCESS, "ack", []]] + def assign(self, host, resource, props): + self.calls.append(["assign", host, resource, props]) + return [[mock_dm_exc.DM_SUCCESS, "ack", []]] + class DrbdManageTestCase(test.TestCase): @@ -215,6 +219,26 @@ class DrbdManageTestCase(test.TestCase): 'created_at': timeutils.utcnow()} dmd = drbdmanagedrv.DrbdManageDriver(configuration=self.configuration) + dmd.drbdmanage_devs_on_controller = False + dmd.odm = DrbdManageFakeDriver() + dmd.create_volume(testvol) + self.assertEqual("create_resource", dmd.odm.calls[0][0]) + self.assertEqual("list_volumes", dmd.odm.calls[1][0]) + self.assertEqual("create_volume", dmd.odm.calls[2][0]) + self.assertEqual(1048576, dmd.odm.calls[2][2]) + self.assertEqual("auto_deploy", dmd.odm.calls[3][0]) + self.assertEqual(len(dmd.odm.calls), 4) + + def test_create_volume_controller_all_vols(self): + testvol = {'project_id': 'testprjid', + 'name': 'testvol', + 'size': 1, + 'id': 'deadbeef-8068-11e4-98c0-5254008ea111', + 'volume_type_id': 'drbdmanage', + 'created_at': timeutils.utcnow()} + + dmd = drbdmanagedrv.DrbdManageDriver(configuration=self.configuration) + dmd.drbdmanage_devs_on_controller = True dmd.odm = DrbdManageFakeDriver() dmd.create_volume(testvol) self.assertEqual("create_resource", dmd.odm.calls[0][0]) @@ -222,6 +246,8 @@ class DrbdManageTestCase(test.TestCase): self.assertEqual("create_volume", dmd.odm.calls[2][0]) self.assertEqual(1048576, dmd.odm.calls[2][2]) self.assertEqual("auto_deploy", dmd.odm.calls[3][0]) + self.assertEqual("assign", dmd.odm.calls[4][0]) + self.assertEqual(len(dmd.odm.calls), 5) def test_delete_volume(self): testvol = {'project_id': 'testprjid', diff --git a/cinder/volume/drivers/drbdmanagedrv.py b/cinder/volume/drivers/drbdmanagedrv.py index aa994f298..464d8a5cc 100644 --- a/cinder/volume/drivers/drbdmanagedrv.py +++ b/cinder/volume/drivers/drbdmanagedrv.py @@ -24,6 +24,7 @@ for more details. """ import six +import socket import uuid from oslo_config import cfg @@ -54,6 +55,13 @@ drbd_opts = [ cfg.StrOpt('drbdmanage_redundancy', default='1', help='Number of nodes that should replicate the data.'), + cfg.BoolOpt('drbdmanage_devs_on_controller', + default=True, + help='''If set, the c-vol node will receive a useable + /dev/drbdX device, even if the actual data is stored on + other nodes only. + This is useful for debugging, maintenance, and to be + able to do the iSCSI export from the c-vol node.''') # TODO(PM): offsite_redundancy? # TODO(PM): choose DRBDmanage storage pool? ] @@ -86,6 +94,10 @@ class DrbdManageDriver(driver.VolumeDriver): self.drbdmanage_dbus_interface = '/interface' self.drbdmanage_redundancy = int(getattr(self.configuration, 'drbdmanage_redundancy', 1)) + self.drbdmanage_devs_on_controller = bool( + getattr(self.configuration, + 'drbdmanage_devs_on_controller', + True)) self.dm_control_vol = ".drbdctrl" # Copied from the LVM driver, see @@ -336,6 +348,14 @@ class DrbdManageDriver(driver.VolumeDriver): 0, True) self._check_result(res) + if self.drbdmanage_devs_on_controller: + # FIXME: Consistency groups, vol# + res = self.call_or_reconnect(self.odm.assign, + socket.gethostname(), + dres, + self.empty_dict) + self._check_result(res, ignore=[dm_exc.DM_EEXIST]) + return 0 def delete_volume(self, volume):