diff --git a/lib/bdev.py b/lib/bdev.py
index 0352ca84630c7d57fa06b75526351cd3a3fcdb91..0e8ddf4d48e8e9353d0f173a558accc69a542cc6 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -2086,6 +2086,7 @@ DEV_MAP = {
   constants.LD_LV: LogicalVolume,
   constants.LD_MD_R1: MDRaid1,
   constants.LD_DRBD7: DRBDev,
+  constants.LD_DRBD8: DRBD8,
   }
 
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 0ef88462847547416110d574f5ec6b164254ae63..ab433ed09a0f23a9770a7ab61f1f9bdf4dd388f2 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2460,9 +2460,9 @@ class LUFailoverInstance(LogicalUnit):
       raise errors.OpPrereqError("Instance '%s' not known" %
                                  self.op.instance_name)
 
-    if instance.disk_template != constants.DT_REMOTE_RAID1:
+    if instance.disk_template not in constants.DTS_NET_MIRROR:
       raise errors.OpPrereqError("Instance's disk layout is not"
-                                 " remote_raid1.")
+                                 " network mirrored, cannot failover.")
 
     secondary_nodes = instance.secondary_nodes
     if not secondary_nodes:
@@ -2636,6 +2636,22 @@ def _GenerateMDDRBDBranch(cfg, primary, secondary, size, names):
   return drbd_dev
 
 
+def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name):
+  """Generate a drbd8 device complete with its children.
+
+  """
+  port = cfg.AllocatePort()
+  vgname = cfg.GetVGName()
+  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),
+                          children = [dev_data, dev_meta],
+                          iv_name=iv_name)
+  return drbd_dev
+
 def _GenerateDiskTemplate(cfg, template_name,
                           instance_name, primary_node,
                           secondary_nodes, disk_sz, swap_sz):
@@ -2696,6 +2712,17 @@ def _GenerateDiskTemplate(cfg, template_name,
     md_sdb_dev = objects.Disk(dev_type=constants.LD_MD_R1, iv_name="sdb",
                               children = [drbd_sdb_dev], size=swap_sz)
     disks = [md_sda_dev, md_sdb_dev]
+  elif template_name == constants.DT_DRBD8:
+    if len(secondary_nodes) != 1:
+      raise errors.ProgrammerError("Wrong template configuration")
+    remote_node = secondary_nodes[0]
+    names = _GenerateUniqueNames(cfg, [".sda_data", ".sda_meta",
+                                       ".sdb_data", ".sdb_meta"])
+    drbd_sda_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node,
+                                         disk_sz, names[0:2], "sda")
+    drbd_sdb_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node,
+                                         swap_sz, names[2:4], "sdb")
+    disks = [drbd_sda_dev, drbd_sdb_dev]
   else:
     raise errors.ProgrammerError("Invalid disk template '%s'" % template_name)
   return disks
@@ -2872,9 +2899,9 @@ class LUCreateInstance(LogicalUnit):
     if self.op.disk_template not in constants.DISK_TEMPLATES:
       raise errors.OpPrereqError("Invalid disk template name")
 
-    if self.op.disk_template == constants.DT_REMOTE_RAID1:
+    if self.op.disk_template in constants.DTS_NET_MIRROR:
       if getattr(self.op, "snode", None) is None:
-        raise errors.OpPrereqError("The 'remote_raid1' disk template needs"
+        raise errors.OpPrereqError("The networked disk templates need"
                                    " a mirror node")
 
       snode_name = self.cfg.ExpandNodeName(self.op.snode)
@@ -2897,6 +2924,7 @@ class LUCreateInstance(LogicalUnit):
       constants.DT_LOCAL_RAID1: (self.op.disk_size + self.op.swap_size) * 2,
       # 256 MB are added for drbd metadata, 128MB for each drbd device
       constants.DT_REMOTE_RAID1: self.op.disk_size + self.op.swap_size + 256,
+      constants.DT_DRBD8: self.op.disk_size + self.op.swap_size + 256,
     }
 
     if self.op.disk_template not in req_size_dict:
@@ -3006,7 +3034,7 @@ class LUCreateInstance(LogicalUnit):
 
     if self.op.wait_for_sync:
       disk_abort = not _WaitForSync(self.cfg, iobj)
-    elif iobj.disk_template == constants.DT_REMOTE_RAID1:
+    elif iobj.disk_template in constants.DTS_NET_MIRROR:
       # make sure the disks are not degraded (still sync-ing is ok)
       time.sleep(15)
       feedback_fn("* checking mirrors status")
@@ -3486,7 +3514,7 @@ class LUQueryInstanceData(NoHooksLU):
     """
     self.cfg.SetDiskID(dev, instance.primary_node)
     dev_pstatus = rpc.call_blockdev_find(instance.primary_node, dev)
-    if dev.dev_type == constants.LD_DRBD7:
+    if dev.dev_type in constants.LDS_DRBD:
       # we change the snode then (otherwise we use the one passed in)
       if dev.logical_id[0] == instance.primary_node:
         snode = dev.logical_id[1]
diff --git a/lib/config.py b/lib/config.py
index e3093166889a2ec7092e8568a277a95c20a19863..0c769d2bce7e9fefaac48778b900d665a90ed9b5 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -198,7 +198,7 @@ class ConfigWriter:
 
     if disk.logical_id is None and disk.physical_id is not None:
       return
-    if disk.dev_type == constants.LD_DRBD7:
+    if disk.dev_type in constants.LDS_DRBD:
       pnode, snode, port = disk.logical_id
       if node_name not in (pnode, snode):
         raise errors.ConfigurationError("DRBD device not knowing node %s" %
diff --git a/lib/constants.py b/lib/constants.py
index 2c9067cc95b17083c9a2d55dd399d8104410765e..a6d99da8297896ab606daedea09172fe3814644d 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -78,18 +78,27 @@ DT_DISKLESS = "diskless"
 DT_PLAIN = "plain"
 DT_LOCAL_RAID1 = "local_raid1"
 DT_REMOTE_RAID1 = "remote_raid1"
+DT_DRBD8 = "drbd"
+
+# the set of network-mirrored disk templates
+DTS_NET_MIRROR = frozenset([DT_REMOTE_RAID1, DT_DRBD8])
 
 # logical disk types
 LD_LV = "lvm"
 LD_MD_R1 = "md_raid1"
 LD_DRBD7 = "drbd"
+LD_DRBD8 = "drbd8"
+
+# the set of drbd-like disk types
+LDS_DRBD = frozenset([LD_DRBD7, LD_DRBD8])
 
 # instance creation modem
 INSTANCE_CREATE = "create"
 INSTANCE_IMPORT = "import"
 
 DISK_TEMPLATES = frozenset([DT_DISKLESS, DT_PLAIN,
-                            DT_LOCAL_RAID1, DT_REMOTE_RAID1])
+                            DT_LOCAL_RAID1, DT_REMOTE_RAID1,
+                            DT_DRBD8])
 
 # import/export config options
 INISECT_EXP = "export"
diff --git a/lib/objects.py b/lib/objects.py
index f5da82a732432f9b363283ddc430e6653a223fea..b009191a212a7e9d94f66596898150fbd9154254 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -314,11 +314,13 @@ class Disk(ConfigObject):
 
   def CreateOnSecondary(self):
     """Test if this device needs to be created on a secondary node."""
-    return self.dev_type in (constants.LD_DRBD7, constants.LD_LV)
+    return self.dev_type in (constants.LD_DRBD7, constants.LD_DRBD8,
+                             constants.LD_LV)
 
   def AssembleOnSecondary(self):
     """Test if this device needs to be assembled on a secondary node."""
-    return self.dev_type in (constants.LD_DRBD7, constants.LD_LV)
+    return self.dev_type in (constants.LD_DRBD7, constants.LD_DRBD8,
+                             constants.LD_LV)
 
   def OpenOnSecondary(self):
     """Test if this device needs to be opened on a secondary node."""
@@ -335,7 +337,7 @@ class Disk(ConfigObject):
     """
     if self.dev_type == constants.LD_LV or self.dev_type == constants.LD_MD_R1:
       result = [node]
-    elif self.dev_type == constants.LD_DRBD7:
+    elif self.dev_type in constants.LDS_DRBD:
       result = [self.logical_id[0], self.logical_id[1]]
       if node not in result:
         raise errors.ConfigurationError("DRBD device passed unknown node")
@@ -436,7 +438,7 @@ class Instance(TaggableObject):
     """
     def _Helper(primary, sec_nodes, device):
       """Recursively computes secondary nodes given a top device."""
-      if device.dev_type == constants.LD_DRBD7:
+      if device.dev_type in constants.LDS_DRBD:
         nodea, nodeb, dummy = device.logical_id
         if nodea == primary:
           candidate = nodeb
@@ -488,7 +490,7 @@ class Instance(TaggableObject):
       if dev.dev_type == constants.LD_LV:
         lvmap[node].append(dev.logical_id[1])
 
-      elif dev.dev_type == constants.LD_DRBD7:
+      elif dev.dev_type in constants.LDS_DRBD:
         if dev.logical_id[0] not in lvmap:
           lvmap[dev.logical_id[0]] = []
 
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 9d78dff99f6ba4b8355c85d3b7abe3a6fcfcce9d..e1bb5af9b4bf1329fd8018a5ec0fe61e353024b5 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -503,7 +503,7 @@ def _FormatBlockDevInfo(buf, dev, indent_level):
     else:
       (path, major, minor, syncp, estt, degr) = status
       buf.write("%s (%d:%d)" % (path, major, minor))
-      if dtype in (constants.LD_MD_R1, constants.LD_DRBD7):
+      if dtype in (constants.LD_MD_R1, constants.LD_DRBD7, constants.LD_DRBD8):
         if syncp is not None:
           sync_text = "*RECOVERING* %5.2f%%," % syncp
           if estt:
@@ -661,8 +661,8 @@ add_opts = [
   make_option("-p", "--cpu", dest="vcpus", help="Number of virtual CPUs",
               default=1, type="int", metavar="<PROC>"),
   make_option("-t", "--disk-template", dest="disk_template",
-              help="Custom disk setup (diskless, plain, local_raid1 or"
-              " remote_raid1)", default=None, metavar="TEMPL"),
+              help="Custom disk setup (diskless, plain, local_raid1,"
+              " remote_raid1 or drbd)", default=None, metavar="TEMPL"),
   make_option("-i", "--ip", dest="ip",
               help="IP address ('none' [default], 'auto', or specify address)",
               default='none', type="string", metavar="<ADDRESS>"),