diff --git a/NEWS b/NEWS
index 562f06ebb7d0a3c3be00d09755221e12a3ae9116..20c283692ee10263531681201728a9276b41758c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,66 @@ News
 ====
 
 
+Version 2.6.2
+-------------
+
+*(Released Fri, 21 Dec 2012)*
+
+Important behaviour change: hbal won't rebalance anymore instances which
+have the ``auto_balance`` attribute set to false. This was the intention
+all along, but until now it only skipped those from the N+1 memory
+reservation (DRBD-specific).
+
+A significant number of bug fixes in this release:
+
+- Fixed disk adoption interaction with ipolicy checks.
+- Fixed networking issues when instances are started, stopped or
+  migrated, by forcing the tap device's MAC prefix to "fe" (issue 217).
+- Fixed the warning in cluster verify for shared storage instances not
+  being redundant.
+- Fixed removal of storage directory on shared file storage (issue 262).
+- Fixed validation of LVM volume group name in OpClusterSetParams
+  (``gnt-cluster modify``) (issue 285).
+- Fixed runtime memory increases (``gnt-instance modify -m``).
+- Fixed live migration under Xen's ``xl`` mode.
+- Fixed ``gnt-instance console`` with ``xl``.
+- Fixed building with newer Haskell compiler/libraries.
+- Fixed PID file writing in Haskell daemons (confd); this prevents
+  restart issues if confd was launched manually (outside of
+  ``daemon-util``) while another copy of it was running
+- Fixed a type error when doing live migrations with KVM (issue 297) and
+  the error messages for failing migrations have been improved.
+- Fixed opcode validation for the out-of-band commands (``gnt-node
+  power``).
+- Fixed a type error when unsetting OS hypervisor parameters (issue
+  311); now it's possible to unset all OS-specific hypervisor
+  parameters.
+- Fixed the ``dry-run`` mode for many operations: verification of
+  results was over-zealous but didn't take into account the ``dry-run``
+  operation, resulting in "wrong" failures.
+- Fixed bash completion in ``gnt-job list`` when the job queue has
+  hundreds of entries; especially with older ``bash`` versions, this
+  results in significant CPU usage.
+
+And lastly, a few other improvements have been made:
+
+- Added option to force master-failover without voting (issue 282).
+- Clarified error message on lock conflict (issue 287).
+- Logging of newly submitted jobs has been improved (issue 290).
+- Hostname checks have been made uniform between instance rename and
+  create (issue 291).
+- The ``--submit`` option is now supported by ``gnt-debug delay``.
+- Shutting down the master daemon by sending SIGTERM now stops it from
+  processing jobs waiting for locks; instead, those jobs will be started
+  once again after the master daemon is started the next time (issue
+  296).
+- Support for Xen's ``xl`` program has been improved (besides the fixes
+  above).
+- Reduced logging noise in the Haskell confd daemon (only show one log
+  entry for each config reload, instead of two).
+- Several man page updates and typo fixes.
+
+
 Version 2.6.1
 -------------
 
diff --git a/autotools/build-bash-completion b/autotools/build-bash-completion
index 0cae30158ea695312113e4d2f7d79aabfcc2d2ed..b60afcac6acfd02a21aa60782f7d03b4c882c88c 100755
--- a/autotools/build-bash-completion
+++ b/autotools/build-bash-completion
@@ -99,10 +99,10 @@ def WritePreamble(sw):
   sw.IncIndent()
   try:
     # FIXME: this is really going into the internals of the job queue
-    sw.Write(("local jlist=$( shopt -s nullglob &&"
-              " cd %s 2>/dev/null && echo job-* || : )"),
+    sw.Write(("local jlist=($( shopt -s nullglob &&"
+              " cd %s 2>/dev/null && echo job-* || : ))"),
              utils.ShellQuote(constants.QUEUE_DIR))
-    sw.Write('echo "${jlist//job-/}"')
+    sw.Write('echo "${jlist[@]/job-/}"')
   finally:
     sw.DecIndent()
   sw.Write("}")
diff --git a/configure.ac b/configure.ac
index 86298ceacf4fc9aba7aa90d5da74ce3829fbd175..b6cb0e2cf4e871e2855ec756600cdfcd5273debc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 # Configure script for Ganeti
 m4_define([gnt_version_major], [2])
 m4_define([gnt_version_minor], [6])
-m4_define([gnt_version_revision], [1])
+m4_define([gnt_version_revision], [2])
 m4_define([gnt_version_suffix], [])
 m4_define([gnt_version_full],
           m4_format([%d.%d.%d%s],
diff --git a/htools/Ganeti/Confd/Server.hs b/htools/Ganeti/Confd/Server.hs
index 14997625280ee8cc2ffd98f5375c5a7b4409d9bb..b562ef7de2aac3c5bc0b0533880c49df622cc5f9 100644
--- a/htools/Ganeti/Confd/Server.hs
+++ b/htools/Ganeti/Confd/Server.hs
@@ -438,7 +438,7 @@ addNotifier inotify path cref mstate = do
 -- | Inotify event handler.
 onInotify :: INotify -> String -> CRef -> MVar ServerState -> Event -> IO ()
 onInotify inotify path cref mstate Ignored = do
-  logInfo "File lost, trying to re-establish notifier"
+  logDebug "File lost, trying to re-establish notifier"
   modifyMVar_ mstate $ \state -> do
     result <- addNotifier inotify path cref mstate
     (newfstat, _) <- safeUpdateConfig path (reloadFStat state) cref
diff --git a/htools/Ganeti/HTools/Cluster.hs b/htools/Ganeti/HTools/Cluster.hs
index 0ccf3bdcdf27e714a7635ff18fd0d63504b52454..f5dc960ffb6762353955f0ac1d6a14ee0fbdb6af 100644
--- a/htools/Ganeti/HTools/Cluster.hs
+++ b/htools/Ganeti/HTools/Cluster.hs
@@ -630,7 +630,8 @@ tryBalance ini_tbl disk_moves inst_moves evac_mode mg_limit min_gain =
                            in filter (any (`elem` bad_nodes) .
                                           Instance.allNodes) all_inst
                       else all_inst
-        reloc_inst = filter Instance.movable all_inst'
+        reloc_inst = filter (\i -> Instance.movable i &&
+                                   Instance.autoBalance i) all_inst'
         node_idx = map Node.idx online_nodes
         fin_tbl = checkMove node_idx disk_moves inst_moves ini_tbl reloc_inst
         (Table _ _ fin_cv _) = fin_tbl
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 8025353520f337485c78cc04b450c163e82b0a66..c3d639eb7c1be541b50ece13d5fa44bf1e25b6c9 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1984,7 +1984,7 @@ class LUClusterVerifyConfig(NoHooksLU, _VerifyErrors):
       msg = ("hypervisor %s parameters syntax check (source %s): %%s" %
              (item, hv_name))
       try:
-        hv_class = hypervisor.GetHypervisor(hv_name)
+        hv_class = hypervisor.GetHypervisorClass(hv_name)
         utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES)
         hv_class.CheckParameterSyntax(hv_params)
       except errors.GenericError, err:
@@ -4088,7 +4088,10 @@ class LUClusterSetParams(LogicalUnit):
           self.new_os_hvp[os_name] = hvs
         else:
           for hv_name, hv_dict in hvs.items():
-            if hv_name not in self.new_os_hvp[os_name]:
+            if hv_dict is None:
+              # Delete if it exists
+              self.new_os_hvp[os_name].pop(hv_name, None)
+            elif hv_name not in self.new_os_hvp[os_name]:
               self.new_os_hvp[os_name][hv_name] = hv_dict
             else:
               self.new_os_hvp[os_name][hv_name].update(hv_dict)
@@ -4134,7 +4137,7 @@ class LUClusterSetParams(LogicalUnit):
             (self.op.enabled_hypervisors and
              hv_name in self.op.enabled_hypervisors)):
           # either this is a new hypervisor, or its parameters have changed
-          hv_class = hypervisor.GetHypervisor(hv_name)
+          hv_class = hypervisor.GetHypervisorClass(hv_name)
           utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES)
           hv_class.CheckParameterSyntax(hv_params)
           _CheckHVParams(self, node_list, hv_name, hv_params)
@@ -4148,7 +4151,7 @@ class LUClusterSetParams(LogicalUnit):
           # we need to fill in the new os_hvp on top of the actual hv_p
           cluster_defaults = self.new_hvparams.get(hv_name, {})
           new_osp = objects.FillDict(cluster_defaults, hv_params)
-          hv_class = hypervisor.GetHypervisor(hv_name)
+          hv_class = hypervisor.GetHypervisorClass(hv_name)
           hv_class.CheckParameterSyntax(new_osp)
           _CheckHVParams(self, node_list, hv_name, new_osp)
 
@@ -4363,11 +4366,13 @@ def _ComputeAncillaryFiles(cluster, redist):
   # Files which should only be on VM-capable nodes
   files_vm = set(filename
     for hv_name in cluster.enabled_hypervisors
-    for filename in hypervisor.GetHypervisor(hv_name).GetAncillaryFiles()[0])
+    for filename in
+      hypervisor.GetHypervisorClass(hv_name).GetAncillaryFiles()[0])
 
   files_opt |= set(filename
     for hv_name in cluster.enabled_hypervisors
-    for filename in hypervisor.GetHypervisor(hv_name).GetAncillaryFiles()[1])
+    for filename in
+      hypervisor.GetHypervisorClass(hv_name).GetAncillaryFiles()[1])
 
   # Filenames in each category must be unique
   all_files_set = files_all | files_mc | files_vm
@@ -6756,7 +6761,7 @@ class LUInstanceStartup(LogicalUnit):
       utils.ForceDictType(self.op.hvparams, constants.HVS_PARAMETER_TYPES)
       filled_hvp = cluster.FillHV(instance)
       filled_hvp.update(self.op.hvparams)
-      hv_type = hypervisor.GetHypervisor(instance.hypervisor)
+      hv_type = hypervisor.GetHypervisorClass(instance.hypervisor)
       hv_type.CheckParameterSyntax(filled_hvp)
       _CheckHVParams(self, instance.all_nodes, instance.hypervisor, filled_hvp)
 
@@ -9728,7 +9733,7 @@ class LUInstanceCreate(LogicalUnit):
     utils.ForceDictType(self.op.hvparams, constants.HVS_PARAMETER_TYPES)
     filled_hvp = cluster.SimpleFillHV(self.op.hypervisor, self.op.os_type,
                                       self.op.hvparams)
-    hv_type = hypervisor.GetHypervisor(self.op.hypervisor)
+    hv_type = hypervisor.GetHypervisorClass(self.op.hypervisor)
     hv_type.CheckParameterSyntax(filled_hvp)
     self.hv_full = filled_hvp
     # check that we don't specify global parameters on an instance
@@ -10360,7 +10365,7 @@ def _GetInstanceConsole(cluster, instance):
   @rtype: dict
 
   """
-  hyper = hypervisor.GetHypervisor(instance.hypervisor)
+  hyper = hypervisor.GetHypervisorClass(instance.hypervisor)
   # beparams and hvparams are passed separately, to avoid editing the
   # instance and then saving the defaults in the instance itself.
   hvparams = cluster.FillHV(instance)
@@ -12454,7 +12459,7 @@ class LUInstanceSetParams(LogicalUnit):
       hv_new = cluster.SimpleFillHV(hv_type, instance.os, i_hvdict)
 
       # local check
-      hypervisor.GetHypervisor(hv_type).CheckParameterSyntax(hv_new)
+      hypervisor.GetHypervisorClass(hv_type).CheckParameterSyntax(hv_new)
       _CheckHVParams(self, nodelist, instance.hypervisor, hv_new)
       self.hv_proposed = self.hv_new = hv_new # the new actual values
       self.hv_inst = i_hvdict # the new dict (without defaults)
diff --git a/lib/mcpu.py b/lib/mcpu.py
index 6ecae61f77e6002470e64c0aa5ecaf620e7bbc79..84ea4158987d03d777a4f10a9f47fa0fb30aa0fe 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -470,8 +470,12 @@ class Processor(object):
     if not (resultcheck_fn is None or resultcheck_fn(result)):
       logging.error("Expected opcode result matching %s, got %s",
                     resultcheck_fn, result)
-      raise errors.OpResultError("Opcode result does not match %s: %s" %
-                                 (resultcheck_fn, utils.Truncate(result, 80)))
+      if not getattr(op, "dry_run", False):
+        # FIXME: LUs should still behave in dry_run mode, or
+        # alternately we should have OP_DRYRUN_RESULT; in the
+        # meantime, we simply skip the OP_RESULT check in dry-run mode
+        raise errors.OpResultError("Opcode result does not match %s: %s" %
+                                   (resultcheck_fn, utils.Truncate(result, 80)))
 
     return result
 
diff --git a/man/gnt-cluster.rst b/man/gnt-cluster.rst
index 6d1c77595347bef585beb0ab87d64a54cd48bacf..44e6aa1451840ffc4121d1752fc56029e531b665 100644
--- a/man/gnt-cluster.rst
+++ b/man/gnt-cluster.rst
@@ -193,7 +193,7 @@ INIT
 | [\--specs-disk-size *spec-param*=*value* [,*spec-param*=*value*...]]
 | [\--specs-mem-size *spec-param*=*value* [,*spec-param*=*value*...]]
 | [\--specs-nic-count *spec-param*=*value* [,*spec-param*=*value*...]]
-| [\--ipol-disk-templates *template* [,*template*...]]
+| [\--ipolicy-disk-templates *template* [,*template*...]]
 | [\--disk-state *diskstate*]
 | [\--hypervisor-state *hvstate*]
 | {*clustername*}
@@ -494,13 +494,13 @@ The ``-C (--candidate-pool-size)`` option specifies the
 that the master will try to keep as master\_candidates. For more
 details about this role and other node roles, see the ganeti(7).
 
-The ``--specs-...`` and ``--ipol-disk-templates`` options specify
+The ``--specs-...`` and ``--ipolicy-disk-templates`` options specify
 instance policy on the cluster. For the ``--specs-...`` options, each
 option can have three values: ``min``, ``max`` and ``std``, which can
 also be modified on group level (except for ``std``, which is defined
 once for the entire cluster). Please note, that ``std`` values are not
 the same as defaults set by ``--beparams``, but they are used for the
-capacity calculations. The ``--ipol-disk-templates`` option takes a
+capacity calculations. The ``--ipolicy-disk-templates`` option takes a
 comma-separated list of disk templates.
 
 - ``--specs-cpu-count`` limits the number of VCPUs that can be used by an
@@ -509,7 +509,7 @@ comma-separated list of disk templates.
 - ``--specs-disk-size`` limits the disk size for every disk used
 - ``--specs-mem-size`` limits the amount of memory available
 - ``--specs-nic-count`` sets limits on the number of NICs used
-- ``--ipol-disk-templates`` limits the allowed disk templates
+- ``--ipolicy-disk-templates`` limits the allowed disk templates
 
 For details about how to use ``--hypervisor-state`` and ``--disk-state``
 have a look at **ganeti**(7).
@@ -586,12 +586,12 @@ MODIFY
 | [\--specs-disk-size *spec-param*=*value* [,*spec-param*=*value*...]]
 | [\--specs-mem-size *spec-param*=*value* [,*spec-param*=*value*...]]
 | [\--specs-nic-count *spec-param*=*value* [,*spec-param*=*value*...]]
-| [\--ipol-disk-templates *template* [,*template*...]]
+| [\--ipolicy-disk-templates *template* [,*template*...]]
 
 
 Modify the options for the cluster.
 
-The ``--vg-name``, ``--no-lvm-storarge``, ``--enabled-hypervisors``,
+The ``--vg-name``, ``--no-lvm-storage``, ``--enabled-hypervisors``,
 ``-H (--hypervisor-parameters)``, ``-B (--backend-parameters)``,
 ``-D (--disk-parameters)``, ``--nic-parameters``, ``-C
 (--candidate-pool-size)``, ``--maintain-node-health``,
@@ -623,8 +623,8 @@ The ``-I (--default-iallocator)`` is described in the **init**
 command. To clear the default iallocator, just pass an empty string
 ('').
 
-The ``--specs-...`` and ``--ipol-disk-templates`` options are described
-in the **init** command.
+The ``--specs-...`` and ``--ipolicy-disk-templates`` options are
+described in the **init** command.
 
 See **ganeti(7)** for a description of ``--submit`` and other common
 options.
diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst
index 9c7c2a6ffc2fcfd6f21495021b0a5e3602664f10..82f95d211e1b9065545a958609a279e8cc3e24c1 100644
--- a/man/gnt-instance.rst
+++ b/man/gnt-instance.rst
@@ -1360,7 +1360,7 @@ GROW-DISK
 | {*instance*} {*disk*} {*amount*}
 
 Grows an instance's disk. This is only possible for instances having a
-plain, drbd or rbd disk template.
+plain, drbd, file, sharedfile or rbd disk template.
 
 Note that this command only change the block device size; it will not
 grow the actual filesystems, partitions, etc. that live on that
@@ -1598,7 +1598,7 @@ instance to stop.
 
 The ``--ignore-consistency`` option will make Ganeti ignore any errors
 in trying to shutdown the instance on its node; useful if the
-hypervisor is broken and you want to recuperate the data.
+hypervisor is broken and you want to recover the data.
 
 If ``--ignore-ipolicy`` is given any instance policy violations occuring
 during this operation are ignored.