On Wed, 2008-05-28 at 15:39 +0200, Robert Millan wrote:
> No reply...  if you're still interested in this, I suggest you contact
> the people who set the current behaviour and involve them in the discussion,
> to see if they have any objections to what you propose.

I've not had as much time to look at it recently as I would have liked
(and I'm just about to disappear for a long weekend).

I've got a pretty skanky patch which attempts to add paravirt support to
grub2's update-grub in a way that's a little more general (perhaps
lguest or some other h/v support would be useful).

I've attached it but don't think it is correct in all cases at the
moment (and some code just echoes "do foo" instead of doing it...).

Ian.

> 
> On Sun, May 11, 2008 at 10:36:38AM +0100, Ian Campbell wrote:
> > Hi all,
> > 
> > The version of update-grub in Debian's grub-legacy packages[0] has an
> > interesting feature where it attempts to detect when I kernel is
> > compiled for Xen and chooses to include it in the menu depending on
> > whether it is running inside a Xen guest domain or not[1].
> > 
> > As described at [2] this behaviour has been broken by the latest kernels
> > which due to the paravirt_ops (CONFIG_PARAVIRT) framework which means
> > that these kernels are now bootable both native and as a Xen guest
> > domain.
> > 
> > Robert asked me to bring the issue here and to ask the question of
> > whether or not this behaviour would be welcomed as a patch to grub 2.
> > 
> > Personally I am not a fan of this behaviour since it causes the wrong
> > thing to occur in several circumstances, i.e. installing into a chroot
> > or switching back and forth between fully- and para-virtualised
> > operation and as time moves on CONFIG_PARAVIRT will become the norm and
> > the behaviour less necessary in general. What is the opinion of the grub
> > 2 devs?
> > 
> > Cheers,
> > Ian.
> > [0] For those not familiar with Xen the classical Xen kernels cannot be
> > run on bare metal so there is an argument that it makes little sense to
> > include them in the menu for the control domain, conversely including a
> > native kernel in the menu for a guest domain is not terribly useful
> > either. CONFIG_PARAVIRT (2.6.22+) changes this and such kernel is now
> > bootable on native and under Xen.
> > [1]
> > http://svn.debian.org/viewsvn/pkg-grub/grub/trunk/debian/update-grub?view=auto
> > [2]
> > http://lists.alioth.debian.org/pipermail/pkg-grub-devel/2008-April/004701.html
> >  
> > http://lists.alioth.debian.org/pipermail/pkg-grub-devel/2008-May/004821.html
> > 
> > 
> > -- 
> > Ian Campbell
> > 
> > Waste not fresh tears over old griefs.
> >             -- Euripides
> 
> 
> 
> > _______________________________________________
> > Grub-devel mailing list
> > Grub-devel@gnu.org
> > http://lists.gnu.org/mailman/listinfo/grub-devel
> 
> 
-- 
Ian Campbell

"Here comes Mr. Bill's dog."
                -- Narrator, Saturday Night Live
? .pc
? patches
? v1
Index: util/grub.d/10_linux.in
===================================================================
RCS file: /cvsroot/grub/grub2/util/grub.d/10_linux.in,v
retrieving revision 1.10
diff -u -r1.10 10_linux.in
--- util/grub.d/10_linux.in	30 Apr 2008 11:06:27 -0000	1.10
+++ util/grub.d/10_linux.in	30 May 2008 07:44:35 -0000
@@ -78,11 +78,36 @@
   echo "$a"
 }
 
+paravirt="${GRUB_PARAVIRT_ENV:-detect}"
+echo "paravirt: $paravirt" >&2
+if [ "$paravirt" == "detect" ] ; then
+    if [ -e /proc/xen/capabilities ] || [ -e /sys/bus/xen ] ; then
+	paravirt="xen"
+    else
+	paravirt="native"
+    fi
+fi
+# Determine the config string to check for in this paravirtual environment.
+case "${paravirt}" in
+    xen) paravirt_guest="CONFIG_XEN=y" ;;
+    native) paravirt_guest= ;;
+    *) # Invalid? Call it native...
+	paravirt=native
+	paravirt_guest=
+	;;
+esac
+echo "paravirt_guest: $paravirt_guest" >&2
+
 list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do
         if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
       done`
+xen_hv=`for i in /boot/xen-*.gz /xen-*.gz ; do
+	if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
+      done`
+xen_hv=${xen_hv_}
 
 while [ "x$list" != "x" ] ; do
+  echo >&2
   linux=`find_latest $list`
   echo "Found linux image: $linux" >&2
   basename=`basename $linux`
@@ -91,6 +116,37 @@
   version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
   alt_version=`echo $version | sed -e "s,\.old$,,g"`
 
+  config=
+  for i in "config-${version}" "config-${alt_version}"; do
+    if test -e "${dirname}/${i}" ; then
+      config="$i"
+      break
+    fi
+  done
+  if test -n "${config}" ; then
+    echo "Found config: ${dirname}/${config}" >&2
+  fi
+
+  is_paravirt=
+  is_paravirt_guest=
+  is_nonparavirt_xen=
+
+  if test -n ${config} ; then
+      if grep -q CONFIG_PARAVIRT=y ${dirname}/${config} ; then
+	  is_paravirt=1
+
+	  if test -n "${paravirt_guest}" && grep -q ${paravirt_guest} ${dirname}/${config} ; then
+	      is_paravirt_guest=1
+	  fi
+      fi
+
+      # Special case to handle pre-CONFIG_PARAVIRT Xen guests.
+      if ! grep -q CONFIG_PARAVIRT ${dirname}/${config} &&
+	  grep -q CONFIG_XEN=y ${dirname}/${config} ; then
+	  is_nonparavirt_xen=1
+      fi
+  fi
+
   initrd=
   for i in "initrd.img-${version}" "initrd-${version}.img" \
 	   "initrd.img-${alt_version}" "initrd-${alt_version}.img"; do
@@ -103,31 +159,73 @@
     echo "Found initrd image: ${dirname}/${initrd}" >&2
   fi
 
-  cat << EOF
+  echo "is_paravirt=$is_paravirt is_paravirt_guest=$is_paravirt_guest is_nonparavirt_xen=$is_nonparavirt_xen" >&2
+  emit=std
+  if [ "${paravirt}" != "native" ] && [ "$is_paravirt_guest" ] ; then
+      emit=pv
+  elif [ "${paravirt}" != "native" ] && [ ! "$is_paravirt_guest" ] ; then
+      if [ "${paravirt}" == "xen" ] && [ "$is_nonparavirt_xen" ]; then
+          # Allow old style non-CONFIG_PARAVIRT Xen kernels.
+	  echo "allowing non-PARAVIRT Xen kernel $linux" >&2
+	  emit=nonpvxen
+      else
+	  echo "skip non-paravirt kernel $linux in guest domain. (B)" >&2
+	  emit=none
+	  #list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
+	  #continue
+      fi
+  else
+      if [ "$is_nonparavirt_xen" ]; then
+	  echo "skip non paravirt Xen kernel $linux on native. (C)" >&2
+	  emit=none
+          # skip xen kernels
+          #list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
+          #continue
+      fi
+  fi
+
+  if [ "${emit}" == "pv" ] || [ "${emit}" == "nonpvxen" ] ; then
+      if [ -n "${xen_hv}" ] ; then
+	  echo "create xen stanzas for $xen_hv and Linux $version" >&2
+	  if [ "${emit}" == "pv" ] ; then
+	      emit="std" # Also emit a non-Xen entry for a paravirt kernel
+	  else
+	      emit=none # But not for an old-style -Xen kernel
+	  fi
+      else
+          # If no hypervisor present then assume guest domain and emit a standard entry
+	  emit="std"
+      fi
+  fi
+
+  if [ "${emit}" == "std" ] ; then
+      echo "create regular entry for $version" >&2
+      cat << EOF
 menuentry "${OS}, linux ${version}" {
 	linux	${grub_dirname}/${basename} root=${GRUB_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}
 EOF
-  if test -n "${initrd}" ; then
+      if test -n "${initrd}" ; then
     cat << EOF
 	initrd	${grub_dirname}/${initrd}
 EOF
-  fi
-  cat << EOF
+      fi
+      cat << EOF
 }
 EOF
 
-  cat << EOF
+      cat << EOF
 menuentry "${OS}, linux ${version} (single-user mode)" {
 	linux	${grub_dirname}/${basename} root=${GRUB_DEVICE} ro single ${GRUB_CMDLINE_LINUX}
 EOF
-  if test -n "${initrd}" ; then
-    cat << EOF
+      if test -n "${initrd}" ; then
+	  cat << EOF
 	initrd	${grub_dirname}/${initrd}
 EOF
-  fi
-  cat << EOF
+      fi
+      cat << EOF
 }
 EOF
+  fi
 
   list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
 done

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to