diff --git a/lib/bdev.py b/lib/bdev.py
index 4732992eff6c35104d00b75eda4713c64bd5d5bf..3648a2c03e370061df36109a33b4a95f9ff06443 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -804,11 +804,11 @@ class DRBD8(BaseDRBD):
 
     if len(children) not in (0, 2):
       raise ValueError("Invalid configuration data %s" % str(children))
-    if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 5:
+    if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 6:
       raise ValueError("Invalid configuration data %s" % str(unique_id))
     (self._lhost, self._lport,
      self._rhost, self._rport,
-     self._aminor) = unique_id
+     self._aminor, self._secret) = unique_id
     if (self._lhost is not None and self._lhost == self._rhost and
         self._lport == self._rport):
       raise ValueError("Invalid configuration data, same local/remote %s" %
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index c9474b0efb984b109c23a4ff42f55dfcef9ef110..4822f54251b95f9b7c92c904977b71f4a3983502 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2923,13 +2923,15 @@ def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name,
   """
   port = cfg.AllocatePort()
   vgname = cfg.GetVGName()
+  shared_secret = cfg.GenerateDRBDSecret()
   dev_data = objects.Disk(dev_type=constants.LD_LV, size=size,
                           logical_id=(vgname, names[0]))
   dev_meta = objects.Disk(dev_type=constants.LD_LV, size=128,
                           logical_id=(vgname, names[1]))
   drbd_dev = objects.Disk(dev_type=constants.LD_DRBD8, size=size,
                           logical_id=(primary, secondary, port,
-                                      p_minor, s_minor),
+                                      p_minor, s_minor,
+                                      shared_secret),
                           children=[dev_data, dev_meta],
                           iv_name=iv_name)
   return drbd_dev
@@ -4050,10 +4052,12 @@ class LUReplaceDisks(LogicalUnit):
       # create new devices on new_node
       if pri_node == dev.logical_id[0]:
         new_logical_id = (pri_node, new_node,
-                          dev.logical_id[2], dev.logical_id[3], new_minor)
+                          dev.logical_id[2], dev.logical_id[3], new_minor,
+                          dev.logical_id[5])
       else:
         new_logical_id = (new_node, pri_node,
-                          dev.logical_id[2], new_minor, dev.logical_id[4])
+                          dev.logical_id[2], new_minor, dev.logical_id[4],
+                          dev.logical_id[5])
       iv_names[dev.iv_name] = (dev, dev.children, new_logical_id)
       logging.debug("Allocated new_minor: %s, new_logical_id: %s", new_minor,
                     new_logical_id)
@@ -4079,9 +4083,9 @@ class LUReplaceDisks(LogicalUnit):
     done = 0
     for dev in instance.disks:
       cfg.SetDiskID(dev, pri_node)
-      # set the physical (unique in bdev terms) id to None, meaning
-      # detach from network
-      dev.physical_id = (None, None, None, None, dev.physical_id[4])
+      # set the network part of the physical (unique in bdev terms) id
+      # to None, meaning detach from network
+      dev.physical_id = (None, None, None, None) + dev.physical_id[4:]
       # and 'find' the device, which will 'fix' it to match the
       # standalone state
       if rpc.call_blockdev_find(pri_node, dev):
diff --git a/lib/config.py b/lib/config.py
index f44340b8d378c84cea68f361c3b33dbe34ca30b1..27f85f56189a07f973e53bca497f984c6d2ab84e 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -126,6 +126,25 @@ class ConfigWriter:
     all_macs = self._AllMACs()
     return mac in all_macs
 
+  @locking.ssynchronized(_config_lock, shared=1)
+  def GenerateDRBDSecret(self):
+    """Generate a DRBD secret.
+
+    This checks the current disks for duplicates.
+
+    """
+    self._OpenConfig()
+    all_secrets = self._AllDRBDSecrets()
+    retries = 64
+    while retries > 0:
+      secret = utils.GenerateSecret()
+      if secret not in all_secrets:
+        break
+      retries -= 1
+    else:
+      raise errors.ConfigurationError("Can't generate unique DRBD secret")
+    return secret
+
   def _ComputeAllLVs(self):
     """Compute the list of all LVs.
 
@@ -185,6 +204,25 @@ class ConfigWriter:
 
     return result
 
+  def _AllDRBDSecrets(self):
+    """Return all DRBD secrets present in the config.
+
+    """
+    def helper(disk, result):
+      """Recursively gather secrets from this disk."""
+      if disk.dev_type == constants.DT_DRBD8:
+        result.append(disk.logical_id[5])
+      if disk.children:
+        for child in disk.children:
+          helper(child, result)
+
+    result = []
+    for instance in self._config_data.instances.values():
+      for disk in instance.disks:
+        helper(disk, result)
+
+    return result
+
   @locking.ssynchronized(_config_lock, shared=1)
   def VerifyConfig(self):
     """Stub verify function.
@@ -268,7 +306,7 @@ class ConfigWriter:
     if disk.logical_id is None and disk.physical_id is not None:
       return
     if disk.dev_type == constants.LD_DRBD8:
-      pnode, snode, port, pminor, sminor = disk.logical_id
+      pnode, snode, port, pminor, sminor, secret = disk.logical_id
       if node_name not in (pnode, snode):
         raise errors.ConfigurationError("DRBD device not knowing node %s" %
                                         node_name)
@@ -280,9 +318,9 @@ class ConfigWriter:
       p_data = (pnode_info.secondary_ip, port)
       s_data = (snode_info.secondary_ip, port)
       if pnode == node_name:
-        disk.physical_id = p_data + s_data + (pminor,)
+        disk.physical_id = p_data + s_data + (pminor, secret)
       else: # it must be secondary, we tested above
-        disk.physical_id = s_data + p_data + (sminor,)
+        disk.physical_id = s_data + p_data + (sminor, secret)
     else:
       disk.physical_id = disk.logical_id
     return
@@ -354,8 +392,8 @@ class ConfigWriter:
 
     """
     def _AppendUsedPorts(instance_name, disk, used):
-      if disk.dev_type == constants.LD_DRBD8 and len(disk.logical_id) == 5:
-        nodeA, nodeB, dummy, minorA, minorB = disk.logical_id
+      if disk.dev_type == constants.LD_DRBD8 and len(disk.logical_id) >= 5:
+        nodeA, nodeB, dummy, minorA, minorB = disk.logical_id[:5]
         for node, port in ((nodeA, minorA), (nodeB, minorB)):
           assert node in used, "Instance node not found in node list"
           if port in used[node]:
diff --git a/lib/objects.py b/lib/objects.py
index 23ecfc87d44892cf48694c83b6aafadfb7d53be2..3af15eb50fc651fe7f699e4a99db26ac8dd68b22 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -412,7 +412,7 @@ class Disk(ConfigObject):
     if self.logical_id is None and self.physical_id is not None:
       return
     if self.dev_type in constants.LDS_DRBD:
-      pnode, snode, port, pminor, sminor = self.logical_id
+      pnode, snode, port, pminor, sminor, secret = self.logical_id
       if target_node not in (pnode, snode):
         raise errors.ConfigurationError("DRBD device not knowing node %s" %
                                         target_node)
@@ -424,9 +424,9 @@ class Disk(ConfigObject):
       p_data = (pnode_ip, port)
       s_data = (snode_ip, port)
       if pnode == target_node:
-        self.physical_id = p_data + s_data + (pminor,)
+        self.physical_id = p_data + s_data + (pminor, secret)
       else: # it must be secondary, we tested above
-        self.physical_id = s_data + p_data + (sminor,)
+        self.physical_id = s_data + p_data + (sminor, secret)
     else:
       self.physical_id = self.logical_id
     return
@@ -458,9 +458,10 @@ class Disk(ConfigObject):
       obj.logical_id = tuple(obj.logical_id)
     if obj.physical_id and isinstance(obj.physical_id, list):
       obj.physical_id = tuple(obj.physical_id)
-    if obj.dev_type in constants.LDS_DRBD and len(obj.logical_id) == 3:
-      # old non-minor based disk type
-      obj.logical_id += (None, None)
+    if obj.dev_type in constants.LDS_DRBD:
+      # we need a tuple of length six here
+      if len(obj.logical_id) < 6:
+        obj.logical_id += (None,) * (6 - len(obj.logical_id))
     return obj
 
   def __str__(self):