A random(ish) colletion of libxl patches. - Fixup idl infrastructure naming clash/annoyance - Consolidate libxl_button_press and libxl_send_trigger - Change the way libxl exposes CPU topology information to be a list of CPU (core,node,socket) tuples instead of three lists. This is a more sensible representation but is also a bit easier on the language bindings. Plus: - Cause xl to use JSON with the "xl create -d" option and similar output. This follows the 20 patches in my "libxl: drop device_model_info" series.
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327510508 0 # Node ID 9a366717e0c0a0e0261796669e9e96c0ba514923 # Parent 9b126ae26d95ff9c54beb7ff0908558d423ba098 libxl: Rename libxl IDL infrastructure. Originally libxltypes.py provided the infrastructure and libxl.idl provided the specific types. In 23887:a543e10211f7 libxl.idl became libxl_types.idl (to allow for libxl_types_internal.idl) which means we now have libxl_types.FOO and libxltypes.FOO providing different things and annoying people in tab completion. Rename the infrastructure as idl. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -107,7 +107,7 @@ libxl_internal_json.h: _libxl_types_inte $(LIBXL_OBJS) $(LIBXLU_OBJS) $(XL_OBJS): libxl.h $(LIBXL_OBJS): libxl_internal.h -_libxl_type%.h _libxl_type%_json.h _libxl_type%.c: libxl_type%.idl gentypes.py libxltypes.py +_libxl_type%.h _libxl_type%_json.h _libxl_type%.c: libxl_type%.idl gentypes.py idl.py $(PYTHON) gentypes.py libxl_type$*.idl __libxl_type$*.h __libxl_type$*_json.h __libxl_type$*.c $(call move-if-changed,__libxl_type$*.h,_libxl_type$*.h) $(call move-if-changed,__libxl_type$*_json.h,_libxl_type$*_json.h) diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py --- a/tools/libxl/gentest.py +++ b/tools/libxl/gentest.py @@ -4,7 +4,7 @@ import sys import re import random -import libxltypes +import idl def randomize_char(c): if random.random() < 0.5: @@ -25,9 +25,9 @@ handcoded = ["libxl_cpumap", "libxl_key_ def gen_rand_init(ty, v, indent = " ", parent = None): s = "" - if isinstance(ty, libxltypes.Enumeration): + if isinstance(ty, idl.Enumeration): s += "%s = %s;\n" % (ty.pass_arg(v, parent is None), randomize_enum(ty)) - elif isinstance(ty, libxltypes.KeyedUnion): + elif isinstance(ty, idl.KeyedUnion): if parent is None: raise Exception("KeyedUnion type must have a parent") s += "switch (%s) {\n" % (parent + ty.keyvar_name) @@ -37,7 +37,7 @@ def gen_rand_init(ty, v, indent = " " s += gen_rand_init(f.type, fexpr, indent + " ", nparent) s += " break;\n" s += "}\n" - elif isinstance(ty, libxltypes.Struct) \ + elif isinstance(ty, idl.Struct) \ and (parent is None or ty.json_fn is None): for f in [f for f in ty.fields if not f.const]: (nparent,fexpr) = ty.member(v, f, parent is None) @@ -45,10 +45,10 @@ def gen_rand_init(ty, v, indent = " " elif hasattr(ty, "rand_init") and ty.rand_init is not None: s += "%s(%s);\n" % (ty.rand_init, ty.pass_arg(v, isref=parent is None, - passby=libxltypes.PASS_BY_REFERENCE)) + passby=idl.PASS_BY_REFERENCE)) elif ty.typename in ["libxl_uuid", "libxl_mac", "libxl_hwcap"]: s += "rand_bytes((uint8_t *)%s, sizeof(*%s));\n" % (v,v) - elif ty.typename in ["libxl_domid"] or isinstance(ty, libxltypes.Number): + elif ty.typename in ["libxl_domid"] or isinstance(ty, idl.Number): s += "%s = rand() %% (sizeof(%s)*8);\n" % \ (ty.pass_arg(v, parent is None), ty.pass_arg(v, parent is None)) @@ -74,8 +74,7 @@ if __name__ == ''__main__'': random.seed() - idl = sys.argv[1] - (builtins,types) = libxltypes.parse(idl) + (builtins,types) = idl.parse(sys.argv[1]) impl = sys.argv[2] f = open(impl, "w") @@ -215,10 +214,10 @@ static void libxl_cpuarray_rand_init(lib if ty.typename not in handcoded: f.write("static void %s_rand_init(%s);\n" % \ (ty.typename, - ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE))) + ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) f.write("static void %s_rand_init(%s)\n" % \ (ty.typename, - ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE))) + ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) f.write("{\n") f.write(gen_rand_init(ty, "p")) f.write("}\n") @@ -252,7 +251,7 @@ int main(int argc, char **argv) for ty in [t for t in types if t.json_fn is not None]: arg = ty.typename + "_val" f.write(" %s_rand_init(%s);\n" % (ty.typename, \ - ty.pass_arg(arg, isref=False, passby=libxltypes.PASS_BY_REFERENCE))) + ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE))) f.write(" s = %s_to_json(ctx, %s);\n" % \ (ty.typename, ty.pass_arg(arg, isref=False))) f.write(" printf(\"%%s: %%s\\n\", \"%s\", s);\n" % ty.typename) @@ -265,7 +264,7 @@ int main(int argc, char **argv) f.write(" printf(\"Testing Enumerations\\n\");\n") f.write(" printf(\"--------------------\\n\");\n") f.write(" printf(\"\\n\");\n") - for ty in [t for t in types if isinstance(t,libxltypes.Enumeration)]: + for ty in [t for t in types if isinstance(t,idl.Enumeration)]: f.write(" printf(\"%s -- to string:\\n\");\n" % (ty.typename)) for v in ty.values: f.write(" printf(\"\\t%s = %%d = \\\"%%s\\\"\\n\", " \ diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py --- a/tools/libxl/gentypes.py +++ b/tools/libxl/gentypes.py @@ -3,10 +3,10 @@ import sys import re -import libxltypes +import idl def libxl_C_instance_of(ty, instancename): - if isinstance(ty, libxltypes.Aggregate) and ty.typename is None: + if isinstance(ty, idl.Aggregate) and ty.typename is None: if instancename is None: return libxl_C_type_define(ty) else: @@ -16,7 +16,7 @@ def libxl_C_instance_of(ty, instancename def libxl_C_type_define(ty, indent = ""): s = "" - if isinstance(ty, libxltypes.Enumeration): + if isinstance(ty, idl.Enumeration): if ty.typename is None: s += "enum {\n" else: @@ -31,7 +31,7 @@ def libxl_C_type_define(ty, indent = "") else: s += "} %s" % ty.typename - elif isinstance(ty, libxltypes.Aggregate): + elif isinstance(ty, idl.Aggregate): if ty.typename is None: s += "%s {\n" % ty.kind else: @@ -53,7 +53,7 @@ def libxl_C_type_define(ty, indent = "") def libxl_C_type_dispose(ty, v, indent = " ", parent = None): s = "" - if isinstance(ty, libxltypes.KeyedUnion): + if isinstance(ty, idl.KeyedUnion): if parent is None: raise Exception("KeyedUnion type must have a parent") s += "switch (%s) {\n" % (parent + ty.keyvar_name) @@ -63,7 +63,7 @@ def libxl_C_type_dispose(ty, v, indent s += libxl_C_type_dispose(f.type, fexpr, indent + " ", nparent) s += " break;\n" s += "}\n" - elif isinstance(ty, libxltypes.Struct) and (parent is None or ty.dispose_fn is None): + elif isinstance(ty, idl.Struct) and (parent is None or ty.dispose_fn is None): for f in [f for f in ty.fields if not f.const]: (nparent,fexpr) = ty.member(v, f, parent is None) s += libxl_C_type_dispose(f.type, fexpr, "", nparent) @@ -79,11 +79,11 @@ def libxl_C_type_gen_json(ty, v, indent s = "" if parent is None: s += "yajl_gen_status s;\n" - if isinstance(ty, libxltypes.Enumeration): + if isinstance(ty, idl.Enumeration): s += "s = libxl__yajl_gen_enum(hand, %s_to_string(%s));\n" % (ty.typename, ty.pass_arg(v, parent is None)) s += "if (s != yajl_gen_status_ok)\n" s += " goto out;\n" - elif isinstance(ty, libxltypes.KeyedUnion): + elif isinstance(ty, idl.KeyedUnion): if parent is None: raise Exception("KeyedUnion type must have a parent") s += "switch (%s) {\n" % (parent + ty.keyvar_name) @@ -93,7 +93,7 @@ def libxl_C_type_gen_json(ty, v, indent s += libxl_C_type_gen_json(f.type, fexpr, indent + " ", nparent) s += " break;\n" s += "}\n" - elif isinstance(ty, libxltypes.Struct) and (parent is None or ty.json_fn is None): + elif isinstance(ty, idl.Struct) and (parent is None or ty.json_fn is None): s += "s = yajl_gen_map_open(hand);\n" s += "if (s != yajl_gen_status_ok)\n" s += " goto out;\n" @@ -123,7 +123,7 @@ def libxl_C_type_gen_json(ty, v, indent def libxl_C_type_to_json(ty, v, indent = " "): s = "" gen = "(libxl__gen_json_callback)&%s_gen_json" % ty.typename - s += "return libxl__object_to_json(ctx, \"%s\", %s, (void *)%s);\n" % (ty.typename, gen, ty.pass_arg(v, passby=libxltypes.PASS_BY_REFERENCE)) + s += "return libxl__object_to_json(ctx, \"%s\", %s, (void *)%s);\n" % (ty.typename, gen, ty.pass_arg(v, passby=idl.PASS_BY_REFERENCE)) if s != "": s = indent + s @@ -171,9 +171,9 @@ if __name__ == ''__main__'': print >>sys.stderr, "Usage: gentypes.py <idl> <header> <header-json> <implementation>" sys.exit(1) - (_, idl, header, header_json, impl) = sys.argv + (_, idlname, header, header_json, impl) = sys.argv - (builtins,types) = libxltypes.parse(idl) + (builtins,types) = idl.parse(idlname) print "outputting libxl type definitions to %s" % header @@ -198,9 +198,9 @@ if __name__ == ''__main__'': f.write("void %s(%s);\n" % (ty.dispose_fn, ty.make_arg("p"))) if ty.json_fn is not None: f.write("char *%s_to_json(libxl_ctx *ctx, %s);\n" % (ty.typename, ty.make_arg("p"))) - if isinstance(ty, libxltypes.Enumeration): + if isinstance(ty, idl.Enumeration): f.write("const char *%s_to_string(%s);\n" % (ty.typename, ty.make_arg("p"))) - f.write("int %s_from_string(const char *s, %s);\n" % (ty.typename, ty.make_arg("e", passby=libxltypes.PASS_BY_REFERENCE))) + f.write("int %s_from_string(const char *s, %s);\n" % (ty.typename, ty.make_arg("e", passby=idl.PASS_BY_REFERENCE))) f.write("extern libxl_enum_string_table %s_string_table[];\n" % (ty.typename)) f.write("\n") @@ -225,7 +225,7 @@ if __name__ == ''__main__'': """ % (header_json_define, header_json_define, " ".join(sys.argv))) for ty in [ty for ty in types+builtins if ty.json_fn is not None]: - f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.typename, ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE))) + f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) f.write("\n") f.write("""#endif /* %s */\n""" % header_json_define) @@ -262,7 +262,7 @@ if __name__ == ''__main__'': f.write("}\n") f.write("\n") - for ty in [t for t in types if isinstance(t,libxltypes.Enumeration)]: + for ty in [t for t in types if isinstance(t,idl.Enumeration)]: f.write("const char *%s_to_string(%s e)\n" % (ty.typename, ty.typename)) f.write("{\n") f.write(libxl_C_enum_to_string(ty, "e")) @@ -278,7 +278,7 @@ if __name__ == ''__main__'': f.write("\n") for ty in [t for t in types if t.json_fn is not None]: - f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE))) + f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) f.write("{\n") f.write(libxl_C_type_gen_json(ty, "p")) f.write("}\n") diff --git a/tools/libxl/libxltypes.py b/tools/libxl/idl.py rename from tools/libxl/libxltypes.py rename to tools/libxl/idl.py diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt --- a/tools/libxl/idl.txt +++ b/tools/libxl/idl.txt @@ -1,10 +1,10 @@ -libxltypes IDL --------------- +libxl IDL +--------- Each type in the libxl interface is represented by an object of type -libxltypes.Type (or a subclass thereof). Every local variable defined -by the .idl file must be an instance of libxltypes.Type (e.g. you may -not define Python functions or any other construct other than defining +idl.Type (or a subclass thereof). Every local variable defined by +the .idl file must be an instance of idl.Type (e.g. you may not +define Python functions or any other construct other than defining variables) The name of the type must be passed as the first argument to the @@ -16,9 +16,9 @@ The Type.typename contains the C name of namespace element while Type.rawname is always set to the ''base'' name of the type. -The libxltypes.Type base class has several other properties which -apply to all types. The properties are set by passing a named -parameter to the constructor. +The idl.Type base class has several other properties which apply +to all types. The properties are set by passing a named parameter to +the constructor. Type.namespace: (default: "libxl_") @@ -28,12 +28,12 @@ Type.namespace: (default: "libxl_") If the typename is not None then the namespace is prepended to the type. -Type.passby: (default: libxltypes.PASS_BY_VALUE) +Type.passby: (default: idl.PASS_BY_VALUE) Defines the manner in which a type should be passed to C functions. Valid values for this fields are: - libxltypes.PASS_BY_VALUE - libxltypes.PASS_BY_REFERENCE + idl.PASS_BY_VALUE + idl.PASS_BY_REFERENCE Type.dispose_fn: (default: typename + "_dispose" or None if type == None) @@ -106,7 +106,7 @@ libxltype.Aggregate Each field has the following properties: - Field.type The type of the member (a libxltypes.Type). + Field.type The type of the member (a idl.Type). Field.name The name of the member (can be None for anonymous fields). Field.const Boolean, true if the member is const. diff --git a/tools/ocaml/libs/xl/Makefile b/tools/ocaml/libs/xl/Makefile --- a/tools/ocaml/libs/xl/Makefile +++ b/tools/ocaml/libs/xl/Makefile @@ -46,7 +46,7 @@ xenlight.mli: xenlight.mli.in _libxl_typ $(Q)mv xenlight.mli.tmp xenlight.mli _libxl_types.ml.in _libxl_types.mli.in _libxl_types.inc: genwrap.py $(XEN_ROOT)/tools/libxl/libxl_types.idl \ - $(XEN_ROOT)/tools/libxl/libxltypes.py + $(XEN_ROOT)/tools/libxl/idl.py PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py \ $(XEN_ROOT)/tools/libxl/libxl_types.idl \ _libxl_types.mli.in _libxl_types.ml.in _libxl_types.inc diff --git a/tools/ocaml/libs/xl/genwrap.py b/tools/ocaml/libs/xl/genwrap.py --- a/tools/ocaml/libs/xl/genwrap.py +++ b/tools/ocaml/libs/xl/genwrap.py @@ -2,7 +2,7 @@ import sys,os -import libxltypes +import idl # typename -> ( ocaml_type, c_from_ocaml, ocaml_from_c ) builtins = { @@ -39,7 +39,7 @@ def stub_fn_name(ty, name): def ocaml_type_of(ty): if ty.rawname == "domid": return "domid" - elif isinstance(ty,libxltypes.UInt): + elif isinstance(ty,idl.UInt): if ty.width in [8, 16]: # handle as ints width = None @@ -52,14 +52,14 @@ def ocaml_type_of(ty): else: return "int" - elif isinstance(ty,libxltypes.Builtin): + elif isinstance(ty,idl.Builtin): if not builtins.has_key(ty.typename): raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty))) typename,_,_ = builtins[ty.typename] if not typename: raise NotImplementedError("No typename for Builtin %s (%s)" % (ty.typename, type(ty))) return typename - elif isinstance(ty,libxltypes.Aggregate): + elif isinstance(ty,idl.Aggregate): return ty.rawname.capitalize() + ".t" else: return ty.rawname @@ -73,11 +73,11 @@ def gen_ocaml_ml(ty, interface, indent=" s = ("""(* %s interface *)\n""" % ty.typename) else: s = ("""(* %s implementation *)\n""" % ty.typename) - if isinstance(ty, libxltypes.Enumeration): + if isinstance(ty, idl.Enumeration): s = "type %s = \n" % ty.rawname for v in ty.values: s += "\t | %s\n" % v.rawname - elif isinstance(ty, libxltypes.Aggregate): + elif isinstance(ty, idl.Aggregate): s = "" if ty.typename is None: raise NotImplementedError("%s has no typename" % type(ty)) @@ -113,7 +113,7 @@ def gen_ocaml_ml(ty, interface, indent=" def c_val(ty, c, o, indent="", parent = None): s = indent - if isinstance(ty,libxltypes.UInt): + if isinstance(ty,idl.UInt): if ty.width in [8, 16]: # handle as ints width = None @@ -125,14 +125,14 @@ def c_val(ty, c, o, indent="", parent = s += "%s = Int%d_val(%s);" % (c, width, o) else: s += "%s = Int_val(%s);" % (c, o) - elif isinstance(ty,libxltypes.Builtin): + elif isinstance(ty,idl.Builtin): if not builtins.has_key(ty.typename): raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty))) _,fn,_ = builtins[ty.typename] if not fn: raise NotImplementedError("No c_val fn for Builtin %s (%s)" % (ty.typename, type(ty))) s += "%s;" % (fn % { "o": o, "c": c }) - elif isinstance(ty,libxltypes.Enumeration) and (parent is None): + elif isinstance(ty,idl.Enumeration) and (parent is None): n = 0 s += "switch(Int_val(%s)) {\n" % o for e in ty.values: @@ -140,21 +140,21 @@ def c_val(ty, c, o, indent="", parent = n += 1 s += " default: failwith_xl(\"cannot convert value to %s\", lg); break;\n" % ty.typename s += "}" - elif isinstance(ty, libxltypes.Aggregate) and (parent is None): + elif isinstance(ty, idl.Aggregate) and (parent is None): n = 0 for f in ty.fields: (nparent,fexpr) = ty.member(c, f, parent is None) s += "%s\n" % c_val(f.type, fexpr, "Field(%s, %d)" % (o,n), parent=nparent) n = n + 1 else: - s += "%s_val(gc, lg, %s, %s);" % (ty.rawname, ty.pass_arg(c, parent is None, passby=libxltypes.PASS_BY_REFERENCE), o) + s += "%s_val(gc, lg, %s, %s);" % (ty.rawname, ty.pass_arg(c, parent is None, passby=idl.PASS_BY_REFERENCE), o) return s.replace("\n", "\n%s" % indent) def gen_c_val(ty, indent=""): s = "/* Convert caml value to %s */\n" % ty.rawname - s += "static int %s_val (caml_gc *gc, struct caml_logger *lg, %s, value v)\n" % (ty.rawname, ty.make_arg("c_val", passby=libxltypes.PASS_BY_REFERENCE)) + s += "static int %s_val (caml_gc *gc, struct caml_logger *lg, %s, value v)\n" % (ty.rawname, ty.make_arg("c_val", passby=idl.PASS_BY_REFERENCE)) s += "{\n" s += "\tCAMLparam1(v);\n" s += "\n" @@ -168,7 +168,7 @@ def gen_c_val(ty, indent=""): def ocaml_Val(ty, o, c, indent="", parent = None): s = indent - if isinstance(ty,libxltypes.UInt): + if isinstance(ty,idl.UInt): if ty.width in [8, 16]: # handle as ints width = None @@ -180,14 +180,14 @@ def ocaml_Val(ty, o, c, indent="", paren s += "%s = caml_copy_int%d(%s);" % (o, width, c) else: s += "%s = Val_int(%s);" % (o, c) - elif isinstance(ty,libxltypes.Builtin): + elif isinstance(ty,idl.Builtin): if not builtins.has_key(ty.typename): raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty))) _,_,fn = builtins[ty.typename] if not fn: raise NotImplementedError("No ocaml Val fn for Builtin %s (%s)" % (ty.typename, type(ty))) s += "%s = %s;" % (o, fn % { "c": c }) - elif isinstance(ty,libxltypes.Enumeration) and (parent is None): + elif isinstance(ty,idl.Enumeration) and (parent is None): n = 0 s += "switch(%s) {\n" % c for e in ty.values: @@ -195,7 +195,7 @@ def ocaml_Val(ty, o, c, indent="", paren n += 1 s += " default: failwith_xl(\"cannot convert value from %s\", lg); break;\n" % ty.typename s += "}" - elif isinstance(ty,libxltypes.Aggregate) and (parent is None): + elif isinstance(ty,idl.Aggregate) and (parent is None): s += "{\n" s += "\tvalue %s_field;\n" % ty.rawname s += "\n" @@ -251,8 +251,7 @@ if __name__ == ''__main__'': print >>sys.stderr, "Usage: genwrap.py <idl> <mli> <ml> <c-inc>" sys.exit(1) - idl = sys.argv[1] - (_,types) = libxltypes.parse(idl) + (_,types) = idl.parse(sys.argv[1]) # Do not generate these yet. blacklist = [ diff --git a/tools/python/Makefile b/tools/python/Makefile --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -11,7 +11,7 @@ genpath-target = $(call buildmakevars2fi .PHONY: build build: genpath genwrap.py $(XEN_ROOT)/tools/libxl/libxl_types.idl \ - $(XEN_ROOT)/tools/libxl/libxltypes.py + $(XEN_ROOT)/tools/libxl/idl.py PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py \ $(XEN_ROOT)/tools/libxl/libxl_types.idl \ xen/lowlevel/xl/_pyxl_types.h \ diff --git a/tools/python/genwrap.py b/tools/python/genwrap.py --- a/tools/python/genwrap.py +++ b/tools/python/genwrap.py @@ -2,23 +2,23 @@ import sys,os -import libxltypes +import idl (TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_STRING, TYPE_AGGREGATE) = range(5) def py_type(ty): - if ty == libxltypes.bool: + if ty == idl.bool: return TYPE_BOOL - if isinstance(ty, libxltypes.Enumeration): + if isinstance(ty, idl.Enumeration): return TYPE_UINT - if isinstance(ty, libxltypes.Number): + if isinstance(ty, idl.Number): if ty.signed: return TYPE_INT else: return TYPE_UINT - if isinstance(ty, libxltypes.Aggregate): + if isinstance(ty, idl.Aggregate): return TYPE_AGGREGATE - if ty == libxltypes.string: + if ty == idl.string: return TYPE_STRING return None @@ -38,7 +38,7 @@ def fsanitize(name): def py_decls(ty): l = [] - if isinstance(ty, libxltypes.Aggregate): + if isinstance(ty, idl.Aggregate): l.append(''_hidden Py_%s *Py%s_New(void);\n''%(ty.rawname, ty.rawname)) l.append(''_hidden int Py%s_Check(PyObject *self);\n''%ty.rawname) for f in ty.fields: @@ -211,10 +211,10 @@ def py_initfuncs(types): l.append(''void genwrap__init(PyObject *m)'') l.append(''{'') for ty in types: - if isinstance(ty, libxltypes.Enumeration): + if isinstance(ty, idl.Enumeration): for v in ty.values: l.append('' PyModule_AddIntConstant(m, "%s", %s);'' % (v.rawname, v.name)) - elif isinstance(ty, libxltypes.Aggregate): + elif isinstance(ty, idl.Aggregate): l.append('' if (PyType_Ready(&Py%s_Type) >= 0) {''%ty.rawname) l.append('' Py_INCREF(&Py%s_Type);''%ty.rawname) l.append('' PyModule_AddObject(m, "%s", (PyObject *)&Py%s_Type);''%(ty.rawname, ty.rawname)) @@ -227,7 +227,7 @@ def py_initfuncs(types): def tree_frob(types): ret = types[:] - for ty in [ty for ty in ret if isinstance(ty, libxltypes.Aggregate)]: + for ty in [ty for ty in ret if isinstance(ty, idl.Aggregate)]: ty.fields = filter(lambda f:f.name is not None and f.type.typename is not None, ty.fields) return ret @@ -236,8 +236,7 @@ if __name__ == ''__main__'': print >>sys.stderr, "Usage: genwrap.py <idl> <decls> <defns>" sys.exit(1) - idl = sys.argv[1] - (_,types) = libxltypes.parse(idl) + (_,types) = idl.parse(sys.argv[1]) types = tree_frob(types) @@ -278,7 +277,7 @@ _hidden PyObject *genwrap__ll_get(long l _hidden int genwrap__ll_set(PyObject *v, long long *val, long long mask); """ % " ".join(sys.argv)) - for ty in [ty for ty in types if isinstance(ty, libxltypes.Aggregate)]: + for ty in [ty for ty in types if isinstance(ty, idl.Aggregate)]: f.write(''/* Internal API for %s wrapper */\n''%ty.typename) f.write(py_wrapstruct(ty)) f.write(py_decls(ty)) @@ -307,7 +306,7 @@ _hidden int genwrap__ll_set(PyObject *v, for ty in types: if ty.private: continue - if isinstance(ty, libxltypes.Aggregate): + if isinstance(ty, idl.Aggregate): f.write(''/* Attribute get/set functions for %s */\n''%ty.typename) for a in ty.fields: if a.type.private:
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327510508 0 # Node ID b9973edc7528e5233698fefd234be19dd6d6bcee # Parent 9a366717e0c0a0e0261796669e9e96c0ba514923 libxl: de-hard-tabbify idl.txt Hard tabs were in the minority, nuke them. Also we no longer supply the inaddr_ip builtin. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt --- a/tools/libxl/idl.txt +++ b/tools/libxl/idl.txt @@ -2,10 +2,9 @@ libxl IDL --------- Each type in the libxl interface is represented by an object of type -idl.Type (or a subclass thereof). Every local variable defined by -the .idl file must be an instance of idl.Type (e.g. you may not -define Python functions or any other construct other than defining -variables) +idl.Type (or a subclass thereof). Every local variable defined by the +.idl file must be an instance of idl.Type (e.g. you may not define +Python functions or any other construct other than defining variables) The name of the type must be passed as the first argument to the constructor when defining a new type. The name given should not @@ -16,9 +15,9 @@ The Type.typename contains the C name of namespace element while Type.rawname is always set to the ''base'' name of the type. -The idl.Type base class has several other properties which apply -to all types. The properties are set by passing a named parameter to -the constructor. +The idl.Type base class has several other properties which apply to +all types. The properties are set by passing a named parameter to the +constructor. Type.namespace: (default: "libxl_") @@ -81,7 +80,7 @@ libxltype.Enumeration Each EnumerationValue has the following properties: - EnumerationValue.enum Reference to containing Enumeration + EnumerationValue.enum Reference to containing Enumeration EnumerationValue.name The C name of this value, including the namespace and typename of the containing Enumeration (e.g. @@ -90,10 +89,10 @@ libxltype.Enumeration the namespace but including the typename of the containing Enumeration (e.g. "FOOENUM_VALUE") - EnumerationValue.valuename The name of this value, excluding the - name of the containing Enumeration - and any namespace (e.g. "VALUE") - EnumerationValue.value The integer value associated with this name. + EnumerationValue.valuename The name of this value, excluding the + name of the containing Enumeration + and any namespace (e.g. "VALUE") + EnumerationValue.value The integer value associated with this name. libxltype.Aggregate @@ -106,10 +105,10 @@ libxltype.Aggregate Each field has the following properties: - Field.type The type of the member (a idl.Type). + Field.type The type of the member (a idl.Type). Field.name The name of the member (can be None for anonymous - fields). - Field.const Boolean, true if the member is const. + fields). + Field.const Boolean, true if the member is const. libxltype.Struct @@ -139,15 +138,13 @@ Standard Types Several standard types a predefined. They are -void (void pointer type) +void (void pointer type) bool size_t -integer 24 bit signed integer. +integer 24 bit signed integer. -uint{8,16,32,64} uint{8,16,32,64}_t +uint{8,16,32,64} uint{8,16,32,64}_t -domid Domain ID +domid Domain ID -string NULL terminated string - -inaddr_ip struct in_addr +string NULL terminated string
Ian Campbell
2012-Jan-25 17:24 UTC
[PATCH 3 of 9] libxl: remove libxl_button_press in favour of libxl_send_trigger
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327510508 0 # Node ID a7776e38447d4e633a45b926295f7923c046fbc9 # Parent b9973edc7528e5233698fefd234be19dd6d6bcee libxl: remove libxl_button_press in favour of libxl_send_trigger. send_trigger already included all the operations covered by button_press. Rework send_trigger to take an enum instead of a string. I stopped short at removing the xl "button-press" command but instead have marked it as deprecated. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1 --- a/docs/man/xl.pod.1 +++ b/docs/man/xl.pod.1 @@ -86,6 +86,8 @@ previously, most commands take I<domain- =item B<button-press> I<domain-id> I<button> +I<This command is deprecated. Please use C<xl trigger> in preference> + Indicate an ACPI button press to the domain. I<button> is may be ''power'' or ''sleep''. This command is only available for HVM domains. @@ -448,7 +450,7 @@ It can be used to send SysRq requests to your Linux Kernel sources for more information. It requires PV drivers to be installed in your guest OS. -=item B<trigger> I<domain-id> I<nmi|reset|init|power|sleep> [I<VCPU>] +=item B<trigger> I<domain-id> I<nmi|reset|init|power|sleep|s3resume> [I<VCPU>] Send a trigger to a domain, where the trigger can be: nmi, reset, init, power or sleep. Optionally a specific vcpu number can be passed as an argument. diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py --- a/tools/libxl/gentypes.py +++ b/tools/libxl/gentypes.py @@ -32,6 +32,9 @@ def libxl_C_type_define(ty, indent = "") s += "} %s" % ty.typename elif isinstance(ty, idl.Aggregate): + if isinstance(ty, idl.KeyedUnion): + s += libxl_C_instance_of(ty.keyvar_type, ty.keyvar_name) + ";\n" + if ty.typename is None: s += "%s {\n" % ty.kind else: diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2477,24 +2477,6 @@ out: return 0; } -int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button) -{ - int rc = -1; - - switch (button) { - case LIBXL_BUTTON_POWER: - rc = xc_domain_send_trigger(ctx->xch, domid, XEN_DOMCTL_SENDTRIGGER_POWER, 0); - break; - case LIBXL_BUTTON_SLEEP: - rc = xc_domain_send_trigger(ctx->xch, domid, XEN_DOMCTL_SENDTRIGGER_SLEEP, 0); - break; - default: - break; - } - - return rc; -} - int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo) { xc_physinfo_t xcphysinfo = { 0 }; @@ -2876,44 +2858,46 @@ int libxl_sched_sedf_domain_set(libxl_ct return 0; } -static int trigger_type_from_string(char *trigger_name) +int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, + libxl_trigger trigger, uint32_t vcpuid) { - if (!strcmp(trigger_name, "nmi")) - return XEN_DOMCTL_SENDTRIGGER_NMI; - else if (!strcmp(trigger_name, "reset")) - return XEN_DOMCTL_SENDTRIGGER_RESET; - else if (!strcmp(trigger_name, "init")) - return XEN_DOMCTL_SENDTRIGGER_INIT; - else if (!strcmp(trigger_name, "power")) - return XEN_DOMCTL_SENDTRIGGER_POWER; - else if (!strcmp(trigger_name, "sleep")) - return XEN_DOMCTL_SENDTRIGGER_SLEEP; - else - return -1; -} - -int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, char *trigger_name, uint32_t vcpuid) -{ - int rc = -1; - int trigger_type = -1; - - if (!strcmp(trigger_name, "s3resume")) { + int rc; + + switch (trigger) { + case LIBXL_TRIGGER_POWER: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_POWER, vcpuid); + break; + case LIBXL_TRIGGER_SLEEP: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_SLEEP, vcpuid); + break; + case LIBXL_TRIGGER_NMI: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_NMI, vcpuid); + break; + case LIBXL_TRIGGER_INIT: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_INIT, vcpuid); + break; + case LIBXL_TRIGGER_RESET: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_RESET, vcpuid); + break; + case LIBXL_TRIGGER_S3RESUME: xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, 0); - return 0; + rc = 0; + break; + default: + rc = EINVAL; + break; } - trigger_type = trigger_type_from_string(trigger_name); - if (trigger_type == -1) { - LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, -1, - "Invalid trigger, valid triggers are <nmi|reset|init|power|sleep>"); - return ERROR_INVAL; - } - - rc = xc_domain_send_trigger(ctx->xch, domid, trigger_type, vcpuid); if (rc != 0) { LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, - "Send trigger ''%s'' failed", trigger_name); - return ERROR_FAIL; + "Send trigger ''%s'' failed", + libxl_trigger_to_string(trigger)); + rc = ERROR_FAIL; } return 0; diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -547,8 +547,6 @@ int libxl_userdata_retrieve(libxl_ctx *c * On error return, *data_r and *datalen_r are undefined. */ -int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button); - int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo); int libxl_get_topologyinfo(libxl_ctx *ctx, libxl_topologyinfo *info); libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, @@ -573,7 +571,7 @@ int libxl_sched_sedf_domain_get(libxl_ct int libxl_sched_sedf_domain_set(libxl_ctx *ctx, uint32_t domid, libxl_sched_sedf *scinfo); int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, - char *trigger_name, uint32_t vcpuid); + libxl_trigger trigger, uint32_t vcpuid); int libxl_send_sysrq(libxl_ctx *ctx, uint32_t domid, char sysrq); int libxl_send_debug_keys(libxl_ctx *ctx, char *keys); diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -80,9 +80,14 @@ libxl_event_type = Enumeration("event_ty (2, "DISK_EJECT"), ]) -libxl_button = Enumeration("button", [ +libxl_trigger = Enumeration("trigger", [ + (0, "UNKNOWN"), (1, "POWER"), (2, "SLEEP"), + (3, "NMI"), + (4, "INIT"), + (5, "RESET"), + (6, "S3RESUME"), ]) libxl_tsc_mode = Enumeration("tsc_mode", [ @@ -203,7 +208,6 @@ libxl_domain_build_info = Struct("domain ("shadow_memkb", uint32), ("disable_migrate", bool), ("cpuid", libxl_cpuid_policy_list), - ("type", libxl_domain_type), ("device_model_version", libxl_device_model_version), ("device_model_stubdomain", bool), diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -3318,26 +3318,29 @@ int main_create(int argc, char **argv) static void button_press(const char *p, const char *b) { - libxl_button button; + libxl_trigger trigger; find_domain(p); if (!strcmp(b, "power")) { - button = LIBXL_BUTTON_POWER; + trigger = LIBXL_TRIGGER_POWER; } else if (!strcmp(b, "sleep")) { - button = LIBXL_BUTTON_SLEEP; + trigger = LIBXL_TRIGGER_SLEEP; } else { fprintf(stderr, "%s is an invalid button identifier\n", b); exit(2); } - libxl_button_press(ctx, domid, button); + libxl_send_trigger(ctx, domid, trigger, 0); } int main_button_press(int argc, char **argv) { int opt; + fprintf(stderr, "WARNING: \"button-press\" is deprecated. " + "Please use \"trigger\"\n"); + if ((opt = def_getopt(argc, argv, "", "button-press", 2)) != -1) return opt; @@ -4322,10 +4325,11 @@ int main_rename(int argc, char **argv) int main_trigger(int argc, char **argv) { int opt; - char *trigger_name = NULL; char *endptr = NULL; const char *dom = NULL; int vcpuid = 0; + const char *trigger_name = NULL; + libxl_trigger trigger; if ((opt = def_getopt(argc, argv, "", "trigger", 2)) != -1) return opt; @@ -4335,6 +4339,10 @@ int main_trigger(int argc, char **argv) find_domain(dom); trigger_name = argv[optind++]; + if (libxl_trigger_from_string(trigger_name, &trigger)) { + fprintf(stderr, "Invalid trigger \"%s\"\n", trigger_name); + return -1; + } if (argv[optind]) { vcpuid = strtol(argv[optind], &endptr, 10); @@ -4343,7 +4351,7 @@ int main_trigger(int argc, char **argv) } } - libxl_send_trigger(ctx, domid, trigger_name, vcpuid); + libxl_send_trigger(ctx, domid, trigger, vcpuid); return 0; } diff --git a/tools/ocaml/libs/xl/xenlight.ml.in b/tools/ocaml/libs/xl/xenlight.ml.in --- a/tools/ocaml/libs/xl/xenlight.ml.in +++ b/tools/ocaml/libs/xl/xenlight.ml.in @@ -29,10 +29,8 @@ module Topologyinfo = struct external get : unit -> t = "stub_xl_topologyinfo" end -external button_press : domid -> button -> unit = "stub_xl_button_press" - -external send_trigger : domid -> string -> int -> unit = "stub_xl_send_trigger" +external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff --git a/tools/ocaml/libs/xl/xenlight.mli.in b/tools/ocaml/libs/xl/xenlight.mli.in --- a/tools/ocaml/libs/xl/xenlight.mli.in +++ b/tools/ocaml/libs/xl/xenlight.mli.in @@ -29,8 +29,6 @@ module Topologyinfo : sig external get : unit -> t = "stub_xl_topologyinfo" end -external button_press : domid -> button -> unit = "stub_xl_button_press" - -external send_trigger : domid -> string -> int -> unit = "stub_xl_send_trigger" +external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c --- a/tools/ocaml/libs/xl/xenlight_stubs.c +++ b/tools/ocaml/libs/xl/xenlight_stubs.c @@ -432,21 +432,6 @@ value stub_xl_device_pci_remove(value in CAMLreturn(Val_unit); } -value stub_xl_button_press(value domid, value button) -{ - CAMLparam2(domid, button); - int ret; - INIT_STRUCT(); - - INIT_CTX(); - ret = libxl_button_press(ctx, Int_val(domid), Int_val(button) + LIBXL_BUTTON_POWER); - if (ret != 0) - failwith_xl("button_press", &lg); - FREE_CTX(); - - CAMLreturn(Val_unit); -} - value stub_xl_physinfo_get(value unit) { CAMLparam1(unit); @@ -523,10 +508,10 @@ value stub_xl_send_trigger(value domid, { CAMLparam3(domid, trigger, vcpuid); int ret; - char *c_trigger; + libxl_trigger c_trigger = LIBXL_TRIGGER_UNKNOWN; INIT_STRUCT(); - c_trigger = dup_String_val(&gc, trigger); + trigger_val(&gc, &lg, &c_trigger, trigger); INIT_CTX(); ret = libxl_send_trigger(ctx, Int_val(domid), c_trigger, Int_val(vcpuid));
Ian Campbell
2012-Jan-25 17:24 UTC
[PATCH 4 of 9] ocaml: add helper''s for Some/None option types
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327512173 0 # Node ID 32e51774992b4d22b07f1ce3ab16880e33aa3794 # Parent a7776e38447d4e633a45b926295f7923c046fbc9 ocaml: add helper''s for Some/None option types. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c --- a/tools/ocaml/libs/xl/xenlight_stubs.c +++ b/tools/ocaml/libs/xl/xenlight_stubs.c @@ -130,6 +130,19 @@ static int string_string_tuple_array_val #endif +/* Option type support as per http://www.linux-nantes.org/~fmonnier/ocaml/ocaml-wrapping-c.php */ +#define Val_none Val_int(0) +#define Some_val(v) Field(v,0) + +static value Val_some(value v) +{ + CAMLparam1(v); + CAMLlocal1(some); + some = caml_alloc(1, 0); + Store_field(some, 0, v); + CAMLreturn(some); +} + static value Val_mac (libxl_mac *c_val) { CAMLparam0(); @@ -205,14 +218,13 @@ static value Val_topologyinfo(libxl_topo topologyinfo = caml_alloc_tuple(c_val->coremap.entries); for (i = 0; i < c_val->coremap.entries; i++) { - v = Val_int(0); /* None */ + v = Val_none; if (c_val->coremap.array[i] != LIBXL_CPUARRAY_INVALID_ENTRY) { topology = caml_alloc_tuple(3); Store_field(topology, 0, Val_int(c_val->coremap.array[i])); Store_field(topology, 1, Val_int(c_val->socketmap.array[i])); Store_field(topology, 2, Val_int(c_val->nodemap.array[i])); - v = caml_alloc(1, 0); /* Some */ - Store_field(v, 0, topology); + v = Val_some(topology); } Store_field(topologyinfo, i, v); }
Ian Campbell
2012-Jan-25 17:24 UTC
[PATCH 5 of 9] ocaml: Topology.get returns an array not a single element
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327512175 0 # Node ID d09c5ab835ec6685822c04a140afa1620cca1138 # Parent 32e51774992b4d22b07f1ce3ab16880e33aa3794 ocaml: Topology.get returns an array not a single element. The stub implementation appears to already be correct. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/tools/ocaml/libs/xl/xenlight.ml.in b/tools/ocaml/libs/xl/xenlight.ml.in --- a/tools/ocaml/libs/xl/xenlight.ml.in +++ b/tools/ocaml/libs/xl/xenlight.ml.in @@ -26,7 +26,7 @@ module Topologyinfo = struct socket : int; node : int; } - external get : unit -> t = "stub_xl_topologyinfo" + external get : unit -> t array = "stub_xl_topologyinfo" end diff --git a/tools/ocaml/libs/xl/xenlight.mli.in b/tools/ocaml/libs/xl/xenlight.mli.in --- a/tools/ocaml/libs/xl/xenlight.mli.in +++ b/tools/ocaml/libs/xl/xenlight.mli.in @@ -26,7 +26,7 @@ module Topologyinfo : sig socket : int; node : int; } - external get : unit -> t = "stub_xl_topologyinfo" + external get : unit -> t array = "stub_xl_topologyinfo" end external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger"
Ian Campbell
2012-Jan-25 17:24 UTC
[PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327512175 0 # Node ID e1753f37c9064f1e84fa32dfc37ff0f286e2df1e # Parent d09c5ab835ec6685822c04a140afa1620cca1138 libxl: expose cpu topology as a single list of cpu->{node,core,socket} maps. Rather than the previous tripple list which is more complicated to work with and harder for language bindings. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py --- a/tools/libxl/gentest.py +++ b/tools/libxl/gentest.py @@ -195,6 +195,7 @@ static void libxl_string_list_rand_init( *p = l; } +#if 0 static void libxl_cpuarray_rand_init(libxl_cpuarray *p) { int i; @@ -209,6 +210,7 @@ static void libxl_cpuarray_rand_init(lib p->array[i] = r; } } +#endif """) for ty in builtins + types: if ty.typename not in handcoded: diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2502,57 +2502,68 @@ int libxl_get_physinfo(libxl_ctx *ctx, l return 0; } -int libxl_get_topologyinfo(libxl_ctx *ctx, libxl_topologyinfo *info) +libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nr) { xc_topologyinfo_t tinfo; DECLARE_HYPERCALL_BUFFER(xc_cpu_to_core_t, coremap); DECLARE_HYPERCALL_BUFFER(xc_cpu_to_socket_t, socketmap); DECLARE_HYPERCALL_BUFFER(xc_cpu_to_node_t, nodemap); + libxl_cputopology *ret = NULL; int i; - int rc = 0; - - rc += libxl_cpuarray_alloc(ctx, &info->coremap); - rc += libxl_cpuarray_alloc(ctx, &info->socketmap); - rc += libxl_cpuarray_alloc(ctx, &info->nodemap); - if (rc) + int max_cpus; + + max_cpus = libxl_get_max_cpus(ctx); + if (max_cpus == 0) + { + LIBXL__LOG(ctx, XTL_ERROR, "Unable to determine number of CPUS"); + return NULL; + } + + coremap = xc_hypercall_buffer_alloc + (ctx->xch, coremap, sizeof(*coremap) * max_cpus); + socketmap = xc_hypercall_buffer_alloc + (ctx->xch, socketmap, sizeof(*socketmap) * max_cpus); + nodemap = xc_hypercall_buffer_alloc + (ctx->xch, nodemap, sizeof(*nodemap) * max_cpus); + if ((coremap == NULL) || (socketmap == NULL) || (nodemap == NULL)) { + LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM, + "Unable to allocate hypercall arguments"); goto fail; - - coremap = xc_hypercall_buffer_alloc(ctx->xch, coremap, sizeof(*coremap) * info->coremap.entries); - socketmap = xc_hypercall_buffer_alloc(ctx->xch, socketmap, sizeof(*socketmap) * info->socketmap.entries); - nodemap = xc_hypercall_buffer_alloc(ctx->xch, nodemap, sizeof(*nodemap) * info->nodemap.entries); - if ((coremap == NULL) || (socketmap == NULL) || (nodemap == NULL)) - goto fail; + } set_xen_guest_handle(tinfo.cpu_to_core, coremap); set_xen_guest_handle(tinfo.cpu_to_socket, socketmap); set_xen_guest_handle(tinfo.cpu_to_node, nodemap); - tinfo.max_cpu_index = info->coremap.entries - 1; - if (xc_topologyinfo(ctx->xch, &tinfo) != 0) + tinfo.max_cpu_index = max_cpus - 1; + if (xc_topologyinfo(ctx->xch, &tinfo) != 0) { + LIBXL__LOG_ERRNO(ctx, XTL_ERROR, "Topology info hypercall failed"); goto fail; - - for (i = 0; i <= tinfo.max_cpu_index; i++) { - if (i < info->coremap.entries) - info->coremap.array[i] = (coremap[i] == INVALID_TOPOLOGY_ID) ? - LIBXL_CPUARRAY_INVALID_ENTRY : coremap[i]; - if (i < info->socketmap.entries) - info->socketmap.array[i] = (socketmap[i] == INVALID_TOPOLOGY_ID) ? - LIBXL_CPUARRAY_INVALID_ENTRY : socketmap[i]; - if (i < info->nodemap.entries) - info->nodemap.array[i] = (nodemap[i] == INVALID_TOPOLOGY_ID) ? - LIBXL_CPUARRAY_INVALID_ENTRY : nodemap[i]; } - xc_hypercall_buffer_free(ctx->xch, coremap); - xc_hypercall_buffer_free(ctx->xch, socketmap); - xc_hypercall_buffer_free(ctx->xch, nodemap); - return 0; + ret = malloc(sizeof(libxl_cputopology) * max_cpus); + if (ret == NULL) { + LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM, + "Unable to allocate return value"); + goto fail; + } + + for (i = 0; i <= max_cpus; i++) { +#define V(map, i) (map[i] == INVALID_TOPOLOGY_ID) ? \ + LIBXL_CPUTOPOLOGY_INVALID_ENTRY : map[i] + ret[i].core = V(coremap, i); + ret[i].socket = V(socketmap, i); + ret[i].node = V(nodemap, i); +#undef V + } fail: xc_hypercall_buffer_free(ctx->xch, coremap); xc_hypercall_buffer_free(ctx->xch, socketmap); xc_hypercall_buffer_free(ctx->xch, nodemap); - libxl_topologyinfo_dispose(info); - return ERROR_FAIL; + + if (ret) + *nr = max_cpus; + return ret; } const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx) @@ -3336,30 +3347,30 @@ int libxl_cpupool_cpuadd(libxl_ctx *ctx, int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus) { int rc = 0; - int cpu; + int cpu, nr; libxl_cpumap freemap; - libxl_topologyinfo topology; + libxl_cputopology *topology; if (libxl_get_freecpus(ctx, &freemap)) { return ERROR_FAIL; } - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &nr); + if (!topology) { rc = ERROR_FAIL; goto out; } *cpus = 0; - for (cpu = 0; cpu < topology.nodemap.entries; cpu++) { - if (libxl_cpumap_test(&freemap, cpu) && - (topology.nodemap.array[cpu] == node) && + for (cpu = 0; cpu < nr; cpu++) { + if (libxl_cpumap_test(&freemap, cpu) && (topology[cpu].node == node) && !libxl_cpupool_cpuadd(ctx, poolid, cpu)) { (*cpus)++; } + libxl_cputopology_dispose(&topology[cpu]); } - libxl_topologyinfo_dispose(&topology); - + free(topology); out: libxl_cpumap_dispose(&freemap); return rc; @@ -3383,8 +3394,8 @@ int libxl_cpupool_cpuremove_node(libxl_c int ret = 0; int n_pools; int p; - int cpu; - libxl_topologyinfo topology; + int cpu, nr_cpus; + libxl_cputopology *topology; libxl_cpupoolinfo *poolinfo; poolinfo = libxl_list_cpupool(ctx, &n_pools); @@ -3392,7 +3403,8 @@ int libxl_cpupool_cpuremove_node(libxl_c return ERROR_NOMEM; } - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &nr_cpus); + if (!topology) { ret = ERROR_FAIL; goto out; } @@ -3400,8 +3412,8 @@ int libxl_cpupool_cpuremove_node(libxl_c *cpus = 0; for (p = 0; p < n_pools; p++) { if (poolinfo[p].poolid == poolid) { - for (cpu = 0; cpu < topology.nodemap.entries; cpu++) { - if ((topology.nodemap.array[cpu] == node) && + for (cpu = 0; cpu < nr_cpus; cpu++) { + if ((topology[cpu].node == node) && libxl_cpumap_test(&poolinfo[p].cpumap, cpu) && !libxl_cpupool_cpuremove(ctx, poolid, cpu)) { (*cpus)++; @@ -3410,7 +3422,9 @@ int libxl_cpupool_cpuremove_node(libxl_c } } - libxl_topologyinfo_dispose(&topology); + for (cpu = 0; cpu < nr_cpus; cpu++) + libxl_cputopology_dispose(&topology[cpu]); + free(topology); out: for (p = 0; p < n_pools; p++) { diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -548,7 +548,8 @@ int libxl_userdata_retrieve(libxl_ctx *c */ int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo); -int libxl_get_topologyinfo(libxl_ctx *ctx, libxl_topologyinfo *info); +#define LIBXL_CPUTOPOLOGY_INVALID_ENTRY ~0 +libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nr); libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, int *nb_vcpu, int *nrcpus); int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -377,10 +377,10 @@ libxl_physinfo = Struct("physinfo", [ ("phys_cap", uint32), ], dispose_fn=None, dir=DIR_OUT) -libxl_topologyinfo = Struct("topologyinfo", [ - ("coremap", libxl_cpuarray), # cpu to core map - ("socketmap", libxl_cpuarray), # cpu to socket map - ("nodemap", libxl_cpuarray), # cpu to node map +libxl_cputopology = Struct("cputopology", [ + ("core", uint32), + ("socket", uint32), + ("node", uint32), ]) libxl_sched_credit = Struct("sched_credit", [ diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -3707,10 +3707,11 @@ static void output_physinfo(void) static void output_topologyinfo(void) { - libxl_topologyinfo info; - int i; - - if (libxl_get_topologyinfo(ctx, &info)) { + libxl_cputopology *info; + int i, nr; + + info = libxl_get_cpu_topology(ctx, &nr); + if (info == NULL) { fprintf(stderr, "libxl_get_topologyinfo failed.\n"); return; } @@ -3718,16 +3719,17 @@ static void output_topologyinfo(void) printf("cpu_topology :\n"); printf("cpu: core socket node\n"); - for (i = 0; i < info.coremap.entries; i++) { - if (info.coremap.array[i] != LIBXL_CPUARRAY_INVALID_ENTRY) - printf("%3d: %4d %4d %4d\n", i, info.coremap.array[i], - info.socketmap.array[i], info.nodemap.array[i]); - } + for (i = 0; i < nr; i++) { + if (info[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY) + printf("%3d: %4d %4d %4d\n", i, + info[i].core, info[i].socket, info[i].node); + libxl_cputopology_dispose(&info[i]); + } + + free(info); printf("numa_info : none\n"); - libxl_topologyinfo_dispose(&info); - return; } @@ -5160,7 +5162,7 @@ int main_cpupoolcreate(int argc, char ** libxl_cpumap freemap; libxl_cpumap cpumap; libxl_uuid uuid; - libxl_topologyinfo topology; + libxl_cputopology *topology; while (1) { opt = getopt_long(argc, argv, "hnf:", long_options, &option_index); @@ -5269,16 +5271,18 @@ int main_cpupoolcreate(int argc, char ** return -ERROR_FAIL; } if (!xlu_cfg_get_list(config, "nodes", &nodes, 0, 0)) { + int nr; n_cpus = 0; n_nodes = 0; - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &nr); + if (topology == NULL) { fprintf(stderr, "libxl_get_topologyinfo failed\n"); return -ERROR_FAIL; } while ((buf = xlu_cfg_get_listitem(nodes, n_nodes)) != NULL) { n = atoi(buf); - for (i = 0; i < topology.nodemap.entries; i++) { - if ((topology.nodemap.array[i] == n) && + for (i = 0; i < nr; i++) { + if ((topology[i].node == n) && libxl_cpumap_test(&freemap, i)) { libxl_cpumap_set(&cpumap, i); n_cpus++; @@ -5287,7 +5291,10 @@ int main_cpupoolcreate(int argc, char ** n_nodes++; } - libxl_topologyinfo_dispose(&topology); + for (i = 0; i < nr; i++) + libxl_cputopology_dispose(&topology[i]); + + free(topology); if (n_cpus == 0) { fprintf(stderr, "no free cpu found\n"); @@ -5609,11 +5616,12 @@ int main_cpupoolnumasplit(int argc, char int schedid; int n_pools; int node; + int n_cpus; char name[16]; libxl_uuid uuid; libxl_cpumap cpumap; libxl_cpupoolinfo *poolinfo; - libxl_topologyinfo topology; + libxl_cputopology *topology; libxl_dominfo info; if ((opt = def_getopt(argc, argv, "", "cpupool-numa-split", 0)) != -1) @@ -5635,21 +5643,24 @@ int main_cpupoolnumasplit(int argc, char return -ERROR_FAIL; } - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &n_cpus); + if (topology == NULL) { fprintf(stderr, "libxl_get_topologyinfo failed\n"); return -ERROR_FAIL; } if (libxl_cpumap_alloc(ctx, &cpumap)) { fprintf(stderr, "Failed to allocate cpumap\n"); - libxl_topologyinfo_dispose(&topology); + for (c=0; c<n_cpus; c++) + libxl_cputopology_dispose(&topology[c]); + free(topology); return -ERROR_FAIL; } /* Reset Pool-0 to 1st node: first add cpus, then remove cpus to avoid a cpupool without cpus in between */ - node = topology.nodemap.array[0]; + node = topology[0].node; if (libxl_cpupool_cpuadd_node(ctx, 0, node, &n)) { fprintf(stderr, "error on adding cpu to Pool 0\n"); return -ERROR_FAIL; @@ -5663,9 +5674,9 @@ int main_cpupoolnumasplit(int argc, char } n = 0; - for (c = 0; c < topology.nodemap.entries; c++) { - if (topology.nodemap.array[c] == node) { - topology.nodemap.array[c] = LIBXL_CPUARRAY_INVALID_ENTRY; + for (c = 0; c < n_cpus; c++) { + if (topology[c].node == node) { + topology[c].node = LIBXL_CPUTOPOLOGY_INVALID_ENTRY; libxl_cpumap_set(&cpumap, n); n++; } @@ -5690,12 +5701,12 @@ int main_cpupoolnumasplit(int argc, char } memset(cpumap.map, 0, cpumap.size); - for (c = 0; c < topology.nodemap.entries; c++) { - if (topology.nodemap.array[c] == LIBXL_CPUARRAY_INVALID_ENTRY) { + for (c = 0; c < n_cpus; c++) { + if (topology[c].node == LIBXL_CPUTOPOLOGY_INVALID_ENTRY) { continue; } - node = topology.nodemap.array[c]; + node = topology[c].node; ret = -libxl_cpupool_cpuremove_node(ctx, 0, node, &n); if (ret) { fprintf(stderr, "error on removing cpu from Pool 0\n"); @@ -5717,15 +5728,17 @@ int main_cpupoolnumasplit(int argc, char goto out; } - for (p = c; p < topology.nodemap.entries; p++) { - if (topology.nodemap.array[p] == node) { - topology.nodemap.array[p] = LIBXL_CPUARRAY_INVALID_ENTRY; + for (p = c; p < n_cpus; p++) { + if (topology[p].node == node) { + topology[p].node = LIBXL_CPUTOPOLOGY_INVALID_ENTRY; } } } out: - libxl_topologyinfo_dispose(&topology); + for (c=0; c<n_cpus; c++) + libxl_cputopology_dispose(&topology[c]); + free(topology); libxl_cpumap_dispose(&cpumap); return ret; diff --git a/tools/ocaml/libs/xl/genwrap.py b/tools/ocaml/libs/xl/genwrap.py --- a/tools/ocaml/libs/xl/genwrap.py +++ b/tools/ocaml/libs/xl/genwrap.py @@ -29,6 +29,8 @@ functions = { # ( name , [type1,type2,.. "device_pci": DEVICE_FUNCTIONS, "physinfo": [ ("get", ["unit", "t"]), ], + "cputopology": [ ("get", ["unit", "t array"]), + ], "sched_credit": [ ("domain_get", ["domid", "t"]), ("domain_set", ["domid", "t", "unit"]), ], @@ -259,7 +261,6 @@ if __name__ == ''__main__'': "domain_create_info", "domain_build_info", "vcpuinfo", - "topologyinfo", ] for t in blacklist: diff --git a/tools/ocaml/libs/xl/xenlight.ml.in b/tools/ocaml/libs/xl/xenlight.ml.in --- a/tools/ocaml/libs/xl/xenlight.ml.in +++ b/tools/ocaml/libs/xl/xenlight.ml.in @@ -19,17 +19,6 @@ type domid = int (* @@LIBXL_TYPES@@ *) -module Topologyinfo = struct - type t - { - core : int; - socket : int; - node : int; - } - external get : unit -> t array = "stub_xl_topologyinfo" -end - - external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff --git a/tools/ocaml/libs/xl/xenlight.mli.in b/tools/ocaml/libs/xl/xenlight.mli.in --- a/tools/ocaml/libs/xl/xenlight.mli.in +++ b/tools/ocaml/libs/xl/xenlight.mli.in @@ -19,16 +19,6 @@ type domid = int (* @@LIBXL_TYPES@@ *) -module Topologyinfo : sig - type t - { - core : int; - socket : int; - node : int; - } - external get : unit -> t array = "stub_xl_topologyinfo" -end - external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c --- a/tools/ocaml/libs/xl/xenlight_stubs.c +++ b/tools/ocaml/libs/xl/xenlight_stubs.c @@ -210,28 +210,6 @@ static value Val_hwcap(libxl_hwcap *c_va #include "_libxl_types.inc" -static value Val_topologyinfo(libxl_topologyinfo *c_val) -{ - CAMLparam0(); - CAMLlocal3(v, topology, topologyinfo); - int i; - - topologyinfo = caml_alloc_tuple(c_val->coremap.entries); - for (i = 0; i < c_val->coremap.entries; i++) { - v = Val_none; - if (c_val->coremap.array[i] != LIBXL_CPUARRAY_INVALID_ENTRY) { - topology = caml_alloc_tuple(3); - Store_field(topology, 0, Val_int(c_val->coremap.array[i])); - Store_field(topology, 1, Val_int(c_val->socketmap.array[i])); - Store_field(topology, 2, Val_int(c_val->nodemap.array[i])); - v = Val_some(topology); - } - Store_field(topologyinfo, i, v); - } - - CAMLreturn(topologyinfo); -} - value stub_xl_device_disk_add(value info, value domid) { CAMLparam2(info, domid); @@ -462,22 +440,34 @@ value stub_xl_physinfo_get(value unit) CAMLreturn(physinfo); } -value stub_xl_topologyinfo(value unit) +value stub_xl_cputopology_get(value unit) { CAMLparam1(unit); - CAMLlocal1(topologyinfo); - libxl_topologyinfo c_topologyinfo; - int ret; + CAMLlocal2(topology, v); + libxl_cputopology *c_topology; + int i, nr, ret; INIT_STRUCT(); INIT_CTX(); - ret = libxl_get_topologyinfo(ctx, &c_topologyinfo); + + c_topology = libxl_get_cpu_topology(ctx, &nr); if (ret != 0) failwith_xl("topologyinfo", &lg); + + topology = caml_alloc_tuple(nr); + for (i = 0; i < nr; i++) { + if (c_topology[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY) + v = Val_some(Val_cputopology(&gc, &lg, &c_topology[i])); + else + v = Val_none; + Store_field(topology, i, v); + libxl_cputopology_dispose(&c_topology[i]); + } + + free(c_topology); + FREE_CTX(); - - topologyinfo = Val_topologyinfo(&c_topologyinfo); - CAMLreturn(topologyinfo); + CAMLreturn(topology); } value stub_xl_sched_credit_domain_get(value domid)
Ian Campbell
2012-Jan-25 17:24 UTC
[PATCH 7 of 9] libxl: drop libxl_cpuarray -- topology was the only user
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327512175 0 # Node ID 0bf43ff297fc2cb4d6982da80cceec181deb6d55 # Parent e1753f37c9064f1e84fa32dfc37ff0f286e2df1e libxl: drop libxl_cpuarray -- topology was the only user. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py --- a/tools/libxl/gentest.py +++ b/tools/libxl/gentest.py @@ -21,7 +21,7 @@ def randomize_enum(e): handcoded = ["libxl_cpumap", "libxl_key_value_list", "libxl_cpuid_policy_list", "libxl_file_reference", - "libxl_string_list", "libxl_cpuarray"] + "libxl_string_list"] def gen_rand_init(ty, v, indent = " ", parent = None): s = "" @@ -194,23 +194,6 @@ static void libxl_string_list_rand_init( l[i] = NULL; *p = l; } - -#if 0 -static void libxl_cpuarray_rand_init(libxl_cpuarray *p) -{ - int i; - /* Up to 16 VCPUs on 32 PCPUS */ - p->entries = rand() % 16; - p->array = calloc(p->entries, sizeof(*p->array)); - for (i = 0; i < p->entries; i++) { - int r = rand() % 32*1.5; /* 2:1 valid:invalid */ - if (r >= 32) - p->array[i] = LIBXL_CPUARRAY_INVALID_ENTRY; - else - p->array[i] = r; - } -} -#endif """) for ty in builtins + types: if ty.typename not in handcoded: diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -158,13 +158,6 @@ typedef struct { void libxl_cpumap_dispose(libxl_cpumap *map); typedef struct { - uint32_t entries; - uint32_t *array; -} libxl_cpuarray; -#define LIBXL_CPUARRAY_INVALID_ENTRY ~0 -void libxl_cpuarray_dispose(libxl_cpuarray *array); - -typedef struct { /* * Path is always set if the file reference is valid. However if * mapped is true then the actual file may already be unlinked. diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c --- a/tools/libxl/libxl_json.c +++ b/tools/libxl/libxl_json.c @@ -246,27 +246,6 @@ out: return s; } -yajl_gen_status libxl_cpuarray_gen_json(yajl_gen hand, - libxl_cpuarray *cpuarray) -{ - yajl_gen_status s; - int i; - - s = yajl_gen_array_open(hand); - if (s != yajl_gen_status_ok) goto out; - - for(i=0; i<cpuarray->entries; i++) { - if (cpuarray->array[i] == LIBXL_CPUARRAY_INVALID_ENTRY) - s = yajl_gen_null(hand); - else - s = yajl_gen_integer(hand, cpuarray->array[i]); - if (s != yajl_gen_status_ok) goto out; - } - s = yajl_gen_array_close(hand); -out: - return s; -} - yajl_gen_status libxl_file_reference_gen_json(yajl_gen hand, libxl_file_reference *p) { diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -9,7 +9,6 @@ libxl_domid = Builtin("domid", json_fn libxl_uuid = Builtin("uuid", passby=PASS_BY_REFERENCE) libxl_mac = Builtin("mac", passby=PASS_BY_REFERENCE) libxl_cpumap = Builtin("cpumap", dispose_fn="libxl_cpumap_dispose", passby=PASS_BY_REFERENCE) -libxl_cpuarray = Builtin("cpuarray", dispose_fn="libxl_cpuarray_dispose", passby=PASS_BY_REFERENCE) libxl_cpuid_policy_list = Builtin("cpuid_policy_list", dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE) libxl_string_list = Builtin("string_list", dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE) diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -514,30 +514,6 @@ void libxl_cpumap_reset(libxl_cpumap *cp cpumap->map[cpu / 8] &= ~(1 << (cpu & 7)); } -int libxl_cpuarray_alloc(libxl_ctx *ctx, libxl_cpuarray *cpuarray) -{ - int max_cpus; - int i; - - max_cpus = libxl_get_max_cpus(ctx); - if (max_cpus == 0) - return ERROR_FAIL; - - cpuarray->array = calloc(max_cpus, sizeof(*cpuarray->array)); - if (!cpuarray->array) - return ERROR_NOMEM; - cpuarray->entries = max_cpus; - for (i = 0; i < max_cpus; i++) - cpuarray->array[i] = LIBXL_CPUARRAY_INVALID_ENTRY; - - return 0; -} - -void libxl_cpuarray_dispose(libxl_cpuarray *array) -{ - free(array->array); -} - int libxl_get_max_cpus(libxl_ctx *ctx) { return xc_get_max_cpus(ctx->xch); diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h --- a/tools/libxl/libxl_utils.h +++ b/tools/libxl/libxl_utils.h @@ -72,8 +72,6 @@ void libxl_cpumap_set(libxl_cpumap *cpum void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu); #define libxl_for_each_cpu(var, map) for (var = 0; var < (map).size * 8; var++) -int libxl_cpuarray_alloc(libxl_ctx *ctx, libxl_cpuarray *cpuarray); - static inline uint32_t libxl__sizekb_to_mb(uint32_t s) { return (s + 1023) / 1024; } diff --git a/tools/python/xen/lowlevel/xl/xl.c b/tools/python/xen/lowlevel/xl/xl.c --- a/tools/python/xen/lowlevel/xl/xl.c +++ b/tools/python/xen/lowlevel/xl/xl.c @@ -227,11 +227,6 @@ int attrib__libxl_cpumap_set(PyObject *v return 0; } -int attrib__libxl_cpuarray_set(PyObject *v, libxl_cpuarray *pptr) -{ - return -1; -} - int attrib__libxl_file_reference_set(PyObject *v, libxl_file_reference *pptr) { return genwrap__string_set(v, &pptr->path); @@ -304,25 +299,6 @@ PyObject *attrib__libxl_cpumap_get(libxl return cpulist; } -PyObject *attrib__libxl_cpuarray_get(libxl_cpuarray *pptr) -{ - PyObject *list = NULL; - int i; - - list = PyList_New(0); - for (i = 0; i < pptr->entries; i++) { - if (pptr->array[i] == LIBXL_CPUARRAY_INVALID_ENTRY) { - PyList_Append(list, Py_None); - } else { - PyObject* pyint = PyInt_FromLong(pptr->array[i]); - - PyList_Append(list, pyint); - Py_DECREF(pyint); - } - } - return list; -} - PyObject *attrib__libxl_file_reference_get(libxl_file_reference *pptr) { return genwrap__string_get(&pptr->path);
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327512175 0 # Node ID f43e2015d86f4d4c7dfa4db69f9d580fb3d705d9 # Parent 0bf43ff297fc2cb4d6982da80cceec181deb6d55 libxl: add named enum for timer mode. Unlike previous iterations of this patch the enum values now match the underlying domctl values. I looked at updating xl.cfg(5) for these while I was here but frankly, even after reading the comment in xen/include/public/hvm/params.h, I don''t have a clue what they mean, no_missed_ticks_pending in particular might as well be written in klingon... For the same reason I didn''t try and give the enum more user-friendly names. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -194,6 +194,8 @@ typedef struct { typedef struct libxl__ctx libxl_ctx; +#define LIBXL_TIMER_MODE_DEFAULT LIBXL_TIMER_MODE_NO_DELAY_FOR_MISSED_TICKS + #include "_libxl_types.h" const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx); diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -250,6 +250,13 @@ out: return ret == 0 ? 0 : ERROR_FAIL; } +static unsigned long timer_mode(const libxl_domain_build_info *info) +{ + const libxl_timer_mode mode = info->u.hvm.timer_mode; + assert(mode != LIBXL_TIMER_MODE_DELAY_FOR_MISSED_TICKS && + mode <= LIBXL_TIMER_MODE_ONE_MISSED_TICK_PENDING); + return ((unsigned long)mode); +} static int hvm_build_set_params(xc_interface *handle, uint32_t domid, libxl_domain_build_info *info, int store_evtchn, unsigned long *store_mfn, @@ -281,7 +288,7 @@ static int hvm_build_set_params(xc_inter xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, info->u.hvm.viridian); xc_set_hvm_param(handle, domid, HVM_PARAM_HPET_ENABLED, (unsigned long) info->u.hvm.hpet); #endif - xc_set_hvm_param(handle, domid, HVM_PARAM_TIMER_MODE, (unsigned long) info->u.hvm.timer_mode); + xc_set_hvm_param(handle, domid, HVM_PARAM_TIMER_MODE, timer_mode(info)); xc_set_hvm_param(handle, domid, HVM_PARAM_VPT_ALIGN, (unsigned long) info->u.hvm.vpt_align); xc_set_hvm_param(handle, domid, HVM_PARAM_NESTEDHVM, info->u.hvm.nested_hvm); xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn); diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -96,6 +96,14 @@ libxl_tsc_mode = Enumeration("tsc_mode", (3, "native_paravirt"), ]) +# Consistent with the values defined for HVM_PARAM_TIMER_MODE. +libxl_timer_mode = Enumeration("timer_mode", [ + (0, "delay_for_missed_ticks"), + (1, "no_delay_for_missed_ticks"), + (2, "no_missed_ticks_pending"), + (3, "one_missed_tick_pending"), + ]) + # # Complex libxl types # @@ -232,7 +240,7 @@ libxl_domain_build_info = Struct("domain ("timeoffset", string), ("hpet", bool), ("vpt_align", bool), - ("timer_mode", integer), + ("timer_mode", libxl_timer_mode), ("nested_hvm", bool), ("no_incr_generationid", bool), ("nographic", bool), diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -357,7 +357,9 @@ static void printf_info(int domid, printf("\t\t\t(viridian %d)\n", b_info->u.hvm.viridian); printf("\t\t\t(hpet %d)\n", b_info->u.hvm.hpet); printf("\t\t\t(vpt_align %d)\n", b_info->u.hvm.vpt_align); - printf("\t\t\t(timer_mode %d)\n", b_info->u.hvm.timer_mode); + printf("\t\t\t(timer_mode %s)\n", + libxl_timer_mode_to_string(b_info->u.hvm.timer_mode)); + printf("\t\t\t(nestedhvm %d)\n", b_info->u.hvm.nested_hvm); printf("\t\t\t(no_incr_generationid %d)\n", b_info->u.hvm.no_incr_generationid); @@ -757,8 +759,30 @@ static void parse_config_data(const char b_info->u.hvm.hpet = l; if (!xlu_cfg_get_long (config, "vpt_align", &l, 0)) b_info->u.hvm.vpt_align = l; - if (!xlu_cfg_get_long (config, "timer_mode", &l, 0)) + + if (!xlu_cfg_get_long(config, "timer_mode", &l, 1)) { + const char *s = libxl_timer_mode_to_string(l); + fprintf(stderr, "WARNING: specifying \"timer_mode\" as an integer is deprecated. " + "Please use the named parameter variant. %s%s%s\n", + s ? "e.g. timer_mode=\"" : "", + s ? s : "", + s ? "\"" : ""); + + if (l < LIBXL_TIMER_MODE_DELAY_FOR_MISSED_TICKS || + l > LIBXL_TIMER_MODE_ONE_MISSED_TICK_PENDING) { + fprintf(stderr, "ERROR: invalid value %ld for \"timer_mode\"\n", l); + exit (1); + } b_info->u.hvm.timer_mode = l; + } else if (!xlu_cfg_get_string(config, "timer_mode", &buf, 0)) { + fprintf(stderr, "got a timer mode string: \"%s\"\n", buf); + if (libxl_timer_mode_from_string(buf, &b_info->u.hvm.timer_mode)) { + fprintf(stderr, "ERROR: invalid value \"%s\" for \"timer_mode\"\n", + buf); + exit (1); + } + } + if (!xlu_cfg_get_long (config, "nestedhvm", &l, 0)) b_info->u.hvm.nested_hvm = l; break;
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327512175 0 # Node ID 9e3be181b2b70f521defcd55ecbd9967cd206fb2 # Parent f43e2015d86f4d4c7dfa4db69f9d580fb3d705d9 xl: use json output by default Move the sxp producing code off into a separate file. It is supported for legacy reasons and needn''t be updated other than the improve compatibility with xm. libxl_domain_config is not currently generated by the IDL (adding the necessary support for Array types is on my to do list) so hand code the json generation function for now. Since this rather directly exposes a libxl data structure it''s not clear what sort of forward compatibility guarantees we can make. However it seems like it should be as stable as libxl''s own API (which we are looking to stabilise) Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1 --- a/docs/man/xl.pod.1 +++ b/docs/man/xl.pod.1 @@ -219,7 +219,7 @@ B<OPTIONS> =item B<-l>, B<--long> The output for B<xl list> is not the table view shown below, but -instead presents the data in SXP compatible format. +instead presents the data in as a JSON data structure. =item B<-Z>, B<--context> Also prints the security labels. diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -62,7 +62,7 @@ LIBXLU_OBJS = libxlu_cfg_y.o libxlu_cfg_ CLIENTS = xl testidl -XL_OBJS = xl.o xl_cmdimpl.o xl_cmdtable.o +XL_OBJS = xl.o xl_cmdimpl.o xl_cmdtable.o xl_sxp.o $(XL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h $(XL_OBJS): CFLAGS += $(CFLAGS_libxenlight) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -239,6 +239,7 @@ typedef struct { libxl_action_on_shutdown on_watchdog; libxl_action_on_shutdown on_crash; } libxl_domain_config; +char *libxl_domain_config_to_json(libxl_ctx *ctx, libxl_domain_config *p); /* context functions */ int libxl_ctx_alloc(libxl_ctx **pctx, int version, diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c --- a/tools/libxl/libxl_json.c +++ b/tools/libxl/libxl_json.c @@ -848,6 +848,158 @@ out: return ret; } +yajl_gen_status libxl_domain_config_gen_json(yajl_gen hand, + libxl_domain_config *p) +{ + yajl_gen_status s; + int i; + + s = yajl_gen_map_open(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"c_info", + sizeof("c_info")-1); + if (s != yajl_gen_status_ok) + goto out; + s = libxl_domain_create_info_gen_json(hand, &p->c_info); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"b_info", + sizeof("b_info")-1); + if (s != yajl_gen_status_ok) + goto out; + s = libxl_domain_build_info_gen_json(hand, &p->b_info); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"disks", + sizeof("disks")-1); + if (s != yajl_gen_status_ok) + goto out; + s = yajl_gen_array_open(hand); + if (s != yajl_gen_status_ok) + goto out; + for (i = 0; i < p->num_disks; i++) { + s = libxl_device_disk_gen_json(hand, &p->disks[i]); + if (s != yajl_gen_status_ok) + goto out; + } + s = yajl_gen_array_close(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"vifs", + sizeof("vifs")-1); + if (s != yajl_gen_status_ok) + goto out; + s = yajl_gen_array_open(hand); + if (s != yajl_gen_status_ok) + goto out; + for (i = 0; i < p->num_vifs; i++) { + s = libxl_device_nic_gen_json(hand, &p->vifs[i]); + if (s != yajl_gen_status_ok) + goto out; + } + s = yajl_gen_array_close(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"pcidevs", + sizeof("pcidevs")-1); + if (s != yajl_gen_status_ok) + goto out; + s = yajl_gen_array_open(hand); + if (s != yajl_gen_status_ok) + goto out; + for (i = 0; i < p->num_pcidevs; i++) { + s = libxl_device_pci_gen_json(hand, &p->pcidevs[i]); + if (s != yajl_gen_status_ok) + goto out; + } + s = yajl_gen_array_close(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"vfbs", + sizeof("vfbs")-1); + if (s != yajl_gen_status_ok) + goto out; + s = yajl_gen_array_open(hand); + if (s != yajl_gen_status_ok) + goto out; + for (i = 0; i < p->num_vfbs; i++) { + s = libxl_device_vfb_gen_json(hand, &p->vfbs[i]); + if (s != yajl_gen_status_ok) + goto out; + } + s = yajl_gen_array_close(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"vkbs", + sizeof("vkbs")-1); + if (s != yajl_gen_status_ok) + goto out; + s = yajl_gen_array_open(hand); + if (s != yajl_gen_status_ok) + goto out; + for (i = 0; i < p->num_vkbs; i++) { + s = libxl_device_vkb_gen_json(hand, &p->vkbs[i]); + if (s != yajl_gen_status_ok) + goto out; + } + s = yajl_gen_array_close(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"on_poweroff", + sizeof("on_poweroff")-1); + if (s != yajl_gen_status_ok) + goto out; + s = libxl_action_on_shutdown_gen_json(hand, &p->on_poweroff); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"on_reboot", + sizeof("on_reboot")-1); + if (s != yajl_gen_status_ok) + goto out; + s = libxl_action_on_shutdown_gen_json(hand, &p->on_reboot); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"on_watchdog", + sizeof("on_watchdog")-1); + if (s != yajl_gen_status_ok) + goto out; + s = libxl_action_on_shutdown_gen_json(hand, &p->on_watchdog); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"on_crash", + sizeof("on_crash")-1); + if (s != yajl_gen_status_ok) + goto out; + s = libxl_action_on_shutdown_gen_json(hand, &p->on_crash); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_map_close(hand); + if (s != yajl_gen_status_ok) + goto out; + out: + return s; +} + +char *libxl_domain_config_to_json(libxl_ctx *ctx, libxl_domain_config *p) +{ + return libxl__object_to_json(ctx, "libxl_domain_config", + (libxl__gen_json_callback)&libxl_domain_config_gen_json, + (void *)p); +} + /* * Local variables: * mode: C diff --git a/tools/libxl/libxl_json.h b/tools/libxl/libxl_json.h --- a/tools/libxl/libxl_json.h +++ b/tools/libxl/libxl_json.h @@ -19,4 +19,7 @@ #include <_libxl_types_json.h> +yajl_gen_status libxl_domain_config_gen_json(yajl_gen hand, + libxl_domain_config *p); + #endif /* LIBXL_JSON_H */ diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c --- a/tools/libxl/xl.c +++ b/tools/libxl/xl.c @@ -38,6 +38,7 @@ int dryrun_only; int autoballoon = 1; char *lockfile; char *default_vifscript = NULL; +enum output_format default_output_format = OUTPUT_FORMAT_JSON; static xentoollog_level minmsglevel = XTL_PROGRESS; @@ -78,6 +79,15 @@ static void parse_global_config(const ch if (!xlu_cfg_get_string (config, "vifscript", &buf, 0)) default_vifscript = strdup(buf); + if (!xlu_cfg_get_string (config, "output_format", &buf, 0)) { + if (!strcmp(buf, "json")) + default_output_format = OUTPUT_FORMAT_JSON; + else if (!strcmp(buf, "sxp")) + default_output_format = OUTPUT_FORMAT_SXP; + else { + fprintf(stderr, "invalid default output format \"%s\"\n", buf); + } + } xlu_cfg_destroy(config); } diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -110,6 +110,14 @@ extern int dryrun_only; extern char *lockfile; extern char *default_vifscript; +enum output_format { + OUTPUT_FORMAT_JSON, + OUTPUT_FORMAT_SXP, +}; +extern enum output_format default_output_format; + +extern void printf_info_sexp(int domid, libxl_domain_config *d_config); + #endif /* XL_H */ /* diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -38,6 +38,7 @@ #include "libxl.h" #include "libxl_utils.h" +#include "libxl_json.h" #include "libxlutil.h" #include "xl.h" @@ -288,187 +289,66 @@ static void dolog(const char *file, int libxl_write_exactly(NULL, logfile, s, rc, NULL, NULL); } -static void printf_info(int domid, +static void printf_info(enum output_format output_format, + int domid, libxl_domain_config *d_config) { - int i; - libxl_dominfo info; - - libxl_domain_create_info *c_info = &d_config->c_info; - libxl_domain_build_info *b_info = &d_config->b_info; - - printf("(domain\n\t(domid %d)\n", domid); - printf("\t(create_info)\n"); - printf("\t(hvm %d)\n", c_info->type == LIBXL_DOMAIN_TYPE_HVM); - printf("\t(hap %d)\n", c_info->hap); - printf("\t(oos %d)\n", c_info->oos); - printf("\t(ssidref %d)\n", c_info->ssidref); - printf("\t(name %s)\n", c_info->name); - - /* retrieve the UUID from dominfo, since it is probably generated - * during parsing and thus does not match the real one - */ - if (libxl_domain_info(ctx, &info, domid) == 0) { - printf("\t(uuid " LIBXL_UUID_FMT ")\n", LIBXL_UUID_BYTES(info.uuid)); - } else { - printf("\t(uuid <unknown>)\n"); - } - - printf("\t(cpupool %s)\n", libxl_cpupoolid_to_name(ctx, c_info->poolid)); - if (c_info->xsdata) - printf("\t(xsdata contains data)\n"); + if (output_format == OUTPUT_FORMAT_SXP) + return printf_info_sexp(domid, d_config); + + yajl_gen_config conf = { 1, " " }; + const char *buf; + unsigned int len = 0; + yajl_gen_status s; + yajl_gen hand; + + hand = yajl_gen_alloc(&conf, NULL); + if (!hand) { + fprintf(stderr, "unable to allocate JSON generator\n"); + return; + } + + s = yajl_gen_map_open(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"domid", + sizeof("domid")-1); + if (s != yajl_gen_status_ok) + goto out; + if (domid != -1) + s = yajl_gen_integer(hand, domid); else - printf("\t(xsdata (null))\n"); - if (c_info->platformdata) - printf("\t(platformdata contains data)\n"); - else - printf("\t(platformdata (null))\n"); - - - printf("\t(build_info)\n"); - printf("\t(max_vcpus %d)\n", b_info->max_vcpus); - printf("\t(tsc_mode %s)\n", libxl_tsc_mode_to_string(b_info->tsc_mode)); - printf("\t(max_memkb %d)\n", b_info->max_memkb); - printf("\t(target_memkb %d)\n", b_info->target_memkb); - printf("\t(nomigrate %d)\n", b_info->disable_migrate); - - if (c_info->type == LIBXL_DOMAIN_TYPE_PV && b_info->u.pv.bootloader) { - int i; - printf("\t(bootloader %s)\n", b_info->u.pv.bootloader); - if (b_info->u.pv.bootloader_args) { - printf("\t(bootloader_args"); - for (i=0; b_info->u.pv.bootloader_args[i]; i++) - printf(" %s", b_info->u.pv.bootloader_args[i]); - printf(")\n"); - } - } - - printf("\t(image\n"); - switch (c_info->type) { - case LIBXL_DOMAIN_TYPE_HVM: - printf("\t\t(hvm\n"); - printf("\t\t\t(firmware %s)\n", b_info->u.hvm.firmware); - printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb); - printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb); - printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae); - printf("\t\t\t(apic %d)\n", b_info->u.hvm.apic); - printf("\t\t\t(acpi %d)\n", b_info->u.hvm.acpi); - printf("\t\t\t(nx %d)\n", b_info->u.hvm.nx); - printf("\t\t\t(viridian %d)\n", b_info->u.hvm.viridian); - printf("\t\t\t(hpet %d)\n", b_info->u.hvm.hpet); - printf("\t\t\t(vpt_align %d)\n", b_info->u.hvm.vpt_align); - printf("\t\t\t(timer_mode %s)\n", - libxl_timer_mode_to_string(b_info->u.hvm.timer_mode)); - - printf("\t\t\t(nestedhvm %d)\n", b_info->u.hvm.nested_hvm); - printf("\t\t\t(no_incr_generationid %d)\n", - b_info->u.hvm.no_incr_generationid); - - printf("\t\t\t(stdvga %d)\n", b_info->u.hvm.stdvga); - printf("\t\t\t(vnc %d)\n", b_info->u.hvm.vnc.enable); - printf("\t\t\t(vnclisten %s)\n", b_info->u.hvm.vnc.listen); - printf("\t\t\t(vncdisplay %d)\n", b_info->u.hvm.vnc.display); - printf("\t\t\t(vncunused %d)\n", b_info->u.hvm.vnc.findunused); - printf("\t\t\t(keymap %s)\n", b_info->u.hvm.keymap); - printf("\t\t\t(sdl %d)\n", b_info->u.hvm.sdl.enable); - printf("\t\t\t(opengl %d)\n", b_info->u.hvm.sdl.opengl); - printf("\t\t\t(nographic %d)\n", b_info->u.hvm.nographic); - printf("\t\t\t(spice %d)\n", b_info->u.hvm.spice.enable); - printf("\t\t\t(spiceport %d)\n", b_info->u.hvm.spice.port); - printf("\t\t\t(spicetls_port %d)\n", b_info->u.hvm.spice.tls_port); - printf("\t\t\t(spicehost %s)\n", b_info->u.hvm.spice.host); - printf("\t\t\t(spicedisable_ticketing %d)\n", - b_info->u.hvm.spice.disable_ticketing); - printf("\t\t\t(spiceagent_mouse %d)\n", b_info->u.hvm.spice.agent_mouse); - - printf("\t\t\t(device_model %s)\n", b_info->device_model ? : "default"); - printf("\t\t\t(gfx_passthru %d)\n", b_info->u.hvm.gfx_passthru); - printf("\t\t\t(serial %s)\n", b_info->u.hvm.serial); - printf("\t\t\t(boot %s)\n", b_info->u.hvm.boot); - printf("\t\t\t(usb %d)\n", b_info->u.hvm.usb); - printf("\t\t\t(usbdevice %s)\n", b_info->u.hvm.usbdevice); - printf("\t\t)\n"); - break; - case LIBXL_DOMAIN_TYPE_PV: - printf("\t\t(linux %d)\n", 0); - printf("\t\t\t(kernel %s)\n", b_info->u.pv.kernel.path); - printf("\t\t\t(cmdline %s)\n", b_info->u.pv.cmdline); - printf("\t\t\t(ramdisk %s)\n", b_info->u.pv.ramdisk.path); - printf("\t\t\t(e820_host %d)\n", b_info->u.pv.e820_host); - printf("\t\t)\n"); - break; - default: - fprintf(stderr, "Unknown domain type %d\n", c_info->type); - exit(1); - } - printf("\t)\n"); - - for (i = 0; i < d_config->num_disks; i++) { - printf("\t(device\n"); - printf("\t\t(tap\n"); - printf("\t\t\t(backend_domid %d)\n", d_config->disks[i].backend_domid); - printf("\t\t\t(frontend_domid %d)\n", domid); - printf("\t\t\t(physpath %s)\n", d_config->disks[i].pdev_path); - printf("\t\t\t(phystype %d)\n", d_config->disks[i].backend); - printf("\t\t\t(virtpath %s)\n", d_config->disks[i].vdev); - printf("\t\t\t(unpluggable %d)\n", d_config->disks[i].removable); - printf("\t\t\t(readwrite %d)\n", d_config->disks[i].readwrite); - printf("\t\t\t(is_cdrom %d)\n", d_config->disks[i].is_cdrom); - printf("\t\t)\n"); - printf("\t)\n"); - } - - for (i = 0; i < d_config->num_vifs; i++) { - printf("\t(device\n"); - printf("\t\t(vif\n"); - if (d_config->vifs[i].ifname) - printf("\t\t\t(vifname %s)\n", d_config->vifs[i].ifname); - printf("\t\t\t(backend_domid %d)\n", d_config->vifs[i].backend_domid); - printf("\t\t\t(frontend_domid %d)\n", domid); - printf("\t\t\t(devid %d)\n", d_config->vifs[i].devid); - printf("\t\t\t(mtu %d)\n", d_config->vifs[i].mtu); - printf("\t\t\t(model %s)\n", d_config->vifs[i].model); - printf("\t\t\t(mac %02x%02x%02x%02x%02x%02x)\n", - d_config->vifs[i].mac[0], d_config->vifs[i].mac[1], - d_config->vifs[i].mac[2], d_config->vifs[i].mac[3], - d_config->vifs[i].mac[4], d_config->vifs[i].mac[5]); - printf("\t\t)\n"); - printf("\t)\n"); - } - - for (i = 0; i < d_config->num_pcidevs; i++) { - printf("\t(device\n"); - printf("\t\t(pci\n"); - printf("\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n", - d_config->pcidevs[i].domain, d_config->pcidevs[i].bus, - d_config->pcidevs[i].dev, d_config->pcidevs[i].func, - d_config->pcidevs[i].vdevfn); - printf("\t\t\t(opts msitranslate %d power_mgmt %d)\n", - d_config->pcidevs[i].msitranslate, - d_config->pcidevs[i].power_mgmt); - printf("\t\t)\n"); - printf("\t)\n"); - } - - for (i = 0; i < d_config->num_vfbs; i++) { - printf("\t(device\n"); - printf("\t\t(vfb\n"); - printf("\t\t\t(backend_domid %d)\n", d_config->vfbs[i].backend_domid); - printf("\t\t\t(frontend_domid %d)\n", domid); - printf("\t\t\t(devid %d)\n", d_config->vfbs[i].devid); - printf("\t\t\t(vnc %d)\n", d_config->vfbs[i].vnc.enable); - printf("\t\t\t(vnclisten %s)\n", d_config->vfbs[i].vnc.listen); - printf("\t\t\t(vncdisplay %d)\n", d_config->vfbs[i].vnc.display); - printf("\t\t\t(vncunused %d)\n", d_config->vfbs[i].vnc.findunused); - printf("\t\t\t(keymap %s)\n", d_config->vfbs[i].keymap); - printf("\t\t\t(sdl %d)\n", d_config->vfbs[i].sdl.enable); - printf("\t\t\t(opengl %d)\n", d_config->vfbs[i].sdl.opengl); - printf("\t\t\t(display %s)\n", d_config->vfbs[i].sdl.display); - printf("\t\t\t(xauthority %s)\n", d_config->vfbs[i].sdl.xauthority); - printf("\t\t)\n"); - printf("\t)\n"); - } - printf(")\n"); + s = yajl_gen_null(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_string(hand, (const unsigned char *)"config", + sizeof("config")-1); + if (s != yajl_gen_status_ok) + goto out; + s = libxl_domain_config_gen_json(hand, d_config); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_map_close(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &len); + if (s != yajl_gen_status_ok) + goto out; + + puts(buf); + +out: + yajl_gen_free(hand); + + if (s != yajl_gen_status_ok) + fprintf(stderr, + "unable to format domain config as JSON (YAJL:%d)\n", s); + + if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); } } static int parse_action_on_shutdown(const char *buf, libxl_action_on_shutdown *a) @@ -622,7 +502,7 @@ static void parse_config_data(const char c_info->hap = l; if (xlu_cfg_replace_string (config, "name", &c_info->name, 0)) { - fprintf(stderr, "Domain name must be specified."); + fprintf(stderr, "Domain name must be specified.\n"); exit(1); } @@ -1599,7 +1479,7 @@ static int create_domain(struct domain_c dom_info->no_incr_generationid; if (debug || dom_info->dryrun) - printf_info(-1, &d_config); + printf_info(default_output_format, -1, &d_config); ret = 0; if (dom_info->dryrun) @@ -2367,7 +2247,7 @@ static void list_domains_details(const l CHK_ERRNO(asprintf(&config_file, "<domid %d data>", info[i].domid)); memset(&d_config, 0x00, sizeof(d_config)); parse_config_data(config_file, (char *)data, len, &d_config); - printf_info(info[i].domid, &d_config); + printf_info(default_output_format, info[i].domid, &d_config); libxl_domain_config_dispose(&d_config); free(data); free(config_file); diff --git a/tools/libxl/xl_sxp.c b/tools/libxl/xl_sxp.c new file mode 100644 --- /dev/null +++ b/tools/libxl/xl_sxp.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2009 Citrix Ltd. + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +/* + * Legacy SXP output handling + */ + +#include "libxl_osdeps.h" + +#include <stdlib.h> + +#include "libxl.h" +#include "libxl_utils.h" +#include "xl.h" + +/* In general you should not add new output to this function since it + * is intended only for legacy use. + */ +void printf_info_sexp(int domid, libxl_domain_config *d_config) +{ + int i; + libxl_dominfo info; + + libxl_domain_create_info *c_info = &d_config->c_info; + libxl_domain_build_info *b_info = &d_config->b_info; + + printf("(domain\n\t(domid %d)\n", domid); + printf("\t(create_info)\n"); + printf("\t(hvm %d)\n", c_info->type == LIBXL_DOMAIN_TYPE_HVM); + printf("\t(hap %d)\n", c_info->hap); + printf("\t(oos %d)\n", c_info->oos); + printf("\t(ssidref %d)\n", c_info->ssidref); + printf("\t(name %s)\n", c_info->name); + + /* retrieve the UUID from dominfo, since it is probably generated + * during parsing and thus does not match the real one + */ + if (libxl_domain_info(ctx, &info, domid) == 0) { + printf("\t(uuid " LIBXL_UUID_FMT ")\n", LIBXL_UUID_BYTES(info.uuid)); + } else { + printf("\t(uuid <unknown>)\n"); + } + + printf("\t(cpupool %s)\n", libxl_cpupoolid_to_name(ctx, c_info->poolid)); + if (c_info->xsdata) + printf("\t(xsdata contains data)\n"); + else + printf("\t(xsdata (null))\n"); + if (c_info->platformdata) + printf("\t(platformdata contains data)\n"); + else + printf("\t(platformdata (null))\n"); + + + printf("\t(build_info)\n"); + printf("\t(max_vcpus %d)\n", b_info->max_vcpus); + printf("\t(tsc_mode %s)\n", libxl_tsc_mode_to_string(b_info->tsc_mode)); + printf("\t(max_memkb %d)\n", b_info->max_memkb); + printf("\t(target_memkb %d)\n", b_info->target_memkb); + printf("\t(nomigrate %d)\n", b_info->disable_migrate); + + if (c_info->type == LIBXL_DOMAIN_TYPE_PV && b_info->u.pv.bootloader) { + int i; + printf("\t(bootloader %s)\n", b_info->u.pv.bootloader); + if (b_info->u.pv.bootloader_args) { + printf("\t(bootloader_args"); + for (i=0; b_info->u.pv.bootloader_args[i]; i++) + printf(" %s", b_info->u.pv.bootloader_args[i]); + printf(")\n"); + } + } + + printf("\t(image\n"); + switch (c_info->type) { + case LIBXL_DOMAIN_TYPE_HVM: + printf("\t\t(hvm\n"); + printf("\t\t\t(firmware %s)\n", b_info->u.hvm.firmware); + printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb); + printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb); + printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae); + printf("\t\t\t(apic %d)\n", b_info->u.hvm.apic); + printf("\t\t\t(acpi %d)\n", b_info->u.hvm.acpi); + printf("\t\t\t(nx %d)\n", b_info->u.hvm.nx); + printf("\t\t\t(viridian %d)\n", b_info->u.hvm.viridian); + printf("\t\t\t(hpet %d)\n", b_info->u.hvm.hpet); + printf("\t\t\t(vpt_align %d)\n", b_info->u.hvm.vpt_align); + printf("\t\t\t(timer_mode %s)\n", + libxl_timer_mode_to_string(b_info->u.hvm.timer_mode)); + printf("\t\t\t(nestedhvm %d)\n", b_info->u.hvm.nested_hvm); + printf("\t\t\t(no_incr_generationid %d)\n", + b_info->u.hvm.no_incr_generationid); + + printf("\t\t\t(stdvga %d)\n", b_info->u.hvm.stdvga); + printf("\t\t\t(vnc %d)\n", b_info->u.hvm.vnc.enable); + printf("\t\t\t(vnclisten %s)\n", b_info->u.hvm.vnc.listen); + printf("\t\t\t(vncdisplay %d)\n", b_info->u.hvm.vnc.display); + printf("\t\t\t(vncunused %d)\n", b_info->u.hvm.vnc.findunused); + printf("\t\t\t(keymap %s)\n", b_info->u.hvm.keymap); + printf("\t\t\t(sdl %d)\n", b_info->u.hvm.sdl.enable); + printf("\t\t\t(opengl %d)\n", b_info->u.hvm.sdl.opengl); + printf("\t\t\t(nographic %d)\n", b_info->u.hvm.nographic); + printf("\t\t\t(spice %d)\n", b_info->u.hvm.spice.enable); + printf("\t\t\t(spiceport %d)\n", b_info->u.hvm.spice.port); + printf("\t\t\t(spicetls_port %d)\n", b_info->u.hvm.spice.tls_port); + printf("\t\t\t(spicehost %s)\n", b_info->u.hvm.spice.host); + printf("\t\t\t(spicedisable_ticketing %d)\n", + b_info->u.hvm.spice.disable_ticketing); + printf("\t\t\t(spiceagent_mouse %d)\n", b_info->u.hvm.spice.agent_mouse); + + printf("\t\t\t(device_model %s)\n", b_info->device_model ? : "default"); + printf("\t\t\t(gfx_passthru %d)\n", b_info->u.hvm.gfx_passthru); + printf("\t\t\t(serial %s)\n", b_info->u.hvm.serial); + printf("\t\t\t(boot %s)\n", b_info->u.hvm.boot); + printf("\t\t\t(usb %d)\n", b_info->u.hvm.usb); + printf("\t\t\t(usbdevice %s)\n", b_info->u.hvm.usbdevice); + printf("\t\t)\n"); + break; + case LIBXL_DOMAIN_TYPE_PV: + printf("\t\t(linux %d)\n", 0); + printf("\t\t\t(kernel %s)\n", b_info->u.pv.kernel.path); + printf("\t\t\t(cmdline %s)\n", b_info->u.pv.cmdline); + printf("\t\t\t(ramdisk %s)\n", b_info->u.pv.ramdisk.path); + printf("\t\t\t(e820_host %d)\n", b_info->u.pv.e820_host); + printf("\t\t)\n"); + break; + default: + fprintf(stderr, "Unknown domain type %d\n", c_info->type); + exit(1); + } + printf("\t)\n"); + + for (i = 0; i < d_config->num_disks; i++) { + printf("\t(device\n"); + printf("\t\t(tap\n"); + printf("\t\t\t(backend_domid %d)\n", d_config->disks[i].backend_domid); + printf("\t\t\t(frontend_domid %d)\n", domid); + printf("\t\t\t(physpath %s)\n", d_config->disks[i].pdev_path); + printf("\t\t\t(phystype %d)\n", d_config->disks[i].backend); + printf("\t\t\t(virtpath %s)\n", d_config->disks[i].vdev); + printf("\t\t\t(unpluggable %d)\n", d_config->disks[i].removable); + printf("\t\t\t(readwrite %d)\n", d_config->disks[i].readwrite); + printf("\t\t\t(is_cdrom %d)\n", d_config->disks[i].is_cdrom); + printf("\t\t)\n"); + printf("\t)\n"); + } + + for (i = 0; i < d_config->num_vifs; i++) { + printf("\t(device\n"); + printf("\t\t(vif\n"); + if (d_config->vifs[i].ifname) + printf("\t\t\t(vifname %s)\n", d_config->vifs[i].ifname); + printf("\t\t\t(backend_domid %d)\n", d_config->vifs[i].backend_domid); + printf("\t\t\t(frontend_domid %d)\n", domid); + printf("\t\t\t(devid %d)\n", d_config->vifs[i].devid); + printf("\t\t\t(mtu %d)\n", d_config->vifs[i].mtu); + printf("\t\t\t(model %s)\n", d_config->vifs[i].model); + printf("\t\t\t(mac %02x%02x%02x%02x%02x%02x)\n", + d_config->vifs[i].mac[0], d_config->vifs[i].mac[1], + d_config->vifs[i].mac[2], d_config->vifs[i].mac[3], + d_config->vifs[i].mac[4], d_config->vifs[i].mac[5]); + printf("\t\t)\n"); + printf("\t)\n"); + } + + for (i = 0; i < d_config->num_pcidevs; i++) { + printf("\t(device\n"); + printf("\t\t(pci\n"); + printf("\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n", + d_config->pcidevs[i].domain, d_config->pcidevs[i].bus, + d_config->pcidevs[i].dev, d_config->pcidevs[i].func, + d_config->pcidevs[i].vdevfn); + printf("\t\t\t(opts msitranslate %d power_mgmt %d)\n", + d_config->pcidevs[i].msitranslate, + d_config->pcidevs[i].power_mgmt); + printf("\t\t)\n"); + printf("\t)\n"); + } + + for (i = 0; i < d_config->num_vfbs; i++) { + printf("\t(device\n"); + printf("\t\t(vfb\n"); + printf("\t\t\t(backend_domid %d)\n", d_config->vfbs[i].backend_domid); + printf("\t\t\t(frontend_domid %d)\n", domid); + printf("\t\t\t(devid %d)\n", d_config->vfbs[i].devid); + printf("\t\t\t(vnc %d)\n", d_config->vfbs[i].vnc.enable); + printf("\t\t\t(vnclisten %s)\n", d_config->vfbs[i].vnc.listen); + printf("\t\t\t(vncdisplay %d)\n", d_config->vfbs[i].vnc.display); + printf("\t\t\t(vncunused %d)\n", d_config->vfbs[i].vnc.findunused); + printf("\t\t\t(keymap %s)\n", d_config->vfbs[i].keymap); + printf("\t\t\t(sdl %d)\n", d_config->vfbs[i].sdl.enable); + printf("\t\t\t(opengl %d)\n", d_config->vfbs[i].sdl.opengl); + printf("\t\t\t(display %s)\n", d_config->vfbs[i].sdl.display); + printf("\t\t\t(xauthority %s)\n", d_config->vfbs[i].sdl.xauthority); + printf("\t\t)\n"); + printf("\t)\n"); + } + printf(")\n"); +} + + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327513374 0 # Node ID 6ad2a7d8805acd8f1b5eaf8ebb7b28007840c8f4 # Parent 9e3be181b2b70f521defcd55ecbd9967cd206fb2 docs: document /etc/xen/xl.conf Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 9e3be181b2b7 -r 6ad2a7d8805a docs/man/xl.conf.pod.5 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/man/xl.conf.pod.5 Wed Jan 25 17:42:54 2012 +0000 @@ -0,0 +1,93 @@ +=head1 NAME + +/etc/xen/xl.conf - XL Global/Host Configuration + +=head1 DESCRIPTION + +The F<xl.conf> file allows configuration of hostwide C<xl> toolstack +options. + +For details of per-domain configuration options please see +L<xl.cfg(5)>. + +=head1 SYNTAX + +The config file consists of a series of C<KEY=VALUE> pairs. + +A value C<VALUE> is one of: + +=over 4 + +=item B<"STRING"> + +A string, surrounded by either single or double quotes. + +=item B<NUMBER> + +A number, in either decimal, octal (using a C<0> prefix) or +hexadecimal (using an C<0x> prefix). + +=item B<BOOLEAN> + +A C<NUMBER> interpreted as C<False> (C<0>) or C<True> (any other +value). + +=item B<[ VALUE, VALUE, ... ]> + +A list of C<VALUES> of the above types. Lists are homogeneous and are +not nested. + +=back + +The semantics of each C<KEY> defines which form of C<VALUE> is required. + +=head1 OPTIONS + +=over 4 + +=item B<autoballoon=BOOLEAN> + +If enabled then C<xl> will not attempt to reduce the amount of memory +assigned to domain 0 in order to create free memory when starting a +new domain. You should set this if you use the C<dom0_mem> hypervisor +command line to reduce the amount of memory given to domain 0 by +default. + +Default: C<0> + +=item B<lockfile="PATH"> + +Sets the path to the lock file used by xl to serialise certain +operations (primarily domain creation). + +Default: C</var/lock/xl> + +=item B<vifscript="PATH"> + +Configures the default hotplug script used by virtual network devices. + +Default: C</etc/xen/scripts/vif-bridge> + +=item B<output_format="json|sxp"> + +Configures the default output format used by xl when printing "machine +readable" information. The default is to use the C<JSON> +L<http://www.json.org/> syntax. However for compatibility with the +previous C<xm> toolstack this can be configured to use the old C<SXP> +(S-Expression-like) syntax instead. + +Default: C<json> + +=back + +=head1 SEE ALSO + +=over 4 + +=item L<xl(1)> + +=item L<xl.cfg(5)> + +=item http://www.json.org/ + +=back
Ian Campbell
2012-Jan-26 08:25 UTC
Re: [PATCH 3 of 9] libxl: remove libxl_button_press in favour of libxl_send_trigger
On Wed, 2012-01-25 at 17:24 +0000, Ian Campbell wrote:> # HG changeset patch > # User Ian Campbell <ian.campbell@citrix.com> > # Date 1327510508 0 > # Node ID a7776e38447d4e633a45b926295f7923c046fbc9 > # Parent b9973edc7528e5233698fefd234be19dd6d6bcee > libxl: remove libxl_button_press in favour of libxl_send_trigger. > > send_trigger already included all the operations covered by button_press. > > Rework send_trigger to take an enum instead of a string. > > I stopped short at removing the xl "button-press" command but instead have > marked it as deprecated. > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>V2: update messages from xl destroy/reboot when no PV mechanism is present. 8<------------------------------------------------------------- # HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1327510508 0 # Node ID a7776e38447d4e633a45b926295f7923c046fbc9 # Parent b9973edc7528e5233698fefd234be19dd6d6bcee libxl: remove libxl_button_press in favour of libxl_send_trigger. send_trigger already included all the operations covered by button_press. Rework send_trigger to take an enum instead of a string. I stopped short at removing the xl "button-press" command but instead have marked it as deprecated. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r b9973edc7528 -r a7776e38447d docs/man/xl.pod.1 --- a/docs/man/xl.pod.1 Wed Jan 25 16:55:08 2012 +0000 +++ b/docs/man/xl.pod.1 Wed Jan 25 16:55:08 2012 +0000 @@ -86,6 +86,8 @@ previously, most commands take I<domain- =item B<button-press> I<domain-id> I<button> +I<This command is deprecated. Please use C<xl trigger> in preference> + Indicate an ACPI button press to the domain. I<button> is may be ''power'' or ''sleep''. This command is only available for HVM domains. @@ -448,7 +450,7 @@ It can be used to send SysRq requests to your Linux Kernel sources for more information. It requires PV drivers to be installed in your guest OS. -=item B<trigger> I<domain-id> I<nmi|reset|init|power|sleep> [I<VCPU>] +=item B<trigger> I<domain-id> I<nmi|reset|init|power|sleep|s3resume> [I<VCPU>] Send a trigger to a domain, where the trigger can be: nmi, reset, init, power or sleep. Optionally a specific vcpu number can be passed as an argument. diff -r b9973edc7528 -r a7776e38447d tools/libxl/gentypes.py --- a/tools/libxl/gentypes.py Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/libxl/gentypes.py Wed Jan 25 16:55:08 2012 +0000 @@ -32,6 +32,9 @@ def libxl_C_type_define(ty, indent = "") s += "} %s" % ty.typename elif isinstance(ty, idl.Aggregate): + if isinstance(ty, idl.KeyedUnion): + s += libxl_C_instance_of(ty.keyvar_type, ty.keyvar_name) + ";\n" + if ty.typename is None: s += "%s {\n" % ty.kind else: diff -r b9973edc7528 -r a7776e38447d tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/libxl/libxl.c Wed Jan 25 16:55:08 2012 +0000 @@ -2477,24 +2477,6 @@ out: return 0; } -int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button) -{ - int rc = -1; - - switch (button) { - case LIBXL_BUTTON_POWER: - rc = xc_domain_send_trigger(ctx->xch, domid, XEN_DOMCTL_SENDTRIGGER_POWER, 0); - break; - case LIBXL_BUTTON_SLEEP: - rc = xc_domain_send_trigger(ctx->xch, domid, XEN_DOMCTL_SENDTRIGGER_SLEEP, 0); - break; - default: - break; - } - - return rc; -} - int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo) { xc_physinfo_t xcphysinfo = { 0 }; @@ -2876,44 +2858,46 @@ int libxl_sched_sedf_domain_set(libxl_ct return 0; } -static int trigger_type_from_string(char *trigger_name) +int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, + libxl_trigger trigger, uint32_t vcpuid) { - if (!strcmp(trigger_name, "nmi")) - return XEN_DOMCTL_SENDTRIGGER_NMI; - else if (!strcmp(trigger_name, "reset")) - return XEN_DOMCTL_SENDTRIGGER_RESET; - else if (!strcmp(trigger_name, "init")) - return XEN_DOMCTL_SENDTRIGGER_INIT; - else if (!strcmp(trigger_name, "power")) - return XEN_DOMCTL_SENDTRIGGER_POWER; - else if (!strcmp(trigger_name, "sleep")) - return XEN_DOMCTL_SENDTRIGGER_SLEEP; - else - return -1; -} - -int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, char *trigger_name, uint32_t vcpuid) -{ - int rc = -1; - int trigger_type = -1; - - if (!strcmp(trigger_name, "s3resume")) { + int rc; + + switch (trigger) { + case LIBXL_TRIGGER_POWER: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_POWER, vcpuid); + break; + case LIBXL_TRIGGER_SLEEP: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_SLEEP, vcpuid); + break; + case LIBXL_TRIGGER_NMI: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_NMI, vcpuid); + break; + case LIBXL_TRIGGER_INIT: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_INIT, vcpuid); + break; + case LIBXL_TRIGGER_RESET: + rc = xc_domain_send_trigger(ctx->xch, domid, + XEN_DOMCTL_SENDTRIGGER_RESET, vcpuid); + break; + case LIBXL_TRIGGER_S3RESUME: xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, 0); - return 0; + rc = 0; + break; + default: + rc = EINVAL; + break; } - trigger_type = trigger_type_from_string(trigger_name); - if (trigger_type == -1) { - LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, -1, - "Invalid trigger, valid triggers are <nmi|reset|init|power|sleep>"); - return ERROR_INVAL; - } - - rc = xc_domain_send_trigger(ctx->xch, domid, trigger_type, vcpuid); if (rc != 0) { LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, - "Send trigger ''%s'' failed", trigger_name); - return ERROR_FAIL; + "Send trigger ''%s'' failed", + libxl_trigger_to_string(trigger)); + rc = ERROR_FAIL; } return 0; diff -r b9973edc7528 -r a7776e38447d tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/libxl/libxl.h Wed Jan 25 16:55:08 2012 +0000 @@ -547,8 +547,6 @@ int libxl_userdata_retrieve(libxl_ctx *c * On error return, *data_r and *datalen_r are undefined. */ -int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button); - int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo); int libxl_get_topologyinfo(libxl_ctx *ctx, libxl_topologyinfo *info); libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, @@ -573,7 +571,7 @@ int libxl_sched_sedf_domain_get(libxl_ct int libxl_sched_sedf_domain_set(libxl_ctx *ctx, uint32_t domid, libxl_sched_sedf *scinfo); int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, - char *trigger_name, uint32_t vcpuid); + libxl_trigger trigger, uint32_t vcpuid); int libxl_send_sysrq(libxl_ctx *ctx, uint32_t domid, char sysrq); int libxl_send_debug_keys(libxl_ctx *ctx, char *keys); diff -r b9973edc7528 -r a7776e38447d tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/libxl/libxl_types.idl Wed Jan 25 16:55:08 2012 +0000 @@ -80,9 +80,14 @@ libxl_event_type = Enumeration("event_ty (2, "DISK_EJECT"), ]) -libxl_button = Enumeration("button", [ +libxl_trigger = Enumeration("trigger", [ + (0, "UNKNOWN"), (1, "POWER"), (2, "SLEEP"), + (3, "NMI"), + (4, "INIT"), + (5, "RESET"), + (6, "S3RESUME"), ]) libxl_tsc_mode = Enumeration("tsc_mode", [ @@ -203,7 +208,6 @@ libxl_domain_build_info = Struct("domain ("shadow_memkb", uint32), ("disable_migrate", bool), ("cpuid", libxl_cpuid_policy_list), - ("type", libxl_domain_type), ("device_model_version", libxl_device_model_version), ("device_model_stubdomain", bool), diff -r b9973edc7528 -r a7776e38447d tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/libxl/xl_cmdimpl.c Wed Jan 25 16:55:08 2012 +0000 @@ -3318,26 +3318,29 @@ int main_create(int argc, char **argv) static void button_press(const char *p, const char *b) { - libxl_button button; + libxl_trigger trigger; find_domain(p); if (!strcmp(b, "power")) { - button = LIBXL_BUTTON_POWER; + trigger = LIBXL_TRIGGER_POWER; } else if (!strcmp(b, "sleep")) { - button = LIBXL_BUTTON_SLEEP; + trigger = LIBXL_TRIGGER_SLEEP; } else { fprintf(stderr, "%s is an invalid button identifier\n", b); exit(2); } - libxl_button_press(ctx, domid, button); + libxl_send_trigger(ctx, domid, trigger, 0); } int main_button_press(int argc, char **argv) { int opt; + fprintf(stderr, "WARNING: \"button-press\" is deprecated. " + "Please use \"trigger\"\n"); + if ((opt = def_getopt(argc, argv, "", "button-press", 2)) != -1) return opt; @@ -4322,10 +4325,11 @@ int main_rename(int argc, char **argv) int main_trigger(int argc, char **argv) { int opt; - char *trigger_name = NULL; char *endptr = NULL; const char *dom = NULL; int vcpuid = 0; + const char *trigger_name = NULL; + libxl_trigger trigger; if ((opt = def_getopt(argc, argv, "", "trigger", 2)) != -1) return opt; @@ -4335,6 +4339,10 @@ int main_trigger(int argc, char **argv) find_domain(dom); trigger_name = argv[optind++]; + if (libxl_trigger_from_string(trigger_name, &trigger)) { + fprintf(stderr, "Invalid trigger \"%s\"\n", trigger_name); + return -1; + } if (argv[optind]) { vcpuid = strtol(argv[optind], &endptr, 10); @@ -4343,7 +4351,7 @@ int main_trigger(int argc, char **argv) } } - libxl_send_trigger(ctx, domid, trigger_name, vcpuid); + libxl_send_trigger(ctx, domid, trigger, vcpuid); return 0; } diff -r b9973edc7528 -r a7776e38447d tools/ocaml/libs/xl/xenlight.ml.in --- a/tools/ocaml/libs/xl/xenlight.ml.in Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/ocaml/libs/xl/xenlight.ml.in Wed Jan 25 16:55:08 2012 +0000 @@ -29,10 +29,8 @@ module Topologyinfo = struct external get : unit -> t = "stub_xl_topologyinfo" end -external button_press : domid -> button -> unit = "stub_xl_button_press" - -external send_trigger : domid -> string -> int -> unit = "stub_xl_send_trigger" +external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff -r b9973edc7528 -r a7776e38447d tools/ocaml/libs/xl/xenlight.mli.in --- a/tools/ocaml/libs/xl/xenlight.mli.in Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/ocaml/libs/xl/xenlight.mli.in Wed Jan 25 16:55:08 2012 +0000 @@ -29,8 +29,6 @@ module Topologyinfo : sig external get : unit -> t = "stub_xl_topologyinfo" end -external button_press : domid -> button -> unit = "stub_xl_button_press" - -external send_trigger : domid -> string -> int -> unit = "stub_xl_send_trigger" +external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff -r b9973edc7528 -r a7776e38447d tools/ocaml/libs/xl/xenlight_stubs.c --- a/tools/ocaml/libs/xl/xenlight_stubs.c Wed Jan 25 16:55:08 2012 +0000 +++ b/tools/ocaml/libs/xl/xenlight_stubs.c Wed Jan 25 16:55:08 2012 +0000 @@ -432,21 +432,6 @@ value stub_xl_device_pci_remove(value in CAMLreturn(Val_unit); } -value stub_xl_button_press(value domid, value button) -{ - CAMLparam2(domid, button); - int ret; - INIT_STRUCT(); - - INIT_CTX(); - ret = libxl_button_press(ctx, Int_val(domid), Int_val(button) + LIBXL_BUTTON_POWER); - if (ret != 0) - failwith_xl("button_press", &lg); - FREE_CTX(); - - CAMLreturn(Val_unit); -} - value stub_xl_physinfo_get(value unit) { CAMLparam1(unit); @@ -523,10 +508,10 @@ value stub_xl_send_trigger(value domid, { CAMLparam3(domid, trigger, vcpuid); int ret; - char *c_trigger; + libxl_trigger c_trigger = LIBXL_TRIGGER_UNKNOWN; INIT_STRUCT(); - c_trigger = dup_String_val(&gc, trigger); + trigger_val(&gc, &lg, &c_trigger, trigger); INIT_CTX(); ret = libxl_send_trigger(ctx, Int_val(domid), c_trigger, Int_val(vcpuid));
Ian Jackson
2012-Jan-27 18:10 UTC
Re: [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps
Ian Campbell writes ("[Xen-devel] [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps"):> libxl: expose cpu topology as a single list of cpu->{node,core,socket} maps. > > Rather than the previous tripple list which is more complicated to work with > and harder for language bindings.This is plausible. But:> +#if 0 > static void libxl_cpuarray_rand_init(libxl_cpuarray *p) > { > int i; > @@ -209,6 +210,7 @@ static void libxl_cpuarray_rand_init(lib > p->array[i] = r; > } > } > +#endifYou haven''t quite finished ?> + for (cpu = 0; cpu < nr; cpu++) {...> + libxl_cputopology_dispose(&topology[cpu]); > } > > - libxl_topologyinfo_dispose(&topology); > - > + free(topology);This is quite ugly to have out here in the caller. Perhaps we should provide a helper for this, called libxl_cputopology_free or something ?> - libxl_topologyinfo_dispose(&topology); > + for (cpu = 0; cpu < nr_cpus; cpu++) > + libxl_cputopology_dispose(&topology[cpu]); > + free(topology);And here it is again, proving my point :-).> +#define LIBXL_CPUTOPOLOGY_INVALID_ENTRY ~0...> +libxl_cputopology = Struct("cputopology", [ > + ("core", uint32), > + ("socket", uint32), > + ("node", uint32),You mean (~(uint32_t)0) I think. The outer ( ) should be included too! Ian.
Ian Jackson
2012-Jan-27 18:11 UTC
Re: [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps
Ian Jackson writes ("Re: [Xen-devel] [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps"):> This is plausible. But: > > > +#if 0...> > +#endif > > You haven''t quite finished ?Oh I see, this is tidied up in 7/9. Ian.
Ian Jackson
2012-Jan-27 18:11 UTC
Re: [PATCH 7 of 9] libxl: drop libxl_cpuarray -- topology was the only user
Ian Campbell writes ("[Xen-devel] [PATCH 7 of 9] libxl: drop libxl_cpuarray -- t> libxl: drop libxl_cpuarray -- topology was the only user.> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Ian.
Ian Campbell writes ("[Xen-devel] [PATCH 0 of 9] libxl: API updates + xl: JSON"):> A random(ish) colletion of libxl patches. > > - Fixup idl infrastructure naming clash/annoyance > - Consolidate libxl_button_press and libxl_send_trigger > - Change the way libxl exposes CPU topology information to be a list > of CPU (core,node,socket) tuples instead of three lists. This is a > more sensible representation but is also a bit easier on the > language bindings.Thanks. 1-5, 7-10: acked. I had some comments on 6. Ian.
Ian Campbell
2012-Jan-30 09:34 UTC
Re: [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps
On Fri, 2012-01-27 at 18:11 +0000, Ian Jackson wrote:> Ian Jackson writes ("Re: [Xen-devel] [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps"): > > This is plausible. But: > > > > > +#if 0 > ... > > > +#endif > > > > You haven''t quite finished ? > > Oh I see, this is tidied up in 7/9.Yes, I should have had a comment next to the #if 0. Ian.
Ian Campbell
2012-Jan-31 14:21 UTC
Re: [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps
On Fri, 2012-01-27 at 18:10 +0000, Ian Jackson wrote:> Ian Campbell writes ("[Xen-devel] [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps"): > > libxl: expose cpu topology as a single list of cpu->{node,core,socket} maps. > > > > Rather than the previous tripple list which is more complicated to work with > > and harder for language bindings. >> > + for (cpu = 0; cpu < nr; cpu++) { > ... > > + libxl_cputopology_dispose(&topology[cpu]); > > } > > > > - libxl_topologyinfo_dispose(&topology); > > - > > + free(topology); > > This is quite ugly to have out here in the caller. Perhaps we should > provide a helper for this, called libxl_cputopology_free or > something ? > > > - libxl_topologyinfo_dispose(&topology); > > + for (cpu = 0; cpu < nr_cpus; cpu++) > > + libxl_cputopology_dispose(&topology[cpu]); > > + free(topology); > > And here it is again, proving my point :-).I added libxl_cputopology_list_free(libxl_cputopology *, int nr) which disposes all elements of the list and frees the underlying storage. Is that what you meant? I don''t like "list" rather than "array" but we use the terminology that way elsewhere too (e.g. libxl_device_FOO_list, so I suppose it is my own fault)> > +#define LIBXL_CPUTOPOLOGY_INVALID_ENTRY ~0 > ... > > +libxl_cputopology = Struct("cputopology", [ > > + ("core", uint32), > > + ("socket", uint32), > > + ("node", uint32), > > You mean (~(uint32_t)0) I think. The outer ( ) should be included too!Done. Updated patch below: # HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1328015490 0 # Node ID f8fbad48472b54e8055a861af0be6c9455e3d160 # Parent 1ab41d14959e9e378ca0ca80603524d1f8a05478 libxl: expose cpu topology as a single list of cpu->{node,core,socket} maps. Rather than the previous tripple list which is more complicated to work with and harder for language bindings. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Ian Jackson <Ian.Jackson@eu.citrix.com> diff -r 1ab41d14959e -r f8fbad48472b tools/libxl/gentest.py --- a/tools/libxl/gentest.py Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/libxl/gentest.py Tue Jan 31 13:11:30 2012 +0000 @@ -195,6 +195,7 @@ static void libxl_string_list_rand_init( *p = l; } +#if 0 /* To be remove in a subsequent patch */ static void libxl_cpuarray_rand_init(libxl_cpuarray *p) { int i; @@ -209,6 +210,7 @@ static void libxl_cpuarray_rand_init(lib p->array[i] = r; } } +#endif """) for ty in builtins + types: if ty.typename not in handcoded: diff -r 1ab41d14959e -r f8fbad48472b tools/libxl/libxl.c --- a/tools/libxl/libxl.c Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/libxl/libxl.c Tue Jan 31 13:11:30 2012 +0000 @@ -2755,57 +2755,68 @@ int libxl_get_physinfo(libxl_ctx *ctx, l return 0; } -int libxl_get_topologyinfo(libxl_ctx *ctx, libxl_topologyinfo *info) +libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nr) { xc_topologyinfo_t tinfo; DECLARE_HYPERCALL_BUFFER(xc_cpu_to_core_t, coremap); DECLARE_HYPERCALL_BUFFER(xc_cpu_to_socket_t, socketmap); DECLARE_HYPERCALL_BUFFER(xc_cpu_to_node_t, nodemap); + libxl_cputopology *ret = NULL; int i; - int rc = 0; - - rc += libxl_cpuarray_alloc(ctx, &info->coremap); - rc += libxl_cpuarray_alloc(ctx, &info->socketmap); - rc += libxl_cpuarray_alloc(ctx, &info->nodemap); - if (rc) + int max_cpus; + + max_cpus = libxl_get_max_cpus(ctx); + if (max_cpus == 0) + { + LIBXL__LOG(ctx, XTL_ERROR, "Unable to determine number of CPUS"); + return NULL; + } + + coremap = xc_hypercall_buffer_alloc + (ctx->xch, coremap, sizeof(*coremap) * max_cpus); + socketmap = xc_hypercall_buffer_alloc + (ctx->xch, socketmap, sizeof(*socketmap) * max_cpus); + nodemap = xc_hypercall_buffer_alloc + (ctx->xch, nodemap, sizeof(*nodemap) * max_cpus); + if ((coremap == NULL) || (socketmap == NULL) || (nodemap == NULL)) { + LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM, + "Unable to allocate hypercall arguments"); goto fail; - - coremap = xc_hypercall_buffer_alloc(ctx->xch, coremap, sizeof(*coremap) * info->coremap.entries); - socketmap = xc_hypercall_buffer_alloc(ctx->xch, socketmap, sizeof(*socketmap) * info->socketmap.entries); - nodemap = xc_hypercall_buffer_alloc(ctx->xch, nodemap, sizeof(*nodemap) * info->nodemap.entries); - if ((coremap == NULL) || (socketmap == NULL) || (nodemap == NULL)) - goto fail; + } set_xen_guest_handle(tinfo.cpu_to_core, coremap); set_xen_guest_handle(tinfo.cpu_to_socket, socketmap); set_xen_guest_handle(tinfo.cpu_to_node, nodemap); - tinfo.max_cpu_index = info->coremap.entries - 1; - if (xc_topologyinfo(ctx->xch, &tinfo) != 0) + tinfo.max_cpu_index = max_cpus - 1; + if (xc_topologyinfo(ctx->xch, &tinfo) != 0) { + LIBXL__LOG_ERRNO(ctx, XTL_ERROR, "Topology info hypercall failed"); goto fail; - - for (i = 0; i <= tinfo.max_cpu_index; i++) { - if (i < info->coremap.entries) - info->coremap.array[i] = (coremap[i] == INVALID_TOPOLOGY_ID) ? - LIBXL_CPUARRAY_INVALID_ENTRY : coremap[i]; - if (i < info->socketmap.entries) - info->socketmap.array[i] = (socketmap[i] == INVALID_TOPOLOGY_ID) ? - LIBXL_CPUARRAY_INVALID_ENTRY : socketmap[i]; - if (i < info->nodemap.entries) - info->nodemap.array[i] = (nodemap[i] == INVALID_TOPOLOGY_ID) ? - LIBXL_CPUARRAY_INVALID_ENTRY : nodemap[i]; } - xc_hypercall_buffer_free(ctx->xch, coremap); - xc_hypercall_buffer_free(ctx->xch, socketmap); - xc_hypercall_buffer_free(ctx->xch, nodemap); - return 0; + ret = malloc(sizeof(libxl_cputopology) * max_cpus); + if (ret == NULL) { + LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM, + "Unable to allocate return value"); + goto fail; + } + + for (i = 0; i <= max_cpus; i++) { +#define V(map, i) (map[i] == INVALID_TOPOLOGY_ID) ? \ + LIBXL_CPUTOPOLOGY_INVALID_ENTRY : map[i] + ret[i].core = V(coremap, i); + ret[i].socket = V(socketmap, i); + ret[i].node = V(nodemap, i); +#undef V + } fail: xc_hypercall_buffer_free(ctx->xch, coremap); xc_hypercall_buffer_free(ctx->xch, socketmap); xc_hypercall_buffer_free(ctx->xch, nodemap); - libxl_topologyinfo_dispose(info); - return ERROR_FAIL; + + if (ret) + *nr = max_cpus; + return ret; } const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx) @@ -3604,30 +3615,30 @@ int libxl_cpupool_cpuadd(libxl_ctx *ctx, int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus) { int rc = 0; - int cpu; + int cpu, nr; libxl_cpumap freemap; - libxl_topologyinfo topology; + libxl_cputopology *topology; if (libxl_get_freecpus(ctx, &freemap)) { return ERROR_FAIL; } - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &nr); + if (!topology) { rc = ERROR_FAIL; goto out; } *cpus = 0; - for (cpu = 0; cpu < topology.nodemap.entries; cpu++) { - if (libxl_cpumap_test(&freemap, cpu) && - (topology.nodemap.array[cpu] == node) && + for (cpu = 0; cpu < nr; cpu++) { + if (libxl_cpumap_test(&freemap, cpu) && (topology[cpu].node == node) && !libxl_cpupool_cpuadd(ctx, poolid, cpu)) { (*cpus)++; } + libxl_cputopology_dispose(&topology[cpu]); } - libxl_topologyinfo_dispose(&topology); - + free(topology); out: libxl_cpumap_dispose(&freemap); return rc; @@ -3651,8 +3662,8 @@ int libxl_cpupool_cpuremove_node(libxl_c int ret = 0; int n_pools; int p; - int cpu; - libxl_topologyinfo topology; + int cpu, nr_cpus; + libxl_cputopology *topology; libxl_cpupoolinfo *poolinfo; poolinfo = libxl_list_cpupool(ctx, &n_pools); @@ -3660,7 +3671,8 @@ int libxl_cpupool_cpuremove_node(libxl_c return ERROR_NOMEM; } - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &nr_cpus); + if (!topology) { ret = ERROR_FAIL; goto out; } @@ -3668,8 +3680,8 @@ int libxl_cpupool_cpuremove_node(libxl_c *cpus = 0; for (p = 0; p < n_pools; p++) { if (poolinfo[p].poolid == poolid) { - for (cpu = 0; cpu < topology.nodemap.entries; cpu++) { - if ((topology.nodemap.array[cpu] == node) && + for (cpu = 0; cpu < nr_cpus; cpu++) { + if ((topology[cpu].node == node) && libxl_cpumap_test(&poolinfo[p].cpumap, cpu) && !libxl_cpupool_cpuremove(ctx, poolid, cpu)) { (*cpus)++; @@ -3678,7 +3690,9 @@ int libxl_cpupool_cpuremove_node(libxl_c } } - libxl_topologyinfo_dispose(&topology); + for (cpu = 0; cpu < nr_cpus; cpu++) + libxl_cputopology_dispose(&topology[cpu]); + free(topology); out: for (p = 0; p < n_pools; p++) { diff -r 1ab41d14959e -r f8fbad48472b tools/libxl/libxl.h --- a/tools/libxl/libxl.h Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/libxl/libxl.h Tue Jan 31 13:11:30 2012 +0000 @@ -576,7 +576,9 @@ int libxl_userdata_retrieve(libxl_ctx *c */ int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo); -int libxl_get_topologyinfo(libxl_ctx *ctx, libxl_topologyinfo *info); +#define LIBXL_CPUTOPOLOGY_INVALID_ENTRY (~(uint32_t)0) +libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nr); +void libxl_cputopology_list_free(libxl_cputopology *, int nr); libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, int *nb_vcpu, int *nrcpus); int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, diff -r 1ab41d14959e -r f8fbad48472b tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/libxl/libxl_types.idl Tue Jan 31 13:11:30 2012 +0000 @@ -376,10 +376,10 @@ libxl_physinfo = Struct("physinfo", [ ("phys_cap", uint32), ], dispose_fn=None, dir=DIR_OUT) -libxl_topologyinfo = Struct("topologyinfo", [ - ("coremap", libxl_cpuarray), # cpu to core map - ("socketmap", libxl_cpuarray), # cpu to socket map - ("nodemap", libxl_cpuarray), # cpu to node map +libxl_cputopology = Struct("cputopology", [ + ("core", uint32), + ("socket", uint32), + ("node", uint32), ]) libxl_sched_credit = Struct("sched_credit", [ diff -r 1ab41d14959e -r f8fbad48472b tools/libxl/libxl_utils.c --- a/tools/libxl/libxl_utils.c Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/libxl/libxl_utils.c Tue Jan 31 13:11:30 2012 +0000 @@ -557,6 +557,14 @@ int libxl__enum_from_string(const libxl_ return ERROR_FAIL; } +void libxl_cputopology_list_free(libxl_cputopology *list, int nr) +{ + int i; + for (i = 0; i < nr; i++) + libxl_cputopology_dispose(&list[i]); + free(list); +} + /* * Local variables: * mode: C diff -r 1ab41d14959e -r f8fbad48472b tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/libxl/xl_cmdimpl.c Tue Jan 31 13:11:30 2012 +0000 @@ -3856,10 +3856,11 @@ static void output_physinfo(void) static void output_topologyinfo(void) { - libxl_topologyinfo info; - int i; - - if (libxl_get_topologyinfo(ctx, &info)) { + libxl_cputopology *info; + int i, nr; + + info = libxl_get_cpu_topology(ctx, &nr); + if (info == NULL) { fprintf(stderr, "libxl_get_topologyinfo failed.\n"); return; } @@ -3867,16 +3868,16 @@ static void output_topologyinfo(void) printf("cpu_topology :\n"); printf("cpu: core socket node\n"); - for (i = 0; i < info.coremap.entries; i++) { - if (info.coremap.array[i] != LIBXL_CPUARRAY_INVALID_ENTRY) - printf("%3d: %4d %4d %4d\n", i, info.coremap.array[i], - info.socketmap.array[i], info.nodemap.array[i]); - } + for (i = 0; i < nr; i++) { + if (info[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY) + printf("%3d: %4d %4d %4d\n", i, + info[i].core, info[i].socket, info[i].node); + } + + libxl_cputopology_list_free(info, nr); printf("numa_info : none\n"); - libxl_topologyinfo_dispose(&info); - return; } @@ -5373,7 +5374,7 @@ int main_cpupoolcreate(int argc, char ** libxl_cpumap freemap; libxl_cpumap cpumap; libxl_uuid uuid; - libxl_topologyinfo topology; + libxl_cputopology *topology; while (1) { opt = getopt_long(argc, argv, "hnf:", long_options, &option_index); @@ -5482,16 +5483,18 @@ int main_cpupoolcreate(int argc, char ** return -ERROR_FAIL; } if (!xlu_cfg_get_list(config, "nodes", &nodes, 0, 0)) { + int nr; n_cpus = 0; n_nodes = 0; - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &nr); + if (topology == NULL) { fprintf(stderr, "libxl_get_topologyinfo failed\n"); return -ERROR_FAIL; } while ((buf = xlu_cfg_get_listitem(nodes, n_nodes)) != NULL) { n = atoi(buf); - for (i = 0; i < topology.nodemap.entries; i++) { - if ((topology.nodemap.array[i] == n) && + for (i = 0; i < nr; i++) { + if ((topology[i].node == n) && libxl_cpumap_test(&freemap, i)) { libxl_cpumap_set(&cpumap, i); n_cpus++; @@ -5500,7 +5503,7 @@ int main_cpupoolcreate(int argc, char ** n_nodes++; } - libxl_topologyinfo_dispose(&topology); + libxl_cputopology_list_free(topology, nr); if (n_cpus == 0) { fprintf(stderr, "no free cpu found\n"); @@ -5822,11 +5825,12 @@ int main_cpupoolnumasplit(int argc, char int schedid; int n_pools; int node; + int n_cpus; char name[16]; libxl_uuid uuid; libxl_cpumap cpumap; libxl_cpupoolinfo *poolinfo; - libxl_topologyinfo topology; + libxl_cputopology *topology; libxl_dominfo info; if ((opt = def_getopt(argc, argv, "", "cpupool-numa-split", 0)) != -1) @@ -5848,21 +5852,22 @@ int main_cpupoolnumasplit(int argc, char return -ERROR_FAIL; } - if (libxl_get_topologyinfo(ctx, &topology)) { + topology = libxl_get_cpu_topology(ctx, &n_cpus); + if (topology == NULL) { fprintf(stderr, "libxl_get_topologyinfo failed\n"); return -ERROR_FAIL; } if (libxl_cpumap_alloc(ctx, &cpumap)) { fprintf(stderr, "Failed to allocate cpumap\n"); - libxl_topologyinfo_dispose(&topology); + libxl_cputopology_list_free(topology, n_cpus); return -ERROR_FAIL; } /* Reset Pool-0 to 1st node: first add cpus, then remove cpus to avoid a cpupool without cpus in between */ - node = topology.nodemap.array[0]; + node = topology[0].node; if (libxl_cpupool_cpuadd_node(ctx, 0, node, &n)) { fprintf(stderr, "error on adding cpu to Pool 0\n"); return -ERROR_FAIL; @@ -5876,9 +5881,9 @@ int main_cpupoolnumasplit(int argc, char } n = 0; - for (c = 0; c < topology.nodemap.entries; c++) { - if (topology.nodemap.array[c] == node) { - topology.nodemap.array[c] = LIBXL_CPUARRAY_INVALID_ENTRY; + for (c = 0; c < n_cpus; c++) { + if (topology[c].node == node) { + topology[c].node = LIBXL_CPUTOPOLOGY_INVALID_ENTRY; libxl_cpumap_set(&cpumap, n); n++; } @@ -5903,12 +5908,12 @@ int main_cpupoolnumasplit(int argc, char } memset(cpumap.map, 0, cpumap.size); - for (c = 0; c < topology.nodemap.entries; c++) { - if (topology.nodemap.array[c] == LIBXL_CPUARRAY_INVALID_ENTRY) { + for (c = 0; c < n_cpus; c++) { + if (topology[c].node == LIBXL_CPUTOPOLOGY_INVALID_ENTRY) { continue; } - node = topology.nodemap.array[c]; + node = topology[c].node; ret = -libxl_cpupool_cpuremove_node(ctx, 0, node, &n); if (ret) { fprintf(stderr, "error on removing cpu from Pool 0\n"); @@ -5930,15 +5935,15 @@ int main_cpupoolnumasplit(int argc, char goto out; } - for (p = c; p < topology.nodemap.entries; p++) { - if (topology.nodemap.array[p] == node) { - topology.nodemap.array[p] = LIBXL_CPUARRAY_INVALID_ENTRY; + for (p = c; p < n_cpus; p++) { + if (topology[p].node == node) { + topology[p].node = LIBXL_CPUTOPOLOGY_INVALID_ENTRY; } } } out: - libxl_topologyinfo_dispose(&topology); + libxl_cputopology_list_free(topology, n_cpus); libxl_cpumap_dispose(&cpumap); return ret; diff -r 1ab41d14959e -r f8fbad48472b tools/ocaml/libs/xl/genwrap.py --- a/tools/ocaml/libs/xl/genwrap.py Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/ocaml/libs/xl/genwrap.py Tue Jan 31 13:11:30 2012 +0000 @@ -29,6 +29,8 @@ functions = { # ( name , [type1,type2,.. "device_pci": DEVICE_FUNCTIONS, "physinfo": [ ("get", ["unit", "t"]), ], + "cputopology": [ ("get", ["unit", "t array"]), + ], "sched_credit": [ ("domain_get", ["domid", "t"]), ("domain_set", ["domid", "t", "unit"]), ], @@ -266,7 +268,6 @@ if __name__ == ''__main__'': "domain_create_info", "domain_build_info", "vcpuinfo", - "topologyinfo", "event", ] diff -r 1ab41d14959e -r f8fbad48472b tools/ocaml/libs/xl/xenlight.ml.in --- a/tools/ocaml/libs/xl/xenlight.ml.in Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/ocaml/libs/xl/xenlight.ml.in Tue Jan 31 13:11:30 2012 +0000 @@ -19,17 +19,6 @@ type domid = int (* @@LIBXL_TYPES@@ *) -module Topologyinfo = struct - type t - { - core : int; - socket : int; - node : int; - } - external get : unit -> t array = "stub_xl_topologyinfo" -end - - external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff -r 1ab41d14959e -r f8fbad48472b tools/ocaml/libs/xl/xenlight.mli.in --- a/tools/ocaml/libs/xl/xenlight.mli.in Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/ocaml/libs/xl/xenlight.mli.in Tue Jan 31 13:11:30 2012 +0000 @@ -19,16 +19,6 @@ type domid = int (* @@LIBXL_TYPES@@ *) -module Topologyinfo : sig - type t - { - core : int; - socket : int; - node : int; - } - external get : unit -> t array = "stub_xl_topologyinfo" -end - external send_trigger : domid -> trigger -> int -> unit = "stub_xl_send_trigger" external send_sysrq : domid -> char -> unit = "stub_xl_send_sysrq" external send_debug_keys : domid -> string -> unit = "stub_xl_send_debug_keys" diff -r 1ab41d14959e -r f8fbad48472b tools/ocaml/libs/xl/xenlight_stubs.c --- a/tools/ocaml/libs/xl/xenlight_stubs.c Tue Jan 31 13:11:29 2012 +0000 +++ b/tools/ocaml/libs/xl/xenlight_stubs.c Tue Jan 31 13:11:30 2012 +0000 @@ -210,28 +210,6 @@ static value Val_hwcap(libxl_hwcap *c_va #include "_libxl_types.inc" -static value Val_topologyinfo(libxl_topologyinfo *c_val) -{ - CAMLparam0(); - CAMLlocal3(v, topology, topologyinfo); - int i; - - topologyinfo = caml_alloc_tuple(c_val->coremap.entries); - for (i = 0; i < c_val->coremap.entries; i++) { - v = Val_none; - if (c_val->coremap.array[i] != LIBXL_CPUARRAY_INVALID_ENTRY) { - topology = caml_alloc_tuple(3); - Store_field(topology, 0, Val_int(c_val->coremap.array[i])); - Store_field(topology, 1, Val_int(c_val->socketmap.array[i])); - Store_field(topology, 2, Val_int(c_val->nodemap.array[i])); - v = Val_some(topology); - } - Store_field(topologyinfo, i, v); - } - - CAMLreturn(topologyinfo); -} - value stub_xl_device_disk_add(value info, value domid) { CAMLparam2(info, domid); @@ -462,22 +440,33 @@ value stub_xl_physinfo_get(value unit) CAMLreturn(physinfo); } -value stub_xl_topologyinfo(value unit) +value stub_xl_cputopology_get(value unit) { CAMLparam1(unit); - CAMLlocal1(topologyinfo); - libxl_topologyinfo c_topologyinfo; - int ret; + CAMLlocal2(topology, v); + libxl_cputopology *c_topology; + int i, nr, ret; INIT_STRUCT(); INIT_CTX(); - ret = libxl_get_topologyinfo(ctx, &c_topologyinfo); + + c_topology = libxl_get_cpu_topology(ctx, &nr); if (ret != 0) failwith_xl("topologyinfo", &lg); + + topology = caml_alloc_tuple(nr); + for (i = 0; i < nr; i++) { + if (c_topology[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY) + v = Val_some(Val_cputopology(&gc, &lg, &c_topology[i])); + else + v = Val_none; + Store_field(topology, i, v); + } + + libxl_cputopology_list_free(c_topology, nr); + FREE_CTX(); - - topologyinfo = Val_topologyinfo(&c_topologyinfo); - CAMLreturn(topologyinfo); + CAMLreturn(topology); } value stub_xl_sched_credit_domain_get(value domid)
Ian Jackson
2012-Jan-31 14:24 UTC
Re: [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps
Ian Campbell writes ("Re: [Xen-devel] [PATCH 6 of 9] libxl: expose cpu topology as a single list of cpu->{node, core, socket} maps"):> I added libxl_cputopology_list_free(libxl_cputopology *, int nr) > which disposes all elements of the list and frees the underlying > storage. Is that what you meant?Yes.> I don''t like "list" rather than "array" but we use the terminology that > way elsewhere too (e.g. libxl_device_FOO_list, so I suppose it is my own > fault)Well if you like add another patch to rename them all :-). But I think "list" is OK.> Done. > > Updated patch below:Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Ian.
On Wed, Jan 25, Ian Campbell wrote:> # HG changeset patch > # User Ian Campbell <ian.campbell@citrix.com> > # Date 1327512175 0 > # Node ID 9e3be181b2b70f521defcd55ecbd9967cd206fb2 > # Parent f43e2015d86f4d4c7dfa4db69f9d580fb3d705d9 > xl: use json output by default > > Move the sxp producing code off into a separate file. It is supported > for legacy reasons and needn''t be updated other than the improve > compatibility with xm. > > libxl_domain_config is not currently generated by the IDL (adding the > necessary support for Array types is on my to do list) so hand code > the json generation function for now. > > Since this rather directly exposes a libxl data structure it''s not > clear what sort of forward compatibility guarantees we can > make. However it seems like it should be as stable as libxl''s own API > (which we are looking to stabilise)This leads to build failures with libyajl2: xl_cmdimpl.c: In function ''printf_info'': xl_cmdimpl.c:300:5: error: statement with no effect [-Werror=unused-value] xl_cmdimpl.c:300:21: error: expected '';'' before ''conf'' xl_cmdimpl.c:306:28: error: ''conf'' undeclared (first use in this function) xl_cmdimpl.c:306:28: note: each undeclared identifier is reported only once for each function it appears in xl_cmdimpl.c:306:5: error: too many arguments to function ''yajl_gen_alloc'' /usr/include/yajl/yajl_gen.h:118:23: note: declared here xl_cmdimpl.c:339:5: error: passing argument 3 of ''yajl_gen_get_buf'' from incompatible pointer type [-Werror] /usr/include/yajl/yajl_gen.h:144:30: note: expected ''size_t *'' but argument is of type ''unsigned int *''
On Thu, 2012-02-09 at 07:30 +0000, Olaf Hering wrote:> On Wed, Jan 25, Ian Campbell wrote: > > > # HG changeset patch > > # User Ian Campbell <ian.campbell@citrix.com> > > # Date 1327512175 0 > > # Node ID 9e3be181b2b70f521defcd55ecbd9967cd206fb2 > > # Parent f43e2015d86f4d4c7dfa4db69f9d580fb3d705d9 > > xl: use json output by default > > > > Move the sxp producing code off into a separate file. It is supported > > for legacy reasons and needn''t be updated other than the improve > > compatibility with xm. > > > > libxl_domain_config is not currently generated by the IDL (adding the > > necessary support for Array types is on my to do list) so hand code > > the json generation function for now. > > > > Since this rather directly exposes a libxl data structure it''s not > > clear what sort of forward compatibility guarantees we can > > make. However it seems like it should be as stable as libxl''s own API > > (which we are looking to stabilise) > > This leads to build failures with libyajl2: > > xl_cmdimpl.c: In function ''printf_info'': > xl_cmdimpl.c:300:5: error: statement with no effect [-Werror=unused-value] > xl_cmdimpl.c:300:21: error: expected '';'' before ''conf'' > xl_cmdimpl.c:306:28: error: ''conf'' undeclared (first use in this function) > xl_cmdimpl.c:306:28: note: each undeclared identifier is reported only once for each function it appears in > xl_cmdimpl.c:306:5: error: too many arguments to function ''yajl_gen_alloc'' > /usr/include/yajl/yajl_gen.h:118:23: note: declared here > xl_cmdimpl.c:339:5: error: passing argument 3 of ''yajl_gen_get_buf'' from incompatible pointer type [-Werror] > /usr/include/yajl/yajl_gen.h:144:30: note: expected ''size_t *'' but argument is of type ''unsigned int *''I suppose we ought to use the helpers defined in libxl_json.h to abstract this away. Could you cook up a patch? Ian.