diff --git a/daemons/daemon-util.in b/daemons/daemon-util.in
index 5bf2c3fa0085286d7473e3a66469d8a499707117..b754e7f603a00769a2c7f6c833f2146c44fed6d8 100644
--- a/daemons/daemon-util.in
+++ b/daemons/daemon-util.in
@@ -203,6 +203,9 @@ start() {
   fi
 
   local name="$1"; shift
+  # Convert daemon name to uppercase after removing "ganeti-" prefix
+  local plain_name=${name#ganeti-}
+  local ucname=$(tr a-z A-Z <<<$plain_name)
   local pidfile=$(_daemon_pidfile $name)
   local usergroup=$(_daemon_usergroup $plain_name)
   local daemonexec=$(_daemon_executable $name)
@@ -213,10 +216,6 @@ start() {
     return 1
   fi
 
-  # Convert daemon name to uppercase after removing "ganeti-" prefix
-  local plain_name=${name#ganeti-}
-  local ucname=$(tr a-z A-Z <<<$plain_name)
-
   # Read $<daemon>_ARGS and $EXTRA_<daemon>_ARGS
   eval local args="\"\$${ucname}_ARGS \$EXTRA_${ucname}_ARGS\""
 
diff --git a/lib/bdev.py b/lib/bdev.py
index 310ddf877df3328ac281ebbfa1f7af6fed1db071..6c16da4250f590ef9e1e7fd1bd93d45a2414c2f9 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -1058,7 +1058,7 @@ class BaseDRBD(BlockDev): # pylint: disable=W0223
   def _CheckMetaSize(meta_device):
     """Check if the given meta device looks like a valid one.
 
-    This currently only check the size, which must be around
+    This currently only checks the size, which must be around
     128MiB.
 
     """
@@ -1197,7 +1197,7 @@ class DRBD8(BaseDRBD):
   def _GetShowParser(cls):
     """Return a parser for `drbd show` output.
 
-    This will either create or return an already-create parser for the
+    This will either create or return an already-created parser for the
     output of the command `drbd show`.
 
     """
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 34902d1270e914c3c08b4d2749e8458c0092dc3c..ba6661c3830310ff9929dc25831775a95d724f0e 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -10138,6 +10138,11 @@ class LUInstanceCreate(LogicalUnit):
     _ReleaseLocks(self, locking.LEVEL_NODE_RES)
 
     if iobj.disk_template != constants.DT_DISKLESS and not self.adopt_disks:
+      # we need to set the disks ID to the primary node, since the
+      # preceding code might or might have not done it, depending on
+      # disk template and other options
+      for disk in iobj.disks:
+        self.cfg.SetDiskID(disk, pnode_name)
       if self.op.mode == constants.INSTANCE_CREATE:
         if not self.op.no_install:
           pause_sync = (iobj.disk_template in constants.DTS_INT_MIRROR and
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 2d6e23b7bbee04d0dd47a466908a59fe027ca99a..087939e95574182d83ff0ff067ea60fa9374b6f6 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -936,6 +936,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       try:
         info = self.GetInstanceInfo(name)
       except errors.HypervisorError:
+        # Ignore exceptions due to instances being shut down
         continue
       if info:
         data.append(info)
diff --git a/lib/qlang.py b/lib/qlang.py
index 839a615baaf9fd0d1605a571410039161257750a..2923194f93d43dac948639390d13e569c5657821 100644
--- a/lib/qlang.py
+++ b/lib/qlang.py
@@ -58,12 +58,16 @@ OP_TRUE = "?"
 # operator-specific value
 OP_EQUAL = "="
 OP_NOT_EQUAL = "!="
+OP_LT = "<"
+OP_LE = "<="
+OP_GT = ">"
+OP_GE = ">="
 OP_REGEXP = "=~"
 OP_CONTAINS = "=[]"
 
 
 #: Characters used for detecting user-written filters (see L{_CheckFilter})
-FILTER_DETECTION_CHARS = frozenset("()=/!~'\"\\" + string.whitespace)
+FILTER_DETECTION_CHARS = frozenset("()=/!~'\"\\<>" + string.whitespace)
 
 #: Characters used to detect globbing filters (see L{_CheckGlobbing})
 GLOB_DETECTION_CHARS = frozenset("*?")
@@ -165,6 +169,10 @@ def BuildFilterParser():
   binopstbl = {
     "==": OP_EQUAL,
     "!=": OP_NOT_EQUAL,
+    "<": OP_LT,
+    "<=": OP_LE,
+    ">": OP_GT,
+    ">=": OP_GE,
     }
 
   binary_cond = (field_name + pyp.oneOf(binopstbl.keys()) + rval)
diff --git a/lib/query.py b/lib/query.py
index ffd4d204ce0b5b230d7828bce3bd8c3a28054e23..a8f19f0a5629cb429c0b5b4705c8fad8037af50c 100644
--- a/lib/query.py
+++ b/lib/query.py
@@ -403,6 +403,18 @@ class _FilterCompilerHelper:
     qlang.OP_NOT_EQUAL:
       (_OPTYPE_BINARY, [(flags, compat.partial(_WrapNot, fn), valprepfn)
                         for (flags, fn, valprepfn) in _EQUALITY_CHECKS]),
+    qlang.OP_LT: (_OPTYPE_BINARY, [
+      (None, operator.lt, None),
+      ]),
+    qlang.OP_GT: (_OPTYPE_BINARY, [
+      (None, operator.gt, None),
+      ]),
+    qlang.OP_LE: (_OPTYPE_BINARY, [
+      (None, operator.le, None),
+      ]),
+    qlang.OP_GE: (_OPTYPE_BINARY, [
+      (None, operator.ge, None),
+      ]),
     qlang.OP_REGEXP: (_OPTYPE_BINARY, [
       (None, lambda lhs, rhs: rhs.search(lhs), _PrepareRegex),
       ]),
diff --git a/man/ganeti.rst b/man/ganeti.rst
index 2d5c82f729f8fd49e6a76c493b3d9fe43f370d7e..d31adfca1bad7494b4354567e4225136e13a6a6c 100644
--- a/man/ganeti.rst
+++ b/man/ganeti.rst
@@ -362,7 +362,7 @@ Syntax in pseudo-BNF::
 
   <condition> ::=
     { /* Value comparison */
-      <field> { == | != } <value>
+      <field> { == | != | < | <= | >= | > } <value>
 
       /* Collection membership */
       | <value> [ not ] in <field>
@@ -389,6 +389,14 @@ Operators:
   Equality
 *!=*
   Inequality
+*<*
+  Less than
+*<=*
+  Less than or equal
+*>*
+  Greater than
+*>=*
+  Greater than or equal
 *=~*
   Pattern match using regular expression
 *!~*
diff --git a/man/gnt-cluster.rst b/man/gnt-cluster.rst
index fb28646eb01a83285e763c36d9de0f59746c1358..8082d14d94b85263fb8b696d579107ae1de32ef8 100644
--- a/man/gnt-cluster.rst
+++ b/man/gnt-cluster.rst
@@ -654,7 +654,7 @@ The ``continue`` option will let the watcher continue.
 
 The ``info`` option shows whether the watcher is currently paused.
 
-redist-conf
+REDIST-CONF
 ~~~~~~~~~~~
 
 **redist-conf** [\--submit]
diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst
index 6d3c1bab1c752ad7e9e366798009d6317579aa15..77bec0d5435e5537e46e1a9442d04ff605c5c4af 100644
--- a/man/gnt-instance.rst
+++ b/man/gnt-instance.rst
@@ -1250,7 +1250,7 @@ REPLACE-DISKS
 [\--disks *idx*] {*instance*}
 
 **replace-disks** [\--submit] [\--early-release] [\--ignore-ipolicy]
-{\--iallocator *name* \| \--node *node* } {*instance*}
+{{-I\|\--iallocator} *name* \| \--node *node* } {*instance*}
 
 **replace-disks** [\--submit] [\--early-release] [\--ignore-ipolicy]
 {\--auto} {*instance*}
diff --git a/qa/qa_instance.py b/qa/qa_instance.py
index 65af80e1c45eb9c6dd0ce3b46c6327914b78a594..5303f255a7a32ab9dd2ba8257f44f946e6f1ec7e 100644
--- a/qa/qa_instance.py
+++ b/qa/qa_instance.py
@@ -513,7 +513,7 @@ def _TestInstanceDiskFailure(instance, node, node2, onmaster):
     AssertCommand(" && ".join(cmds), node=[node2, node][int(onmaster)])
 
     print qa_utils.FormatInfo("Write to disks and give some time to notice"
-                              " to notice the problem")
+                              " the problem")
     cmds = []
     for disk in devpath:
       cmds.append(sq(["dd", "count=1", "bs=512", "conv=notrunc",
diff --git a/test/cfgupgrade_unittest.py b/test/cfgupgrade_unittest.py
index a8eb8bcd183aa0b61b56426dadb4ac4e38f6fb78..7ca5c3d017f6986ed9712ced92ad1f43ce5500f8 100755
--- a/test/cfgupgrade_unittest.py
+++ b/test/cfgupgrade_unittest.py
@@ -91,6 +91,7 @@ class TestCfgupgrade(unittest.TestCase):
     utils.WriteFile(self.config_path, data=serializer.DumpJson({
       "version": constants.CONFIG_VERSION,
       "cluster": {},
+      "instances": {},
       }))
 
     hostname = netutils.GetHostname().name
@@ -105,6 +106,7 @@ class TestCfgupgrade(unittest.TestCase):
     utils.WriteFile(self.config_path, data=serializer.DumpJson({
       "version": constants.CONFIG_VERSION,
       "cluster": {},
+      "instances": {},
       }))
 
     utils.WriteFile(self.ss_master_node_path,
@@ -120,6 +122,7 @@ class TestCfgupgrade(unittest.TestCase):
       "cluster": {
         "config_version": 0,
         },
+      "instances": {},
       }
     utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg))
     self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
@@ -134,6 +137,7 @@ class TestCfgupgrade(unittest.TestCase):
     cfg = {
       "version": from_version,
       "cluster": {},
+      "instances": {},
       }
     self._CreateValidConfigDir()
     utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg))
diff --git a/test/ganeti.qlang_unittest.py b/test/ganeti.qlang_unittest.py
index 02b953406655efa29cf6b7120507c0e7e8752e06..df249ec68915a8118d674ba14f17caad92df5ac4 100755
--- a/test/ganeti.qlang_unittest.py
+++ b/test/ganeti.qlang_unittest.py
@@ -147,6 +147,11 @@ class TestParseFilter(unittest.TestCase):
                [qlang.OP_NOT, [qlang.OP_REGEXP, "field",
                                utils.DnsNameGlobPattern("*.example.*")]])
 
+    self._Test("ctime < 1234", [qlang.OP_LT, "ctime", 1234])
+    self._Test("ctime > 1234", [qlang.OP_GT, "ctime", 1234])
+    self._Test("mtime <= 9999", [qlang.OP_LE, "mtime", 9999])
+    self._Test("mtime >= 9999", [qlang.OP_GE, "mtime", 9999])
+
   def testAllFields(self):
     for name in frozenset(i for d in query.ALL_FIELD_LISTS for i in d.keys()):
       self._Test("%s == \"value\"" % name, [qlang.OP_EQUAL, name, "value"])
@@ -167,6 +172,11 @@ class TestParseFilter(unittest.TestCase):
     # Non-matching regexp delimiters
     tests.append("name =~ /foobarbaz#")
 
+    # Invalid operators
+    tests.append("name <> value")
+    tests.append("name => value")
+    tests.append("name =< value")
+
     for qfilter in tests:
       try:
         qlang.ParseFilter(qfilter, parser=self.parser)
diff --git a/test/ganeti.query_unittest.py b/test/ganeti.query_unittest.py
index 87034436a03c4a9827da54b445aeaff9b182c219..ca83d1cc9c99ddecb45553730af2af5e98b8a64f 100755
--- a/test/ganeti.query_unittest.py
+++ b/test/ganeti.query_unittest.py
@@ -1745,6 +1745,38 @@ class TestQueryFilter(unittest.TestCase):
     self.assertRaises(errors.ParameterError, query.Query, fielddefs, ["name"],
                       qfilter=["=~", "name", r"["])
 
+  def testFilterLessGreater(self):
+    fielddefs = query._PrepareFieldList([
+      (query._MakeField("value", "Value", constants.QFT_NUMBER, "Value"),
+       None, 0, lambda ctx, item: item),
+      ], [])
+
+    data = range(100)
+
+    q = query.Query(fielddefs, ["value"],
+                    qfilter=["<", "value", 20])
+    self.assertTrue(q.RequestedNames() is None)
+    self.assertEqual(q.Query(data),
+                     [[(constants.RS_NORMAL, i)] for i in range(20)])
+
+    q = query.Query(fielddefs, ["value"],
+                    qfilter=["<=", "value", 30])
+    self.assertTrue(q.RequestedNames() is None)
+    self.assertEqual(q.Query(data),
+                     [[(constants.RS_NORMAL, i)] for i in range(31)])
+
+    q = query.Query(fielddefs, ["value"],
+                    qfilter=[">", "value", 40])
+    self.assertTrue(q.RequestedNames() is None)
+    self.assertEqual(q.Query(data),
+                     [[(constants.RS_NORMAL, i)] for i in range(41, 100)])
+
+    q = query.Query(fielddefs, ["value"],
+                    qfilter=[">=", "value", 50])
+    self.assertTrue(q.RequestedNames() is None)
+    self.assertEqual(q.Query(data),
+                     [[(constants.RS_NORMAL, i)] for i in range(50, 100)])
+
 
 if __name__ == "__main__":
   testutils.GanetiTestProgram()
diff --git a/tools/cfgupgrade b/tools/cfgupgrade
index 05022c906054e67857efdee49bbd235e8438dadf..81dce1dd2ce6378e09b1b9bcef6353f6acc05d08 100755
--- a/tools/cfgupgrade
+++ b/tools/cfgupgrade
@@ -188,6 +188,21 @@ def main():
     config_data["version"] = constants.BuildVersion(TARGET_MAJOR,
                                                     TARGET_MINOR, 0)
 
+    if "instances" not in config_data:
+      raise Error("Can't find the 'instances' key in the configuration!")
+    for instance, iobj in config_data["instances"].items():
+      if "disks" not in iobj:
+        raise Error("Instance '%s' doesn't have a disks entry?!" % instance)
+      disks = iobj["disks"]
+      for idx, dobj in enumerate(disks):
+        expected = "disk/%s" % idx
+        current = dobj.get("iv_name", "")
+        if current != expected:
+          logging.warning("Updating iv_name for instance %s/disk %s"
+                          " from '%s' to '%s'",
+                          instance, idx, current, expected)
+          dobj["iv_name"] = expected
+
   elif config_major == TARGET_MAJOR and config_minor == TARGET_MINOR:
     logging.info("No changes necessary")