direct-io.hg

view tools/python/xen/xend/server/blkif.py @ 12051:90164f5fbd50

[XEND] Improve error message for unparsed disk modes.
Signed-off-by: John Levon <john.levon@sun.com>
author kfraser@localhost.localdomain
date Tue Oct 31 18:24:44 2006 +0000 (2006-10-31)
parents f5321161c649
children 33e9c88aab02
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 #============================================================================
20 import re
21 import string
23 from xen.util import blkif
24 from xen.util import security
25 from xen.xend import sxp
26 from xen.xend.XendError import VmError
28 from xen.xend.server.DevController import DevController
31 class BlkifController(DevController):
32 """Block device interface controller. Handles all block devices
33 for a domain.
34 """
36 def __init__(self, vm):
37 """Create a block device controller.
38 """
39 DevController.__init__(self, vm)
42 def getDeviceDetails(self, config):
43 """@see DevController.getDeviceDetails"""
44 uname = sxp.child_value(config, 'uname')
46 dev = sxp.child_value(config, 'dev')
48 if 'ioemu:' in dev:
49 (_, dev) = string.split(dev, ':', 1)
50 try:
51 (dev, dev_type) = string.split(dev, ':', 1)
52 except ValueError:
53 dev_type = "disk"
55 if uname is None:
56 if dev_type == 'cdrom':
57 (typ, params) = ("", "")
58 else:
59 raise VmError(
60 'Block device must have physical details specified')
61 else:
62 try:
63 (typ, params) = string.split(uname, ':', 1)
64 except ValueError:
65 (typ, params) = ("", "")
67 mode = sxp.child_value(config, 'mode', 'r')
68 if mode not in ('r', 'w', 'w!'):
69 name = uname
70 if not name:
71 name = sxp.child_value(config, 'dev')
72 raise VmError('Invalid mode \'%s\' for %s. Valid modes are '
73 '{r,w,w!}' % (mode, name))
75 back = { 'dev' : dev,
76 'type' : typ,
77 'params' : params,
78 'mode' : mode
79 }
81 if security.on():
82 (label, ssidref, policy) = security.get_res_security_details(uname)
83 back.update({'acm_label' : label,
84 'acm_ssidref': str(ssidref),
85 'acm_policy' : policy})
87 devid = blkif.blkdev_name_to_number(dev)
88 if not devid:
89 raise VmError('Unable to find number for device (%s)' % (dev))
91 front = { 'virtual-device' : "%i" % devid,
92 'device-type' : dev_type
93 }
95 return (devid, back, front)
98 def reconfigureDevice(self, _, config):
99 """@see DevController.reconfigureDevice"""
100 (devid, new_back, new_front) = self.getDeviceDetails(config)
102 (dev, mode) = self.readBackend(devid, 'dev', 'mode')
103 dev_type = self.readFrontend(devid, 'device-type')
105 if (dev_type == 'cdrom' and new_front['device-type'] == 'cdrom' and
106 dev == new_back['dev'] and mode == 'r'):
107 self.writeBackend(devid,
108 'type', new_back['type'],
109 'params', new_back['params'])
110 else:
111 raise VmError('Refusing to reconfigure device %s:%d to %s' %
112 (self.deviceClass, devid, config))
115 def configuration(self, devid):
116 """@see DevController.configuration"""
118 result = DevController.configuration(self, devid)
120 (dev, typ, params, mode) = self.readBackend(devid,
121 'dev', 'type', 'params',
122 'mode')
124 if dev:
125 (dev_type) = self.readFrontend(devid, 'device-type')
126 if dev_type:
127 dev += ":" + dev_type
128 result.append(['dev', dev])
129 if typ and params:
130 result.append(['uname', typ + ":" + params])
131 if mode:
132 result.append(['mode', mode])
134 return result
137 def destroyDevice(self, devid):
138 """@see DevController.destroyDevice"""
140 # If we are given a device name, then look up the device ID from it,
141 # and destroy that ID instead. If what we are given is an integer,
142 # then assume it's a device ID and pass it straight through to our
143 # superclass's method.
145 try:
146 DevController.destroyDevice(self, int(devid))
147 except ValueError:
148 devid_end = type(devid) is str and devid.split('/')[-1] or None
150 for i in self.deviceIDs():
151 d = self.readBackend(i, 'dev')
152 if d == devid or (devid_end and d == devid_end):
153 DevController.destroyDevice(self, i)
154 return
155 raise VmError("Device %s not connected" % devid)