]> xenbits.xensource.com Git - people/dariof/xen.git/commitdiff
libxl: introduce a way to mark fields as deprecated in the idl
authorRoger Pau Monne <roger.pau@citrix.com>
Thu, 28 Sep 2017 11:04:06 +0000 (12:04 +0100)
committerRoger Pau Monne <roger.pau@citrix.com>
Thu, 28 Sep 2017 11:04:06 +0000 (12:04 +0100)
The deprecation involves generating a function that copies the
deprecated fields into it's new location if the new location has not
been set.

The fields that are going to be shared between PVH and HVM or between
PVH and PV are moved to the top level of libxl_domain_build_info, and
the old locations are marked as deprecated.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxl/gentypes.py
tools/libxl/idl.py
tools/libxl/libxl_types.idl

index 4ea7091e6bda2be2e99622a808c65fe374a74733..76aca76aaae8d457087f7bc1180d384b383aa34d 100644 (file)
@@ -261,6 +261,67 @@ def libxl_C_type_gen_map_key(f, parent, indent = ""):
         s = indent + s
     return s.replace("\n", "\n%s" % indent).rstrip(indent)
 
+def libxl_C_type_copy_deprecated(field, v, indent = "    ", vparent = None):
+    s = ""
+
+    if isinstance(field.type, idl.KeyedUnion):
+        if vparent is None:
+            raise Exception("KeyedUnion type must have a parent")
+        s += "switch (%s) {\n" % (vparent + field.type.keyvar.name)
+        for f in [f for f in field.type.fields if not f.const]:
+            (vnparent,vfexpr) = ty.member(v, f, vparent is None)
+            s += "case %s:\n" % f.enumname
+            if f.type is not None:
+                s += libxl_C_type_copy_deprecated(f, vfexpr, indent, vnparent)
+            s+= "    break;\n"
+        s+="}\n";
+    elif isinstance(field.type, idl.Array) and field.deprecated_by:
+        raise Exception("Array type is not supported for deprecation")
+    elif isinstance(field.type, idl.Struct) and field.type.copy_fn is None:
+        for f in [f for f in field.type.fields if not f.const]:
+            (vnparent,vfexpr) = ty.member(v, f, vparent is None)
+            s += libxl_C_type_copy_deprecated(f, vfexpr, "", vnparent)
+    elif field.deprecated_by is not None:
+        if field.type.check_default_fn is None:
+            raise Exception(
+"Deprecated field %s type doesn't have a default value checker" % field.name)
+        field_val = field.type.pass_arg(v, vparent is None,
+                                        passby=idl.PASS_BY_VALUE)
+        field_ptr = field.type.pass_arg(v, vparent is None,
+                                        passby=idl.PASS_BY_REFERENCE)
+        s+= "if (!%s(&p->%s) && !%s(%s))\n" % (field.type.check_default_fn,
+                                               field.deprecated_by,
+                                               field.type.check_default_fn,
+                                               field_ptr)
+        s+= "    return -EINVAL;\n"
+        s+="(void) (&p->%s == %s);\n" % (field.deprecated_by, field_ptr)
+        s+= "if (%s(&p->%s)) {\n" % (field.type.check_default_fn,
+                                     field.deprecated_by)
+        s+= "    "
+        if field.type.copy_fn is not None:
+            s+= "%s(ctx, &p->%s, %s);\n" % (field.type.copy_fn,
+                                            field.deprecated_by, field_ptr)
+        else:
+            s+= "p->%s = %s;\n" % (field.deprecated_by, field_val)
+
+        if field.type.dispose_fn is not None:
+            s+= "    %s(%s);\n" % (field.type.dispose_fn,
+                                   field.type.pass_arg(v, vparent is None))
+
+        s+= "    "
+        if field.type.init_fn is not None:
+            s+= "%s(%s);\n" % (field.type.init_fn, field_ptr)
+        elif field.type.init_val is not None:
+            s+= "%s = %s;\n" % (field_val, field.type.init_val)
+        else:
+            s+= "memset(%s, 0, sizeof(*%s));\n" % (field_ptr, field_ptr)
+
+        s+= "}\n"
+
+    if s != "":
+        s = indent + s
+    return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
 def get_init_val(f):
     if f.init_val is not None:
         return f.init_val
@@ -543,6 +604,10 @@ if __name__ == '__main__':
         f.write(libxl_C_type_define(ty) + ";\n")
         if ty.dispose_fn is not None:
             f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.dispose_fn, ty.make_arg("p")))
+        if ty.copy_deprecated_fn is not None:
+            f.write("%sint %s(libxl_ctx *ctx, %s);\n" % (ty.hidden(),
+                                                         ty.copy_deprecated_fn,
+                                                         ty.make_arg("p")))
         if ty.copy_fn is not None:
             f.write("%svoid %s(libxl_ctx *ctx, %s, const %s);\n" % (ty.hidden(), ty.copy_fn,
                                               ty.make_arg("dst"), ty.make_arg("src")))
@@ -657,6 +722,18 @@ if __name__ == '__main__':
         f.write("}\n")
         f.write("\n")
         
+    for ty in [t for t in types if t.copy_deprecated_fn]:
+        f.write("int %s(libxl_ctx *ctx, %s)\n" % (ty.copy_deprecated_fn,
+            ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+        f.write("{\n")
+        for field in [field for field in ty.fields if not field.const]:
+            (vnparent,vfexpr) = ty.member("p", field, True)
+            f.write(libxl_C_type_copy_deprecated(field, vfexpr,
+                                                 vparent = vnparent))
+        f.write("    return 0;\n")
+        f.write("}\n")
+        f.write("\n")
+
     for ty in [t for t in types if t.init_fn is not None and t.autogenerate_init_fn]:
         f.write(libxl_C_type_init(ty))
         for field in libxl_init_members(ty):
index a4a084e1ce84442bbb6b7e936a52e7b1e1a5d698..2a7f3c44feb89bc8579f3be44af10419f85d3f02 100644 (file)
@@ -72,6 +72,8 @@ class Type(object):
         self.autogenerate_init_fn = kwargs.setdefault('autogenerate_init_fn', False)
 
         self.check_default_fn = kwargs.setdefault('check_default_fn', None)
+        self.copy_deprecated_fn = kwargs.setdefault('copy_deprecated_fn',
+                                                    None)
 
         if self.typename is not None and not self.private:
             self.json_gen_fn = kwargs.setdefault('json_gen_fn', self.typename + "_gen_json")
@@ -193,6 +195,7 @@ class Field(object):
         self.const = kwargs.setdefault('const', False)
         self.enumname = kwargs.setdefault('enumname', None)
         self.init_val = kwargs.setdefault('init_val', None)
+        self.deprecated_by = kwargs.setdefault('deprecated_by', None)
 
 class Aggregate(Type):
     """A type containing a collection of other types"""
index 6b56954bc3747d3cb64bbe6fef99a36750958890..df74e247913cc1274a9001768b4b230608d6b627 100644 (file)
@@ -510,11 +510,16 @@ libxl_domain_build_info = Struct("domain_build_info",[
     # 65000 which is reserved by the toolstack.
     ("device_tree",      string),
     ("acpi",             libxl_defbool),
+    ("bootloader",       string),
+    ("bootloader_args",  libxl_string_list),
+    ("timer_mode",       libxl_timer_mode),
+    ("nested_hvm",       libxl_defbool),
+    ("apic",             libxl_defbool),
     ("u", KeyedUnion(None, libxl_domain_type, "type",
                 [("hvm", Struct(None, [("firmware",         string),
                                        ("bios",             libxl_bios_type),
                                        ("pae",              libxl_defbool),
-                                       ("apic",             libxl_defbool),
+                                       ("apic",             libxl_defbool, {'deprecated_by': 'apic'}),
                                        # The following acpi field is deprecated.
                                        # Please use the unified acpi field above
                                        # which works for both x86 and ARM.
@@ -530,8 +535,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("hpet",             libxl_defbool),
                                        ("vpt_align",        libxl_defbool),
                                        ("mmio_hole_memkb",  MemKB),
-                                       ("timer_mode",       libxl_timer_mode),
-                                       ("nested_hvm",       libxl_defbool),
+                                       ("timer_mode",       libxl_timer_mode, {'deprecated_by': 'timer_mode'}),
+                                       ("nested_hvm",       libxl_defbool, {'deprecated_by': 'nested_hvm'}),
                                        # The u.hvm.altp2m field is used solely
                                        # for x86 HVM guests and is maintained
                                        # for legacy purposes.
@@ -572,8 +577,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ])),
                  ("pv", Struct(None, [("kernel", string),
                                       ("slack_memkb", MemKB),
-                                      ("bootloader", string),
-                                      ("bootloader_args", libxl_string_list),
+                                      ("bootloader", string, {'deprecated_by': 'bootloader'}),
+                                      ("bootloader_args", libxl_string_list, {'deprecated_by': 'bootloader_args'}),
                                       ("cmdline", string),
                                       ("ramdisk", string),
                                       ("features", string, {'const': True}),
@@ -590,7 +595,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
     # supported by x86 HVM and ARM support is planned.
     ("altp2m", libxl_altp2m_mode),
 
-    ], dir=DIR_IN
+    ], dir=DIR_IN,
+       copy_deprecated_fn="libxl__domain_build_info_copy_deprecated",
 )
 
 libxl_device_vfb = Struct("device_vfb", [