summary refs log tree commit diff
path: root/gnu/packages/patches/ganeti-drbd-compat.patch
blob: 32f46bc7edc29871fd4ef76558f60dbecc3d1a28 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
This patch adds support for newer versions of DRBD.

Submitted upstream: <https://github.com/ganeti/ganeti/pull/1496>.

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]