WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [PYGRUB] Plumb bootloader I/O through xen

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [PYGRUB] Plumb bootloader I/O through xenconsole.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 22 Jan 2007 08:50:12 -0800
Delivery-date: Mon, 22 Jan 2007 08:50:25 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1169466554 0
# Node ID 5f998c3170f70d37b896b1930d0394953c62e178
# Parent  51ff4083947086bd48328698052b03421edb7c82
[PYGRUB] Plumb bootloader I/O through xenconsole.

 - xend forwards console traffic between the running bootloader and a pty
   which it writes to the store so the xenconsole client can see it.
 - the xenconsole client handles the domain's console pty changing.
 - xm create no longer runs the bootloader.
 - pygrub gets '-i' option to explicitly request an interactive session.
 - xend unlocks the domain list during bootloading so that "xm console"
   can see the domain and attach to its console pty.

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
 tools/console/client/main.c             |  129 ++++++++++++++++++++------------
 tools/misc/xend                         |    2 
 tools/pygrub/src/pygrub                 |   13 ++-
 tools/python/xen/xend/XendBootloader.py |   97 +++++++++++++++++++++---
 tools/python/xen/xend/XendDomain.py     |   20 +---
 tools/python/xen/xend/XendDomainInfo.py |   17 +++-
 tools/python/xen/xm/create.py           |   53 ++++++-------
 7 files changed, 226 insertions(+), 105 deletions(-)

diff -r 51ff40839470 -r 5f998c3170f7 tools/console/client/main.c
--- a/tools/console/client/main.c       Mon Jan 22 11:49:11 2007 +0000
+++ b/tools/console/client/main.c       Mon Jan 22 11:49:14 2007 +0000
@@ -71,6 +71,43 @@ static void usage(const char *program) {
               , program);
 }
 
+static int get_pty_fd(struct xs_handle *xs, char *path, int seconds)
+/* Check for a pty in xenstore, open it and return its fd.
+ * Assumes there is already a watch set in the store for this path. */
+{
+       struct timeval tv;
+       fd_set watch_fdset;
+       int xs_fd = xs_fileno(xs), pty_fd = -1;
+       int start, now;
+       unsigned int len = 0;
+       char *pty_path, **watch_paths;;
+
+       start = now = time(NULL);
+       do {
+               tv.tv_usec = 0;
+               tv.tv_sec = (start + seconds) - now;
+               FD_ZERO(&watch_fdset);
+               FD_SET(xs_fd, &watch_fdset);
+               if (select(xs_fd + 1, &watch_fdset, NULL, NULL, &tv)) {
+                       /* Read the watch to drain the buffer */
+                       watch_paths = xs_read_watch(xs, &len);
+                       free(watch_paths);
+                       /* We only watch for one thing, so no need to 
+                        * disambiguate: just read the pty path */
+                       pty_path = xs_read(xs, XBT_NULL, path, &len);
+                       if (pty_path != NULL) {
+                               pty_fd = open(pty_path, O_RDWR | O_NOCTTY);
+                               if (pty_fd == -1) 
+                                       err(errno, "Could not open tty `%s'", 
+                                           pty_path);
+                               free(pty_path);
+                       }
+               }
+       } while (pty_fd == -1 && (now = time(NULL)) < start + seconds);
+       return pty_fd;
+}
+
+
 /* don't worry too much if setting terminal attributes fail */
 static void init_term(int fd, struct termios *old)
 {
@@ -91,23 +128,37 @@ static void restore_term(int fd, struct 
        tcsetattr(fd, TCSAFLUSH, old);
 }
 
-static int console_loop(int fd)
-{
-       int ret;
+static int console_loop(int fd, struct xs_handle *xs, char *pty_path)
+{
+       int ret, xs_fd = xs_fileno(xs), max_fd;
 
        do {
                fd_set fds;
 
                FD_ZERO(&fds);
                FD_SET(STDIN_FILENO, &fds);
-               FD_SET(fd, &fds);
-
-               ret = select(fd + 1, &fds, NULL, NULL, NULL);
+               max_fd = STDIN_FILENO;
+               FD_SET(xs_fd, &fds);
+               if (xs_fd > max_fd) max_fd = xs_fd;
+               if (fd != -1) FD_SET(fd, &fds);
+               if (fd > max_fd) max_fd = fd;
+
+               ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
                if (ret == -1) {
                        if (errno == EINTR || errno == EAGAIN) {
                                continue;
                        }
                        return -1;
+               }
+
+               if (FD_ISSET(xs_fileno(xs), &fds)) {
+                       int newfd = get_pty_fd(xs, pty_path, 0);
+                       close(fd);
+                        if (newfd == -1) 
+                               /* Console PTY has become invalid */
+                               return 0;
+                       fd = newfd;
+                       continue;
                }
 
                if (FD_ISSET(STDIN_FILENO, &fds)) {
@@ -128,12 +179,13 @@ static int console_loop(int fd)
                        }
 
                        if (!write_sync(fd, msg, len)) {
-                               perror("write() failed");
-                               return -1;
-                       }
-               }
-
-               if (FD_ISSET(fd, &fds)) {
+                               close(fd);
+                               fd = -1;
+                               continue;
+                       }
+               }
+
+               if (fd != -1 && FD_ISSET(fd, &fds)) {
                        ssize_t len;
                        char msg[512];
 
@@ -143,7 +195,9 @@ static int console_loop(int fd)
                                    (errno == EINTR || errno == EAGAIN)) {
                                        continue;
                                }
-                               return -1;
+                               close(fd);
+                               fd = -1;
+                               continue;
                        }
 
                        if (!write_sync(STDOUT_FILENO, msg, len)) {
@@ -168,12 +222,10 @@ int main(int argc, char **argv)
                { 0 },
 
        };
-       char *str_pty, *path;
-       int spty;
-       unsigned int len = 0;
+       char *path;
+       int spty, xsfd;
        struct xs_handle *xs;
        char *end;
-       time_t now;
 
        while((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
                switch(ch) {
@@ -213,7 +265,6 @@ int main(int argc, char **argv)
        if (path == NULL)
                err(ENOMEM, "realloc");
        strcat(path, "/console/tty");
-       str_pty = xs_read(xs, XBT_NULL, path, &len);
 
        /* FIXME consoled currently does not assume domain-0 doesn't have a
           console which is good when we break domain-0 up.  To keep us
@@ -224,38 +275,24 @@ int main(int argc, char **argv)
                exit(EINVAL);
        }
 
+       /* Set a watch on this domain's console pty */
+       if (!xs_watch(xs, path, ""))
+               err(errno, "Can't set watch for console pty");
+       xsfd = xs_fileno(xs);
+
        /* Wait a little bit for tty to appear.  There is a race
-          condition that occurs after xend creates a domain.  This
-          code might be running before consoled has noticed the new
-          domain and setup a pty for it.
-
-          A xenstore watch would slightly improve responsiveness but
-          a timeout would still be needed since we don't want to
-          block forever if given an invalid domain or worse yet, a
-          domain that someone else has connected to. */
-
-       now = time(0);
-       while (str_pty == NULL && (now + 5) > time(0)) {
-               struct timeval tv = { 0, 250000 };
-               select(0, NULL, NULL, NULL, &tv); /* pause briefly */
-
-               str_pty = xs_read(xs, XBT_NULL, path, &len);
-       }
-
-       if (str_pty == NULL) {
+          condition that occurs after xend creates a domain.  This code
+          might be running before consoled has noticed the new domain
+          and setup a pty for it. */ 
+        spty = get_pty_fd(xs, path, 5);
+       if (spty == -1) {
                err(errno, "Could not read tty from store");
        }
 
-       spty = open(str_pty, O_RDWR | O_NOCTTY);
-       if (spty == -1) {
-               err(errno, "Could not open tty `%s'", str_pty);
-       }
-       free(str_pty);
+       init_term(STDIN_FILENO, &attr);
+       console_loop(spty, xs, path);
+       restore_term(STDIN_FILENO, &attr);
+
        free(path);
-
-       init_term(STDIN_FILENO, &attr);
-       console_loop(spty);
-       restore_term(STDIN_FILENO, &attr);
-
        return 0;
  }
diff -r 51ff40839470 -r 5f998c3170f7 tools/misc/xend
--- a/tools/misc/xend   Mon Jan 22 11:49:11 2007 +0000
+++ b/tools/misc/xend   Mon Jan 22 11:49:14 2007 +0000
@@ -44,7 +44,7 @@ for p in ['python%s' % sys.version[:3], 
         if os.path.exists(os.path.join(d, AUXBIN)):
             sys.path.append(d)
             import xen.util.auxbin
-            libpath = xen.util.auxbin.libpath()
+            libpath = os.path.join(xen.util.auxbin.libpath(), p)
             sys.path = sys.path[:-1]
             sys.path.append(libpath)
             break
diff -r 51ff40839470 -r 5f998c3170f7 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Mon Jan 22 11:49:11 2007 +0000
+++ b/tools/pygrub/src/pygrub   Mon Jan 22 11:49:14 2007 +0000
@@ -201,7 +201,9 @@ class Grub:
             enable_cursor(False)
             self.entry_win = curses.newwin(10, 74, 2, 1)
             self.text_win = curses.newwin(10, 70, 12, 5)
-            
+            curses.def_prog_mode()
+        
+        curses.reset_prog_mode()
         self.screen.clear()
         self.screen.refresh()
 
@@ -549,11 +551,12 @@ if __name__ == "__main__":
     sel = None
     
     def usage():
-        print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--kernel=] 
[--ramdisk=] [--args=] [--entry=] <image>" %(sys.argv[0],)
+        print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive] 
[--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] <image>" 
%(sys.argv[0],)
 
     try:
-        opts, args = getopt.gnu_getopt(sys.argv[1:], 'qh::',
-                                   ["quiet", "help", "output=", "entry=", 
"kernel=", "ramdisk=", "args=",
+        opts, args = getopt.gnu_getopt(sys.argv[1:], 'qih::',
+                                   ["quiet", "interactive", "help", "output=",
+                                    "entry=", "kernel=", "ramdisk=", "args=",
                                     "isconfig"])
     except getopt.GetoptError:
         usage()
@@ -579,6 +582,8 @@ if __name__ == "__main__":
     for o, a in opts:
         if o in ("-q", "--quiet"):
             interactive = False
+        elif o in ("-i", "--interactive"):
+            interactive = True
         elif o in ("-h", "--help"):
             usage()
             sys.exit()
diff -r 51ff40839470 -r 5f998c3170f7 tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py   Mon Jan 22 11:49:11 2007 +0000
+++ b/tools/python/xen/xend/XendBootloader.py   Mon Jan 22 11:49:14 2007 +0000
@@ -12,7 +12,7 @@
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 #
 
-import os, select, errno, stat
+import os, select, errno, stat, signal
 import random
 import shlex
 from xen.xend import sxp
@@ -21,12 +21,15 @@ from XendLogging import log
 from XendLogging import log
 from XendError import VmError
 
-def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '',
+import pty, ptsname, termios, fcntl
+
+def bootloader(blexec, disk, dom, quiet = False, blargs = '', kernel = '',
                ramdisk = '', kernel_args = ''):
     """Run the boot loader executable on the given disk and return a
     config image.
     @param blexec  Binary to use as the boot loader
     @param disk Disk to run the boot loader on.
+    @param dom DomainInfo representing the domain being booted.
     @param quiet Run in non-interactive mode, just booting the default.
     @param blargs Arguments to pass to the bootloader."""
     
@@ -50,7 +53,33 @@ def bootloader(blexec, disk, quiet = Fal
                 raise
         break
 
-    child = os.fork()
+    # We need to present the bootloader's tty as a pty slave that xenconsole
+    # can access.  Since the bootloader itself needs a pty slave, 
+    # we end up with a connection like this:
+    #
+    # xenconsole -- (slave pty1 master) <-> (master pty2 slave) -- bootloader
+    #
+    # where we copy characters between the two master fds, as well as
+    # listening on the bootloader's fifo for the results.
+
+    # Termios runes for very raw access to the pty master fds.
+    attr = [ 0, 0, termios.CS8 | termios.CREAD | termios.CLOCAL,
+             0, 0, 0, [0] * 32 ]
+
+    (m1, s1) = pty.openpty()
+    termios.tcsetattr(m1, termios.TCSANOW, attr)
+    fcntl.fcntl(m1, fcntl.F_SETFL, os.O_NDELAY);
+    os.close(s1)
+    slavename = ptsname.ptsname(m1)
+    dom.storeDom("console/tty", slavename)
+
+    # Release the domain lock here, because we definitely don't want 
+    # a stuck bootloader to deny service to other xend clients.
+    from xen.xend import XendDomain
+    domains = XendDomain.instance()
+    domains.domains_lock.release()
+    
+    (child, m2) = pty.fork()
     if (not child):
         args = [ blexec ]
         if kernel:
@@ -74,6 +103,11 @@ def bootloader(blexec, disk, quiet = Fal
             pass
         os._exit(1)
 
+    # record that this domain is bootloading
+    dom.bootloader_pid = child
+
+    termios.tcsetattr(m2, termios.TCSANOW, attr)
+    fcntl.fcntl(m2, fcntl.F_SETFL, os.O_NDELAY);
     while True:
         try:
             r = os.open(fifo, os.O_RDONLY)
@@ -82,16 +116,52 @@ def bootloader(blexec, disk, quiet = Fal
                 continue
         break
     ret = ""
+    inbuf=""; outbuf="";
     while True:
-        select.select([r], [], [])
-        s = os.read(r, 1024)
-        ret = ret + s
-        if len(s) == 0:
-            break
-        
+        sel = select.select([r, m1, m2], [m1, m2], [])
+        try: 
+            if m1 in sel[0]:
+                s = os.read(m1, 1)
+                inbuf += s
+            if m2 in sel[1] and len(inbuf) != 0:
+                os.write(m2, inbuf[0])
+                inbuf = inbuf[1:]
+        except OSError, e:
+            if e.errno == errno.EIO:
+                pass
+        try:
+            if m2 in sel[0]:
+                s = os.read(m2, 1)
+                outbuf += s
+            if m1 in sel[1] and len(outbuf) != 0:
+                os.write(m1, outbuf[0])
+                outbuf = outbuf[1:]
+        except OSError, e:
+            if e.errno == errno.EIO:
+                pass
+        if r in sel[0]:
+            s = os.read(r, 1)
+            ret = ret + s
+            if len(s) == 0:
+                break
+    del inbuf
+    del outbuf
     os.waitpid(child, 0)
     os.close(r)
+    os.close(m2)
+    os.close(m1)
     os.unlink(fifo)
+
+    # Re-acquire the lock to cover the changes we're about to make
+    # when we return to domain creation.
+    domains.domains_lock.acquire()    
+
+    if dom.bootloader_pid is None:
+        msg = "Domain was died while the bootloader was running."
+        log.error(msg)
+        raise VmError, msg        
+        
+    dom.bootloader_pid = None
 
     if len(ret) == 0:
         msg = "Boot loader didn't return any data!"
@@ -103,3 +173,12 @@ def bootloader(blexec, disk, quiet = Fal
     pin.input_eof()
     blcfg = pin.val
     return blcfg
+
+
+def bootloader_tidy(dom):
+    if hasattr(dom, "bootloader_pid") and dom.bootloader_pid is not None:
+        pid = dom.bootloader_pid
+        dom.bootloader_pid = None
+        os.kill(pid, signal.SIGKILL)
+
+
diff -r 51ff40839470 -r 5f998c3170f7 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Jan 22 11:49:11 2007 +0000
+++ b/tools/python/xen/xend/XendDomain.py       Mon Jan 22 11:49:14 2007 +0000
@@ -115,7 +115,6 @@ class XendDomain:
                 
                 dom0info['name'] = DOM0_NAME
                 dom0 = XendDomainInfo.recreate(dom0info, True)
-                self._add_domain(dom0)
             except IndexError:
                 raise XendError('Unable to find Domain 0')
             
@@ -172,7 +171,6 @@ class XendDomain:
                 if dom['domid'] != DOM0_ID:
                     try:
                         new_dom = XendDomainInfo.recreate(dom, False)
-                        self._add_domain(new_dom)
                     except Exception:
                         log.exception("Failed to create reference to running "
                                       "domain id: %d" % dom['domid'])
@@ -397,7 +395,6 @@ class XendDomain:
             elif domid not in self.domains and dom['dying'] != 1:
                 try:
                     new_dom = XendDomainInfo.recreate(dom, False)
-                    self._add_domain(new_dom)                    
                 except VmError:
                     log.exception("Unable to recreate domain")
                     try:
@@ -416,10 +413,10 @@ class XendDomain:
         running_domids = [d['domid'] for d in running if d['dying'] != 1]
         for domid, dom in self.domains.items():
             if domid not in running_domids and domid != DOM0_ID:
-                self._remove_domain(dom, domid)
-
-
-    def _add_domain(self, info):
+                self.remove_domain(dom, domid)
+
+
+    def add_domain(self, info):
         """Add a domain to the list of running domains
         
         @requires: Expects to be protected by the domains_lock.
@@ -434,7 +431,7 @@ class XendDomain:
         if info.get_uuid() in self.managed_domains:
             self._managed_domain_register(info)
 
-    def _remove_domain(self, info, domid = None):
+    def remove_domain(self, info, domid = None):
         """Remove the domain from the list of running domains
         
         @requires: Expects to be protected by the domains_lock.
@@ -473,7 +470,6 @@ class XendDomain:
         try:
             security.refresh_ssidref(config)
             dominfo = XendDomainInfo.restore(config)
-            self._add_domain(dominfo)
             return dominfo
         finally:
             self.domains_lock.release()
@@ -848,7 +844,6 @@ class XendDomain:
                                            os.open(chkpath, os.O_RDONLY),
                                            dominfo,
                                            paused = start_paused)
-                    self._add_domain(dominfo)
                     os.unlink(chkpath)
                 except OSError, ex:
                     raise XendError("Failed to read stored checkpoint file")
@@ -873,7 +868,6 @@ class XendDomain:
             self._refresh()
 
             dominfo = XendDomainInfo.create(config)
-            self._add_domain(dominfo)
             self.domain_sched_credit_set(dominfo.getDomid(),
                                          dominfo.getWeight(),
                                          dominfo.getCap())
@@ -893,7 +887,6 @@ class XendDomain:
             self._refresh()
 
             dominfo = XendDomainInfo.create_from_dict(config_dict)
-            self._add_domain(dominfo)
             self.domain_sched_credit_set(dominfo.getDomid(),
                                          dominfo.getWeight(),
                                          dominfo.getCap())
@@ -950,7 +943,6 @@ class XendDomain:
                                  POWER_STATE_NAMES[dominfo.state])
             
             dominfo.start(is_managed = True)
-            self._add_domain(dominfo)
         finally:
             self.domains_lock.release()
         dominfo.waitForDevices()
@@ -983,7 +975,7 @@ class XendDomain:
                          (dominfo.getName(), dominfo.info.get('uuid')))
 
                 self._managed_domain_unregister(dominfo)
-                self._remove_domain(dominfo)
+                self.remove_domain(dominfo)
                 XendDevices.destroy_device_state(dominfo)
             except Exception, ex:
                 raise XendError(str(ex))
diff -r 51ff40839470 -r 5f998c3170f7 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Jan 22 11:49:11 2007 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Jan 22 11:49:14 2007 +0000
@@ -41,7 +41,7 @@ from xen.xend import XendOptions, XendNo
 from xen.xend import XendOptions, XendNode, XendConfig
 
 from xen.xend.XendConfig import scrub_password
-from xen.xend.XendBootloader import bootloader
+from xen.xend.XendBootloader import bootloader, bootloader_tidy
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendDevices import XendDevices
 from xen.xend.xenstore.xstransact import xstransact, complete
@@ -101,7 +101,6 @@ def create_from_dict(config_dict):
         log.exception('Domain construction failed')
         vm.destroy()
         raise
-
     return vm
 
 def recreate(info, priv):
@@ -187,6 +186,11 @@ def recreate(info, priv):
 
     vm._registerWatches()
     vm.refreshShutdown(xeninfo)
+
+    # register the domain in the list 
+    from xen.xend import XendDomain
+    XendDomain.instance().add_domain(vm)
+
     return vm
 
 
@@ -1338,6 +1342,9 @@ class XendDomainInfo:
         # Set maximum number of vcpus in domain
         xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
 
+        # register the domain in the list 
+        from xen.xend import XendDomain
+        XendDomain.instance().add_domain(self)
 
     def _introduceDomain(self):
         assert self.domid is not None
@@ -1436,6 +1443,7 @@ class XendDomainInfo:
         try:
             self.unwatchShutdown()
             self._releaseDevices()
+            bootloader_tidy(self)
 
             if self.image:
                 try:
@@ -1536,6 +1544,9 @@ class XendDomainInfo:
         except:
             log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
 
+        from xen.xend import XendDomain
+        XendDomain.instance().remove_domain(self)
+
         self.cleanupDomain()
 
 
@@ -1631,7 +1642,7 @@ class XendDomainInfo:
                     fn = BOOTLOADER_LOOPBACK_DEVICE
 
                 try:
-                    blcfg = bootloader(blexec, fn, True,
+                    blcfg = bootloader(blexec, fn, self, False,
                                        bootloader_args, kernel, ramdisk, args)
                 finally:
                     if mounted:
diff -r 51ff40839470 -r 5f998c3170f7 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Mon Jan 22 11:49:11 2007 +0000
+++ b/tools/python/xen/xm/create.py     Mon Jan 22 11:49:14 2007 +0000
@@ -24,6 +24,7 @@ import sys
 import sys
 import socket
 import re
+import time
 import xmlrpclib
 
 from xen.xend import sxp
@@ -709,26 +710,6 @@ def configure_hvm(config_image, vals):
             config_image.append([a, vals.__dict__[a]])
     config_image.append(['vncpasswd', vals.vncpasswd])
 
-def run_bootloader(vals, config_image):
-    if not os.access(vals.bootloader, os.F_OK):
-        err("Bootloader '%s' does not exist" % vals.bootloader)
-    if not os.access(vals.bootloader, os.X_OK):
-        err("Bootloader '%s' isn't executable" % vals.bootloader)
-    if len(vals.disk) < 1:
-        err("No disks configured and boot loader requested")
-    (uname, dev, mode, backend) = vals.disk[0]
-    file = blkif.blkdev_uname_to_file(uname)
-
-    if vals.bootentry:
-        warn("The bootentry option is deprecated.  Use bootargs and pass "
-             "--entry= directly.")
-        vals.bootargs = "--entry=%s" %(vals.bootentry,)
-
-    kernel = sxp.child_value(config_image, 'kernel')
-    ramdisk = sxp.child_value(config_image, 'ramdisk')
-    args = sxp.child_value(config_image, 'args')
-    return bootloader(vals.bootloader, file, not vals.console_autoconnect,
-                      vals.bootargs, kernel, ramdisk, args)
 
 def make_config(vals):
     """Create the domain configuration.
@@ -771,14 +752,11 @@ def make_config(vals):
         if vals.bootloader == "pygrub":
             vals.bootloader = osdep.pygrub_path
 
-        # if a kernel is specified, we're using the bootloader
-        # non-interactively, and need to let xend run it so we preserve the
-        # real kernel choice.
-        if not vals.kernel:
-            config_image = run_bootloader(vals, config_image)
         config.append(['bootloader', vals.bootloader])
         if vals.bootargs:
             config.append(['bootloader_args', vals.bootargs])
+        else: 
+            config.append(['bootloader_args', '-q'])        
     config.append(['image', config_image])
 
     config_devs = []
@@ -1266,9 +1244,28 @@ def main(argv):
         if not create_security_check(config):
             raise security.ACMError('Security Configuration prevents domain 
from starting')
         else:
+            if opts.vals.console_autoconnect:
+                cpid = os.fork() 
+                if cpid != 0:
+                    for i in range(10):
+                        # Catch failure of the create process 
+                        time.sleep(1)
+                        (p, rv) = os.waitpid(cpid, os.WNOHANG)
+                        if os.WIFEXITED(rv):
+                            if os.WEXITSTATUS(rv) != 0:
+                                sys.exit(os.WEXITSTATUS(rv))
+                        try:
+                            # Acquire the console of the created dom
+                            name = sxp.child_value(config, 'name', -1)
+                            dom = server.xend.domain(name)
+                            domid = int(sxp.child_value(dom, 'domid', '-1'))
+                            console.execConsole(domid)
+                        except:
+                            pass
+                    print("Could not start console\n");
+                    sys.exit(0)
             dom = make_domain(opts, config)
-            if opts.vals.console_autoconnect:
-                console.execConsole(dom)        
-             
+
+
 if __name__ == '__main__':
     main(sys.argv)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [PYGRUB] Plumb bootloader I/O through xenconsole., Xen patchbot-unstable <=