2008-03-15 00:07:14 +01:00
|
|
|
Index: xen-3.2.1-testing/tools/python/xen/xend/server/HalDaemon.py
|
2007-07-21 18:12:17 +02:00
|
|
|
===================================================================
|
2008-03-15 00:07:14 +01:00
|
|
|
--- /dev/null
|
|
|
|
+++ xen-3.2.1-testing/tools/python/xen/xend/server/HalDaemon.py
|
2008-01-12 02:32:53 +01:00
|
|
|
@@ -0,0 +1,238 @@
|
2007-07-21 18:12:17 +02:00
|
|
|
+#!/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
|
|
|
|
+
|
|
|
|
+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/vbd"
|
|
|
|
+ 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):
|
|
|
|
+ domains = xstransact.List(self.dbpath)
|
|
|
|
+ log.debug('domains: %s', domains)
|
|
|
|
+ for domain in domains: # for each domain
|
|
|
|
+ devices = xstransact.List( self.dbpath + '/' + 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 = self.dbpath + '/' + domain + '/' + device
|
|
|
|
+ listing = xstransact.List(vbd_device_path)
|
|
|
|
+ for entry in listing: # for each entry
|
|
|
|
+ item = self.dbpath + '/' + 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(':')
|
2008-01-12 02:32:53 +01:00
|
|
|
+ imajor = parse_hex(inode[0])
|
|
|
|
+ iminor = parse_hex(inode[1])
|
2007-07-21 18:12:17 +02:00
|
|
|
+ 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()
|
|
|
|
+
|
2008-01-12 02:32:53 +01:00
|
|
|
+
|
|
|
|
+def parse_hex(val):
|
|
|
|
+ try:
|
|
|
|
+ if isinstance(val, types.StringTypes):
|
|
|
|
+ return int(val, 16)
|
|
|
|
+ else:
|
|
|
|
+ return val
|
|
|
|
+ except ValueError:
|
|
|
|
+ return None
|
|
|
|
+
|
2007-07-21 18:12:17 +02:00
|
|
|
+if __name__ == "__main__":
|
|
|
|
+ watcher = HalDaemon()
|
|
|
|
+ watcher.run()
|
|
|
|
+ print 'Falling off end'
|
|
|
|
+
|
|
|
|
+
|
2008-03-15 00:07:14 +01:00
|
|
|
Index: xen-3.2.1-testing/tools/python/xen/xend/server/Hald.py
|
2007-07-21 18:12:17 +02:00
|
|
|
===================================================================
|
2008-03-15 00:07:14 +01:00
|
|
|
--- /dev/null
|
|
|
|
+++ xen-3.2.1-testing/tools/python/xen/xend/server/Hald.py
|
2008-01-12 02:32:53 +01:00
|
|
|
@@ -0,0 +1,125 @@
|
2007-07-21 18:12:17 +02:00
|
|
|
+#============================================================================
|
|
|
|
+# 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("/")
|
2008-01-12 02:32:53 +01:00
|
|
|
+ env = os.environ.copy()
|
|
|
|
+ env['PYTHONPATH'] = self.getpythonpath()
|
2007-07-21 18:12:17 +02:00
|
|
|
+ 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)
|
2008-01-12 02:32:53 +01:00
|
|
|
+ os.execvpe(prog, args, env)
|
2007-07-21 18:12:17 +02:00
|
|
|
+ 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
|
|
|
|
+
|
2008-01-12 02:32:53 +01:00
|
|
|
+ def getpythonpath(self):
|
|
|
|
+ str = " "
|
|
|
|
+ for p in sys.path:
|
|
|
|
+ if str != " ":
|
|
|
|
+ str = str + ":" + p
|
|
|
|
+ else:
|
|
|
|
+ if str != "":
|
|
|
|
+ str = p
|
|
|
|
+ return str
|
|
|
|
+
|
2007-07-21 18:12:17 +02:00
|
|
|
+ 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()
|
2008-03-15 00:07:14 +01:00
|
|
|
Index: xen-3.2.1-testing/tools/python/xen/xend/server/SrvServer.py
|
2007-07-21 18:12:17 +02:00
|
|
|
===================================================================
|
2008-03-15 00:07:14 +01:00
|
|
|
--- xen-3.2.1-testing.orig/tools/python/xen/xend/server/SrvServer.py
|
|
|
|
+++ xen-3.2.1-testing/tools/python/xen/xend/server/SrvServer.py
|
|
|
|
@@ -56,6 +56,7 @@ from xen.web.SrvDir import SrvDir
|
2007-07-21 18:12:17 +02:00
|
|
|
|
|
|
|
from SrvRoot import SrvRoot
|
|
|
|
from XMLRPCServer import XMLRPCServer
|
|
|
|
+from xen.xend.server.Hald import Hald
|
|
|
|
|
|
|
|
xoptions = XendOptions.instance()
|
|
|
|
|
2008-03-15 00:07:14 +01:00
|
|
|
@@ -245,6 +246,8 @@ def _loadConfig(servers, root, reload):
|
2007-07-21 18:12:17 +02:00
|
|
|
if xoptions.get_xend_unix_xmlrpc_server():
|
|
|
|
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
|
|
|
|
|
|
|
|
+ servers.add(Hald())
|
|
|
|
+
|
|
|
|
|
|
|
|
def create():
|
|
|
|
root = SrvDir()
|
2008-03-15 00:07:14 +01:00
|
|
|
Index: xen-3.2.1-testing/tools/ioemu/xenstore.c
|
2008-01-12 02:32:53 +01:00
|
|
|
===================================================================
|
2008-03-15 00:07:14 +01:00
|
|
|
--- xen-3.2.1-testing.orig/tools/ioemu/xenstore.c
|
|
|
|
+++ xen-3.2.1-testing/tools/ioemu/xenstore.c
|
2008-04-12 21:41:18 +02:00
|
|
|
@@ -232,6 +232,16 @@ void xenstore_parse_domain_config(int do
|
|
|
|
fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
|
|
|
|
params);
|
|
|
|
}
|
|
|
|
+ /* if pyhsical CDROM put a watch on media-present after creating it */
|
|
|
|
+ if (type && !strcmp(type, "cdrom") && drv && !strcmp(drv, "phy")) {
|
|
|
|
+ if (pasprintf(&buf, "%s/media-present", bpath) != -1) {
|
|
|
|
+ if (bdrv_is_inserted(bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)]))
|
2008-01-12 02:32:53 +01:00
|
|
|
+ xs_write(xsh, XBT_NULL, buf, "1", strlen("1"));
|
2008-04-12 21:41:18 +02:00
|
|
|
+ else
|
|
|
|
+ xs_write(xsh, XBT_NULL, buf, "0", strlen("0"));
|
|
|
|
+ xs_watch(xsh, buf, "media-present");
|
2008-01-12 02:32:53 +01:00
|
|
|
+ }
|
2008-04-12 21:41:18 +02:00
|
|
|
+ }
|
|
|
|
}
|
2008-03-15 00:07:14 +01:00
|
|
|
|
2008-04-12 21:41:18 +02:00
|
|
|
/* Set a watch for log-dirty requests from the migration tools */
|
|
|
|
@@ -425,6 +435,50 @@ void xenstore_record_dm_state(char *stat
|
2008-01-12 02:32:53 +01:00
|
|
|
free(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
+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)
|
|
|
|
{
|
2008-03-06 02:36:51 +01:00
|
|
|
char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
|
2008-04-12 21:41:18 +02:00
|
|
|
@@ -444,6 +498,11 @@ void xenstore_process_event(void *opaque
|
2008-01-12 02:32:53 +01:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (!strcmp(vec[XS_WATCH_TOKEN], "media-present")) {
|
|
|
|
+ xenstore_process_media_change_event(vec);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
|
|
|
|
strlen(vec[XS_WATCH_TOKEN]) != 3)
|
|
|
|
goto out;
|
2008-03-15 00:07:14 +01:00
|
|
|
Index: xen-3.2.1-testing/tools/ioemu/hw/ide.c
|
2008-03-06 02:36:51 +01:00
|
|
|
===================================================================
|
2008-03-15 00:07:14 +01:00
|
|
|
--- xen-3.2.1-testing.orig/tools/ioemu/hw/ide.c
|
|
|
|
+++ xen-3.2.1-testing/tools/ioemu/hw/ide.c
|
|
|
|
@@ -350,6 +350,7 @@ typedef struct IDEState {
|
2008-03-06 02:36:51 +01:00
|
|
|
uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
|
|
|
|
QEMUTimer *sector_write_timer; /* only used for win2k instal hack */
|
|
|
|
uint32_t irq_count; /* counts IRQs when using win2k install hack */
|
|
|
|
+ uint8_t send_ua; /* send SENSE_UNIT_ATTENTION on next ready */
|
|
|
|
} IDEState;
|
|
|
|
|
|
|
|
#define BM_STATUS_DMAING 0x01
|
2008-04-12 21:41:18 +02:00
|
|
|
@@ -1446,8 +1447,15 @@ static void ide_atapi_cmd(IDEState *s)
|
2008-03-06 02:36:51 +01:00
|
|
|
switch(s->io_buffer[0]) {
|
|
|
|
case GPCMD_TEST_UNIT_READY:
|
|
|
|
if (bdrv_is_inserted(s->bs)) {
|
|
|
|
+ if (s->send_ua) {
|
|
|
|
+ ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION,
|
|
|
|
+ ASC_MEDIUM_NOT_PRESENT);
|
|
|
|
+ s->send_ua = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
ide_atapi_cmd_ok(s);
|
|
|
|
} else {
|
|
|
|
+ s->send_ua = 1;
|
|
|
|
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
|
|
ASC_MEDIUM_NOT_PRESENT);
|
|
|
|
xenstore_check_new_media_present(1000);
|