Re: [Xen-devel] booting domU guest as pvh works in xen-4.11.1 but fails in 4.12
On Tue, 16 Apr 2019, M A Young wrote: > On Tue, 16 Apr 2019, Andrew Cooper wrote: > >> From the log: >> >> traps: modprobe[48] trap invalid opcode ip:7f797dc7bb95 sp:7ffe3099cdb8 erro >> r:0 in ld-2.29.so[7f797dc61000+21000] >> >> >> Can you disassemble ld-2.29.so and find out what that instruction is? It is >> almost certainly a related factor. > > I get lines like > [1.384356] traps: modprobe[36] trap invalid opcode ip:7f57448af179 > sp:7fff8fc3a938 error:0 in ld-2.29.so[7f5744895000+2] > > I am guessing the right place to look in ld-2.29.so is > 0x7f57448af179-0x7f5744895-2 = 86873 in which case I get > (gdb) x/10i 86873 > 0x15359 <_dl_close_worker+3593>:mov(%rsi,%rcx,8),%r8 > 0x1535d <_dl_close_worker+3597>:testb $0x20,0x31d(%r8) > 0x15365 <_dl_close_worker+3605>:jne0x15375 > <_dl_close_worker+3621> > 0x15367 <_dl_close_worker+3607>:cmp%ecx,%edx > 0x15369 <_dl_close_worker+3609>:je 0x15372 > <_dl_close_worker+3618> > 0x1536b <_dl_close_worker+3611>:mov%edx,%r9d > 0x1536e <_dl_close_worker+3614>:mov%r8,(%rsi,%r9,8) > 0x15372 <_dl_close_worker+3618>:add$0x1,%edx > 0x15375 <_dl_close_worker+3621>:add$0x1,%rcx > 0x15379 <_dl_close_worker+3625>:cmp%ecx,%eax > > Some more lines like this are > [1.571479] traps: modprobe[41] trap invalid opcode ip:7f3e3628d179 > sp:7ffc86abbe08 error:0 in ld-2.29.so[7f3e36273000+2] > [1.630562] traps: modprobe[43] trap invalid opcode ip:7f227b39a179 > sp:7ffdfd943198 error:0 in ld-2.29.so[7f227b38+2] > which all seem to get to the same place. Is this useful or am I looking in > the wrong place? I did a bisect on this issue, and it identified the first bad commit as fd32dcfe4c9a539f8e5d26ff4c5ca50ee54556b2 x86/vmx: Don't leak EFER.NXE into guest context Michael Young ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] booting domU guest as pvh works in xen-4.11.1 but fails in 4.12
On Fri, 31 May 2019, Andrew Cooper wrote: >> I did a bisect on this issue, and it identified the first bad commit as >> fd32dcfe4c9a539f8e5d26ff4c5ca50ee54556b2 >> x86/vmx: Don't leak EFER.NXE into guest context > > Aah - this will be a harpertown core. > > You need e28c0ee3356f52f589bbae54e89aaed25c1f599d from staging, which > has been backported to staging-4.12 > (8457c15b981ba04c0709e6f25af3b76beb34cafa) two weeks ago. > > This but accidentally resulted in the SYSCALL instruction being disabled > behind the back of the guest, which broke all userspace system calls. Thanks, that patch fixes the DomU boot problem I was seeing. Michael Young ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] issues with Python 3.8
Fedora rawhide is about to to update to Python 3.8 (in beta I think) and there are two issues with compiling xen with it (see https://bugzilla.redhat.com/show_bug.cgi?id=1704807 ). It seems that in 3.8 python3-config --libs no longer includes -lpython3.8 by default which causes tools/configure to fail. You can get -lpython3.8 back by adding --embed , but this option isn't recognized in earlier versions of python. It also seems python 3.8 adds the options -Wno-unused-result -Wsign-compare to the compilations in tools/python (though I am not sure how this happens) and -Wsign-compare gives some build warnings which the Fedora build treats as errors. I have attached the patch I used to get xen-4.12.0 to build with python 3.8 and also the build warnings it fixes in case they are useful. Michael Young--- xen-4.12.0/m4/python_devel.m4.orig 2019-05-31 23:30:42.489738121 +0100 +++ xen-4.12.0/m4/python_devel.m4 2019-06-01 17:02:38.886934441 +0100 @@ -24,7 +24,8 @@ dnl If python-config is found use it CPPFLAGS="$CFLAGS `$PYTHON-config --cflags`" LDFLAGS="$LDFLAGS `$PYTHON-config --ldflags`" -LIBS="$LIBS `$PYTHON-config --libs`" +LIBSTMP="`$PYTHON-config --libs --embed`" || LIBSTMP="`$PYTHON-config --libs`" +LIBS="$LIBS $LIBSTMP" ]) AC_CHECK_HEADER([Python.h], [], --- xen-4.12.0/tools/configure.orig 2019-05-31 23:30:42.498738452 +0100 +++ xen-4.12.0/tools/configure 2019-06-01 17:08:26.100727658 +0100 @@ -7482,7 +7482,8 @@ CPPFLAGS="$CFLAGS `$PYTHON-config --cflags`" LDFLAGS="$LDFLAGS `$PYTHON-config --ldflags`" -LIBS="$LIBS `$PYTHON-config --libs`" +LIBSTMP="`$PYTHON-config --libs --embed`" || LIBSTMP="`$PYTHON-config --libs`" +LIBS="$LIBS $LIBSTMP" fi --- xen-4.12.0/tools/python/xen/lowlevel/xc/xc.c.orig 2019-04-01 12:03:23.0 +0100 +++ xen-4.12.0/tools/python/xen/lowlevel/xc/xc.c2019-06-01 17:58:39.567729630 +0100 @@ -118,7 +118,8 @@ PyObject *kwds) { uint32_t dom = 0, target = 0; -int ret, i; +int ret; +unsigned int i; PyObject *pyhandle = NULL; struct xen_domctl_createdomain config = { .handle = { @@ -296,7 +297,7 @@ static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args) { -int i; +unsigned int i; uint32_t dom; PyObject *pyhandle; xen_domain_handle_t handle; @@ -337,7 +338,8 @@ PyObject *list, *info_dict, *pyhandle; uint32_t first_dom = 0; -int max_doms = 1024, nr_doms, i, j; +int max_doms = 1024, nr_doms, i; +unsigned int j; xc_dominfo_t *info; static char *kwd_list[] = { "first_dom", "max_doms", NULL }; @@ -632,7 +634,8 @@ { uint32_t sbdf; uint32_t max_sdevs, num_sdevs; -int domid, seg, bus, dev, func, rc, i; +int domid, seg, bus, dev, func, rc; +unsigned int i; PyObject *Pystr; char *group_str; char dev_str[9]; @@ -972,7 +975,7 @@ { xc_physinfo_t pinfo; char cpu_cap[128], virt_caps[128], *p; -int i; +unsigned int i; const char *virtcap_names[] = { "hvm", "hvm_directio" }; if ( xc_physinfo(self->xc_handle, &pinfo) != 0 ) --- xen-4.12.0/tools/python/xen/lowlevel/xs/xs.c.orig 2019-04-01 12:03:23.0 +0100 +++ xen-4.12.0/tools/python/xen/lowlevel/xs/xs.c2019-06-01 18:59:46.316760561 +0100 @@ -186,7 +186,7 @@ Py_END_ALLOW_THREADS if (xsval) { -int i; +unsigned int i; PyObject *val = PyList_New(xsval_n); for (i = 0; i < xsval_n; i++) #if PY_MAJOR_VERSION >= 3 @@ -276,7 +276,7 @@ struct xs_handle *xh = xshandle(self); struct xs_permissions *perms; unsigned int perms_n = 0; -int i; +unsigned int i; xs_transaction_t th; char *thstr; BUILDSTDERR: xen/lowlevel/xc/xc.c: In function âpyxc_domain_createâ: BUILDSTDERR: xen/lowlevel/xc/xc.c:148:24: warning: comparison of integer expressions of different signedness: âintâ and âlong unsigned intâ [-Wsign-compare] BUILDSTDERR: for ( i = 0; i < sizeof(xen_domain_handle_t); i++ ) BUILDSTDERR: ^ BUILDSTDERR: xen/lowlevel/xc/xc.c: In function âpyxc_domain_sethandleâ: BUILDSTDERR: xen/lowlevel/xc/xc.c:313:20: warning: comparison of integer expressions of different signedness: âintâ and âlong unsigned intâ [-Wsign-compare] BUILDSTDERR: for ( i = 0; i < sizeof(xen_domain_handle_t); i++ ) BUILDSTDERR: ^ BUILDSTDERR: xen/lowlevel/xc/xc.c: In function âpyxc_domain_getinfoâ: BUILDSTDERR: xen/lowlevel/xc/xc.c:392:24: warning: comparison of integer expressions of different signedness: âintâ and âlong unsigned intâ [-Wsign-compare] BUILDSTDERR: for ( j = 0; j < sizeof(xen_domain_handle_t); j++ ) BUILDSTDERR: ^ BUILDSTDERR: xen/lowlevel/xc/xc.c: In function âpyxc_get_device_groupâ: BUILDSTDERR: xen/lowlevel/xc/xc.c:678
[Xen-devel] [PATCH] failing to set value to 0 in Grub2ConfigFile
I have been looking at the pygrub code to see if it is possible to cope with grub files with BLSCFG and spotted this minor issue in GrubConf.py where the code intends to replace ${saved_entry} and ${next_entry} with 0 but doesn't succeed. Signed-off-by: Michael Young From a08eff9b1b881dc61f9427153706e2d5b3bd0e01 Mon Sep 17 00:00:00 2001 From: Michael Young Date: Tue, 13 Aug 2019 21:15:02 +0100 Subject: [PATCH] failing to set value to 0 in Grub2ConfigFile In Grub2ConfigFile the code to handle ${saved_entry} and ${next_entry} sets arg = "0" but this now does nothing following "tools/pygrub: Make pygrub understand default entry in string format" d1b93ea2615bd789ee28901f1f1c05ffb319cb61 which replaced arg.strip() with arg_strip in the following line. This patch restores the previous behaviour. --- tools/pygrub/src/GrubConf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py index 594139bac7..73f1bbed2f 100644 --- a/tools/pygrub/src/GrubConf.py +++ b/tools/pygrub/src/GrubConf.py @@ -440,7 +440,7 @@ class Grub2ConfigFile(_GrubConfigFile): arg_strip = arg.strip() if arg_strip == "${saved_entry}" or arg_strip == "${next_entry}": logging.warning("grub2's saved_entry/next_entry not supported") -arg = "0" +arg_strip = "0" setattr(self, self.commands[com], arg_strip) else: logging.info("Ignored directive %s" %(com,)) -- 2.21.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] failing to set value to 0 in Grub2ConfigFile
On Tue, 13 Aug 2019, Andrew Cooper wrote: > On 13/08/2019 22:02, YOUNG, MICHAEL A. wrote: >> I have been looking at the pygrub code to see if it is possible to cope >> with grub files with BLSCFG and spotted this minor issue in GrubConf.py >> where the code intends to replace ${saved_entry} and ${next_entry} with 0 >> but doesn't succeed. >> >> Signed-off-by: Michael Young > > Ah - this looks suspiciously like it might be the bugfix for an issue > reported by Steven. > > Steven - do you mind giving this patch a try for your "Fedora 30 DomU - > pygrub always boots the second menu option" problem? Sadly I don't think it is that simple and to it properly would require parsing if clauses in the grub file and also reading variables from the grubenv file. I do however have an idea which might work which is to ignore anything in if clauses, read the grubenv file (which I now have a hacky way of doing) and treating the value of next_entry or saved_entry as the setting for the default kernel to pick. If I finish a patch that does this I will post it on the list, but I very much doubt it will be of commitable quality. Michael Young ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH] read grubenv and set default from saved_entry or next_entry
This patch may help your issue with the default kernel setting on Fedora 30 as it uses the setting of saved_entry or next_entry from the grubenv file to choose the default kernel which should override any setting picked up from if clauses in the grub.cfg file. I have only done limited and somewhat imperfect testing on it and isn't a proper fix (which would use grubenv settings based on what is in the if clauses) but I think it should work in your case. Michael Young ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] read grubenv and set default from saved_entry or next_entry
On Thu, 15 Aug 2019, Michael Young wrote: > This patch may help your issue with the default kernel setting on Fedora 30 > as it uses the setting of saved_entry or next_entry from the grubenv file to > choose the default kernel which should override any setting picked up from if > clauses in the grub.cfg file. > > I have only done limited and somewhat imperfect testing on it and isn't a > proper fix (which would use grubenv settings based on what is in the if > clauses) but I think it should work in your case. The patch is actually attached this time. Michael YoungFrom 00dfa97d97f0c7c18d95ab47706660c7ab15b733 Mon Sep 17 00:00:00 2001 From: Michael Young Date: Thu, 15 Aug 2019 00:16:44 +0100 Subject: [PATCH] read grubenv and set default from saved_entry or next_entry This patch looks for a grubenv file in the same directory as the grub.cfg file and includes it at front of the grub.cfg file when passed to parse() As the grubenv file consists of variable=value lines padded by hashes these are treated as commands in parse() where it uses the value of saved_entry or next_entry (if set) to set the default entry if a title matches. --- tools/pygrub/src/GrubConf.py | 9 + tools/pygrub/src/pygrub | 13 - 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py index 594139bac7..c9a81fe936 100644 --- a/tools/pygrub/src/GrubConf.py +++ b/tools/pygrub/src/GrubConf.py @@ -383,6 +383,8 @@ class Grub2ConfigFile(_GrubConfigFile): img = None title = "" menu_level=0 +img_count=0 +default_title="" for l in lines: l = l.strip() # skip blank lines @@ -408,6 +410,9 @@ class Grub2ConfigFile(_GrubConfigFile): raise RuntimeError("syntax error: cannot nest menuentry (%d %s)" % (len(img),img)) img = [] title = title_match.group(1) +if title == default_title: +setattr(self, 'default', img_count) +img_count += 1 continue if l.startswith("submenu"): @@ -432,6 +437,10 @@ class Grub2ConfigFile(_GrubConfigFile): (com, arg) = grub_exact_split(l, 2) +if com == "saved_entry" or com == "next_entry": +default_title = arg +continue + if com == "set": (com,arg) = grub2_handle_set(arg) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index ce7ab0eb8c..267788795b 100755 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -454,8 +454,19 @@ class Grub: if self.__dict__.get('cf', None) is None: raise RuntimeError("couldn't find bootloader config file in the image provided.") f = fs.open_file(self.cf.filename) +fenv = self.cf.filename.replace("grub.cfg","grubenv") +if fenv != self.cf.filename and fs.file_exists(fenv): +# if grubenv file exists next to grub.cfg prepend it +fenvf = fs.open_file(fenv) +if sys.version_info[0] < 3: +fsep = "\n" +else: +fsep = b"\n" +buf = fsep.join((fenvf.read(FS_READ_MAX),f.read(FS_READ_MAX))) +del fenvf # limit read size to avoid pathological cases -buf = f.read(FS_READ_MAX) +else: +buf = f.read(FS_READ_MAX) del f if sys.version_info[0] < 3: self.cf.parse(buf) -- 2.21.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] read grubenv and set default from saved_entry or next_entry
On Thu, 15 Aug 2019, Steven Haigh wrote: > Having a bit of a look here > > My test system grubenv file has: > # GRUB Environment Block > saved_entry=0 > kernelopts=root=UUID=5346b4d9-885f-4673-8aff-04a16bf1971a ro > rootflags=subvol=root selinux=0 rhgb quiet > boot_success=1 > # I have attached a revision of the first patch which should handle a numeric saved_entry. Michael YoungFrom 51a9dce9de3ea159011928e2db8541f3c7e8383a Mon Sep 17 00:00:00 2001 From: Michael Young Date: Thu, 15 Aug 2019 19:55:30 +0100 Subject: [PATCH] read grubenv and set default from saved_entry or next_entry This patch looks for a grubenv file in the same directory as the grub.cfg file and includes it at front of the grub.cfg file when passed to parse() As the grubenv file consists of variable=value lines padded by hashes these are treated as commands in parse() where it uses the value of saved_entry or next_entry (if set) to set the default entry if a title matches or is a number. --- tools/pygrub/src/GrubConf.py | 11 +++ tools/pygrub/src/pygrub | 13 - 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py index 594139bac7..22e0948da2 100644 --- a/tools/pygrub/src/GrubConf.py +++ b/tools/pygrub/src/GrubConf.py @@ -383,6 +383,8 @@ class Grub2ConfigFile(_GrubConfigFile): img = None title = "" menu_level=0 +img_count=0 +default_title="" for l in lines: l = l.strip() # skip blank lines @@ -408,6 +410,9 @@ class Grub2ConfigFile(_GrubConfigFile): raise RuntimeError("syntax error: cannot nest menuentry (%d %s)" % (len(img),img)) img = [] title = title_match.group(1) +if title == default_title: +setattr(self, 'default', img_count) +img_count += 1 continue if l.startswith("submenu"): @@ -432,6 +437,10 @@ class Grub2ConfigFile(_GrubConfigFile): (com, arg) = grub_exact_split(l, 2) +if com == "saved_entry" or com == "next_entry": +default_title = arg +continue + if com == "set": (com,arg) = grub2_handle_set(arg) @@ -449,6 +458,8 @@ class Grub2ConfigFile(_GrubConfigFile): else: logging.warning("Unknown directive %s" %(com,)) +if default_title.isdigit(): +setattr(self, 'default', default_title) if img is not None: raise RuntimeError("syntax error: end of file with open menuentry(%d %s)" % (len(img),img)) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index ce7ab0eb8c..267788795b 100755 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -454,8 +454,19 @@ class Grub: if self.__dict__.get('cf', None) is None: raise RuntimeError("couldn't find bootloader config file in the image provided.") f = fs.open_file(self.cf.filename) +fenv = self.cf.filename.replace("grub.cfg","grubenv") +if fenv != self.cf.filename and fs.file_exists(fenv): +# if grubenv file exists next to grub.cfg prepend it +fenvf = fs.open_file(fenv) +if sys.version_info[0] < 3: +fsep = "\n" +else: +fsep = b"\n" +buf = fsep.join((fenvf.read(FS_READ_MAX),f.read(FS_READ_MAX))) +del fenvf # limit read size to avoid pathological cases -buf = f.read(FS_READ_MAX) +else: +buf = f.read(FS_READ_MAX) del f if sys.version_info[0] < 3: self.cf.parse(buf) -- 2.21.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] python3 issues
I have been testing the python3 changes committed to xen and found a few issues. There are a couple of ocaml python build scripts that don't work for me with python3, and I needed a few fixes to get pygrub to work, mostly due to the change from strings to bytes. I am attaching the patch I put together in testing to get these things to work to illustrate where the problems are and in case it is useful to others, though I believe at least some of it isn't compatible with python2. Michael Young--- xen-4.12.0-rc5/tools/ocaml/libs/xentoollog/genlevels.py.orig 2019-03-06 14:42:49.0 + +++ xen-4.12.0-rc5/tools/ocaml/libs/xentoollog/genlevels.py 2019-03-13 21:33:59.805930989 + @@ -1,6 +1,7 @@ #!/usr/bin/python import sys +from functools import reduce def read_levels(): f = open('../../../libs/toollog/include/xentoollog.h', 'r') @@ -86,14 +87,14 @@ def autogen_header(open_comment, close_comment): s = open_comment + " AUTO-GENERATED FILE DO NOT EDIT " + close_comment + "\n" s += open_comment + " autogenerated by \n" -s += reduce(lambda x,y: x + " ", range(len(open_comment + " ")), "") +s += reduce(lambda x,y: x + " ", list(range(len(open_comment + " "))), "") s += "%s" % " ".join(sys.argv) s += "\n " + close_comment + "\n\n" return s if __name__ == '__main__': if len(sys.argv) < 3: - print >>sys.stderr, "Usage: genlevels.py " + print("Usage: genlevels.py ", file=sys.stderr) sys.exit(1) levels, olevels = read_levels() --- xen-4.12.0-rc5/tools/ocaml/libs/xl/genwrap.py.orig 2019-03-06 14:42:49.0 + +++ xen-4.12.0-rc5/tools/ocaml/libs/xl/genwrap.py 2019-03-13 21:34:00.674962832 + @@ -3,6 +3,7 @@ import sys,os import idl +from functools import reduce # typename -> ( ocaml_type, c_from_ocaml, ocaml_from_c ) builtins = { @@ -78,7 +79,7 @@ elif isinstance(ty,idl.Array): return "%s array" % ocaml_type_of(ty.elem_type) elif isinstance(ty,idl.Builtin): -if not builtins.has_key(ty.typename): +if ty.typename not in builtins: raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty))) typename,_,_ = builtins[ty.typename] if not typename: @@ -251,7 +252,7 @@ else: s += "\texternal default : ctx -> %sunit -> t = \"stub_libxl_%s_init\"\n" % (union_args, ty.rawname) -if functions.has_key(ty.rawname): +if ty.rawname in functions: for name,args in functions[ty.rawname]: s += "\texternal %s : " % name s += " -> ".join(args) @@ -278,7 +279,7 @@ else: s += "%s = Int_val(%s);" % (c, o) elif isinstance(ty,idl.Builtin): -if not builtins.has_key(ty.typename): +if ty.typename not in builtins: raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty))) _,fn,_ = builtins[ty.typename] if not fn: @@ -375,7 +376,7 @@ else: s += "%s = Val_int(%s);" % (o, c) elif isinstance(ty,idl.Builtin): -if not builtins.has_key(ty.typename): +if ty.typename not in builtins: raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty))) _,_,fn = builtins[ty.typename] if not fn: @@ -513,14 +514,14 @@ def autogen_header(open_comment, close_comment): s = open_comment + " AUTO-GENERATED FILE DO NOT EDIT " + close_comment + "\n" s += open_comment + " autogenerated by \n" -s += reduce(lambda x,y: x + " ", range(len(open_comment + " ")), "") +s += reduce(lambda x,y: x + " ", list(range(len(open_comment + " "))), "") s += "%s" % " ".join(sys.argv) s += "\n " + close_comment + "\n\n" return s if __name__ == '__main__': if len(sys.argv) < 4: -print >>sys.stderr, "Usage: genwrap.py" +print("Usage: genwrap.py", file=sys.stderr) sys.exit(1) (_,types) = idl.parse(sys.argv[1]) @@ -533,7 +534,7 @@ for t in blacklist: if t not in [ty.rawname for ty in types]: -print "unknown type %s in blacklist" % t +print("unknown type %s in blacklist" % t) types = [ty for ty in types if not ty.rawname in blacklist] @@ -564,7 +565,7 @@ cinc.write("\n") cinc.write(gen_Val_ocaml(ty)) cinc.write("\n") -if functions.has_key(ty.rawname): +if ty.rawname in functions: cinc.write(gen_c_stub_prototype(ty, functions[ty.rawname])) cinc.write("\n") if ty.init_fn is not None: --- xen-4.12.0-rc6/tools/pygrub/src/GrubConf.py.orig2019-03-24 22:44:05.502581989 + +++ xen-4.12.0-rc6/tools/pygrub/src/GrubConf.py 2019-03-24 22:49:14.025934786 + @@ -230,10 +230,10 @@ def _get_default(self): return self._default def _set_defa
Re: [Xen-devel] [PATCH 0/4] More python fixes
On Mon, 1 Apr 2019, Wei Liu wrote: > Wei Liu (4): > pygrub: fix message in grub parser > pygrub/grub: always use integer for default entry > pygrub: decode string in Python 3 > tools/ocaml: make python scripts 2 and 3 compatible > > tools/ocaml/libs/xentoollog/genlevels.py | 5 - > tools/ocaml/libs/xl/genwrap.py | 17 ++--- > tools/pygrub/src/GrubConf.py | 8 ++-- > tools/pygrub/src/pygrub | 5 - > 4 files changed, 24 insertions(+), 11 deletions(-) There is a bit missing compared to my original patch which is to convert the string back to bytes for the final write out and avoid the error Traceback (most recent call last): File "/tmp/xencode/usr/libexec/xen/bin/pygrub", line 967, in os.write(fd, ostring) TypeError: a bytes-like object is required, not 'str' The attached patch works for me in a quick test on python3 though I haven't tested it on python2 yet. Michael Young--- xen-4.12.0/tools/pygrub/src/pygrub.orig 2019-04-01 21:25:33.206405995 +0100 +++ xen-4.12.0/tools/pygrub/src/pygrub 2019-04-01 21:27:36.179929105 +0100 @@ -963,5 +963,8 @@ ostring = format_simple(bootcfg["kernel"], bootcfg["ramdisk"], args, "\0") sys.stdout.flush() -os.write(fd, ostring) +if sys.version_info[0] < 3: +os.write(fd, ostring) +else: +os.write(fd, ostring.encode()) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] read grubenv and set default from saved_entry or next_entry [and 1 more messages]
On Wed, 11 Sep 2019, Ian Jackson wrote: > Steven Haigh writes ("Re: [Xen-devel] [PATCH] read grubenv and set default > from saved_entry or next_entry"): >> Just wanted to give this a quick followup... Did this end up >> progressing? > > Hi. I'm a tools maintainer and probably your best bet for a review > etc of this patch. If, next time, you use add_maintainers.pl or > something, you'll end up CCing the maintainer and your mail won't get > dropped. Anyway, thanks for chasing it up through a back channel :-). > > Michael Young : >> From 51a9dce9de3ea159011928e2db8541f3c7e8383a Mon Sep 17 00:00:00 2001 >> From: Michael Young >> Date: Thu, 15 Aug 2019 19:55:30 +0100 >> Subject: [PATCH] read grubenv and set default from saved_entry or next_entry >> >> This patch looks for a grubenv file in the same directory as the >> grub.cfg file and includes it at front of the grub.cfg file when passed >> to parse() > > Thanks for the contribution. I reviewed the patch and I have some > comments. > > I think this patch would be less confusing if it were two patches. > One which does the saved/next entry, and one which reads grubenv. Do > you think that would make sense ? If so I would appreciate it if you > would split it up (and write a nice explanatory commit message about > the saved_entry stuff). Yes, it makes sense to split it up, perhaps with a third patch for a format change of what is passed from pygrub to the backemds. >> As the grubenv file consists of variable=value lines padded by hashes these >> are treated as commands in parse() where it uses the value of saved_entry >> or next_entry (if set) to set the default entry if a title matches or is >> a number. > > I like reusing the parser. > >> diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub >> index ce7ab0eb8c..267788795b 100755 >> --- a/tools/pygrub/src/pygrub >> +++ b/tools/pygrub/src/pygrub >> @@ -454,8 +454,19 @@ class Grub: >> if self.__dict__.get('cf', None) is None: >> raise RuntimeError("couldn't find bootloader config file in the >> image provided.") >> f = fs.open_file(self.cf.filename) >> +fenv = self.cf.filename.replace("grub.cfg","grubenv") > > I find this filename hackery rather unprincipled. I'm not entirely > sure I can see a better way, given the way cfg_list is constructed. > Can you think of a less hacky approach ? > > What would happen in future if we provided a way to control the > grub.cfg read by pygrub and a user configured it to (say) > `grub.cfg.old' ? Would we really want it to read `grubenv.old' ? > One option would be to do a fresh search for grubenv in the same places we looked for grub.cfg. Alternatively, it should be possible to do a more precise edit using f.rpartition("/"). >> +if fenv != self.cf.filename and fs.file_exists(fenv): >> +# if grubenv file exists next to grub.cfg prepend it >> +fenvf = fs.open_file(fenv) >> +if sys.version_info[0] < 3: >> +fsep = "\n" >> +else: >> +fsep = b"\n" >> +buf = fsep.join((fenvf.read(FS_READ_MAX),f.read(FS_READ_MAX))) >> +del fenvf >> # limit read size to avoid pathological cases >> -buf = f.read(FS_READ_MAX) >> +else: >> +buf = f.read(FS_READ_MAX) >> del f >> if sys.version_info[0] < 3: >> self.cf.parse(buf) > > Can we instead make the parser take a list ? This business of > constructing a concatenated string is not very nice. Yes a list is probably the way to go, particularly as we might want to pass more file contents later for BLS support. Michael Young ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [XEN PATCH 0/3] read grubenv and set default from it
This series of patches is to improve the parsing by pygrub of grub configuration on Fedora. The current result of parsing is generally that the second kernel listed is set as the default due to a set default=1 line in grub.cfg which is only intended to be reached after repeated boot failures. The patches read the grubenv file (which consists of key=value lines padded to 1024 characters by # characters) to get the values of next_entry and saved_entry, which can be a kernel string or an order number. Unfortunately, for Fedora 31 at least, this is often a BLS-style string so it isn't necessarily useful. The patches use the value of next_entry or of saved_entry to set the default kernel or sets it to the first kernel listed if those values are set but not used. Michael Young (3): set default kernel from grubenv next_entry or saved_entry read a grubenv file if it is next to the grub.cfg file Example Fedora 31 grub.cfg and grubenv files tools/pygrub/examples/fedora-31.grub.cfg | 200 +++ tools/pygrub/examples/fedora-31.grubenv | 5 + tools/pygrub/src/GrubConf.py | 31 +++- tools/pygrub/src/pygrub | 21 ++- 4 files changed, 253 insertions(+), 4 deletions(-) create mode 100644 tools/pygrub/examples/fedora-31.grub.cfg create mode 100644 tools/pygrub/examples/fedora-31.grubenv -- 2.21.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [XEN PATCH 3/3] Example Fedora 31 grub.cfg and grubenv files
This patch adds an example grub.cfg and grubenv file for reference Signed-off-by: Michael Young --- tools/pygrub/examples/fedora-31.grub.cfg | 200 +++ tools/pygrub/examples/fedora-31.grubenv | 5 + 2 files changed, 205 insertions(+) create mode 100644 tools/pygrub/examples/fedora-31.grub.cfg create mode 100644 tools/pygrub/examples/fedora-31.grubenv diff --git a/tools/pygrub/examples/fedora-31.grub.cfg b/tools/pygrub/examples/fedora-31.grub.cfg new file mode 100644 index 00..9ce38d43b7 --- /dev/null +++ b/tools/pygrub/examples/fedora-31.grub.cfg @@ -0,0 +1,200 @@ +# +# DO NOT EDIT THIS FILE +# +# It is automatically generated by grub2-mkconfig using templates +# from /etc/grub.d and settings from /etc/default/grub +# + +### BEGIN /etc/grub.d/00_header ### +set pager=1 + +if [ -f ${config_directory}/grubenv ]; then + load_env -f ${config_directory}/grubenv +elif [ -s $prefix/grubenv ]; then + load_env +fi +if [ "${next_entry}" ] ; then + set default="${next_entry}" + set next_entry= + save_env next_entry + set boot_once=true +else + set default="${saved_entry}" +fi + +if [ x"${feature_menuentry_id}" = xy ]; then + menuentry_id_option="--id" +else + menuentry_id_option="" +fi + +export menuentry_id_option + +if [ "${prev_saved_entry}" ]; then + set saved_entry="${prev_saved_entry}" + save_env saved_entry + set prev_saved_entry= + save_env prev_saved_entry + set boot_once=true +fi + +function savedefault { + if [ -z "${boot_once}" ]; then +saved_entry="${chosen}" +save_env saved_entry + fi +} + +function load_video { + if [ x$feature_all_video_module = xy ]; then +insmod all_video + else +insmod efi_gop +insmod efi_uga +insmod ieee1275_fb +insmod vbe +insmod vga +insmod video_bochs +insmod video_cirrus + fi +} + +terminal_output console +if [ x$feature_timeout_style = xy ] ; then + set timeout_style=menu + set timeout=5 +# Fallback normal timeout code in case the timeout_style feature is +# unavailable. +else + set timeout=5 +fi +### END /etc/grub.d/00_header ### + +### BEGIN /etc/grub.d/01_users ### +if [ -f ${prefix}/user.cfg ]; then + source ${prefix}/user.cfg + if [ -n "${GRUB2_PASSWORD}" ]; then +set superusers="root" +export superusers +password_pbkdf2 root ${GRUB2_PASSWORD} + fi +fi +### END /etc/grub.d/01_users ### + +### BEGIN /etc/grub.d/08_fallback_counting ### +insmod increment +# Check if boot_counter exists and boot_success=0 to activate this behaviour. +if [ -n "${boot_counter}" -a "${boot_success}" = "0" ]; then + # if countdown has ended, choose to boot rollback deployment, + # i.e. default=1 on OSTree-based systems. + if [ "${boot_counter}" = "0" -o "${boot_counter}" = "-1" ]; then +set default=1 +set boot_counter=-1 + # otherwise decrement boot_counter + else +decrement boot_counter + fi + save_env boot_counter +fi +### END /etc/grub.d/08_fallback_counting ### + +### BEGIN /etc/grub.d/10_linux ### +menuentry 'Fedora (5.3.6-300.fc31.x86_64) 31 (Thirty One)' --class fedora --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.3.6-300.fc31.x86_64-advanced-1dec723d-4bdf-461a-a09b-e71ba5974892' { + load_video + set gfxpayload=keep + insmod gzio + insmod part_msdos + insmod ext2 + set root='hd0,msdos1' + if [ x$feature_platform_search_hint = xy ]; then + search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 00c6a44a-1624-4c8f-bd08-bc66ea59edbe + else + search --no-floppy --fs-uuid --set=root 00c6a44a-1624-4c8f-bd08-bc66ea59edbe + fi + linux /vmlinuz-5.3.6-300.fc31.x86_64 root=/dev/mapper/fedora_localhost--live-root ro resume=/dev/mapper/fedora_localhost--live-swap rd.lvm.lv=fedora_localhost-live/root rd.lvm.lv=fedora_localhost-live/swap rhgb quiet + initrd /initramfs-5.3.6-300.fc31.x86_64.img +} +menuentry 'Fedora (0-rescue-fbc80dcce05d4a1a9b9a7951232a4eeb) 31 (Thirty One)' --class fedora --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-fbc80dcce05d4a1a9b9a7951232a4eeb-advanced-1dec723d-4bdf-461a-a09b-e71ba5974892' { + load_video + insmod gzio + insmod part_msdos + insmod ext2 + set root='hd0,msdos1' + if [ x$feature_platform_search_hint = xy ]; then + search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 00c6a44a-1624-4c8f-bd08-bc66ea59edbe + else + search --no-floppy --fs-uuid --set=root 00c6a44a-1624-4c8f-bd08-bc66ea59edbe + fi + linux /vmlinuz-0-rescue-fbc80dcce05d4a1a9b9a7951232a4eeb root=/dev/mapper/fedora_localhost--live-root ro resume=/dev/mapper/fedora_localhost--live-swap rd.lvm.lv=fedora_localhost-live/root rd.lvm.lv=fedora_localhost-live/swap rhgb quiet + initrd /initramfs-0-rescue-fbc80dcce05d4a1a9b9a7951232a4eeb.img +} + +### END /etc/grub.d/10_linux ### + +### BEGIN /e
[Xen-devel] [XEN PATCH 2/3] read a grubenv file if it is next to the grub.cfg file
When a grub.cfg file is found this patch checks if there is grubenv file in the same directory as the grub.cfg file. If there is it passes the contents to parse(). Signed-off-by: Michael Young --- tools/pygrub/src/pygrub | 21 ++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index ce7ab0eb8c..53a0803817 100755 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -457,10 +457,25 @@ class Grub: # limit read size to avoid pathological cases buf = f.read(FS_READ_MAX) del f -if sys.version_info[0] < 3: -self.cf.parse(buf) +# check for a grubenv file next to the grub.cfg file +(fdir, fsep, ffile) = self.cf.filename.rpartition("/") +if fdir != "" and ffile == "grub.cfg": +fenv = fdir + "/grubenv" else: -self.cf.parse(buf.decode()) +fenv = "" +if fenv != "" and fs.file_exists(fenv): +fenvf = fs.open_file(fenv) +grubenv = fenvf.read(FS_READ_MAX) +del fenvf +if sys.version_info[0] < 3: +self.cf.parse(buf, grubenv) +else: +self.cf.parse(buf.decode(), grubenv.decode()) +else: +if sys.version_info[0] < 3: +self.cf.parse(buf) +else: +self.cf.parse(buf.decode()) def image_index(self): if isinstance(self.cf.default, int): -- 2.21.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [XEN PATCH 1/3] set default kernel from grubenv next_entry or saved_entry
This patch reads the contents of a grubenv file if available, and uses the value of next_entry (in preference) or of saved_entry to set the default kernel if there is a matching title or if it is a number. If either next_entry or saved_entry is set and neither is used then the default is set to 0. Signed-off-by: Michael Young --- tools/pygrub/src/GrubConf.py | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py index 73f1bbed2f..1fc68cadb2 100644 --- a/tools/pygrub/src/GrubConf.py +++ b/tools/pygrub/src/GrubConf.py @@ -368,7 +368,7 @@ class Grub2ConfigFile(_GrubConfigFile): def new_image(self, title, lines): return Grub2Image(title, lines) -def parse(self, buf = None): +def parse(self, buf = None, grubenv = None): if buf is None: if self.filename is None: raise ValueError("No config file defined to parse!") @@ -379,10 +379,17 @@ class Grub2ConfigFile(_GrubConfigFile): else: lines = buf.split("\n") +if grubenv is not None: +lines = grubenv.split("\n") + lines + in_function = False img = None title = "" menu_level=0 +img_count=0 +saved_entry = "" +next_entry = "" +entry_matched = False for l in lines: l = l.strip() # skip blank lines @@ -408,6 +415,13 @@ class Grub2ConfigFile(_GrubConfigFile): raise RuntimeError("syntax error: cannot nest menuentry (%d %s)" % (len(img),img)) img = [] title = title_match.group(1) +if title == next_entry: +setattr(self, 'default', img_count) +entry_matched = True +if title == saved_entry and not entry_matched: +setattr(self, 'default', img_count) +entry_matched = True +img_count += 1 continue if l.startswith("submenu"): @@ -432,6 +446,14 @@ class Grub2ConfigFile(_GrubConfigFile): (com, arg) = grub_exact_split(l, 2) +if com == "next_entry": +next_entry = arg +continue + +if com == "saved_entry": +saved_entry = arg +continue + if com == "set": (com,arg) = grub2_handle_set(arg) @@ -448,6 +470,13 @@ class Grub2ConfigFile(_GrubConfigFile): pass else: logging.warning("Unknown directive %s" %(com,)) + +if next_entry.isdigit(): +setattr(self, 'default', next_entry) +elif saved_entry.isdigit() and not entry_matched: +setattr(self, 'default', saved_entry) +elif (next_entry != "" or saved_entry != "") and not entry_matched: +setattr(self, 'default', 0) if img is not None: raise RuntimeError("syntax error: end of file with open menuentry(%d %s)" % (len(img),img)) -- 2.21.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [XEN PATCH 0/3] read grubenv and set default from it
On Sat, 26 Oct 2019, Steven Haigh wrote: > If / when pygrub is able to properly read and boot from BLS based > configurations (I'm not sure if this patchset makes pygrub BLS compatible, or > just fixes the existing issues) - but we can look at revisiting removing > these workarounds from anaconda / grub2 packages in F30 / F31 / Rawhide. The patchset doesn't add BLS compatibility but should be useful for what I expect BLS support to look like (I have a idea of what would be required though I haven't worked out the details yet). Michael Young ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [XEN PATCH] mismatch between pyxc_methods flags and PyObject definitions
pygrub in xen-4.13.0 with python 3.8.2 fails with the error Traceback (most recent call last): File "/usr/libexec/xen/bin/pygrub", line 21, in import xen.lowlevel.xc SystemError: bad call flags This patch fixes mismatches in tools/python/xen/lowlevel/xc/xc.c between the flag bits defined in pyxc_methods and the parameters passed to the corresponding PyObject definitions. With this patch applied pygrub works as expected. Signed-off-by: Michael Young --- tools/python/xen/lowlevel/xc/xc.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index ac0e26a742..8fde5f311f 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -2028,7 +2028,7 @@ static PyMethodDef pyxc_methods[] = { { "gnttab_hvm_seed", (PyCFunction)pyxc_gnttab_hvm_seed, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Initialise HVM guest grant table.\n" " dom [int]: Identifier of domain to build into.\n" " console_gmfn [int]: \n" @@ -2097,7 +2097,7 @@ static PyMethodDef pyxc_methods[] = { { "sched_credit_domain_set", (PyCFunction)pyxc_sched_credit_domain_set, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Set the scheduling parameters for a domain when running with the\n" "SMP credit scheduler.\n" " domid [int]: domain id to set\n" @@ -2115,7 +2115,7 @@ static PyMethodDef pyxc_methods[] = { { "sched_credit2_domain_set", (PyCFunction)pyxc_sched_credit2_domain_set, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Set the scheduling parameters for a domain when running with the\n" "SMP credit2 scheduler.\n" " domid [int]: domain id to set\n" @@ -2393,21 +2393,21 @@ static PyMethodDef pyxc_methods[] = { { "flask_context_to_sid", (PyCFunction)pyflask_context_to_sid, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Convert a context string to a dynamic SID.\n" " context [str]: String specifying context to be converted\n" "Returns: [int]: Numeric SID on success; -1 on error.\n" }, { "flask_sid_to_context", (PyCFunction)pyflask_sid_to_context, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Convert a dynamic SID to context string.\n" " context [int]: SID to be converted\n" "Returns: [str]: Numeric SID on success; -1 on error.\n" }, { "flask_load", (PyCFunction)pyflask_load, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Loads a policy into the hypervisor.\n" " policy [str]: policy to be load\n" "Returns: [int]: 0 on success; -1 on failure.\n" }, @@ -2420,14 +2420,14 @@ static PyMethodDef pyxc_methods[] = { { "flask_setenforce", (PyCFunction)pyflask_setenforce, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Modifies the current mode for the Flask XSM module.\n" " mode [int]: mode to change to\n" "Returns: [int]: 0 on success; -1 on failure.\n" }, { "flask_access", (PyCFunction)pyflask_access, - METH_KEYWORDS, "\n" + METH_VARARGS | METH_KEYWORDS, "\n" "Returns whether a source context has access to target context based on \ class and permissions requested.\n" " scon [str]: source context\n" -- 2.21.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] pygrub, installed with Python 3, doesn't boot Xen DomU-s
On Mon, 22 Jul 2019, Andrew Cooper wrote: > On 22/07/2019 03:57, Kevin Buckley wrote: >> bash-5.0# /usr/lib/xen/bin/pygrub --debug --offset=1048576 >> --list-entries /dev/vg_xen_vbds/lv_4g_02 >> Using to parse /boot/grub/grub.cfg >> Traceback (most recent call last): >> File "/usr/lib/xen/bin/pygrub", line 907, in >> chosencfg = run_grub(file, entry, fs, incfg["args"]) >> File "/usr/lib/xen/bin/pygrub", line 625, in run_grub >> g = Grub(file, fs) >> File "/usr/lib/xen/bin/pygrub", line 249, in __init__ >> self.read_config(file, fs) >> File "/usr/lib/xen/bin/pygrub", line 460, in read_config >> self.cf.parse(buf) >> File "/usr/lib/python3.7/site-packages/grub/GrubConf.py", line 376, in >> parse >> lines = buf.split("\n") >> TypeError: a bytes-like object is required, not 'str' >> >> ... >> >> Ok, so then I went hunting around for the cause of the error >> I was seeing on the LFS system and got pointed towards the >> cause being a Pythin2->3 issue, with the way 3 now differentiates >> between strings and bytes. > > Yes - this looks like a Py 2/3 compatibility issue. This particular one > is related to > https://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=ff915c8cacc264ae1380d51fea07267b8308d7ba > > However, I can't explain why python is complaining at str.split(). > split() is a string operation, not a bytes operation. It looks like you are missing the above patch and I think you also need https://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=485079e816788d70169f45579e1f5a8f909dc1b3 https://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=767ba397d34848c7e0c4e9cdfc5efa4e0cb61442 and perhaps https://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=a57a1b26ec0ae31f924cf2bbcf479637d007be44 if you build with ocaml. Actually the first of these 3 patches is optional as it is just an error message change but should allow the second patch to apply cleanly. Michael Young ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel