mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.1159.212.10 (41dde8b1uPUodrtnTKejSUrLg-fcoQ)
xend extensiosn for VMX guests
This commit is contained in:
1 parent
8543240ec9
commit
179b35aad7
12 files changed
+1389
-10
No files matched your search
@@ -16,6 +16,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include "xc_private.h"
|
||||
#include "gzip_stream.h"
|
||||
#include "linux_boot_params.h"
|
||||
|
||||
/* Needed for Python versions earlier than 2.3. */
|
||||
#ifndef PyMODINIT_FUNC
|
||||
@@ -393,6 +394,87 @@ static PyObject *pyxc_plan9_build(PyObject *self,
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_vmx_build(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
XcObject *xc = (XcObject *)self;
|
||||
|
||||
u32 dom;
|
||||
char *image, *ramdisk = NULL, *cmdline = "";
|
||||
PyObject *memmap;
|
||||
int control_evtchn, flags = 0;
|
||||
int numItems, i;
|
||||
struct mem_map mem_map;
|
||||
|
||||
static char *kwd_list[] = { "dom", "control_evtchn",
|
||||
"image", "memmap",
|
||||
"ramdisk", "cmdline", "flags",
|
||||
NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iisO!|ssi", kwd_list,
|
||||
&dom, &control_evtchn,
|
||||
&image, &PyList_Type, &memmap,
|
||||
&ramdisk, &cmdline, &flags) )
|
||||
return NULL;
|
||||
|
||||
memset(&mem_map, 0, sizeof(mem_map));
|
||||
/* Parse memmap */
|
||||
|
||||
/* get the number of lines passed to us */
|
||||
numItems = PyList_Size(memmap) - 1; /* removing the line
|
||||
containing "memmap" */
|
||||
printf ("numItems: %d\n", numItems);
|
||||
mem_map.nr_map = numItems;
|
||||
|
||||
|
||||
/* should raise an error here. */
|
||||
if (numItems < 0) return NULL; /* Not a list */
|
||||
|
||||
|
||||
/* iterate over items of the list, grabbing ranges and parsing them */
|
||||
for (i = 1; i <= numItems; i++) { // skip over "memmap"
|
||||
PyObject *item, *f1, *f2, *f3, *f4;
|
||||
int numFields;
|
||||
unsigned long lf1, lf2, lf3, lf4;
|
||||
char *sf1, *sf2;
|
||||
|
||||
/* grab the string object from the next element of the list */
|
||||
item = PyList_GetItem(memmap, i); /* Can't fail */
|
||||
|
||||
/* get the number of lines passed to us */
|
||||
numFields = PyList_Size(item);
|
||||
|
||||
if (numFields != 4)
|
||||
return NULL;
|
||||
|
||||
f1 = PyList_GetItem(item, 0);
|
||||
f2 = PyList_GetItem(item, 1);
|
||||
f3 = PyList_GetItem(item, 2);
|
||||
f4 = PyList_GetItem(item, 3);
|
||||
|
||||
/* Convert objects to strings/longs */
|
||||
sf1 = PyString_AsString(f1);
|
||||
sf2 = PyString_AsString(f2);
|
||||
lf3 = PyLong_AsLong(f3);
|
||||
lf4 = PyLong_AsLong(f4);
|
||||
sscanf(sf1, "%lx", &lf1);
|
||||
sscanf(sf2, "%lx", &lf2);
|
||||
|
||||
mem_map.map[i-1].addr = lf1;
|
||||
mem_map.map[i-1].size = lf2 - lf1;
|
||||
mem_map.map[i-1].type = lf3;
|
||||
mem_map.map[i-1].caching_attr = lf4;
|
||||
}
|
||||
|
||||
if ( xc_vmx_build(xc->xc_handle, dom, image, &mem_map,
|
||||
ramdisk, cmdline, control_evtchn, flags) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_bvtsched_global_set(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
@@ -943,6 +1025,17 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" cmdline [str, n/a]: Kernel parameters, if any.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "vmx_build",
|
||||
(PyCFunction)pyxc_vmx_build,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Build a new Linux guest OS.\n"
|
||||
" dom [int]: Identifier of domain to build into.\n"
|
||||
" image [str]: Name of kernel image file. May be gzipped.\n"
|
||||
" memmap [str]: Memory map.\n\n"
|
||||
" ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
|
||||
" cmdline [str, n/a]: Kernel parameters, if any.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "bvtsched_global_set",
|
||||
(PyCFunction)pyxc_bvtsched_global_set,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
mem_caching_attr = {
|
||||
'UC' : 0,
|
||||
'WC' : 1,
|
||||
'WT' : 4,
|
||||
'WP' : 5,
|
||||
'WB' : 6,
|
||||
};
|
||||
|
||||
e820_mem_type = {
|
||||
'AddressRangeMemory' : 1,
|
||||
'AddressRangeReserved' : 2,
|
||||
'AddressRangeACPI' : 3,
|
||||
'AddressRangeNVS' : 4,
|
||||
'AddressRangeIO' : 16,
|
||||
'AddressRangeShared' : 17,
|
||||
};
|
||||
|
||||
MT_COL = 2
|
||||
MA_COL = 3
|
||||
|
||||
def strmap(row):
|
||||
if (type(row) != type([])):
|
||||
return row
|
||||
row[MT_COL] = e820_mem_type[row[MT_COL]]
|
||||
row[MA_COL] = mem_caching_attr[row[MA_COL]]
|
||||
return row
|
||||
|
||||
def memmap_parse(memmap):
|
||||
return map(strmap, memmap)
|
||||
|
||||
if __name__ == '__main__':
|
||||
memmap = [ 'memmap',
|
||||
[ '1', '2', 'AddressRangeMemory', 'UC'],
|
||||
[ '1', '2', 'AddressRangeReserved', 'UC'],
|
||||
[ '1', '2', 'AddressRangeACPI', 'WB'],
|
||||
[ '1', '2', 'AddressRangeNVS', 'WB'],
|
||||
[ '1', '2', 'AddressRangeIO', 'WB'],
|
||||
[ '1', '2', 'AddressRangeShared', 'WB']]
|
||||
print memmap_parse(memmap);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ from twisted.internet import defer
|
||||
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
|
||||
|
||||
import sxp
|
||||
|
||||
@@ -319,6 +320,7 @@ class XendDomainInfo:
|
||||
self.restart_time = None
|
||||
self.console_port = None
|
||||
self.savedinfo = None
|
||||
self.is_vmx = 0
|
||||
|
||||
def setdom(self, dom):
|
||||
"""Set the domain id.
|
||||
@@ -720,7 +722,7 @@ class XendDomainInfo:
|
||||
log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, name, memory)
|
||||
self.setdom(dom)
|
||||
|
||||
def build_domain(self, ostype, kernel, ramdisk, cmdline):
|
||||
def build_domain(self, ostype, kernel, ramdisk, cmdline, memmap):
|
||||
"""Build the domain boot image.
|
||||
"""
|
||||
if self.recreate or self.restore: return
|
||||
@@ -735,17 +737,26 @@ class XendDomainInfo:
|
||||
flags = 0
|
||||
if self.netif_backend: flags |= SIF_NET_BE_DOMAIN
|
||||
if self.blkif_backend: flags |= SIF_BLK_BE_DOMAIN
|
||||
err = buildfn(dom = dom,
|
||||
image = kernel,
|
||||
control_evtchn = self.console.getRemotePort(),
|
||||
cmdline = cmdline,
|
||||
ramdisk = ramdisk,
|
||||
flags = flags)
|
||||
if ostype == "vmx":
|
||||
err = buildfn(dom = dom,
|
||||
image = kernel,
|
||||
control_evtchn = 0,
|
||||
memmap = memmap,
|
||||
cmdline = cmdline,
|
||||
ramdisk = ramdisk,
|
||||
flags = flags)
|
||||
else:
|
||||
err = buildfn(dom = dom,
|
||||
image = kernel,
|
||||
control_evtchn = self.console.getRemotePort(),
|
||||
cmdline = cmdline,
|
||||
ramdisk = ramdisk,
|
||||
flags = flags)
|
||||
if err != 0:
|
||||
raise VmError('Building domain failed: type=%s dom=%d err=%d'
|
||||
% (ostype, dom, err))
|
||||
|
||||
def create_domain(self, ostype, kernel, ramdisk, cmdline):
|
||||
def create_domain(self, ostype, kernel, ramdisk, cmdline, memmap=''):
|
||||
"""Create a domain. Builds the image but does not configure it.
|
||||
|
||||
@param ostype: OS type
|
||||
@@ -760,7 +771,7 @@ class XendDomainInfo:
|
||||
else:
|
||||
self.console = xendConsole.console_create(
|
||||
self.dom, console_port=self.console_port)
|
||||
self.build_domain(ostype, kernel, ramdisk, cmdline)
|
||||
self.build_domain(ostype, kernel, ramdisk, cmdline, memmap)
|
||||
self.image = kernel
|
||||
self.ramdisk = ramdisk
|
||||
self.cmdline = cmdline
|
||||
@@ -804,6 +815,18 @@ class XendDomainInfo:
|
||||
index[dev_name] = dev_index + 1
|
||||
deferred = defer.DeferredList(dlist, fireOnOneErrback=1)
|
||||
deferred.addErrback(dlist_err)
|
||||
if self.is_vmx:
|
||||
device_model = sxp.child_value(self.config, 'device_model')
|
||||
device_config = sxp.child_value(self.config, 'device_config')
|
||||
memory = sxp.child_value(self.config, "memory")
|
||||
# Create an event channel
|
||||
device_channel = channel.eventChannel(0, self.dom)
|
||||
# Fork and exec device_model -f device_config <port>
|
||||
os.system(device_model
|
||||
+ " -f %s" % device_config
|
||||
+ " -d %d" % self.dom
|
||||
+ " -p %d" % device_channel['port1']
|
||||
+ " -m %s &" % memory)
|
||||
return deferred
|
||||
|
||||
def device_create(self, dev_config):
|
||||
@@ -1091,7 +1114,33 @@ def vm_image_plan9(vm, image):
|
||||
vm.create_domain("plan9", kernel, ramdisk, cmdline)
|
||||
return vm
|
||||
|
||||
|
||||
def vm_image_vmx(vm, image):
|
||||
"""Create a VM for the VMX environment.
|
||||
|
||||
@param name: vm name
|
||||
@param memory: vm memory
|
||||
@param image: image config
|
||||
@return: vm
|
||||
"""
|
||||
kernel = sxp.child_value(image, "kernel")
|
||||
cmdline = ""
|
||||
ip = sxp.child_value(image, "ip", "dhcp")
|
||||
if ip:
|
||||
cmdline += " ip=" + ip
|
||||
root = sxp.child_value(image, "root")
|
||||
if root:
|
||||
cmdline += " root=" + root
|
||||
args = sxp.child_value(image, "args")
|
||||
if args:
|
||||
cmdline += " " + args
|
||||
ramdisk = sxp.child_value(image, "ramdisk", '')
|
||||
memmap = sxp.child_value(vm.config, "memmap", '')
|
||||
memmap = sxp.parse(open(memmap))[0]
|
||||
from xen.util.memmap import memmap_parse
|
||||
memmap = memmap_parse(memmap)
|
||||
vm.create_domain("vmx", kernel, ramdisk, cmdline, memmap)
|
||||
vm.is_vmx = 1
|
||||
return vm
|
||||
|
||||
def vm_dev_vif(vm, val, index, change=0):
|
||||
"""Create a virtual network interface (vif).
|
||||
@@ -1215,6 +1264,7 @@ def vm_field_maxmem(vm, config, val, index):
|
||||
# Register image handlers.
|
||||
add_image_handler('linux', vm_image_linux)
|
||||
add_image_handler('plan9', vm_image_plan9)
|
||||
add_image_handler('vmx', vm_image_vmx)
|
||||
|
||||
# Register device handlers.
|
||||
add_device_handler('vif', vm_dev_vif)
|
||||
|
||||
@@ -210,6 +210,18 @@ gopts.var('nfs_root', val="PATH",
|
||||
fn=set_value, default=None,
|
||||
use="Set the path of the root NFS directory.")
|
||||
|
||||
gopts.var('memmap', val='FILE',
|
||||
fn=set_value, default='',
|
||||
use="Path to memap SXP file.")
|
||||
|
||||
gopts.var('device_model', val='FILE',
|
||||
fn=set_value, default='',
|
||||
use="Path to device model program.")
|
||||
|
||||
gopts.var('device_config', val='FILE',
|
||||
fn=set_value, default='',
|
||||
use="Path to device model configuration.")
|
||||
|
||||
def strip(pre, s):
|
||||
"""Strip prefix 'pre' if present.
|
||||
"""
|
||||
@@ -309,6 +321,15 @@ def configure_vfr(config, vals):
|
||||
config_vfr.append(['vif', ['id', idx], ['ip', ip]])
|
||||
config.append(config_vfr)
|
||||
|
||||
def configure_vmx(config_devs, vals):
|
||||
"""Create the config for VMX devices.
|
||||
"""
|
||||
memmap = vals.memmap
|
||||
device_model = vals.device_model
|
||||
device_config = vals.device_config
|
||||
config_devs.append(['memmap', memmap])
|
||||
config_devs.append(['device_model', device_model])
|
||||
config_devs.append(['device_config', device_config])
|
||||
|
||||
def make_config(vals):
|
||||
"""Create the domain configuration.
|
||||
@@ -337,6 +358,7 @@ def make_config(vals):
|
||||
configure_disks(config_devs, vals)
|
||||
configure_pci(config_devs, vals)
|
||||
configure_vifs(config_devs, vals)
|
||||
configure_vmx(config_devs, vals)
|
||||
config += config_devs
|
||||
return config
|
||||
|
||||
|
||||