775 lines
25 KiB
Diff
775 lines
25 KiB
Diff
|
Index: xen-3.1-testing/tools/ioemu/block.c
|
||
|
===================================================================
|
||
|
--- xen-3.1-testing.orig/tools/ioemu/block.c 2007-07-17 08:02:01.000000000 -0600
|
||
|
+++ xen-3.1-testing/tools/ioemu/block.c 2007-07-17 08:05:58.000000000 -0600
|
||
|
@@ -185,6 +185,13 @@
|
||
|
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;
|
||
|
@@ -536,21 +543,11 @@
|
||
|
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,
|
||
|
void (*change_cb)(void *opaque), void *opaque)
|
||
|
{
|
||
|
@@ -697,8 +694,10 @@
|
||
|
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
|
||
|
@@ -769,8 +768,97 @@
|
||
|
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;
|
||
|
+ }
|
||
|
+ if (ret == -1) { // iso case
|
||
|
+ 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>
|
||
|
#include <winioctl.h>
|
||
|
@@ -850,6 +938,12 @@
|
||
|
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)
|
||
|
@@ -866,3 +960,96 @@
|
||
|
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);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
Index: xen-3.1-testing/tools/ioemu/block_int.h
|
||
|
===================================================================
|
||
|
--- xen-3.1-testing.orig/tools/ioemu/block_int.h 2007-05-17 09:51:09.000000000 -0600
|
||
|
+++ xen-3.1-testing/tools/ioemu/block_int.h 2007-07-17 08:05:58.000000000 -0600
|
||
|
@@ -41,6 +41,13 @@
|
||
|
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 @@
|
||
|
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;
|
||
|
|
||
|
Index: xen-3.1-testing/tools/ioemu/hw/ide.c
|
||
|
===================================================================
|
||
|
--- xen-3.1-testing.orig/tools/ioemu/hw/ide.c 2007-05-17 09:51:09.000000000 -0600
|
||
|
+++ xen-3.1-testing/tools/ioemu/hw/ide.c 2007-07-17 08:05:58.000000000 -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 @@
|
||
|
} PCIIDEState;
|
||
|
|
||
|
#define DMA_MULTI_THREAD
|
||
|
+#undef DMA_MULTI_THREAD
|
||
|
|
||
|
#ifdef DMA_MULTI_THREAD
|
||
|
|
||
|
@@ -1341,7 +1343,6 @@
|
||
|
} 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 @@
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
Index: xen-3.1-testing/tools/ioemu/xenstore.c
|
||
|
===================================================================
|
||
|
--- xen-3.1-testing.orig/tools/ioemu/xenstore.c 2007-05-17 09:51:09.000000000 -0600
|
||
|
+++ xen-3.1-testing/tools/ioemu/xenstore.c 2007-07-17 08:05:58.000000000 -0600
|
||
|
@@ -82,7 +82,7 @@
|
||
|
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;
|
||
|
|
||
|
@@ -170,6 +170,11 @@
|
||
|
bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
|
||
|
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);
|
||
|
+ xs_watch(xsh, buf, "media_present");
|
||
|
+ }
|
||
|
}
|
||
|
/* open device now if media present */
|
||
|
if (params[0]) {
|
||
|
@@ -313,7 +318,7 @@
|
||
|
|
||
|
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);
|
||
|
@@ -325,6 +330,40 @@
|
||
|
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;
|
||
|
+ }
|
||
|
+
|
||
|
if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
|
||
|
strlen(vec[XS_WATCH_TOKEN]) != 3)
|
||
|
goto out;
|
||
|
Index: xen-3.1-testing/tools/python/xen/xend/server/HalDaemon.py
|
||
|
===================================================================
|
||
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||
|
+++ xen-3.1-testing/tools/python/xen/xend/server/HalDaemon.py 2007-07-17 08:05:58.000000000 -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'
|
||
|
+
|
||
|
+
|
||
|
Index: xen-3.1-testing/tools/python/xen/xend/server/Hald.py
|
||
|
===================================================================
|
||
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||
|
+++ xen-3.1-testing/tools/python/xen/xend/server/Hald.py 2007-07-17 08:05:58.000000000 -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()
|
||
|
Index: xen-3.1-testing/tools/python/xen/xend/server/SrvServer.py
|
||
|
===================================================================
|
||
|
--- xen-3.1-testing.orig/tools/python/xen/xend/server/SrvServer.py 2007-05-17 09:51:10.000000000 -0600
|
||
|
+++ xen-3.1-testing/tools/python/xen/xend/server/SrvServer.py 2007-07-17 08:05:58.000000000 -0600
|
||
|
@@ -57,6 +57,7 @@
|
||
|
|
||
|
from SrvRoot import SrvRoot
|
||
|
from XMLRPCServer import XMLRPCServer
|
||
|
+from xen.xend.server.Hald import Hald
|
||
|
|
||
|
xoptions = XendOptions.instance()
|
||
|
|
||
|
@@ -248,6 +249,8 @@
|
||
|
if xoptions.get_xend_unix_xmlrpc_server():
|
||
|
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
|
||
|
|
||
|
+ servers.add(Hald())
|
||
|
+
|
||
|
|
||
|
def create():
|
||
|
root = SrvDir()
|