ia64/xen-unstable

view tools/python/xen/xend/server/blkif.py @ 12830:0c1e2abc1888

[HVM] Fix reboot failure when configured 'cdrom', i.e. bug 832.
Signed-off-by : Xinmei Huang <xinmei.huang@intel.com>
author kfraser@localhost.localdomain
date Thu Dec 07 11:16:17 2006 +0000 (2006-12-07)
parents 5bed7bc05c8a
children ef5e6df3ba9e
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 # Copyright (C) 2005, 2006 XenSource Inc.
17 #============================================================================
19 import re
20 import string
22 from xen.util import blkif
23 from xen.util import security
24 from xen.xend.XendError import VmError
25 from xen.xend.server.DevController import DevController
27 class BlkifController(DevController):
28 """Block device interface controller. Handles all block devices
29 for a domain.
30 """
32 def __init__(self, vm):
33 """Create a block device controller.
34 """
35 DevController.__init__(self, vm)
37 def getDeviceDetails(self, config):
38 """@see DevController.getDeviceDetails"""
39 uname = config.get('uname', '')
40 dev = config.get('dev', '')
42 if 'ioemu:' in dev:
43 (_, dev) = string.split(dev, ':', 1)
44 try:
45 (dev, dev_type) = string.split(dev, ':', 1)
46 except ValueError:
47 dev_type = "disk"
49 if uname is None:
50 if dev_type == 'cdrom':
51 (typ, params) = ("", "")
52 else:
53 raise VmError(
54 'Block device must have physical details specified')
55 else:
56 try:
57 (typ, params) = string.split(uname, ':', 1)
58 except ValueError:
59 (typ, params) = ("", "")
61 mode = config.get('mode', 'r')
62 if mode not in ('r', 'w', 'w!'):
63 raise VmError('Invalid mode')
65 back = {'dev' : dev,
66 'type' : typ,
67 'params' : params,
68 'mode' : mode,
69 }
71 uuid = config.get('uuid')
72 if uuid:
73 back['uuid'] = uuid
75 if security.on():
76 (label, ssidref, policy) = security.get_res_security_details(uname)
77 back.update({'acm_label' : label,
78 'acm_ssidref': str(ssidref),
79 'acm_policy' : policy})
81 devid = blkif.blkdev_name_to_number(dev)
82 if devid is None:
83 raise VmError('Unable to find number for device (%s)' % (dev))
85 front = { 'virtual-device' : "%i" % devid,
86 'device-type' : dev_type
87 }
89 return (devid, back, front)
92 def reconfigureDevice(self, _, config):
93 """@see DevController.reconfigureDevice"""
94 (devid, new_back, new_front) = self.getDeviceDetails(config)
96 (dev, mode) = self.readBackend(devid, 'dev', 'mode')
97 dev_type = self.readFrontend(devid, 'device-type')
99 if (dev_type == 'cdrom' and new_front['device-type'] == 'cdrom' and
100 dev == new_back['dev'] and mode == 'r'):
101 self.writeBackend(devid,
102 'type', new_back['type'],
103 'params', new_back['params'])
104 else:
105 raise VmError('Refusing to reconfigure device %s:%d to %s' %
106 (self.deviceClass, devid, config))
109 def getDeviceConfiguration(self, devid):
110 """Returns the configuration of a device.
112 @note: Similar to L{configuration} except it returns a dict.
113 @return: dict
114 """
115 config = DevController.getDeviceConfiguration(self, devid)
116 devinfo = self.readBackend(devid, 'dev', 'type', 'params', 'mode',
117 'uuid')
118 dev, typ, params, mode, uuid = devinfo
120 if dev:
121 dev_type = self.readFrontend(devid, 'device-type')
122 if dev_type:
123 dev += ':' + dev_type
124 config['dev'] = dev
125 if typ and params:
126 config['uname'] = typ +':' + params
127 else:
128 config['uname'] = None
129 if mode:
130 config['mode'] = mode
131 if uuid:
132 config['uuid'] = uuid
134 return config
136 def destroyDevice(self, devid):
137 """@see DevController.destroyDevice"""
139 # If we are given a device name, then look up the device ID from it,
140 # and destroy that ID instead. If what we are given is an integer,
141 # then assume it's a device ID and pass it straight through to our
142 # superclass's method.
144 try:
145 DevController.destroyDevice(self, int(devid))
146 except ValueError:
147 devid_end = type(devid) is str and devid.split('/')[-1] or None
149 for i in self.deviceIDs():
150 d = self.readBackend(i, 'dev')
151 if d == devid or (devid_end and d == devid_end):
152 DevController.destroyDevice(self, i)
153 return
154 raise VmError("Device %s not connected" % devid)