#!/usr/bin/python
#  -*- mode: python; -*-
#============================================================================
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005-2006 XenSource Inc
#============================================================================

"""Xen management daemon.
   Provides console server and HTTP management api.

   Run:
   xend start

   Restart:
   xend restart

   The daemon is stopped with:
   xend stop

   The daemon should reconnect to device control interfaces
   and recover its state when restarted.
"""
import fcntl
import glob
import os
import os.path
import sys
import socket
import signal
import time
import commands


# Use the auxbin module in Xend to determine the correct Python path.  We
# take the first installed instance of auxbin that we find, and then run it
# to determine the correct path, appending that to sys.path.

AUXBIN = 'xen/util/auxbin.py'

for p in ['python%s' % sys.version[:3], 'python']:
    for l in ['/usr/lib64', '/usr/lib']:
        d = os.path.join(l, p)
        if os.path.exists(os.path.join(d, AUXBIN)):
            sys.path.append(d)
            import xen.util.auxbin
            libpath = xen.util.auxbin.libpath()
            sys.path = sys.path[:-1]
            sys.path.append(libpath)
            break

from xen.xend.server import SrvDaemon

class CheckError(ValueError):
    pass

def hline():
    print >>sys.stderr, "*" * 70

def msg(message):
    print >>sys.stderr, "*" * 3, message

def check_logging():
    """Check python logging is installed and raise an error if not.
    Logging is standard from Python 2.3 on.
    """
    try:
        import logging
    except ImportError:
        hline()
        msg("Python logging is not installed.")
        msg("Use 'make install-logging' at the xen root to install.")
        msg("")
        msg("Alternatively download and install from")
        msg("http://www.red-dove.com/python_logging.html")
        hline()
        raise CheckError("logging is not installed")

def check_user():
    """Check that the effective user id is 0 (root).
    """
    if os.geteuid() != 0:
        hline()
        msg("Xend must be run as root.")
        hline()
        raise CheckError("invalid user")

def start_xenstored():
    pidfname = "/var/run/xenstore.pid"
    try:
        f = open(pidfname, "a")
        try:
            fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
            rootdir = os.getenv("XENSTORED_ROOTDIR") or "/var/lib/xenstored"
            for i in glob.glob(rootdir + "/tdb*"):
                try:
                    os.unlink(i)
                except:
                    pass
            os.unlink(pidfname)
        except:
            pass
        f.close()
    except:
        pass
    XENSTORED_TRACE = os.getenv("XENSTORED_TRACE")
    cmd = "xenstored --pid-file /var/run/xenstore.pid"
    if XENSTORED_TRACE:
        cmd += " -T /var/log/xen/xenstored-trace.log"
    s,o = commands.getstatusoutput(cmd)

def start_consoled():
    XENCONSOLED_LOG_HYPERVISOR = os.getenv("XENCONSOLED_LOG_HYPERVISOR")
    XENCONSOLED_TIMESTAMP_HYPERVISOR_LOG = os.getenv("XENCONSOLED_TIMESTAMP_HYPERVISOR_LOG")
    XENCONSOLED_LOG_GUESTS = os.getenv("XENCONSOLED_LOG_GUESTS")
    XENCONSOLED_TIMESTAMP_GUEST_LOG = os.getenv("XENCONSOLED_TIMESTAMP_GUEST_LOG")
    XENCONSOLED_LOG_DIR = os.getenv("XENCONSOLED_LOG_DIR")

    args = ['xenconsoled', "--log"]
    if XENCONSOLED_LOG_GUESTS == "yes" and XENCONSOLED_LOG_HYPERVISOR == "yes":
        args += ["all"]
    elif XENCONSOLED_LOG_GUESTS == "yes":
        args += ["guest"]
    elif XENCONSOLED_LOG_HYPERVISOR == "yes":
        args += ["hv"]
    else:
        args += ["none"]

    args += ["--timestamp"]
    if XENCONSOLED_TIMESTAMP_GUEST_LOG == "yes" and \
       XENCONSOLED_TIMESTAMP_HYPERVISOR_LOG == "yes":
        args += ["all"]
    elif XENCONSOLED_TIMESTAMP_GUEST_LOG == "yes":
        args += ["guest"]
    elif XENCONSOLED_TIMESTAMP_HYPERVISOR_LOG == "yes":
        args += ["hv"]
    else:
        args += ["none"]

    if XENCONSOLED_LOG_DIR is not None and XENCONSOLED_LOG_DIR != "":
        args += ["--log-dir"]
        args += [XENCONSOLED_LOG_DIR]

    if os.fork() == 0:
        os.execvp('xenconsoled', args)

def start_blktapctrl():
    if os.fork() == 0:
        os.execvp('blktapctrl', ['blktapctrl'])
            
def main():
    try:
        check_logging()
        check_user()
    except CheckError:
        sys.exit(1)
    
    daemon = SrvDaemon.instance()
    if not sys.argv[1:]:
        print 'usage: %s {start|stop|restart}' % sys.argv[0]
    elif sys.argv[1] == 'start':
        start_xenstored()
        start_consoled()
	start_blktapctrl()
        return daemon.start()
    elif sys.argv[1] == 'trace_start':
        start_xenstored()
        start_consoled()
        start_blktapctrl()
        return daemon.start(trace=1)
    elif sys.argv[1] == 'stop':
        return daemon.stop()
    elif sys.argv[1] == 'restart':
        start_xenstored()
        start_consoled()
        start_blktapctrl()
        return daemon.stop() or daemon.start()
    elif sys.argv[1] == 'status':
        return daemon.status()
    else:
        print 'not an option:', sys.argv[1]
    return 1

if __name__ == '__main__':
    sys.exit(main())
