direct-io.hg

changeset 1204:5f1ec88d7c3a

bitkeeper revision 1.815 (405ed20aUPuCpxY9bW6IV5l8ztG3Og)

console.c, console_client.py, Xeno-HOWTO.txt, README.CD:
Many console fixes.
author kaf24@scramble.cl.cam.ac.uk
date Mon Mar 22 11:46:18 2004 +0000 (2004-03-22)
parents 416921d3ed45
children 38b05d6c12f5
files README.CD docs/Xeno-HOWTO.txt tools/xenctl/lib/console_client.py xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c
line diff
     1.1 --- a/README.CD	Mon Mar 22 08:05:03 2004 +0000
     1.2 +++ b/README.CD	Mon Mar 22 11:46:18 2004 +0000
     1.3 @@ -536,19 +536,24 @@ given direct access to the graphics card
     1.4  console. Other domains don't have ttyN consoles, so attempts to run a
     1.5  'mingetty' against them will fail, generating periodic warning
     1.6  messages from 'init' about services respawning too fast. They should
     1.7 -work for domain0 just fine.
     1.8 -
     1.9 -In future, we may make the current 'xencons' accept input as well as
    1.10 -output, so that a getty can be run against it. In the meantime, other
    1.11 -domains don't have a console suitable for logging in on, so you'll
    1.12 -have to run sshd and ssh in to them.
    1.13 +work for domain0 just fine.  
    1.14 +IMPORTANT: To prevent warning messages when running RH9 you'll need to
    1.15 +remove ttyN from /etc/inittab for domains>0.  Due to a bug in the RH9
    1.16 +/etc/rc.sysinit script #'ing the lines out of /etc/inittab won't work
    1.17 +as it ignores the '#' and tries to access them anyway.
    1.18  
    1.19 -To prevent the warning messages you'll need to remove them from
    1.20 -/etc/inittab for domains>0.  Due to a bug in the RH9 /etc/rc.sysinit
    1.21 -script #'ing the lines out of /etc/inittab won't work as it ignores
    1.22 -the '#' and tries to access them anyway.
    1.23 +Every Xenolinux instance owns a bidirectional 'virtual
    1.24 +console'. Boot-time output can be directed to this console by
    1.25 +specifying 'console=xencons0' as a boot parameter. It is also possible
    1.26 +to log in via the virtual console. To do this, you must run a mingetty
    1.27 +on the virtual console, which you can achieve as follows:
    1.28 + # mkdir -p /dev/xen
    1.29 + # mknod /dev/xen/cons c 4 123
    1.30 + # echo "c:2345:respawn:/sbin/mingetty --noclear xen/cons" >>/etc/inittab
    1.31 +If you wish to permit root logins via the virtual console then you must
    1.32 +also add 'xen/cons' to the list of trusted ttys in /etc/securetty.
    1.33  
    1.34 -Also, because domains>0 don't have any privileged access at all,
    1.35 +Note that, because domains>0 don't have any privileged access at all,
    1.36  certain commands in the default boot sequence will fail e.g. attempts
    1.37  to update the hwclock, change the console font, update the keytable
    1.38  map, start apmd (power management), or gpm (mouse cursor).  Either
     2.1 --- a/docs/Xeno-HOWTO.txt	Mon Mar 22 08:05:03 2004 +0000
     2.2 +++ b/docs/Xeno-HOWTO.txt	Mon Mar 22 11:46:18 2004 +0000
     2.3 @@ -272,6 +272,16 @@ session. An alternative is to specify '-
     2.4  xc_dom_create.py to automatically become teh console terminal after
     2.5  starting the domain.
     2.6  
     2.7 +Boot-time output can be directed to this 'virtual console' by
     2.8 +specifying 'console=xencons0' as a boot parameter. It is also possible
     2.9 +to log in via the virtual console. To do this, you must run a mingetty
    2.10 +on the virtual console, which you can achieve as follows:
    2.11 + # mkdir -p /dev/xen
    2.12 + # mknod /dev/xen/cons c 4 123
    2.13 + # echo "c:2345:respawn:/sbin/mingetty --noclear xen/cons" >>/etc/inittab
    2.14 +If you wish to permit root logins via the virtual console then you must
    2.15 +also add 'xen/cons' to the list of trusted ttys in /etc/securetty.
    2.16 +
    2.17  
    2.18  Manage Running Domains
    2.19  ==============================
     3.1 --- a/tools/xenctl/lib/console_client.py	Mon Mar 22 08:05:03 2004 +0000
     3.2 +++ b/tools/xenctl/lib/console_client.py	Mon Mar 22 11:46:18 2004 +0000
     3.3 @@ -38,7 +38,13 @@ def __send_to_sock(sock):
     3.4          data = os.read(0,1)
     3.5          if ord(data[0]) == ord(']')-64:
     3.6              break
     3.7 -        sock.send(data)
     3.8 +        try:
     3.9 +            sock.send(data)
    3.10 +        except socket.error, error:
    3.11 +            if error[0] == errno.EPIPE:
    3.12 +                sys.exit(0)
    3.13 +            if error[0] != errno.EINTR:
    3.14 +                raise
    3.15      sys.exit(0)
    3.16  
    3.17  def connect(host,port):
    3.18 @@ -69,6 +75,7 @@ def connect(host,port):
    3.19              print
    3.20              print "************ REMOTE CONSOLE EXITED *****************"
    3.21      else:
    3.22 +        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
    3.23          __send_to_sock(sock)
    3.24  
    3.25  if __name__ == '__main__':
     4.1 --- a/xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c	Mon Mar 22 08:05:03 2004 +0000
     4.2 +++ b/xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c	Mon Mar 22 11:46:18 2004 +0000
     4.3 @@ -151,7 +151,6 @@ static struct tty_struct *xeno_console_t
     4.4  static struct termios *xeno_console_termios[1];
     4.5  static struct termios *xeno_console_termios_locked[1];
     4.6  static struct tty_struct *xeno_console_tty;
     4.7 -static int xeno_console_use_count;
     4.8  
     4.9  #define WBUF_SIZE     1024
    4.10  #define WBUF_MASK(_i) ((_i)&(WBUF_SIZE-1))
    4.11 @@ -164,7 +163,7 @@ static void __do_console_io(void)
    4.12      control_msg_t   *msg;
    4.13      evtchn_op_t      evtchn_op;
    4.14      CONTROL_RING_IDX c;
    4.15 -    int              i, len, work_done = 0;
    4.16 +    int              i, l, work_done = 0;
    4.17      static char      rbuf[16];
    4.18  
    4.19      if ( xeno_console_tty == NULL )
    4.20 @@ -174,20 +173,24 @@ static void __do_console_io(void)
    4.21      if ( start_info.flags & SIF_INITDOMAIN )
    4.22      {
    4.23          /* Receive work. */
    4.24 -        while ( (len = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0 )
    4.25 -            for ( i = 0; i < len; i++ )
    4.26 +        while ( (l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0 )
    4.27 +            for ( i = 0; i < l; i++ )
    4.28                  tty_insert_flip_char(xeno_console_tty, rbuf[i], 0);
    4.29          if ( xeno_console_tty->flip.count != 0 )
    4.30              tty_flip_buffer_push(xeno_console_tty);
    4.31  
    4.32          /* Transmit work. */
    4.33 -        if ( wc != wp )
    4.34 +        while ( wc != wp )
    4.35          {
    4.36 -            len = wp - wc;
    4.37 -            if ( len > (WBUF_SIZE - WBUF_MASK(wc)) )
    4.38 -                len = WBUF_SIZE - WBUF_MASK(wc);
    4.39 -            priv_conwrite(&wbuf[WBUF_MASK(wc)], len);
    4.40 -            wc += len;
    4.41 +            l = wp - wc;
    4.42 +            if ( l > (WBUF_SIZE - WBUF_MASK(wc)) )
    4.43 +                l = WBUF_SIZE - WBUF_MASK(wc);
    4.44 +            priv_conwrite(&wbuf[WBUF_MASK(wc)], l);
    4.45 +            wc += l;
    4.46 +            wake_up_interruptible(&xeno_console_tty->write_wait);
    4.47 +            if ( (xeno_console_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
    4.48 +                 (xeno_console_tty->ldisc.write_wakeup != NULL) )
    4.49 +                (xeno_console_tty->ldisc.write_wakeup)(xeno_console_tty);
    4.50          }
    4.51  
    4.52          return;
    4.53 @@ -228,32 +231,33 @@ static void __do_console_io(void)
    4.54          msg->type    = CMSG_CONSOLE;
    4.55          msg->subtype = CMSG_CONSOLE_DATA;
    4.56          msg->id      = 0xaa;
    4.57 -        len = 0;
    4.58 +        l = 0;
    4.59          if ( x_char != 0 ) /* Handle XON/XOFF urgently. */
    4.60          {
    4.61 -            msg->msg[len++] = x_char;
    4.62 +            msg->msg[l++] = x_char;
    4.63              x_char = 0;
    4.64          }
    4.65 -        while ( (len < sizeof(msg->msg)) && (wc != wp) )
    4.66 -            msg->msg[len++] = wbuf[WBUF_MASK(wc++)];
    4.67 -        msg->length = len;
    4.68 +        while ( (l < sizeof(msg->msg)) && (wc != wp) )
    4.69 +            msg->msg[l++] = wbuf[WBUF_MASK(wc++)];
    4.70 +        msg->length = l;
    4.71      }
    4.72      if ( ctrl_if->tx_req_prod != c )
    4.73      {
    4.74          ctrl_if->tx_req_prod = c;
    4.75          work_done = 1;
    4.76 +        /* There might be something for waiters to do. */
    4.77 +        wake_up_interruptible(&xeno_console_tty->write_wait);
    4.78 +        if ( (xeno_console_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
    4.79 +             (xeno_console_tty->ldisc.write_wakeup != NULL) )
    4.80 +            (xeno_console_tty->ldisc.write_wakeup)(xeno_console_tty);
    4.81      }
    4.82 -        
    4.83 +
    4.84      if ( work_done )
    4.85      {
    4.86          /* Send a notification to the controller. */
    4.87          evtchn_op.cmd = EVTCHNOP_send;
    4.88          evtchn_op.u.send.local_port = 0;
    4.89          (void)HYPERVISOR_event_channel_op(&evtchn_op);
    4.90 -
    4.91 -        /* There might be something for waiters to do. */
    4.92 -        if ( xeno_console_tty != NULL )
    4.93 -            wake_up_interruptible(&xeno_console_tty->write_wait);
    4.94      }
    4.95  }
    4.96  
    4.97 @@ -374,35 +378,64 @@ static void xeno_console_flush_chars(str
    4.98      spin_unlock_irqrestore(&xeno_console_lock, flags);    
    4.99  }
   4.100  
   4.101 +static void xeno_console_wait_until_sent(struct tty_struct *tty, int timeout)
   4.102 +{
   4.103 +    unsigned long orig_jiffies = jiffies;
   4.104 +
   4.105 +    while ( tty->driver.chars_in_buffer(tty) )
   4.106 +    {
   4.107 +        set_current_state(TASK_INTERRUPTIBLE);
   4.108 +        schedule_timeout(1);
   4.109 +        if ( signal_pending(current) )
   4.110 +            break;
   4.111 +        if ( (timeout != 0) && time_after(jiffies, orig_jiffies + timeout) )
   4.112 +            break;
   4.113 +    }
   4.114 +    
   4.115 +    set_current_state(TASK_RUNNING);
   4.116 +}
   4.117 +
   4.118  static int xeno_console_open(struct tty_struct *tty, struct file *filp)
   4.119  {
   4.120      int line;
   4.121 +    unsigned long flags;
   4.122  
   4.123      MOD_INC_USE_COUNT;
   4.124      line = MINOR(tty->device) - tty->driver.minor_start;
   4.125 -    if ( line )
   4.126 +    if ( line != 0 )
   4.127      {
   4.128          MOD_DEC_USE_COUNT;
   4.129          return -ENODEV;
   4.130      }
   4.131  
   4.132 +    spin_lock_irqsave(&xeno_console_lock, flags);
   4.133      tty->driver_data = NULL;
   4.134      if ( xeno_console_tty == NULL )
   4.135 -    {
   4.136          xeno_console_tty = tty;
   4.137 -        wc = wp = 0;
   4.138 -        __do_console_io();
   4.139 -    }
   4.140 -
   4.141 -    xeno_console_use_count++;
   4.142 +    __do_console_io();
   4.143 +    spin_unlock_irqrestore(&xeno_console_lock, flags);    
   4.144  
   4.145      return 0;
   4.146  }
   4.147  
   4.148  static void xeno_console_close(struct tty_struct *tty, struct file *filp)
   4.149  {
   4.150 -    if ( --xeno_console_use_count == 0 )
   4.151 +    unsigned long flags;
   4.152 +
   4.153 +    if ( tty->count == 1 )
   4.154 +    {
   4.155 +        tty->closing = 1;
   4.156 +        tty_wait_until_sent(tty, 0);
   4.157 +        if ( tty->driver.flush_buffer != NULL )
   4.158 +            tty->driver.flush_buffer(tty);
   4.159 +        if ( tty->ldisc.flush_buffer != NULL )
   4.160 +            tty->ldisc.flush_buffer(tty);
   4.161 +        tty->closing = 0;
   4.162 +        spin_lock_irqsave(&xeno_console_lock, flags);
   4.163          xeno_console_tty = NULL;
   4.164 +        spin_unlock_irqrestore(&xeno_console_lock, flags);    
   4.165 +    }
   4.166 +
   4.167      MOD_DEC_USE_COUNT;
   4.168  }
   4.169  
   4.170 @@ -417,7 +450,8 @@ int __init xeno_con_init(void)
   4.171      xeno_console_driver.type            = TTY_DRIVER_TYPE_SERIAL;
   4.172      xeno_console_driver.subtype         = SERIAL_TYPE_NORMAL;
   4.173      xeno_console_driver.init_termios    = tty_std_termios;
   4.174 -    xeno_console_driver.flags           = TTY_DRIVER_REAL_RAW;
   4.175 +    xeno_console_driver.flags           = 
   4.176 +        TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS;
   4.177      xeno_console_driver.refcount        = &xeno_console_refcount;
   4.178      xeno_console_driver.table           = xeno_console_table;
   4.179      xeno_console_driver.termios         = xeno_console_termios;
   4.180 @@ -434,6 +468,7 @@ int __init xeno_con_init(void)
   4.181      xeno_console_driver.flush_buffer    = xeno_console_flush_buffer;
   4.182      xeno_console_driver.throttle        = xeno_console_throttle;
   4.183      xeno_console_driver.unthrottle      = xeno_console_unthrottle;
   4.184 +    xeno_console_driver.wait_until_sent = xeno_console_wait_until_sent;
   4.185  
   4.186      if ( tty_register_driver(&xeno_console_driver) )
   4.187          panic("Couldn't register Xeno console driver\n");