80e28a00ec
- unmodified_drivers: handle IRQF_SAMPLE_RANDOM, it was removed in 3.6-rc1 - bnc#778105 - first XEN-PV VM fails to spawn xend: Increase wait time for disk to appear in host bootloader Modified existing xen-domUloader.diff - Disable the snapshot patches. Snapshot only supported the qcow2 image format which was poorly implemented qemu 0.10.2. Snapshot support may be restored in the future when the newer upstream qemu is used by Xen. - bnc#776995 - attaching scsi control luns with pvscsi - xend/pvscsi: fix passing of SCSI control LUNs xen-bug776995-pvscsi-no-devname.patch - xend/pvscsi: fix usage of persistant device names for SCSI devices xen-bug776995-pvscsi-persistent-names.patch - xend/pvscsi: update sysfs parser for Linux 3.0 xen-bug776995-pvscsi-sysfs-parser.patch - Update to Xen 4.2.0 RC3+ c/s 25779 - Update to Xen 4.2.0 RC2+ c/s 25765 OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=199
497 lines
18 KiB
Diff
497 lines
18 KiB
Diff
Index: xen-4.2.0-testing/tools/python/xen/xend/server/HalDaemon.py
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ xen-4.2.0-testing/tools/python/xen/xend/server/HalDaemon.py
|
|
@@ -0,0 +1,243 @@
|
|
+#!/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 Pat Campbell <plc@novell.com>
|
|
+# Copyright (C) 2007 Novell Inc.
|
|
+#============================================================================
|
|
+
|
|
+"""hald (Hardware Abstraction Layer Daemon) watcher for Xen management
|
|
+ of removable block device media.
|
|
+
|
|
+"""
|
|
+
|
|
+import gobject
|
|
+import dbus
|
|
+import dbus.glib
|
|
+import os
|
|
+import types
|
|
+import sys
|
|
+import signal
|
|
+import traceback
|
|
+from xen.xend.xenstore.xstransact import xstransact, complete
|
|
+from xen.xend.xenstore.xsutil import xshandle
|
|
+from xen.xend import PrettyPrint
|
|
+from xen.xend import XendLogging
|
|
+from xen.xend.XendLogging import log
|
|
+
|
|
+DEVICE_TYPES = ['vbd', 'tap']
|
|
+
|
|
+class HalDaemon:
|
|
+ """The Hald block device watcher for XEN
|
|
+ """
|
|
+
|
|
+ """Default path to the log file. """
|
|
+ logfile_default = "/var/log/xen/hald.log"
|
|
+
|
|
+ """Default level of information to be logged."""
|
|
+ loglevel_default = 'INFO'
|
|
+
|
|
+
|
|
+ def __init__(self):
|
|
+
|
|
+ XendLogging.init(self.logfile_default, self.loglevel_default)
|
|
+ log.debug( "%s", "__init__")
|
|
+
|
|
+ self.udi_dict = {}
|
|
+ self.debug = 0
|
|
+ self.dbpath = "/local/domain/0/backend"
|
|
+ self.bus = dbus.SystemBus()
|
|
+ self.hal_manager_obj = self.bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
|
|
+ self.hal_manager = dbus.Interface( self.hal_manager_obj, 'org.freedesktop.Hal.Manager')
|
|
+ self.gatherBlockDevices()
|
|
+ self.registerDeviceCallbacks()
|
|
+
|
|
+ def run(self):
|
|
+ log.debug( "%s", "In new run" );
|
|
+ try:
|
|
+ self.mainloop = gobject.MainLoop()
|
|
+ self.mainloop.run()
|
|
+ except KeyboardInterrupt, ex:
|
|
+ log.debug('Keyboard exception handler: %s', ex )
|
|
+ self.mainloop.quit()
|
|
+ except Exception, ex:
|
|
+ log.debug('Generic exception handler: %s', ex )
|
|
+ self.mainloop.quit()
|
|
+
|
|
+ def __del__(self):
|
|
+ log.debug( "%s", "In del " );
|
|
+ self.unRegisterDeviceCallbacks()
|
|
+ self.mainloop.quit()
|
|
+
|
|
+ def shutdown(self):
|
|
+ log.debug( "%s", "In shutdown now " );
|
|
+ self.unRegisterDeviceCallbacks()
|
|
+ self.mainloop.quit()
|
|
+
|
|
+ def stop(self):
|
|
+ log.debug( "%s", "In stop now " );
|
|
+ self.unRegisterDeviceCallbacks()
|
|
+ self.mainloop.quit()
|
|
+
|
|
+ def gatherBlockDevices(self):
|
|
+
|
|
+ # Get all the current devices from hal and save in a dictionary
|
|
+ try:
|
|
+ device_names = self.hal_manager.GetAllDevices()
|
|
+ i = 0;
|
|
+ for name in device_names:
|
|
+ #log.debug("device name, device=%s",name)
|
|
+ dev_obj = self.bus.get_object ('org.freedesktop.Hal', name)
|
|
+ dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device')
|
|
+ dev_properties = dev_obj.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device")
|
|
+ if dev_properties.has_key('block.device'):
|
|
+ dev_str = dev_properties['block.device']
|
|
+ dev_major = dev_properties['block.major']
|
|
+ dev_minor = dev_properties['block.minor']
|
|
+ udi_info = {}
|
|
+ udi_info['device'] = dev_str
|
|
+ udi_info['major'] = dev_major
|
|
+ udi_info['minor'] = dev_minor
|
|
+ udi_info['udi'] = name
|
|
+ self.udi_dict[i] = udi_info
|
|
+ i = i + 1
|
|
+ except Exception, ex:
|
|
+ print >>sys.stderr, 'Exception gathering block devices:', ex
|
|
+ log.warn("Exception gathering block devices (%s)",ex)
|
|
+
|
|
+ #
|
|
+ def registerDeviceCallbacks(self):
|
|
+ # setup the callbacks for when the gdl changes
|
|
+ self.hal_manager.connect_to_signal('DeviceAdded', self.device_added_callback)
|
|
+ self.hal_manager.connect_to_signal('DeviceRemoved', self.device_removed_callback)
|
|
+
|
|
+ #
|
|
+ def unRegisterDeviceCallbacks(self):
|
|
+ # setup the callbacks for when the gdl changes
|
|
+ self.hal_manager.remove_signal_receiver(self.device_added_callback,'DeviceAdded')
|
|
+ self.hal_manager.remove_signal_receiver(self.device_removed_callback,'DeviceRemoved')
|
|
+
|
|
+ #
|
|
+ def device_removed_callback(self,udi):
|
|
+ log.debug('UDI %s was removed',udi)
|
|
+ self.show_dict(self.udi_dict)
|
|
+ for key in self.udi_dict:
|
|
+ udi_info = self.udi_dict[key]
|
|
+ if udi_info['udi'] == udi:
|
|
+ device = udi_info['device']
|
|
+ major = udi_info['major']
|
|
+ minor = udi_info['minor']
|
|
+ self.change_xenstore( "remove", device, major, minor)
|
|
+
|
|
+ # Adds device to dictionary if not already there
|
|
+ def device_added_callback(self,udi):
|
|
+ log.debug('UDI %s was added', udi)
|
|
+ self.show_dict(self.udi_dict)
|
|
+ dev_obj = self.bus.get_object ('org.freedesktop.Hal', udi)
|
|
+ dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device')
|
|
+ device = dev.GetProperty ('block.device')
|
|
+ major = dev.GetProperty ('block.major')
|
|
+ minor = dev.GetProperty ('block.minor')
|
|
+ udi_info = {}
|
|
+ udi_info['device'] = device
|
|
+ udi_info['major'] = major
|
|
+ udi_info['minor'] = minor
|
|
+ udi_info['udi'] = udi
|
|
+ already = 0
|
|
+ cnt = 0;
|
|
+ for key in self.udi_dict:
|
|
+ info = self.udi_dict[key]
|
|
+ if info['udi'] == udi:
|
|
+ already = 1
|
|
+ break
|
|
+ cnt = cnt + 1
|
|
+ if already == 0:
|
|
+ self.udi_dict[cnt] = udi_info;
|
|
+ log.debug('UDI %s was added, device:%s major:%s minor:%s index:%d\n', udi, device, major, minor, cnt)
|
|
+ self.change_xenstore( "add", device, major, minor)
|
|
+
|
|
+ # Debug helper, shows dictionary contents
|
|
+ def show_dict(self,dict=None):
|
|
+ if self.debug == 0 :
|
|
+ return
|
|
+ if dict == None :
|
|
+ dict = self.udi_dict
|
|
+ for key in dict:
|
|
+ log.debug('udi_info %s udi_info:%s',key,dict[key])
|
|
+
|
|
+ # Set or clear xenstore media-present depending on the action argument
|
|
+ # for every vbd that has this block device
|
|
+ def change_xenstore(self,action, device, major, minor):
|
|
+ for type in DEVICE_TYPES:
|
|
+ path = self.dbpath + '/' + type
|
|
+ domains = xstransact.List(path)
|
|
+ log.debug('domains: %s', domains)
|
|
+ for domain in domains: # for each domain
|
|
+ devices = xstransact.List( path + '/' + domain)
|
|
+ log.debug('devices: %s',devices)
|
|
+ for device in devices: # for each vbd device
|
|
+ str = device.split('/')
|
|
+ vbd_type = None;
|
|
+ vbd_physical_device = None
|
|
+ vbd_media = None
|
|
+ vbd_device_path = path + '/' + domain + '/' + device
|
|
+ listing = xstransact.List(vbd_device_path)
|
|
+ for entry in listing: # for each entry
|
|
+ item = path + '/' + entry
|
|
+ value = xstransact.Read( vbd_device_path + '/' + entry)
|
|
+ log.debug('%s=%s',item,value)
|
|
+ if item.find('media-present') != -1:
|
|
+ vbd_media = item;
|
|
+ vbd_media_path = item
|
|
+ if item.find('physical-device') != -1:
|
|
+ vbd_physical_device = value;
|
|
+ if item.find('type') != -1:
|
|
+ vbd_type = value;
|
|
+ if vbd_type is not None and vbd_physical_device is not None and vbd_media is not None :
|
|
+ inode = vbd_physical_device.split(':')
|
|
+ imajor = parse_hex(inode[0])
|
|
+ iminor = parse_hex(inode[1])
|
|
+ log.debug("action:%s major:%s- minor:%s- imajor:%s- iminor:%s- inode: %s",
|
|
+ action,major,minor, imajor, iminor, inode)
|
|
+ if int(imajor) == int(major) and int(iminor) == int(minor):
|
|
+ if action == "add":
|
|
+ xs_dict = {'media': "1"}
|
|
+ xstransact.Write(vbd_device_path, 'media-present', "1" )
|
|
+ log.debug("wrote xenstore media-present 1 path:%s",vbd_media_path)
|
|
+ else:
|
|
+ xstransact.Write(vbd_device_path, 'media-present', "0" )
|
|
+ log.debug("wrote xenstore media 0 path:%s",vbd_media_path)
|
|
+
|
|
+def mylog( fmt, *args):
|
|
+ f = open('/tmp/haldaemon.log', 'a')
|
|
+ print >>f, "HalDaemon ", fmt % args
|
|
+ f.close()
|
|
+
|
|
+
|
|
+def parse_hex(val):
|
|
+ try:
|
|
+ if isinstance(val, types.StringTypes):
|
|
+ return int(val, 16)
|
|
+ else:
|
|
+ return val
|
|
+ except ValueError:
|
|
+ return None
|
|
+
|
|
+if __name__ == "__main__":
|
|
+ watcher = HalDaemon()
|
|
+ watcher.run()
|
|
+ print 'Falling off end'
|
|
+
|
|
+
|
|
Index: xen-4.2.0-testing/tools/python/xen/xend/server/Hald.py
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ xen-4.2.0-testing/tools/python/xen/xend/server/Hald.py
|
|
@@ -0,0 +1,125 @@
|
|
+#============================================================================
|
|
+# 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 Pat Campbell <plc@novell.com>
|
|
+# Copyright (C) 2007 Novell Inc.
|
|
+#============================================================================
|
|
+
|
|
+import errno
|
|
+import types
|
|
+import os
|
|
+import sys
|
|
+import time
|
|
+import signal
|
|
+from traceback import print_exc
|
|
+
|
|
+from xen.xend.XendLogging import log
|
|
+
|
|
+class Hald:
|
|
+ def __init__(self):
|
|
+ self.ready = False
|
|
+ self.running = True
|
|
+
|
|
+ def run(self):
|
|
+ """Starts the HalDaemon process
|
|
+ """
|
|
+ self.ready = True
|
|
+ try:
|
|
+ myfile = self.find("xen/xend/server/HalDaemon.py")
|
|
+ args = (["python", myfile ])
|
|
+ self.pid = self.daemonize("python", args )
|
|
+ #log.debug( "%s %s pid:%d", "Hald.py starting ", args, self.pid )
|
|
+ except:
|
|
+ self.pid = -1
|
|
+ log.debug("Unable to start HalDaemon process")
|
|
+
|
|
+ def shutdown(self):
|
|
+ """Shutdown the HalDaemon process
|
|
+ """
|
|
+ log.debug("%s pid:%d", "Hald.shutdown()", self.pid)
|
|
+ self.running = False
|
|
+ self.ready = False
|
|
+ if self.pid != -1:
|
|
+ try:
|
|
+ os.kill(self.pid, signal.SIGINT)
|
|
+ except:
|
|
+ print_exc()
|
|
+
|
|
+ def daemonize(self,prog, args):
|
|
+ """Runs a program as a daemon with the list of arguments. Returns the PID
|
|
+ of the daemonized program, or returns 0 on error.
|
|
+ Copied from xm/create.py instead of importing to reduce coupling
|
|
+ """
|
|
+ r, w = os.pipe()
|
|
+ pid = os.fork()
|
|
+
|
|
+ if pid == 0:
|
|
+ os.close(r)
|
|
+ w = os.fdopen(w, 'w')
|
|
+ os.setsid()
|
|
+ try:
|
|
+ pid2 = os.fork()
|
|
+ except:
|
|
+ pid2 = None
|
|
+ if pid2 == 0:
|
|
+ os.chdir("/")
|
|
+ env = os.environ.copy()
|
|
+ env['PYTHONPATH'] = self.getpythonpath()
|
|
+ for fd in range(0, 256):
|
|
+ try:
|
|
+ os.close(fd)
|
|
+ except:
|
|
+ pass
|
|
+ os.open("/dev/null", os.O_RDWR)
|
|
+ os.dup2(0, 1)
|
|
+ os.dup2(0, 2)
|
|
+ os.execvpe(prog, args, env)
|
|
+ os._exit(1)
|
|
+ else:
|
|
+ w.write(str(pid2 or 0))
|
|
+ w.close()
|
|
+ os._exit(0)
|
|
+ os.close(w)
|
|
+ r = os.fdopen(r)
|
|
+ daemon_pid = int(r.read())
|
|
+ r.close()
|
|
+ os.waitpid(pid, 0)
|
|
+ #log.debug( "daemon_pid: %d", daemon_pid )
|
|
+ return daemon_pid
|
|
+
|
|
+ def getpythonpath(self):
|
|
+ str = " "
|
|
+ for p in sys.path:
|
|
+ if str != " ":
|
|
+ str = str + ":" + p
|
|
+ else:
|
|
+ if str != "":
|
|
+ str = p
|
|
+ return str
|
|
+
|
|
+ def find(self,path, matchFunc=os.path.isfile):
|
|
+ """Find a module in the sys.path
|
|
+ From web page: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52224
|
|
+ """
|
|
+ for dirname in sys.path:
|
|
+ candidate = os.path.join(dirname, path)
|
|
+ if matchFunc(candidate):
|
|
+ return candidate
|
|
+ raise Error("Can't find file %s" % path)
|
|
+
|
|
+if __name__ == "__main__":
|
|
+ watcher = Hald()
|
|
+ watcher.run()
|
|
+ time.sleep(10)
|
|
+ watcher.shutdown()
|
|
Index: xen-4.2.0-testing/tools/python/xen/xend/server/SrvServer.py
|
|
===================================================================
|
|
--- xen-4.2.0-testing.orig/tools/python/xen/xend/server/SrvServer.py
|
|
+++ xen-4.2.0-testing/tools/python/xen/xend/server/SrvServer.py
|
|
@@ -57,6 +57,7 @@ from xen.web.SrvDir import SrvDir
|
|
|
|
from SrvRoot import SrvRoot
|
|
from XMLRPCServer import XMLRPCServer
|
|
+from xen.xend.server.Hald import Hald
|
|
|
|
xoptions = XendOptions.instance()
|
|
|
|
@@ -252,6 +253,8 @@ def _loadConfig(servers, root, reload):
|
|
if xoptions.get_xend_unix_xmlrpc_server():
|
|
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
|
|
|
|
+ servers.add(Hald())
|
|
+
|
|
|
|
def create():
|
|
root = SrvDir()
|
|
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
|
|
===================================================================
|
|
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
|
|
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
|
|
@@ -18,6 +18,7 @@
|
|
#include "exec-all.h"
|
|
#include "sysemu.h"
|
|
|
|
+#include "console.h"
|
|
#include "hw.h"
|
|
#include "pci.h"
|
|
#include "qemu-timer.h"
|
|
@@ -595,6 +596,21 @@ void xenstore_parse_domain_config(int hv
|
|
#endif
|
|
|
|
bs = bdrv_new(dev);
|
|
+
|
|
+ /* if cdrom physical put a watch on media-present */
|
|
+ if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
|
|
+ if (drv && !strcmp(drv, "phy")) {
|
|
+ if (pasprintf(&buf, "%s/media-present", bpath) != -1) {
|
|
+ if (bdrv_is_inserted(bs))
|
|
+ xs_write(xsh, XBT_NULL, buf, "1", strlen("1"));
|
|
+ else {
|
|
+ xs_write(xsh, XBT_NULL, buf, "0", strlen("0"));
|
|
+ }
|
|
+ xs_watch(xsh, buf, "media-present");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
/* check if it is a cdrom */
|
|
if (danger_type && !strcmp(danger_type, "cdrom")) {
|
|
bdrv_set_type_hint(bs, BDRV_TYPE_CDROM);
|
|
@@ -1028,6 +1044,50 @@ static void xenstore_process_vcpu_set_ev
|
|
return;
|
|
}
|
|
|
|
+static void xenstore_process_media_change_event(char **vec)
|
|
+{
|
|
+ char *media_present = NULL;
|
|
+ unsigned int len;
|
|
+
|
|
+ media_present = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
|
|
+
|
|
+ if (media_present) {
|
|
+ BlockDriverState *bs;
|
|
+ char *buf = NULL, *cp = NULL, *path = NULL, *dev = NULL;
|
|
+
|
|
+ path = strdup(vec[XS_WATCH_PATH]);
|
|
+ cp = strstr(path, "media-present");
|
|
+ if (cp){
|
|
+ *(cp-1) = '\0';
|
|
+ pasprintf(&buf, "%s/dev", path);
|
|
+ dev = xs_read(xsh, XBT_NULL, buf, &len);
|
|
+ if (dev) {
|
|
+ if ( !strncmp(dev, "xvd", 3)) {
|
|
+ memmove(dev, dev+1, strlen(dev));
|
|
+ dev[0] = 'h';
|
|
+ dev[1] = 'd';
|
|
+ }
|
|
+ bs = bdrv_find(dev);
|
|
+ if (!bs) {
|
|
+ term_printf("device not found\n");
|
|
+ return;
|
|
+ }
|
|
+ if (strcmp(media_present, "0") == 0 && bs) {
|
|
+ bdrv_close(bs);
|
|
+ }
|
|
+ else if (strcmp(media_present, "1") == 0 &&
|
|
+ bs != NULL && bs->drv == NULL) {
|
|
+ if (bdrv_open(bs, bs->filename, 0 /* snapshot */) < 0) {
|
|
+ fprintf(logfile, "%s() qemu: could not open cdrom disk '%s'\n",
|
|
+ __func__, bs->filename);
|
|
+ }
|
|
+ bs->media_changed = 1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
void xenstore_process_event(void *opaque)
|
|
{
|
|
char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
|
|
@@ -1063,6 +1123,11 @@ void xenstore_process_event(void *opaque
|
|
xenstore_watch_callbacks[i].cb(vec[XS_WATCH_TOKEN],
|
|
xenstore_watch_callbacks[i].opaque);
|
|
|
|
+ if (!strcmp(vec[XS_WATCH_TOKEN], "media-present")) {
|
|
+ xenstore_process_media_change_event(vec);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
hd_index = drive_name_to_index(vec[XS_WATCH_TOKEN]);
|
|
if (hd_index == -1) {
|
|
fprintf(stderr,"medium change watch on `%s' -"
|