aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-02-17 11:19:55 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-02-17 11:19:55 +0000
commitf9de1c1ae6e28887c00fb85459fc19b0d89848a2 (patch)
treef6e452f485c98e3c9ed2cbc69ae172b4f7e5ecbb
parentae4aa4f8030d63720eb0c9db63a2a53dbdddfa1b (diff)
downloadxen-f9de1c1ae6e28887c00fb85459fc19b0d89848a2.tar.gz
xen-f9de1c1ae6e28887c00fb85459fc19b0d89848a2.tar.bz2
xen-f9de1c1ae6e28887c00fb85459fc19b0d89848a2.zip
pvSCSI, xend: add new device assignment mode
You can use "host" mode by specifying keyword "host" as virtual scsi device. Following is usage example. xm scsi-attach 1 2:0:3:4 host In this case, all LUNs under host=2 are attached to guest domain 1. The channel=0, target=3 and lun=4 are ignored. Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com> Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com> Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
-rw-r--r--tools/python/xen/xend/XendConfig.py34
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py11
-rw-r--r--tools/python/xen/xend/server/vscsiif.py15
-rw-r--r--tools/python/xen/xm/create.py43
-rw-r--r--tools/python/xen/xm/main.py59
5 files changed, 117 insertions, 45 deletions
diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py
index 5bdf02804a..8c0df3b1c2 100644
--- a/tools/python/xen/xend/XendConfig.py
+++ b/tools/python/xen/xend/XendConfig.py
@@ -1274,6 +1274,7 @@ class XendConfig(dict):
uuid.createString())
vscsi_dict = self.vscsi_convert_sxp_to_dict(config)
vscsi_devs = vscsi_dict['devs']
+ vscsi_mode = vscsi_dict['feature-host']
# create XenAPI DSCSI objects.
for vscsi_dev in vscsi_devs:
@@ -1288,9 +1289,14 @@ class XendConfig(dict):
}
XendDSCSI(dscsi_uuid, dscsi_record)
- target['devices'][vscsi_devs_uuid] = \
- (dev_type, {'devs': vscsi_devs, 'uuid': vscsi_devs_uuid} )
- log.debug("XendConfig: reading device: %s" % vscsi_devs)
+ vscsi_info = {
+ 'devs': vscsi_devs,
+ 'feature-host': vscsi_mode,
+ 'uuid': vscsi_devs_uuid
+ }
+ target['devices'][vscsi_devs_uuid] = (dev_type, vscsi_info)
+ log.debug("XendConfig: reading device: %s,%s" % \
+ (vscsi_devs, vscsi_mode))
return vscsi_devs_uuid
for opt_val in config[1:]:
@@ -1614,6 +1620,7 @@ class XendConfig(dict):
#
# [device,
# [vscsi,
+ # [feature-host, 0],
# [dev,
# [devid, 0], [p-devname, sdb], [p-dev, 1:0:0:1],
# [v-dev, 0:0:0:0], [state, 1]
@@ -1624,6 +1631,7 @@ class XendConfig(dict):
# ]
# ],
# [vscsi,
+ # [feature-host, 1],
# [dev,
# [devid, 1], [p-devname, sdg], [p-dev, 2:0:0:0],
# [v-dev, 1:0:0:0], [state, 1]
@@ -1644,6 +1652,7 @@ class XendConfig(dict):
#
# [device,
# [vscsi,
+ # [feature-host, 0],
# [dev,
# [devid, 0], [p-devname, sdd], [p-dev, 1:0:0:3],
# [v-dev, 0:0:0:2], [state, 1]
@@ -1658,7 +1667,8 @@ class XendConfig(dict):
# The Dict looks like this:
#
# { devs: [ {devid: 0, p-devname: sdd, p-dev: 1:0:0:3,
- # v-dev: 0:0:0:2, state: 1} ] }
+ # v-dev: 0:0:0:2, state: 1} ],
+ # feature-host: 1 }
dev_config = {}
@@ -1677,6 +1687,9 @@ class XendConfig(dict):
vscsi_devs.append(vscsi_dev_info)
dev_config['devs'] = vscsi_devs
+ vscsi_mode = sxp.children(dev_sxp, 'feature-host')[0]
+ dev_config['feature-host'] = vscsi_mode[1]
+
return dev_config
def console_add(self, protocol, location, other_config = {}):
@@ -1789,6 +1802,7 @@ class XendConfig(dict):
if dev_type == 'vscsi': # Special case for vscsi
vscsi_dict = self.vscsi_convert_sxp_to_dict(config)
vscsi_devs = vscsi_dict['devs']
+ vscsi_mode = vscsi_dict['feature-host']
# destroy existing XenAPI DSCSI objects
for dscsi_uuid in XendDSCSI.get_by_VM(self['uuid']):
@@ -1807,8 +1821,12 @@ class XendConfig(dict):
}
XendDSCSI(dscsi_uuid, dscsi_record)
- self['devices'][dev_uuid] = \
- (dev_type, {'devs': vscsi_devs, 'uuid': dev_uuid} )
+ vscsi_info = {
+ 'devs': vscsi_devs,
+ 'feature-host': vscsi_mode,
+ 'uuid': dev_uuid
+ }
+ self['devices'][dev_uuid] = (dev_type, vscsi_info)
return True
for opt_val in config[1:]:
@@ -1885,7 +1903,6 @@ class XendConfig(dict):
def all_devices_sxpr(self, target = None):
"""Returns the SXPR for all devices in the current configuration."""
sxprs = []
- pci_devs = []
if target == None:
target = self
@@ -1900,7 +1917,8 @@ class XendConfig(dict):
if dev_type == 'pci':
sxpr = ['pci', ['uuid', dev_info['uuid']]]
elif dev_type == 'vscsi':
- sxpr = ['vscsi', ['uuid', dev_info['uuid']]]
+ sxpr = ['vscsi', ['uuid', dev_info['uuid']],
+ ['feature-host', dev_info['feature-host']]]
for pci_dev_info in dev_info['devs']:
pci_dev_sxpr = ['dev']
for opt, val in pci_dev_info.items():
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index b56d3c55ef..0857c847c1 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -898,15 +898,21 @@ class XendDomainInfo:
else:
cur_dev_sxp = self._getDeviceInfo_vscsi(req_devid, None)
new_dev_sxp = ['vscsi']
+ cur_mode = sxp.children(cur_dev_sxp, 'feature-host')[0]
+ new_dev_sxp.append(cur_mode)
+
for cur_dev in sxp.children(cur_dev_sxp, 'dev'):
if state == xenbusState['Closing']:
+ if int(cur_mode[1]) == 1:
+ continue
cur_dev_vdev = sxp.child_value(cur_dev, 'v-dev')
if cur_dev_vdev == dev['v-dev']:
continue
new_dev_sxp.append(cur_dev)
if state == xenbusState['Initialising']:
- new_dev_sxp.append(sxp.child0(dev_sxp, 'dev'))
+ for new_dev in sxp.children(dev_sxp, 'dev'):
+ new_dev_sxp.append(new_dev)
dev_uuid = sxp.child_value(cur_dev_sxp, 'uuid')
self.info.device_update(dev_uuid, new_dev_sxp)
@@ -1112,7 +1118,8 @@ class XendDomainInfo:
vscsi_dev.append(['frontstate', None])
vscsi_devs[1].append(vscsi_dev)
dev_num = int(sxp.child_value(vscsi_dev, 'devid'))
- sxprs.append([dev_num, [vscsi_devs]])
+ vscsi_mode = sxp.children(dev_info, 'feature-host')[0]
+ sxprs.append([dev_num, [vscsi_devs, vscsi_mode]])
elif deviceClass == 'vbd':
dev = sxp.child_value(dev_info, 'dev')
if 'ioemu:' in dev:
diff --git a/tools/python/xen/xend/server/vscsiif.py b/tools/python/xen/xend/server/vscsiif.py
index db23244cc4..9657e4f4a8 100644
--- a/tools/python/xen/xend/server/vscsiif.py
+++ b/tools/python/xen/xend/server/vscsiif.py
@@ -68,6 +68,8 @@ class VSCSIController(DevController):
vscsi_config.append(['devs', devs])
state = self.readFrontend(devid, 'state')
vscsi_config.append(['state', state])
+ hostmode = self.readBackend(devid, 'feature-host')
+ vscsi_config.append(['feature-host', hostmode])
backid = self.readFrontend(devid, 'backend-id')
vscsi_config.append(['backend-id', backid])
backpath = self.readFrontend(devid, 'backend')
@@ -98,6 +100,8 @@ class VSCSIController(DevController):
devid = vscsi_config.get('devid', '')
back[devpath + '/devid'] = str(devid)
+ host_mode = config.get('feature-host','')
+ back['feature-host'] = str(host_mode)
back['uuid'] = config.get('uuid','')
devid = int(devid)
return (devid, back, {})
@@ -133,6 +137,7 @@ class VSCSIController(DevController):
vscsi_devs.append(dev_dict)
config['devs'] = vscsi_devs
+ config['feature-host'] = self.readBackend(devid, 'feature-host')
config['uuid'] = self.readBackend(devid, 'uuid')
return config
@@ -171,6 +176,7 @@ class VSCSIController(DevController):
vscsi_config = config['devs'][0]
state = vscsi_config.get('state', xenbusState['Unknown'])
driver_state = self.readBackend(devid, 'state')
+
if str(xenbusState['Connected']) != driver_state:
raise VmError("Driver status is not connected")
@@ -182,13 +188,20 @@ class VSCSIController(DevController):
elif state == xenbusState['Closing']:
found = False
devs = self.readBackendList(devid, "vscsi-devs")
+ hostmode = int(self.readBackend(devid, 'feature-host'))
vscsipath = "vscsi-devs/"
vdev = vscsi_config.get('v-dev', '')
for dev in devs:
devpath = vscsipath + dev
old_vdev = self.readBackend(devid, devpath + '/v-dev')
- if vdev == old_vdev:
+
+ if hostmode == 1:
+ #At hostmode, all v-dev that belongs to devid is deleted.
+ found = True
+ self.writeBackend(devid, devpath + '/state', \
+ str(xenbusState['Closing']))
+ elif vdev == old_vdev:
found = True
self.writeBackend(devid, devpath + '/state', \
str(xenbusState['Closing']))
diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py
index d1a8ca2e0c..d292773d9e 100644
--- a/tools/python/xen/xm/create.py
+++ b/tools/python/xen/xm/create.py
@@ -717,7 +717,7 @@ def vscsi_lookup_devid(devlist, req_devid):
if len(devlist) == 0:
return 0
else:
- for devid, backend in devlist:
+ for (devid, _, _) in devlist:
if devid == req_devid:
return 1
return 0
@@ -725,6 +725,10 @@ def vscsi_lookup_devid(devlist, req_devid):
def configure_vscsis(config_devs, vals):
"""Create the config for vscsis (virtual scsi devices).
"""
+
+ def get_devid(hctl):
+ return int(hctl.split(':')[0])
+
devidlist = []
config_scsi = []
if len(vals.vscsi) == 0:
@@ -738,31 +742,40 @@ def configure_vscsis(config_devs, vals):
if p_hctl == None:
raise ValueError('Cannot find device "%s"' % p_dev)
+ host_mode = 0
+ if v_dev == 'host':
+ host_mode = 1
+ scsi_info = []
+ devid = get_devid(p_hctl)
+ for (pHCTL, devname, _, _) in scsi_devices:
+ if get_devid(pHCTL) == devid:
+ scsi_info.append([devid, pHCTL, devname, pHCTL])
+ else:
+ scsi_info = [[get_devid(v_dev), p_hctl, devname, v_dev]]
+
for config in config_scsi:
dev = vscsi_convert_sxp_to_dict(config)
- if dev['v-dev'] == v_dev:
+ if dev['v-dev'] in [scsi_info[x][3] for x in range(len(scsi_info))]:
raise ValueError('The virtual device "%s" is already defined' % v_dev)
- v_hctl = v_dev.split(':')
- devid = int(v_hctl[0])
- config_scsi.append(['dev', \
- ['state', xenbusState['Initialising']], \
- ['devid', devid], \
- ['p-dev', p_hctl], \
- ['p-devname', devname], \
- ['v-dev', v_dev] ])
+ for (devid, pHCTL, devname, vHCTL) in scsi_info:
+ config_scsi.append(['dev', \
+ ['state', xenbusState['Initialising']], \
+ ['devid', devid], \
+ ['p-dev', pHCTL], \
+ ['p-devname', devname], \
+ ['v-dev', vHCTL] ])
if vscsi_lookup_devid(devidlist, devid) == 0:
- devidlist.append([devid, backend])
+ devidlist.append([devid, backend, host_mode])
- for devid, backend in devidlist:
- tmp = []
+ for (devid, backend, host_mode) in devidlist:
+ tmp = ['vscsi', ['feature-host', host_mode]]
for config in config_scsi:
dev = vscsi_convert_sxp_to_dict(config)
if dev['devid'] == devid:
tmp.append(config)
- tmp.insert(0, 'vscsi')
if backend:
tmp.append(['backend', backend])
config_devs.append(['device', tmp])
@@ -1044,7 +1057,7 @@ def preprocess_vscsi(vals):
n = len(d)
if n == 2:
tmp = d[1].split(':')
- if len(tmp) != 4:
+ if d[1] != 'host' and len(tmp) != 4:
err('vscsi syntax error "%s"' % d[1])
else:
d.append(None)
diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py
index 7eba580a66..193141236a 100644
--- a/tools/python/xen/xm/main.py
+++ b/tools/python/xen/xm/main.py
@@ -2032,6 +2032,8 @@ def parse_dev_info(info):
'mac' : get_info('mac', str, '??'),
#block-device specific
'ring-ref' : get_info('ring-ref', int, -1),
+ #vscsi specific
+ 'feature-host' : get_info('feature-host', int, -1),
}
def arg_check_for_resource_list(args, name):
@@ -2275,14 +2277,14 @@ def xm_scsi_list(args):
hdr = 0
for x in devs:
if hdr == 0:
- print "%-3s %-3s %-5s %-10s %-5s %-10s %-4s" \
- % ('Idx', 'BE', 'state', 'phy-hctl', 'phy', 'vir-hctl', 'devstate')
+ print "%-3s %-3s %-5s %-4s %-10s %-5s %-10s %-4s" \
+ % ('Idx', 'BE', 'state', 'host', 'phy-hctl', 'phy', 'vir-hctl', 'devstate')
hdr = 1
ni = parse_dev_info(x[1])
ni['idx'] = int(x[0])
for dev in x[1][0][1]:
mi = vscsi_convert_sxp_to_dict(dev)
- print "%(idx)-3d %(backend-id)-3d %(state)-5d " % ni,
+ print "%(idx)-3d %(backend-id)-3d %(state)-5d %(feature-host)-4d " % ni,
print "%(p-dev)-10s %(p-devname)-5s %(v-dev)-10s %(frontstate)-4s" % mi
def parse_block_configuration(args):
@@ -2512,27 +2514,46 @@ def xm_pci_attach(args):
server.xend.domain.device_configure(dom, pci)
def parse_scsi_configuration(p_scsi, v_hctl, state):
- v = v_hctl.split(':')
- if len(v) != 4:
- raise OptionError("Invalid argument: %s" % v_hctl)
+ def get_devid(hctl):
+ return int(hctl.split(':')[0])
+
+ host_mode = 0
+ scsi_devices = None
- p_hctl = None
- devname = None
if p_scsi is not None:
+ # xm scsi-attach
+ if v_hctl == "host":
+ host_mode = 1
+ scsi_devices = vscsi_util.vscsi_get_scsidevices()
+ elif len(v_hctl.split(':')) != 4:
+ raise OptionError("Invalid argument: %s" % v_hctl)
(p_hctl, devname) = \
- vscsi_util.vscsi_get_hctl_and_devname_by(p_scsi)
+ vscsi_util.vscsi_get_hctl_and_devname_by(p_scsi, scsi_devices)
if p_hctl is None:
raise OptionError("Cannot find device '%s'" % p_scsi)
-
- scsi = ['vscsi']
- scsi.append(['dev', \
- ['state', state], \
- ['devid', int(v[0])], \
- ['p-dev', p_hctl], \
- ['p-devname', devname], \
- ['v-dev', v_hctl] \
- ])
-
+ if host_mode:
+ scsi_info = []
+ devid = get_devid(p_hctl)
+ for pHCTL, devname, _, _ in scsi_devices:
+ if get_devid(pHCTL) == devid:
+ scsi_info.append([devid, pHCTL, devname, pHCTL])
+ else:
+ scsi_info = [[get_devid(v_hctl), p_hctl, devname, v_hctl]]
+ else:
+ # xm scsi-detach
+ if len(v_hctl.split(':')) != 4:
+ raise OptionError("Invalid argument: %s" % v_hctl)
+ scsi_info = [[get_devid(v_hctl), None, None, v_hctl]]
+
+ scsi = ['vscsi', ['feature-host', host_mode]]
+ for devid, pHCTL, devname, vHCTL in scsi_info:
+ scsi.append(['dev', \
+ ['state', state], \
+ ['devid', devid], \
+ ['p-dev', pHCTL], \
+ ['p-devname', devname], \
+ ['v-dev', vHCTL] \
+ ])
return scsi
def xm_scsi_attach(args):