Revision cf8df3f3

b/lib/bdev.py
786 786
  _MAX_MINORS = 255
787 787
  _PARSE_SHOW = None
788 788

  
789
  # timeout constants
790
  _NET_RECONFIG_TIMEOUT = 60
791

  
789 792
  def __init__(self, unique_id, children):
790 793
    if children and children.count(None) > 0:
791 794
      children = []
......
1232 1235
      logging.error(msg)
1233 1236
      raise errors.BlockDeviceError(msg)
1234 1237

  
1238
  def DisconnectNet(self):
1239
    """Removes network configuration.
1240

  
1241
    This method shutdowns the network side of the device.
1242

  
1243
    The method will wait up to a hardcoded timeout for the device to
1244
    go into standalone after the 'disconnect' command before
1245
    re-configuring it, as sometimes it takes a while for the
1246
    disconnect to actually propagate and thus we might issue a 'net'
1247
    command while the device is still connected. If the device will
1248
    still be attached to the network and we time out, we raise an
1249
    exception.
1250

  
1251
    """
1252
    if self.minor is None:
1253
      raise errors.BlockDeviceError("DRBD disk not attached in re-attach net")
1254

  
1255
    if None in (self._lhost, self._lport, self._rhost, self._rport):
1256
      raise errors.BlockDeviceError("DRBD disk missing network info in"
1257
                                    " DisconnectNet()")
1258

  
1259
    ever_disconnected = self._ShutdownNet(self.minor)
1260
    timeout_limit = time.time() + self._NET_RECONFIG_TIMEOUT
1261
    sleep_time = 0.100 # we start the retry time at 100 miliseconds
1262
    while time.time() < timeout_limit:
1263
      status = self.GetProcStatus()
1264
      if status.is_standalone:
1265
        break
1266
      # retry the disconnect, it seems possible that due to a
1267
      # well-time disconnect on the peer, my disconnect command might
1268
      # be ingored and forgotten
1269
      ever_disconnected = self._ShutdownNet(self.minor) or ever_disconnected
1270
      time.sleep(sleep_time)
1271
      sleep_time = min(2, sleep_time * 1.5)
1272

  
1273
    if not status.is_standalone:
1274
      if ever_disconnected:
1275
        msg = ("Device did not react to the"
1276
               " 'disconnect' command in a timely manner")
1277
      else:
1278
        msg = ("Can't shutdown network, even after multiple retries")
1279
      raise errors.BlockDeviceError(msg)
1280

  
1281
    reconfig_time = time.time() - timeout_limit + self._NET_RECONFIG_TIMEOUT
1282
    if reconfig_time > 15: # hardcoded alert limit
1283
      logging.debug("DRBD8.DisconnectNet: detach took %.3f seconds",
1284
                    reconfig_time)
1285

  
1286
  def AttachNet(self, multimaster):
1287
    """Reconnects the network.
1288

  
1289
    This method connects the network side of the device with a
1290
    specified multi-master flag. The device needs to be 'Standalone'
1291
    but have valid network configuration data.
1292

  
1293
    Args:
1294
      - multimaster: init the network in dual-primary mode
1295

  
1296
    """
1297
    if self.minor is None:
1298
      raise errors.BlockDeviceError("DRBD disk not attached in AttachNet")
1299

  
1300
    if None in (self._lhost, self._lport, self._rhost, self._rport):
1301
      raise errors.BlockDeviceError("DRBD disk missing network info in"
1302
                                    " AttachNet()")
1303

  
1304
    status = self.GetProcStatus()
1305

  
1306
    if not status.is_standalone:
1307
      raise errors.BlockDeviceError("Device is not standalone in AttachNet")
1308

  
1309
    return self._AssembleNet(self.minor,
1310
                             (self._lhost, self._lport,
1311
                              self._rhost, self._rport),
1312
                             "C", dual_pri=multimaster)
1313

  
1235 1314
  def Attach(self):
1236 1315
    """Find a DRBD device which matches our config and attach to it.
1237 1316

  

Also available in: Unified diff