All of lore.kernel.org
 help / color / mirror / Atom feed
* RFC: Xen 3.1.1
@ 2007-09-03 14:34 Keir Fraser
  2007-09-03 19:18 ` Daniel P. Berrange
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Keir Fraser @ 2007-09-03 14:34 UTC (permalink / raw)
  To: xen-devel

Folks,

We're planning to roll an update to the 3.1 branch, hopefully towards the
end of next week. I have a fair number of patches already queued up to
consider for backport, but if anyone has any in particular they would like
to be considered, please let us know! This is *particularly* aimed at ia64
and powerpc maintainers, since I currently have no ia64 or ppc patches
queued up for backport.

 Regards,
 Keir

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen 3.1.1
  2007-09-03 14:34 RFC: Xen 3.1.1 Keir Fraser
@ 2007-09-03 19:18 ` Daniel P. Berrange
  2007-09-04  7:12   ` Keir Fraser
  2007-09-05 16:43   ` RFC: Xen cdrom haldaemon Pat Campbell
  2007-09-03 23:00 ` RFC: Xen 3.1.1 James Harper
  2007-09-04  0:32 ` John Levon
  2 siblings, 2 replies; 11+ messages in thread
From: Daniel P. Berrange @ 2007-09-03 19:18 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

On Mon, Sep 03, 2007 at 03:34:42PM +0100, Keir Fraser wrote:
> Folks,
> 
> We're planning to roll an update to the 3.1 branch, hopefully towards the
> end of next week. I have a fair number of patches already queued up to
> consider for backport, but if anyone has any in particular they would like
> to be considered, please let us know! This is *particularly* aimed at ia64
> and powerpc maintainers, since I currently have no ia64 or ppc patches
> queued up for backport.

I'd like to get the PVFB changes to replace libvncserver with QEMU into the
release. I'll post updated patches ASAP.

I recently managed to get support for TLS + x509 certificate authentication
merged into upstream QEMU for the VNC server so we have some serious quality
security there. The back-port to QEMU 0.9.0 in Xen should be fairly easy for
me to do, so I'll hopefully be able submit that in the next week too.

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: RFC: Xen 3.1.1
  2007-09-03 14:34 RFC: Xen 3.1.1 Keir Fraser
  2007-09-03 19:18 ` Daniel P. Berrange
@ 2007-09-03 23:00 ` James Harper
  2007-09-04  0:32 ` John Levon
  2 siblings, 0 replies; 11+ messages in thread
From: James Harper @ 2007-09-03 23:00 UTC (permalink / raw)
  To: Keir Fraser, xen-devel

Two things I would like to see fixed (which may already be...) are:

1. the bug in qemu that was giving me random crashes (see patch supplied
by 'Daniel P. Berrange [berrange@redhat.com]' in the xen-users list with
the subject 'qemu-dm crashing under 3.1' on or around 20070615). HVM is
pretty much not usable without it - uptimes of a few days maximum.

2. A fix for the bug where HVM domains ignore the flag to say use local
time. My windows domains all start 10 hours off.

Thanks

James

> -----Original Message-----
> From: xen-devel-bounces@lists.xensource.com [mailto:xen-devel-
> bounces@lists.xensource.com] On Behalf Of Keir Fraser
> Sent: Tuesday, 4 September 2007 00:35
> To: xen-devel
> Subject: [Xen-devel] RFC: Xen 3.1.1
> 
> Folks,
> 
> We're planning to roll an update to the 3.1 branch, hopefully towards
the
> end of next week. I have a fair number of patches already queued up to
> consider for backport, but if anyone has any in particular they would
like
> to be considered, please let us know! This is *particularly* aimed at
ia64
> and powerpc maintainers, since I currently have no ia64 or ppc patches
> queued up for backport.
> 
>  Regards,
>  Keir
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen 3.1.1
  2007-09-03 14:34 RFC: Xen 3.1.1 Keir Fraser
  2007-09-03 19:18 ` Daniel P. Berrange
  2007-09-03 23:00 ` RFC: Xen 3.1.1 James Harper
@ 2007-09-04  0:32 ` John Levon
  2 siblings, 0 replies; 11+ messages in thread
From: John Levon @ 2007-09-04  0:32 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

On Mon, Sep 03, 2007 at 03:34:42PM +0100, Keir Fraser wrote:

> We're planning to roll an update to the 3.1 branch, hopefully towards the
> end of next week.

That seems awfully quick, given that we can't yet see what will be in the
release?

Top of my list are all the patches that implement missing Xen API stuff
such as 15275:b643179d7452

Also the managed domain foibles like 15149:8fcefab1d63b and
15394:168b143a1a88, etc.

Both of these groups of patches are essentially finishing stuff that
should have been in the release already so seem important.

15161:e046da853ffc - whilst an RFE, this would be very nice to have.

15164:d93e560c1d50
15165:4730ec3d5ab3
15179:152dc0d812b2 - these are essentially about not losing data

15621:f85acff5bef5, 15251:6f06bd06ef47 and related - low risk but
without these ballooning patches, dom0 behaviour can become pathological

15253:ebe4140fe4f8 - this was a nasty little bug

15283:e08cbd487414 - reflect current reality

15671:0c79a9414f8d, 15673:f343d3c16dcc, 15674:07364f8574b8 - nasty
random corruption?

regards
john

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen 3.1.1
  2007-09-03 19:18 ` Daniel P. Berrange
@ 2007-09-04  7:12   ` Keir Fraser
  2007-09-04 13:30     ` Daniel P. Berrange
  2007-09-05 16:43   ` RFC: Xen cdrom haldaemon Pat Campbell
  1 sibling, 1 reply; 11+ messages in thread
From: Keir Fraser @ 2007-09-04  7:12 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: xen-devel

On 3/9/07 20:18, "Daniel P. Berrange" <berrange@redhat.com> wrote:

> I'd like to get the PVFB changes to replace libvncserver with QEMU into the
> release. I'll post updated patches ASAP.
> 
> I recently managed to get support for TLS + x509 certificate authentication
> merged into upstream QEMU for the VNC server so we have some serious quality
> security there. The back-port to QEMU 0.9.0 in Xen should be fairly easy for
> me to do, so I'll hopefully be able submit that in the next week too.

Does backporting these to 3.1 make sense given that it uses qemu 0.8.2?

 -- Keir

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen 3.1.1
  2007-09-04  7:12   ` Keir Fraser
@ 2007-09-04 13:30     ` Daniel P. Berrange
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel P. Berrange @ 2007-09-04 13:30 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

On Tue, Sep 04, 2007 at 08:12:58AM +0100, Keir Fraser wrote:
> On 3/9/07 20:18, "Daniel P. Berrange" <berrange@redhat.com> wrote:
> 
> > I'd like to get the PVFB changes to replace libvncserver with QEMU into the
> > release. I'll post updated patches ASAP.
> > 
> > I recently managed to get support for TLS + x509 certificate authentication
> > merged into upstream QEMU for the VNC server so we have some serious quality
> > security there. The back-port to QEMU 0.9.0 in Xen should be fairly easy for
> > me to do, so I'll hopefully be able submit that in the next week too.
> 
> Does backporting these to 3.1 make sense given that it uses qemu 0.8.2?

I've backported them to 3.1 / QEMU 0.8.2 for the Fedora 8, test2 release but 
it was not exactly pretty. There've been a fair few changes to QEMU & its VNC
server between 0.8.2 and 0.9.0, plus the various Xen specific patches, so I had
to pull in a fair number of other changes first. If there's interest I can
send out the patches against 3.1, but otherwise I'll just focus on the 
xen-unstable tree.

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RFC: Xen cdrom haldaemon
  2007-09-03 19:18 ` Daniel P. Berrange
  2007-09-04  7:12   ` Keir Fraser
@ 2007-09-05 16:43   ` Pat Campbell
  2007-09-05 17:39     ` Keir Fraser
  2007-09-05 17:56     ` Daniel P. Berrange
  1 sibling, 2 replies; 11+ messages in thread
From: Pat Campbell @ 2007-09-05 16:43 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 3566 bytes --]

Hi,

I have found that the DOM0 CDROM device returns a stale disk 
size if a CD is changed while any application has the device open.

Test scenerio:  ( Don't need XEN for this )
  Two shell processes
    Shell A runs simple test program with an arg to 
       open the cd for reading 
       report media size using lseek(0, SEEK_END) 
       then enter a sleep loop leaving FD open
    In Shell B 
       eject 
       insert a different CD 
       eject -t, 
       run simple test progran, no arg 
           ( size is still what was reported in shell A)
       Kill Shell A test CD process
       Run test CD process again, now you should have the 
           correct size

  Simple test program, cdrom-test.c, has been attached.

I did enter a defect against the Linux kernel about this but
was unable to convince them it was their defect.

If we put Xen in the mix, say installing a FV Redhat system
from physical CD media you will have two CDROM device file
descriptors open.  One in blkback and the other in QEMU. 
When you get to CD #2 you won't be able to complete the
install as the total disk size has not been updated for
the larger CD #2, stays at the smaller CD #1 size.

You can get the QEMU descriptor closed by using xen-store
writes but none effect the blkback FD and there is no
way, that I have found, to effect ALL open Xen related FDs on 
that device.

I have created a proof of concept patch for 3.1 that addresses the 
above issue by causing all VMs, FV and PV, to close thier open
pyhsical CDROM file descriptors when the device door is opened.  File
descriptors are re-opened when the door is closed AND a CD was 
inserted.

The basic flow of the patch is:

 Kernel:
     blkback driver: 
       if block device is a physical cdrom then
          Add media_present=1 into xenstore  backend/vbd 
             for this device
          Place a xenstore watch on media_present
       
       watch_handler
          if watch token is media_present
              read value
              if 0 then close block device fd
              if 1 then re-open block device fd

       Any access with fd closed results in EACCESS error

    qemu
       if block device is a cdrom
          Place a xenstore watch on media_present 
       watch_handler
          if watch token is media_present
              read value
              if 0 then close block device
              if 1 then re-open block device and set media_changed

       Any access with fd closed results in EACCESS error
 
    xend
       Starts XEN HalDaemon process
    
    XEN HalDaemon   
      Registers event callback for HALD events
       callback handler
          gets device major/minor numbers
          for each vbd in xenstore
             if matching major and minor
                if add_event ( cdrom door closed with media )
                   xenstore write 1 to vbd/media_present
                else         ( cddrom door open )
                   xenstore write 0 to vbd/media_present

      I am just learning python, could use a python guy to enhance and 
      generalize.

With my patch applied I was able to install RHEL5 from the 5 CD set as
well as a WIN2003 server from multi CD media.  

The patch is attached. Patch still needs some work but I would like 
some feedback before going further down this path. Is this something
that fits into the current and near future architecture and might be 
considered for addition?  

Thanks in advance

Pat



[-- Attachment #2: cdrom-test.c --]
[-- Type: application/octet-stream, Size: 1055 bytes --]

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/cdrom.h>
#include <linux/hdreg.h>
#include <errno.h>

#define O_LARGEFILE     0100000
static int raw_open( const char *filename)
{
    int fd;
    int64_t size;
    off_t len;
    int64_t total_sectors;

    fprintf(stderr, " %s() filename:%s \n", __PRETTY_FUNCTION__, filename);
    fd = open(filename, O_RDWR |  O_LARGEFILE);
    if (fd < 0) {
        fd = open(filename, O_RDONLY | O_LARGEFILE);
        if (fd < 0)
            return -1;
    }

    len = lseek(fd, 0, SEEK_END);
    if ( len == -1 )
    {
        perror("lseek");
        fprintf(stderr, " len:%lld errno:%d \n",len, errno);
    }
    total_sectors = len / 512;
    fprintf(stderr, " %s()           len:%lld \n", __PRETTY_FUNCTION__, len );
    fprintf(stderr, " %s() total_sectors:%lld \n", __PRETTY_FUNCTION__, total_sectors );
    return 0;
}


main( int argc, char **argv )
{
    raw_open( "/dev/cdrom");
    if ( argc != 1 )
    {
        while( 1 )
            sleep(1);
    }
}

[-- Attachment #3: xen-3.1-cdrom.patch --]
[-- Type: text/plain, Size: 38705 bytes --]

# HG changeset patch
# User plc@plc4.provo.novell.com
# Date 1182539263 21600
# Node ID fa6ec13addb49f7054c364a90bbcbfae1d79fea8
# Parent  362adec0c4592f130ba17304126656b40f1b0324
CDROM removable media-present attribute plus handling code

diff -r 362adec0c459 -r fa6ec13addb4 linux-2.6-xen-sparse/drivers/xen/blkback/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Jun 22 13:02:23 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Jun 22 13:07:43 2007 -0600
@@ -1,3 +1,3 @@ obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkb
 obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o
 
-blkbk-y	:= blkback.o xenbus.o interface.o vbd.o
+blkbk-y	:= blkback.o xenbus.o interface.o vbd.o cdrom.o
diff -r 362adec0c459 -r fa6ec13addb4 linux-2.6-xen-sparse/drivers/xen/blkback/cdrom.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/cdrom.c	Fri Jun 22 13:07:43 2007 -0600
@@ -0,0 +1,169 @@
+/******************************************************************************
+ * blkback/cdrom.c
+ *
+ * Routines for managing cdrom watch and media-present attribute of a
+ * cdrom type virtual block device (VBD).
+ *
+ * Copyright (c) 2003-2005, Keir Fraser & Steve Hand
+ * Copyright (c) 2007       Pat Campbell
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "common.h"
+
+#undef DPRINTK
+#define DPRINTK(_f, _a...)			\
+	printk("(%s() file=%s, line=%d) " _f "\n",	\
+		 __PRETTY_FUNCTION__, __FILE__ , __LINE__ , ##_a )
+
+
+#define MEDIA_PRESENT "media-present"
+
+static void cdrom_media_changed(struct xenbus_watch *, const char **, unsigned int);
+
+/**
+ * Writes media-present=1 attribute for the given vbd device if not
+ * already there
+ */
+static int cdrom_xenstore_write_media_present(struct backend_info *be)
+{
+	struct xenbus_device *dev = be->dev;
+	struct xenbus_transaction xbt;
+	int err;
+    int media_present;
+
+	DPRINTK(" ");
+
+	err = xenbus_scanf(XBT_NIL, dev->nodename, MEDIA_PRESENT, "%d",
+			   &media_present);
+	if ( 0 < err) {
+		DPRINTK("already written err%d", err);
+		return(0);
+	}
+    media_present = 1;
+
+again:
+	err = xenbus_transaction_start(&xbt);
+	if (err) {
+		xenbus_dev_fatal(dev, err, "starting transaction");
+		return(-1);
+	}
+
+	err = xenbus_printf(xbt, dev->nodename, MEDIA_PRESENT, "%d", media_present );
+	if (err) {
+		xenbus_dev_fatal(dev, err, "writing %s/%s",
+			 dev->nodename, MEDIA_PRESENT);
+		goto abort;
+	}
+	err = xenbus_transaction_end(xbt, 0);
+	if (err == -EAGAIN)
+		goto again;
+	if (err)
+		xenbus_dev_fatal(dev, err, "ending transaction");
+    return(0);
+ abort:
+	xenbus_transaction_end(xbt, 1);
+    return(-1);
+}
+
+/**
+ *
+ */
+int cdrom_is_type(struct backend_info *be)
+{
+    DPRINTK( "type:%x", be->blkif->vbd.type );
+    if ( be->blkif->vbd.type & VDISK_CDROM && be->blkif->vbd.type & GENHD_FL_REMOVABLE){
+	    return(1);
+	}
+	return(0);
+}
+
+/**
+ *
+ */
+void cdrom_add_media_watch(struct backend_info *be)
+{
+	struct xenbus_device *dev = be->dev;
+	int err;
+
+    DPRINTK( "nodename:%s", dev->nodename);
+    if (cdrom_is_type(be)) {
+        DPRINTK("is a cdrom");
+        if ( cdrom_xenstore_write_media_present(be) == 0 ) {
+            DPRINTK( "xenstore wrote OK");
+	        err = xenbus_watch_path2(dev, dev->nodename, MEDIA_PRESENT,
+		        &be->backend_cdrom_watch, cdrom_media_changed);
+		    if (err) {
+			    DPRINTK( "media_present watch add failed" );
+		    }
+        }
+	}
+}
+
+/**
+ * Callback received when the "media_present" xenstore node is changed
+ */
+static void cdrom_media_changed(struct xenbus_watch *watch,
+			    const char **vec, unsigned int len)
+{
+	int err;
+	unsigned media_present;
+	struct backend_info *be
+		= container_of(watch, struct backend_info, backend_cdrom_watch);
+	struct xenbus_device *dev = be->dev;
+
+	DPRINTK(" ");
+
+    if ( !(cdrom_is_type(be))) {
+		DPRINTK("callback not for a cdrom" );
+		return;
+	}
+
+	err = xenbus_scanf(XBT_NIL, dev->nodename, MEDIA_PRESENT, "%d",
+			   &media_present);
+	if (err == 0 || err == -ENOENT) {
+		DPRINTK("xenbus_read of cdrom media_present node error:%d",err);
+		return;
+	}
+
+	if (media_present == 0) {
+	    vbd_free(&be->blkif->vbd);
+	}
+	else {
+		char *p = strrchr(dev->otherend, '/') + 1;
+		long handle = simple_strtoul(p, NULL, 0);
+
+        if (be->blkif->vbd.bdev == NULL) {
+		    err = vbd_create(be->blkif, handle, be->major, be->minor,
+				     (NULL == strchr(be->mode, 'w')));
+		    if (err) {
+			    be->major = be->minor = 0;
+			    xenbus_dev_fatal(dev, err, "creating vbd structure");
+			    return;
+		    }
+		}
+	}
+}
diff -r 362adec0c459 -r fa6ec13addb4 linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Jun 22 13:02:23 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Jun 22 13:07:43 2007 -0600
@@ -96,6 +96,17 @@ typedef struct blkif_st {
 	grant_ref_t    shmem_ref;
 } blkif_t;
 
+struct backend_info
+{
+	struct xenbus_device *dev;
+	blkif_t *blkif;
+	struct xenbus_watch backend_watch;
+	struct xenbus_watch backend_cdrom_watch;
+	unsigned major;
+	unsigned minor;
+	char *mode;
+};
+
 blkif_t *blkif_alloc(domid_t domid);
 void blkif_disconnect(blkif_t *blkif);
 void blkif_free(blkif_t *blkif);
@@ -136,4 +147,8 @@ int blkback_barrier(struct xenbus_transa
 int blkback_barrier(struct xenbus_transaction xbt,
 		    struct backend_info *be, int state);
 
+/* cdrom media change */
+int cdrom_is_type(struct backend_info *be);
+void cdrom_add_media_watch(struct backend_info *be);
+
 #endif /* __BLKIF__BACKEND__COMMON_H__ */
diff -r 362adec0c459 -r fa6ec13addb4 linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Jun 22 13:02:23 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Jun 22 13:07:43 2007 -0600
@@ -106,6 +106,9 @@ int vbd_translate(struct phys_req *req, 
 	if ((operation != READ) && vbd->readonly)
 		goto out;
 
+	if (vbd->bdev == NULL)
+		goto out;
+
 	if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
 		goto out;
 
diff -r 362adec0c459 -r fa6ec13addb4 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Jun 22 13:02:23 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Jun 22 13:07:43 2007 -0600
@@ -26,16 +26,6 @@
 #define DPRINTK(fmt, args...)				\
 	pr_debug("blkback/xenbus (%s:%d) " fmt ".\n",	\
 		 __FUNCTION__, __LINE__, ##args)
-
-struct backend_info
-{
-	struct xenbus_device *dev;
-	blkif_t *blkif;
-	struct xenbus_watch backend_watch;
-	unsigned major;
-	unsigned minor;
-	char *mode;
-};
 
 static void connect(struct backend_info *);
 static int connect_ring(struct backend_info *);
@@ -179,6 +169,12 @@ static int blkback_remove(struct xenbus_
 		be->backend_watch.node = NULL;
 	}
 
+	if (be->backend_cdrom_watch.node) {
+		unregister_xenbus_watch(&be->backend_cdrom_watch);
+		kfree(be->backend_cdrom_watch.node);
+		be->backend_cdrom_watch.node = NULL;
+	}
+
 	if (be->blkif) {
 		blkif_disconnect(be->blkif);
 		vbd_free(&be->blkif->vbd);
@@ -330,6 +326,9 @@ static void backend_changed(struct xenbu
 
 		/* We're potentially connected now */
 		update_blkif_status(be->blkif);
+
+		/* Add watch for cdrom media status if necessay */
+		cdrom_add_media_watch(be);
 	}
 }
 
diff -r 362adec0c459 -r fa6ec13addb4 tools/ioemu/block.c
--- a/tools/ioemu/block.c	Fri Jun 22 13:02:23 2007 -0600
+++ b/tools/ioemu/block.c	Fri Jun 22 13:07:43 2007 -0600
@@ -185,6 +185,13 @@ static BlockDriver *find_image_format(co
     uint8_t *buf;
     size_t bufsize = 1024;
 
+    if ( strcmp(filename, "/dev/cdrom") == 0) {
+        drv = bdrv_find_format("raw");
+        if (drv != NULL) {
+            return(drv);
+        }
+    }
+
     fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
     if (fd < 0) {
         buf = NULL;
@@ -531,19 +538,9 @@ int bdrv_is_read_only(BlockDriverState *
     return bs->read_only;
 }
 
-int bdrv_is_inserted(BlockDriverState *bs)
-{
-    return bs->inserted;
-}
-
 int bdrv_is_locked(BlockDriverState *bs)
 {
     return bs->locked;
-}
-
-void bdrv_set_locked(BlockDriverState *bs, int locked)
-{
-    bs->locked = locked;
 }
 
 void bdrv_set_change_cb(BlockDriverState *bs, 
@@ -692,8 +689,10 @@ static int raw_open(BlockDriverState *bs
     fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
     if (fd < 0) {
         fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
-        if (fd < 0)
-            return -1;
+        if (fd < 0 && strstart(filename, "/dev/cd", NULL))
+            fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE | O_NONBLOCK );
+            if (fd < 0)
+                return -1;
         bs->read_only = 1;
     }
 #ifdef _BSD
@@ -764,7 +763,93 @@ static void raw_close(BlockDriverState *
     BDRVRawState *s = bs->opaque;
     bs->total_sectors = 0;
     close(s->fd);
-}
+    s->fd = -1;
+}
+
+#include <linux/cdrom.h>
+#include <sys/ioctl.h>
+static int raw_is_inserted(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    int ret;
+
+    switch(bs->removable) {
+    case BDRV_TYPE_CDROM:
+        ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+        if (ret == CDS_DISC_OK) {
+            return 1;
+		}
+        else {
+            return 0;
+		}
+        break;
+    default:
+        return 1;
+    }
+}
+
+static int raw_media_changed(BlockDriverState *bs)
+{
+	int ret = 0;
+
+    switch(bs->removable) {
+    case BDRV_TYPE_CDROM:
+	  {
+        if( bs->media_changed == 1 )
+		{
+		  ret = 1;
+		  bs->media_changed = 0;
+		}
+		return ret;
+	  }
+	default:
+	  return -ENOTSUP;
+  }
+}
+
+
+static int raw_eject(BlockDriverState *bs, int eject_flag)
+{
+    char cmd[sizeof(bs->device_name) + 32];
+
+    switch(bs->removable) {
+        case BDRV_TYPE_CDROM:
+            if (eject_flag) {
+                sprintf(cmd, "eject %s", bs->filename);
+                if (system(cmd) == -1) {
+                    perror("CDROMEJECT");
+                }
+            } else {
+                sprintf(cmd, "eject -t %s", bs->filename);
+                if (system(cmd) == -1) {
+                    perror("CDROMCLOSETRAY");
+                }
+            }
+            break;
+        default:
+            return -ENOTSUP;
+    }
+    return 0;
+}
+
+static int raw_set_locked(BlockDriverState *bs, int locked)
+{
+    BDRVRawState *s = bs->opaque;
+
+    switch(bs->removable) {
+    case BDRV_TYPE_CDROM:
+        if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
+            /* Note: an error can happen if the distribution automatically
+               mounts the CD-ROM */
+            //        perror("CDROM_LOCKDOOR");
+        }
+        break;
+    default:
+        return -ENOTSUP;
+    }
+    return 0;
+}
+
 
 #ifdef _WIN32
 #include <windows.h>
@@ -845,6 +930,12 @@ BlockDriver bdrv_raw = {
     raw_close,
     raw_create,
     raw_flush,
+
+    /* removable device support */
+    .bdrv_is_inserted = raw_is_inserted,
+    .bdrv_media_changed = raw_media_changed,
+    .bdrv_eject = raw_eject,
+    .bdrv_set_locked = raw_set_locked,
 };
 
 void bdrv_init(void)
@@ -861,3 +952,96 @@ void bdrv_init(void)
     bdrv_register(&bdrv_vpc);
     bdrv_register(&bdrv_vvfat);
 }
+
+/**************************************************************/
+/* removable device support */
+
+/**
+ * Return TRUE if the media is present
+ */
+int bdrv_is_inserted(BlockDriverState *bs)
+{
+    BlockDriver *drv = bs->drv;
+    int ret;
+    if (!drv)
+        return 0;
+    if (!drv->bdrv_is_inserted)
+        return 1;
+    ret = drv->bdrv_is_inserted(bs);
+    return ret;
+}
+
+/**
+ * Return TRUE if the media changed since the last call to this
+ * function.
+ */
+int bdrv_media_changed(BlockDriverState *bs)
+{
+  BlockDriver *drv = bs->drv;
+  int ret;
+
+  if (!drv || !drv->bdrv_media_changed)
+	ret = -ENOTSUP;
+  else
+	ret = drv->bdrv_media_changed(bs);
+  if (ret == -ENOTSUP)
+	ret = bs->media_changed;
+  bs->media_changed = 0;
+  return ret;
+}
+
+
+/**
+ * If eject_flag is TRUE, eject the media. Otherwise, close the tray
+ */
+void bdrv_eject(BlockDriverState *bs, int eject_flag)
+{
+
+    int ret = 0;
+    char cmd[sizeof(bs->device_name) + 32];
+    BlockDriver *drv = bs->drv;
+
+    switch(bs->removable) {
+        case BDRV_TYPE_CDROM:
+            if (eject_flag) {
+                sprintf(cmd, "eject %s", bs->filename);
+                if (system(cmd) == -1) {
+                    perror("CDROMEJECT");
+                    ret = -ENOTSUP;
+                }
+            } else {
+                sprintf(cmd, "eject -t %s", bs->filename);
+                if (system(cmd) == -1) {
+                    perror("CDROMCLOSETRAY");
+                    ret = -ENOTSUP;
+                }
+            }
+            break;
+        default:
+            if (!drv || !drv->bdrv_eject) {
+                ret = -ENOTSUP;
+            } else {
+                ret = drv->bdrv_eject(bs, eject_flag);
+            }
+            if (ret == -ENOTSUP) {
+                if (eject_flag)
+                    bdrv_close(bs);
+            }
+    }
+    //return ret;
+}
+
+/**
+ * Lock or unlock the media (if it is locked, the user won't be able
+ * to eject it manually).
+ */
+void bdrv_set_locked(BlockDriverState *bs, int locked)
+{
+    BlockDriver *drv = bs->drv;
+
+    bs->locked = locked;
+    if (drv && drv->bdrv_set_locked) {
+        drv->bdrv_set_locked(bs, locked);
+    }
+}
+
diff -r 362adec0c459 -r fa6ec13addb4 tools/ioemu/block_int.h
--- a/tools/ioemu/block_int.h	Fri Jun 22 13:02:23 2007 -0600
+++ b/tools/ioemu/block_int.h	Fri Jun 22 13:07:43 2007 -0600
@@ -41,6 +41,13 @@ struct BlockDriver {
                              int nb_sectors, int *pnum);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
     int (*bdrv_make_empty)(BlockDriverState *bs);
+
+    /* removable device specific */
+    int (*bdrv_is_inserted)(BlockDriverState *bs);
+    int (*bdrv_media_changed)(BlockDriverState *bs);
+    int (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
+    int (*bdrv_set_locked)(BlockDriverState *bs, int locked);
+
     struct BlockDriver *next;
 };
 
@@ -65,6 +72,7 @@ struct BlockDriverState {
     char backing_file[1024]; /* if non zero, the image is a diff of
                                 this file image */
     int is_temporary;
+    int media_changed;
     
     BlockDriverState *backing_hd;
     
diff -r 362adec0c459 -r fa6ec13addb4 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c	Fri Jun 22 13:02:23 2007 -0600
+++ b/tools/ioemu/hw/ide.c	Fri Jun 22 13:07:43 2007 -0600
@@ -278,6 +278,7 @@
 #define ASC_ILLEGAL_OPCODE                   0x20
 #define ASC_LOGICAL_BLOCK_OOR                0x21
 #define ASC_INV_FIELD_IN_CMD_PACKET          0x24
+#define ASC_MEDIA_CHANGED                    0x28
 #define ASC_MEDIUM_NOT_PRESENT               0x3a
 #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
 
@@ -393,6 +394,7 @@ typedef struct PCIIDEState {
 } PCIIDEState;
 
 #define DMA_MULTI_THREAD
+#undef DMA_MULTI_THREAD
 
 #ifdef DMA_MULTI_THREAD
 
@@ -1341,7 +1343,6 @@ static void ide_atapi_cmd(IDEState *s)
         } else {
             ide_atapi_cmd_error(s, SENSE_NOT_READY, 
                                 ASC_MEDIUM_NOT_PRESENT);
-            xenstore_check_new_media_present(1000);
         }
         break;
     case GPCMD_MODE_SENSE_10:
@@ -1530,7 +1531,10 @@ static void ide_atapi_cmd(IDEState *s)
             
             if (eject && !start) {
                 /* eject the disk */
-                bdrv_close(s->bs);
+                bdrv_eject(s->bs, 1);
+            } else if (eject && start) {
+                /* close the tray */
+                bdrv_eject(s->bs, 0);
             }
             ide_atapi_cmd_ok(s);
         }
diff -r 362adec0c459 -r fa6ec13addb4 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c	Fri Jun 22 13:02:23 2007 -0600
+++ b/tools/ioemu/xenstore.c	Fri Jun 22 13:07:43 2007 -0600
@@ -82,7 +82,7 @@ void xenstore_parse_domain_config(int do
     char **e = NULL;
     char *buf = NULL, *path;
     char *fpath = NULL, *bpath = NULL,
-        *dev = NULL, *params = NULL, *type = NULL;
+        *dev = NULL, *params = NULL, *type = NULL, *media_present = NULL;
     int i, is_scsi;
     unsigned int len, num, hd_index;
 
@@ -168,8 +168,12 @@ void xenstore_parse_domain_config(int do
         /* check if it is a cdrom */
         if (type && !strcmp(type, "cdrom")) {
             bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
-            if (pasprintf(&buf, "%s/params", bpath) != -1)
-                xs_watch(xsh, buf, dev);
+            xs_watch(xsh, buf, dev);
+	    if (pasprintf(&buf, "%s/media-present", bpath) != -1) {
+                free(media_present);
+                media_present = xs_read(xsh, XBT_NULL, buf, &len);
+                xs_watch(xsh, buf, "media_present");
+            }
         }
         /* open device now if media present */
         if (params[0]) {
@@ -313,7 +317,7 @@ void xenstore_process_logdirty_event(voi
 
 void xenstore_process_event(void *opaque)
 {
-    char **vec, *image = NULL;
+    char **vec, *image = NULL, *media_present = NULL;
     unsigned int len, num, hd_index;
 
     vec = xs_read_watch(xsh, &num);
@@ -322,6 +326,40 @@ void xenstore_process_event(void *opaque
 
     if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
         xenstore_process_logdirty_event();
+        goto out;
+    }
+
+    if (!strcmp(vec[XS_WATCH_TOKEN], "media_present")) {
+        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) {
+                    bs = bdrv_find(dev);
+                    if (!bs) {
+                        term_printf("device not found\n");
+                        goto out;
+                    }
+                    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(stderr, "qemu: could not open hard disk image '%s'\n",
+                                    bs->filename);
+                        }
+                        bs->media_changed = 1;
+                    }
+                }
+            }
+        }
         goto out;
     }
 
diff -r 362adec0c459 -r fa6ec13addb4 tools/python/xen/xend/server/HalDaemon.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/HalDaemon.py	Fri Jun 22 13:07:43 2007 -0600
@@ -0,0 +1,228 @@
+#!/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(':')
+                   imajor = inode[0]
+                   iminor = 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()
+
+if __name__ == "__main__":
+    watcher = HalDaemon()
+    watcher.run()
+    print 'Falling off end'
+
+
diff -r 362adec0c459 -r fa6ec13addb4 tools/python/xen/xend/server/Hald.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/Hald.py	Fri Jun 22 13:07:43 2007 -0600
@@ -0,0 +1,113 @@
+#============================================================================
+# 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("/")
+                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.execvp(prog, args)
+                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 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()
diff -r 362adec0c459 -r fa6ec13addb4 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py	Fri Jun 22 13:02:23 2007 -0600
+++ b/tools/python/xen/xend/server/SrvServer.py	Fri Jun 22 13:07:43 2007 -0600
@@ -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()
 
@@ -248,6 +249,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()
# HG changeset patch
# User plc@plc4.provo.novell.com
# Date 1182542474 21600
# Node ID 46685041fb424de81500375183149ecb126e1a88
# Parent  fa6ec13addb49f7054c364a90bbcbfae1d79fea8
Added return true to raw_is_inserted() if ioctl fails

diff -r fa6ec13addb4 -r 46685041fb42 tools/ioemu/block.c
--- a/tools/ioemu/block.c	Fri Jun 22 13:07:43 2007 -0600
+++ b/tools/ioemu/block.c	Fri Jun 22 14:01:14 2007 -0600
@@ -777,6 +777,9 @@ static int raw_is_inserted(BlockDriverSt
     case BDRV_TYPE_CDROM:
         ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
         if (ret == CDS_DISC_OK) {
+            return 1;
+		}
+        if (ret == -1) {  // iso case
             return 1;
 		}
         else {
# HG changeset patch
# User plc@plc4.provo.novell.com
# Date 1182542925 21600
# Node ID 69fc41d0f24bbc6a428d0e5dd23225ef7aa9d6f5
# Parent  46685041fb424de81500375183149ecb126e1a88
Added if test for params

diff -r 46685041fb42 -r 69fc41d0f24b tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c	Fri Jun 22 14:01:14 2007 -0600
+++ b/tools/ioemu/xenstore.c	Fri Jun 22 14:08:45 2007 -0600
@@ -168,7 +168,8 @@ void xenstore_parse_domain_config(int do
         /* check if it is a cdrom */
         if (type && !strcmp(type, "cdrom")) {
             bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
-            xs_watch(xsh, buf, dev);
+            if (pasprintf(&buf, "%s/params", bpath) != -1)
+                xs_watch(xsh, buf, dev);
 	    if (pasprintf(&buf, "%s/media-present", bpath) != -1) {
                 free(media_present);
                 media_present = xs_read(xsh, XBT_NULL, buf, &len);
diff -ur a/tools/python/xen/xend/server/Hald.py b/tools/python/xen/xend/server/Hald.py
--- a/tools/python/xen/xend/server/Hald.py	2007-06-28 09:24:34.000000000 -0600
+++ b/tools/python/xen/xend/server/Hald.py	2007-06-28 09:25:33.000000000 -0600
@@ -74,6 +74,8 @@
                 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)
@@ -82,7 +84,7 @@
                 os.open("/dev/null", os.O_RDWR)
                 os.dup2(0, 1)
                 os.dup2(0, 2)
-                os.execvp(prog, args)
+                os.execvpe(prog, args, env)
                 os._exit(1)
             else:
                 w.write(str(pid2 or 0))
@@ -96,6 +98,16 @@
         #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

[-- Attachment #4: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen cdrom haldaemon
  2007-09-05 16:43   ` RFC: Xen cdrom haldaemon Pat Campbell
@ 2007-09-05 17:39     ` Keir Fraser
  2007-09-06 13:13       ` Pat Campbell
  2007-09-05 17:56     ` Daniel P. Berrange
  1 sibling, 1 reply; 11+ messages in thread
From: Keir Fraser @ 2007-09-05 17:39 UTC (permalink / raw)
  To: Pat Campbell, xen-devel

Could the haldaemon's work be pushed into blkback in the kernel?

 -- Keir

On 5/9/07 17:43, "Pat Campbell" <plc@novell.com> wrote:

> Hi,
> 
> I have found that the DOM0 CDROM device returns a stale disk
> size if a CD is changed while any application has the device open.
> 
> Test scenerio:  ( Don't need XEN for this )
>   Two shell processes
>     Shell A runs simple test program with an arg to
>        open the cd for reading
>        report media size using lseek(0, SEEK_END)
>        then enter a sleep loop leaving FD open
>     In Shell B 
>        eject 
>        insert a different CD
>        eject -t, 
>        run simple test progran, no arg
>            ( size is still what was reported in shell A)
>        Kill Shell A test CD process
>        Run test CD process again, now you should have the
>            correct size
> 
>   Simple test program, cdrom-test.c, has been attached.
> 
> I did enter a defect against the Linux kernel about this but
> was unable to convince them it was their defect.
> 
> If we put Xen in the mix, say installing a FV Redhat system
> from physical CD media you will have two CDROM device file
> descriptors open.  One in blkback and the other in QEMU.
> When you get to CD #2 you won't be able to complete the
> install as the total disk size has not been updated for
> the larger CD #2, stays at the smaller CD #1 size.
> 
> You can get the QEMU descriptor closed by using xen-store
> writes but none effect the blkback FD and there is no
> way, that I have found, to effect ALL open Xen related FDs on
> that device.
> 
> I have created a proof of concept patch for 3.1 that addresses the
> above issue by causing all VMs, FV and PV, to close thier open
> pyhsical CDROM file descriptors when the device door is opened.  File
> descriptors are re-opened when the door is closed AND a CD was
> inserted.
> 
> The basic flow of the patch is:
> 
>  Kernel:
>      blkback driver:
>        if block device is a physical cdrom then
>           Add media_present=1 into xenstore  backend/vbd
>              for this device
>           Place a xenstore watch on media_present
>        
>        watch_handler
>           if watch token is media_present
>               read value
>               if 0 then close block device fd
>               if 1 then re-open block device fd
> 
>        Any access with fd closed results in EACCESS error
> 
>     qemu
>        if block device is a cdrom
>           Place a xenstore watch on media_present
>        watch_handler
>           if watch token is media_present
>               read value
>               if 0 then close block device
>               if 1 then re-open block device and set media_changed
> 
>        Any access with fd closed results in EACCESS error
>  
>     xend
>        Starts XEN HalDaemon process
>     
>     XEN HalDaemon
>       Registers event callback for HALD events
>        callback handler
>           gets device major/minor numbers
>           for each vbd in xenstore
>              if matching major and minor
>                 if add_event ( cdrom door closed with media )
>                    xenstore write 1 to vbd/media_present
>                 else         ( cddrom door open )
>                    xenstore write 0 to vbd/media_present
> 
>       I am just learning python, could use a python guy to enhance and
>       generalize.
> 
> With my patch applied I was able to install RHEL5 from the 5 CD set as
> well as a WIN2003 server from multi CD media.
> 
> The patch is attached. Patch still needs some work but I would like
> some feedback before going further down this path. Is this something
> that fits into the current and near future architecture and might be
> considered for addition?
> 
> Thanks in advance
> 
> Pat
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen cdrom haldaemon
  2007-09-05 16:43   ` RFC: Xen cdrom haldaemon Pat Campbell
  2007-09-05 17:39     ` Keir Fraser
@ 2007-09-05 17:56     ` Daniel P. Berrange
  2007-09-06 14:05       ` Pat Campbell
  1 sibling, 1 reply; 11+ messages in thread
From: Daniel P. Berrange @ 2007-09-05 17:56 UTC (permalink / raw)
  To: Pat Campbell; +Cc: xen-devel

On Wed, Sep 05, 2007 at 10:43:30AM -0600, Pat Campbell wrote:
> The basic flow of the patch is:
> 
>  Kernel:
>      blkback driver: 
>        if block device is a physical cdrom then
>           Add media_present=1 into xenstore  backend/vbd 
>              for this device
>           Place a xenstore watch on media_present
>        
>        watch_handler
>           if watch token is media_present
>               read value
>               if 0 then close block device fd
>               if 1 then re-open block device fd
> 
>        Any access with fd closed results in EACCESS error
> 
>     qemu
>        if block device is a cdrom
>           Place a xenstore watch on media_present 
>        watch_handler
>           if watch token is media_present
>               read value
>               if 0 then close block device
>               if 1 then re-open block device and set media_changed
> 
>        Any access with fd closed results in EACCESS error
>  
>     xend
>        Starts XEN HalDaemon process
>     
>     XEN HalDaemon   
>       Registers event callback for HALD events
>        callback handler
>           gets device major/minor numbers
>           for each vbd in xenstore
>              if matching major and minor
>                 if add_event ( cdrom door closed with media )
>                    xenstore write 1 to vbd/media_present
>                 else         ( cddrom door open )
>                    xenstore write 0 to vbd/media_present
> 
>       I am just learning python, could use a python guy to enhance and 
>       generalize.

To be honest this sounds like rather overkill. Why on earth is blkback
opening the device in the first place? blkback/blkfront don't have any
kind of support for CDROM capabilities, so paravirt drivers for a disk
device Xend marked as a cdrom don't make sense. If we stop blkback from
processing any devices with the ':cdrom' annotation, then only QEMU will
have the device open & the problem should go away if I'm understanding
your description properly.

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen cdrom haldaemon
  2007-09-05 17:39     ` Keir Fraser
@ 2007-09-06 13:13       ` Pat Campbell
  0 siblings, 0 replies; 11+ messages in thread
From: Pat Campbell @ 2007-09-06 13:13 UTC (permalink / raw)
  To: Keir Fraser, xen-devel


> On Wed, Sep 5, 2007 at 11:39 AM,  Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote: 
>
> Could the haldaemon's work be pushed into blkback in the kernel?

Could be but if we pull it into the kernel we would have to write our own device
poll routine and no longer leverage HALD and DBUS. 

As I have thought about this some more I think the code I added to blkback 
to create the media present attribute should be moved up into xend as well.  

Pat

> 
>  --  Keir
> 
> On 5/9/07 17:43, "Pat Campbell" <plc@novell.com> wrote:
> 
>> Hi,
>> 
>> I have found that the DOM0 CDROM device returns a stale disk
>> size if a CD is changed while any application has the device open.
>> 
>> Test scenerio:  ( Don't need XEN for this )
>>   Two shell processes
>>     Shell A runs simple test program with an arg to
>>        open the cd for reading
>>        report media size using lseek(0, SEEK_END)
>>        then enter a sleep loop leaving FD open
>>     In Shell B 
>>        eject 
>>        insert a different CD
>>        eject - t, 
>>        run simple test progran, no arg
>>            ( size is still what was reported in shell A)
>>        Kill Shell A test CD process
>>        Run test CD process again, now you should have the
>>            correct size
>> 
>>   Simple test program, cdrom- test.c, has been attached.
>> 
>> I did enter a defect against the Linux kernel about this but
>> was unable to convince them it was their defect.
>> 
>> If we put Xen in the mix, say installing a FV Redhat system
>> from physical CD media you will have two CDROM device file
>> descriptors open.  One in blkback and the other in QEMU.
>> When you get to CD #2 you won't be able to complete the
>> install as the total disk size has not been updated for
>> the larger CD #2, stays at the smaller CD #1 size.
>> 
>> You can get the QEMU descriptor closed by using xen- store
>> writes but none effect the blkback FD and there is no
>> way, that I have found, to effect ALL open Xen related FDs on
>> that device.
>> 
>> I have created a proof of concept patch for 3.1 that addresses the
>> above issue by causing all VMs, FV and PV, to close thier open
>> pyhsical CDROM file descriptors when the device door is opened.  File
>> descriptors are re- opened when the door is closed AND a CD was
>> inserted.
>> 
>> The basic flow of the patch is:
>> 
>>  Kernel:
>>      blkback driver:
>>        if block device is a physical cdrom then
>>           Add media_present=1 into xenstore  backend/vbd
>>              for this device
>>           Place a xenstore watch on media_present
>>        
>>        watch_handler
>>           if watch token is media_present
>>               read value
>>               if 0 then close block device fd
>>               if 1 then re- open block device fd
>> 
>>        Any access with fd closed results in EACCESS error
>> 
>>     qemu
>>        if block device is a cdrom
>>           Place a xenstore watch on media_present
>>        watch_handler
>>           if watch token is media_present
>>               read value
>>               if 0 then close block device
>>               if 1 then re- open block device and set media_changed
>> 
>>        Any access with fd closed results in EACCESS error
>>  
>>     xend
>>        Starts XEN HalDaemon process
>>     
>>     XEN HalDaemon
>>       Registers event callback for HALD events
>>        callback handler
>>           gets device major/minor numbers
>>           for each vbd in xenstore
>>              if matching major and minor
>>                 if add_event ( cdrom door closed with media )
>>                    xenstore write 1 to vbd/media_present
>>                 else         ( cddrom door open )
>>                    xenstore write 0 to vbd/media_present
>> 
>>       I am just learning python, could use a python guy to enhance and
>>       generalize.
>> 
>> With my patch applied I was able to install RHEL5 from the 5 CD set as
>> well as a WIN2003 server from multi CD media.
>> 
>> The patch is attached. Patch still needs some work but I would like
>> some feedback before going further down this path. Is this something
>> that fits into the current and near future architecture and might be
>> considered for addition?
>> 
>> Thanks in advance
>> 
>> Pat
>> 
>> 
>> _______________________________________________
>> Xen- devel mailing list
>> Xen- devel@lists.xensource.com
>> http://lists.xensource.com/xen- devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFC: Xen cdrom haldaemon
  2007-09-05 17:56     ` Daniel P. Berrange
@ 2007-09-06 14:05       ` Pat Campbell
  0 siblings, 0 replies; 11+ messages in thread
From: Pat Campbell @ 2007-09-06 14:05 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: xen-devel

>>> On Wed, Sep 5, 2007 at 11:56 AM, in message <20070905175633.GI5503@redhat.com>,
"Daniel P. Berrange" <berrange@redhat.com> wrote: 
> On Wed, Sep 05, 2007 at 10:43:30AM - 0600, Pat Campbell wrote:
>> The basic flow of the patch is:
>> 
>>  Kernel:
>>      blkback driver: 
>>        if block device is a physical cdrom then
>>           Add media_present=1 into xenstore  backend/vbd 
>>              for this device
>>           Place a xenstore watch on media_present
>>        
>>        watch_handler
>>           if watch token is media_present
>>               read value
>>               if 0 then close block device fd
>>               if 1 then re- open block device fd
>> 
>>        Any access with fd closed results in EACCESS error
>> 
>>     qemu
>>        if block device is a cdrom
>>           Place a xenstore watch on media_present 
>>        watch_handler
>>           if watch token is media_present
>>               read value
>>               if 0 then close block device
>>               if 1 then re- open block device and set media_changed
>> 
>>        Any access with fd closed results in EACCESS error
>>  
>>     xend
>>        Starts XEN HalDaemon process
>>     
>>     XEN HalDaemon   
>>       Registers event callback for HALD events
>>        callback handler
>>           gets device major/minor numbers
>>           for each vbd in xenstore
>>              if matching major and minor
>>                 if add_event ( cdrom door closed with media )
>>                    xenstore write 1 to vbd/media_present
>>                 else         ( cddrom door open )
>>                    xenstore write 0 to vbd/media_present
>> 
>>       I am just learning python, could use a python guy to enhance and 
>>       generalize.
> 
> To be honest this sounds like rather overkill. Why on earth is blkback
> opening the device in the first place? blkback/blkfront don't have any
> kind of support for CDROM capabilities, so paravirt drivers for a disk
> device Xend marked as a cdrom don't make sense. If we stop blkback from
> processing any devices with the ':cdrom' annotation, then only QEMU will
> have the device open & the problem should go away if I'm understanding
> your description properly.
> 
> Dan.

Getting rid of the blkback open FD for QEMU guests would help but the
root problem still exists.  We still need to get all open file descriptors to the
CDROM device closed and reopened when the media is swapped out.

This is a contrived scenario but possible.  
    4 active FV guests, all configured to the same physical CDROM 
       ( These guests for whatever reason share the CDROM data )
    Currently there will be 8 open descriptors, 4 if blkback is changed
    Admin wants to swap out the CD with a new one that has additional info
      All open descriptors have to be closed before any guest will be 
      able to access the additional info because of the CD size not being 
      changed while any app has the CD device open. 

Pat

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2007-09-06 14:05 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-03 14:34 RFC: Xen 3.1.1 Keir Fraser
2007-09-03 19:18 ` Daniel P. Berrange
2007-09-04  7:12   ` Keir Fraser
2007-09-04 13:30     ` Daniel P. Berrange
2007-09-05 16:43   ` RFC: Xen cdrom haldaemon Pat Campbell
2007-09-05 17:39     ` Keir Fraser
2007-09-06 13:13       ` Pat Campbell
2007-09-05 17:56     ` Daniel P. Berrange
2007-09-06 14:05       ` Pat Campbell
2007-09-03 23:00 ` RFC: Xen 3.1.1 James Harper
2007-09-04  0:32 ` John Levon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.