diff --git a/lib/bdev.py b/lib/bdev.py index 030d19522720a9bac8a19908f77a6169247b2da0..666c44c08f1b54cabf532da2fb9ffc7937ebe1eb 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -228,12 +228,15 @@ class BlockDev(object): @param params: dictionary of LD level disk parameters related to the synchronization. + @rtype: list + @return: a list of error messages, emitted both by the current node and by + children. An empty list means no errors. """ - result = True + result = [] if self._children: for child in self._children: - result = result and child.SetSyncParams(params) + result.extend(child.SetSyncParams(params)) return result def PauseResumeSync(self, pause): @@ -1475,7 +1478,10 @@ class DRBD8(BaseDRBD): # 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. - self._SetMinorSyncParams(minor, self.params) + sync_errors = self._SetMinorSyncParams(minor, self.params) + if sync_errors: + _ThrowError("drbd%d: can't set the synchronization parameters: %s" % + (minor, utils.CommaJoin(sync_errors))) if netutils.IP6Address.IsValid(lhost): if not netutils.IP6Address.IsValid(rhost): @@ -1584,8 +1590,8 @@ class DRBD8(BaseDRBD): @param minor: the drbd minor whose settings we change @type params: dict @param params: LD level disk parameters related to the synchronization - @rtype: boolean - @return: the success of the operation + @rtype: list + @return: a list of error messages """ @@ -1598,13 +1604,25 @@ class DRBD8(BaseDRBD): # By definition we are using 8.x, so just check the rest of the version # number if vmin != 3 or vrel < 9: - logging.error("The current DRBD version (8.%d.%d) does not support the" - " dynamic resync speed controller", vmin, vrel) - return False + msg = ("The current DRBD version (8.%d.%d) does not support the " + "dynamic resync speed controller" % (vmin, vrel)) + logging.error(msg) + return [msg] + + if params[constants.LDP_PLAN_AHEAD] == 0: + msg = ("A value of 0 for c-plan-ahead disables the dynamic sync speed" + " controller at DRBD level. If you want to disable it, please" + " set the dynamic-resync disk parameter to False.") + logging.error(msg) + return [msg] # add the c-* parameters to args - # TODO(spadaccio) use the actual parameters - args.extend(["--c-plan-ahead", "20"]) + args.extend(["--c-plan-ahead", params[constants.LDP_PLAN_AHEAD], + "--c-fill-target", params[constants.LDP_FILL_TARGET], + "--c-delay-target", params[constants.LDP_DELAY_TARGET], + "--c-max-rate", params[constants.LDP_MAX_RATE], + "--c-min-rate", params[constants.LDP_MIN_RATE], + ]) else: args.extend(["-r", "%d" % params[constants.LDP_RESYNC_RATE]]) @@ -1612,24 +1630,31 @@ class DRBD8(BaseDRBD): args.append("--create-device") result = utils.RunCmd(args) if result.failed: - logging.error("Can't change syncer rate: %s - %s", - result.fail_reason, result.output) - return not result.failed + msg = ("Can't change syncer rate: %s - %s" % + (result.fail_reason, result.output)) + logging.error(msg) + return msg + + return [] def SetSyncParams(self, params): """Set the synchronization parameters of the DRBD syncer. @type params: dict @param params: LD level disk parameters related to the synchronization - @rtype: boolean - @return: the success of the operation + @rtype: list + @return: a list of error messages, emitted both by the current node and by + children. An empty list means no errors """ if self.minor is None: - logging.info("Not attached during SetSyncParams") - return False + err = "Not attached during SetSyncParams" + logging.info(err) + return [err] + children_result = super(DRBD8, self).SetSyncParams(params) - return self._SetMinorSyncParams(self.minor, params) and children_result + children_result.extend(self._SetMinorSyncParams(self.minor, params)) + return children_result def PauseResumeSync(self, pause): """Pauses or resumes the sync of a DRBD device. @@ -1866,7 +1891,10 @@ class DRBD8(BaseDRBD): # the device self._SlowAssemble() - self.SetSyncParams(self.params) + sync_errors = self.SetSyncParams(self.params) + if sync_errors: + _ThrowError("drbd%d: can't set the synchronization parameters: %s" % + (self.minor, utils.CommaJoin(sync_errors))) def _SlowAssemble(self): """Assembles the DRBD device from a (partially) configured device. diff --git a/lib/cmdlib.py b/lib/cmdlib.py index bd68cc9ef173bf08f0d1312dd044f8f2e8a62027..04d26f95b929a759457455d3f829f43437b04974 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -8246,6 +8246,11 @@ def _ComputeLDParams(disk_template, disk_params): constants.LDP_DISK_CUSTOM: dt_params[constants.DRBD_DISK_CUSTOM], constants.LDP_NET_CUSTOM: dt_params[constants.DRBD_NET_CUSTOM], constants.LDP_DYNAMIC_RESYNC: dt_params[constants.DRBD_DYNAMIC_RESYNC], + constants.LDP_PLAN_AHEAD: dt_params[constants.DRBD_PLAN_AHEAD], + constants.LDP_FILL_TARGET: dt_params[constants.DRBD_FILL_TARGET], + constants.LDP_DELAY_TARGET: dt_params[constants.DRBD_DELAY_TARGET], + constants.LDP_MAX_RATE: dt_params[constants.DRBD_MAX_RATE], + constants.LDP_MIN_RATE: dt_params[constants.DRBD_MIN_RATE], } drbd_params = \ diff --git a/lib/constants.py b/lib/constants.py index 41e1647b5c3b2117a13b6ca128c19c320d16eed5..64669cc9d49a385aab422024ec5a772aae67caa3 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -966,6 +966,11 @@ LDP_DEFAULT_METAVG = "default-metavg" LDP_DISK_CUSTOM = "disk-custom" LDP_NET_CUSTOM = "net-custom" LDP_DYNAMIC_RESYNC = "dynamic-resync" +LDP_PLAN_AHEAD = "c-plan-ahead" +LDP_FILL_TARGET = "c-fill-target" +LDP_DELAY_TARGET = "c-delay-target" +LDP_MAX_RATE = "c-max-rate" +LDP_MIN_RATE = "c-min-rate" DISK_LD_TYPES = { LDP_RESYNC_RATE: VTYPE_INT, LDP_STRIPES: VTYPE_INT, @@ -975,6 +980,11 @@ DISK_LD_TYPES = { LDP_DISK_CUSTOM: VTYPE_STRING, LDP_NET_CUSTOM: VTYPE_STRING, LDP_DYNAMIC_RESYNC: VTYPE_BOOL, + LDP_PLAN_AHEAD: VTYPE_INT, + LDP_FILL_TARGET: VTYPE_INT, + LDP_DELAY_TARGET: VTYPE_INT, + LDP_MAX_RATE: VTYPE_INT, + LDP_MIN_RATE: VTYPE_INT, } DISK_LD_PARAMETERS = frozenset(DISK_LD_TYPES.keys()) @@ -989,6 +999,11 @@ DRBD_DEFAULT_METAVG = "metavg" DRBD_DISK_CUSTOM = "disk-custom" DRBD_NET_CUSTOM = "net-custom" DRBD_DYNAMIC_RESYNC = "dynamic-resync" +DRBD_PLAN_AHEAD = "c-plan-ahead" +DRBD_FILL_TARGET = "c-fill-target" +DRBD_DELAY_TARGET = "c-delay-target" +DRBD_MAX_RATE = "c-max-rate" +DRBD_MIN_RATE = "c-min-rate" LV_STRIPES = "stripes" DISK_DT_TYPES = { DRBD_RESYNC_RATE: VTYPE_INT, @@ -1000,6 +1015,11 @@ DISK_DT_TYPES = { DRBD_DISK_CUSTOM: VTYPE_STRING, DRBD_NET_CUSTOM: VTYPE_STRING, DRBD_DYNAMIC_RESYNC: VTYPE_BOOL, + DRBD_PLAN_AHEAD: VTYPE_INT, + DRBD_FILL_TARGET: VTYPE_INT, + DRBD_DELAY_TARGET: VTYPE_INT, + DRBD_MAX_RATE: VTYPE_INT, + DRBD_MIN_RATE: VTYPE_INT, LV_STRIPES: VTYPE_INT, } @@ -1781,6 +1801,17 @@ DISK_LD_DEFAULTS = { LDP_DISK_CUSTOM: "", LDP_NET_CUSTOM: "", LDP_DYNAMIC_RESYNC: False, + + # The default values for the DRBD dynamic resync speed algorithm are taken + # from the drbsetup 8.3.11 man page, except for c-plan-ahead (that we + # don't need to set to 0, because we have a separate option to enable it) + # and for c-max-rate, that we cap to the default value for the static resync + # rate. + LDP_PLAN_AHEAD: 20, # ds + LDP_FILL_TARGET: 0, # sectors + LDP_DELAY_TARGET: 1, # ds + LDP_MAX_RATE: CLASSIC_DRBD_SYNC_SPEED, # KiB/s + LDP_MIN_RATE: 4 * 1024, # KiB/s }, LD_LV: { LDP_STRIPES: _autoconf.LVM_STRIPECOUNT @@ -1791,20 +1822,29 @@ DISK_LD_DEFAULTS = { }, } +# readability shortcuts +_LV_DEFAULTS = DISK_LD_DEFAULTS[LD_LV] +_DRBD_DEFAULTS = DISK_LD_DEFAULTS[LD_DRBD8] + DISK_DT_DEFAULTS = { DT_PLAIN: { LV_STRIPES: DISK_LD_DEFAULTS[LD_LV][LDP_STRIPES], }, DT_DRBD8: { - DRBD_RESYNC_RATE: DISK_LD_DEFAULTS[LD_DRBD8][LDP_RESYNC_RATE], - DRBD_DATA_STRIPES: DISK_LD_DEFAULTS[LD_LV][LDP_STRIPES], - DRBD_META_STRIPES: DISK_LD_DEFAULTS[LD_LV][LDP_STRIPES], - DRBD_DISK_BARRIERS: DISK_LD_DEFAULTS[LD_DRBD8][LDP_BARRIERS], - DRBD_META_BARRIERS: DISK_LD_DEFAULTS[LD_DRBD8][LDP_NO_META_FLUSH], - DRBD_DEFAULT_METAVG: DISK_LD_DEFAULTS[LD_DRBD8][LDP_DEFAULT_METAVG], - DRBD_DISK_CUSTOM: DISK_LD_DEFAULTS[LD_DRBD8][LDP_DISK_CUSTOM], - DRBD_NET_CUSTOM: DISK_LD_DEFAULTS[LD_DRBD8][LDP_NET_CUSTOM], - DRBD_DYNAMIC_RESYNC: DISK_LD_DEFAULTS[LD_DRBD8][LDP_DYNAMIC_RESYNC], + DRBD_RESYNC_RATE: _DRBD_DEFAULTS[LDP_RESYNC_RATE], + DRBD_DATA_STRIPES: _LV_DEFAULTS[LDP_STRIPES], + DRBD_META_STRIPES: _LV_DEFAULTS[LDP_STRIPES], + DRBD_DISK_BARRIERS: _DRBD_DEFAULTS[LDP_BARRIERS], + DRBD_META_BARRIERS: _DRBD_DEFAULTS[LDP_NO_META_FLUSH], + DRBD_DEFAULT_METAVG: _DRBD_DEFAULTS[LDP_DEFAULT_METAVG], + DRBD_DISK_CUSTOM: _DRBD_DEFAULTS[LDP_DISK_CUSTOM], + DRBD_NET_CUSTOM: _DRBD_DEFAULTS[LDP_NET_CUSTOM], + DRBD_DYNAMIC_RESYNC: _DRBD_DEFAULTS[LDP_DYNAMIC_RESYNC], + DRBD_PLAN_AHEAD: _DRBD_DEFAULTS[LDP_PLAN_AHEAD], + DRBD_FILL_TARGET: _DRBD_DEFAULTS[LDP_FILL_TARGET], + DRBD_DELAY_TARGET: _DRBD_DEFAULTS[LDP_DELAY_TARGET], + DRBD_MAX_RATE: _DRBD_DEFAULTS[LDP_MAX_RATE], + DRBD_MIN_RATE: _DRBD_DEFAULTS[LDP_MIN_RATE], }, DT_DISKLESS: { }, @@ -1816,6 +1856,9 @@ DISK_DT_DEFAULTS = { }, } +# we don't want to export the shortcuts +del _LV_DEFAULTS, _DRBD_DEFAULTS + NICC_DEFAULTS = { NIC_MODE: NIC_MODE_BRIDGED, NIC_LINK: DEFAULT_BRIDGE,