Revision 8a69b3a8
b/Makefile.am | ||
---|---|---|
985 | 985 |
echo "TOOLSDIR = '$(toolsdir)'"; \ |
986 | 986 |
echo "GNT_SCRIPTS = [$(foreach i,$(notdir $(gnt_scripts)),'$(i)',)]"; \ |
987 | 987 |
echo "PKGLIBDIR = '$(pkglibdir)'"; \ |
988 |
echo "DRBD_BARRIERS = $(DRBD_BARRIERS)"; \ |
|
988 |
echo "DRBD_BARRIERS = '$(DRBD_BARRIERS)'"; \ |
|
989 |
echo "DRBD_NO_META_FLUSH = $(DRBD_NO_META_FLUSH)"; \ |
|
989 | 990 |
echo "SYSLOG_USAGE = '$(SYSLOG_USAGE)'"; \ |
990 | 991 |
echo "DAEMONS_GROUP = '$(DAEMONS_GROUP)'"; \ |
991 | 992 |
echo "ADMIN_GROUP = '$(ADMIN_GROUP)'"; \ |
b/configure.ac | ||
---|---|---|
208 | 208 |
# --enable-drbd-barriers |
209 | 209 |
AC_ARG_ENABLE([drbd-barriers], |
210 | 210 |
[AS_HELP_STRING([--enable-drbd-barriers], |
211 |
[enable the DRBD barrier functionality (>= 8.0.12) (default: enabled)])],
|
|
211 |
[enable by default the DRBD barriers functionality (>= 8.0.12) (default: enabled)])],
|
|
212 | 212 |
[[if test "$enableval" != no; then |
213 |
DRBD_BARRIERS=True |
|
213 |
DRBD_BARRIERS=n |
|
214 |
DRBD_NO_META_FLUSH=False |
|
214 | 215 |
else |
215 |
DRBD_BARRIERS=False |
|
216 |
DRBD_BARRIERS=bfd |
|
217 |
DRBD_NO_META_FLUSH=True |
|
216 | 218 |
fi |
217 | 219 |
]], |
218 |
[DRBD_BARRIERS=True]) |
|
220 |
[DRBD_BARRIERS=n |
|
221 |
DRBD_NO_META_FLUSH=False |
|
222 |
]) |
|
219 | 223 |
AC_SUBST(DRBD_BARRIERS, $DRBD_BARRIERS) |
224 |
AC_SUBST(DRBD_NO_META_FLUSH, $DRBD_NO_META_FLUSH) |
|
220 | 225 |
|
221 | 226 |
# --enable-syslog[=no/yes/only] |
222 | 227 |
AC_ARG_ENABLE([syslog], |
b/doc/design-resource-model.rst | ||
---|---|---|
724 | 724 |
| | | |as the meta LVs are | | |
725 | 725 |
| | | |small | | |
726 | 726 |
+--------+-------------+-------------------------+---------------------+------+ |
727 |
|drbd |disk_barriers|What kind of barriers to |Either all enabled or|string|
|
|
727 |
|drbd |disk-barriers|What kind of barriers to |Either all enabled or|string|
|
|
728 | 728 |
| | |*disable* for disks; |all disabled, per | | |
729 | 729 |
| | |either "n" or a string |./configure time | | |
730 | 730 |
| | |containing a subset of |option | | |
731 | 731 |
| | |"bfd" | | | |
732 | 732 |
+--------+-------------+-------------------------+---------------------+------+ |
733 |
|drbd |meta_barriers|Whether barriers are |Handled together with|bool |
|
|
734 |
| | |enabled or not for the |disk_barriers | |
|
|
735 |
| | |meta volume | | |
|
|
733 |
|drbd |meta-barriers|Whether to disable or not|Handled together with|bool |
|
|
734 |
| | |the barriers for the meta|disk-barriers | |
|
|
735 |
| | |volume | | |
|
|
736 | 736 |
+--------+-------------+-------------------------+---------------------+------+ |
737 |
|drbd |resync_rate |The (static) resync rate |Hardcoded in |int |
|
|
737 |
|drbd |resync-rate |The (static) resync rate |Hardcoded in |int |
|
|
738 | 738 |
| | |for drbd, when using the |constants.py, not | | |
739 | 739 |
| | |static syncer, in MiB/s |changeable via Ganeti| | |
740 | 740 |
+--------+-------------+-------------------------+---------------------+------+ |
741 |
|drbd |disk_custom |Free-form string that |Not supported |string|
|
|
741 |
|drbd |disk-custom |Free-form string that |Not supported |string|
|
|
742 | 742 |
| | |will be appended to the | | | |
743 | 743 |
| | |drbdsetup disk command | | | |
744 | 744 |
| | |line, for custom options | | | |
745 | 745 |
| | |not supported by Ganeti | | | |
746 | 746 |
| | |itself | | | |
747 | 747 |
+--------+-------------+-------------------------+---------------------+------+ |
748 |
|drbd |net_custom |Free-form string for |Not supported |string|
|
|
748 |
|drbd |net-custom |Free-form string for |Not supported |string|
|
|
749 | 749 |
| | |custom net setup options | | | |
750 | 750 |
+--------+-------------+-------------------------+---------------------+------+ |
751 | 751 |
|
b/lib/bdev.py | ||
---|---|---|
1103 | 1103 |
# timeout constants |
1104 | 1104 |
_NET_RECONFIG_TIMEOUT = 60 |
1105 | 1105 |
|
1106 |
# command line options for barriers |
|
1107 |
_DISABLE_DISK_OPTION = "--no-disk-barrier" # -a |
|
1108 |
_DISABLE_DRAIN_OPTION = "--no-disk-drain" # -D |
|
1109 |
_DISABLE_FLUSH_OPTION = "--no-disk-flushes" # -i |
|
1110 |
_DISABLE_META_FLUSH_OPTION = "--no-md-flushes" # -m |
|
1111 |
|
|
1106 | 1112 |
def __init__(self, unique_id, children, size, params): |
1107 | 1113 |
if children and children.count(None) > 0: |
1108 | 1114 |
children = [] |
... | ... | |
1344 | 1350 |
info["remote_addr"] == (self._rhost, self._rport)) |
1345 | 1351 |
return retval |
1346 | 1352 |
|
1347 |
@classmethod |
|
1348 |
def _AssembleLocal(cls, minor, backend, meta, size): |
|
1353 |
def _AssembleLocal(self, minor, backend, meta, size): |
|
1349 | 1354 |
"""Configure the local part of a DRBD device. |
1350 | 1355 |
|
1351 | 1356 |
""" |
1352 |
args = ["drbdsetup", cls._DevPath(minor), "disk",
|
|
1357 |
args = ["drbdsetup", self._DevPath(minor), "disk",
|
|
1353 | 1358 |
backend, meta, "0", |
1354 | 1359 |
"-e", "detach", |
1355 | 1360 |
"--create-device"] |
1356 | 1361 |
if size: |
1357 | 1362 |
args.extend(["-d", "%sm" % size]) |
1358 |
if not constants.DRBD_BARRIERS: # disable barriers, if configured so |
|
1359 |
version = cls._GetVersion(cls._GetProcData()) |
|
1360 |
# various DRBD versions support different disk barrier options; |
|
1361 |
# what we aim here is to revert back to the 'drain' method of |
|
1362 |
# disk flushes and to disable metadata barriers, in effect going |
|
1363 |
# back to pre-8.0.7 behaviour |
|
1364 |
vmaj = version["k_major"] |
|
1365 |
vmin = version["k_minor"] |
|
1366 |
vrel = version["k_point"] |
|
1367 |
assert vmaj == 8 |
|
1368 |
if vmin == 0: # 8.0.x |
|
1369 |
if vrel >= 12: |
|
1370 |
args.extend(["-i", "-m"]) |
|
1371 |
elif vmin == 2: # 8.2.x |
|
1372 |
if vrel >= 7: |
|
1373 |
args.extend(["-i", "-m"]) |
|
1374 |
elif vmaj >= 3: # 8.3.x or newer |
|
1375 |
args.extend(["-i", "-a", "m"]) |
|
1363 |
|
|
1364 |
version = self._GetVersion(self._GetProcData()) |
|
1365 |
vmaj = version["k_major"] |
|
1366 |
vmin = version["k_minor"] |
|
1367 |
vrel = version["k_point"] |
|
1368 |
|
|
1369 |
barrier_args = \ |
|
1370 |
self._ComputeDiskBarrierArgs(vmaj, vmin, vrel, |
|
1371 |
self.params[constants.BARRIERS], |
|
1372 |
self.params[constants.NO_META_FLUSH]) |
|
1373 |
args.extend(barrier_args) |
|
1374 |
|
|
1376 | 1375 |
result = utils.RunCmd(args) |
1377 | 1376 |
if result.failed: |
1378 | 1377 |
_ThrowError("drbd%d: can't attach local disk: %s", minor, result.output) |
1379 | 1378 |
|
1379 |
@classmethod |
|
1380 |
def _ComputeDiskBarrierArgs(cls, vmaj, vmin, vrel, disabled_barriers, |
|
1381 |
disable_meta_flush): |
|
1382 |
"""Compute the DRBD command line parameters for disk barriers |
|
1383 |
|
|
1384 |
Returns a list of the disk barrier parameters as requested via the |
|
1385 |
disabled_barriers and disable_meta_flush arguments, and according to the |
|
1386 |
supported ones in the DRBD version vmaj.vmin.vrel |
|
1387 |
|
|
1388 |
If the desired option is unsupported, raises errors.BlockDeviceError. |
|
1389 |
|
|
1390 |
""" |
|
1391 |
disabled_barriers_set = frozenset(disabled_barriers) |
|
1392 |
if not disabled_barriers_set in constants.DRBD_VALID_BARRIER_OPT: |
|
1393 |
raise errors.BlockDeviceError("%s is not a valid option set for DRBD" |
|
1394 |
" barriers" % disabled_barriers) |
|
1395 |
|
|
1396 |
args = [] |
|
1397 |
|
|
1398 |
# The following code assumes DRBD 8.x, with x < 4 and x != 1 (DRBD 8.1.x |
|
1399 |
# does not exist) |
|
1400 |
if not vmaj == 8 and vmin in (0, 2, 3): |
|
1401 |
raise errors.BlockDeviceError("Unsupported DRBD version: %d.%d.%d" % |
|
1402 |
(vmaj, vmin, vrel)) |
|
1403 |
|
|
1404 |
def _AppendOrRaise(option, min_version): |
|
1405 |
"""Helper for DRBD options""" |
|
1406 |
if min_version is not None and vrel >= min_version: |
|
1407 |
args.append(option) |
|
1408 |
else: |
|
1409 |
raise errors.BlockDeviceError("Could not use the option %s as the" |
|
1410 |
" DRBD version %d.%d.%d does not support" |
|
1411 |
" it." % (option, vmaj, vmin, vrel)) |
|
1412 |
|
|
1413 |
# the minimum version for each feature is encoded via pairs of (minor |
|
1414 |
# version -> x) where x is version in which support for the option was |
|
1415 |
# introduced. |
|
1416 |
meta_flush_supported = disk_flush_supported = { |
|
1417 |
0: 12, |
|
1418 |
2: 7, |
|
1419 |
3: 0, |
|
1420 |
} |
|
1421 |
|
|
1422 |
disk_drain_supported = { |
|
1423 |
2: 7, |
|
1424 |
3: 0, |
|
1425 |
} |
|
1426 |
|
|
1427 |
disk_barriers_supported = { |
|
1428 |
3: 0, |
|
1429 |
} |
|
1430 |
|
|
1431 |
# meta flushes |
|
1432 |
if disable_meta_flush: |
|
1433 |
_AppendOrRaise(cls._DISABLE_META_FLUSH_OPTION, |
|
1434 |
meta_flush_supported.get(vmin, None)) |
|
1435 |
|
|
1436 |
# disk flushes |
|
1437 |
if constants.DRBD_B_DISK_FLUSH in disabled_barriers_set: |
|
1438 |
_AppendOrRaise(cls._DISABLE_FLUSH_OPTION, |
|
1439 |
disk_flush_supported.get(vmin, None)) |
|
1440 |
|
|
1441 |
# disk drain |
|
1442 |
if constants.DRBD_B_DISK_DRAIN in disabled_barriers_set: |
|
1443 |
_AppendOrRaise(cls._DISABLE_DRAIN_OPTION, |
|
1444 |
disk_drain_supported.get(vmin, None)) |
|
1445 |
|
|
1446 |
# disk barriers |
|
1447 |
if constants.DRBD_B_DISK_BARRIERS in disabled_barriers_set: |
|
1448 |
_AppendOrRaise(cls._DISABLE_DISK_OPTION, |
|
1449 |
disk_barriers_supported.get(vmin, None)) |
|
1450 |
|
|
1451 |
return args |
|
1452 |
|
|
1380 | 1453 |
def _AssembleNet(self, minor, net_info, protocol, |
1381 | 1454 |
dual_pri=False, hmac=None, secret=None): |
1382 | 1455 |
"""Configure the network part of the device. |
b/lib/cmdlib.py | ||
---|---|---|
8058 | 8058 |
dt_params = disk_params[disk_template] |
8059 | 8059 |
if disk_template == constants.DT_DRBD8: |
8060 | 8060 |
drbd_params = { |
8061 |
constants.RESYNC_RATE: dt_params[constants.DRBD_RESYNC_RATE] |
|
8061 |
constants.RESYNC_RATE: dt_params[constants.DRBD_RESYNC_RATE], |
|
8062 |
constants.BARRIERS: dt_params[constants.DRBD_DISK_BARRIERS], |
|
8063 |
constants.NO_META_FLUSH: dt_params[constants.DRBD_META_BARRIERS], |
|
8062 | 8064 |
} |
8063 | 8065 |
|
8064 | 8066 |
drbd_params = \ |
b/lib/constants.py | ||
---|---|---|
472 | 472 |
# drbd constants |
473 | 473 |
DRBD_HMAC_ALG = "md5" |
474 | 474 |
DRBD_NET_PROTOCOL = "C" |
475 |
DRBD_BARRIERS = _autoconf.DRBD_BARRIERS |
|
475 |
|
|
476 |
# drbd barrier types |
|
477 |
DRBD_B_NONE = "n" |
|
478 |
DRBD_B_DISK_BARRIERS = "b" |
|
479 |
DRBD_B_DISK_DRAIN = "d" |
|
480 |
DRBD_B_DISK_FLUSH = "f" |
|
481 |
|
|
482 |
# Valid barrier combinations: "n" or any non-null subset of "bfd" |
|
483 |
DRBD_VALID_BARRIER_OPT = frozenset([ |
|
484 |
frozenset([DRBD_B_NONE]), |
|
485 |
frozenset([DRBD_B_DISK_BARRIERS]), |
|
486 |
frozenset([DRBD_B_DISK_DRAIN]), |
|
487 |
frozenset([DRBD_B_DISK_FLUSH]), |
|
488 |
frozenset([DRBD_B_DISK_DRAIN, DRBD_B_DISK_FLUSH]), |
|
489 |
frozenset([DRBD_B_DISK_DRAIN, DRBD_B_DISK_FLUSH]), |
|
490 |
frozenset([DRBD_B_DISK_BARRIERS, DRBD_B_DISK_DRAIN]), |
|
491 |
frozenset([DRBD_B_DISK_BARRIERS, DRBD_B_DISK_FLUSH]), |
|
492 |
frozenset([DRBD_B_DISK_BARRIERS, DRBD_B_DISK_FLUSH, DRBD_B_DISK_DRAIN]), |
|
493 |
]) |
|
476 | 494 |
|
477 | 495 |
# file backend driver |
478 | 496 |
FD_LOOP = "loop" |
... | ... | |
898 | 916 |
# Logical Disks parameters |
899 | 917 |
RESYNC_RATE = "resync-rate" |
900 | 918 |
STRIPES = "stripes" |
919 |
BARRIERS = "disabled-barriers" |
|
920 |
NO_META_FLUSH = "disable-meta-flush" |
|
901 | 921 |
DISK_LD_TYPES = { |
902 | 922 |
RESYNC_RATE: VTYPE_INT, |
903 | 923 |
STRIPES: VTYPE_INT, |
924 |
BARRIERS: VTYPE_STRING, |
|
925 |
NO_META_FLUSH: VTYPE_BOOL, |
|
904 | 926 |
} |
905 | 927 |
DISK_LD_PARAMETERS = frozenset(DISK_LD_TYPES.keys()) |
906 | 928 |
|
... | ... | |
908 | 930 |
DRBD_RESYNC_RATE = "resync-rate" |
909 | 931 |
DRBD_DATA_STRIPES = "data-stripes" |
910 | 932 |
DRBD_META_STRIPES = "meta-stripes" |
933 |
DRBD_DISK_BARRIERS = "disk-barriers" |
|
934 |
DRBD_META_BARRIERS = "meta-barriers" |
|
911 | 935 |
LV_STRIPES = "stripes" |
912 | 936 |
DISK_DT_TYPES = { |
913 | 937 |
DRBD_RESYNC_RATE: VTYPE_INT, |
914 | 938 |
DRBD_DATA_STRIPES: VTYPE_INT, |
915 | 939 |
DRBD_META_STRIPES: VTYPE_INT, |
940 |
DRBD_DISK_BARRIERS: VTYPE_STRING, |
|
941 |
DRBD_META_BARRIERS: VTYPE_BOOL, |
|
916 | 942 |
LV_STRIPES: VTYPE_INT, |
917 | 943 |
} |
918 | 944 |
|
... | ... | |
1683 | 1709 |
DISK_LD_DEFAULTS = { |
1684 | 1710 |
LD_DRBD8: { |
1685 | 1711 |
RESYNC_RATE: CLASSIC_DRBD_SYNC_SPEED, |
1712 |
BARRIERS: _autoconf.DRBD_BARRIERS, |
|
1713 |
NO_META_FLUSH: _autoconf.DRBD_NO_META_FLUSH, |
|
1686 | 1714 |
}, |
1687 | 1715 |
LD_LV: { |
1688 | 1716 |
STRIPES: _autoconf.LVM_STRIPECOUNT |
... | ... | |
1701 | 1729 |
DRBD_RESYNC_RATE: DISK_LD_DEFAULTS[LD_DRBD8][RESYNC_RATE], |
1702 | 1730 |
DRBD_DATA_STRIPES: DISK_LD_DEFAULTS[LD_LV][STRIPES], |
1703 | 1731 |
DRBD_META_STRIPES: DISK_LD_DEFAULTS[LD_LV][STRIPES], |
1732 |
DRBD_DISK_BARRIERS: DISK_LD_DEFAULTS[LD_DRBD8][BARRIERS], |
|
1733 |
DRBD_META_BARRIERS: DISK_LD_DEFAULTS[LD_DRBD8][NO_META_FLUSH], |
|
1704 | 1734 |
}, |
1705 | 1735 |
DT_DISKLESS: { |
1706 | 1736 |
}, |
b/test/ganeti.bdev_unittest.py | ||
---|---|---|
27 | 27 |
|
28 | 28 |
from ganeti import bdev |
29 | 29 |
from ganeti import errors |
30 |
from ganeti import constants |
|
30 | 31 |
|
31 | 32 |
import testutils |
32 | 33 |
|
... | ... | |
156 | 157 |
"remote_addr" not in result), |
157 | 158 |
"Should not find network info") |
158 | 159 |
|
160 |
def testBarriersOptions(self): |
|
161 |
"""Test class method that generates drbdsetup options for disk barriers""" |
|
162 |
# Tests that should fail because of wrong version/options combinations |
|
163 |
should_fail = [ |
|
164 |
(8, 0, 12, "bfd", True), |
|
165 |
(8, 0, 12, "fd", False), |
|
166 |
(8, 0, 12, "b", True), |
|
167 |
(8, 2, 7, "bfd", True), |
|
168 |
(8, 2, 7, "b", True) |
|
169 |
] |
|
170 |
|
|
171 |
for vmaj, vmin, vrel, opts, meta in should_fail: |
|
172 |
self.assertRaises(errors.BlockDeviceError, |
|
173 |
bdev.DRBD8._ComputeDiskBarrierArgs, |
|
174 |
vmaj, vmin, vrel, opts, meta) |
|
175 |
|
|
176 |
# get the valid options from the frozenset(frozenset()) in constants. |
|
177 |
valid_options = [list(x)[0] for x in constants.DRBD_VALID_BARRIER_OPT] |
|
178 |
|
|
179 |
# Versions that do not support anything |
|
180 |
for vmaj, vmin, vrel in ((8, 0, 0), (8, 0, 11), (8, 2, 6)): |
|
181 |
for opts in valid_options: |
|
182 |
self.assertRaises(errors.BlockDeviceError, |
|
183 |
bdev.DRBD8._ComputeDiskBarrierArgs, |
|
184 |
vmaj, vmin, vrel, opts, True) |
|
185 |
|
|
186 |
# Versions with partial support (testing only options that are supported) |
|
187 |
tests = [ |
|
188 |
(8, 0, 12, "n", False, []), |
|
189 |
(8, 0, 12, "n", True, ["--no-md-flushes"]), |
|
190 |
(8, 2, 7, "n", False, []), |
|
191 |
(8, 2, 7, "fd", False, ["--no-disk-flushes", "--no-disk-drain"]), |
|
192 |
(8, 0, 12, "n", True, ["--no-md-flushes"]), |
|
193 |
] |
|
194 |
|
|
195 |
# Versions that support everything |
|
196 |
for vmaj, vmin, vrel in ((8, 3, 0), (8, 3, 12)): |
|
197 |
tests.append((vmaj, vmin, vrel, "bfd", True, |
|
198 |
["--no-disk-barrier", "--no-disk-drain", |
|
199 |
"--no-disk-flushes", "--no-md-flushes"])) |
|
200 |
tests.append((vmaj, vmin, vrel, "n", False, [])) |
|
201 |
tests.append((vmaj, vmin, vrel, "b", True, |
|
202 |
["--no-disk-barrier", "--no-md-flushes"])) |
|
203 |
tests.append((vmaj, vmin, vrel, "fd", False, |
|
204 |
["--no-disk-flushes", "--no-disk-drain"])) |
|
205 |
tests.append((vmaj, vmin, vrel, "n", True, ["--no-md-flushes"])) |
|
206 |
|
|
207 |
# Test execution |
|
208 |
for test in tests: |
|
209 |
vmaj, vmin, vrel, disabled_barriers, disable_meta_flush, expected = test |
|
210 |
args = \ |
|
211 |
bdev.DRBD8._ComputeDiskBarrierArgs(vmaj, vmin, vrel, |
|
212 |
disabled_barriers, |
|
213 |
disable_meta_flush) |
|
214 |
self.failUnless(set(args) == set(expected), |
|
215 |
"For test %s, got wrong results %s" % (test, args)) |
|
216 |
|
|
217 |
# Unsupported or invalid versions |
|
218 |
for vmaj, vmin, vrel in ((0, 7, 25), (9, 0, 0), (7, 0, 0), (8, 4, 0)): |
|
219 |
self.assertRaises(errors.BlockDeviceError, |
|
220 |
bdev.DRBD8._ComputeDiskBarrierArgs, |
|
221 |
vmaj, vmin, vrel, "n", True) |
|
222 |
|
|
223 |
# Invalid options |
|
224 |
for option in ("", "c", "whatever", "nbdfc", "nf"): |
|
225 |
self.assertRaises(errors.BlockDeviceError, |
|
226 |
bdev.DRBD8._ComputeDiskBarrierArgs, |
|
227 |
8, 3, 11, option, True) |
|
228 |
|
|
159 | 229 |
|
160 | 230 |
class TestDRBD8Status(testutils.GanetiTestCase): |
161 | 231 |
"""Testing case for DRBD8 /proc status""" |
Also available in: Unified diff