Commit 7d585316 authored by Iustin Pop's avatar Iustin Pop
Browse files

Work around a DRBD sync speed race condition

This is modified forward-port of commit 1544 on the 1.2 branch:

  When DRBD is doing its dance to establish a connection with its
  peer, it also sends the synchronization speed over the wire. In
  some cases setting the sync speed only after setting up both
  sides can race with DRBD connecting, hence we set it here before
  telling DRBD anything about its peer.

  Reviewed-by: iustinp

The modification we make is that we split SetSyncSpeed in two so that we
don't need to modify our minor temporarily, and the fact that we call
this function from within _AssembleNet (right before enabling network),
instead of Assemble()/Attach().

Original-Author: imsnah
parent 90e722d1
......@@ -1056,6 +1056,14 @@ class DRBD8(BaseDRBD):
# sure its shutdown
return cls._ShutdownNet(minor)
# Workaround for a race condition. When DRBD is doing its dance to
# establish a connection with its peer, it also sends the
# synchronization speed over the wire. In some cases setting the
# sync speed only after setting up both sides can race with DRBD
# connecting, hence we set it here before telling DRBD anything
# about its peer.
cls._SetMinorSyncSpeed(minor, constants.SYNC_SPEED)
args = ["drbdsetup", cls._DevPath(minor), "net",
"%s:%s" % (lhost, lport), "%s:%s" % (rhost, rport), protocol,
"-A", "discard-zero-changes",
......@@ -1145,20 +1153,41 @@ class DRBD8(BaseDRBD):
raise errors.BlockDeviceError("Can't detach from local storage")
self._children = []
def SetSyncSpeed(self, kbytes):
@classmethod
def _SetMinorSyncSpeed(cls, minor, kbytes):
"""Set the speed of the DRBD syncer.
This is the low-level implementation.
@type minor: int
@param minor: the drbd minor whose settings we change
@type kbytes: int
@param kbytes: the speed in kbytes/second
@rtype: boolean
@return: the success of the operation
"""
children_result = super(DRBD8, self).SetSyncSpeed(kbytes)
if self.minor is None:
logging.info("Instance not attached to a device")
return False
result = utils.RunCmd(["drbdsetup", self.dev_path, "syncer", "-r", "%d" %
kbytes])
result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "syncer",
"-r", "%d" % kbytes, "--create-device"])
if result.failed:
logging.error("Can't change syncer rate: %s - %s",
result.fail_reason, result.output)
return not result.failed and children_result
return not result.failed
def SetSyncSpeed(self, kbytes):
"""Set the speed of the DRBD syncer.
@type kbytes: int
@param kbytes: the speed in kbytes/second
@rtype: boolean
@return: the success of the operation
"""
if self.minor is None:
logging.info("Not attached during SetSyncSpeed")
return False
children_result = super(DRBD8, self).SetSyncSpeed(kbytes)
return self._SetMinorSyncSpeed(self.minor, kbytes) and children_result
def GetProcStatus(self):
"""Return device data from /proc.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment