mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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>
This commit is contained in:
1 parent
ae4aa4f803
commit
f9de1c1ae6
5 files changed
+116
-44
No files matched your search
@@ -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():
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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']))
|
||||
|
||||
@@ -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)
|
||||
|
||||
+39
-18
@@ -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)
|
||||
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']
|
||||
scsi.append(['dev', \
|
||||
['state', state], \
|
||||
['devid', int(v[0])], \
|
||||
['p-dev', p_hctl], \
|
||||
['p-devname', devname], \
|
||||
['v-dev', 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):
|
||||
|
||||