pvSCSI: xend changes

Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
This commit is contained in:
Keir Fraser committed 2008-07-03 13:39:06 +01:00
1 parent d2831c8ba9
commit 08a42ca0b5
14 files changed
+773 -6

No files matched your search

+133
View File
@@ -0,0 +1,133 @@
#!/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) 2008 FUJITSU Limited
# Based on the blkif.py
#============================================================================
"""Support for VSCSI Devices.
"""
import os
import sys
import re
import string
def _vscsi_hctl_block(name, scsi_devices):
""" block-device name is convert into hctl. (e.g., '/dev/sda',
'0:0:0:0')"""
try:
search = re.compile(r'' + name + '$', re.DOTALL)
except Exception, e:
raise VmError("vscsi: invalid expression. " + str(e))
chk = 0
for hctl, block, sg, scsi_id in scsi_devices:
if search.match(hctl):
chk = 1
break
if chk:
return (hctl, block)
else:
return (None, None)
def _vscsi_block_scsiid_to_hctl(phyname, scsi_devices):
""" block-device name is convert into hctl. (e.g., '/dev/sda',
'0:0:0:0')"""
if re.match('/dev/sd[a-z]+([1-9]|1[0-5])?$', phyname):
# sd driver
name = re.sub('(^/dev/)|([1-9]|1[0-5])?$', '', phyname)
elif re.match('/dev/sg[0-9]+$', phyname):
# sg driver
name = re.sub('^/dev/', '', phyname)
elif re.match('/dev/st[0-9]+$', phyname):
# st driver
name = re.sub('^/dev/', '', phyname)
else:
# scsi_id -gu
name = phyname
chk = 0
for hctl, block, sg, scsi_id in scsi_devices:
if block == name:
chk = 1
break
elif sg == name:
chk = 1
break
elif scsi_id == name:
chk = 1
break
if chk:
return (hctl, block)
else:
return (None, None)
def vscsi_get_scsidevices():
""" get all scsi devices"""
SERCH_SCSI_PATH = "/sys/bus/scsi/devices"
devices = []
for dirpath, dirnames, files in os.walk(SERCH_SCSI_PATH):
for hctl in dirnames:
paths = os.path.join(dirpath, hctl)
block = "-"
for f in os.listdir(paths):
if re.match('^block', f):
os.chdir(os.path.join(paths, f))
block = os.path.basename(os.getcwd())
elif re.match('^tape', f):
os.chdir(os.path.join(paths, f))
block = os.path.basename(os.getcwd())
elif re.match('^scsi_changer', f):
os.chdir(os.path.join(paths, f))
block = os.path.basename(os.getcwd())
elif re.match('^onstream_tape', f):
os.chdir(os.path.join(paths, f))
block = os.path.basename(os.getcwd())
if re.match('^scsi_generic', f):
os.chdir(os.path.join(paths, f))
sg = os.path.basename(os.getcwd())
lines = os.popen('/sbin/scsi_id -gu -s /class/scsi_generic/' + sg).read().split()
if len(lines) == 0:
scsi_id = '-'
else:
scsi_id = lines[0]
devices.append([hctl, block, sg, scsi_id])
return devices
def vscsi_search_hctl_and_block(device):
scsi_devices = vscsi_get_scsidevices()
tmp = device.split(':')
if len(tmp) == 4:
(hctl, block) = _vscsi_hctl_block(device, scsi_devices)
else:
(hctl, block) = _vscsi_block_scsiid_to_hctl(device, scsi_devices)
return (hctl, block)
+7 -4
View File
@@ -1216,7 +1216,7 @@ class XendConfig(dict):
dev_type = sxp.name(config)
dev_info = {}
if dev_type == 'pci':
if dev_type == 'pci' or dev_type == 'vscsi':
pci_devs_uuid = sxp.child_value(config, 'uuid',
uuid.createString())
@@ -1625,7 +1625,7 @@ class XendConfig(dict):
dev_type, dev_info = self['devices'][dev_uuid]
if dev_type == 'pci': # Special case for pci
if dev_type == 'pci' or dev_type == 'vscsi': # Special case for pci
pci_dict = self.pci_convert_sxp_to_dict(config)
pci_devs = pci_dict['devs']
@@ -1739,8 +1739,11 @@ class XendConfig(dict):
ordered_refs = self.ordered_device_refs(target = target)
for dev_uuid in ordered_refs:
dev_type, dev_info = target['devices'][dev_uuid]
if dev_type == 'pci': # special case for pci devices
sxpr = ['pci', ['uuid', dev_info['uuid']]]
if dev_type == 'pci' or dev_type == 'vscsi': # special case for pci devices
if dev_type == 'pci':
sxpr = ['pci', ['uuid', dev_info['uuid']]]
elif dev_type == 'vscsi':
sxpr = ['vscsi', ['uuid', dev_info['uuid']]]
for pci_dev_info in dev_info['devs']:
pci_dev_sxpr = ['dev']
for opt, val in pci_dev_info.items():
+2 -1
View File
@@ -19,7 +19,7 @@
# A collection of DevControllers
#
from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, vfbif
from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, vfbif, vscsiif
from xen.xend.server.BlktapController import BlktapController
from xen.xend.server.ConsoleController import ConsoleController
@@ -45,6 +45,7 @@ class XendDevices:
'vfb': vfbif.VfbifController,
'vkbd': vfbif.VkbdifController,
'console': ConsoleController,
'vscsi': vscsiif.VSCSIController,
}
#@classmethod
+92 -1
View File
@@ -750,6 +750,52 @@ class XendDomainInfo:
return True
def vscsi_device_configure(self, dev_sxp):
"""Configure an existing vscsi device.
quoted pci funciton
"""
dev_class = sxp.name(dev_sxp)
if dev_class != 'vscsi':
return False
dev_config = self.pci_convert_sxp_to_dict(dev_sxp)
dev = dev_config['devs'][0]
req_devid = sxp.child_value(dev_sxp, 'devid')
req_devid = int(req_devid)
existing_dev_info = self._getDeviceInfo_vscsi(req_devid, dev['v-dev'])
state = sxp.child_value(dev_sxp, 'state')
if state == 'Initialising':
# new create
# If request devid does not exist, create and exit.
if existing_dev_info is None:
self.device_create(dev_sxp)
return True
elif existing_dev_info == "exists":
raise XendError("The virtual device %s is already defined" % dev['v-dev'])
elif state == 'Closing':
if existing_dev_info is None:
raise XendError("Cannot detach vscsi device does not exist")
# use DevController.reconfigureDevice to change device config
dev_control = self.getDeviceController(dev_class)
dev_uuid = dev_control.reconfigureDevice(req_devid, dev_config)
dev_control.waitForDevice_reconfigure(req_devid)
num_devs = dev_control.cleanupDevice(req_devid)
# update XendConfig with new device info
if dev_uuid:
new_dev_sxp = dev_control.configuration(req_devid)
self.info.device_update(dev_uuid, new_dev_sxp)
# If there is no device left, destroy vscsi and remove config.
if num_devs == 0:
self.destroyDevice('vscsi', req_devid)
del self.info['devices'][dev_uuid]
return True
def device_configure(self, dev_sxp, devid = None):
"""Configure an existing device.
@@ -768,6 +814,9 @@ class XendDomainInfo:
if dev_class == 'pci':
return self.pci_device_configure(dev_sxp)
if dev_class == 'vscsi':
return self.vscsi_device_configure(dev_sxp)
for opt_val in dev_sxp[1:]:
try:
dev_config[opt_val[0]] = opt_val[1]
@@ -942,6 +991,25 @@ class XendDomainInfo:
return dev_info
return None
def _getDeviceInfo_vscsi(self, devid, vdev):
devid = int(devid)
for dev_type, dev_info in self.info.all_devices_sxpr():
if dev_type != 'vscsi':
continue
existing_dev_uuid = sxp.child_value(dev_info, 'uuid')
existing_conf = self.info['devices'][existing_dev_uuid][1]
existing_dev = existing_conf['devs'][0]
existing_devid = int(existing_dev['devid'])
existing_vdev = existing_dev['v-dev']
if vdev == existing_vdev:
return "exists"
if devid == existing_devid:
return dev_info
return None
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
@@ -1811,10 +1879,12 @@ class XendDomainInfo:
if self.image:
self.image.prepareEnvironment()
vscsi_uuidlist = {}
vscsi_devidlist = []
ordered_refs = self.info.ordered_device_refs()
for dev_uuid in ordered_refs:
devclass, config = self.info['devices'][dev_uuid]
if devclass in XendDevices.valid_devices():
if devclass in XendDevices.valid_devices() and devclass != 'vscsi':
log.info("createDevice: %s : %s" % (devclass, scrub_password(config)))
dev_uuid = config.get('uuid')
devid = self._createDevice(devclass, config)
@@ -1823,6 +1893,27 @@ class XendDomainInfo:
if dev_uuid in self.info['devices']:
self.info['devices'][dev_uuid][1]['devid'] = devid
elif devclass == 'vscsi':
vscsi_config = config.get('devs', [])[0]
devid = vscsi_config.get('devid', '')
dev_uuid = config.get('uuid')
vscsi_uuidlist[devid] = dev_uuid
vscsi_devidlist.append(devid)
#It is necessary to sorted it for /dev/sdxx in guest.
if len(vscsi_uuidlist) > 0:
vscsi_devidlist.sort()
for vscsiid in vscsi_devidlist:
dev_uuid = vscsi_uuidlist[vscsiid]
devclass, config = self.info['devices'][dev_uuid]
log.info("createDevice: %s : %s" % (devclass, scrub_password(config)))
dev_uuid = config.get('uuid')
devid = self._createDevice(devclass, config)
# store devid in XendConfig for caching reasons
if dev_uuid in self.info['devices']:
self.info['devices'][dev_uuid][1]['devid'] = devid
if self.image:
self.image.createDeviceModel()
+228
View File
@@ -0,0 +1,228 @@
#============================================================================
# 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 FUJITSU Limited
# Based on the blkif.py
#============================================================================
"""Support for VSCSI Devices.
"""
import re
import string
import types
from xen.xend import sxp
from xen.xend.XendError import VmError
from xen.xend.XendLogging import log
from xen.xend.server.DevController import DevController, xenbusState
from xen.xend.xenstore.xstransact import xstransact
class VSCSIController(DevController):
"""VSCSI Devices.
"""
def __init__(self, vm):
"""Create a VSCSI Devices.
"""
DevController.__init__(self, vm)
def sxprs(self):
"""@see DevController.sxprs"""
devslist = []
for devid in self.deviceIDs():
vscsi_devs = self.readBackendList(devid, "vscsi-devs")
vscsipath = "vscsi-devs/"
devs = []
vscsi_config = []
for dev in vscsi_devs:
devpath = vscsipath + dev
backstate = self.readBackend(devid, devpath + '/state')
pdev = self.readBackend(devid, devpath + '/p-dev')
pdevname = self.readBackend(devid, devpath + '/p-devname')
vdev = self.readBackend(devid, devpath + '/v-dev')
localdevid = self.readBackend(devid, devpath + '/devid')
frontstate = self.readFrontend(devid, devpath + '/state')
devs.append(['dev', \
['state', backstate], \
['devid', localdevid], \
['p-dev', pdev], \
['p-devname', pdevname], \
['v-dev', vdev], \
['frontstate', frontstate] ])
vscsi_config.append(['devs', devs])
state = self.readFrontend(devid, 'state')
vscsi_config.append(['state', state])
backid = self.readFrontend(devid, 'backend-id')
vscsi_config.append(['backend-id', backid])
backpath = self.readFrontend(devid, 'backend')
vscsi_config.append(['backend', backpath])
devslist.append([devid, vscsi_config])
return devslist
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
back = {}
vscsipath = "vscsi-devs/"
for vscsi_config in config.get('devs', []):
localdevid = self.allocateDeviceID()
# vscsi-devs/dev-0
devpath = vscsipath + 'dev-%i' % localdevid
back[devpath] = ""
pdev = vscsi_config.get('p-dev', '')
back[devpath + '/p-dev'] = pdev
pdevname = vscsi_config.get('p-devname', '')
back[devpath + '/p-devname'] = pdevname
vdev = vscsi_config.get('v-dev', '')
back[devpath + '/v-dev'] = vdev
state = vscsi_config.get('state', '')
back[devpath + '/state'] = str(xenbusState[state])
devid = vscsi_config.get('devid', '')
back[devpath + '/devid'] = str(devid)
back['uuid'] = config.get('uuid','')
devid = int(devid)
return (devid, back, {})
def readBackendList(self, devid, *args):
frontpath = self.frontendPath(devid)
backpath = xstransact.Read(frontpath + "/backend")
if backpath:
paths = map(lambda x: backpath + "/" + x, args)
return xstransact.List(*paths)
def getDeviceConfiguration(self, devid, transaction = None):
config = DevController.getDeviceConfiguration(self, devid, transaction)
vscsi_devs = []
devs = self.readBackendList(devid, "vscsi-devs")
vscsipath = "vscsi-devs/"
for dev in devs:
devpath = vscsipath + dev
pdev = self.readBackend(devid, devpath + '/p-dev')
pdevname = self.readBackend(devid, devpath + '/p-devname')
vdev = self.readBackend(devid, devpath + '/v-dev')
state = self.readBackend(devid, devpath + '/state')
localdevid = self.readBackend(devid, devpath + '/devid')
dev_dict = {'p-dev': pdev,
'p-devname': pdevname,
'v-dev': pdevname,
'state': state,
'devid': localdevid }
vscsi_devs.append(dev_dict)
config['devs'] = vscsi_devs
config['uuid'] = self.readBackend(devid, 'uuid')
return config
def configuration(self, devid, transaction = None):
"""Returns SXPR for devices on domain.
@note: we treat this dict especially to convert to
SXP because it is not a straight dict of strings."""
configDict = self.getDeviceConfiguration(devid, transaction)
sxpr = [self.deviceClass]
# remove devs
devs = configDict.pop('devs', [])
for dev in devs:
dev_sxpr = ['dev']
for dev_item in dev.items():
dev_sxpr.append(list(dev_item))
sxpr.append(dev_sxpr)
for key, val in configDict.items():
if type(val) == type(list()):
for v in val:
sxpr.append([key, v])
else:
sxpr.append([key, val])
return sxpr
def reconfigureDevice(self, _, config):
"""@see DevController.reconfigureDevice"""
(devid, back, front) = self.getDeviceDetails(config)
devid = int(devid)
vscsi_config = config['devs'][0]
states = config.get('states', [])
uuid = self.readBackend(devid, 'uuid')
if states[0] == 'Initialising':
back['uuid'] = uuid
self.writeBackend(devid, back)
elif states[0] == 'Closing':
found = False
devs = self.readBackendList(devid, "vscsi-devs")
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:
found = True
self.writeBackend(devid, devpath + '/state', \
str(xenbusState['Closing']))
break
if not found:
raise VmError("Device %s not connected" % vdev)
else:
raise XendError('Error configuring device invalid state %s'
% state)
self.writeBackend(devid, 'state', str(xenbusState['Reconfiguring']))
return self.readBackend(devid, 'uuid')
def cleanupDevice(self, devid):
devs = self.readBackendList(devid, "vscsi-devs")
vscsipath = "vscsi-devs/"
new_num_devs = 0
for dev in devs:
new_num_devs = new_num_devs + 1
devpath = vscsipath + dev
devstate = self.readBackend(devid, devpath + '/state')
if str(xenbusState['Closed']) == devstate:
self.removeBackend(devid, devpath)
frontpath = self.frontendPath(devid)
xstransact.Remove(frontpath + '/' + devpath)
new_num_devs = new_num_devs - 1
frontpath = self.frontendPath(devid)
front_devstate = xstransact.Read(frontpath + '/' + devpath)
if front_devstate is not None:
if str(xenbusState['Closed']) == front_devstate:
self.removeBackend(devid, devpath)
xstransact.Remove(frontpath + '/' + devpath)
new_num_devs = new_num_devs - 1
return new_num_devs
+94
View File
@@ -33,6 +33,7 @@ from xen.xend import osdep
import xen.xend.XendClient
from xen.xend.XendBootloader import bootloader
from xen.util import blkif
from xen.util import vscsi_util
import xen.util.xsm.xsm as security
from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
@@ -307,6 +308,11 @@ gopts.var('pci', val='BUS:DEV.FUNC',
For example 'pci=c0:02.1'.
The option may be repeated to add more than one pci device.""")
gopts.var('vscsi', val='PDEV,VDEV[,DOM]',
fn=append_value, default=[],
use="""Add a SCSI device to a domain. The physical device is PDEV,
which is exported to the domain as VDEV(X:X:X:X).""")
gopts.var('ioports', val='FROM[-TO]',
fn=append_value, default=[],
use="""Add a legacy I/O range to a domain, using given params (in hex).
@@ -638,6 +644,73 @@ def configure_pci(config_devs, vals):
config_pci.insert(0, 'pci')
config_devs.append(['device', config_pci])
def vscsi_convert_sxp_to_dict(dev_sxp):
dev_dict = {}
for opt_val in dev_sxp[1:]:
try:
opt, val = opt_val
dev_dict[opt] = val
except TypeError:
pass
return dev_dict
def vscsi_lookup_devid(devlist, req_devid):
if len(devlist) == 0:
return 0
else:
for devid, backend in devlist:
if devid == req_devid:
return 1
return 0
def configure_vscsis(config_devs, vals):
"""Create the config for vscsis (virtual scsi devices).
"""
devidlist = []
config_scsi = []
if len(vals.vscsi) == 0:
return 0
scsi_devices = vscsi_util.vscsi_get_scsidevices()
for (p_dev, v_dev, backend) in vals.vscsi:
tmp = p_dev.split(':')
if len(tmp) == 4:
(p_hctl, block) = vscsi_util._vscsi_hctl_block(p_dev, scsi_devices)
else:
(p_hctl, block) = vscsi_util._vscsi_block_scsiid_to_hctl(p_dev, scsi_devices)
if p_hctl == None:
raise ValueError("Cannot find device \"%s\"" % p_dev)
for config in config_scsi:
dev = vscsi_convert_sxp_to_dict(config)
if dev['v-dev'] == v_dev:
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', 'Initialising'], \
['devid', devid], \
['p-dev', p_hctl], \
['p-devname', block], \
['v-dev', v_dev] ])
if vscsi_lookup_devid(devidlist, devid) == 0:
devidlist.append([devid, backend])
for devid, backend in devidlist:
tmp = []
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])
def configure_ioports(config_devs, vals):
"""Create the config for legacy i/o ranges.
"""
@@ -829,6 +902,7 @@ def make_config(vals):
config_devs = []
configure_disks(config_devs, vals)
configure_pci(config_devs, vals)
configure_vscsis(config_devs, vals)
configure_ioports(config_devs, vals)
configure_irq(config_devs, vals)
configure_vifs(config_devs, vals)
@@ -896,6 +970,25 @@ def preprocess_pci(vals):
err('Error in PCI slot syntax "%s"'%(pci_dev_str))
vals.pci = pci
def preprocess_vscsi(vals):
if not vals.vscsi: return
scsi = []
for scsi_str in vals.vscsi:
d = scsi_str.split(',')
n = len(d)
if n == 2:
tmp = d[1].split(':')
if len(tmp) != 4:
err('vscsi syntax error "%s"' % d[1])
else:
d.append(None)
elif n == 3:
pass
else:
err('vscsi syntax error "%s"' % scsi_str)
scsi.append(d)
vals.vscsi = scsi
def preprocess_ioports(vals):
if not vals.ioports: return
ioports = []
@@ -1075,6 +1168,7 @@ def preprocess_vnc(vals):
def preprocess(vals):
preprocess_disk(vals)
preprocess_pci(vals)
preprocess_vscsi(vals)
preprocess_ioports(vals)
preprocess_ip(vals)
preprocess_nfs(vals)
+101
View File
@@ -37,6 +37,7 @@ import datetime
from select import select
import xml.dom.minidom
from xen.util.blkif import blkdev_name_to_number
from xen.util import vscsi_util
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
@@ -182,6 +183,12 @@ SUBCOMMAND_HELP = {
'Remove a domain\'s pass-through pci device.'),
'pci-list' : ('<Domain>',
'List pass-through pci devices for a domain.'),
'scsi-attach' : ('<Domain> <PhysDevice> <VirtDevice> [BackDomain]',
'Attach a new SCSI device.'),
'scsi-detach' : ('<Domain> <VirtDevice>',
'Detach a specified SCSI device.'),
'scsi-list' : ('<Domain> [--long]',
'List all SCSI devices currently attached.'),
# security
@@ -348,6 +355,9 @@ device_commands = [
"pci-attach",
"pci-detach",
"pci-list",
"scsi-attach",
"scsi-detach",
"scsi-list",
]
vnet_commands = [
@@ -2106,6 +2116,40 @@ def xm_pci_list(args):
hdr = 1
print ( fmt_str % x )
def vscsi_convert_sxp_to_dict(dev_sxp):
dev_dict = {}
for opt_val in dev_sxp[1:]:
try:
opt, val = opt_val
dev_dict[opt] = val
except TypeError:
pass
return dev_dict
def xm_scsi_list(args):
xenapi_unsupported()
(use_long, params) = arg_check_for_resource_list(args, "scsi-list")
dom = params[0]
devs = server.xend.domain.getDeviceSxprs(dom, 'vscsi')
if use_long:
map(PrettyPrint.prettyprint, devs)
else:
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')
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 "%(p-dev)-10s %(p-devname)-5s %(v-dev)-10s %(frontstate)-4s" % mi
def parse_block_configuration(args):
dom = args[0]
@@ -2285,6 +2329,38 @@ def xm_pci_attach(args):
(dom, pci) = parse_pci_configuration(args, 'Initialising')
server.xend.domain.device_configure(dom, pci)
def xm_scsi_attach(args):
xenapi_unsupported()
arg_check(args, 'scsi-attach', 3, 4)
p_devname = args[1]
v_dev = args[2]
v_hctl = v_dev.split(':')
if len(v_hctl) != 4:
raise OptionError("Invalid argument: %s" % v_dev)
(p_hctl, block) = vscsi_util.vscsi_search_hctl_and_block(p_devname)
if p_hctl == None:
raise OptionError("Cannot find device \"%s\"" % p_devname)
dom = args[0]
vscsi = ['vscsi']
vscsi.append(['dev', \
['state', 'Initialising'], \
['devid', v_hctl[0]], \
['p-dev', p_hctl], \
['p-devname', block], \
['v-dev', v_dev] ])
if len(args) == 4:
vscsi.append(['backend', args[3]])
vscsi.append(['state', 'Initialising'])
vscsi.append(['devid', v_hctl[0]])
server.xend.domain.device_configure(dom, vscsi)
def detach(args, deviceClass):
rm_cfg = True
dom = args[0]
@@ -2353,6 +2429,27 @@ def xm_pci_detach(args):
(dom, pci) = parse_pci_configuration(args, 'Closing')
server.xend.domain.device_configure(dom, pci)
def xm_scsi_detach(args):
xenapi_unsupported()
arg_check(args, 'scsi-detach', 2)
v_dev = args[1]
v_hctl = v_dev.split(':')
if len(v_hctl) != 4:
raise OptionError("Invalid argument: %s" % v_dev)
dom = args[0]
vscsi = ['vscsi']
vscsi.append(['dev', \
['state', 'Closing'], \
['devid', v_hctl[0]], \
['p-dev', ''], \
['p-devname', ''], \
['v-dev', v_dev] ])
vscsi.append(['state', 'Closing'])
vscsi.append(['devid', v_hctl[0]])
server.xend.domain.device_configure(dom, vscsi)
def xm_vnet_list(args):
xenapi_unsupported()
@@ -2548,6 +2645,10 @@ commands = {
"pci-attach": xm_pci_attach,
"pci-detach": xm_pci_detach,
"pci-list": xm_pci_list,
# vscsi
"scsi-attach": xm_scsi_attach,
"scsi-detach": xm_scsi_detach,
"scsi-list": xm_scsi_list,
}
## The commands supported by a separate argument parser in xend.xm.
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.