ia64/xen-unstable

changeset 2407:f406a0f99a84

bitkeeper revision 1.1159.68.1 (41373ddcTLdrlPC1j7y6wwqeJNMnzw)

Get xend to start xfrd. Remove some dead code.
author mjw@wray-m-3.hpl.hp.com
date Thu Sep 02 15:35:56 2004 +0000 (2004-09-02)
parents 9dfa683873c2
children 46918bf8df85 ccdb04941d97 24dd2dc4a142
files tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/params.py tools/xfrd/xfrd.c
line diff
     1.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Thu Sep 02 13:58:04 2004 +0000
     1.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Thu Sep 02 15:35:56 2004 +0000
     1.3 @@ -23,7 +23,6 @@ from twisted.internet import reactor
     1.4  from twisted.internet import protocol
     1.5  from twisted.internet import abstract
     1.6  from twisted.internet import defer
     1.7 -#defer.Deferred.debug = 1
     1.8  
     1.9  from xen.lowlevel import xu
    1.10  
    1.11 @@ -45,127 +44,6 @@ from params import *
    1.12  
    1.13  DEBUG = 1
    1.14  
    1.15 -class MgmtProtocol(protocol.DatagramProtocol):
    1.16 -    """Handler for the management socket (unix-domain).
    1.17 -    """
    1.18 -
    1.19 -    def __init__(self, daemon):
    1.20 -        #protocol.DatagramProtocol.__init__(self)
    1.21 -        self.daemon = daemon
    1.22 -    
    1.23 -    def write(self, data, addr):
    1.24 -        return self.transport.write(data, addr)
    1.25 -
    1.26 -    def datagramReceived(self, data, addr):
    1.27 -        if DEBUG: print 'datagramReceived> addr=', addr, 'data=', data
    1.28 -        io = StringIO.StringIO(data)
    1.29 -        try:
    1.30 -            vals = sxp.parse(io)
    1.31 -            res = self.dispatch(vals[0])
    1.32 -            self.send_result(addr, res)
    1.33 -        except SystemExit:
    1.34 -            raise
    1.35 -        except:
    1.36 -            if DEBUG:
    1.37 -                raise
    1.38 -            else:
    1.39 -                self.send_error(addr)
    1.40 -
    1.41 -    def send_reply(self, addr, sxpr):
    1.42 -        io = StringIO.StringIO()
    1.43 -        sxp.show(sxpr, out=io)
    1.44 -        io.seek(0)
    1.45 -        self.write(io.getvalue(), addr)
    1.46 -
    1.47 -    def send_result(self, addr, res):
    1.48 -        
    1.49 -        def fn(res, self=self, addr=addr):
    1.50 -            self.send_reply(addr, ['ok', res])
    1.51 -            
    1.52 -        if isinstance(res, defer.Deferred):
    1.53 -            res.addCallback(fn)
    1.54 -        else:
    1.55 -            fn(res)
    1.56 -
    1.57 -    def send_error(self, addr):
    1.58 -        (extype, exval) = sys.exc_info()[:2]
    1.59 -        self.send_reply(addr, ['err',
    1.60 -                               ['type',  str(extype) ],
    1.61 -                               ['value', str(exval)  ] ] )
    1.62 -
    1.63 -    def opname(self, name):
    1.64 -        """Get the name of the method for an operation.
    1.65 -        """
    1.66 -        return 'op_' + name.replace('.', '_')
    1.67 -
    1.68 -    def operror(self, name, v):
    1.69 -        """Default operation handler - signals an error.
    1.70 -        """
    1.71 -        raise NotImplementedError('Invalid operation: ' +name)
    1.72 -
    1.73 -    def dispatch(self, req):
    1.74 -        """Dispatch a request to its handler.
    1.75 -        """
    1.76 -        op_name = sxp.name(req)
    1.77 -        op_method_name = self.opname(op_name)
    1.78 -        op_method = getattr(self, op_method_name, self.operror)
    1.79 -        return op_method(op_name, req)
    1.80 -
    1.81 -    def op_console_create(self, name, req):
    1.82 -        """Create a new control interface - console for a domain.
    1.83 -        """
    1.84 -        print name, req
    1.85 -        dom = sxp.child_value(req, 'domain')
    1.86 -        if not dom: raise XendError('Missing domain')
    1.87 -        dom = int(dom)
    1.88 -        console_port = sxp.child_value(req, 'console_port')
    1.89 -        if console_port:
    1.90 -            console_port = int(console_port)
    1.91 -        resp = self.daemon.console_create(dom, console_port).sxpr()
    1.92 -        print name, resp
    1.93 -        return resp
    1.94 -
    1.95 -    def op_consoles(self, name, req):
    1.96 -        """Get a list of the consoles.
    1.97 -        """
    1.98 -        return self.daemon.consoles()
    1.99 -
   1.100 -    def op_console_disconnect(self, name, req):
   1.101 -        id = sxp.child_value(req, 'id')
   1.102 -        if not id:
   1.103 -            raise XendError('Missing console id')
   1.104 -        id = int(id)
   1.105 -        console = self.daemon.get_console(id)
   1.106 -        if not console:
   1.107 -            raise XendError('Invalid console id')
   1.108 -        if console.conn:
   1.109 -            console.conn.loseConnection()
   1.110 -        return ['ok']
   1.111 -
   1.112 -    def op_blkifs(self, name, req):
   1.113 -        pass
   1.114 -    
   1.115 -    def op_blkif_devs(self, name, req):
   1.116 -        pass
   1.117 -
   1.118 -    def op_blkif_create(self, name, req):
   1.119 -        pass
   1.120 -    
   1.121 -    def op_blkif_dev_create(self, name, req):
   1.122 -        pass
   1.123 -
   1.124 -    def op_netifs(self, name, req):
   1.125 -        pass
   1.126 -
   1.127 -    def op_netif_devs(self, name, req):
   1.128 -        pass
   1.129 -
   1.130 -    def op_netif_create(self, name, req):
   1.131 -        pass
   1.132 -
   1.133 -    def op_netif_dev_create(self, name, req):
   1.134 -        pass
   1.135 -
   1.136  class NotifierProtocol(protocol.Protocol):
   1.137      """Asynchronous handler for i/o on the notifier (event channel).
   1.138      """
   1.139 @@ -245,17 +123,14 @@ class NotifierPort(abstract.FileDescript
   1.140              del self.d
   1.141          
   1.142      def doRead(self):
   1.143 -        #print 'NotifierPort>doRead>', self
   1.144          count = 0
   1.145          while 1:            
   1.146 -            #print 'NotifierPort>doRead>', count
   1.147              notification = self.notifier.read()
   1.148              if not notification:
   1.149                  break
   1.150              self.protocol.notificationReceived(notification)
   1.151              self.notifier.unmask(notification)
   1.152              count += 1
   1.153 -        #print 'NotifierPort>doRead<'
   1.154  
   1.155  class EventProtocol(protocol.Protocol):
   1.156      """Asynchronous handler for a connected event socket.
   1.157 @@ -481,25 +356,69 @@ class Daemon:
   1.158              err = 1
   1.159              print "Daemon already running: ", pids
   1.160          return err
   1.161 -            
   1.162 +
   1.163 +    def read_pid(self, pidfile):
   1.164 +        """Read process id from a file.
   1.165 +
   1.166 +        @param pidfile: file to read
   1.167 +        @return pid or 0
   1.168 +        """
   1.169 +        pid = 0
   1.170 +        if os.path.isfile(pidfile) and os.path.getsize(pidfile):
   1.171 +            try:
   1.172 +                pid = open(pidfile, 'r').read()
   1.173 +                pid = int(pid)
   1.174 +            except:
   1.175 +                pid = 0
   1.176 +        return pid
   1.177 +
   1.178 +    def find_process(self, pid, name):
   1.179 +        """Search for a process.
   1.180 +
   1.181 +        @param pid: process id
   1.182 +        @param name: process name
   1.183 +        @return: pid if found, 0 otherwise
   1.184 +        """
   1.185 +        running = 0
   1.186 +        if pid:
   1.187 +            lines = os.popen('ps %d 2>/dev/null' % pid).readlines()
   1.188 +            exp = '^ *%d.+%s' % (pid, name)
   1.189 +            for line in lines:
   1.190 +                if re.search(exp, line):
   1.191 +                    running = pid
   1.192 +                    break
   1.193 +        return running
   1.194 +
   1.195 +    def cleanup_process(self, pidfile, name, kill):
   1.196 +        """Clean up the pidfile for a process.
   1.197 +        If a running process is found, kills it if 'kill' is true.
   1.198 +
   1.199 +        @param pidfile: pid file
   1.200 +        @param name: process name
   1.201 +        @param kill: whether to kill the process
   1.202 +        @return running process id or 0
   1.203 +        """
   1.204 +        running = 0
   1.205 +        pid = self.read_pid(pidfile)
   1.206 +        if self.find_process(pid, name):
   1.207 +            if kill:
   1.208 +                os.kill(pid, 1)
   1.209 +            else:
   1.210 +                running = pid
   1.211 +        if running == 0 and os.path.isfile(pidfile):
   1.212 +            os.remove(pidfile)
   1.213 +        return running
   1.214 +
   1.215 +    def cleanup_xend(self, kill=False):
   1.216 +        return self.cleanup_process(XEND_PID_FILE, "xend", kill)
   1.217 +
   1.218 +    def cleanup_xfrd(self, kill=False):
   1.219 +        return self.cleanup_process(XFRD_PID_FILE, "xfrd", kill)
   1.220 +
   1.221      def cleanup(self, kill=False):
   1.222 -        # No cleanup to do if PID_FILE is empty.
   1.223 -        if not os.path.isfile(PID_FILE) or not os.path.getsize(PID_FILE):
   1.224 -            return 0
   1.225 -        # Read the pid of the previous invocation and search active process list.
   1.226 -        pid = open(PID_FILE, 'r').read()
   1.227 -        lines = os.popen('ps ' + pid + ' 2>/dev/null').readlines()
   1.228 -        for line in lines:
   1.229 -            if re.search('^ *' + pid + '.+xend', line):
   1.230 -                if not kill:
   1.231 -                    print "Daemon is already running (pid %d)" % int(pid)
   1.232 -                    return 1
   1.233 -                # Old daemon is still active: terminate it.
   1.234 -                os.kill(int(pid), 1)
   1.235 -        # Delete the stale PID_FILE.
   1.236 -        os.remove(PID_FILE)
   1.237 -        return 0
   1.238 -
   1.239 +        self.cleanup_xend(kill=kill)
   1.240 +        self.cleanup_xfrd(kill=kill)
   1.241 +            
   1.242      def install_child_reaper(self):
   1.243          #signal.signal(signal.SIGCHLD, self.onSIGCHLD)
   1.244          # Ensure that zombie children are automatically reaped.
   1.245 @@ -510,42 +429,65 @@ class Daemon:
   1.246          while code > 0:
   1.247              code = os.waitpid(-1, os.WNOHANG)
   1.248  
   1.249 +    def fork_pid(self, pidfile):
   1.250 +        """Fork and write the pid of the child to 'pidfile'.
   1.251 +
   1.252 +        @param pidfile: pid file
   1.253 +        @return: pid of child in parent, 0 in child
   1.254 +        """
   1.255 +        pid = os.fork()
   1.256 +        if pid:
   1.257 +            # Parent
   1.258 +            pidfile = open(pidfile, 'w')
   1.259 +            pidfile.write(str(pid))
   1.260 +            pidfile.close()
   1.261 +        return pid
   1.262 +
   1.263 +    def start_xfrd(self):
   1.264 +        """Fork and exec xfrd, writing its pid to XFRD_PID_FILE.
   1.265 +        """
   1.266 +        if self.fork_pid(XFRD_PID_FILE):
   1.267 +            # Parent
   1.268 +            pass
   1.269 +        else:
   1.270 +            # Child
   1.271 +            self.set_user()
   1.272 +            os.execl("/usr/sbin/xfrd", "xfrd")
   1.273 +            
   1.274      def start(self, trace=0):
   1.275 -        if self.cleanup(kill=False):
   1.276 +        xend_pid = self.cleanup_xend()
   1.277 +        xfrd_pid = self.cleanup_xfrd()
   1.278 +        if xfrd_pid == 0:
   1.279 +            self.start_xfrd()
   1.280 +        if xend_pid > 0:
   1.281              return 1
   1.282  
   1.283          # Detach from TTY.
   1.284          if not DEBUG:
   1.285              os.setsid()
   1.286 -
   1.287          if self.set_user():
   1.288              return 1
   1.289 -
   1.290          self.install_child_reaper()
   1.291  
   1.292 -        # Fork -- parent writes PID_FILE and exits.
   1.293 -        pid = os.fork()
   1.294 -        if pid:
   1.295 -            # Parent
   1.296 -            pidfile = open(PID_FILE, 'w')
   1.297 -            pidfile.write(str(pid))
   1.298 -            pidfile.close()
   1.299 -            return 0
   1.300 -        # Child
   1.301 -        self.tracing(trace)
   1.302 -        self.run()
   1.303 +        if self.fork_pid(XEND_PID_FILE):
   1.304 +            #Parent
   1.305 +            pass
   1.306 +        else:
   1.307 +            # Child
   1.308 +            self.tracing(trace)
   1.309 +            self.run()
   1.310          return 0
   1.311  
   1.312      def tracing(self, traceon):
   1.313          """Turn tracing on or off.
   1.314  
   1.315 -        traceon tracing flag
   1.316 +        @param traceon: tracing flag
   1.317          """
   1.318          if traceon == self.traceon:
   1.319              return
   1.320          self.traceon = traceon
   1.321          if traceon:
   1.322 -            self.tracefile = open('/var/log/xend.trace', 'w+', 1)
   1.323 +            self.tracefile = open(XEND_TRACE_FILE, 'w+', 1)
   1.324              self.traceindent = 0
   1.325              sys.settrace(self.trace)
   1.326              try:
   1.327 @@ -620,7 +562,6 @@ class Daemon:
   1.328          xroot = XendRoot.instance()
   1.329          log.info("Xend Daemon started")
   1.330          self.createFactories()
   1.331 -        self.listenMgmt()
   1.332          self.listenEvent()
   1.333          self.listenNotifier()
   1.334          self.listenVirq()
   1.335 @@ -634,13 +575,6 @@ class Daemon:
   1.336          self.netifCF = netif.NetifControllerFactory()
   1.337          self.consoleCF = console.ConsoleControllerFactory()
   1.338  
   1.339 -    def listenMgmt(self):
   1.340 -        protocol = MgmtProtocol(self)
   1.341 -        s = os.path.join(CONTROL_DIR, MGMT_SOCK)
   1.342 -        if os.path.exists(s):
   1.343 -            os.unlink(s)
   1.344 -        return reactor.listenUNIXDatagram(s, protocol)
   1.345 -
   1.346      def listenEvent(self):
   1.347          protocol = EventFactory(self)
   1.348          return reactor.listenTCP(EVENT_PORT, protocol)
   1.349 @@ -656,7 +590,7 @@ class Daemon:
   1.350          virqChan.registerClient(VirqClient(self))
   1.351  
   1.352      def exit(self):
   1.353 -        reactor.diconnectAll()
   1.354 +        reactor.disconnectAll()
   1.355          sys.exit(0)
   1.356  
   1.357      def getDomChannel(self, dom):
     2.1 --- a/tools/python/xen/xend/server/params.py	Thu Sep 02 13:58:04 2004 +0000
     2.2 +++ b/tools/python/xen/xend/server/params.py	Thu Sep 02 15:35:56 2004 +0000
     2.3 @@ -1,8 +1,10 @@
     2.4  # The following parameters could be placed in a configuration file.
     2.5 -PID_FILE  = '/var/run/xend.pid'
     2.6 +XEND_PID_FILE = '/var/run/xend.pid'
     2.7 +XFRD_PID_FILE = '/var/run/xfrd.pid'
     2.8 +XEND_TRACE_FILE = '/var/log/xend.trace'
     2.9 +
    2.10  USER = 'root'
    2.11 -CONTROL_DIR  = '/var/run/xend'
    2.12 -MGMT_SOCK    = 'xendsock' # relative to CONTROL_DIR
    2.13 +
    2.14  EVENT_PORT = 8001
    2.15  
    2.16  CONSOLE_PORT_BASE = 9600
     3.1 --- a/tools/xfrd/xfrd.c	Thu Sep 02 13:58:04 2004 +0000
     3.2 +++ b/tools/xfrd/xfrd.c	Thu Sep 02 15:35:56 2004 +0000
     3.3 @@ -50,6 +50,7 @@
     3.4  
     3.5  #define MODULE_NAME "XFRD"
     3.6  #define DEBUG 0
     3.7 +#undef DEBUG
     3.8  #include "debug.h"
     3.9  
    3.10  /*
    3.11 @@ -1142,7 +1143,11 @@ int main(int argc, char *argv[]){
    3.12      int err = 0;
    3.13      int key = 0;
    3.14      int long_index = 0;
    3.15 +    static const char * LOGFILE = "/var/log/xfrd.log";
    3.16  
    3.17 +    freopen(LOGFILE, "w+", stdout);
    3.18 +    fclose(stderr);
    3.19 +    stderr = stdout;
    3.20      dprintf(">\n");
    3.21      set_defaults(args);
    3.22      while(1){