bitkeeper revision 1.1327.2.13 (4270d6c35WpxFmhdkREjmSvk82s-Bg)

Merge Jeremy's pygrub bootloader patch.

Signed-off-by: Jeremy Katz <katzj@redhat.com>
Signed-off-by: Mike Wray <mike.wray@hp.com>
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2005-04-28 12:27:47 +00:00
1 parent b4ac7763be
commit 51a9f171a5
16 files changed
+1190 -17

No files matched your search

+94
View File
@@ -0,0 +1,94 @@
#
# XendBootloader.py - Framework to run a boot loader for picking the kernel
#
# Copyright 2005 Red Hat, Inc.
# Jeremy Katz <katzj@xxxxxxxxxx>
#
# 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, sys, select
import sxp
from XendLogging import log
from XendError import VmError
BL_FIFO = "/var/lib/xen/xenbl"
def bootloader(blexec, disk, quiet = 0, vcpus = None, entry = 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 vcpus Number of vcpus for the domain.
@param entry Default entry to boot."""
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)
os.mkfifo(BL_FIFO, 0600)
child = os.fork()
if (not child):
args = [ blexec ]
if quiet:
args.append("-q")
args.append("--output=%s" %(BL_FIFO,))
if entry is not None:
args.append("--entry=%s" %(entry,))
args.append(disk)
try:
os.execvp(args[0], args)
except OSError, e:
print e
pass
os._exit(1)
while 1:
try:
r = os.open(BL_FIFO, os.O_RDONLY)
except OSError, e:
if e.errno == 4:
continue
break
ret = ""
while 1:
select.select([r], [], [])
s = os.read(r, 1024)
ret = ret + s
if len(s) == 0:
break
(pid, status) = os.waitpid(child, 0)
os.close(r)
os.unlink(BL_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()
config_image = pin.val
if vcpus and sxp.child_value(config_image, "vcpus") is None:
config_image.append(['vcpus', vcpus])
config = ['image', config_image]
return config
+40
View File
@@ -16,11 +16,13 @@ import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
import xen.util.ip
from xen.util.ip import _readline, _readlines
from xen.xend.server import channel, controller
from xen.xend.server.blkif import blkdev_uname_to_file
from server.channel import channelFactory
import server.SrvDaemon; xend = server.SrvDaemon.instance()
from server import messages
from xen.xend.XendBootloader import bootloader
import sxp
from XendLogging import log
from XendError import VmError
@@ -294,6 +296,7 @@ class XendDomainInfo:
self.image_handler = None
self.is_vmx = False
self.vcpus = 1
self.bootloader = None
def setdom(self, dom):
"""Set the domain id.
@@ -496,6 +499,7 @@ class XendDomainInfo:
self.find_image_handler()
self.init_domain()
self.register_domain()
self.configure_bootloader()
# Create domain devices.
self.configure_backends()
@@ -674,6 +678,13 @@ class XendDomainInfo:
memory = memory * 1024 + self.pgtable_size(memory)
dom = xc.domain_create(dom= dom, mem_kb= memory,
cpu= cpu, cpu_weight= cpu_weight)
if self.bootloader:
try:
if kernel: os.unlink(kernel)
if ramdisk: os.unlink(ramdisk)
except OSError, e:
log.warning('unable to unlink kernel/ramdisk: %s' %(e,))
if dom <= 0:
raise VmError('Creating domain failed: name=%s memory=%d'
% (self.name, memory))
@@ -854,6 +865,13 @@ class XendDomainInfo:
self.config.remove(['device', dev_config])
self.deleteDevice(type, dev.getId())
def configure_bootloader(self):
"""Configure boot loader.
"""
bl = sxp.child_value(self.config, "bootloader")
if bl is not None:
self.bootloader = bl
def configure_console(self):
"""Configure the vm console port.
"""
@@ -931,10 +949,30 @@ class XendDomainInfo:
self.state = STATE_VM_OK
self.restart_check()
self.restart_state = STATE_RESTART_BOOTING
if self.bootloader:
self.config = self.bootloader_config()
self.construct(self.config)
finally:
self.restart_state = None
def bootloader_config(self):
# if we're restarting with a bootloader, we need to run it
# FIXME: this assumes the disk is the first device and
# that we're booting from the first disk
blcfg = None
# FIXME: this assumes that we want to use the first disk
dev = sxp.child_value(self.config, "device")
if dev:
disk = sxp.child_value(dev, "uname")
fn = blkdev_uname_to_file(disk)
blcfg = bootloader(self.bootloader, fn, 1, self.vcpus)
if blcfg is None:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
raise VmError(msg)
config = sxp.merge(['vm', blconfig ], self.config)
return config
def configure_backends(self):
"""Set configuration flags if the vm is a backend for netif or blkif.
Configure the backends to use for vbd and vif if specified.
@@ -1071,6 +1109,7 @@ def vm_image_linux(vm, image):
if args:
cmdline += " " + args
ramdisk = sxp.child_value(image, "ramdisk", '')
log.debug("creating linux domain with cmdline: %s" %(cmdline,))
vm.create_domain("linux", kernel, ramdisk, cmdline)
return vm
@@ -1169,6 +1208,7 @@ add_config_handler('image', vm_field_ignore)
add_config_handler('device', vm_field_ignore)
add_config_handler('backend', vm_field_ignore)
add_config_handler('vcpus', vm_field_ignore)
add_config_handler('bootloader', vm_field_ignore)
# Register other config handlers.
add_config_handler('maxmem', vm_field_maxmem)
+9
View File
@@ -71,6 +71,15 @@ def blkdev_segment(name):
'type' : 'Disk' }
return val
def blkdev_uname_to_file(uname):
"""Take a blkdev uname and return the corresponding filename."""
fn = None
if uname.find(":") != -1:
(typ, fn) = uname.split(":")
if typ == "phy" and not fn.startswith("/dev/"):
fn = "/dev/%s" %(fn,)
return fn
def mount_mode(name):
mode = None
name = expand_dev_name(name)
+45 -16
View File
@@ -10,6 +10,8 @@ import socket
from xen.xend import sxp
from xen.xend import PrettyPrint
from xen.xend.XendClient import server, XendError
from xen.xend.XendBootloader import bootloader
from xen.xend.server import blkif
from xen.util import console_client
@@ -94,6 +96,14 @@ gopts.var('name', val='NAME',
fn=set_value, default=None,
use="Domain name. Must be unique.")
gopts.var('bootloader', val='FILE',
fn=set_value, default=None,
use="Path to bootloader.")
gopts.var('bootentry', val='NAME',
fn=set_value, default=None,
use="Entry to boot via boot loader")
gopts.var('kernel', val='FILE',
fn=set_value, default=None,
use="Path to kernel image.")
@@ -252,7 +262,7 @@ def strip(pre, s):
else:
return s
def configure_image(config, vals):
def configure_image(opts, config, vals):
"""Create the image config.
"""
config_image = [ vals.builder ]
@@ -272,7 +282,7 @@ def configure_image(config, vals):
config.append(['image', config_image ])
def configure_disks(config_devs, vals):
def configure_disks(opts, config_devs, vals):
"""Create the config for disks (virtual block devices).
"""
for (uname, dev, mode, backend) in vals.disk:
@@ -284,14 +294,14 @@ def configure_disks(config_devs, vals):
config_vbd.append(['backend', backend])
config_devs.append(['device', config_vbd])
def configure_pci(config_devs, vals):
def configure_pci(opts, config_devs, vals):
"""Create the config for pci devices.
"""
for (bus, dev, func) in vals.pci:
config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
config_devs.append(['device', config_pci])
def configure_usb(config_devs, vals):
def configure_usb(opts, config_devs, vals):
for path in vals.usb:
config_usb = ['usb', ['path', path]]
config_devs.append(['device', config_usb])
@@ -315,7 +325,7 @@ def randomMAC():
random.randint(0x00, 0xff) ]
return ':'.join(map(lambda x: "%02x" % x, mac))
def configure_vifs(config_devs, vals):
def configure_vifs(opts, config_devs, vals):
"""Create the config for virtual network interfaces.
"""
vifs = vals.vif
@@ -357,7 +367,7 @@ def configure_vifs(config_devs, vals):
config_vif.append(['ip', ip])
config_devs.append(['device', config_vif])
def configure_vfr(config, vals):
def configure_vfr(opts, config, vals):
if not vals.ipaddr: return
config_vfr = ['vfr']
idx = 0 # No way of saying which IP is for which vif?
@@ -365,7 +375,7 @@ def configure_vfr(config, vals):
config_vfr.append(['vif', ['id', idx], ['ip', ip]])
config.append(config_vfr)
def configure_vmx(config_devs, vals):
def configure_vmx(opts, config_devs, vals):
"""Create the config for VMX devices.
"""
memmap = vals.memmap
@@ -375,7 +385,21 @@ def configure_vmx(config_devs, vals):
config_devs.append(['device_model', device_model])
config_devs.append(['device_config', device_config])
def make_config(vals):
def run_bootloader(opts, config, vals):
if not os.access(vals.bootloader, os.X_OK):
opts.err("Bootloader isn't executable")
if len(vals.disk) < 1:
opts.err("No disks configured and boot loader requested")
(uname, dev, mode, backend) = vals.disk[0]
file = blkif.blkdev_uname_to_file(uname)
blcfg = bootloader(vals.bootloader, file, not vals.console_autoconnect,
vals.vcpus, vals.blentry)
config.append(['bootloader', vals.bootloader])
config.append(blcfg)
def make_config(opts, vals):
"""Create the domain configuration.
"""
@@ -396,15 +420,19 @@ def make_config(vals):
config.append(['restart', vals.restart])
if vals.console:
config.append(['console', vals.console])
configure_image(config, vals)
if vals.bootloader:
run_bootloader(opts, config, vals)
else:
configure_image(opts, config, vals)
config_devs = []
configure_disks(config_devs, vals)
configure_pci(config_devs, vals)
configure_vifs(config_devs, vals)
configure_usb(config_devs, vals)
configure_vmx(config_devs, vals)
configure_disks(opts, config_devs, vals)
configure_pci(opts, config_devs, vals)
configure_vifs(opts, config_devs, vals)
configure_usb(opts, config_devs, vals)
configure_vmx(opts, config_devs, vals)
config += config_devs
return config
def preprocess_disk(opts, vals):
@@ -587,7 +615,8 @@ def main(argv):
preprocess(opts, opts.vals)
if not opts.getopt('name') and opts.getopt('defconfig'):
opts.setopt('name', os.path.basename(opts.getopt('defconfig')))
config = make_config(opts.vals)
config = make_config(opts, opts.vals)
if opts.vals.dryrun:
PrettyPrint.prettyprint(config)
else:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.