diff --git a/lib/backend.py b/lib/backend.py
index 4e719ac6fbfbe6ae2914e10ea35500930395dde9..366a3b459cd0c0100f03bbd84dffd8bd6655104f 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -1774,14 +1774,16 @@ def DiagnoseOS(top_dirs=None):
       search (if not given defaults to
       L{constants.OS_SEARCH_PATH})
   @rtype: list of L{objects.OS}
-  @return: a list of tuples (name, path, status, diagnose, variants)
-      for all (potential) OSes under all search paths, where:
+  @return: a list of tuples (name, path, status, diagnose, variants,
+      parameters, api_version) for all (potential) OSes under all
+      search paths, where:
           - name is the (potential) OS name
           - path is the full path to the OS
           - status True/False is the validity of the OS
           - diagnose is the error message for an invalid OS, otherwise empty
           - variants is a list of supported OS variants, if any
           - parameters is a list of (name, help) parameters, if any
+          - api_version is a list of support OS API versions
 
   """
   if top_dirs is None:
@@ -1802,10 +1804,12 @@ def DiagnoseOS(top_dirs=None):
           diagnose = ""
           variants = os_inst.supported_variants
           parameters = os_inst.supported_parameters
+          api_versions = os_inst.api_versions
         else:
           diagnose = os_inst
-          variants = parameters = []
-        result.append((name, os_path, status, diagnose, variants, parameters))
+          variants = parameters = api_versions = []
+        result.append((name, os_path, status, diagnose, variants,
+                       parameters, api_versions))
 
   return result
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 029f641adf02d6f1e2c6f4914f3321e58abd930e..0941fa5e5ae78812bf618c185d66747b8fc2bf60 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2738,9 +2738,8 @@ class LUDiagnoseOS(NoHooksLU):
   _OP_REQP = ["output_fields", "names"]
   REQ_BGL = False
   _FIELDS_STATIC = utils.FieldSet()
-  _FIELDS_DYNAMIC = utils.FieldSet("name", "valid", "node_status", "variants")
-  # Fields that need calculation of global os validity
-  _FIELDS_NEEDVALID = frozenset(["valid", "variants"])
+  _FIELDS_DYNAMIC = utils.FieldSet("name", "valid", "node_status", "variants",
+                                   "parameters", "api_versions")
 
   def ExpandNames(self):
     if self.op.names:
@@ -2772,7 +2771,7 @@ class LUDiagnoseOS(NoHooksLU):
     @rtype: dict
     @return: a dictionary with osnames as keys and as value another
         map, with nodes as keys and tuples of (path, status, diagnose,
-        variants, parameters) as values, eg::
+        variants, parameters, api_versions) as values, eg::
 
           {"debian-etch": {"node1": [(/usr/lib/..., True, "", [], []),
                                      (/srv/..., False, "invalid api")],
@@ -2789,15 +2788,18 @@ class LUDiagnoseOS(NoHooksLU):
     for node_name, nr in rlist.items():
       if nr.fail_msg or not nr.payload:
         continue
-      for name, path, status, diagnose, variants, params in nr.payload:
+      for (name, path, status, diagnose, variants,
+           params, api_versions) in nr.payload:
         if name not in all_os:
           # build a list of nodes for this os containing empty lists
           # for each node in node_list
           all_os[name] = {}
           for nname in good_nodes:
             all_os[name][nname] = []
+        # convert params from [name, help] to (name, help)
+        params = [tuple(v) for v in params]
         all_os[name][node_name].append((path, status, diagnose,
-                                        variants, params))
+                                        variants, params, api_versions))
     return all_os
 
   def Exec(self, feedback_fn):
@@ -2808,25 +2810,25 @@ class LUDiagnoseOS(NoHooksLU):
     node_data = self.rpc.call_os_diagnose(valid_nodes)
     pol = self._DiagnoseByOS(node_data)
     output = []
-    calc_valid = self._FIELDS_NEEDVALID.intersection(self.op.output_fields)
-    calc_variants = "variants" in self.op.output_fields
 
     for os_name, os_data in pol.items():
       row = []
-      if calc_valid:
-        valid = True
-        variants = None
-        for osl in os_data.values():
-          valid = bool(valid and osl and osl[0][1])
-          if not valid:
-            variants = set()
-            break
-          if calc_variants:
-            node_variants = osl[0][3]
-            if variants is None:
-              variants = set(node_variants)
-            else:
-              variants.intersection_update(node_variants)
+      valid = True
+      (variants, params, api_versions) = null_state = (set(), set(), set())
+      for idx, osl in enumerate(os_data.values()):
+        valid = bool(valid and osl and osl[0][1])
+        if not valid:
+          (variants, params, api_versions) = null_state
+          break
+        node_variants, node_params, node_api = osl[0][3:6]
+        if idx == 0: # first entry
+          variants = set(node_variants)
+          params = set(node_params)
+          api_versions = set(node_api)
+        else: # keep consistency
+          variants.intersection_update(node_variants)
+          params.intersection_update(node_params)
+          api_versions.intersection_update(node_api)
 
       for field in self.op.output_fields:
         if field == "name":
@@ -2840,6 +2842,10 @@ class LUDiagnoseOS(NoHooksLU):
             val[node_name] = nos_list
         elif field == "variants":
           val = list(variants)
+        elif field == "parameters":
+          val = list(params)
+        elif field == "api_versions":
+          val = list(api_versions)
         else:
           raise errors.ParameterError(field)
         row.append(val)
diff --git a/scripts/gnt-os b/scripts/gnt-os
index e7177c3333a9bbaeeb01fa51f58e0b97167649ae..ef42106e493ec3cabc8f4ec85b44670c07b9d78c 100755
--- a/scripts/gnt-os
+++ b/scripts/gnt-os
@@ -114,17 +114,18 @@ def DiagnoseOS(opts, args):
       nodes_hidden[node_name] = []
       if node_info: # at least one entry in the per-node list
         (first_os_path, first_os_status, first_os_msg,
-         first_os_variants, _) = node_info.pop(0)
+         first_os_variants, _, first_os_api) = node_info.pop(0)
         if not first_os_variants:
           first_os_variants = []
-        first_os_msg = ("%s (path: %s) [variants: %s]" %
+        first_os_msg = ("%s (path: %s) [variants: %s] [api: %s]" %
                         (_OsStatus(first_os_status, first_os_msg),
-                         first_os_path, utils.CommaJoin(first_os_variants)))
+                         first_os_path, utils.CommaJoin(first_os_variants),
+                         utils.CommaJoin(first_os_api)))
         if first_os_status:
           nodes_valid[node_name] = first_os_msg
         else:
           nodes_bad[node_name] = first_os_msg
-        for hpath, hstatus, hmsg in node_info:
+        for hpath, hstatus, hmsg, _, _, _ in node_info:
           nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
                                          (hpath, _OsStatus(hstatus, hmsg)))
       else: