Revision 1063abd1

b/lib/backend.py
1094 1094
  clist = []
1095 1095
  if disk.children:
1096 1096
    for child in disk.children:
1097
      crdev = _RecursiveAssembleBD(child, owner, on_primary)
1097
      try:
1098
        crdev = _RecursiveAssembleBD(child, owner, on_primary)
1099
      except errors.BlockDeviceError, err:
1100
        errmsg = "Can't assemble device %s: %s" % (child, err)
1101
        logging.error(errmsg)
1102
        return False, errmsg
1098 1103
      if on_primary or disk.AssembleOnSecondary():
1099 1104
        # we need the children open in case the device itself has to
1100 1105
        # be assembled
1101
        crdev.Open()
1106
        try:
1107
          crdev.Open()
1108
        except errors.BlockDeviceError, err:
1109
          errmsg = "Can't make child '%s' read-write: %s" (child, err)
1110
          logging.error(errmsg)
1111
          return False, errmsg
1102 1112
      clist.append(crdev)
1103 1113

  
1104 1114
  try:
1105 1115
    device = bdev.Create(disk.dev_type, disk.physical_id, clist, size)
1106
  except errors.GenericError, err:
1116
  except errors.BlockDeviceError, err:
1107 1117
    return False, "Can't create block device: %s" % str(err)
1108 1118

  
1109 1119
  if on_primary or disk.AssembleOnSecondary():
1110
    if not device.Assemble():
1111
      errorstring = "Can't assemble device after creation, very unusual event"
1112
      logging.error(errorstring)
1113
      return False, errorstring
1120
    try:
1121
      device.Assemble()
1122
    except errors.BlockDeviceError, err:
1123
      errmsg = ("Can't assemble device after creation, very"
1124
                " unusual event: %s" % str(err))
1125
      logging.error(errmsg)
1126
      return False, errmsg
1114 1127
    device.SetSyncSpeed(constants.SYNC_SPEED)
1115 1128
    if on_primary or disk.OpenOnSecondary():
1116
      device.Open(force=True)
1129
      try:
1130
        device.Open(force=True)
1131
      except errors.BlockDeviceError, err:
1132
        errmsg = ("Can't make device r/w after creation, very"
1133
                  " unusual event: %s" % str(err))
1134
        logging.error(errmsg)
1135
        return False, errmsg
1117 1136
    DevCacheManager.UpdateCache(device.dev_path, owner,
1118 1137
                                on_primary, disk.iv_name)
1119 1138

  
......
1198 1217
        if children.count(None) >= mcn:
1199 1218
          raise
1200 1219
        cdev = None
1201
        logging.error("Error in child activation: %s", str(err))
1220
        logging.error("Error in child activation (but continuing): %s",
1221
                      str(err))
1202 1222
      children.append(cdev)
1203 1223

  
1204 1224
  if as_primary or disk.AssembleOnSecondary():
......
1225 1245
      C{True} for secondary nodes
1226 1246

  
1227 1247
  """
1228
  status = False
1248
  status = True
1229 1249
  result = "no error information"
1230 1250
  try:
1231 1251
    result = _RecursiveAssembleBD(disk, owner, as_primary)
1232 1252
    if isinstance(result, bdev.BlockDev):
1233 1253
      result = result.dev_path
1234
      status = True
1235
    if result == True:
1236
      status = True
1237 1254
  except errors.BlockDeviceError, err:
1238 1255
    result = "Error while assembling disk: %s" % str(err)
1256
    status = False
1239 1257
  return (status, result)
1240 1258

  
1241 1259

  
b/lib/bdev.py
128 128
        this method is idempotent
129 129

  
130 130
    """
131
    return True
131
    pass
132 132

  
133 133
  def Attach(self):
134 134
    """Find a device which matches our config and attach to it.
......
441 441
    """
442 442
    result = utils.RunCmd(["lvchange", "-ay", self.dev_path])
443 443
    if result.failed:
444
      logging.error("Can't activate lv %s: %s", self.dev_path, result.output)
445
      return False
446
    return self.Attach()
444
      _ThrowError("Can't activate lv %s: %s", self.dev_path, result.output)
447 445

  
448 446
  def Shutdown(self):
449 447
    """Shutdown the device.
......
1034 1032
            backend, meta, "0", "-e", "detach", "--create-device"]
1035 1033
    result = utils.RunCmd(args)
1036 1034
    if result.failed:
1037
      logging.error("Can't attach local disk: %s", result.output)
1038
    return not result.failed
1035
      _ThrowError("drbd%d: can't attach local disk: %s", minor, result.output)
1039 1036

  
1040 1037
  @classmethod
1041 1038
  def _AssembleNet(cls, minor, net_info, protocol,
......
1047 1044
    if None in net_info:
1048 1045
      # we don't want network connection and actually want to make
1049 1046
      # sure its shutdown
1050
      return cls._ShutdownNet(minor)
1047
      cls._ShutdownNet(minor)
1048
      return
1051 1049

  
1052 1050
    # Workaround for a race condition. When DRBD is doing its dance to
1053 1051
    # establish a connection with its peer, it also sends the
......
1069 1067
      args.extend(["-a", hmac, "-x", secret])
1070 1068
    result = utils.RunCmd(args)
1071 1069
    if result.failed:
1072
      logging.error("Can't setup network for dbrd device: %s - %s",
1073
                    result.fail_reason, result.output)
1074
      return False
1070
      _ThrowError("drbd%d: can't setup network: %s - %s",
1071
                  minor, result.fail_reason, result.output)
1075 1072

  
1076 1073
    timeout = time.time() + 10
1077 1074
    ok = False
......
1087 1084
      ok = True
1088 1085
      break
1089 1086
    if not ok:
1090
      logging.error("Timeout while configuring network")
1091
      return False
1092
    return True
1087
      _ThrowError("drbd%d: timeout while configuring network", minor)
1093 1088

  
1094 1089
  def AddChildren(self, devices):
1095 1090
    """Add a disk to the DRBD device.
......
1112 1107
      raise errors.BlockDeviceError("Invalid meta device size")
1113 1108
    self._InitMeta(self._FindUnusedMinor(), meta.dev_path)
1114 1109

  
1115
    if not self._AssembleLocal(self.minor, backend.dev_path, meta.dev_path):
1116
      raise errors.BlockDeviceError("Can't attach to local storage")
1110
    self._AssembleLocal(self.minor, backend.dev_path, meta.dev_path)
1117 1111
    self._children = devices
1118 1112

  
1119 1113
  def RemoveChildren(self, devices):
......
1140 1134
        _ThrowError("drbd%d: mismatch in local storage (%s != %s) in"
1141 1135
                    " RemoveChildren", self.minor, dev, child.dev_path)
1142 1136

  
1143
    if not self._ShutdownLocal(self.minor):
1144
      raise errors.BlockDeviceError("Can't detach from local storage")
1137
    self._ShutdownLocal(self.minor)
1145 1138
    self._children = []
1146 1139

  
1147 1140
  @classmethod
......
1271 1264
      _ThrowError("drbd%d: DRBD disk missing network info in"
1272 1265
                  " DisconnectNet()", self.minor)
1273 1266

  
1274
    ever_disconnected = self._ShutdownNet(self.minor)
1267
    ever_disconnected = _IgnoreError(self._ShutdownNet, self.minor)
1275 1268
    timeout_limit = time.time() + self._NET_RECONFIG_TIMEOUT
1276 1269
    sleep_time = 0.100 # we start the retry time at 100 miliseconds
1277 1270
    while time.time() < timeout_limit:
......
1281 1274
      # retry the disconnect, it seems possible that due to a
1282 1275
      # well-time disconnect on the peer, my disconnect command might
1283 1276
      # be ingored and forgotten
1284
      ever_disconnected = self._ShutdownNet(self.minor) or ever_disconnected
1277
      ever_disconnected = _IgnoreError(self._ShutdownNet, self.minor) or \
1278
                          ever_disconnected
1285 1279
      time.sleep(sleep_time)
1286 1280
      sleep_time = min(2, sleep_time * 1.5)
1287 1281

  
......
1320 1314
    if not status.is_standalone:
1321 1315
      _ThrowError("drbd%d: device is not standalone in AttachNet", self.minor)
1322 1316

  
1323
    return self._AssembleNet(self.minor,
1324
                             (self._lhost, self._lport,
1325
                              self._rhost, self._rport),
1326
                             "C", dual_pri=multimaster)
1317
    self._AssembleNet(self.minor,
1318
                      (self._lhost, self._lport, self._rhost, self._rport),
1319
                      constants.DRBD_NET_PROTOCOL, dual_pri=multimaster,
1320
                      hmac=constants.DRBD_HMAC_ALG, secret=self._secret)
1327 1321

  
1328 1322
  def Attach(self):
1329 1323
    """Check if our minor is configured.
......
1354 1348
      - if not, we create it from zero
1355 1349

  
1356 1350
    """
1357
    result = super(DRBD8, self).Assemble()
1358
    if not result:
1359
      return result
1351
    super(DRBD8, self).Assemble()
1360 1352

  
1361 1353
    self.Attach()
1362 1354
    if self.minor is None:
1363 1355
      # local device completely unconfigured
1364
      return self._FastAssemble()
1356
      self._FastAssemble()
1365 1357
    else:
1366 1358
      # we have to recheck the local and network status and try to fix
1367 1359
      # the device
1368
      return self._SlowAssemble()
1360
      self._SlowAssemble()
1369 1361

  
1370 1362
  def _SlowAssemble(self):
1371 1363
    """Assembles the DRBD device from a (partially) configured device.
......
1375 1367
    the attach if can return success.
1376 1368

  
1377 1369
    """
1370
    net_data = (self._lhost, self._lport, self._rhost, self._rport)
1378 1371
    for minor in (self._aminor,):
1379 1372
      info = self._GetDevInfo(self._GetShowData(minor))
1380 1373
      match_l = self._MatchesLocal(info)
1381 1374
      match_r = self._MatchesNet(info)
1375

  
1382 1376
      if match_l and match_r:
1377
        # everything matches
1383 1378
        break
1379

  
1384 1380
      if match_l and not match_r and "local_addr" not in info:
1385
        res_r = self._AssembleNet(minor,
1386
                                  (self._lhost, self._lport,
1387
                                   self._rhost, self._rport),
1388
                                  constants.DRBD_NET_PROTOCOL,
1389
                                  hmac=constants.DRBD_HMAC_ALG,
1390
                                  secret=self._secret
1391
                                  )
1392
        if res_r:
1393
          if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
1394
            break
1395
      # the weakest case: we find something that is only net attached
1396
      # even though we were passed some children at init time
1381
        # disk matches, but not attached to network, attach and recheck
1382
        self._AssembleNet(minor, net_data, constants.DRBD_NET_PROTOCOL,
1383
                          hmac=constants.DRBD_HMAC_ALG, secret=self._secret)
1384
        if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
1385
          break
1386
        else:
1387
          _ThrowError("drbd%d: network attach successful, but 'drbdsetup"
1388
                      " show' disagrees", minor)
1389

  
1397 1390
      if match_r and "local_dev" not in info:
1398
        break
1391
        # no local disk, but network attached and it matches
1392
        self._AssembleLocal(minor, self._children[0].dev_path,
1393
                            self._children[1].dev_path)
1394
        if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
1395
          break
1396
        else:
1397
          _ThrowError("drbd%d: disk attach successful, but 'drbdsetup"
1398
                      " show' disagrees", minor)
1399 1399

  
1400 1400
      # this case must be considered only if we actually have local
1401 1401
      # storage, i.e. not in diskless mode, because all diskless
......
1407 1407
        # else, even though its local storage is ours; as we own the
1408 1408
        # drbd space, we try to disconnect from the remote peer and
1409 1409
        # reconnect to our correct one
1410
        if not self._ShutdownNet(minor):
1411
          raise errors.BlockDeviceError("Device has correct local storage,"
1412
                                        " wrong remote peer and is unable to"
1413
                                        " disconnect in order to attach to"
1414
                                        " the correct peer")
1410
        try:
1411
          self._ShutdownNet(minor)
1412
        except errors.BlockDeviceError, err:
1413
          _ThrowError("Device has correct local storage, wrong remote peer"
1414
                      " and is unable to disconnect in order to attach to"
1415
                      " the correct peer: %s", str(err))
1415 1416
        # note: _AssembleNet also handles the case when we don't want
1416 1417
        # local storage (i.e. one or more of the _[lr](host|port) is
1417 1418
        # None)
1418
        if (self._AssembleNet(minor, (self._lhost, self._lport,
1419
                                      self._rhost, self._rport),
1420
                              constants.DRBD_NET_PROTOCOL,
1421
                              hmac=constants.DRBD_HMAC_ALG,
1422
                              secret=self._secret) and
1423
            self._MatchesNet(self._GetDevInfo(self._GetShowData(minor)))):
1419
        self._AssembleNet(minor, net_data, constants.DRBD_NET_PROTOCOL,
1420
                          hmac=constants.DRBD_HMAC_ALG, secret=self._secret)
1421
        if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
1424 1422
          break
1423
        else:
1424
          _ThrowError("drbd%d: network attach successful, but 'drbdsetup"
1425
                      " show' disagrees", minor)
1425 1426

  
1426 1427
    else:
1427 1428
      minor = None
1428 1429

  
1429 1430
    self._SetFromMinor(minor)
1430
    return minor is not None
1431
    if minor is None:
1432
      _ThrowError("drbd%d: cannot activate, unknown or unhandled reason",
1433
                  self._aminor)
1431 1434

  
1432 1435
  def _FastAssemble(self):
1433 1436
    """Assemble the drbd device from zero.
......
1435 1438
    This is run when in Assemble we detect our minor is unused.
1436 1439

  
1437 1440
    """
1438
    # TODO: maybe completely tear-down the minor (drbdsetup ... down)
1439
    # before attaching our own?
1440 1441
    minor = self._aminor
1441
    need_localdev_teardown = False
1442 1442
    if self._children and self._children[0] and self._children[1]:
1443
      result = self._AssembleLocal(minor, self._children[0].dev_path,
1444
                                   self._children[1].dev_path)
1445
      if not result:
1446
        return False
1443
      self._AssembleLocal(minor, self._children[0].dev_path,
1444
                          self._children[1].dev_path)
1447 1445
    if self._lhost and self._lport and self._rhost and self._rport:
1448
      result = self._AssembleNet(minor,
1449
                                 (self._lhost, self._lport,
1450
                                  self._rhost, self._rport),
1451
                                 constants.DRBD_NET_PROTOCOL,
1452
                                 hmac=constants.DRBD_HMAC_ALG,
1453
                                 secret=self._secret)
1454
      if not result:
1455
        return False
1446
      self._AssembleNet(minor,
1447
                        (self._lhost, self._lport, self._rhost, self._rport),
1448
                        constants.DRBD_NET_PROTOCOL,
1449
                        hmac=constants.DRBD_HMAC_ALG, secret=self._secret)
1456 1450
    self._SetFromMinor(minor)
1457
    return True
1458 1451

  
1459 1452
  @classmethod
1460 1453
  def _ShutdownLocal(cls, minor):
......
1466 1459
    """
1467 1460
    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "detach"])
1468 1461
    if result.failed:
1469
      logging.error("Can't detach local device: %s", result.output)
1470
    return not result.failed
1462
      _ThrowError("drbd%d: can't detach local disk: %s", minor, result.output)
1471 1463

  
1472 1464
  @classmethod
1473 1465
  def _ShutdownNet(cls, minor):
......
1478 1470
    """
1479 1471
    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "disconnect"])
1480 1472
    if result.failed:
1481
      logging.error("Can't shutdown network: %s", result.output)
1482
    return not result.failed
1473
      _ThrowError("drbd%d: can't shutdown network: %s", minor, result.output)
1483 1474

  
1484 1475
  @classmethod
1485 1476
  def _ShutdownAll(cls, minor):
......
1581 1572

  
1582 1573
    """
1583 1574
    if not os.path.exists(self.dev_path):
1584
      raise errors.BlockDeviceError("File device '%s' does not exist." %
1585
                                    self.dev_path)
1586
    return True
1575
      _ThrowError("File device '%s' does not exist" % self.dev_path)
1587 1576

  
1588 1577
  def Shutdown(self):
1589 1578
    """Shutdown the device.
......
1692 1681
  if dev_type not in DEV_MAP:
1693 1682
    raise errors.ProgrammerError("Invalid block device type '%s'" % dev_type)
1694 1683
  device = DEV_MAP[dev_type](unique_id, children)
1695
  if not device.Assemble():
1696
    raise errors.BlockDeviceError("Can't find a valid block device for"
1697
                                  " %s/%s/%s" %
1698
                                  (dev_type, unique_id, children))
1684
  device.Assemble()
1699 1685
  return device
1700 1686

  
1701 1687

  

Also available in: Unified diff