From c8cce1edddec9f95726c1ff9450ee4c3c6bfe483 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:01:09 +0000 Subject: [PATCH 01/49] [XEND] Fix VCPU_params to return string map. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendAPI.py | 4 ++-- tools/python/xen/xend/XendDomainInfo.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index 0b249f9449..193d382b13 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -1121,11 +1121,11 @@ class XendAPI(object): def VM_get_VCPUs_policy(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return dom.get_vcpus_policy() + return xen_api_success(dom.get_vcpus_policy()) def VM_get_VCPUs_params(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() # need access to scheduler + return xen_api_success(dom.get_vcpus_params()) def VM_get_actions_after_shutdown(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index d657d4a1f1..fde0a8f4bc 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1976,7 +1976,11 @@ class XendDomainInfo: else: return 'unknown' def get_vcpus_params(self): - return '' # TODO + if self.getDomid() is None: + return {} + + retval = xc.sched_credit_domain_get(self.getDomid()) + return retval def get_power_state(self): return XEN_API_VM_POWER_STATE[self.state] def get_platform_std_vga(self): From f32d40076720284ffd928e649dd6b9175176f0bb Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:02:20 +0000 Subject: [PATCH 02/49] [XEND] Hide other_config from console and vfb SXP to prevent string representation of dict to appear in SXP. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendConfig.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index f17a5a2295..a3c5398b49 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -1223,7 +1223,12 @@ class XendConfig(dict): "configuration dictionary.") sxpr.append(dev_type) - config = [(opt, val) for opt, val in dev_info.items()] + if dev_type in ('console', 'vfb'): + config = [(opt, val) for opt, val in dev_info.items() + if opt != 'other_config'] + else: + config = [(opt, val) for opt, val in dev_info.items()] + sxpr += config return sxpr From 1f66881925afc33113faa3d372a13c60e1e6b197 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:03:22 +0000 Subject: [PATCH 03/49] [XEND] Make VBD.bootable in XendConfig kept as int. This will prevent it from being displayed as 'False' and 'True' everywhere in the device SXP. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendConfig.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index a3c5398b49..81c1323a2c 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -905,7 +905,7 @@ class XendConfig(dict): # store as part of the device config. dev_uuid = sxp.child_value(config, 'uuid') dev_type, dev_cfg = self['devices'][dev_uuid] - is_bootable = dev_cfg.get('bootable', False) + is_bootable = dev_cfg.get('bootable', 0) config.append(['bootable', int(is_bootable)]) sxpr.append(['device', config]) @@ -978,7 +978,7 @@ class XendConfig(dict): pass if dev_type == 'vbd': - dev_info['bootable'] = False + dev_info['bootable'] = 0 if dev_info.get('dev', '').startswith('ioemu:'): dev_info['driver'] = 'ioemu' else: @@ -998,7 +998,7 @@ class XendConfig(dict): if dev_type == 'vbd' and not target[param]: # Compat hack -- this is the first disk, so mark it # bootable. - dev_info['bootable'] = True + dev_info['bootable'] = 1 target[param].append(dev_uuid) elif dev_type == 'tap': if 'vbd_refs' not in target: @@ -1007,7 +1007,7 @@ class XendConfig(dict): if not target['vbd_refs']: # Compat hack -- this is the first disk, so mark it # bootable. - dev_info['bootable'] = True + dev_info['bootable'] = 1 target['vbd_refs'].append(dev_uuid) elif dev_type == 'vfb': @@ -1070,8 +1070,8 @@ class XendConfig(dict): dev_info['uname'] = cfg_xenapi.get('image', '') dev_info['dev'] = '%s:%s' % (cfg_xenapi.get('device'), old_vbd_type) - dev_info['bootable'] = cfg_xenapi.get('bootable', False) - dev_info['driver'] = cfg_xenapi.get('driver') + dev_info['bootable'] = int(cfg_xenapi.get('bootable', 0)) + dev_info['driver'] = cfg_xenapi.get('driver', '') dev_info['VDI'] = cfg_xenapi.get('VDI', '') if cfg_xenapi.get('mode') == 'RW': From 975e8c91544a5ce1bcdb4d49e78e0f9cc040d5cb Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:04:06 +0000 Subject: [PATCH 04/49] [XEND] Make sure other_config is by default an empty string map. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendAPI.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index 193d382b13..b3d9e39bd1 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -1186,7 +1186,7 @@ class XendAPI(object): return xen_api_success(dom.get_platform_keymap()) def VM_get_other_config(self, session, vm_ref): - return self.VM_get('otherconfig', session, vm_ref) + return self.VM_get('other_config', session, vm_ref) def VM_get_is_control_domain(self, session, vm_ref): xd = XendDomain.instance() @@ -1363,7 +1363,7 @@ class XendAPI(object): 'platform_keymap': xeninfo.get_platform_keymap(), 'PCI_bus': xeninfo.get_pci_bus(), 'tools_version': xeninfo.get_tools_version(), - 'other_config': xeninfo.info.get('otherconfig'), + 'other_config': xeninfo.info.get('other_config', {}), 'is_control_domain': xeninfo == xendom.privilegedDomain(), } return xen_api_success(record) From 48af590de3f0f1ca8113b9858d45bc6d44166d7c Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:05:58 +0000 Subject: [PATCH 05/49] [XEND] Use VDI.location rather than VDI.image_uri/uri for Xen API Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendAPI.py | 2 +- tools/python/xen/xend/XendVDI.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index b3d9e39bd1..c1ecf3cab3 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -1469,7 +1469,7 @@ class XendAPI(object): vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref) if not vdi: return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref]) - vdi_image = vdi.get_image_uri() + vdi_image = vdi.get_location() vbd_ref = XendTask.log_progress(0, 100, dom.create_vbd, vbd_struct, vdi_image) diff --git a/tools/python/xen/xend/XendVDI.py b/tools/python/xen/xend/XendVDI.py index 0868814c8f..f0dda203a8 100644 --- a/tools/python/xen/xend/XendVDI.py +++ b/tools/python/xen/xend/XendVDI.py @@ -73,6 +73,7 @@ class XendVDI(AutoSaveObject): self.sharable = False self.read_only = False self.type = "system" + self.location = '' def load_config_dict(self, cfg): """Loads configuration into the object from a dict. @@ -147,9 +148,10 @@ class XendVDI(AutoSaveObject): 'sharable': False, 'readonly': False, 'SR': self.sr_uuid, + 'location': self.get_location(), 'VBDs': []} - def get_image_uri(self): + def get_location(self): raise NotImplementedError() @@ -163,9 +165,10 @@ class XendQCoWVDI(XendVDI): self.virtual_size = vsize self.sector_size = 512 self.auto_save = True + self.location = 'tap:qcow:%s' % self.qcow_path - def get_image_uri(self): - return 'tap:qcow:%s' % self.qcow_path + def get_location(self): + return self.location class XendLocalVDI(XendVDI): def __init__(self, vdi_struct): @@ -183,7 +186,7 @@ class XendLocalVDI(XendVDI): self.type = vdi_struct.get('type', '') self.sharable = vdi_struct.get('sharable', False) self.read_only = vdi_struct.get('read_only', False) - self.image_uri = vdi_struct.get('uri', 'file:/dev/null') + self.location = vdi_struct.get('location', 'file:/dev/null') - def get_image_uri(self): - return self.image_uri + def get_location(self): + return self.location From ad643e3ef0104d2b986b7ce37fb8980bcb98d393 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:06:40 +0000 Subject: [PATCH 06/49] [XENAPI] Remove some deprecated fields from the Xen API test script. Signed-off-by: Alastair Tse --- tools/python/scripts/test_hvm_create.py | 9 ++------- tools/python/scripts/test_vm_create.py | 11 +++-------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/tools/python/scripts/test_hvm_create.py b/tools/python/scripts/test_hvm_create.py index 8effd42db9..7cae70539a 100644 --- a/tools/python/scripts/test_hvm_create.py +++ b/tools/python/scripts/test_hvm_create.py @@ -13,16 +13,11 @@ vm_cfg = { 'VCPUs_policy': 'credit', - 'VCPUs_params': '', + 'VCPUs_params': {}, 'VCPUs_number': 2, - 'VCPUs_features_required': '', - 'VCPUs_features_can_use': '', - 'VCPUs_features_force_on': '', - 'VCPUs_features_force_off': '', 'actions_after_shutdown': 'destroy', 'actions_after_reboot': 'restart', - 'actions_after_suspend': 'destroy', 'actions_after_crash': 'destroy', 'PV_bootloader': '', @@ -44,7 +39,7 @@ vm_cfg = { local_vdi_cfg = { 'name_label': 'gentoo.hvm', 'name_description': '', - 'uri': 'file:/root/gentoo.amd64.hvm.img', + 'location': 'file:/root/gentoo.amd64.hvm.img', 'virtual_size': 0, 'sector_size': 0, 'type': 'system', diff --git a/tools/python/scripts/test_vm_create.py b/tools/python/scripts/test_vm_create.py index 0d702aae69..84959c3e0d 100644 --- a/tools/python/scripts/test_vm_create.py +++ b/tools/python/scripts/test_vm_create.py @@ -15,14 +15,9 @@ vm_cfg = { 'VCPUs_policy': 'credit', 'VCPUs_params': '', 'VCPUs_number': 2, - 'VCPUs_features_required': '', - 'VCPUs_features_can_use': '', - 'VCPUs_features_force_on': '', - 'VCPUs_features_force_off': '', 'actions_after_shutdown': 'destroy', 'actions_after_reboot': 'restart', - 'actions_after_suspend': 'destroy', 'actions_after_crash': 'destroy', 'PV_bootloader': '', @@ -65,7 +60,7 @@ vbd_cfg = { local_vdi_cfg = { 'name_label': 'gentoo.amd64.img', 'name_description': '', - 'uri': 'file:/root/gentoo.amd64.img', + 'location': 'file:/root/gentoo.amd64.img', 'virtual_size': 0, 'sector_size': 0, 'type': 'system', @@ -183,13 +178,13 @@ def test_vm_create(): execute(server, 'VM.resume', (session, vm_uuid, False)) print 'Resumed VM.' + finally: # Wait for user to say we're good to shut it down while True: destroy = raw_input('destroy VM? ') if destroy[0] in ('y', 'Y'): break - - finally: + # Clean up if vif_uuid: execute(server, 'VIF.destroy', (session, vif_uuid)) From ddffd1ed7d3c1a73135c187886d35b4f66c7fd3e Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:08:29 +0000 Subject: [PATCH 07/49] [XENAPI] Add VDI.location support and test c prog for HVM test. Signed-off-by: Alastair Tse --- tools/libxen/Makefile | 3 + tools/libxen/include/xen_vdi.h | 1 + tools/libxen/src/xen_vdi.c | 3 + tools/libxen/test/test_bindings.c | 12 +- tools/libxen/test/test_hvm_bindings.c | 445 ++++++++++++++++++++++++++ 5 files changed, 459 insertions(+), 5 deletions(-) create mode 100644 tools/libxen/test/test_hvm_bindings.c diff --git a/tools/libxen/Makefile b/tools/libxen/Makefile index c72206442a..e2eeda74d8 100644 --- a/tools/libxen/Makefile +++ b/tools/libxen/Makefile @@ -51,6 +51,9 @@ libxenapi.a: $(LIBXENAPI_OBJS) test/test_bindings: test/test_bindings.o libxenapi.so $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi +test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so + $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi + .PHONY: install install: all diff --git a/tools/libxen/include/xen_vdi.h b/tools/libxen/include/xen_vdi.h index d72eceb001..8533df31a8 100644 --- a/tools/libxen/include/xen_vdi.h +++ b/tools/libxen/include/xen_vdi.h @@ -74,6 +74,7 @@ typedef struct xen_vdi_record int64_t virtual_size; int64_t physical_utilisation; int64_t sector_size; + char *location; enum xen_vdi_type type; bool sharable; bool read_only; diff --git a/tools/libxen/src/xen_vdi.c b/tools/libxen/src/xen_vdi.c index b2eddbcafb..005425ebc1 100644 --- a/tools/libxen/src/xen_vdi.c +++ b/tools/libxen/src/xen_vdi.c @@ -67,6 +67,9 @@ static const struct_member xen_vdi_record_struct_members[] = { .key = "sector_size", .type = &abstract_type_int, .offset = offsetof(xen_vdi_record, sector_size) }, + { .key = "location", + .type = &abstract_type_string, + .offset = offsetof(xen_vdi_record, location) }, { .key = "type", .type = &xen_vdi_type_abstract_type_, .offset = offsetof(xen_vdi_record, type) }, diff --git a/tools/libxen/test/test_bindings.c b/tools/libxen/test/test_bindings.c index 88fce8b35b..0d6bed18dd 100644 --- a/tools/libxen/test/test_bindings.c +++ b/tools/libxen/test/test_bindings.c @@ -295,10 +295,10 @@ static xen_vm create_new_vm(xen_session *session) .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART, .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE, .hvm_boot = "", - .pv_bootloader = "pygrub", - .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen", + //.pv_bootloader = "pygrub", + .pv_kernel = "/boot/vmlinuz-2.6.18-xenU", .pv_ramdisk = "", - .pv_args = "", + .pv_args = "root=/dev/sda1 ro", .pv_bootloader_args = "" }; @@ -338,6 +338,7 @@ static xen_vm create_new_vm(xen_session *session) .sr = &sr_record, .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector .sector_size = 512, + .location = "file:/root/gentoo.amd64.img", .type = XEN_VDI_TYPE_SYSTEM, .sharable = false, .read_only = false @@ -367,8 +368,9 @@ static xen_vm create_new_vm(xen_session *session) { .vm = &vm_record_opt, .vdi = &vdi0_record_opt, - .device = "xvda1", - .mode = XEN_VBD_MODE_RW + .device = "sda1", + .mode = XEN_VBD_MODE_RW, + .bootable = 1, }; xen_vbd vbd0; diff --git a/tools/libxen/test/test_hvm_bindings.c b/tools/libxen/test/test_hvm_bindings.c new file mode 100644 index 0000000000..8bc8e7c347 --- /dev/null +++ b/tools/libxen/test/test_hvm_bindings.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2006 XenSource, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include +#include + +#include "xen_host.h" +#include "xen_sr.h" +#include "xen_vbd.h" +#include "xen_vdi.h" +#include "xen_vm.h" + + +static void usage() +{ + fprintf(stderr, +"Usage:\n" +"\n" +" test_bindings \n" +"\n" +"where\n" +" is a fragment of the server's URL, e.g. localhost:8005/RPC2;\n" +" is the username to use at the server; and\n" +" is the password.\n"); + + exit(EXIT_FAILURE); +} + + +static char *url; + + +typedef struct +{ + xen_result_func func; + void *handle; +} xen_comms; + + +static xen_vm create_new_vm(xen_session *session); +static void print_vm_power_state(xen_session *session, xen_vm vm); + + +static size_t +write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms) +{ + size_t n = size * nmemb; + return comms->func(ptr, n, comms->handle) ? n : 0; +} + + +static int +call_func(const void *data, size_t len, void *user_handle, + void *result_handle, xen_result_func result_func) +{ + (void)user_handle; + + CURL *curl = curl_easy_init(); + if (!curl) { + return -1; + } + + xen_comms comms = { + .func = result_func, + .handle = result_handle + }; + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(curl, CURLOPT_MUTE, 1); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms); + curl_easy_setopt(curl, CURLOPT_POST, 1); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len); + + CURLcode result = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + + return result; +} + + +static void print_error(xen_session *session) +{ + fprintf(stderr, "Error: %d", session->error_description_count); + for (int i = 0; i < session->error_description_count; i++) + { + fprintf(stderr, "%s ", session->error_description[i]); + } + fprintf(stderr, "\n"); +} + + +int main(int argc, char **argv) +{ + if (argc != 4) + { + usage(); + } + + url = argv[1]; + char *username = argv[2]; + char *password = argv[3]; + + xmlInitParser(); + xen_init(); + curl_global_init(CURL_GLOBAL_ALL); + +#define CLEANUP \ + do { \ + xen_session_logout(session); \ + curl_global_cleanup(); \ + xen_fini(); \ + xmlCleanupParser(); \ + } while(0) \ + + + xen_session *session = + xen_session_login_with_password(call_func, NULL, username, password); + + xen_vm vm; + if (!xen_vm_get_by_uuid(session, &vm, + "00000000-0000-0000-0000-000000000000")) + { + print_error(session); + CLEANUP; + return 1; + } + + char *vm_uuid; + if (!xen_vm_get_uuid(session, &vm_uuid, vm)) + { + print_error(session); + xen_vm_free(vm); + CLEANUP; + return 1; + } + + char *vm_uuid_bytes; + if (!xen_uuid_string_to_bytes(vm_uuid, &vm_uuid_bytes)) + { + fprintf(stderr, "xen_uuid_string_to_bytes failed.\n"); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + CLEANUP; + return 1; + } + + xen_vm_record *vm_record; + if (!xen_vm_get_record(session, &vm_record, vm)) + { + print_error(session); + xen_uuid_bytes_free(vm_uuid_bytes); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + CLEANUP; + return 1; + } + + xen_host host; + if (!xen_session_get_this_host(session, &host)) + { + print_error(session); + xen_vm_record_free(vm_record); + xen_uuid_bytes_free(vm_uuid_bytes); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + CLEANUP; + return 1; + } + + xen_string_string_map *versions; + if (!xen_host_get_software_version(session, &versions, host)) + { + print_error(session); + xen_host_free(host); + xen_vm_record_free(vm_record); + xen_uuid_bytes_free(vm_uuid_bytes); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + CLEANUP; + return 1; + } + + printf("%s.\n", vm_uuid); + + fprintf(stderr, "In bytes, the VM UUID is "); + for (int i = 0; i < 15; i++) + { + fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]); + } + fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]); + + printf("%zd.\n", versions->size); + + for (size_t i = 0; i < versions->size; i++) + { + printf("%s -> %s.\n", versions->contents[i].key, + versions->contents[i].val); + } + + printf("%s.\n", vm_record->uuid); + + printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle); + + printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state)); + + for (size_t i = 0; i < vm_record->vcpus_utilisation->size; i++) + { + printf("%"PRId64" -> %lf.\n", + vm_record->vcpus_utilisation->contents[i].key, + vm_record->vcpus_utilisation->contents[i].val); + } + + xen_uuid_bytes_free(vm_uuid_bytes); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + + xen_vm_record_free(vm_record); + + xen_host_free(host); + xen_string_string_map_free(versions); + + + xen_vm new_vm = create_new_vm(session); + if (!session->ok) + { + /* Error has been logged, just clean up. */ + CLEANUP; + return 1; + } + + print_vm_power_state(session, new_vm); + if (!session->ok) + { + /* Error has been logged, just clean up. */ + xen_vm_free(new_vm); + CLEANUP; + return 1; + } + + xen_vm_free(new_vm); + CLEANUP; + + return 0; +} + + +/** + * Creation of a new VM, using the Named Parameters idiom. Allocate the + * xen_vm_record here, but the sets through the library. Either + * allocation patterns can be used, as long as the allocation and free are + * paired correctly. + */ +static xen_vm create_new_vm(xen_session *session) +{ + xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1); + xen_vm_record vm_record = + { + .name_label = "NewHVM", + .name_description = "New HVM Description", + .user_version = 1, + .is_a_template = false, + .memory_static_max = 256, + .memory_dynamic_max = 256, + .memory_dynamic_min = 128, + .memory_static_min = 128, + .vcpus_policy = "credit", + .vcpus_params = vcpus_params, + .vcpus_number = 2, + .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY, + .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART, + .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE, + .hvm_boot = "cda", + }; + + + xen_vm vm; + xen_vm_create(session, &vm, &vm_record); + + if (!session->ok) + { + fprintf(stderr, "VM creation failed.\n"); + print_error(session); + return NULL; + } + + + /* + * Create a new disk for the new VM. + */ + xen_sr_set *srs; + if (!xen_sr_get_by_name_label(session, &srs, "Local") || + srs->size < 1) + { + fprintf(stderr, "SR lookup failed.\n"); + print_error(session); + xen_vm_free(vm); + return NULL; + } + + xen_sr_record_opt sr_record = + { + .u.handle = srs->contents[0] + }; + xen_vdi_record vdi0_record = + { + .name_label = "MyRootFS", + .name_description = "MyRootFS description", + .sr = &sr_record, + .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector + .sector_size = 512, + .location = "file:/root/gentoo.amd64.hvm.img", + .type = XEN_VDI_TYPE_SYSTEM, + .sharable = false, + .read_only = false + }; + + xen_vdi vdi0; + if (!xen_vdi_create(session, &vdi0, &vdi0_record)) + { + fprintf(stderr, "VDI creation failed.\n"); + print_error(session); + + xen_sr_set_free(srs); + xen_vm_free(vm); + return NULL; + } + + + xen_vm_record_opt vm_record_opt = + { + .u.handle = vm + }; + xen_vdi_record_opt vdi0_record_opt = + { + .u.handle = vdi0 + }; + xen_vbd_record vbd0_record = + { + .vm = &vm_record_opt, + .vdi = &vdi0_record_opt, + .device = "xvda1", + .mode = XEN_VBD_MODE_RW + }; + + xen_vbd vbd0; + if (!xen_vbd_create(session, &vbd0, &vbd0_record)) + { + fprintf(stderr, "VBD creation failed.\n"); + print_error(session); + + xen_vdi_free(vdi0); + xen_sr_set_free(srs); + xen_vm_free(vm); + return NULL; + } + + char *vm_uuid; + char *vdi0_uuid; + char *vbd0_uuid; + + xen_vm_get_uuid(session, &vm_uuid, vm); + xen_vdi_get_uuid(session, &vdi0_uuid, vdi0); + xen_vbd_get_uuid(session, &vbd0_uuid, vbd0); + + if (!session->ok) + { + fprintf(stderr, "get_uuid call failed.\n"); + print_error(session); + + xen_uuid_free(vm_uuid); + xen_uuid_free(vdi0_uuid); + xen_uuid_free(vbd0_uuid); + xen_vbd_free(vbd0); + xen_vdi_free(vdi0); + xen_sr_set_free(srs); + xen_vm_free(vm); + return NULL; + } + + fprintf(stderr, + "Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n", + vm_uuid, vdi0_uuid, vbd0_uuid); + + xen_uuid_free(vm_uuid); + xen_uuid_free(vdi0_uuid); + xen_uuid_free(vbd0_uuid); + xen_vbd_free(vbd0); + xen_vdi_free(vdi0); + xen_sr_set_free(srs); + + return vm; +} + + +/** + * Print the power state for the given VM. + */ +static void print_vm_power_state(xen_session *session, xen_vm vm) +{ + char *vm_uuid; + enum xen_vm_power_state power_state; + + if (!xen_vm_get_uuid(session, &vm_uuid, vm)) + { + print_error(session); + return; + } + + if (!xen_vm_get_power_state(session, &power_state, vm)) + { + xen_uuid_free(vm_uuid); + print_error(session); + return; + } + + printf("VM %s power state is %s.\n", vm_uuid, + xen_vm_power_state_to_string(power_state)); + + xen_uuid_free(vm_uuid); +} From 68429d2e8070b99ae6e29ffa75d794293b8f6b68 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Wed, 31 Jan 2007 15:22:33 +0000 Subject: [PATCH 08/49] [XEND] Fix typos in vfb/vnc detect in image.py Signed-off-by: Alastair Tse --- tools/python/xen/xend/image.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index eeb8bd0ebd..e1f87e1e8f 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -450,10 +450,10 @@ class HVMImageHandler(ImageHandler): vnc_config = {} has_vfb = False - has_vnc = int(vmConfig['image'].get('vnc')) != 0 + has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0 for dev_uuid in vmConfig['console_refs']: - dev_type, dev_info = vmConfig['devices'][devuuid] - if dev_type == 'rfb': + dev_type, dev_info = vmConfig['devices'][dev_uuid] + if dev_type == 'vfb': vnc_config = dev_info.get('other_config', {}) has_vfb = True break From e42527954eec82f52422669a9d4c36e6c4f8438c Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Wed, 31 Jan 2007 15:23:51 +0000 Subject: [PATCH 09/49] [TOOLS] Fix typos which breaks readnotes transparent gunzipping ... From: Gerd Hoffmann Signed-off-by: Emmanuel Ackaouy --- tools/xcutils/readnotes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c index fac684014a..f3e412da4e 100644 --- a/tools/xcutils/readnotes.c +++ b/tools/xcutils/readnotes.c @@ -72,8 +72,8 @@ int main(int argc, char **argv) usize = xc_dom_check_gzip(image, st.st_size); if (usize) { - tmp = malloc(size); - xc_dom_do_gunzip(image, st.st_size, tmp, size); + tmp = malloc(usize); + xc_dom_do_gunzip(image, st.st_size, tmp, usize); image = tmp; size = usize; } From 680963aa78d9f9e820eb83e247b3ad0cb05c2070 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 31 Jan 2007 16:54:21 +0000 Subject: [PATCH 10/49] [XEN] Fix dom/sysctl structure alignement. Versions of gcc up to and including 3.3 appear to ignore __attribute__((align(x))) when applied to typedefs or to members of anonymous unions. Workaround this by explicitly aligning each definition of a 64 bit guest handle. Tidy up x86_64 compat entry.S a bit. Signed-off-by: Ian Campbell --- xen/arch/x86/x86_64/compat/entry.S | 7 ++----- xen/include/public/arch-x86/xen-x86_32.h | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index dadd1abe65..070deec3d1 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -281,9 +281,6 @@ CFIX14: .quad CFLT14,CFIX14 .previous -compat_domctl: -compat_sysctl: - .section .rodata, "a", @progbits ENTRY(compat_hypercall_table) @@ -365,8 +362,8 @@ ENTRY(compat_hypercall_args_table) .byte 2 /* compat_event_channel_op */ .byte 2 /* compat_physdev_op */ .byte 2 /* do_hvm_op */ - .byte 1 /* compat_sysctl */ /* 35 */ - .byte 1 /* compat_domctl */ + .byte 1 /* do_sysctl */ /* 35 */ + .byte 1 /* do_domctl */ .byte 2 /* compat_kexec_op */ .rept NR_hypercalls-(.-compat_hypercall_args_table) .byte 0 /* compat_ni_hypercall */ diff --git a/xen/include/public/arch-x86/xen-x86_32.h b/xen/include/public/arch-x86/xen-x86_32.h index 6728b818cd..2633ff082f 100644 --- a/xen/include/public/arch-x86/xen-x86_32.h +++ b/xen/include/public/arch-x86/xen-x86_32.h @@ -103,7 +103,7 @@ (hnd).p = val; \ } while ( 0 ) #define uint64_aligned_t uint64_t __attribute__((aligned(8))) -#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name +#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name __attribute__((aligned(8))) #endif #ifndef __ASSEMBLY__ From 782821bcb0e1a7e8db090401b775a7b4622fd623 Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Wed, 31 Jan 2007 17:22:00 +0000 Subject: [PATCH 11/49] [HVM] Save/restore: clean up the new hypercall interface Pass a buffer and size through instead of fixed-size structure. Signed-off-by: Zhai Edwin Signed-off-by: Tim Deegan --- tools/libxc/xc_domain.c | 36 ++++++++++-------- tools/libxc/xc_hvm_restore.c | 21 ++++++----- tools/libxc/xc_hvm_save.c | 40 ++++++++++---------- tools/libxc/xenctrl.h | 12 ++++-- xen/arch/x86/domctl.c | 62 ++++++++++++++++--------------- xen/arch/x86/hvm/intercept.c | 6 +-- xen/include/asm-x86/hvm/domain.h | 2 - xen/include/asm-x86/hvm/support.h | 7 ++++ xen/include/public/domctl.h | 11 +----- 9 files changed, 104 insertions(+), 93 deletions(-) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 6b67450261..e557f43f13 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -241,45 +241,49 @@ int xc_domain_getinfolist(int xc_handle, /* get info from hvm guest for save */ int xc_domain_hvm_getcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt) + uint8_t *ctxt_buf, + uint32_t size) { - int rc; + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_gethvmcontext; domctl.domain = (domid_t)domid; - set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt); + domctl.u.hvmcontext.size = size; + set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf); - if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 ) - return rc; + if ( (ret = lock_pages(ctxt_buf, size)) != 0 ) + return ret; - rc = do_domctl(xc_handle, &domctl); + ret = do_domctl(xc_handle, &domctl); - safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt)); + unlock_pages(ctxt_buf, size); - return rc; + return (ret < 0 ? -1 : domctl.u.hvmcontext.size); } /* set info to hvm guest for restore */ int xc_domain_hvm_setcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt) + uint8_t *ctxt_buf, + uint32_t size) { - int rc; + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_sethvmcontext; domctl.domain = domid; - set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt); + domctl.u.hvmcontext.size = size; + set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf); - if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 ) - return rc; + if ( (ret = lock_pages(ctxt_buf, size)) != 0 ) + return ret; - rc = do_domctl(xc_handle, &domctl); + ret = do_domctl(xc_handle, &domctl); - safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt)); + unlock_pages(ctxt_buf, size); - return rc; + return ret; } int xc_vcpu_getcontext(int xc_handle, diff --git a/tools/libxc/xc_hvm_restore.c b/tools/libxc/xc_hvm_restore.c index b2b9999fea..6622b49f79 100644 --- a/tools/libxc/xc_hvm_restore.c +++ b/tools/libxc/xc_hvm_restore.c @@ -87,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io_fd, xc_dominfo_t info; unsigned int rc = 1, n, i; uint32_t rec_len, nr_vcpus; - hvm_domain_context_t hvm_ctxt; + uint8_t *hvm_buf = NULL; unsigned long long v_end, memsize; unsigned long shared_page_nr; @@ -128,8 +128,7 @@ int xc_hvm_restore(int xc_handle, int io_fd, } - p2m = malloc(max_pfn * sizeof(xen_pfn_t)); - + p2m = malloc(max_pfn * sizeof(xen_pfn_t)); if (p2m == NULL) { ERROR("memory alloc failed"); errno = ENOMEM; @@ -297,18 +296,21 @@ int xc_hvm_restore(int xc_handle, int io_fd, ERROR("error read hvm context size!\n"); goto out; } - if (rec_len != sizeof(hvm_ctxt)) { - ERROR("hvm context size dismatch!\n"); + + hvm_buf = malloc(rec_len); + if (hvm_buf == NULL) { + ERROR("memory alloc for hvm context buffer failed"); + errno = ENOMEM; goto out; } - if (!read_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt))) { - ERROR("error read hvm context!\n"); + if (!read_exact(io_fd, hvm_buf, rec_len)) { + ERROR("error read hvm buffer!\n"); goto out; } - if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, &hvm_ctxt))) { - ERROR("error set hvm context!\n"); + if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len))) { + ERROR("error set hvm buffer!\n"); goto out; } @@ -361,6 +363,7 @@ int xc_hvm_restore(int xc_handle, int io_fd, if ( (rc != 0) && (dom != 0) ) xc_domain_destroy(xc_handle, dom); free(p2m); + free(hvm_buf); DPRINTF("Restore exit with rc=%d\n", rc); diff --git a/tools/libxc/xc_hvm_save.c b/tools/libxc/xc_hvm_save.c index 3d08a509d9..d9cca58d07 100644 --- a/tools/libxc/xc_hvm_save.c +++ b/tools/libxc/xc_hvm_save.c @@ -32,6 +32,12 @@ #include "xg_private.h" #include "xg_save_restore.h" +/* + * Size of a buffer big enough to take the HVM state of a domain. + * Ought to calculate this a bit more carefully, or maybe ask Xen. + */ +#define HVM_CTXT_SIZE 8192 + /* ** Default values for important tuning parameters. Can override by passing ** non-zero replacement values to xc_hvm_save(). @@ -279,8 +285,8 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, unsigned long *pfn_type = NULL; unsigned long *pfn_batch = NULL; - /* A copy of hvm domain context */ - hvm_domain_context_t hvm_ctxt; + /* A copy of hvm domain context buffer*/ + uint8_t *hvm_buf = NULL; /* Live mapping of shared info structure */ shared_info_t *live_shinfo = NULL; @@ -423,8 +429,12 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, to_send = malloc(BITMAP_SIZE); to_skip = malloc(BITMAP_SIZE); - if (!to_send ||!to_skip) { - ERROR("Couldn't allocate to_send array"); + page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn); + + hvm_buf = malloc(HVM_CTXT_SIZE); + + if (!to_send ||!to_skip ||!page_array ||!hvm_buf ) { + ERROR("Couldn't allocate memory"); goto out; } @@ -444,11 +454,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, analysis_phase(xc_handle, dom, max_pfn, to_skip, 0); /* get all the HVM domain pfns */ - if ( (page_array = (unsigned long *) malloc (sizeof(unsigned long) * max_pfn)) == NULL) { - ERROR("HVM:malloc fail!\n"); - goto out; - } - for ( i = 0; i < max_pfn; i++) page_array[i] = i; @@ -655,24 +660,18 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, goto out; } - /* save hvm hypervisor state including pic/pit/shpage */ - if (mlock(&hvm_ctxt, sizeof(hvm_ctxt))) { - ERROR("Unable to mlock ctxt"); - return 1; - } - - if (xc_domain_hvm_getcontext(xc_handle, dom, &hvm_ctxt)){ - ERROR("HVM:Could not get hvm context"); + if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, + HVM_CTXT_SIZE)) == -1) { + ERROR("HVM:Could not get hvm buffer"); goto out; } - rec_size = sizeof(hvm_ctxt); if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) { - ERROR("error write hvm ctxt size"); + ERROR("error write hvm buffer size"); goto out; } - if ( !write_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt)) ) { + if ( !write_exact(io_fd, hvm_buf, rec_size) ) { ERROR("write HVM info failed!\n"); } @@ -722,6 +721,7 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } } + free(hvm_buf); free(page_array); free(pfn_type); diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 26cd638db5..14704e2e92 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -328,13 +328,15 @@ int xc_domain_getinfolist(int xc_handle, * This function returns information about the context of a hvm domain * @parm xc_handle a handle to an open hypervisor interface * @parm domid the domain to get information from - * @parm hvm_ctxt a pointer to a structure to store the execution context of the - * hvm domain + * @parm ctxt_buf a pointer to a structure to store the execution context of + * the hvm domain + * @parm size the size of ctxt_buf in bytes * @return 0 on success, -1 on failure */ int xc_domain_hvm_getcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt); + uint8_t *ctxt_buf, + uint32_t size); /** * This function will set the context for hvm domain @@ -342,11 +344,13 @@ int xc_domain_hvm_getcontext(int xc_handle, * @parm xc_handle a handle to an open hypervisor interface * @parm domid the domain to set the hvm domain context for * @parm hvm_ctxt pointer to the the hvm context with the values to set + * @parm size the size of hvm_ctxt in bytes * @return 0 on success, -1 on failure */ int xc_domain_hvm_setcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt); + uint8_t *hvm_ctxt, + uint32_t size); /** * This function returns information about the execution context of a diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index db18c7cecf..d73ae65bd5 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -288,71 +288,73 @@ long arch_do_domctl( case XEN_DOMCTL_sethvmcontext: { - struct hvm_domain_context *c; + struct hvm_domain_context c; struct domain *d; + c.cur = 0; + c.size = domctl->u.hvmcontext.size; + c.data = NULL; + ret = -ESRCH; if ( (d = get_domain_by_id(domctl->domain)) == NULL ) break; - ret = -ENOMEM; - if ( (c = xmalloc(struct hvm_domain_context)) == NULL ) - goto sethvmcontext_out; - - ret = -EFAULT; - if ( copy_from_guest(c, domctl->u.hvmcontext.ctxt, 1) != 0 ) - goto sethvmcontext_out; - c->size = sizeof (c->data); - c->cur = 0; - ret = -EINVAL; if ( !is_hvm_domain(d) ) goto sethvmcontext_out; - ret = hvm_load(d, c); + ret = -ENOMEM; + if ( (c.data = xmalloc_bytes(c.size)) == NULL ) + goto sethvmcontext_out; - xfree(c); + ret = -EFAULT; + if ( copy_from_guest(c.data, domctl->u.hvmcontext.buffer, c.size) != 0) + goto sethvmcontext_out; + + ret = hvm_load(d, &c); sethvmcontext_out: - put_domain(d); + if ( c.data != NULL ) + xfree(c.data); + put_domain(d); } break; case XEN_DOMCTL_gethvmcontext: { - struct hvm_domain_context *c; + struct hvm_domain_context c; struct domain *d; + c.cur = 0; + c.size = domctl->u.hvmcontext.size; + c.data = NULL; + ret = -ESRCH; if ( (d = get_domain_by_id(domctl->domain)) == NULL ) break; - ret = -ENOMEM; - if ( (c = xmalloc(struct hvm_domain_context)) == NULL ) - goto gethvmcontext_out; - memset(c, 0, sizeof(*c)); - c->size = sizeof (c->data); - - ret = -ENODATA; + ret = -EINVAL; if ( !is_hvm_domain(d) ) goto gethvmcontext_out; - - ret = 0; - if (hvm_save(d, c) != 0) - ret = -EFAULT; - if ( copy_to_guest(domctl->u.hvmcontext.ctxt, c, 1) ) - ret = -EFAULT; + ret = -ENOMEM; + if ( (c.data = xmalloc_bytes(c.size)) == NULL ) + goto gethvmcontext_out; - xfree(c); + ret = hvm_save(d, &c); + + if ( copy_to_guest(domctl->u.hvmcontext.buffer, c.data, c.size) != 0 ) + ret = -EFAULT; if ( copy_to_guest(u_domctl, domctl, 1) ) ret = -EFAULT; gethvmcontext_out: - put_domain(d); + if ( c.data != NULL ) + xfree(c.data); + put_domain(d); } break; diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c index 802f67e077..f130a252ab 100644 --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -205,7 +205,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h) if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 ) { gdprintk(XENLOG_ERR, "HVM save: failed to write header\n"); - return -1; + return -EFAULT; } /* Save all available kinds of state */ @@ -219,7 +219,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h) { gdprintk(XENLOG_ERR, "HVM save: failed to save type %"PRIu16"\n", i); - return -1; + return -EFAULT; } } } @@ -229,7 +229,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h) { /* Run out of data */ gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n"); - return -1; + return -EFAULT; } /* Save macros should not have let us overrun */ diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h index f0b818462b..8c5c5f2748 100644 --- a/xen/include/asm-x86/hvm/domain.h +++ b/xen/include/asm-x86/hvm/domain.h @@ -49,8 +49,6 @@ struct hvm_domain { spinlock_t pbuf_lock; uint64_t params[HVM_NR_PARAMS]; - - struct hvm_domain_context *hvm_ctxt; }; #endif /* __ASM_X86_HVM_DOMAIN_H__ */ diff --git a/xen/include/asm-x86/hvm/support.h b/xen/include/asm-x86/hvm/support.h index 066fba87d0..6d57140fae 100644 --- a/xen/include/asm-x86/hvm/support.h +++ b/xen/include/asm-x86/hvm/support.h @@ -123,6 +123,13 @@ extern unsigned int opt_hvm_debug_level; * Save/restore support */ +/* Marshalling and unmarshalling uses a buffer with size and cursor. */ +typedef struct hvm_domain_context { + uint32_t cur; + uint32_t size; + uint8_t *data; +} hvm_domain_context_t; + /* Marshalling an entry: check space and fill in the header */ static inline int _hvm_init_entry(struct hvm_domain_context *h, uint16_t tc, uint16_t inst, uint32_t len) diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index ad255f24d1..93f44f3ba5 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -386,18 +386,11 @@ struct xen_domctl_settimeoffset { typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t); -#define HVM_CTXT_SIZE 8192 -typedef struct hvm_domain_context { - uint32_t cur; - uint32_t size; - uint8_t data[HVM_CTXT_SIZE]; -} hvm_domain_context_t; -DEFINE_XEN_GUEST_HANDLE(hvm_domain_context_t); - #define XEN_DOMCTL_gethvmcontext 33 #define XEN_DOMCTL_sethvmcontext 34 typedef struct xen_domctl_hvmcontext { - XEN_GUEST_HANDLE_64(hvm_domain_context_t) ctxt; /* IN/OUT */ + uint32_t size; /* IN/OUT: size of buffer / bytes filled */ + XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT */ } xen_domctl_hvmcontext_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t); From 05e5154038b4614f4b7d6f43eb7e8b741a014608 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 31 Jan 2007 17:58:00 +0000 Subject: [PATCH 12/49] [XEN] Fix perfc after 13756:56377f5ce588 64 bit guest handles can no longer be passed as parameters to functions. Extract such parameters into a regular guest handle first. Signed-off-by: Ian Campbell --- xen/common/perfc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/xen/common/perfc.c b/xen/common/perfc.c index bbff5d7b5c..d5bcd9b2e1 100644 --- a/xen/common/perfc.c +++ b/xen/common/perfc.c @@ -136,8 +136,8 @@ static xen_sysctl_perfc_desc_t perfc_d[NR_PERFCTRS]; static xen_sysctl_perfc_val_t *perfc_vals; static int perfc_nbr_vals; static int perfc_init = 0; -static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc, - XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val) +static int perfc_copy_info(XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc, + XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val) { unsigned int i, j; unsigned int v = 0; @@ -217,20 +217,29 @@ static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc, int perfc_control(xen_sysctl_perfc_op_t *pc) { static DEFINE_SPINLOCK(lock); + XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc; + XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val; int rc; + /* + * 64 bit guest handles cannot be passed as parameters to + * functions so cast to a regular guest handle. + */ + desc = guest_handle_cast(pc->desc, xen_sysctl_perfc_desc_t); + val = guest_handle_cast(pc->val, xen_sysctl_perfc_val_t); + spin_lock(&lock); switch ( pc->cmd ) { case XEN_SYSCTL_PERFCOP_reset: - perfc_copy_info(pc->desc, pc->val); + perfc_copy_info(desc, val); perfc_reset(0); rc = 0; break; case XEN_SYSCTL_PERFCOP_query: - perfc_copy_info(pc->desc, pc->val); + perfc_copy_info(desc, val); rc = 0; break; From 3290ac980d2be1fc63b84f90b0a21a510edd5b8a Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Wed, 31 Jan 2007 18:15:00 +0000 Subject: [PATCH 13/49] [HVM] Save/restore: save HPET registers Signed-off-by: Tim Deegan --- xen/arch/x86/hvm/hpet.c | 42 ++++++++++++++++++++++++++++++----- xen/include/asm-x86/hvm/vpt.h | 25 ++++----------------- xen/include/public/hvm/save.h | 32 +++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 28 deletions(-) diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index b0f6413669..dcc6ca3a4d 100644 --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -279,7 +279,7 @@ static void hpet_write( (h->hpet.timers[tn].config & HPET_TN_SETVAL) ) h->hpet.timers[tn].cmp = new_val; else - h->period[tn] = new_val; + h->hpet.period[tn] = new_val; h->hpet.timers[tn].config &= ~HPET_TN_SETVAL; if ( hpet_enabled(h) && timer_enabled(h, tn) ) hpet_set_timer(h, tn); @@ -289,7 +289,7 @@ static void hpet_write( case HPET_T1_ROUTE: case HPET_T2_ROUTE: tn = (addr - HPET_T0_ROUTE) >> 5; - h->hpet.timers[tn].hpet_fsb[0] = new_val; + h->hpet.timers[tn].fsb = new_val; break; default: @@ -351,21 +351,22 @@ static void hpet_timer_fn(void *opaque) hpet_route_interrupt(h, tn); - if ( timer_is_periodic(h, tn) && (h->period[tn] != 0) ) + if ( timer_is_periodic(h, tn) && (h->hpet.period[tn] != 0) ) { uint64_t mc = hpet_read_maincounter(h); if ( timer_is_32bit(h, tn) ) { while ( hpet_time_after(mc, h->hpet.timers[tn].cmp) ) h->hpet.timers[tn].cmp = (uint32_t)( - h->hpet.timers[tn].cmp + h->period[tn]); + h->hpet.timers[tn].cmp + h->hpet.period[tn]); } else { while ( hpet_time_after64(mc, h->hpet.timers[tn].cmp) ) - h->hpet.timers[tn].cmp += h->period[tn]; + h->hpet.timers[tn].cmp += h->hpet.period[tn]; } - set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn])); + set_timer(&h->timers[tn], + NOW() + hpet_tick_to_ns(h, h->hpet.period[tn])); } } @@ -378,6 +379,35 @@ void hpet_migrate_timers(struct vcpu *v) migrate_timer(&h->timers[i], v->processor); } +static int hpet_save(struct domain *d, hvm_domain_context_t *h) +{ + HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet; + + /* Save the HPET registers */ + return hvm_save_entry(HPET, 0, h, &hp->hpet); +} + +static int hpet_load(struct domain *d, hvm_domain_context_t *h) +{ + HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet; + int i; + + /* Reload the HPET registers */ + if ( hvm_load_entry(HPET, h, &hp->hpet) ) + return -EINVAL; + + /* Recalculate the offset between the main counter and guest time */ + hp->mc_offset = hp->hpet.mc64 - hvm_get_guest_time(hp->vcpu); + + /* Restart the timers */ + for ( i = 0; i < HPET_TIMER_NUM; i++ ) + hpet_set_timer(hp, i); + + return 0; +} + +HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load); + void hpet_init(struct vcpu *v) { HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet; diff --git a/xen/include/asm-x86/hvm/vpt.h b/xen/include/asm-x86/hvm/vpt.h index f51e16948a..7868404426 100644 --- a/xen/include/asm-x86/hvm/vpt.h +++ b/xen/include/asm-x86/hvm/vpt.h @@ -31,22 +31,6 @@ #include #include -#define HPET_TIMER_NUM 3 /* 3 timers supported now */ -struct HPET { - uint64_t capability; /* capabilities */ - uint64_t res0; /* reserved */ - uint64_t config; /* configuration */ - uint64_t res1; /* reserved */ - uint64_t isr; /* interrupt status reg */ - uint64_t res2[25]; /* reserved */ - uint64_t mc64; /* main counter */ - uint64_t res3; /* reserved */ - struct { /* timers */ - uint64_t config; /* configuration/cap */ - uint64_t cmp; /* comparator */ - uint64_t hpet_fsb[2]; /* FSB route, not supported now */ - } timers[HPET_TIMER_NUM]; -}; struct HPETState; struct HPET_timer_fn_info { @@ -55,11 +39,10 @@ struct HPET_timer_fn_info { }; typedef struct HPETState { - struct HPET hpet; - struct vcpu *vcpu; - uint64_t tsc_freq; - uint64_t mc_offset; - uint64_t period[HPET_TIMER_NUM]; + struct hvm_hw_hpet hpet; + struct vcpu *vcpu; + uint64_t tsc_freq; + uint64_t mc_offset; struct timer timers[HPET_TIMER_NUM]; struct HPET_timer_fn_info timer_fn_info[HPET_TIMER_NUM]; } HPETState; diff --git a/xen/include/public/hvm/save.h b/xen/include/public/hvm/save.h index fbf160b8ef..48dfc187f0 100644 --- a/xen/include/public/hvm/save.h +++ b/xen/include/public/hvm/save.h @@ -381,10 +381,40 @@ struct hvm_hw_rtc { DECLARE_HVM_SAVE_TYPE(RTC, 9, struct hvm_hw_rtc); +/* + * HPET + */ + +#define HPET_TIMER_NUM 3 /* 3 timers supported now */ +struct hvm_hw_hpet { + /* Memory-mapped, software visible registers */ + uint64_t capability; /* capabilities */ + uint64_t res0; /* reserved */ + uint64_t config; /* configuration */ + uint64_t res1; /* reserved */ + uint64_t isr; /* interrupt status reg */ + uint64_t res2[25]; /* reserved */ + uint64_t mc64; /* main counter */ + uint64_t res3; /* reserved */ + struct { /* timers */ + uint64_t config; /* configuration/cap */ + uint64_t cmp; /* comparator */ + uint64_t fsb; /* FSB route, not supported now */ + uint64_t res4; /* reserved */ + } timers[HPET_TIMER_NUM]; + uint64_t res5[4*(24-HPET_TIMER_NUM)]; /* reserved, up to 0x3ff */ + + /* Hidden register state */ + uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */ +}; + +DECLARE_HVM_SAVE_TYPE(HPET, 10, struct hvm_hw_hpet); + + /* * Largest type-code in use */ -#define HVM_SAVE_CODE_MAX 9 +#define HVM_SAVE_CODE_MAX 10 /* From 165a4a0f9fb1d8ef858a2653fae74fd239d2034b Mon Sep 17 00:00:00 2001 From: Travis Betak Date: Wed, 31 Jan 2007 19:37:44 +0000 Subject: [PATCH 14/49] [HVM][SVM] Updated the SVM V_TPR register on MMIO writes to the VLAPIC TPR The SVM architecture includes a virtual TPR register. This patch updates this register on MMIO writes to the HVM Virtual APIC. VT does not have this register as far as I know so a stub is added in the VT code. Signed-off-by: Travis Betak --- xen/arch/x86/hvm/svm/svm.c | 10 ++++++++++ xen/arch/x86/hvm/vlapic.c | 1 + xen/arch/x86/hvm/vmx/vmx.c | 7 +++++++ xen/include/asm-x86/hvm/hvm.h | 11 +++++++++++ 4 files changed, 29 insertions(+) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index b2637a7807..a35b84848d 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -660,6 +660,13 @@ void svm_update_guest_cr3(struct vcpu *v) v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; } +static void svm_update_vtpr(struct vcpu *v, unsigned long value) +{ + struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + + vmcb->vintr.fields.tpr = value & 0x0f; +} + unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num) { switch ( num ) @@ -1048,6 +1055,8 @@ int start_svm(void) hvm_funcs.update_host_cr3 = svm_update_host_cr3; hvm_funcs.update_guest_cr3 = svm_update_guest_cr3; + hvm_funcs.update_vtpr = svm_update_vtpr; + hvm_funcs.stts = svm_stts; hvm_funcs.set_tsc_offset = svm_set_tsc_offset; @@ -1939,6 +1948,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs) case 8: vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4)); + vmcb->vintr.fields.tpr = value & 0x0F; break; default: diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 4ac13ba9c4..b38dee2e85 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -593,6 +593,7 @@ static void vlapic_write(struct vcpu *v, unsigned long address, { case APIC_TASKPRI: vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff); + hvm_update_vtpr(v, (val >> 4) & 0x0f); break; case APIC_EOI: diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index c3a2ed4585..8a8691c383 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -986,6 +986,11 @@ static void vmx_inject_exception( v->arch.hvm_vmx.cpu_cr2 = cr2; } +static void vmx_update_vtpr(struct vcpu *v, unsigned long value) +{ + /* VMX doesn't have a V_TPR field */ +} + /* Setup HVM interfaces */ static void vmx_setup_hvm_funcs(void) { @@ -1011,6 +1016,8 @@ static void vmx_setup_hvm_funcs(void) hvm_funcs.update_host_cr3 = vmx_update_host_cr3; hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3; + hvm_funcs.update_vtpr = vmx_update_vtpr; + hvm_funcs.stts = vmx_stts; hvm_funcs.set_tsc_offset = vmx_set_tsc_offset; diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 953cc60b3c..1e8093dafa 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -114,6 +114,11 @@ struct hvm_function_table { */ void (*update_guest_cr3)(struct vcpu *v); + /* + * Reflect the virtual APIC's value in the guest's V_TPR register + */ + void (*update_vtpr)(struct vcpu *v, unsigned long value); + /* * Update specifics of the guest state: * 1) TS bit in guest cr0 @@ -203,6 +208,12 @@ hvm_update_host_cr3(struct vcpu *v) hvm_funcs.update_host_cr3(v); } +static inline void +hvm_update_vtpr(struct vcpu *v, unsigned long value) +{ + hvm_funcs.update_vtpr(v, value); +} + void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3); void hvm_hypercall_page_initialise(struct domain *d, From 5d4e92412ea79ff6a085b756721ddc735a99aa1d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 1 Feb 2007 10:20:34 +0000 Subject: [PATCH 15/49] [LINUX] netfront: Don't call netif_carrier_off until the device is fuly allocated. netif_carrier_off() causes events to be queued on the device so if we subsequently abort the allocation (e.g. due to lack of grant entries) then we crash trying to access the now invalid device. Signed-off-by: Ian Campbell --- linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index f54cc84b89..bd86948fed 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -1935,8 +1935,6 @@ static struct net_device * __devinit create_netdev(struct xenbus_device *dev) np = netdev_priv(netdev); np->xbdev = dev; - netif_carrier_off(netdev); - spin_lock_init(&np->tx_lock); spin_lock_init(&np->rx_lock); @@ -1991,6 +1989,9 @@ static struct net_device * __devinit create_netdev(struct xenbus_device *dev) SET_NETDEV_DEV(netdev, &dev->dev); np->netdev = netdev; + + netif_carrier_off(netdev); + return netdev; exit_free_tx: From 9c4ed974a4505b140782688093bc54d750716e38 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 1 Feb 2007 10:21:42 +0000 Subject: [PATCH 16/49] [TOOLS] Remove a debug message which is spamming the logs during live migration. Signed-off-by: Ian Campbell --- tools/libxc/xc_linux_save.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index de1c605002..0d8f045951 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -536,8 +536,6 @@ static int canonicalize_pagetable(unsigned long type, unsigned long pfn, if (!MFN_IS_IN_PSEUDOPHYS_MAP(mfn)) { /* This will happen if the type info is stale which is quite feasible under live migration */ - DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n", - type, i, (unsigned long long)pte, mfn); pfn = 0; /* zap it - we'll retransmit this page later */ race = 1; /* inform the caller of race; fatal if !live */ } else From 6880c9f6b778acf031f54fb8f2b44730db085434 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 11:42:50 +0000 Subject: [PATCH 17/49] Copy the definition of DOM0_UUID into XenDomain so that we don't need to import large swathes of the server to run the Xen-API tests. Signed-off-by: Ewan Mellor --- tools/xm-test/lib/XmTestLib/XenDomain.py | 3 +++ tools/xm-test/tests/vtpm/09_vtpm-xapi.py | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/xm-test/lib/XmTestLib/XenDomain.py b/tools/xm-test/lib/XmTestLib/XenDomain.py index 3fcfcea4f1..09d6f4c764 100644 --- a/tools/xm-test/lib/XmTestLib/XenDomain.py +++ b/tools/xm-test/lib/XmTestLib/XenDomain.py @@ -33,6 +33,9 @@ from DomainTracking import * from acm import * +DOM0_UUID = "00000000-0000-0000-0000-000000000000" + + def getDefaultKernel(): return arch.getDefaultKernel() diff --git a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py index 4798dc13c6..6a17c51045 100644 --- a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py +++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py @@ -13,7 +13,6 @@ from XmTestLib import xapi from XmTestLib.XenAPIDomain import XmTestAPIDomain from XmTestLib import * -from xen.xend import XendDomain from vtpm_utils import * import commands import os @@ -28,7 +27,7 @@ except Exception, e: vm_uuid = domain.get_uuid() vtpmcfg = {} -vtpmcfg['backend'] = XendDomain.DOM0_UUID +vtpmcfg['backend'] = DOM0_UUID vtpmcfg['VM'] = vm_uuid session = xapi.connect() From 6552100e95eff8719a53ed1d1710a149e756aa05 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 1 Feb 2007 13:44:35 +0000 Subject: [PATCH 18/49] safe_str*() functions check their destination argument is a character-array type. Fix two bad callers. Signed-off-by: Keir Fraser --- xen/arch/x86/dmi_scan.c | 2 +- xen/common/kexec.c | 2 +- xen/include/xen/string.h | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c index 2d49d412fc..b867febc1e 100644 --- a/xen/arch/x86/dmi_scan.c +++ b/xen/arch/x86/dmi_scan.c @@ -159,7 +159,7 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) return; dmi_ident[slot] = alloc_bootmem(strlen(p)+1); if(dmi_ident[slot]) - safe_strcpy(dmi_ident[slot], p); + strlcpy(dmi_ident[slot], p, strlen(p)+1); else printk(KERN_ERR "dmi_save_ident: out of memory.\n"); } diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 04a1468d3a..9e6e1858a4 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -131,7 +131,7 @@ __initcall(register_crashdump_trigger); static void setup_note(Elf_Note *n, const char *name, int type, int descsz) { - safe_strcpy(ELFNOTE_NAME(n), name); + strlcpy(ELFNOTE_NAME(n), name, INT_MAX); n->namesz = strlen(name); n->descsz = descsz; n->type = type; diff --git a/xen/include/xen/string.h b/xen/include/xen/string.h index d0c23a1411..f26b9949b2 100644 --- a/xen/include/xen/string.h +++ b/xen/include/xen/string.h @@ -82,8 +82,16 @@ extern void * memchr(const void *,int,__kernel_size_t); } #endif +#define is_char_array(x) __builtin_types_compatible_p(typeof(x), char[]) + /* safe_xxx always NUL-terminates and returns !=0 if result is truncated. */ -#define safe_strcpy(d, s) (strlcpy(d, s, sizeof(d)) >= sizeof(d)) -#define safe_strcat(d, s) (strlcat(d, s, sizeof(d)) >= sizeof(d)) +#define safe_strcpy(d, s) ({ \ + BUILD_BUG_ON(!is_char_array(d)); \ + (strlcpy(d, s, sizeof(d)) >= sizeof(d)); \ +}) +#define safe_strcat(d, s) ({ \ + BUILD_BUG_ON(!is_char_array(d)); \ + (strlcat(d, s, sizeof(d)) >= sizeof(d)); \ +}) #endif /* _LINUX_STRING_H_ */ From d0a7aa6a33391fccc6ef4eedd1b54a4cc1171356 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 1 Feb 2007 14:15:37 +0000 Subject: [PATCH 19/49] Allocate Xen kexec/kdump elfnote sections of the correct size. Signed-off-by: Keir Fraser --- xen/common/kexec.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 9e6e1858a4..ca729d10c1 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -131,12 +131,20 @@ __initcall(register_crashdump_trigger); static void setup_note(Elf_Note *n, const char *name, int type, int descsz) { - strlcpy(ELFNOTE_NAME(n), name, INT_MAX); - n->namesz = strlen(name); + int l = strlen(name) + 1; + strlcpy(ELFNOTE_NAME(n), name, l); + n->namesz = l; n->descsz = descsz; n->type = type; } +static int sizeof_note(const char *name, int descsz) +{ + return (sizeof(Elf_Note) + + ELFNOTE_ALIGN(sizeof(name)) + + ELFNOTE_ALIGN(descsz)); +} + #define kexec_get(x) kexec_get_##x #endif @@ -162,16 +170,17 @@ static int kexec_get(xen)(xen_kexec_range_t *range) static int kexec_get(cpu)(xen_kexec_range_t *range) { int nr = range->nr; - int nr_bytes = sizeof(Elf_Note) * 2 - + ELFNOTE_ALIGN(sizeof(ELF_Prstatus)) - + ELFNOTE_ALIGN(sizeof(crash_xen_core_t)); + int nr_bytes = 0; if ( nr < 0 || nr >= num_present_cpus() ) return -EINVAL; + nr_bytes += sizeof_note("CORE", sizeof(ELF_Prstatus)); + nr_bytes += sizeof_note("Xen", sizeof(crash_xen_core_t)); + /* The Xen info note is included in CPU0's range. */ if ( nr == 0 ) - nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t)); + nr_bytes += sizeof_note("Xen", sizeof(crash_xen_info_t)); if ( per_cpu(crash_notes, nr) == NULL ) { From 73c92d7bb211dd3a8d1c5bb086a70a3232a73d43 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 11:55:31 +0000 Subject: [PATCH 20/49] Change VM.HVM_boot to VM.HVM_boot_policy and VM.HVM_boot_params. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 174 ++++++++++++++++++++-- tools/libxen/include/xen_vm.h | 53 +++++-- tools/libxen/src/xen_vm.c | 87 ++++++++++- tools/libxen/test/test_bindings.c | 11 +- tools/python/xen/xend/XendAPI.py | 44 +++++- tools/python/xen/xend/XendConfig.py | 16 +- tools/python/xen/xend/XendDomainInfo.py | 5 +- tools/python/xen/xm/messages/en/xen-xm.po | 5 +- 8 files changed, 349 insertions(+), 46 deletions(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index edfb8890bd..3868c1fecd 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -1026,9 +1026,9 @@ references to objects with match names virtual machine (or 'guest'). VM booting is controlled by setting one of the two mutually exclusive -groups: "PV", and "HVM". If HVM.boot is the empty string, then paravirtual -domain building and booting will be used; otherwise the VM will be loaded -as an HVM domain, and booted using an emulated BIOS. +groups: "PV", and "HVM". If HVM.boot\_policy is the empty string, then +paravirtual domain building and booting will be used; otherwise the VM will +be loaded as an HVM domain, and booted using an emulated BIOS. When paravirtual booting is in use, the PV/bootloader field indicates the bootloader to use. It may be "pygrub", in which case the platform's @@ -1053,7 +1053,10 @@ ramdisk values will be treated as paths within the control domain. If both PV/bootloader and PV/kernel are empty, then the behaviour is as if PV/bootloader was specified as "pygrub". -When using HVM booting, HVM/boot specifies the order of the boot devices.}} \\ +When using HVM booting, HVM/boot\_policy and HVM/boot\_params specify the +boot handling. Only one policy is currently defined: "BIOS order". In +this case, HVM/boot\_params should contain one key-value pair "order" = "N" +where N is the string that will be passed to QEMU.}} \\ \hline Quals & Field & Type & Description \\ \hline @@ -1089,7 +1092,8 @@ $\mathit{RW}$ & {\tt PV/kernel} & string & path to the kernel \\ $\mathit{RW}$ & {\tt PV/ramdisk} & string & path to the initrd \\ $\mathit{RW}$ & {\tt PV/args} & string & kernel command-line arguments \\ $\mathit{RW}$ & {\tt PV/bootloader\_args} & string & miscellaneous arguments for the bootloader \\ -$\mathit{RW}$ & {\tt HVM/boot} & string & device boot order \\ +$\mathit{RW}$ & {\tt HVM/boot\_policy} & string & HVM boot policy \\ +$\mathit{RW}$ & {\tt HVM/boot\_params} & (string $\rightarrow$ string) Map & HVM boot params \\ $\mathit{RW}$ & {\tt platform/std\_VGA} & bool & emulate standard VGA instead of cirrus logic \\ $\mathit{RW}$ & {\tt platform/serial} & string & redirect serial port to pty \\ $\mathit{RW}$ & {\tt platform/localtime} & bool & set RTC to local time \\ @@ -3297,13 +3301,13 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_HVM\_boot} +\subsubsection{RPC name:~get\_HVM\_boot\_policy} {\bf Overview:} -Get the HVM/boot field of the given VM. +Get the HVM/boot\_policy field of the given VM. \noindent {\bf Signature:} -\begin{verbatim} string get_HVM_boot (session_id s, VM ref self)\end{verbatim} +\begin{verbatim} string get_HVM_boot_policy (session_id s, VM ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -3329,13 +3333,13 @@ value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~set\_HVM\_boot} +\subsubsection{RPC name:~set\_HVM\_boot\_policy} {\bf Overview:} -Set the HVM/boot field of the given VM. +Set the HVM/boot\_policy field of the given VM. \noindent {\bf Signature:} -\begin{verbatim} void set_HVM_boot (session_id s, VM ref self, string value)\end{verbatim} +\begin{verbatim} void set_HVM_boot_policy (session_id s, VM ref self, string value)\end{verbatim} \noindent{\bf Arguments:} @@ -3360,6 +3364,143 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_HVM\_boot\_params} + +{\bf Overview:} +Get the HVM/boot\_params field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_HVM_boot_params (session_id s, VM ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_HVM\_boot\_params} + +{\bf Overview:} +Set the HVM/boot\_params field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} void set_HVM_boot_params (session_id s, VM ref self, (string -> string) Map value)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~add\_to\_HVM\_boot\_params} + +{\bf Overview:} +Add the given key-value pair to the HVM/boot\_params field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} void add_to_HVM_boot_params (session_id s, VM ref self, string key, string value)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + +{\tt string } & key & Key to add \\ \hline + +{\tt string } & value & Value to add \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~remove\_from\_HVM\_boot\_params} + +{\bf Overview:} +Remove the given key and its corresponding value from the HVM/boot\_params +field of the given VM. If the key is not in that Map, then do nothing. + + \noindent {\bf Signature:} +\begin{verbatim} void remove_from_HVM_boot_params (session_id s, VM ref self, string key)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + +{\tt string } & key & Key to remove \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -11758,6 +11899,17 @@ The handle parameter echoes the bad value given. \begin{verbatim}TASK_HANDLE_INVALID(handle)\end{verbatim} \begin{center}\rule{10em}{0.1pt}\end{center} +\subsubsection{VALUE\_NOT\_SUPPORTED} + +You attempted to set a value that is not supported by this implementation. +The fully-qualified field name and the value that you tried to set are +returned. Also returned is a developer-only diagnostic reason. + +\vspace{0.3cm} +{\bf Signature:} +\begin{verbatim}VALUE_NOT_SUPPORTED(field, value, reason)\end{verbatim} +\begin{center}\rule{10em}{0.1pt}\end{center} + \subsubsection{VBD\_HANDLE\_INVALID} You gave an invalid VBD handle. The VBD may have recently been deleted. diff --git a/tools/libxen/include/xen_vm.h b/tools/libxen/include/xen_vm.h index 7a56ba482e..3c23784cf5 100644 --- a/tools/libxen/include/xen_vm.h +++ b/tools/libxen/include/xen_vm.h @@ -42,9 +42,9 @@ * A virtual machine (or 'guest'). * * VM booting is controlled by setting one of the two mutually exclusive - * groups: "PV", and "HVM". If HVM.boot is the empty string, then paravirtual - * domain building and booting will be used; otherwise the VM will be loaded - * as an HVM domain, and booted using an emulated BIOS. + * groups: "PV", and "HVM". If HVM.boot_policy is the empty string, then + * paravirtual domain building and booting will be used; otherwise the VM will + * be loaded as an HVM domain, and booted using an emulated BIOS. * * When paravirtual booting is in use, the PV/bootloader field indicates the * bootloader to use. It may be "pygrub", in which case the platform's @@ -69,7 +69,10 @@ * PV/bootloader and PV/kernel are empty, then the behaviour is as if * PV/bootloader was specified as "pygrub". * - * When using HVM booting, HVM/boot specifies the order of the boot devices. + * When using HVM booting, HVM/boot_policy and HVM/boot_params specify the + * boot handling. Only one policy is currently defined: "BIOS order". In + * this case, HVM/boot_params should contain one key-value pair "order" = "N" + * where N is the string that will be passed to QEMU.. */ @@ -136,7 +139,8 @@ typedef struct xen_vm_record char *pv_ramdisk; char *pv_args; char *pv_bootloader_args; - char *hvm_boot; + char *hvm_boot_policy; + xen_string_string_map *hvm_boot_params; bool platform_std_vga; char *platform_serial; bool platform_localtime; @@ -490,10 +494,17 @@ xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm); /** - * Get the HVM/boot field of the given VM. + * Get the HVM/boot_policy field of the given VM. */ extern bool -xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm); +xen_vm_get_hvm_boot_policy(xen_session *session, char **result, xen_vm vm); + + +/** + * Get the HVM/boot_params field of the given VM. + */ +extern bool +xen_vm_get_hvm_boot_params(xen_session *session, xen_string_string_map **result, xen_vm vm); /** @@ -731,10 +742,34 @@ xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_ /** - * Set the HVM/boot field of the given VM. + * Set the HVM/boot_policy field of the given VM. */ extern bool -xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot); +xen_vm_set_hvm_boot_policy(xen_session *session, xen_vm vm, char *boot_policy); + + +/** + * Set the HVM/boot_params field of the given VM. + */ +extern bool +xen_vm_set_hvm_boot_params(xen_session *session, xen_vm vm, xen_string_string_map *boot_params); + + +/** + * Add the given key-value pair to the HVM/boot_params field of the + * given VM. + */ +extern bool +xen_vm_add_to_hvm_boot_params(xen_session *session, xen_vm vm, char *key, char *value); + + +/** + * Remove the given key and its corresponding value from the + * HVM/boot_params field of the given VM. If the key is not in that Map, then + * do nothing. + */ +extern bool +xen_vm_remove_from_hvm_boot_params(xen_session *session, xen_vm vm, char *key); /** diff --git a/tools/libxen/src/xen_vm.c b/tools/libxen/src/xen_vm.c index 6cbc3670b0..e3f82575bd 100644 --- a/tools/libxen/src/xen_vm.c +++ b/tools/libxen/src/xen_vm.c @@ -145,9 +145,12 @@ static const struct_member xen_vm_record_struct_members[] = { .key = "PV_bootloader_args", .type = &abstract_type_string, .offset = offsetof(xen_vm_record, pv_bootloader_args) }, - { .key = "HVM_boot", + { .key = "HVM_boot_policy", .type = &abstract_type_string, - .offset = offsetof(xen_vm_record, hvm_boot) }, + .offset = offsetof(xen_vm_record, hvm_boot_policy) }, + { .key = "HVM_boot_params", + .type = &abstract_type_string_string_map, + .offset = offsetof(xen_vm_record, hvm_boot_params) }, { .key = "platform_std_VGA", .type = &abstract_type_bool, .offset = offsetof(xen_vm_record, platform_std_vga) }, @@ -216,7 +219,8 @@ xen_vm_record_free(xen_vm_record *record) free(record->pv_ramdisk); free(record->pv_args); free(record->pv_bootloader_args); - free(record->hvm_boot); + free(record->hvm_boot_policy); + xen_string_string_map_free(record->hvm_boot_params); free(record->platform_serial); free(record->pci_bus); xen_string_string_map_free(record->tools_version); @@ -824,7 +828,7 @@ xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm) bool -xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm) +xen_vm_get_hvm_boot_policy(xen_session *session, char **result, xen_vm vm) { abstract_value param_values[] = { @@ -835,7 +839,24 @@ xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm) abstract_type result_type = abstract_type_string; *result = NULL; - XEN_CALL_("VM.get_HVM_boot"); + XEN_CALL_("VM.get_HVM_boot_policy"); + return session->ok; +} + + +bool +xen_vm_get_hvm_boot_params(xen_session *session, xen_string_string_map **result, xen_vm vm) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm } + }; + + abstract_type result_type = abstract_type_string_string_map; + + *result = NULL; + XEN_CALL_("VM.get_HVM_boot_params"); return session->ok; } @@ -1376,17 +1397,67 @@ xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_ bool -xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot) +xen_vm_set_hvm_boot_policy(xen_session *session, xen_vm vm, char *boot_policy) { abstract_value param_values[] = { { .type = &abstract_type_string, .u.string_val = vm }, { .type = &abstract_type_string, - .u.string_val = boot } + .u.string_val = boot_policy } }; - xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL); + xen_call_(session, "VM.set_HVM_boot_policy", param_values, 2, NULL, NULL); + return session->ok; +} + + +bool +xen_vm_set_hvm_boot_params(xen_session *session, xen_vm vm, xen_string_string_map *boot_params) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string_string_map, + .u.set_val = (arbitrary_set *)boot_params } + }; + + xen_call_(session, "VM.set_HVM_boot_params", param_values, 2, NULL, NULL); + return session->ok; +} + + +bool +xen_vm_add_to_hvm_boot_params(xen_session *session, xen_vm vm, char *key, char *value) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = key }, + { .type = &abstract_type_string, + .u.string_val = value } + }; + + xen_call_(session, "VM.add_to_HVM_boot_params", param_values, 3, NULL, NULL); + return session->ok; +} + + +bool +xen_vm_remove_from_hvm_boot_params(xen_session *session, xen_vm vm, char *key) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = key } + }; + + xen_call_(session, "VM.remove_from_HVM_boot_params", param_values, 2, NULL, NULL); return session->ok; } diff --git a/tools/libxen/test/test_bindings.c b/tools/libxen/test/test_bindings.c index 0d6bed18dd..b3ac7f0886 100644 --- a/tools/libxen/test/test_bindings.c +++ b/tools/libxen/test/test_bindings.c @@ -278,6 +278,8 @@ int main(int argc, char **argv) static xen_vm create_new_vm(xen_session *session) { xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1); + vcpus_params->contents[0].key = strdup("weight"); + vcpus_params->contents[0].val = strdup("300"); xen_vm_record vm_record = { .name_label = "NewVM", @@ -294,9 +296,10 @@ static xen_vm create_new_vm(xen_session *session) .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY, .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART, .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE, - .hvm_boot = "", - //.pv_bootloader = "pygrub", - .pv_kernel = "/boot/vmlinuz-2.6.18-xenU", + .hvm_boot_policy = NULL, + .hvm_boot_params = NULL, + .pv_bootloader = "pygrub", + .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen", .pv_ramdisk = "", .pv_args = "root=/dev/sda1 ro", .pv_bootloader_args = "" @@ -306,6 +309,8 @@ static xen_vm create_new_vm(xen_session *session) xen_vm vm; xen_vm_create(session, &vm, &vm_record); + xen_string_string_map_free(vcpus_params); + if (!session->ok) { fprintf(stderr, "VM creation failed.\n"); diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index c1ecf3cab3..0b3c54a89b 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -974,7 +974,8 @@ class XendAPI(object): 'PV_ramdisk', 'PV_args', 'PV_bootloader_args', - 'HVM_boot', + 'HVM_boot_policy', + 'HVM_boot_params', 'platform_std_VGA', 'platform_serial', 'platform_localtime', @@ -1020,7 +1021,8 @@ class XendAPI(object): 'PV_ramdisk', 'PV_args', 'PV_bootloader_args', - 'HVM_boot', + 'HVM_boot_policy', + 'HVM_boot_params', 'platform_std_VGA', 'platform_serial', 'platform_localtime', @@ -1158,8 +1160,11 @@ class XendAPI(object): def VM_get_PV_bootloader_args(self, session, vm_ref): return self.VM_get('PV_bootloader_args', session, vm_ref) - def VM_get_HVM_boot(self, session, vm_ref): - return self.VM_get('HVM_boot', session, vm_ref) + def VM_get_HVM_boot_policy(self, session, vm_ref): + return self.VM_get('HVM_boot_policy', session, vm_ref) + + def VM_get_HVM_boot_params(self, session, vm_ref): + return self.VM_get('HVM_boot_params', session, vm_ref) def VM_get_platform_std_VGA(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) @@ -1246,8 +1251,30 @@ class XendAPI(object): return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref]) return self.VM_set('actions_after_crash', session, vm_ref, action) - def VM_set_HVM_boot(self, session, vm_ref, value): - return self.VM_set('HVM_boot', session, vm_ref, value) + def VM_set_HVM_boot_policy(self, session, vm_ref, value): + if value != "" and value != "BIOS order": + return xen_api_error( + ['VALUE_NOT_SUPPORTED', 'VM.HVM_boot_policy', value, + 'Xend supports only the "BIOS order" boot policy.']) + else: + return self.VM_set('HVM_boot_policy', session, vm_ref, value) + + def VM_set_HVM_boot_params(self, session, vm_ref, value): + return self.VM_set('HVM_boot_params', session, vm_ref, value) + + def VM_add_to_HVM_boot_params(self, session, vm_ref, key, value): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + if 'HVM_boot_params' not in dom.info: + dom.info['HVM_boot_params'] = {} + dom.info['HVM_boot_params'][key] = value + return xen_api_success_void() + + def VM_remove_from_HVM_boot_params(self, session, vm_ref, key): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + if 'HVM_boot_params' in dom.info \ + and key in dom.info['HVM_boot_params']: + del dom.info['HVM_boot_params'][key] + return xen_api_success_void() def VM_set_PV_bootloader(self, session, vm_ref, value): return self.VM_set('PV_bootloader', session, vm_ref, value) @@ -1354,7 +1381,8 @@ class XendAPI(object): 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'), 'PV_args': xeninfo.info.get('PV_args'), 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'), - 'HVM_boot': xeninfo.info.get('HVM_boot'), + 'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'), + 'HVM_boot_params': xeninfo.info.get('HVM_boot_params'), 'platform_std_VGA': xeninfo.get_platform_std_vga(), 'platform_serial': xeninfo.get_platform_serial(), 'platform_localtime': xeninfo.get_platform_localtime(), @@ -1622,7 +1650,7 @@ class XendAPI(object): xendom = XendDomain.instance() return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, 'io_write_kbs')) - + def VIF_get_all(self, session): xendom = XendDomain.instance() vifs = [d.get_vifs() for d in XendDomain.instance().list('all')] diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 81c1323a2c..220c211bad 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -28,7 +28,7 @@ from xen.xend.PrettyPrint import prettyprintstring from xen.xend.XendConstants import DOM_STATE_HALTED log = logging.getLogger("xend.XendConfig") -log.setLevel(logging.WARN) +log.setLevel(logging.DEBUG) """ @@ -164,7 +164,8 @@ XENAPI_CFG_TYPES = { 'PV_ramdisk': str, 'PV_args': str, 'PV_bootloader_args': str, - 'HVM_boot': str, + 'HVM_boot_policy': str, + 'HVM_boot_params': dict, 'platform_std_vga': bool0, 'platform_serial': str, 'platform_localtime': bool0, @@ -361,7 +362,8 @@ class XendConfig(dict): 'PV_ramdisk': '', 'PV_args': '', 'PV_bootloader_args': '', - 'HVM_boot': '', + 'HVM_boot_policy': '', + 'HVM_boot_params': {}, 'memory_static_min': 0, 'memory_dynamic_min': 0, 'shadow_memory': 0, @@ -496,6 +498,12 @@ class XendConfig(dict): log.warn("Unable to parse key %s: %s: %s" % (key, str(val), e)) + # Compatibility hack -- can go soon. + boot_order = sxp.child_value(sxp_cfg, 'HVM_boot') + if boot_order: + cfg['HVM_boot_policy'] = 'BIOS order' + cfg['HVM_boot_params'] = { 'order' : boot_order } + # Parsing the device SXP's. In most cases, the SXP looks # like this: # @@ -768,7 +776,7 @@ class XendConfig(dict): if 'image' in xapi_dict: self['image'].update(xapi_dict['image']) else: - hvm = self['HVM_boot'] != '' + hvm = self['HVM_boot_policy'] != '' self['image']['type'] = hvm and 'hvm' or 'linux' if hvm: self['image']['hvm'] = {'devices': {}} diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index fde0a8f4bc..35d35ba28a 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1648,14 +1648,15 @@ class XendDomainInfo: kernel = self.info['PV_kernel'] ramdisk = self.info['PV_ramdisk'] args = self.info['PV_args'] - boot = self.info['HVM_boot'] + boot = self.info['HVM_boot_policy'] if boot: # HVM booting. self.info['image']['type'] = 'hvm' if not 'devices' in self.info['image']: self.info['image']['devices'] = {} - self.info['image']['devices']['boot'] = boot + self.info['image']['devices']['boot'] = \ + self.info['HVM_boot_params'].get('order', 'dc') elif not blexec and kernel: # Boot from dom0. Nothing left to do -- the kernel and ramdisk # will be picked up by image.py. diff --git a/tools/python/xen/xm/messages/en/xen-xm.po b/tools/python/xen/xm/messages/en/xen-xm.po index d422b2e6b8..aca4aceafe 100644 --- a/tools/python/xen/xm/messages/en/xen-xm.po +++ b/tools/python/xen/xm/messages/en/xen-xm.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Xen-xm 3.0\n" -"PO-Revision-Date: 2007-01-30 17:15+0000\n" +"PO-Revision-Date: 2007-01-31 12:34+0000\n" "Last-Translator: Ewan Mellor \n" "Language-Team: xen-devel \n" "MIME-Version: 1.0\n" @@ -41,6 +41,9 @@ msgstr "The method %(1)s takes %(2)s argument(s) (%(3)s given)." msgid "SESSION_AUTHENTICATION_FAILED" msgstr "Permission denied." +msgid "VALUE_NOT_SUPPORTED" +msgstr "Value \"%(2)s\" for %(1)s is not supported by this server. The server said \"%(3)s\"." + msgid "HOST_CPU_HANDLE_INVALID" msgstr "The host_cpu handle %(1)s is invalid." From a84714b11ccd74c59d1034cf709e14e05ace4601 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 12:48:53 +0000 Subject: [PATCH 21/49] Break out the Python path interrogation into a separate script. This has the advantage that the temporary path manipulation cannot affect the main script, and that it can be shared with other programs, such as xm-test. Signed-off-by: Ewan Mellor --- tools/misc/Makefile | 2 +- tools/misc/xen-python-path | 41 ++++++++++++++++++++++++++++++++++++++ tools/misc/xend | 22 ++++++-------------- 3 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 tools/misc/xen-python-path diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 13c95b56f7..80b52c0063 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -12,7 +12,7 @@ HDRS = $(wildcard *.h) TARGETS = xenperf xc_shadow INSTALL_BIN = $(TARGETS) xencons -INSTALL_SBIN = netfix xm xen-bugtool xend xenperf +INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf .PHONY: all all: build diff --git a/tools/misc/xen-python-path b/tools/misc/xen-python-path new file mode 100644 index 0000000000..03c572b8ef --- /dev/null +++ b/tools/misc/xen-python-path @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- mode: python; -*- +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2007 XenSource Inc. +#============================================================================ + + +# 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' + +import os +import os.path +import sys + +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 + print os.path.join(xen.util.auxbin.libpath(), p) + sys.exit(0) + +print >>sys.stderr, "Cannot find Xen Python modules." +sys.exit(1) diff --git a/tools/misc/xend b/tools/misc/xend index 0832f84010..860dcbcd25 100644 --- a/tools/misc/xend +++ b/tools/misc/xend @@ -31,23 +31,13 @@ import signal import time import commands +result = commands.getstatusoutput(os.path.join(os.path.dirname(sys.argv[0]), + 'xen-python-path')) +if result[0] != 0: + print >>sys.stderr, result[1] + sys.exit(1) -# 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 = os.path.join(xen.util.auxbin.libpath(), p) - sys.path = sys.path[:-1] - sys.path.append(libpath) - break +sys.path.append(result[1]) from xen.xend.server import SrvDaemon From 9ed702329188d028ff588a5e0f4bd8956b31222d Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Thu, 1 Feb 2007 13:14:43 +0000 Subject: [PATCH 22/49] [XEN] Wrap compat XLAT_ macros in "do { } while (0)". This unbreaks code like if ( !IS_COMPAT(dom) ) memcpy(); else XLAT_foo(); Signed-off-by: Tim Deegan --- xen/tools/get-fields.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xen/tools/get-fields.sh b/xen/tools/get-fields.sh index ccf5675c02..0936bb8fe3 100644 --- a/xen/tools/get-fields.sh +++ b/xen/tools/get-fields.sh @@ -227,7 +227,7 @@ handle_array() { build_body() { echo - echo -n "#define XLAT_$1(_d_, _s_)" + echo -n "#define XLAT_$1(_d_, _s_) do {" local level=1 fields= id= array= arrlvl=1 array_type= type= token for token in $2 do @@ -303,6 +303,8 @@ build_body() { esac test -z "$fields" || fields="$fields $token" done + echo " \\" + echo "} while (0)" echo "" } From edb08a7488e85500f1b96e82965a99745e327f5d Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 14:41:58 +0000 Subject: [PATCH 23/49] Use the new xen-python-path to set PYTHONPATH, rather than trying to do it in XmTestLib.__init__ (and getting it wrong). Signed-off-by: Ewan Mellor --- tools/xm-test/configure.ac | 4 +++- tools/xm-test/lib/XmTestLib/__init__.py | 20 -------------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/tools/xm-test/configure.ac b/tools/xm-test/configure.ac index ffbf146f34..d3c651a250 100644 --- a/tools/xm-test/configure.ac +++ b/tools/xm-test/configure.ac @@ -11,10 +11,12 @@ AC_PROG_CC #AC_PROG_INSTALL AC_CHECK_PROG([LILO], lilo, lilo, "no", [$PATH]) +XEN_PYTHON_PATH=$(/usr/sbin/xen-python-path) + # Right now, we can assume that the lib/ directory # is two levels above the tests TESTLIB=../../lib -TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB" +TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB:$XEN_PYTHON_PATH" AC_ARG_ENABLE(hvm-support, [[ --enable-hvm-support enable hardware virtual machine assist]], diff --git a/tools/xm-test/lib/XmTestLib/__init__.py b/tools/xm-test/lib/XmTestLib/__init__.py index f638003b08..40aacf7ecd 100644 --- a/tools/xm-test/lib/XmTestLib/__init__.py +++ b/tools/xm-test/lib/XmTestLib/__init__.py @@ -3,26 +3,6 @@ # Author: Dan Smith # -import os.path -import sys - -# 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 Console import * from Test import * from Xm import * From 479f9c8a5d0a0d61efed553218febbea3a82162c Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Thu, 1 Feb 2007 15:03:37 +0000 Subject: [PATCH 24/49] [PYGRUB] Invoke pygrub with TERM=vt100 Signed-off-by: Tim Deegan --- tools/pygrub/src/pygrub | 5 ++++- tools/python/xen/xend/XendBootloader.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index cf0efcb185..9b3d15f675 100644 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -197,7 +197,10 @@ class Grub: self.screen = curses.initscr() self.screen.timeout(1000) if hasattr(curses, 'use_default_colors'): - curses.use_default_colors() + try: + curses.use_default_colors() + except: + pass # Not important if we can't use colour enable_cursor(False) self.entry_win = curses.newwin(10, 74, 2, 1) self.text_win = curses.newwin(10, 70, 12, 5) diff --git a/tools/python/xen/xend/XendBootloader.py b/tools/python/xen/xend/XendBootloader.py index 29644c5004..4220cde6eb 100644 --- a/tools/python/xen/xend/XendBootloader.py +++ b/tools/python/xen/xend/XendBootloader.py @@ -97,7 +97,9 @@ def bootloader(blexec, disk, dom, quiet = False, blargs = '', kernel = '', try: log.debug("Launching bootloader as %s." % str(args)) - os.execvp(args[0], args) + env = os.environ.copy() + env['TERM'] = 'vt100' + os.execvpe(args[0], args, env) except OSError, e: print e pass From d6f8b69ced6deb05dc56ad4363cfa9e55ddcd493 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 15:30:22 +0000 Subject: [PATCH 25/49] Fix HVM save/restore wrt console handling. From Tim Deegan . Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendConfig.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 220c211bad..7753c89cb1 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -679,6 +679,9 @@ class XendConfig(dict): if self['devices'][console_uuid][1].get('protocol') == 'rfb': has_rfb = True break + if self['devices'][console_uuid][0] == 'vfb': + has_rfb = True + break if not has_rfb: dev_config = ['vfb'] From f9d2dae496ea8602c3b3573e7d203eddc6decd36 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 15:31:34 +0000 Subject: [PATCH 26/49] Fix merge conflict between new HVM console handling and new HVM boot handling. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/vfbif.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py index 0bd1b92bf3..fb510de25f 100644 --- a/tools/python/xen/xend/server/vfbif.py +++ b/tools/python/xen/xend/server/vfbif.py @@ -46,7 +46,7 @@ class VfbifController(DevController): def createDevice(self, config): DevController.createDevice(self, config) - if self.vm.info.get('HVM_boot'): + if self.vm.info.get('HVM_boot_policy'): # is HVM, so qemu-dm will handle the vfb. return @@ -90,7 +90,7 @@ class VfbifController(DevController): def waitForDevice(self, devid): - if self.vm.info.get('HVM_boot'): + if self.vm.info.get('HVM_boot_policy'): log.debug('skip waiting for HVM vfb') # is a qemu-dm managed device, don't wait for hotplug for these. return @@ -110,7 +110,7 @@ class VfbifController(DevController): raise VmError('Refusing to reconfigure device vfb:%d' % devid) def destroyDevice(self, devid, force): - if self.vm.info.get('HVM_boot'): + if self.vm.info.get('HVM_boot_policy'): # remove the backend xenstore entries for HVM guests no matter # what DevController.destroyDevice(self, devid, True) @@ -119,7 +119,7 @@ class VfbifController(DevController): def migrate(self, deviceConfig, network, dst, step, domName): - if self.vm.info.get('HVM_boot'): + if self.vm.info.get('HVM_boot_policy'): return 0 return DevController.migrate(self, deviceConfig, network, dst, step, domName) @@ -136,14 +136,14 @@ class VkbdifController(DevController): return (devid, back, front) def waitForDevice(self, config): - if self.vm.info.get('HVM_boot'): + if self.vm.info.get('HVM_boot_policy'): # is a qemu-dm managed device, don't wait for hotplug for these. return DevController.waitForDevice(self, config) def destroyDevice(self, devid, force): - if self.vm.info.get('HVM_boot'): + if self.vm.info.get('HVM_boot_policy'): # remove the backend xenstore entries for HVM guests no matter # what DevController.destroyDevice(self, devid, True) @@ -151,7 +151,7 @@ class VkbdifController(DevController): DevController.destroyDevice(self, devid, force) def migrate(self, deviceConfig, network, dst, step, domName): - if self.vm.info.get('HVM_boot'): + if self.vm.info.get('HVM_boot_policy'): return 0 return DevController.migrate(self, deviceConfig, network, dst, step, domName) From c3bf42e922450f25a90babf16655f12ecd1449de Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 15:32:16 +0000 Subject: [PATCH 27/49] Fix handling of HVM boot. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendConfig.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 7753c89cb1..b8cbd8cd7c 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -125,8 +125,7 @@ XENAPI_HVM_CFG = { 'platform_std_vga': 'stdvga', 'platform_serial' : 'serial', 'platform_localtime': 'localtime', - 'platform_keymap' : 'keymap', - 'HVM_boot': 'boot', + 'platform_keymap' : 'keymap' } # List of XendConfig configuration keys that have no direct equivalent @@ -735,6 +734,7 @@ class XendConfig(dict): val = sxp.child_value(image_sxp, imgkey, None) if val != None: self[apikey] = val + self._hvm_boot_params_from_sxp(image_sxp) # extract backend value @@ -1372,12 +1372,19 @@ class XendConfig(dict): val = sxp.child_value(image_sxp, imgkey, None) if val != None: type_conv = XENAPI_CFG_TYPES[apikey] - if callable(conv): + if callable(type_conv): self[apikey] = type_conv(val) else: self[apikey] = val + self._hvm_boot_params_from_sxp(image_sxp) + def _hvm_boot_params_from_sxp(self, image_sxp): + boot = sxp.child_value(image_sxp, 'boot', None) + if boot is not None: + self['HVM_boot_policy'] = 'BIOS order' + self['HVM_boot_params'] = { 'order' : boot } + # # debugging From fa39434f9aa2ad31e32112c0321248db9e540ba2 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 15:44:00 +0000 Subject: [PATCH 28/49] Fix SDL option for HVM domains. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/image.py | 66 +++++++++++++++++----------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index e1f87e1e8f..7a20eae3c8 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -449,48 +449,50 @@ class HVMImageHandler(ImageHandler): return ret vnc_config = {} - has_vfb = False has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0 + has_sdl = int(vmConfig['image'].get('sdl', 0)) != 0 for dev_uuid in vmConfig['console_refs']: dev_type, dev_info = vmConfig['devices'][dev_uuid] if dev_type == 'vfb': vnc_config = dev_info.get('other_config', {}) - has_vfb = True + has_vnc = True break - if not vnc_config: - for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'): - if key in vmConfig['image']: - vnc_config[key] = vmConfig['image'][key] + if has_vnc: + if not vnc_config: + for key in ('vncunused', 'vnclisten', 'vncdisplay', + 'vncpasswd'): + if key in vmConfig['image']: + vnc_config[key] = vmConfig['image'][key] - if not has_vfb and not has_vnc: - ret.append('-nographic') - return ret + if not vnc_config.get('vncunused', 0) and \ + vnc_config.get('vncdisplay', 0): + ret.append('-vnc') + ret.append(str(vncdisplay)) + else: + ret.append('-vncunused') - - if not vnc_config.get('vncunused', 0) and \ - vnc_config.get('vncdisplay', 0): - ret.append('-vnc') - ret.append(str(vncdisplay)) + vnclisten = vnc_config.get('vnclisten', + xenopts().get_vnclisten_address()) + ret.append('-vnclisten') + ret.append(str(vnclisten)) + + # Store vncpassword in xenstore + vncpasswd = vnc_config.get('vncpasswd') + if not vncpasswd: + vncpasswd = xenopts().get_vncpasswd_default() + + if vncpasswd is None: + raise VmError('vncpasswd is not setup in vmconfig or ' + 'xend-config.sxp') + + if vncpasswd != '': + self.vm.storeVm('vncpasswd', vncpasswd) + elif has_sdl: + # SDL is default in QEMU. + pass else: - ret.append('-vncunused') - - vnclisten = vnc_config.get('vnclisten', - xenopts().get_vnclisten_address()) - ret.append('-vnclisten') - ret.append(str(vnclisten)) - - # Store vncpassword in xenstore - vncpasswd = vnc_config.get('vncpasswd') - if not vncpasswd: - vncpasswd = xenopts().get_vncpasswd_default() - - if vncpasswd is None: - raise VmError('vncpasswd is not setup in vmconfig or ' - 'xend-config.sxp') - - if vncpasswd != '': - self.vm.storeVm('vncpasswd', vncpasswd) + ret.append('-nographic') return ret From 11247302ade76cc40b28e01f500d0db7f26b72c4 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 1 Feb 2007 16:07:22 +0000 Subject: [PATCH 29/49] [XEN] Extend the range returned by KEXEC_RANGE_MA_XEN to cover the heap as well as code+data. This makes kdump work again after 13546:d86a96ca47a3 Also fix sizeof_note to correctly calculate the length of the name field. Signed-off-by: Ian Campbell --- xen/common/kexec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/common/kexec.c b/xen/common/kexec.c index ca729d10c1..a9e85cad7f 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -141,7 +141,7 @@ static void setup_note(Elf_Note *n, const char *name, int type, int descsz) static int sizeof_note(const char *name, int descsz) { return (sizeof(Elf_Note) + - ELFNOTE_ALIGN(sizeof(name)) + + ELFNOTE_ALIGN(strlen(name)+1) + ELFNOTE_ALIGN(descsz)); } @@ -163,7 +163,7 @@ static int kexec_get(reserve)(xen_kexec_range_t *range) static int kexec_get(xen)(xen_kexec_range_t *range) { range->start = virt_to_maddr(_start); - range->size = (unsigned long)_end - (unsigned long)_start; + range->size = (unsigned long)xenheap_phys_end - (unsigned long)range->start; return 0; } From 437359ebc877a4bbad10a8933f35160a060a9caf Mon Sep 17 00:00:00 2001 From: "john.levon@sun.com" Date: Thu, 1 Feb 2007 08:41:36 -0800 Subject: [PATCH 30/49] Fix Solaris build - use $(MAKE) not make. Signed-off-by: John Levon --- tools/Rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Rules.mk b/tools/Rules.mk index af530ac65d..df3b231a1a 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -56,6 +56,6 @@ mk-symlinks-xen: ( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/Makefile . ) ( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/reference.size . ) ( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/*.py . ) - make -C xen/foreign + $(MAKE) -C xen/foreign mk-symlinks: mk-symlinks-xen mk-symlinks-$(XEN_OS) From 47fd2b1be1ac5e0a906302711aa0e5a45c3a975b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 1 Feb 2007 17:52:08 +0000 Subject: [PATCH 31/49] Fix xen-x86_32 defconfig to includean option needed for PAE builds. Signed-off-by: Keir Fraser --- buildconfigs/linux-defconfig_xen_x86_32 | 1 + 1 file changed, 1 insertion(+) diff --git a/buildconfigs/linux-defconfig_xen_x86_32 b/buildconfigs/linux-defconfig_xen_x86_32 index 328b86d938..8a793de380 100644 --- a/buildconfigs/linux-defconfig_xen_x86_32 +++ b/buildconfigs/linux-defconfig_xen_x86_32 @@ -1268,6 +1268,7 @@ CONFIG_IEEE1394_RAWIO=m CONFIG_I2O=m CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y CONFIG_I2O_CONFIG=m CONFIG_I2O_CONFIG_OLD_IOCTL=y CONFIG_I2O_BUS=m From 19b798343207a490d6e61f2c3d5d52ac59c95370 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 18:14:40 +0000 Subject: [PATCH 32/49] Return the stored vcpus_params if the domain is not running. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomainInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 35d35ba28a..ddc240b96b 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1978,7 +1978,7 @@ class XendDomainInfo: return 'unknown' def get_vcpus_params(self): if self.getDomid() is None: - return {} + return self.info['vcpus_params'] retval = xc.sched_credit_domain_get(self.getDomid()) return retval From f51cfb888beedf48bdb69ae24dd8ad054eb116d6 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 18:15:36 +0000 Subject: [PATCH 33/49] Treat the empty string as an absent UUID, not an invalid one. Fix to_sxp wrt dictionaries. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendConfig.py | 46 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index b8cbd8cd7c..1c59b78c76 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -146,7 +146,7 @@ XENAPI_CFG_TYPES = { 'memory_actual': int, 'cpus': list, 'vcpus_policy': str, - 'vcpus_params': str, + 'vcpus_params': dict, 'vcpus_number': int, 'vcpus_features_required': list, 'vcpus_features_can_use': list, @@ -349,7 +349,6 @@ class XendConfig(dict): def _defaults(self): defaults = { - 'uuid': uuid.createString(), 'name_label': 'Domain-Unnamed', 'actions_after_shutdown': 'destroy', 'actions_after_reboot': 'restart', @@ -385,7 +384,6 @@ class XendConfig(dict): 'other_config': {}, } - defaults['name_label'] = 'Domain-' + defaults['uuid'] return defaults def _memory_sanity_check(self): @@ -415,13 +413,21 @@ class XendConfig(dict): def _uuid_sanity_check(self): """Make sure UUID is in proper string format with hyphens.""" - self['uuid'] = uuid.toString(uuid.fromString(self['uuid'])) + if 'uuid' not in self or not self['uuid']: + self['uuid'] = uuid.createString() + else: + self['uuid'] = uuid.toString(uuid.fromString(self['uuid'])) + + def _name_sanity_check(self): + if 'name_label' not in self: + self['name_label'] = 'Domain-' + self['uuid'] def validate(self): + self._uuid_sanity_check() + self._name_sanity_check() self._memory_sanity_check() self._actions_sanity_check() self._vcpus_sanity_check() - self._uuid_sanity_check() def _dominfo_to_xapi(self, dominfo): self['domid'] = dominfo['domid'] @@ -840,8 +846,6 @@ class XendConfig(dict): else: self[key] = val - self.validate() - def to_sxp(self, domain = None, ignore_devices = False, ignore = [], legacy_only = True): """ Get SXP representation of this config object. @@ -865,9 +869,13 @@ class XendConfig(dict): sxpr.append(['domid', domain.getDomid()]) if not legacy_only: - for name in XENAPI_CFG_TYPES.keys(): + for name, typ in XENAPI_CFG_TYPES.items(): if name in self and self[name] not in (None, []): - sxpr.append([name, str(self[name])]) + if typ == dict: + s = self[name].items() + else: + s = str(self[name]) + sxpr.append([name, s]) for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items(): if self.has_key(xenapi) and self[xenapi] not in (None, []): @@ -996,7 +1004,9 @@ class XendConfig(dict): dev_info['driver'] = 'paravirtualised' # create uuid if it doesn't exist - dev_uuid = dev_info.get('uuid', uuid.createString()) + dev_uuid = dev_info.get('uuid', None) + if not dev_uuid: + dev_uuid = uuid.createString() dev_info['uuid'] = dev_uuid # store dev references by uuid for certain device types @@ -1066,7 +1076,9 @@ class XendConfig(dict): if cfg_xenapi.get('name'): dev_info['name'] = cfg_xenapi.get('name') - dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) + dev_uuid = cfg_xenapi.get('uuid', None) + if not dev_uuid: + dev_uuid = uuid.createString() dev_info['uuid'] = dev_uuid target['devices'][dev_uuid] = (dev_type, dev_info) target['vif_refs'].append(dev_uuid) @@ -1090,7 +1102,9 @@ class XendConfig(dict): else: dev_info['mode'] = 'r' - dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) + dev_uuid = cfg_xenapi.get('uuid', None) + if not dev_uuid: + dev_uuid = uuid.createString() dev_info['uuid'] = dev_uuid target['devices'][dev_uuid] = (dev_type, dev_info) target['vbd_refs'].append(dev_uuid) @@ -1099,13 +1113,17 @@ class XendConfig(dict): if cfg_xenapi.get('type'): dev_info['type'] = cfg_xenapi.get('type') - dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) + dev_uuid = cfg_xenapi.get('uuid', None) + if not dev_uuid: + dev_uuid = uuid.createString() dev_info['uuid'] = dev_uuid target['devices'][dev_uuid] = (dev_type, dev_info) target['vtpm_refs'].append(dev_uuid) elif dev_type == 'console': - dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) + dev_uuid = cfg_xenapi.get('uuid', None) + if not dev_uuid: + dev_uuid = uuid.createString() dev_info['uuid'] = dev_uuid dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb') dev_info['other_config'] = cfg_xenapi.get('other_config', {}) From d1e7d46990144f1f5568d1bc2697a1e1c2e42bb7 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 18:45:50 +0000 Subject: [PATCH 34/49] Clean up some cruft. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendConfig.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 1c59b78c76..3c36eb0421 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -148,15 +148,9 @@ XENAPI_CFG_TYPES = { 'vcpus_policy': str, 'vcpus_params': dict, 'vcpus_number': int, - 'vcpus_features_required': list, - 'vcpus_features_can_use': list, - 'vcpus_features_force_on': list, - 'vcpus_features_force_off': list, 'actions_after_shutdown': str, 'actions_after_reboot': str, - 'actions_after_suspend': str, 'actions_after_crash': str, - 'tpm_instance': int, 'tpm_backend': int, 'PV_bootloader': str, 'PV_kernel': str, From f72dfefae2eeaa789f23cc77787f5d18d253837b Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 19:00:17 +0000 Subject: [PATCH 35/49] Make the string->string map and int->float map allocation functions set the map size on allocation. Signed-off-by: Ewan Mellor --- tools/libxen/src/xen_int_float_map.c | 6 ++++-- tools/libxen/src/xen_string_string_map.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/libxen/src/xen_int_float_map.c b/tools/libxen/src/xen_int_float_map.c index edfcb21ac2..33ff29de62 100644 --- a/tools/libxen/src/xen_int_float_map.c +++ b/tools/libxen/src/xen_int_float_map.c @@ -25,8 +25,10 @@ xen_int_float_map * xen_int_float_map_alloc(size_t size) { - return calloc(1, sizeof(xen_int_float_map) + - size * sizeof(struct xen_int_float_map_contents)); + xen_int_float_map *result = calloc(1, sizeof(xen_int_float_map) + + size * sizeof(struct xen_int_float_map_contents)); + result->size = size; + return result; } diff --git a/tools/libxen/src/xen_string_string_map.c b/tools/libxen/src/xen_string_string_map.c index 34f5ec4d70..b07acfbf7c 100644 --- a/tools/libxen/src/xen_string_string_map.c +++ b/tools/libxen/src/xen_string_string_map.c @@ -25,8 +25,10 @@ xen_string_string_map * xen_string_string_map_alloc(size_t size) { - return calloc(1, sizeof(xen_string_string_map) + - size * sizeof(struct xen_string_string_map_contents)); + xen_string_string_map *result = calloc(1, sizeof(xen_string_string_map) + + size * sizeof(struct xen_string_string_map_contents)); + result->size = size; + return result; } From 948fd9f5a1e8db844b1a1f0a0fec93f5a29434cc Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 19:02:13 +0000 Subject: [PATCH 36/49] Added support for maps inside structs, so that we can send the HVM boot params and VCPU params. Signed-off-by: Ewan Mellor --- tools/libxen/src/xen_common.c | 144 +++++++++++++++++++++++++--------- 1 file changed, 106 insertions(+), 38 deletions(-) diff --git a/tools/libxen/src/xen_common.c b/tools/libxen/src/xen_common.c index 9834565ff0..8c5feeb33f 100644 --- a/tools/libxen/src/xen_common.c +++ b/tools/libxen/src/xen_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 XenSource, Inc. + * Copyright (c) 2006-2007 XenSource, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -86,6 +86,8 @@ static xmlNode * add_param_struct(xmlNode *); static xmlNode * add_struct_array(xmlNode *, const char *); +static xmlNode * +add_nested_struct(xmlNode *, const char *); static void add_struct_member(xmlNode *, const char *, const char *, const char *); static void @@ -107,6 +109,9 @@ parse_structmap_value(xen_session *, xmlNode *, const abstract_type *, static size_t size_of_member(const abstract_type *); +static const char * +get_val_as_string(const struct abstract_type *, void *, char *); + void xen_init(void) @@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_type *type, void *value, switch (type->typename) { case REF: - { - arbitrary_record_opt *val = *(arbitrary_record_opt **)value; - if (val != NULL) - { - if (val->is_record) - { - adder(node, key, "string", val->u.record->handle); - } - else - { - adder(node, key, "string", val->u.handle); - } - } - } - break; - case STRING: - { - char *val = *(char **)value; - if (val != NULL) - { - adder(node, key, "string", val); - } - } - break; - case INT: + case ENUM: { - int64_t val = *(int64_t *)value; - snprintf(buf, sizeof(buf), "%"PRId64, val); - adder(node, key, "string", buf); + const char *val_as_string = get_val_as_string(type, value, buf); + adder(node, key, "string", val_as_string); } break; @@ -1223,13 +1203,6 @@ add_struct_value(const struct abstract_type *type, void *value, } break; - case ENUM: - { - int val = *(int *)value; - adder(node, key, "string", type->enum_marshaller(val)); - } - break; - case SET: { const struct abstract_type *member_type = type->child; @@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_type *type, void *value, break; case STRUCT: - case MAP: { + assert(false); /* XXX Nested structures aren't supported yet, but fortunately we don't need them, because we don't have any "deep create" calls. This will need to be - fixed. We don't need maps either. */ + fixed. */ + } + break; + + case MAP: + { + size_t member_size = type->struct_size; + const struct abstract_type *l_type = type->members[0].type; + const struct abstract_type *r_type = type->members[1].type; + int l_offset = type->members[0].offset; + int r_offset = type->members[1].offset; + + arbitrary_map *map_val = *(arbitrary_map **)value; + + if (map_val != NULL) + { + xmlNode *struct_node = add_nested_struct(node, key); + + for (size_t i = 0; i < map_val->size; i++) + { + void *contents = (void *)map_val->contents; + void *l_value = contents + (i * member_size) + l_offset; + void *r_value = contents + (i * member_size) + r_offset; + + const char *l_value_as_string = + get_val_as_string(l_type, l_value, buf); + + add_struct_value(r_type, r_value, add_struct_member, + l_value_as_string, struct_node); + } + } + } + break; + + default: + assert(false); + } +} + + +static const char * +get_val_as_string(const struct abstract_type *type, void *value, char *buf) +{ + switch (type->typename) + { + case REF: + { + arbitrary_record_opt *val = *(arbitrary_record_opt **)value; + if (val != NULL) + { + if (val->is_record) + { + return val->u.record->handle; + } + else + { + return val->u.handle; + } + } + else + { + return NULL; + } + } + break; + + case STRING: + { + return *(char **)value; + } + break; + + case INT: + { + int64_t val = *(int64_t *)value; + snprintf(buf, sizeof(buf), "%"PRId64, val); + return buf; + } + break; + + case ENUM: + { + int val = *(int *)value; + return type->enum_marshaller(val); } break; @@ -1331,7 +1387,19 @@ add_struct_array(xmlNode *struct_node, const char *name) xmlNode *array_node = add_container(value_node, "array"); return add_container(array_node, "data"); +} + +static xmlNode * +add_nested_struct(xmlNode *struct_node, const char *name) +{ + xmlNode *member_node = add_container(struct_node, "member"); + + xmlNewChild(member_node, NULL, BAD_CAST "name", BAD_CAST name); + + xmlNode *value_node = add_container(member_node, "value"); + + return add_container(value_node, "struct"); } From a98eadf63a3dd41abd04c5cf42721e016352bbf2 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 1 Feb 2007 19:02:55 +0000 Subject: [PATCH 37/49] Improved the example to show creation of a VNC console, and the difference between HVM and PV domains. Signed-off-by: Ewan Mellor --- tools/libxen/test/test_bindings.c | 86 ++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/tools/libxen/test/test_bindings.c b/tools/libxen/test/test_bindings.c index b3ac7f0886..8ce02377b1 100644 --- a/tools/libxen/test/test_bindings.c +++ b/tools/libxen/test/test_bindings.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 XenSource, Inc. + * Copyright (c) 2006-2007 XenSource, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,6 +29,7 @@ #include "xen_sr.h" #include "xen_vbd.h" #include "xen_vdi.h" +#include "xen_console.h" #include "xen_vm.h" @@ -58,7 +59,7 @@ typedef struct } xen_comms; -static xen_vm create_new_vm(xen_session *session); +static xen_vm create_new_vm(xen_session *session, bool hvm); static void print_vm_power_state(xen_session *session, xen_vm vm); @@ -245,7 +246,7 @@ int main(int argc, char **argv) xen_string_string_map_free(versions); - xen_vm new_vm = create_new_vm(session); + xen_vm new_vm = create_new_vm(session, true); if (!session->ok) { /* Error has been logged, just clean up. */ @@ -275,15 +276,28 @@ int main(int argc, char **argv) * allocation patterns can be used, as long as the allocation and free are * paired correctly. */ -static xen_vm create_new_vm(xen_session *session) +static xen_vm create_new_vm(xen_session *session, bool hvm) { xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1); vcpus_params->contents[0].key = strdup("weight"); vcpus_params->contents[0].val = strdup("300"); + + xen_string_string_map *hvm_boot_params; + if (hvm) + { + hvm_boot_params = xen_string_string_map_alloc(1); + hvm_boot_params->contents[0].key = strdup("order"); + hvm_boot_params->contents[0].val = strdup("cd"); + } + else + { + hvm_boot_params = NULL; + } + xen_vm_record vm_record = { - .name_label = "NewVM", - .name_description = "New VM Description", + .name_label = hvm ? "NewHVM" : "NewPV", + .name_description = hvm ? "New HVM VM" : "New PV VM", .user_version = 1, .is_a_template = false, .memory_static_max = 256, @@ -296,20 +310,17 @@ static xen_vm create_new_vm(xen_session *session) .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY, .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART, .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE, - .hvm_boot_policy = NULL, - .hvm_boot_params = NULL, - .pv_bootloader = "pygrub", - .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen", - .pv_ramdisk = "", - .pv_args = "root=/dev/sda1 ro", - .pv_bootloader_args = "" + .hvm_boot_policy = hvm ? "BIOS order" : NULL, + .hvm_boot_params = hvm ? hvm_boot_params : NULL, + .pv_bootloader = hvm ? NULL : "pygrub", + .pv_kernel = hvm ? NULL : "/boot/vmlinuz-2.6.16.33-xen", }; - xen_vm vm; xen_vm_create(session, &vm, &vm_record); xen_string_string_map_free(vcpus_params); + xen_string_string_map_free(hvm_boot_params); if (!session->ok) { @@ -343,7 +354,6 @@ static xen_vm create_new_vm(xen_session *session) .sr = &sr_record, .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector .sector_size = 512, - .location = "file:/root/gentoo.amd64.img", .type = XEN_VDI_TYPE_SYSTEM, .sharable = false, .read_only = false @@ -373,7 +383,7 @@ static xen_vm create_new_vm(xen_session *session) { .vm = &vm_record_opt, .vdi = &vdi0_record_opt, - .device = "sda1", + .device = "xvda1", .mode = XEN_VBD_MODE_RW, .bootable = 1, }; @@ -390,13 +400,38 @@ static xen_vm create_new_vm(xen_session *session) return NULL; } + xen_console vnc_console = NULL; + if (hvm) { + xen_console_record vnc_console_record = + { + .protocol = XEN_CONSOLE_PROTOCOL_RFB, + .vm = &vm_record_opt, + }; + + if (!xen_console_create(session, &vnc_console, &vnc_console_record)) + { + fprintf(stderr, "VNC console creation failed.\n"); + print_error(session); + + xen_vbd_free(vbd0); + xen_vdi_free(vdi0); + xen_sr_set_free(srs); + xen_vm_free(vm); + return NULL; + } + } + char *vm_uuid; char *vdi0_uuid; char *vbd0_uuid; + char *vnc_uuid = NULL; xen_vm_get_uuid(session, &vm_uuid, vm); xen_vdi_get_uuid(session, &vdi0_uuid, vdi0); xen_vbd_get_uuid(session, &vbd0_uuid, vbd0); + if (hvm) { + xen_console_get_uuid(session, &vnc_uuid, vnc_console); + } if (!session->ok) { @@ -406,22 +441,35 @@ static xen_vm create_new_vm(xen_session *session) xen_uuid_free(vm_uuid); xen_uuid_free(vdi0_uuid); xen_uuid_free(vbd0_uuid); + xen_uuid_free(vnc_uuid); xen_vbd_free(vbd0); xen_vdi_free(vdi0); + xen_console_free(vnc_console); xen_sr_set_free(srs); xen_vm_free(vm); return NULL; } - fprintf(stderr, - "Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n", - vm_uuid, vdi0_uuid, vbd0_uuid); + if (hvm) { + fprintf(stderr, + "Created a new HVM VM, with UUID %s, VDI UUID %s, VBD " + "UUID %s, and VNC console UUID %s.\n", + vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid); + } + else { + fprintf(stderr, + "Created a new PV VM, with UUID %s, VDI UUID %s, and VBD " + "UUID %s.\n", + vm_uuid, vdi0_uuid, vbd0_uuid); + } xen_uuid_free(vm_uuid); xen_uuid_free(vdi0_uuid); xen_uuid_free(vbd0_uuid); + xen_uuid_free(vnc_uuid); xen_vbd_free(vbd0); xen_vdi_free(vdi0); + xen_console_free(vnc_console); xen_sr_set_free(srs); return vm; From 437919c58fe857ddc5695e1639516391a745bc86 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 2 Feb 2007 10:03:21 +0000 Subject: [PATCH 38/49] Remove some obsolete constants (XEN_API_DRIVER_TYPE, XEN_API_BOOT_TYPE). Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendAPIConstants.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/python/xen/xend/XendAPIConstants.py b/tools/python/xen/xend/XendAPIConstants.py index 9805cf02a7..68a29bb107 100644 --- a/tools/python/xen/xend/XendAPIConstants.py +++ b/tools/python/xen/xend/XendAPIConstants.py @@ -12,7 +12,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #============================================================================ -# Copyright (C) 2006 XenSource Ltd. +# Copyright (C) 2006-2007 XenSource Ltd. #============================================================================ # @@ -49,16 +49,8 @@ XEN_API_ON_CRASH_BEHAVIOUR = [ 'rename_restart' ] -XEN_API_BOOT_TYPE = [ - 'bios', - 'grub', - 'kernel_external', - 'kernel_internal' -] - XEN_API_VBD_MODE = ['RO', 'RW'] XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral'] -XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised'] XEN_API_VBD_TYPE = ['CD', 'Disk'] XEN_API_TASK_STATUS_TYPE = ['pending', 'success', 'failure'] XEN_API_CONSOLE_PROTOCOL = ['vt100', 'rfb', 'rdp'] From d650ce4366197c1a7bfd4519f7a60702301f7a27 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 2 Feb 2007 10:07:58 +0000 Subject: [PATCH 39/49] Remove VM_power_state value ShuttingDown. This should be indicated with an in-progress task, when known. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 1 - tools/libxen/include/xen_vm_power_state.h | 5 ----- tools/libxen/src/xen_vm_power_state.c | 1 - tools/python/xen/xend/XendAPIConstants.py | 2 +- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 3868c1fecd..739d270244 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -142,7 +142,6 @@ The following enumeration types are used: \hspace{0.5cm}{\tt Paused} & Paused \\ \hspace{0.5cm}{\tt Running} & Running \\ \hspace{0.5cm}{\tt Suspended} & Suspended \\ -\hspace{0.5cm}{\tt ShuttingDown} & Shutting Down \\ \hspace{0.5cm}{\tt Unknown} & Some other unknown state \\ \hline \end{longtable} diff --git a/tools/libxen/include/xen_vm_power_state.h b/tools/libxen/include/xen_vm_power_state.h index 3e805ed671..c5404b89cf 100644 --- a/tools/libxen/include/xen_vm_power_state.h +++ b/tools/libxen/include/xen_vm_power_state.h @@ -45,11 +45,6 @@ enum xen_vm_power_state */ XEN_VM_POWER_STATE_SUSPENDED, - /** - * Shutting Down - */ - XEN_VM_POWER_STATE_SHUTTINGDOWN, - /** * Some other unknown state */ diff --git a/tools/libxen/src/xen_vm_power_state.c b/tools/libxen/src/xen_vm_power_state.c index a9e2545c47..9f96f34f9b 100644 --- a/tools/libxen/src/xen_vm_power_state.c +++ b/tools/libxen/src/xen_vm_power_state.c @@ -32,7 +32,6 @@ static const char *lookup_table[] = "Paused", "Running", "Suspended", - "ShuttingDown", "Unknown" }; diff --git a/tools/python/xen/xend/XendAPIConstants.py b/tools/python/xen/xend/XendAPIConstants.py index 68a29bb107..41e212d495 100644 --- a/tools/python/xen/xend/XendAPIConstants.py +++ b/tools/python/xen/xend/XendAPIConstants.py @@ -24,7 +24,7 @@ XEN_API_VM_POWER_STATE = [ 'Paused', 'Running', 'Suspended', - 'ShuttingDown', + 'Halted', 'Unknown' ] From 8389ab43f55c635516235c48ba1d38562a84070c Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 2 Feb 2007 10:25:17 +0000 Subject: [PATCH 40/49] Added host.dmesg method. Also, fixed all of the host methods, which had been broken by the introduction of the host_metrics class. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 34 ++++++++++++++++++++++++++++++- tools/libxen/include/xen_host.h | 7 +++++++ tools/libxen/src/xen_host.c | 17 ++++++++++++++++ tools/libxen/test/test_bindings.c | 17 ++++++++++++++++ tools/python/xen/xend/XendAPI.py | 10 ++++++--- 5 files changed, 81 insertions(+), 4 deletions(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 739d270244..ee34fc7160 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -4661,13 +4661,45 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~dmesg} + +{\bf Overview:} +Get the host xen dmesg. + + \noindent {\bf Signature:} +\begin{verbatim} string dmesg (session_id s, host ref host)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & host & The Host to query \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +dmesg string \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} \subsubsection{RPC name:~get\_all} {\bf Overview:} -Return a list of all the hosts known to the system +Return a list of all the hosts known to the system. \noindent {\bf Signature:} \begin{verbatim} ((host ref) Set) get_all (session_id s)\end{verbatim} diff --git a/tools/libxen/include/xen_host.h b/tools/libxen/include/xen_host.h index e64390b89f..26ca29d592 100644 --- a/tools/libxen/include/xen_host.h +++ b/tools/libxen/include/xen_host.h @@ -393,6 +393,13 @@ extern bool xen_host_reboot(xen_session *session, xen_host host); +/** + * Get the host xen dmesg. + */ +extern bool +xen_host_dmesg(xen_session *session, char **result, xen_host host); + + /** * Return a list of all the hosts known to the system. */ diff --git a/tools/libxen/src/xen_host.c b/tools/libxen/src/xen_host.c index 7968b96994..4a79daa90f 100644 --- a/tools/libxen/src/xen_host.c +++ b/tools/libxen/src/xen_host.c @@ -631,6 +631,23 @@ xen_host_reboot(xen_session *session, xen_host host) } +bool +xen_host_dmesg(xen_session *session, char **result, xen_host host) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = host } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("host.dmesg"); + return session->ok; +} + + bool xen_host_get_all(xen_session *session, struct xen_host_set **result) { diff --git a/tools/libxen/test/test_bindings.c b/tools/libxen/test/test_bindings.c index 8ce02377b1..c1df98dcea 100644 --- a/tools/libxen/test/test_bindings.c +++ b/tools/libxen/test/test_bindings.c @@ -206,6 +206,20 @@ int main(int argc, char **argv) return 1; } + char *dmesg; + if (!xen_host_dmesg(session, &dmesg, host)) + { + print_error(session); + xen_string_string_map_free(versions); + xen_host_free(host); + xen_vm_record_free(vm_record); + xen_uuid_bytes_free(vm_uuid_bytes); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + CLEANUP; + return 1; + } + printf("%s.\n", vm_uuid); fprintf(stderr, "In bytes, the VM UUID is "); @@ -223,6 +237,8 @@ int main(int argc, char **argv) versions->contents[i].val); } + printf("Host dmesg follows:\n%s\n\n", dmesg); + printf("%s.\n", vm_record->uuid); printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle); @@ -244,6 +260,7 @@ int main(int argc, char **argv) xen_host_free(host); xen_string_string_map_free(versions); + free(dmesg); xen_vm new_vm = create_new_vm(session, true); diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index 0b3c54a89b..49f2082893 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -22,7 +22,7 @@ import sys import traceback import threading -from xen.xend import XendDomain, XendDomainInfo, XendNode +from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg from xen.xend import XendLogging, XendTaskManager from xen.xend.XendAuthSessions import instance as auth_manager @@ -615,7 +615,8 @@ class XendAPI(object): ('reboot', None), ('shutdown', None), ('add_to_other_config', None), - ('remove_from_other_config', None)] + ('remove_from_other_config', None), + ('dmesg', 'String')] host_funcs = [('get_by_name_label', 'Set(host)')] @@ -674,6 +675,9 @@ class XendAPI(object): return xen_api_error(XEND_ERROR_HOST_RUNNING) return xen_api_error(XEND_ERROR_UNSUPPORTED) + def host_dmesg(self, session, host_ref): + return xen_api_success(XendDmesg.instance().info()) + def host_get_record(self, session, host_ref): node = XendNode.instance() dom = XendDomain.instance() @@ -737,7 +741,7 @@ class XendAPI(object): 'memory_free', 'host'] host_metrics_attr_rw = [] - host_methods = [] + host_metrics_methods = [] def _host_metrics_get(self, ref, f): return xen_api_success(getattr(node, f)()) From 8ae342b80bfa616e1e25287a4d496139a7ab88cf Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 2 Feb 2007 14:32:48 +0000 Subject: [PATCH 41/49] Added default for the vcpus_params key. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendConfig.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 3c36eb0421..223a90cf6e 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -371,6 +371,7 @@ class XendConfig(dict): 'cpu_weight': 256, 'cpu_cap': 0, 'vcpus_number': 1, + 'vcpus_params': {}, 'console_refs': [], 'vif_refs': [], 'vbd_refs': [], From 502043ef9001010fc8f6390a15b50d584d1e088f Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 15:30:49 +0000 Subject: [PATCH 42/49] minios: Fix ret_from_exception routine. Stack consistency is now preserved. Signed-off-by: Grzegorz Milos --- extras/mini-os/arch/x86/x86_32.S | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/extras/mini-os/arch/x86/x86_32.S b/extras/mini-os/arch/x86/x86_32.S index 46fce169ca..b10bc23401 100644 --- a/extras/mini-os/arch/x86/x86_32.S +++ b/extras/mini-os/arch/x86/x86_32.S @@ -69,7 +69,7 @@ CS = 0x2C popl %ds; \ popl %es; \ addl $4,%esp; \ - iret; \ + iret; ENTRY(divide_error) pushl $0 # no error code @@ -101,10 +101,9 @@ do_exception: jmp ret_from_exception ret_from_exception: - movb CS(%esp),%cl - test $2,%cl # slow return to ring 2 or 3 - jne safesti - RESTORE_ALL + movb CS(%esp),%cl + addl $8,%esp + RESTORE_ALL # A note on the "critical region" in our callback handler. # We want to avoid stacking callback handlers due to events occurring From 44480a08208d2a31fd7c5ff66aaa7cf44f7176bb Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 15:41:45 +0000 Subject: [PATCH 43/49] libxc: Domain builder must align initial virtual mapping to 4MB boundaries. From: Gerd Hoffmann Signed-off-by: Keir Fraser --- tools/libxc/xc_dom_core.c | 3 +++ tools/libxc/xc_dom_x86.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c index 8d329ae74f..ae64972ed5 100644 --- a/tools/libxc/xc_dom_core.c +++ b/tools/libxc/xc_dom_core.c @@ -717,6 +717,9 @@ int xc_dom_build_image(struct xc_dom_image *dom) } page_size = XC_DOM_PAGE_SIZE(dom); + /* 4MB align virtual base address */ + dom->parms.virt_base &= ~(((uint64_t)1<<22)-1); + /* load kernel */ if (0 != xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel", dom->kernel_seg.vstart, diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c index 9e489c320d..fdc3d4ba5e 100644 --- a/tools/libxc/xc_dom_x86.c +++ b/tools/libxc/xc_dom_x86.c @@ -66,11 +66,12 @@ static int count_pgtables(struct xc_dom_image *dom, int pae, extra_pages = dom->alloc_bootstack ? 1 : 0; extra_pages += dom->extra_pages; + extra_pages += 128; /* 512kB padding */ pages = extra_pages; for (;;) { try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86, - bits_to_mask(l1_bits)); + bits_to_mask(22)); /* 4MB alignment */ dom->pg_l4 = nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits); dom->pg_l3 = @@ -313,6 +314,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom) if (xc_dom_feature_translated(dom)) dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info"); dom->alloc_bootstack = 1; + return 0; } From 34814f4465cdb53af4dfbe08c0083d646721c17a Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 15:50:27 +0000 Subject: [PATCH 44/49] New domain builder arch_setup hook clean up. arch_setup_early -> arch_setup_meminit arch_setup_middle -> arch_setup_bootearly arch_setup_late -> arch_setup_bootlate Signed-off-by: Isaku Yamahata --- tools/libxc/xc_dom_boot.c | 39 ++++++++++++++++++--------------------- tools/libxc/xc_dom_ia64.c | 6 +----- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c index d8bfe485d8..83b1abe1eb 100644 --- a/tools/libxc/xc_dom_boot.c +++ b/tools/libxc/xc_dom_boot.c @@ -144,7 +144,7 @@ static int x86_shadow(int xc, domid_t domid) return rc; } -static int arch_setup_early(struct xc_dom_image *dom) +static int arch_setup_meminit(struct xc_dom_image *dom) { int rc = 0; @@ -157,13 +157,13 @@ static int arch_setup_early(struct xc_dom_image *dom) return rc; } -static int arch_setup_middle(struct xc_dom_image *dom) +static int arch_setup_bootearly(struct xc_dom_image *dom) { xc_dom_printf("%s: doing nothing\n", __FUNCTION__); return 0; } -static int arch_setup_late(struct xc_dom_image *dom) +static int arch_setup_bootlate(struct xc_dom_image *dom) { static const struct { char *guest; @@ -263,13 +263,13 @@ static int arch_setup_late(struct xc_dom_image *dom) #elif defined(__ia64__) -static int arch_setup_early(struct xc_dom_image *dom) +static int arch_setup_meminit(struct xc_dom_image *dom) { xc_dom_printf("%s: doing nothing\n", __FUNCTION__); return 0; } -static int arch_setup_middle(struct xc_dom_image *dom) +static int arch_setup_bootearly(struct xc_dom_image *dom) { DECLARE_DOMCTL; int rc; @@ -281,10 +281,6 @@ static int arch_setup_middle(struct xc_dom_image *dom) domctl.domain = dom->guest_domid; domctl.u.arch_setup.flags = 0; - /* dom->start_info_pfn should be initialized by alloc_magic_pages(). - * However it is called later. So we initialize here. - */ - dom->start_info_pfn = dom->total_pages - 3; domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT) + sizeof(start_info_t); /* 3 = start info page, xenstore page and console page */ @@ -293,7 +289,7 @@ static int arch_setup_middle(struct xc_dom_image *dom) return rc; } -static int arch_setup_late(struct xc_dom_image *dom) +static int arch_setup_bootlate(struct xc_dom_image *dom) { unsigned int page_size = XC_DOM_PAGE_SIZE(dom); shared_info_t *shared_info; @@ -317,19 +313,19 @@ static int arch_setup_late(struct xc_dom_image *dom) #elif defined(__powerpc64__) -static int arch_setup_early(struct xc_dom_image *dom) +static int arch_setup_meminit(struct xc_dom_image *dom) { xc_dom_printf("%s: doing nothing\n", __FUNCTION__); return 0; } -static int arch_setup_middle(struct xc_dom_image *dom) +static int arch_setup_bootearly(struct xc_dom_image *dom) { xc_dom_printf("%s: doing nothing\n", __FUNCTION__); return 0; } -static int arch_setup_late(struct xc_dom_image *dom) +static int arch_setup_bootlate(struct xc_dom_image *dom) { start_info_t *si = xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); @@ -355,19 +351,19 @@ static int arch_setup_late(struct xc_dom_image *dom) #else -static int arch_setup_early(struct xc_dom_image *dom) +static int arch_setup_meminit(struct xc_dom_image *dom) { xc_dom_printf("%s: doing nothing\n", __FUNCTION__); return 0; } -static int arch_setup_middle(struct xc_dom_image *dom) +static int arch_setup_bootearly(struct xc_dom_image *dom) { xc_dom_printf("%s: doing nothing\n", __FUNCTION__); return 0; } -static int arch_setup_late(struct xc_dom_image *dom) +static int arch_setup_bootlate(struct xc_dom_image *dom) { xc_dom_printf("%s: doing nothing\n", __FUNCTION__); return 0; @@ -423,7 +419,7 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom) xc_dom_printf("%s: called\n", __FUNCTION__); - if (0 != (rc = arch_setup_early(dom))) + if (0 != (rc = arch_setup_meminit(dom))) return rc; /* allocate guest memory */ @@ -438,9 +434,6 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom) return rc; } - if (0 != (rc = arch_setup_middle(dom))) - return rc; - return 0; } @@ -497,6 +490,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom) xc_dom_printf("%s: called\n", __FUNCTION__); + /* misc ia64 stuff*/ + if (0 != (rc = arch_setup_bootearly(dom))) + return rc; + /* collect some info */ domctl.cmd = XEN_DOMCTL_getdomaininfo; domctl.domain = dom->guest_domid; @@ -542,7 +539,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom) xc_dom_log_memory_footprint(dom); /* misc x86 stuff */ - if (0 != (rc = arch_setup_late(dom))) + if (0 != (rc = arch_setup_bootlate(dom))) return rc; /* let the vm run */ diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c index c6e4424515..2ffce5a4d7 100644 --- a/tools/libxc/xc_dom_ia64.c +++ b/tools/libxc/xc_dom_ia64.c @@ -26,11 +26,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom) /* allocate special pages */ dom->console_pfn = dom->total_pages -1; dom->xenstore_pfn = dom->total_pages -2; - - /* - * this is initialized by arch_setup_middle(). - * dom->start_info_pfn = dom->total_pages -3; - */ + dom->start_info_pfn = dom->total_pages -3; return 0; } From 0ee998f095671221b77d69d75e301b777d24b4fd Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 15:52:30 +0000 Subject: [PATCH 45/49] linux: compilation fix of linux/drivers/oprofile/oprof.c Signed-off-by: Isaku Yamahata --- patches/linux-2.6.18/xenoprof-generic.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/patches/linux-2.6.18/xenoprof-generic.patch b/patches/linux-2.6.18/xenoprof-generic.patch index 0e05586df1..d2542b2d13 100644 --- a/patches/linux-2.6.18/xenoprof-generic.patch +++ b/patches/linux-2.6.18/xenoprof-generic.patch @@ -363,9 +363,9 @@ diff -pruN ../orig-linux-2.6.18/drivers/oprofile/oprof.c ./drivers/oprofile/opro + if (!oprofile_ops.set_active) + return -EINVAL; + -+ down(&start_sem); ++ mutex_lock(&start_mutex); + err = oprofile_ops.set_active(active_domains, adomains); -+ up(&start_sem); ++ mutex_unlock(&start_mutex); + return err; +} + @@ -376,9 +376,9 @@ diff -pruN ../orig-linux-2.6.18/drivers/oprofile/oprof.c ./drivers/oprofile/opro + if (!oprofile_ops.set_passive) + return -EINVAL; + -+ down(&start_sem); ++ mutex_lock(&start_mutex); + err = oprofile_ops.set_passive(passive_domains, pdomains); -+ up(&start_sem); ++ mutex_unlock(&start_mutex); + return err; +} + From b5c66d349302228614c1082d830c83e8aec7794f Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 15:54:42 +0000 Subject: [PATCH 46/49] Fix cross-compile: ia64 build on x86. Signed-off-by: Isaku Yamahata --- xen/include/public/foreign/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/xen/include/public/foreign/Makefile b/xen/include/public/foreign/Makefile index 7f91dd87b9..7bf028e72a 100644 --- a/xen/include/public/foreign/Makefile +++ b/xen/include/public/foreign/Makefile @@ -13,9 +13,16 @@ clean: rm -f checker checker.c $(XEN_TARGET_ARCH).size rm -f *.pyc *.o *~ +ifeq ($(CROSS_COMPILE),) check-headers: checker ./checker > $(XEN_TARGET_ARCH).size diff -u reference.size $(XEN_TARGET_ARCH).size +checker: checker.c $(headers) + $(HOSTCC) $(CFLAGS) -o $@ $< +else +check-headers: + @echo "cross build: skipping check" +endif x86_32.h: ../arch-x86/xen-x86_32.h ../arch-x86/xen.h ../xen.h $(scripts) python mkheader.py $* $@ $(filter %.h,$^) @@ -26,8 +33,5 @@ x86_64.h: ../arch-x86/xen-x86_64.h ../arch-x86/xen.h ../xen.h $(scripts) ia64.h: ../arch-ia64.h ../xen.h $(scripts) python mkheader.py $* $@ $(filter %.h,$^) -checker: checker.c $(headers) - $(HOSTCC) $(CFLAGS) -o $@ $< - checker.c: $(scripts) python mkchecker.py $(XEN_TARGET_ARCH) $@ $(architectures) From e5a28da5dbbe1d54b3738e7979f1d0cf125f2595 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 15:55:56 +0000 Subject: [PATCH 47/49] minios: Fix bug in xenbus implementation. Signed-off-by: Keir Fraser --- extras/mini-os/xenbus/xenbus.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extras/mini-os/xenbus/xenbus.c b/extras/mini-os/xenbus/xenbus.c index 1a0f0e048f..f2428c12fa 100644 --- a/extras/mini-os/xenbus/xenbus.c +++ b/extras/mini-os/xenbus/xenbus.c @@ -178,6 +178,7 @@ static void release_xenbus_id(int id) BUG_ON(!req_info[id].in_use); spin_lock(&req_lock); nr_live_reqs--; + req_info[id].in_use = 0; if (nr_live_reqs == NR_REQS - 1) wake_up(&req_wq); spin_unlock(&req_lock); @@ -212,6 +213,7 @@ static int allocate_xenbus_id(void) probe = o_probe + 1; spin_unlock(&req_lock); init_waitqueue_head(&req_info[o_probe].waitq); + return o_probe; } From e03f6e62c8e9c6532bab15219c1da41376c16232 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 16:04:11 +0000 Subject: [PATCH 48/49] linux: Allow xenbus_strstate() to be used from modules. The function is referenced by a number of DPRINTK()-s. Also, properly const-ify it. Signed-off-by: Jan Beulich --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c | 5 +++-- linux-2.6-xen-sparse/include/xen/xenbus.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c index f294ec1cc9..49878d17e0 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c @@ -42,9 +42,9 @@ #define DPRINTK(fmt, args...) \ pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args) -char *xenbus_strstate(enum xenbus_state state) +const char *xenbus_strstate(enum xenbus_state state) { - static char *name[] = { + static const char *const name[] = { [ XenbusStateUnknown ] = "Unknown", [ XenbusStateInitialising ] = "Initialising", [ XenbusStateInitWait ] = "InitWait", @@ -55,6 +55,7 @@ char *xenbus_strstate(enum xenbus_state state) }; return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID"; } +EXPORT_SYMBOL_GPL(xenbus_strstate); int xenbus_watch_path(struct xenbus_device *dev, const char *path, struct xenbus_watch *watch, diff --git a/linux-2.6-xen-sparse/include/xen/xenbus.h b/linux-2.6-xen-sparse/include/xen/xenbus.h index a26ca12820..cbf6fe351d 100644 --- a/linux-2.6-xen-sparse/include/xen/xenbus.h +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h @@ -295,7 +295,7 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, int __init xenbus_dev_init(void); -char *xenbus_strstate(enum xenbus_state state); +const char *xenbus_strstate(enum xenbus_state state); int xenbus_dev_is_online(struct xenbus_device *dev); int xenbus_frontend_closed(struct xenbus_device *dev); From ec48ab815b556a8f0a2ba9c5287b13fd4cf39607 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 2 Feb 2007 16:07:13 +0000 Subject: [PATCH 49/49] Hide RDTSCP feature flag from PV guests. Linux 2.6.19 (x86-64) makes use of this feature if available, but Xen (validly) fails the attempt to write the respective MSR. Hence the feature must be hidden from PV guests. Signed-off-by: Jan Beulich --- xen/arch/x86/traps.c | 5 +++++ xen/include/asm-x86/cpufeature.h | 1 + 2 files changed, 6 insertions(+) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 16b1e48ca8..dfa22bce04 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -597,6 +597,11 @@ static int emulate_forced_invalid_op(struct cpu_user_regs *regs) if ( !IS_PRIV(current->domain) ) clear_bit(X86_FEATURE_MTRR, &d); } + else if ( regs->eax == 0x80000001 ) + { + /* Modify Feature Information. */ + clear_bit(X86_FEATURE_RDTSCP % 32, &d); + } else { (void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d); diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h index a092a83ad5..a6f2f757bc 100644 --- a/xen/include/asm-x86/cpufeature.h +++ b/xen/include/asm-x86/cpufeature.h @@ -49,6 +49,7 @@ #define X86_FEATURE_MP (1*32+19) /* MP Capable. */ #define X86_FEATURE_NX (1*32+20) /* Execute Disable */ #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ +#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */ #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ #define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */