direct-io.hg

changeset 13679:1e88f0b736b5

Added a VBD.bootable flag.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Sun Jan 28 17:11:40 2007 +0000 (2007-01-28)
parents 4651595d9502
children 207ee547b193
files docs/xen-api/xenapi-datamodel.tex tools/libxen/include/xen_vbd.h tools/libxen/src/xen_vbd.c tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py
line diff
     1.1 --- a/docs/xen-api/xenapi-datamodel.tex	Sun Jan 28 15:55:55 2007 +0000
     1.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Sun Jan 28 17:11:40 2007 +0000
     1.3 @@ -1089,7 +1089,10 @@ control domain to some other bootloader.
     1.4  PV/ramdisk, PV/args and PV/bootloader\_args will be passed to the
     1.5  bootloader unmodified, and interpretation of those fields is then specific
     1.6  to the bootloader itself, including the possibility that the bootloader
     1.7 -will ignore some or all of those given values.
     1.8 +will ignore some or all of those given values. Finally the paths of all
     1.9 +bootable disks are added to the bootloader commandline (a disk is bootable
    1.10 +if its VBD has the bootable flag set). There may be zero, one or many
    1.11 +bootable disks; the bootloader decides which disk (if any) to boot from.
    1.12  
    1.13  If the bootloader is pygrub, then the menu.lst is parsed if present in the
    1.14  guest's filesystem, otherwise the specified kernel and ramdisk are used, or
    1.15 @@ -8665,7 +8668,8 @@ Quals & Field & Type & Description \\
    1.16  $\mathit{RW}$ &  {\tt VM} & VM ref & the virtual machine \\
    1.17  $\mathit{RW}$ &  {\tt VDI} & VDI ref & the virtual disk \\
    1.18  $\mathit{RW}$ &  {\tt device} & string & device seen by the guest e.g. hda1 \\
    1.19 -$\mathit{RW}$ &  {\tt mode} & vbd\_mode & the mode the disk should be mounted with \\
    1.20 +$\mathit{RW}$ &  {\tt bootable} & bool & true if this VBD is bootable \\
    1.21 +$\mathit{RW}$ &  {\tt mode} & vbd\_mode & the mode the VBD should be mounted with \\
    1.22  $\mathit{RW}$ &  {\tt type} & vbd\_type & how the VBD will appear to the guest (e.g. disk or CD) \\
    1.23  $\mathit{RW}$ &  {\tt driver} & driver\_type & the style of driver \\
    1.24  $\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
    1.25 @@ -8937,6 +8941,72 @@ void
    1.26  \vspace{0.3cm}
    1.27  \vspace{0.3cm}
    1.28  \vspace{0.3cm}
    1.29 +\subsubsection{RPC name:~get\_bootable}
    1.30 +
    1.31 +{\bf Overview:} 
    1.32 +Get the bootable field of the given VBD.
    1.33 +
    1.34 + \noindent {\bf Signature:} 
    1.35 +\begin{verbatim} bool get_bootable (session_id s, VBD ref self)\end{verbatim}
    1.36 +
    1.37 +
    1.38 +\noindent{\bf Arguments:}
    1.39 +
    1.40 + 
    1.41 +\vspace{0.3cm}
    1.42 +\begin{tabular}{|c|c|p{7cm}|}
    1.43 + \hline
    1.44 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    1.45 +{\tt VBD ref } & self & reference to the object \\ \hline 
    1.46 +
    1.47 +\end{tabular}
    1.48 +
    1.49 +\vspace{0.3cm}
    1.50 +
    1.51 + \noindent {\bf Return Type:} 
    1.52 +{\tt 
    1.53 +bool
    1.54 +}
    1.55 +
    1.56 +
    1.57 +value of the field
    1.58 +\vspace{0.3cm}
    1.59 +\vspace{0.3cm}
    1.60 +\vspace{0.3cm}
    1.61 +\subsubsection{RPC name:~set\_bootable}
    1.62 +
    1.63 +{\bf Overview:} 
    1.64 +Set the bootable field of the given VBD.
    1.65 +
    1.66 + \noindent {\bf Signature:} 
    1.67 +\begin{verbatim} void set_bootable (session_id s, VBD ref self, bool value)\end{verbatim}
    1.68 +
    1.69 +
    1.70 +\noindent{\bf Arguments:}
    1.71 +
    1.72 + 
    1.73 +\vspace{0.3cm}
    1.74 +\begin{tabular}{|c|c|p{7cm}|}
    1.75 + \hline
    1.76 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    1.77 +{\tt VBD ref } & self & reference to the object \\ \hline 
    1.78 +
    1.79 +{\tt bool } & value & New value to set \\ \hline 
    1.80 +
    1.81 +\end{tabular}
    1.82 +
    1.83 +\vspace{0.3cm}
    1.84 +
    1.85 + \noindent {\bf Return Type:} 
    1.86 +{\tt 
    1.87 +void
    1.88 +}
    1.89 +
    1.90 +
    1.91 +
    1.92 +\vspace{0.3cm}
    1.93 +\vspace{0.3cm}
    1.94 +\vspace{0.3cm}
    1.95  \subsubsection{RPC name:~get\_mode}
    1.96  
    1.97  {\bf Overview:} 
     2.1 --- a/tools/libxen/include/xen_vbd.h	Sun Jan 28 15:55:55 2007 +0000
     2.2 +++ b/tools/libxen/include/xen_vbd.h	Sun Jan 28 17:11:40 2007 +0000
     2.3 @@ -70,6 +70,7 @@ typedef struct xen_vbd_record
     2.4      struct xen_vdi_record_opt *vdi;
     2.5      char *device;
     2.6      char *image;
     2.7 +    bool bootable;
     2.8      enum xen_vbd_mode mode;
     2.9      enum xen_driver_type driver;
    2.10      double io_read_kbs;
    2.11 @@ -212,6 +213,13 @@ xen_vbd_get_device(xen_session *session,
    2.12  
    2.13  
    2.14  /**
    2.15 + * Get the bootable field of the given VBD.
    2.16 + */
    2.17 +extern bool
    2.18 +xen_vbd_get_bootable(xen_session *session, bool *result, xen_vbd vbd);
    2.19 +
    2.20 +
    2.21 +/**
    2.22   * Get the mode field of the given VBD.
    2.23   */
    2.24  extern bool
    2.25 @@ -261,6 +269,13 @@ xen_vbd_set_device(xen_session *session,
    2.26  
    2.27  
    2.28  /**
    2.29 + * Set the bootable field of the given VBD.
    2.30 + */
    2.31 +extern bool
    2.32 +xen_vbd_set_bootable(xen_session *session, xen_vbd vbd, bool bootable);
    2.33 +
    2.34 +
    2.35 +/**
    2.36   * Set the mode field of the given VBD.
    2.37   */
    2.38  extern bool
     3.1 --- a/tools/libxen/src/xen_vbd.c	Sun Jan 28 15:55:55 2007 +0000
     3.2 +++ b/tools/libxen/src/xen_vbd.c	Sun Jan 28 17:11:40 2007 +0000
     3.3 @@ -55,6 +55,9 @@ static const struct_member xen_vbd_recor
     3.4          { .key = "image",
     3.5            .type = &abstract_type_string,
     3.6            .offset = offsetof(xen_vbd_record, image) },
     3.7 +        { .key = "bootable",
     3.8 +          .type = &abstract_type_bool,
     3.9 +          .offset = offsetof(xen_vbd_record, bootable) },
    3.10          { .key = "mode",
    3.11            .type = &xen_vbd_mode_abstract_type_,
    3.12            .offset = offsetof(xen_vbd_record, mode) },
    3.13 @@ -218,6 +221,22 @@ xen_vbd_get_device(xen_session *session,
    3.14  
    3.15  
    3.16  bool
    3.17 +xen_vbd_get_bootable(xen_session *session, bool *result, xen_vbd vbd)
    3.18 +{
    3.19 +    abstract_value param_values[] =
    3.20 +        {
    3.21 +            { .type = &abstract_type_string,
    3.22 +              .u.string_val = vbd }
    3.23 +        };
    3.24 +
    3.25 +    abstract_type result_type = abstract_type_bool;
    3.26 +
    3.27 +    XEN_CALL_("VBD.get_bootable");
    3.28 +    return session->ok;
    3.29 +}
    3.30 +
    3.31 +
    3.32 +bool
    3.33  xen_vbd_get_mode(xen_session *session, enum xen_vbd_mode *result, xen_vbd vbd)
    3.34  {
    3.35      abstract_value param_values[] =
    3.36 @@ -332,6 +351,22 @@ xen_vbd_set_device(xen_session *session,
    3.37  
    3.38  
    3.39  bool
    3.40 +xen_vbd_set_bootable(xen_session *session, xen_vbd vbd, bool bootable)
    3.41 +{
    3.42 +    abstract_value param_values[] =
    3.43 +        {
    3.44 +            { .type = &abstract_type_string,
    3.45 +              .u.string_val = vbd },
    3.46 +            { .type = &abstract_type_bool,
    3.47 +              .u.bool_val = bootable }
    3.48 +        };
    3.49 +
    3.50 +    xen_call_(session, "VBD.set_bootable", param_values, 2, NULL, NULL);
    3.51 +    return session->ok;
    3.52 +}
    3.53 +
    3.54 +
    3.55 +bool
    3.56  xen_vbd_set_mode(xen_session *session, xen_vbd vbd, enum xen_vbd_mode mode)
    3.57  {
    3.58      abstract_value param_values[] =
     4.1 --- a/tools/python/xen/xend/XendAPI.py	Sun Jan 28 15:55:55 2007 +0000
     4.2 +++ b/tools/python/xen/xend/XendAPI.py	Sun Jan 28 17:11:40 2007 +0000
     4.3 @@ -1348,6 +1348,7 @@ class XendAPI(object):
     4.4      VBD_attr_rw = ['VM',
     4.5                     'VDI',
     4.6                     'device',
     4.7 +                   'bootable',
     4.8                     'mode',
     4.9                     'type',                   
    4.10                     'driver']
    4.11 @@ -1429,6 +1430,10 @@ class XendAPI(object):
    4.12          xendom = XendDomain.instance()
    4.13          return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
    4.14                                                                 'device'))
    4.15 +    def VBD_get_bootable(self, session, vbd_ref):
    4.16 +        xendom = XendDomain.instance()
    4.17 +        return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
    4.18 +                                                               'bootable'))
    4.19      def VBD_get_mode(self, session, vbd_ref):
    4.20          xendom = XendDomain.instance()
    4.21          return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
    4.22 @@ -1454,6 +1459,14 @@ class XendAPI(object):
    4.23          return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
    4.24                                                                'io_read_kbs'))
    4.25      
    4.26 +    def VBD_set_bootable(self, session, vbd_ref, bootable):
    4.27 +        bootable = bool(bootable)
    4.28 +        xd = XendDomain.instance()
    4.29 +        vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
    4.30 +        vm.set_dev_property('vbd', vbd_ref, 'bootable', bootable)
    4.31 +        xd.managed_config_save(vm)
    4.32 +        return xen_api_success_void()
    4.33 +
    4.34      def VBD_get_all(self, session):
    4.35          xendom = XendDomain.instance()
    4.36          vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
     5.1 --- a/tools/python/xen/xend/XendConfig.py	Sun Jan 28 15:55:55 2007 +0000
     5.2 +++ b/tools/python/xen/xend/XendConfig.py	Sun Jan 28 17:11:40 2007 +0000
     5.3 @@ -28,7 +28,7 @@ from xen.xend.PrettyPrint import prettyp
     5.4  from xen.xend.XendConstants import DOM_STATE_HALTED
     5.5  
     5.6  log = logging.getLogger("xend.XendConfig")
     5.7 -log.setLevel(logging.WARN)
     5.8 +log.setLevel(logging.DEBUG)
     5.9  
    5.10  
    5.11  """
    5.12 @@ -878,6 +878,13 @@ class XendConfig(dict):
    5.13                          controller = domain.getDeviceController(cls)
    5.14                          configs = controller.configurations()
    5.15                          for config in configs:
    5.16 +                            if sxp.name(config) in ('vbd', 'tap'):
    5.17 +                                # The bootable flag is never written to the
    5.18 +                                # store as part of the device config.
    5.19 +                                uuid = sxp.child_value(sxpr, 'uuid')
    5.20 +                                sxpr.append(
    5.21 +                                    'bootable', 
    5.22 +                                    self['devices'][dev_uuid]['bootable'])
    5.23                              sxpr.append(['device', config])
    5.24  
    5.25                          found = True
    5.26 @@ -948,6 +955,7 @@ class XendConfig(dict):
    5.27                      pass
    5.28  
    5.29              if dev_type == 'vbd':
    5.30 +                dev_info['bootable'] = False
    5.31                  if dev_info.get('dev', '').startswith('ioemu:'):
    5.32                      dev_info['driver'] = 'ioemu'
    5.33                  else:
    5.34 @@ -964,13 +972,21 @@ class XendConfig(dict):
    5.35                  if param not in target:
    5.36                      target[param] = []
    5.37                  if dev_uuid not in target[param]:
    5.38 +                    if dev_type == 'vbd' and not target[param]:
    5.39 +                        # Compat hack -- this is the first disk, so mark it
    5.40 +                        # bootable.
    5.41 +                        dev_info['bootable'] = True
    5.42                      target[param].append(dev_uuid)
    5.43 -            elif dev_type in ('tap',):
    5.44 +            elif dev_type == 'tap':
    5.45                  if 'vbd_refs' not in target:
    5.46                      target['vbd_refs'] = []
    5.47                  if dev_uuid not in target['vbd_refs']:
    5.48 +                    if not target['vbd_refs']:
    5.49 +                        # Compat hack -- this is the first disk, so mark it
    5.50 +                        # bootable.
    5.51 +                        dev_info['bootable'] = True
    5.52                      target['vbd_refs'].append(dev_uuid)
    5.53 -            elif dev_type in ('console',):
    5.54 +            elif dev_type == 'console':
    5.55                  if 'console_refs' not in target:
    5.56                      target['console_refs'] = []
    5.57                  if dev_uuid not in target['console_refs']:
    5.58 @@ -1009,6 +1025,7 @@ class XendConfig(dict):
    5.59                  dev_info['uname'] = cfg_xenapi.get('image', '')
    5.60                  dev_info['dev'] = '%s:%s' % (cfg_xenapi.get('device'),
    5.61                                               old_vbd_type)
    5.62 +                dev_info['bootable'] = cfg_xenapi.get('bootable', False)
    5.63                  dev_info['driver'] = cfg_xenapi.get('driver')
    5.64                  dev_info['VDI'] = cfg_xenapi.get('VDI', '')
    5.65                      
     6.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Sun Jan 28 15:55:55 2007 +0000
     6.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Sun Jan 28 17:11:40 2007 +0000
     6.3 @@ -1653,48 +1653,45 @@ class XendDomainInfo:
     6.4                  blexec = osdep.pygrub_path
     6.5  
     6.6              blcfg = None
     6.7 -            for (devtype, devinfo) in self.info.all_devices_sxpr():
     6.8 -                if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
     6.9 -                    continue
    6.10 -                disk = None
    6.11 -                for param in devinfo:
    6.12 -                    if param[0] == 'uname':
    6.13 -                        disk = param[1]
    6.14 -                        break
    6.15 +            disks = [x for x in self.info['vbd_refs']
    6.16 +                     if self.info['devices'][x][1]['bootable']]
    6.17 +
    6.18 +            if not disks:
    6.19 +                msg = "Had a bootloader specified, but no disks are bootable"
    6.20 +                log.error(msg)
    6.21 +                raise VmError(msg)
    6.22 +
    6.23 +            disk = disks[0]
    6.24 +
    6.25 +            fn = blkdev_uname_to_file(disk)
    6.26 +            mounted = devtype == 'tap' and not os.stat(fn).st_rdev
    6.27 +            if mounted:
    6.28 +                # This is a file, not a device.  pygrub can cope with a
    6.29 +                # file if it's raw, but if it's QCOW or other such formats
    6.30 +                # used through blktap, then we need to mount it first.
    6.31  
    6.32 -                if disk is None:
    6.33 -                    continue
    6.34 -                fn = blkdev_uname_to_file(disk)
    6.35 -                mounted = devtype == 'tap' and not os.stat(fn).st_rdev
    6.36 +                log.info("Mounting %s on %s." %
    6.37 +                         (fn, BOOTLOADER_LOOPBACK_DEVICE))
    6.38 +
    6.39 +                vbd = {
    6.40 +                    'mode': 'RO',
    6.41 +                    'device': BOOTLOADER_LOOPBACK_DEVICE,
    6.42 +                    }
    6.43 +
    6.44 +                from xen.xend import XendDomain
    6.45 +                dom0 = XendDomain.instance().privilegedDomain()
    6.46 +                dom0._waitForDeviceUUID(dom0.create_vbd(vbd, fn))
    6.47 +                fn = BOOTLOADER_LOOPBACK_DEVICE
    6.48 +
    6.49 +            try:
    6.50 +                blcfg = bootloader(blexec, fn, self, False,
    6.51 +                                   bootloader_args, kernel, ramdisk, args)
    6.52 +            finally:
    6.53                  if mounted:
    6.54 -                    # This is a file, not a device.  pygrub can cope with a
    6.55 -                    # file if it's raw, but if it's QCOW or other such formats
    6.56 -                    # used through blktap, then we need to mount it first.
    6.57 -
    6.58 -                    log.info("Mounting %s on %s." %
    6.59 +                    log.info("Unmounting %s from %s." %
    6.60                               (fn, BOOTLOADER_LOOPBACK_DEVICE))
    6.61  
    6.62 -                    vbd = {
    6.63 -                        'mode': 'RO',
    6.64 -                        'device': BOOTLOADER_LOOPBACK_DEVICE,
    6.65 -                        }
    6.66 -
    6.67 -                    from xen.xend import XendDomain
    6.68 -                    dom0 = XendDomain.instance().privilegedDomain()
    6.69 -                    dom0._waitForDeviceUUID(dom0.create_vbd(vbd, fn))
    6.70 -                    fn = BOOTLOADER_LOOPBACK_DEVICE
    6.71 -
    6.72 -                try:
    6.73 -                    blcfg = bootloader(blexec, fn, self, False,
    6.74 -                                       bootloader_args, kernel, ramdisk, args)
    6.75 -                finally:
    6.76 -                    if mounted:
    6.77 -                        log.info("Unmounting %s from %s." %
    6.78 -                                 (fn, BOOTLOADER_LOOPBACK_DEVICE))
    6.79 -
    6.80 -                        dom0.destroyDevice('tap', '/dev/xvdp')
    6.81 -
    6.82 -                break
    6.83 +                    dom0.destroyDevice('tap', '/dev/xvdp')
    6.84  
    6.85              if blcfg is None:
    6.86                  msg = "Had a bootloader specified, but can't find disk"
    6.87 @@ -2137,6 +2134,9 @@ class XendDomainInfo:
    6.88          except KeyError:
    6.89              raise XendError('Invalid property for device: %s' % field)
    6.90  
    6.91 +    def set_dev_property(self, dev_class, dev_uuid, field, value):
    6.92 +        self.info['devices'][dev_uuid][1][field] = value
    6.93 +
    6.94      def get_vcpus_util(self):
    6.95          vcpu_util = {}
    6.96          xennode = XendNode.instance()