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