Revision 8a69b3a8 lib/bdev.py

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.

Also available in: Unified diff