diff --git a/lib/cli.py b/lib/cli.py
index 1de60a02f3f90b1916739c6d29aa56b6aea80e72..92877e2fd6381b94156e215b2a89ab792b59b2c1 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -87,6 +87,7 @@ __all__ = [
   "MAINTAIN_NODE_HEALTH_OPT",
   "MASTER_NETDEV_OPT",
   "MC_OPT",
+  "MIGRATION_TYPE_OPT",
   "NET_OPT",
   "NEW_CLUSTER_CERT_OPT",
   "NEW_CLUSTER_DOMAIN_SECRET_OPT",
@@ -698,6 +699,12 @@ NONLIVE_OPT = cli_option("--non-live", dest="live",
                          " freeze the instance, save the state, transfer and"
                          " only then resume running on the secondary node)")
 
+MIGRATION_TYPE_OPT = cli_option("--migration-type", dest="migration_type",
+                                default=None,
+                                choices=list(constants.HT_MIGRATION_TYPES),
+                                help="Override default migration type (choose"
+                                " either live or non-live")
+
 NODE_PLACEMENT_OPT = cli_option("-n", "--node", dest="node",
                                 help="Target node and optional secondary node",
                                 metavar="<pnode>[:<snode>]",
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 37fcca58d430366b6d149c697a28adad2e477c09..d65b8f5403b9a3fb75944409feffcfd424d4bbd8 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -232,6 +232,10 @@ _PInstanceName = ("instance_name", _NoDefault, _TNonEmptyString)
 #: a required node name (for single-node LUs)
 _PNodeName = ("node_name", _NoDefault, _TNonEmptyString)
 
+#: the migration type (live/non-live)
+_PMigrationLive = ("live", None, _TOr(_TNone,
+                                      _TElemOf(constants.HT_MIGRATION_TYPES)))
+
 
 # End types
 class LogicalUnit(object):
@@ -5486,7 +5490,7 @@ class LUMigrateInstance(LogicalUnit):
   HTYPE = constants.HTYPE_INSTANCE
   _OP_PARAMS = [
     _PInstanceName,
-    ("live", True, _TBool),
+    _PMigrationLive,
     ("cleanup", False, _TBool),
     ]
 
@@ -5499,7 +5503,7 @@ class LUMigrateInstance(LogicalUnit):
     self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_REPLACE
 
     self._migrater = TLMigrateInstance(self, self.op.instance_name,
-                                       self.op.live, self.op.cleanup)
+                                       self.op.cleanup)
     self.tasklets = [self._migrater]
 
   def DeclareLocks(self, level):
@@ -5717,7 +5721,7 @@ class LUMigrateNode(LogicalUnit):
   HTYPE = constants.HTYPE_NODE
   _OP_PARAMS = [
     _PNodeName,
-    ("live", False, _TBool),
+    _PMigrationLive,
     ]
   REQ_BGL = False
 
@@ -5738,7 +5742,7 @@ class LUMigrateNode(LogicalUnit):
       logging.debug("Migrating instance %s", inst.name)
       names.append(inst.name)
 
-      tasklets.append(TLMigrateInstance(self, inst.name, self.op.live, False))
+      tasklets.append(TLMigrateInstance(self, inst.name, False))
 
     self.tasklets = tasklets
 
@@ -5765,7 +5769,7 @@ class LUMigrateNode(LogicalUnit):
 
 
 class TLMigrateInstance(Tasklet):
-  def __init__(self, lu, instance_name, live, cleanup):
+  def __init__(self, lu, instance_name, cleanup):
     """Initializes this class.
 
     """
@@ -5773,8 +5777,8 @@ class TLMigrateInstance(Tasklet):
 
     # Parameters
     self.instance_name = instance_name
-    self.live = live
     self.cleanup = cleanup
+    self.live = False # will be overridden later
 
   def CheckPrereq(self):
     """Check prerequisites.
@@ -5815,6 +5819,13 @@ class TLMigrateInstance(Tasklet):
 
     self.instance = instance
 
+    if self.lu.op.live is None:
+      # read the default value from the hypervisor
+      i_hv = self.cfg.GetClusterInfo().FillHV(instance, skip_globals=False)
+      self.lu.op.live = i_hv[constants.HV_MIGRATION_TYPE]
+
+    self.live = self.lu.op.live == constants.HT_MIGRATION_LIVE
+
   def _WaitUntilSync(self):
     """Poll with custom rpc for disk sync.
 
diff --git a/lib/constants.py b/lib/constants.py
index 0a4687b8cee0dc3d8da2fd3e69c957917a13df0a..4b6d4188363fe45c02b49eae454610fcf9e15ead 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -537,6 +537,7 @@ HV_INIT_SCRIPT = "init_script"
 HV_MIGRATION_PORT = "migration_port"
 HV_MIGRATION_BANDWIDTH = "migration_bandwidth"
 HV_MIGRATION_DOWNTIME = "migration_downtime"
+HV_MIGRATION_TYPE = "migration_type"
 HV_USE_LOCALTIME = "use_localtime"
 HV_DISK_CACHE = "disk_cache"
 HV_SECURITY_MODEL = "security_model"
@@ -571,6 +572,7 @@ HVS_PARAMETER_TYPES = {
   HV_MIGRATION_PORT: VTYPE_INT,
   HV_MIGRATION_BANDWIDTH: VTYPE_INT,
   HV_MIGRATION_DOWNTIME: VTYPE_INT,
+  HV_MIGRATION_TYPE: VTYPE_STRING,
   HV_USE_LOCALTIME: VTYPE_BOOL,
   HV_DISK_CACHE: VTYPE_STRING,
   HV_SECURITY_MODEL: VTYPE_STRING,
@@ -717,6 +719,11 @@ HT_KVM_DISABLED = "disabled"
 
 HT_KVM_FLAG_VALUES = frozenset([HT_KVM_ENABLED, HT_KVM_DISABLED])
 
+# Migration type
+HT_MIGRATION_LIVE = "live"
+HT_MIGRATION_NONLIVE = "non-live"
+HT_MIGRATION_TYPES = frozenset([HT_MIGRATION_LIVE, HT_MIGRATION_NONLIVE])
+
 # Cluster Verify steps
 VERIFY_NPLUSONE_MEM = 'nplusone_mem'
 VERIFY_OPTIONAL_CHECKS = frozenset([VERIFY_NPLUSONE_MEM])
@@ -859,6 +866,7 @@ HVC_DEFAULTS = {
     HV_ROOT_PATH: '/dev/sda1',
     HV_KERNEL_ARGS: 'ro',
     HV_MIGRATION_PORT: 8002,
+    HV_MIGRATION_TYPE: HT_MIGRATION_LIVE,
     },
   HT_XEN_HVM: {
     HV_BOOT_ORDER: "cd",
@@ -872,6 +880,7 @@ HVC_DEFAULTS = {
     HV_KERNEL_PATH: "/usr/lib/xen/boot/hvmloader",
     HV_DEVICE_MODEL: "/usr/lib/xen/bin/qemu-dm",
     HV_MIGRATION_PORT: 8002,
+    HV_MIGRATION_TYPE: HT_MIGRATION_NONLIVE,
     HV_USE_LOCALTIME: False,
     },
   HT_KVM: {
@@ -894,6 +903,7 @@ HVC_DEFAULTS = {
     HV_MIGRATION_PORT: 8102,
     HV_MIGRATION_BANDWIDTH: 32, # MiB/s
     HV_MIGRATION_DOWNTIME: 30,  # ms
+    HV_MIGRATION_TYPE: HT_MIGRATION_LIVE,
     HV_USE_LOCALTIME: False,
     HV_DISK_CACHE: HT_CACHE_DEFAULT,
     HV_SECURITY_MODEL: HT_SM_NONE,
@@ -914,6 +924,7 @@ HVC_DEFAULTS = {
 HVC_GLOBALS = frozenset([
   HV_MIGRATION_PORT,
   HV_MIGRATION_BANDWIDTH,
+  HV_MIGRATION_TYPE,
   ])
 
 BEC_DEFAULTS = {
diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py
index cd9632484217548f9e9461a65d7946d190e355f7..6bcf6d7bf5243ed9acb01e9fc77e42d295cbd2eb 100644
--- a/lib/hypervisor/hv_base.py
+++ b/lib/hypervisor/hv_base.py
@@ -44,6 +44,7 @@ import logging
 
 from ganeti import errors
 from ganeti import utils
+from ganeti import constants
 
 
 # Read the BaseHypervisor.PARAMETERS docstring for the syntax of the
@@ -71,6 +72,10 @@ NO_CHECK = (False, None, None, None, None)
 # required, but no other checks
 REQUIRED_CHECK = (True, None, None, None, None)
 
+# migration type
+MIGRATION_TYPE_CHECK = (True, lambda x: x in constants.HT_MIGRATION_TYPES,
+                        "invalid migration type", None, None)
+
 
 def ParamInSet(required, my_set):
   """Builds parameter checker for set membership.
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 35082a7cd0a71b2058526c2fbce3684cebc6fa06..7ddd46b3ae4d2c3d090c83be12697fed831c08c5 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -194,6 +194,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     constants.HV_MIGRATION_PORT: hv_base.NET_PORT_CHECK,
     constants.HV_MIGRATION_BANDWIDTH: hv_base.NO_CHECK,
     constants.HV_MIGRATION_DOWNTIME: hv_base.NO_CHECK,
+    constants.HV_MIGRATION_TYPE: hv_base.MIGRATION_TYPE_CHECK,
     constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
     constants.HV_DISK_CACHE:
       hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index 4f53d7f1bada44c67d893beb116361e5fb46fc6c..a020358679312aa71f3fd2c5aa438fe9d4cdaa85 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -458,6 +458,7 @@ class XenPvmHypervisor(XenHypervisor):
     constants.HV_ROOT_PATH: hv_base.REQUIRED_CHECK,
     constants.HV_KERNEL_ARGS: hv_base.NO_CHECK,
     constants.HV_MIGRATION_PORT: hv_base.NET_PORT_CHECK,
+    constants.HV_MIGRATION_TYPE: hv_base.MIGRATION_TYPE_CHECK,
     }
 
   @classmethod
@@ -556,6 +557,7 @@ class XenHvmHypervisor(XenHypervisor):
     constants.HV_DEVICE_MODEL: hv_base.REQ_FILE_CHECK,
     constants.HV_VNC_PASSWORD_FILE: hv_base.REQ_FILE_CHECK,
     constants.HV_MIGRATION_PORT: hv_base.NET_PORT_CHECK,
+    constants.HV_MIGRATION_TYPE: hv_base.MIGRATION_TYPE_CHECK,
     constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
     }
 
diff --git a/man/gnt-instance.sgml b/man/gnt-instance.sgml
index dd68fd15c6282d986e285af0da70a829376ac96a..b12337506835835051d9912fcd8ac13cbc6439b4 100644
--- a/man/gnt-instance.sgml
+++ b/man/gnt-instance.sgml
@@ -2389,6 +2389,7 @@ node1.example.com:disk/1:/dev/drbd1
           <command>migrate</command>
           <arg>-f</arg>
           <arg>--non-live</arg>
+          <arg>--migration-type=live|non-live</arg>
           <arg choice="req"><replaceable>instance</replaceable></arg>
         </cmdsynopsis>
 
@@ -2405,15 +2406,21 @@ node1.example.com:disk/1:/dev/drbd1
         </para>
 
         <para>
-          The <option>--non-live</option> option will switch (for the
-          hypervisors that support it) between a "fully live"
-          (i.e. the interruption is as minimal as possible) migration
-          and one in which the instance is frozen, its state saved and
-          transported to the remote node, and then resumed there. This
-          all depends on the hypervisor support for two different
-          methods. In any case, it is not an error to pass this
-          parameter (it will just be ignored if the hypervisor doesn't
-          support it).
+          The <option>--non-live</option>
+          and <option>--migration-type=non-live</option> options will
+          switch (for the hypervisors that support it) between a
+          "fully live" (i.e. the interruption is as minimal as
+          possible) migration and one in which the instance is frozen,
+          its state saved and transported to the remote node, and then
+          resumed there. This all depends on the hypervisor support
+          for two different methods. In any case, it is not an error
+          to pass this parameter (it will just be ignored if the
+          hypervisor doesn't support it). The
+          option <option>--migration-type=live</option> option will
+          request a fully-live migration. The default, when neither
+          option is passed, depends on the hypervisor parameters (and
+          can be viewed with the <command>gnt-cluster info</command>
+          command).
         </para>
 
         <para>
diff --git a/man/gnt-node.sgml b/man/gnt-node.sgml
index c8509d672810623e705e2a6e775af4a4b8619f65..ea20e32daa788d4141d3c458edfa9ddb8a1962b5 100644
--- a/man/gnt-node.sgml
+++ b/man/gnt-node.sgml
@@ -571,6 +571,7 @@
         <command>migrate</command>
         <arg>-f</arg>
         <arg>--non-live</arg>
+        <arg>--migration-type=live|non-live</arg>
         <arg choice="req"><replaceable>node</replaceable></arg>
       </cmdsynopsis>
 
@@ -582,8 +583,9 @@
 
       <para>
         As for the <command>gnt-instance migrate</command> command,
-        the <option>--no-live</option> option can be given to do a
-        non-live migration.
+        the options <option>--no-live</option>
+        and <option>--migration-type</option> can be given to
+        influence the migration type.
       </para>
 
       <para>
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 1bddbc9caf3cbd7535b65e95625e172dcfe1fe4c..0502cdea3788092f7fdd53090ec2fb5d4b0faffb 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -897,7 +897,17 @@ def MigrateInstance(opts, args):
     if not AskUser(usertext):
       return 1
 
-  op = opcodes.OpMigrateInstance(instance_name=instance_name, live=opts.live,
+  # this should be removed once --non-live is deprecated
+  if not opts.live and opts.migration_type is not None:
+    raise errors.OpPrereqError("Only one of the --non-live and "
+                               "--migration-type options can be passed",
+                               errors.ECODE_INVAL)
+  if not opts.live: # --non-live passed
+    live = constants.HT_MIGRATION_NONLIVE
+  else:
+    live = opts.migration_type
+
+  op = opcodes.OpMigrateInstance(instance_name=instance_name, live=live,
                                  cleanup=opts.cleanup)
   SubmitOpCode(op, cl=cl, opts=opts)
   return 0
@@ -1409,7 +1419,7 @@ commands = {
     " using the remote mirror (only for instances of type drbd)"),
   'migrate': (
     MigrateInstance, ARGS_ONE_INSTANCE,
-    [FORCE_OPT, NONLIVE_OPT, CLEANUP_OPT],
+    [FORCE_OPT, NONLIVE_OPT, MIGRATION_TYPE_OPT, CLEANUP_OPT],
     "[-f] <instance>", "Migrate instance to its secondary node"
     " (only for instances of type drbd)"),
   'move': (
diff --git a/scripts/gnt-node b/scripts/gnt-node
index 75161017b35d845f4eb27daf490bdaaa169bb5cd..363b676dd2e5e9ecdeaf559454c72a0fca521ec6 100755
--- a/scripts/gnt-node
+++ b/scripts/gnt-node
@@ -360,7 +360,16 @@ def MigrateNode(opts, args):
                                (",".join("'%s'" % name for name in pinst))):
     return 2
 
-  op = opcodes.OpMigrateNode(node_name=args[0], live=opts.live)
+  # this should be removed once --non-live is deprecated
+  if not opts.live and opts.migration_type is not None:
+    raise errors.OpPrereqError("Only one of the --non-live and "
+                               "--migration-type options can be passed",
+                               errors.ECODE_INVAL)
+  if not opts.live: # --non-live passed
+    live = constants.HT_MIGRATION_NONLIVE
+  else:
+    live = opts.migration_type
+  op = opcodes.OpMigrateNode(node_name=args[0], live=live)
   SubmitOpCode(op, cl=cl, opts=opts)
 
 
@@ -652,7 +661,7 @@ commands = {
     "Stops the primary instances on a node and start them on their"
     " secondary node (only for instances with drbd disk template)"),
   'migrate': (
-    MigrateNode, ARGS_ONE_NODE, [FORCE_OPT, NONLIVE_OPT],
+    MigrateNode, ARGS_ONE_NODE, [FORCE_OPT, NONLIVE_OPT, MIGRATION_TYPE_OPT],
     "[-f] <node>",
     "Migrate all the primary instance on a node away from it"
     " (only for instances of type drbd)"),