This patch adds support for newer versions of DRBD. Submitted upstream: . diff --git a/lib/storage/drbd.py b/lib/storage/drbd.py --- a/lib/storage/drbd.py +++ b/lib/storage/drbd.py @@ -315,6 +315,13 @@ class DRBD8Dev(base.BlockDev): """ return self._show_info_cls.GetDevInfo(self._GetShowData(minor)) + @staticmethod + def _NeedsLocalSyncerParams(): + # For DRBD >= 8.4, syncer init must be done after local, not in net. + info = DRBD8.GetProcInfo() + version = info.GetVersion() + return version["k_minor"] >= 4 + def _MatchesLocal(self, info): """Test if our local config matches with an existing device. @@ -397,6 +404,20 @@ class DRBD8Dev(base.BlockDev): base.ThrowError("drbd%d: can't attach local disk: %s", minor, result.output) + def _WaitForMinorSyncParams(): + """Call _SetMinorSyncParams and raise RetryAgain on errors. + """ + if self._SetMinorSyncParams(minor, self.params): + raise utils.RetryAgain() + + if self._NeedsLocalSyncerParams(): + # Retry because disk config for DRBD resource may be still uninitialized. + try: + utils.Retry(_WaitForMinorSyncParams, 1.0, 5.0) + except utils.RetryTimeout as e: + base.ThrowError("drbd%d: can't set the synchronization parameters: %s" % + (minor, utils.CommaJoin(e.args[0]))) + def _AssembleNet(self, minor, net_info, dual_pri=False, hmac=None, secret=None): """Configure the network part of the device. @@ -432,21 +453,24 @@ class DRBD8Dev(base.BlockDev): # 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. - sync_errors = self._SetMinorSyncParams(minor, self.params) - if sync_errors: - base.ThrowError("drbd%d: can't set the synchronization parameters: %s" % - (minor, utils.CommaJoin(sync_errors))) + + if not self._NeedsLocalSyncerParams(): + sync_errors = self._SetMinorSyncParams(minor, self.params) + if sync_errors: + base.ThrowError("drbd%d: can't set the synchronization parameters: %s" % + (minor, utils.CommaJoin(sync_errors))) family = self._GetNetFamily(minor, lhost, rhost) - cmd = self._cmd_gen.GenNetInitCmd(minor, family, lhost, lport, + cmds = self._cmd_gen.GenNetInitCmds(minor, family, lhost, lport, rhost, rport, protocol, dual_pri, hmac, secret, self.params) - result = utils.RunCmd(cmd) - if result.failed: - base.ThrowError("drbd%d: can't setup network: %s - %s", - minor, result.fail_reason, result.output) + for cmd in cmds: + result = utils.RunCmd(cmd) + if result.failed: + base.ThrowError("drbd%d: can't setup network: %s - %s", + minor, result.fail_reason, result.output) def _CheckNetworkConfig(): info = self._GetShowInfo(minor) @@ -463,19 +487,20 @@ class DRBD8Dev(base.BlockDev): base.ThrowError("drbd%d: timeout while configuring network", minor) # Once the assembly is over, try to set the synchronization parameters - try: - # The minor may not have been set yet, requiring us to set it at least - # temporarily - old_minor = self.minor - self._SetFromMinor(minor) - sync_errors = self.SetSyncParams(self.params) - if sync_errors: - base.ThrowError("drbd%d: can't set the synchronization parameters: %s" % - (self.minor, utils.CommaJoin(sync_errors))) - finally: - # Undo the change, regardless of whether it will have to be done again - # soon - self._SetFromMinor(old_minor) + if not self._NeedsLocalSyncerParams(): + try: + # The minor may not have been set yet, requiring us to set it at least + # temporarily + old_minor = self.minor + self._SetFromMinor(minor) + sync_errors = self.SetSyncParams(self.params) + if sync_errors: + base.ThrowError("drbd%d: can't set the synchronization parameters: %s" % + (self.minor, utils.CommaJoin(sync_errors))) + finally: + # Undo the change, regardless of whether it will have to be done again + # soon + self._SetFromMinor(old_minor) @staticmethod def _GetNetFamily(minor, lhost, rhost): diff --git a/lib/storage/drbd_cmdgen.py b/lib/storage/drbd_cmdgen.py --- a/lib/storage/drbd_cmdgen.py +++ b/lib/storage/drbd_cmdgen.py @@ -56,7 +56,7 @@ class BaseDRBDCmdGenerator(object): def GenLocalInitCmds(self, minor, data_dev, meta_dev, size_mb, params): raise NotImplementedError - def GenNetInitCmd(self, minor, family, lhost, lport, rhost, rport, protocol, + def GenNetInitCmds(self, minor, family, lhost, lport, rhost, rport, protocol, dual_pri, hmac, secret, params): raise NotImplementedError @@ -138,7 +138,7 @@ class DRBD83CmdGenerator(BaseDRBDCmdGenerator): return [args] - def GenNetInitCmd(self, minor, family, lhost, lport, rhost, rport, protocol, + def GenNetInitCmds(self, minor, family, lhost, lport, rhost, rport, protocol, dual_pri, hmac, secret, params): args = ["drbdsetup", self._DevPath(minor), "net", "%s:%s:%s" % (family, lhost, lport), @@ -155,7 +155,7 @@ class DRBD83CmdGenerator(BaseDRBDCmdGenerator): if params[constants.LDP_NET_CUSTOM]: args.extend(shlex.split(params[constants.LDP_NET_CUSTOM])) - return args + return [args] def GenSyncParamsCmd(self, minor, params): args = ["drbdsetup", self._DevPath(minor), "syncer"] @@ -345,8 +345,14 @@ class DRBD84CmdGenerator(BaseDRBDCmdGenerator): return cmds - def GenNetInitCmd(self, minor, family, lhost, lport, rhost, rport, protocol, + def GenNetInitCmds(self, minor, family, lhost, lport, rhost, rport, protocol, dual_pri, hmac, secret, params): + cmds = [] + + cmds.append(["drbdsetup", "new-resource", self._GetResource(minor)]) + cmds.append(["drbdsetup", "new-minor", self._GetResource(minor), + str(minor), "0"]) + args = ["drbdsetup", "connect", self._GetResource(minor), "%s:%s:%s" % (family, lhost, lport), "%s:%s:%s" % (family, rhost, rport), @@ -362,7 +368,8 @@ class DRBD84CmdGenerator(BaseDRBDCmdGenerator): if params[constants.LDP_NET_CUSTOM]: args.extend(shlex.split(params[constants.LDP_NET_CUSTOM])) - return args + cmds.append(args) + return cmds def GenSyncParamsCmd(self, minor, params): args = ["drbdsetup", "disk-options", minor]