ia64/xen-unstable

changeset 19224:a35dffe6f1b6

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>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Feb 17 11:19:55 2009 +0000 (2009-02-17)
parents 634b425cafa3
children 7fe15a0ee3d8
files tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/vscsiif.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py
line diff
     1.1 --- a/tools/python/xen/xend/XendConfig.py	Tue Feb 17 11:13:34 2009 +0000
     1.2 +++ b/tools/python/xen/xend/XendConfig.py	Tue Feb 17 11:19:55 2009 +0000
     1.3 @@ -1274,6 +1274,7 @@ class XendConfig(dict):
     1.4                                                    uuid.createString())
     1.5                  vscsi_dict = self.vscsi_convert_sxp_to_dict(config)
     1.6                  vscsi_devs = vscsi_dict['devs']
     1.7 +                vscsi_mode = vscsi_dict['feature-host']
     1.8  
     1.9                  # create XenAPI DSCSI objects.
    1.10                  for vscsi_dev in vscsi_devs:
    1.11 @@ -1288,9 +1289,14 @@ class XendConfig(dict):
    1.12                      }
    1.13                      XendDSCSI(dscsi_uuid, dscsi_record)
    1.14  
    1.15 -                target['devices'][vscsi_devs_uuid] = \
    1.16 -                    (dev_type, {'devs': vscsi_devs, 'uuid': vscsi_devs_uuid} )
    1.17 -                log.debug("XendConfig: reading device: %s" % vscsi_devs)
    1.18 +                vscsi_info = {
    1.19 +                    'devs': vscsi_devs,
    1.20 +                    'feature-host': vscsi_mode,
    1.21 +                    'uuid': vscsi_devs_uuid
    1.22 +                }
    1.23 +                target['devices'][vscsi_devs_uuid] = (dev_type, vscsi_info)
    1.24 +                log.debug("XendConfig: reading device: %s,%s" % \
    1.25 +                          (vscsi_devs, vscsi_mode))
    1.26                  return vscsi_devs_uuid
    1.27  
    1.28              for opt_val in config[1:]:
    1.29 @@ -1614,6 +1620,7 @@ class XendConfig(dict):
    1.30          #
    1.31          # [device,
    1.32          #   [vscsi,
    1.33 +        #     [feature-host, 0],
    1.34          #     [dev,
    1.35          #       [devid, 0], [p-devname, sdb], [p-dev, 1:0:0:1],
    1.36          #       [v-dev, 0:0:0:0], [state, 1]
    1.37 @@ -1624,6 +1631,7 @@ class XendConfig(dict):
    1.38          #     ]
    1.39          #   ],
    1.40          #   [vscsi,
    1.41 +        #     [feature-host, 1],
    1.42          #     [dev,
    1.43          #       [devid, 1], [p-devname, sdg], [p-dev, 2:0:0:0],
    1.44          #       [v-dev, 1:0:0:0], [state, 1]
    1.45 @@ -1644,6 +1652,7 @@ class XendConfig(dict):
    1.46          #
    1.47          # [device,
    1.48          #   [vscsi,
    1.49 +        #     [feature-host, 0],
    1.50          #     [dev,
    1.51          #       [devid, 0], [p-devname, sdd], [p-dev, 1:0:0:3],
    1.52          #       [v-dev, 0:0:0:2], [state, 1]
    1.53 @@ -1658,7 +1667,8 @@ class XendConfig(dict):
    1.54          # The Dict looks like this:
    1.55          #
    1.56          # { devs: [ {devid: 0, p-devname: sdd, p-dev: 1:0:0:3,
    1.57 -        #            v-dev: 0:0:0:2, state: 1} ] }
    1.58 +        #            v-dev: 0:0:0:2, state: 1} ],
    1.59 +        #   feature-host: 1 }
    1.60  
    1.61          dev_config = {}
    1.62  
    1.63 @@ -1677,6 +1687,9 @@ class XendConfig(dict):
    1.64              vscsi_devs.append(vscsi_dev_info)
    1.65          dev_config['devs'] = vscsi_devs 
    1.66  
    1.67 +        vscsi_mode = sxp.children(dev_sxp, 'feature-host')[0]
    1.68 +        dev_config['feature-host'] = vscsi_mode[1]
    1.69 +
    1.70          return dev_config
    1.71  
    1.72      def console_add(self, protocol, location, other_config = {}):
    1.73 @@ -1789,6 +1802,7 @@ class XendConfig(dict):
    1.74              if dev_type == 'vscsi': # Special case for vscsi
    1.75                  vscsi_dict = self.vscsi_convert_sxp_to_dict(config)
    1.76                  vscsi_devs = vscsi_dict['devs']
    1.77 +                vscsi_mode = vscsi_dict['feature-host']
    1.78  
    1.79                  # destroy existing XenAPI DSCSI objects
    1.80                  for dscsi_uuid in XendDSCSI.get_by_VM(self['uuid']):
    1.81 @@ -1807,8 +1821,12 @@ class XendConfig(dict):
    1.82                      }
    1.83                      XendDSCSI(dscsi_uuid, dscsi_record)
    1.84  
    1.85 -                self['devices'][dev_uuid] = \
    1.86 -                    (dev_type, {'devs': vscsi_devs, 'uuid': dev_uuid} )
    1.87 +                vscsi_info = { 
    1.88 +                    'devs': vscsi_devs,
    1.89 +                    'feature-host': vscsi_mode,
    1.90 +                    'uuid': dev_uuid
    1.91 +                }
    1.92 +                self['devices'][dev_uuid] = (dev_type, vscsi_info)
    1.93                  return True
    1.94                  
    1.95              for opt_val in config[1:]:
    1.96 @@ -1885,7 +1903,6 @@ class XendConfig(dict):
    1.97      def all_devices_sxpr(self, target = None):
    1.98          """Returns the SXPR for all devices in the current configuration."""
    1.99          sxprs = []
   1.100 -        pci_devs = []
   1.101  
   1.102          if target == None:
   1.103              target = self
   1.104 @@ -1900,7 +1917,8 @@ class XendConfig(dict):
   1.105                  if dev_type == 'pci':
   1.106                      sxpr = ['pci', ['uuid', dev_info['uuid']]]
   1.107                  elif dev_type == 'vscsi':
   1.108 -                    sxpr = ['vscsi', ['uuid', dev_info['uuid']]]
   1.109 +                    sxpr = ['vscsi', ['uuid', dev_info['uuid']],
   1.110 +                                     ['feature-host', dev_info['feature-host']]]
   1.111                  for pci_dev_info in dev_info['devs']:
   1.112                      pci_dev_sxpr = ['dev']
   1.113                      for opt, val in pci_dev_info.items():
     2.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Feb 17 11:13:34 2009 +0000
     2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Feb 17 11:19:55 2009 +0000
     2.3 @@ -898,15 +898,21 @@ class XendDomainInfo:
     2.4          else:
     2.5              cur_dev_sxp = self._getDeviceInfo_vscsi(req_devid, None)
     2.6              new_dev_sxp = ['vscsi']
     2.7 +            cur_mode = sxp.children(cur_dev_sxp, 'feature-host')[0]
     2.8 +            new_dev_sxp.append(cur_mode)
     2.9 +
    2.10              for cur_dev in sxp.children(cur_dev_sxp, 'dev'):
    2.11                  if state == xenbusState['Closing']:
    2.12 +                    if int(cur_mode[1]) == 1:
    2.13 +                        continue
    2.14                      cur_dev_vdev = sxp.child_value(cur_dev, 'v-dev')
    2.15                      if cur_dev_vdev == dev['v-dev']:
    2.16                          continue
    2.17                  new_dev_sxp.append(cur_dev)
    2.18  
    2.19              if state == xenbusState['Initialising']:
    2.20 -                new_dev_sxp.append(sxp.child0(dev_sxp, 'dev'))
    2.21 +                for new_dev in sxp.children(dev_sxp, 'dev'):
    2.22 +                    new_dev_sxp.append(new_dev)
    2.23  
    2.24              dev_uuid = sxp.child_value(cur_dev_sxp, 'uuid')
    2.25              self.info.device_update(dev_uuid, new_dev_sxp)
    2.26 @@ -1112,7 +1118,8 @@ class XendDomainInfo:
    2.27                          vscsi_dev.append(['frontstate', None])
    2.28                          vscsi_devs[1].append(vscsi_dev)
    2.29                          dev_num = int(sxp.child_value(vscsi_dev, 'devid'))
    2.30 -                    sxprs.append([dev_num, [vscsi_devs]])
    2.31 +                    vscsi_mode = sxp.children(dev_info, 'feature-host')[0]
    2.32 +                    sxprs.append([dev_num, [vscsi_devs, vscsi_mode]])
    2.33                  elif deviceClass == 'vbd':
    2.34                      dev = sxp.child_value(dev_info, 'dev')
    2.35                      if 'ioemu:' in dev:
     3.1 --- a/tools/python/xen/xend/server/vscsiif.py	Tue Feb 17 11:13:34 2009 +0000
     3.2 +++ b/tools/python/xen/xend/server/vscsiif.py	Tue Feb 17 11:19:55 2009 +0000
     3.3 @@ -68,6 +68,8 @@ class VSCSIController(DevController):
     3.4              vscsi_config.append(['devs', devs])
     3.5              state = self.readFrontend(devid, 'state')
     3.6              vscsi_config.append(['state', state])
     3.7 +            hostmode = self.readBackend(devid, 'feature-host')
     3.8 +            vscsi_config.append(['feature-host', hostmode])
     3.9              backid = self.readFrontend(devid, 'backend-id')
    3.10              vscsi_config.append(['backend-id', backid])
    3.11              backpath = self.readFrontend(devid, 'backend')
    3.12 @@ -98,6 +100,8 @@ class VSCSIController(DevController):
    3.13              devid = vscsi_config.get('devid', '')
    3.14              back[devpath + '/devid'] = str(devid)
    3.15  
    3.16 +        host_mode = config.get('feature-host','')
    3.17 +        back['feature-host'] = str(host_mode)
    3.18          back['uuid'] = config.get('uuid','')
    3.19          devid = int(devid)
    3.20          return (devid, back, {})
    3.21 @@ -133,6 +137,7 @@ class VSCSIController(DevController):
    3.22              vscsi_devs.append(dev_dict)
    3.23  
    3.24          config['devs'] = vscsi_devs
    3.25 +        config['feature-host'] = self.readBackend(devid, 'feature-host')
    3.26          config['uuid'] = self.readBackend(devid, 'uuid')
    3.27          return config
    3.28  
    3.29 @@ -171,6 +176,7 @@ class VSCSIController(DevController):
    3.30          vscsi_config = config['devs'][0]
    3.31          state = vscsi_config.get('state', xenbusState['Unknown'])
    3.32          driver_state = self.readBackend(devid, 'state')
    3.33 +
    3.34          if str(xenbusState['Connected']) != driver_state:
    3.35              raise VmError("Driver status is not connected")
    3.36  
    3.37 @@ -182,13 +188,20 @@ class VSCSIController(DevController):
    3.38          elif state == xenbusState['Closing']:
    3.39              found = False
    3.40              devs = self.readBackendList(devid, "vscsi-devs")
    3.41 +            hostmode = int(self.readBackend(devid, 'feature-host'))
    3.42              vscsipath = "vscsi-devs/"
    3.43              vdev = vscsi_config.get('v-dev', '')
    3.44  
    3.45              for dev in devs:
    3.46                  devpath = vscsipath + dev
    3.47                  old_vdev = self.readBackend(devid, devpath + '/v-dev')
    3.48 -                if vdev == old_vdev:
    3.49 +
    3.50 +                if hostmode == 1:
    3.51 +                    #At hostmode, all v-dev that belongs to devid is deleted.
    3.52 +                    found = True
    3.53 +                    self.writeBackend(devid, devpath + '/state', \
    3.54 +                                    str(xenbusState['Closing']))
    3.55 +                elif vdev == old_vdev:
    3.56                      found = True
    3.57                      self.writeBackend(devid, devpath + '/state', \
    3.58                                      str(xenbusState['Closing']))
     4.1 --- a/tools/python/xen/xm/create.py	Tue Feb 17 11:13:34 2009 +0000
     4.2 +++ b/tools/python/xen/xm/create.py	Tue Feb 17 11:19:55 2009 +0000
     4.3 @@ -717,7 +717,7 @@ def vscsi_lookup_devid(devlist, req_devi
     4.4      if len(devlist) == 0:
     4.5          return 0
     4.6      else:
     4.7 -        for devid, backend in devlist:
     4.8 +        for (devid, _, _) in devlist:
     4.9              if devid == req_devid:
    4.10                  return 1
    4.11          return 0
    4.12 @@ -725,6 +725,10 @@ def vscsi_lookup_devid(devlist, req_devi
    4.13  def configure_vscsis(config_devs, vals):
    4.14      """Create the config for vscsis (virtual scsi devices).
    4.15      """
    4.16 +
    4.17 +    def get_devid(hctl):
    4.18 +        return int(hctl.split(':')[0])
    4.19 +
    4.20      devidlist = []
    4.21      config_scsi = []
    4.22      if len(vals.vscsi) == 0:
    4.23 @@ -738,31 +742,40 @@ def configure_vscsis(config_devs, vals):
    4.24          if p_hctl == None:
    4.25              raise ValueError('Cannot find device "%s"' % p_dev)
    4.26  
    4.27 +        host_mode = 0
    4.28 +        if v_dev == 'host':
    4.29 +            host_mode = 1
    4.30 +            scsi_info = []
    4.31 +            devid = get_devid(p_hctl)
    4.32 +            for (pHCTL, devname, _, _) in scsi_devices:
    4.33 +                if get_devid(pHCTL) == devid:
    4.34 +                    scsi_info.append([devid, pHCTL, devname, pHCTL])
    4.35 +        else:
    4.36 +            scsi_info = [[get_devid(v_dev), p_hctl, devname, v_dev]]
    4.37 +
    4.38          for config in config_scsi:
    4.39              dev = vscsi_convert_sxp_to_dict(config)
    4.40 -            if dev['v-dev'] == v_dev:
    4.41 +            if dev['v-dev'] in [scsi_info[x][3] for x in range(len(scsi_info))]:
    4.42                  raise ValueError('The virtual device "%s" is already defined' % v_dev)
    4.43  
    4.44 -        v_hctl = v_dev.split(':')
    4.45 -        devid = int(v_hctl[0])
    4.46 -        config_scsi.append(['dev', \
    4.47 -                        ['state', xenbusState['Initialising']], \
    4.48 -                        ['devid', devid], \
    4.49 -                        ['p-dev', p_hctl], \
    4.50 -                        ['p-devname', devname], \
    4.51 -                        ['v-dev', v_dev] ])
    4.52 +        for (devid, pHCTL, devname, vHCTL) in scsi_info:
    4.53 +            config_scsi.append(['dev', \
    4.54 +                                ['state', xenbusState['Initialising']], \
    4.55 +                                ['devid', devid], \
    4.56 +                                ['p-dev', pHCTL], \
    4.57 +                                ['p-devname', devname], \
    4.58 +                                ['v-dev', vHCTL] ])
    4.59  
    4.60          if vscsi_lookup_devid(devidlist, devid) == 0:
    4.61 -            devidlist.append([devid, backend])
    4.62 +            devidlist.append([devid, backend, host_mode])
    4.63  
    4.64 -    for devid, backend in devidlist:
    4.65 -        tmp = []
    4.66 +    for (devid, backend, host_mode) in devidlist:
    4.67 +        tmp = ['vscsi', ['feature-host', host_mode]]
    4.68          for config in config_scsi:
    4.69              dev = vscsi_convert_sxp_to_dict(config)
    4.70              if dev['devid'] == devid:
    4.71                  tmp.append(config)
    4.72  
    4.73 -        tmp.insert(0, 'vscsi')
    4.74          if backend:
    4.75              tmp.append(['backend', backend])
    4.76          config_devs.append(['device', tmp])
    4.77 @@ -1044,7 +1057,7 @@ def preprocess_vscsi(vals):
    4.78          n = len(d)
    4.79          if n == 2:
    4.80              tmp = d[1].split(':')
    4.81 -            if len(tmp) != 4:
    4.82 +            if d[1] != 'host' and len(tmp) != 4:
    4.83                  err('vscsi syntax error "%s"' % d[1])
    4.84              else:
    4.85                  d.append(None)
     5.1 --- a/tools/python/xen/xm/main.py	Tue Feb 17 11:13:34 2009 +0000
     5.2 +++ b/tools/python/xen/xm/main.py	Tue Feb 17 11:19:55 2009 +0000
     5.3 @@ -2032,6 +2032,8 @@ def parse_dev_info(info):
     5.4          'mac'        : get_info('mac',          str,   '??'),
     5.5          #block-device specific
     5.6          'ring-ref'   : get_info('ring-ref',     int,   -1),
     5.7 +        #vscsi specific
     5.8 +        'feature-host'   : get_info('feature-host',     int,   -1),
     5.9          }
    5.10  
    5.11  def arg_check_for_resource_list(args, name):
    5.12 @@ -2275,14 +2277,14 @@ def xm_scsi_list(args):
    5.13          hdr = 0
    5.14          for x in devs:
    5.15              if hdr == 0:
    5.16 -                print "%-3s %-3s %-5s  %-10s %-5s %-10s %-4s" \
    5.17 -                        % ('Idx', 'BE', 'state', 'phy-hctl', 'phy', 'vir-hctl', 'devstate')
    5.18 +                print "%-3s %-3s %-5s %-4s  %-10s %-5s %-10s %-4s" \
    5.19 +                        % ('Idx', 'BE', 'state', 'host', 'phy-hctl', 'phy', 'vir-hctl', 'devstate')
    5.20                  hdr = 1
    5.21              ni = parse_dev_info(x[1])
    5.22              ni['idx'] = int(x[0])
    5.23              for dev in x[1][0][1]:
    5.24                  mi = vscsi_convert_sxp_to_dict(dev)
    5.25 -                print "%(idx)-3d %(backend-id)-3d %(state)-5d " % ni,
    5.26 +                print "%(idx)-3d %(backend-id)-3d %(state)-5d %(feature-host)-4d " % ni,
    5.27                  print "%(p-dev)-10s %(p-devname)-5s %(v-dev)-10s %(frontstate)-4s" % mi
    5.28  
    5.29  def parse_block_configuration(args):
    5.30 @@ -2512,27 +2514,46 @@ def xm_pci_attach(args):
    5.31          server.xend.domain.device_configure(dom, pci)
    5.32  
    5.33  def parse_scsi_configuration(p_scsi, v_hctl, state):
    5.34 -    v = v_hctl.split(':')
    5.35 -    if len(v) != 4:
    5.36 -        raise OptionError("Invalid argument: %s" % v_hctl)
    5.37 -
    5.38 -    p_hctl = None
    5.39 -    devname = None
    5.40 +    def get_devid(hctl):
    5.41 +        return int(hctl.split(':')[0])
    5.42 +
    5.43 +    host_mode = 0
    5.44 +    scsi_devices = None
    5.45 +
    5.46      if p_scsi is not None:
    5.47 +        # xm scsi-attach
    5.48 +        if v_hctl == "host":
    5.49 +            host_mode = 1
    5.50 +            scsi_devices = vscsi_util.vscsi_get_scsidevices()
    5.51 +        elif len(v_hctl.split(':')) != 4:
    5.52 +            raise OptionError("Invalid argument: %s" % v_hctl)
    5.53          (p_hctl, devname) = \
    5.54 -            vscsi_util.vscsi_get_hctl_and_devname_by(p_scsi)
    5.55 +            vscsi_util.vscsi_get_hctl_and_devname_by(p_scsi, scsi_devices)
    5.56          if p_hctl is None:
    5.57              raise OptionError("Cannot find device '%s'" % p_scsi)
    5.58 -
    5.59 -    scsi = ['vscsi']
    5.60 -    scsi.append(['dev', \
    5.61 -                 ['state', state], \
    5.62 -                 ['devid', int(v[0])], \
    5.63 -                 ['p-dev', p_hctl], \
    5.64 -                 ['p-devname', devname], \
    5.65 -                 ['v-dev', v_hctl] \
    5.66 -               ])
    5.67 -
    5.68 +        if host_mode:
    5.69 +            scsi_info = []
    5.70 +            devid = get_devid(p_hctl)
    5.71 +            for pHCTL, devname, _, _ in scsi_devices:
    5.72 +                if get_devid(pHCTL) == devid:
    5.73 +                    scsi_info.append([devid, pHCTL, devname, pHCTL])
    5.74 +        else:
    5.75 +            scsi_info = [[get_devid(v_hctl), p_hctl, devname, v_hctl]] 
    5.76 +    else:
    5.77 +        # xm scsi-detach
    5.78 +        if len(v_hctl.split(':')) != 4:
    5.79 +            raise OptionError("Invalid argument: %s" % v_hctl)
    5.80 +        scsi_info = [[get_devid(v_hctl), None, None, v_hctl]]
    5.81 +
    5.82 +    scsi = ['vscsi', ['feature-host', host_mode]]
    5.83 +    for devid, pHCTL, devname, vHCTL in scsi_info:
    5.84 +        scsi.append(['dev', \
    5.85 +                     ['state', state], \
    5.86 +                     ['devid', devid], \
    5.87 +                     ['p-dev', pHCTL], \
    5.88 +                     ['p-devname', devname], \
    5.89 +                     ['v-dev', vHCTL] \
    5.90 +                   ])
    5.91      return scsi
    5.92  
    5.93  def xm_scsi_attach(args):