+ if match_l and not match_r and "local_addr" not in info:
+ # disk matches, but not attached to network, attach and recheck
+ self._AssembleNet(minor, net_data, constants.DRBD_NET_PROTOCOL,
+ hmac=constants.DRBD_HMAC_ALG, secret=self._secret)
+ if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
+ break
+ else:
+ _ThrowError("drbd%d: network attach successful, but 'drbdsetup"
+ " show' disagrees", minor)
+
+ if match_r and "local_dev" not in info:
+ # no local disk, but network attached and it matches
+ self._AssembleLocal(minor, self._children[0].dev_path,
+ self._children[1].dev_path, self.size)
+ if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
+ break
+ else:
+ _ThrowError("drbd%d: disk attach successful, but 'drbdsetup"
+ " show' disagrees", minor)
+
+ # this case must be considered only if we actually have local
+ # storage, i.e. not in diskless mode, because all diskless
+ # devices are equal from the point of view of local
+ # configuration
+ if (match_l and "local_dev" in info and
+ not match_r and "local_addr" in info):
+ # strange case - the device network part points to somewhere
+ # else, even though its local storage is ours; as we own the
+ # drbd space, we try to disconnect from the remote peer and
+ # reconnect to our correct one
+ try:
+ self._ShutdownNet(minor)
+ except errors.BlockDeviceError, err:
+ _ThrowError("drbd%d: device has correct local storage, wrong"
+ " remote peer and is unable to disconnect in order"
+ " to attach to the correct peer: %s", minor, str(err))
+ # note: _AssembleNet also handles the case when we don't want
+ # local storage (i.e. one or more of the _[lr](host|port) is
+ # None)
+ self._AssembleNet(minor, net_data, constants.DRBD_NET_PROTOCOL,
+ hmac=constants.DRBD_HMAC_ALG, secret=self._secret)
+ if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
+ break
+ else:
+ _ThrowError("drbd%d: network attach successful, but 'drbdsetup"
+ " show' disagrees", minor)
+