File: XendBootloader.py

package info (click to toggle)
xen-3.0 3.0.3-0-2
  • links: PTS
  • area: main
  • in suites: etch-m68k
  • size: 31,772 kB
  • ctags: 70,362
  • sloc: ansic: 417,153; python: 28,855; asm: 23,892; sh: 5,157; makefile: 4,830; objc: 613; perl: 372; xml: 351
file content (96 lines) | stat: -rw-r--r-- 2,497 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#
# XendBootloader.py - Framework to run a boot loader for picking the kernel
#
# Copyright 2005-2006 Red Hat, Inc.
# Jeremy Katz <katzj@redhat.com>
#
# This software may be freely redistributed under the terms of the GNU
# general public license.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

import os, select, errno
import random
import sxp
import shlex

from XendLogging import log
from XendError import VmError

def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None):
    """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 quiet Run in non-interactive mode, just booting the default.
    @param blargs Arguments to pass to the bootloader."""
    
    if not os.access(blexec, os.X_OK):
        msg = "Bootloader isn't executable"
        log.error(msg)
        raise VmError(msg)
    if not os.access(disk, os.R_OK):
        msg = "Disk isn't accessible"
        log.error(msg)
        raise VmError(msg)

    while True:
        fifo = "/var/lib/xen/xenbl.%s" %(random.randint(0, 32000),)
        if not os.path.exists(fifo):
            break
    os.mkfifo(fifo, 0600)

    child = os.fork()
    if (not child):
        args = [ blexec ]
        if quiet:
            args.append("-q")
        args.append("--output=%s" %(fifo,))
        if blargs is not None:
            args.extend(shlex.split(blargs))
        args.append(disk)

        try:
            os.execvp(args[0], args)
        except OSError, e:
            print e
            pass
        os._exit(1)

    while 1:
        try:
            r = os.open(fifo, os.O_RDONLY)
        except OSError, e:
            if e.errno == errno.EINTR:
                continue
        break
    ret = ""
    while 1:
        select.select([r], [], [])
        s = os.read(r, 1024)
        ret = ret + s
        if len(s) == 0:
            break
        
    os.waitpid(child, 0)
    os.close(r)
    os.unlink(fifo)

    if len(ret) == 0:
        msg = "Boot loader didn't return any data!"
        log.error(msg)
        raise VmError, msg

    pin = sxp.Parser()
    pin.input(ret)
    pin.input_eof()
    blcfg = pin.val

    if imgcfg is None:
        return blcfg
    else:
        c = sxp.merge(blcfg, imgcfg)
        return c