ia64/xen-unstable

changeset 8489:9fedfb8cb1b2

merge
author vhanquez@kneesa.uk.xensource.com
date Tue Jan 03 13:04:59 2006 +0000 (2006-01-03)
parents 2a873f8020ae 5b30599761b3
children 399c68937d59
files
line diff
     1.1 --- a/tools/examples/xmexample.vmx	Tue Jan 03 13:03:35 2006 +0000
     1.2 +++ b/tools/examples/xmexample.vmx	Tue Jan 03 13:04:59 2006 +0000
     1.3 @@ -30,6 +30,9 @@ name = "ExampleVMXDomain"
     1.4  # the number of cpus guest platform has, default=1
     1.5  vcpus=1
     1.6  
     1.7 +# enable/disalbe vmx guest ACPI, default=0 (disabled)
     1.8 +#acpi=0
     1.9 +
    1.10  # List of which CPUS this domain is allowed to use, default Xen picks
    1.11  #cpus = ""         # leave to Xen to pick
    1.12  #cpus = "0"        # all vcpus run on CPU0
     2.1 --- a/tools/firmware/vmxassist/Makefile	Tue Jan 03 13:03:35 2006 +0000
     2.2 +++ b/tools/firmware/vmxassist/Makefile	Tue Jan 03 13:04:59 2006 +0000
     2.3 @@ -24,7 +24,7 @@ include $(XEN_ROOT)/tools/Rules.mk
     2.4  # The emulator code lives in ROM space
     2.5  TEXTADDR=0x000D0000
     2.6  
     2.7 -DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR)
     2.8 +DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
     2.9  XENINC=-I$(XEN_ROOT)/tools/libxc
    2.10  
    2.11  LD       = ld
     3.1 --- a/tools/firmware/vmxassist/acpi_madt.c	Tue Jan 03 13:03:35 2006 +0000
     3.2 +++ b/tools/firmware/vmxassist/acpi_madt.c	Tue Jan 03 13:04:59 2006 +0000
     3.3 @@ -24,23 +24,75 @@
     3.4  
     3.5  extern int puts(const char *s);
     3.6  
     3.7 -#define VCPU_NR_PAGE        0x0009F000
     3.8 -#define VCPU_NR_OFFSET      0x00000800
     3.9 -#define VCPU_MAGIC          0x76637075  /* "vcpu" */
    3.10 +#define HVM_INFO_PAGE	0x0009F000
    3.11 +#define HVM_INFO_OFFSET	0x00000800
    3.12 +
    3.13 +struct hvm_info_table {
    3.14 +	char     signature[8]; /* "HVM INFO" */
    3.15 +	uint32_t length;
    3.16 +	uint8_t  checksum;
    3.17 +	uint8_t  acpi_enabled;
    3.18 +	uint8_t  pad[2];
    3.19 +	uint32_t nr_vcpus;
    3.20 +};
    3.21 +
    3.22 +static struct hvm_info_table *table = NULL;
    3.23 +
    3.24 +static int
    3.25 +checksum_valid(uint8_t *ptr, int len)
    3.26 +{
    3.27 +	uint8_t sum=0;
    3.28 +	int i;
    3.29 +
    3.30 +	for (i = 0; i < len; i++)
    3.31 +		sum += ptr[i];
    3.32 +
    3.33 +	return (sum == 0);
    3.34 +}
    3.35  
    3.36 -/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
    3.37 -static int
    3.38 +/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
    3.39 +static struct hvm_info_table *
    3.40 +get_hvm_info_table(void)
    3.41 +{
    3.42 +	struct hvm_info_table *t;
    3.43 +	char signature[] = "HVM INFO";
    3.44 +	int i;
    3.45 +
    3.46 +	if (table != NULL)
    3.47 +		return table;
    3.48 +
    3.49 +	t = (struct hvm_info_table *)(HVM_INFO_PAGE + HVM_INFO_OFFSET);
    3.50 +
    3.51 +	/* strncmp(t->signature, "HVM INFO", 8) */
    3.52 +	for (i = 0; i < 8; i++) {
    3.53 +		if (signature[i] != t->signature[i]) {
    3.54 +			puts("Bad hvm info signature\n");
    3.55 +			return NULL;
    3.56 +		}
    3.57 +	}
    3.58 +
    3.59 +	if (!checksum_valid((uint8_t *)t, t->length)) {
    3.60 +		puts("Bad hvm info checksum\n");
    3.61 +		return NULL;
    3.62 +	}
    3.63 +
    3.64 +	table = t;
    3.65 +
    3.66 +	return table;
    3.67 +}
    3.68 +
    3.69 +int
    3.70  get_vcpu_nr(void)
    3.71  {
    3.72 -	unsigned int *vcpus;
    3.73 +	struct hvm_info_table *t = get_hvm_info_table();
    3.74 +	return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
    3.75 +}
    3.76  
    3.77 -	vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET);
    3.78 -	if (vcpus[0] != VCPU_MAGIC) {
    3.79 -		puts("Bad vcpus magic, set vcpu number to 1 by default.\n");
    3.80 -		return 1;
    3.81 -	}
    3.82 -
    3.83 -	return vcpus[1];
    3.84 +int
    3.85 +get_acpi_enabled(void)
    3.86 +{
    3.87 +	struct hvm_info_table *t = get_hvm_info_table();
    3.88 +	return (t ? t->acpi_enabled : 0); /* default no acpi */
    3.89  }
    3.90  
    3.91  static void *
     4.1 --- a/tools/firmware/vmxassist/vmxloader.c	Tue Jan 03 13:03:35 2006 +0000
     4.2 +++ b/tools/firmware/vmxassist/vmxloader.c	Tue Jan 03 13:04:59 2006 +0000
     4.3 @@ -24,12 +24,10 @@
     4.4  #include "machine.h"
     4.5  #include "roms.h"
     4.6  
     4.7 -#ifdef _ACPI_
     4.8  #include "acpi.h"
     4.9  #include "../acpi/acpi2_0.h"  // for ACPI_PHYSICAL_ADDRESS
    4.10  int acpi_madt_update(unsigned char* acpi_start);
    4.11 -#endif
    4.12 -
    4.13 +int get_acpi_enabled(void);
    4.14  
    4.15  /*
    4.16   * C runtime start off
    4.17 @@ -120,18 +118,17 @@ main(void)
    4.18  		memcpy((void *)0xC0000,
    4.19  			vgabios_stdvga, sizeof(vgabios_stdvga));
    4.20  	}
    4.21 -#ifdef _ACPI_
    4.22 -	puts("Loading ACPI ...\n");
    4.23  
    4.24 -	acpi_madt_update(acpi);
    4.25 -
    4.26 -	if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
    4.27 -		/* make sure acpi table does not overlap rombios
    4.28 - 		 * currently acpi less than 8K will be OK.
    4.29 -		 */
    4.30 -		 memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
    4.31 +	if (get_acpi_enabled() != 0) {
    4.32 +		puts("Loading ACPI ...\n");
    4.33 +		acpi_madt_update((unsigned char*)acpi);
    4.34 +		if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
    4.35 +			/* make sure acpi table does not overlap rombios
    4.36 +			 * currently acpi less than 8K will be OK.
    4.37 +			 */
    4.38 +			memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
    4.39 +		}
    4.40  	}
    4.41 -#endif
    4.42  
    4.43  	puts("Loading VMXAssist ...\n");
    4.44  	memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
     5.1 --- a/tools/libxc/xc_vmx_build.c	Tue Jan 03 13:03:35 2006 +0000
     5.2 +++ b/tools/libxc/xc_vmx_build.c	Tue Jan 03 13:04:59 2006 +0000
     5.3 @@ -33,8 +33,17 @@
     5.4  #define E820_MAP_NR_OFFSET  0x000001E8
     5.5  #define E820_MAP_OFFSET     0x000002D0
     5.6  
     5.7 -#define VCPU_NR_PAGE        0x0009F000
     5.8 -#define VCPU_NR_OFFSET      0x00000800
     5.9 +#define HVM_INFO_PAGE        0x0009F000
    5.10 +#define HVM_INFO_OFFSET      0x00000800
    5.11 +
    5.12 +struct hvm_info_table {
    5.13 +    char     signature[8]; /* "HVM INFO" */
    5.14 +    uint32_t length;
    5.15 +    uint8_t  checksum;
    5.16 +    uint8_t  acpi_enabled;
    5.17 +    uint8_t  pad[2];
    5.18 +    uint32_t nr_vcpus;
    5.19 +};
    5.20  
    5.21  struct e820entry {
    5.22      uint64_t addr;
    5.23 @@ -119,26 +128,45 @@ static unsigned char build_e820map(void 
    5.24      return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
    5.25  }
    5.26  
    5.27 +static void 
    5.28 +set_hvm_info_checksum(struct hvm_info_table *t)
    5.29 +{
    5.30 +    uint8_t *ptr = (uint8_t *)t, sum = 0;
    5.31 +    unsigned int i;
    5.32 +
    5.33 +    t->checksum = 0;
    5.34 +
    5.35 +    for (i = 0; i < t->length; i++)
    5.36 +        sum += *ptr++;
    5.37 +
    5.38 +    t->checksum = -sum;
    5.39 +}
    5.40 +
    5.41  /*
    5.42 - * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader
    5.43 - * vmxloader will use it to config ACPI MADT table
    5.44 + * Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
    5.45 + * vmxloader will use this info to set BIOS accordingly
    5.46   */
    5.47 -#define VCPU_MAGIC      0x76637075  /* "vcpu" */
    5.48 -static int set_vcpu_nr(int xc_handle, uint32_t dom,
    5.49 -                        unsigned long *pfn_list, unsigned int vcpus)
    5.50 +static int set_hvm_info(int xc_handle, uint32_t dom,
    5.51 +                        unsigned long *pfn_list, unsigned int vcpus,
    5.52 +                        unsigned int acpi)
    5.53  {
    5.54 -    char         *va_map;
    5.55 -    unsigned int *va_vcpus;
    5.56 +    char *va_map;
    5.57 +    struct hvm_info_table *va_hvm;
    5.58  
    5.59      va_map = xc_map_foreign_range(xc_handle, dom,
    5.60                                    PAGE_SIZE, PROT_READ|PROT_WRITE,
    5.61 -                                  pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]);
    5.62 +                                  pfn_list[HVM_INFO_PAGE >> PAGE_SHIFT]);
    5.63      if ( va_map == NULL )
    5.64          return -1;
    5.65  
    5.66 -    va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET);
    5.67 -    va_vcpus[0] = VCPU_MAGIC;
    5.68 -    va_vcpus[1] = vcpus;
    5.69 +    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
    5.70 +    memset(va_hvm, 0, sizeof(*va_hvm));
    5.71 +    strncpy(va_hvm->signature, "HVM INFO", 8);
    5.72 +    va_hvm->length       = sizeof(struct hvm_info_table);
    5.73 +    va_hvm->acpi_enabled = acpi;
    5.74 +    va_hvm->nr_vcpus     = vcpus;
    5.75 +    
    5.76 +    set_hvm_info_checksum(va_hvm);
    5.77  
    5.78      munmap(va_map, PAGE_SIZE);
    5.79  
    5.80 @@ -281,6 +309,7 @@ static int setup_guest(int xc_handle,
    5.81                         unsigned int control_evtchn,
    5.82                         unsigned int lapic,
    5.83                         unsigned int vcpus,
    5.84 +                       unsigned int acpi,
    5.85                         unsigned int store_evtchn,
    5.86                         unsigned long *store_mfn)
    5.87  {
    5.88 @@ -490,8 +519,8 @@ static int setup_guest(int xc_handle,
    5.89              goto error_out;
    5.90      }
    5.91  
    5.92 -    if (set_vcpu_nr(xc_handle, dom, page_array, vcpus)) {
    5.93 -        fprintf(stderr, "Couldn't set vcpu number for VMX guest.\n");
    5.94 +    if (set_hvm_info(xc_handle, dom, page_array, vcpus, acpi)) {
    5.95 +        fprintf(stderr, "Couldn't set hvm info for VMX guest.\n");
    5.96          goto error_out;
    5.97      }
    5.98  
    5.99 @@ -581,6 +610,7 @@ int xc_vmx_build(int xc_handle,
   5.100                   unsigned int control_evtchn,
   5.101                   unsigned int lapic,
   5.102                   unsigned int vcpus,
   5.103 +                 unsigned int acpi,
   5.104                   unsigned int store_evtchn,
   5.105                   unsigned long *store_mfn)
   5.106  {
   5.107 @@ -644,7 +674,7 @@ int xc_vmx_build(int xc_handle,
   5.108  
   5.109      if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
   5.110                       ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
   5.111 -                     lapic, vcpus, store_evtchn, store_mfn) < 0)
   5.112 +                     lapic, vcpus, acpi, store_evtchn, store_mfn) < 0)
   5.113      {
   5.114          ERROR("Error constructing guest OS");
   5.115          goto error_out;
     6.1 --- a/tools/libxc/xenguest.h	Tue Jan 03 13:03:35 2006 +0000
     6.2 +++ b/tools/libxc/xenguest.h	Tue Jan 03 13:04:59 2006 +0000
     6.3 @@ -58,6 +58,7 @@ int xc_vmx_build(int xc_handle,
     6.4                   unsigned int control_evtchn,
     6.5                   unsigned int lapic,
     6.6                   unsigned int vcpus,
     6.7 +                 unsigned int acpi,
     6.8                   unsigned int store_evtchn,
     6.9                   unsigned long *store_mfn);
    6.10  
     7.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Tue Jan 03 13:03:35 2006 +0000
     7.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue Jan 03 13:04:59 2006 +0000
     7.3 @@ -364,19 +364,20 @@ static PyObject *pyxc_vmx_build(XcObject
     7.4      int control_evtchn, store_evtchn;
     7.5      int vcpus = 1;
     7.6      int lapic = 0;
     7.7 +    int acpi = 0;
     7.8      int memsize;
     7.9      unsigned long store_mfn = 0;
    7.10  
    7.11      static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
    7.12 -                                "memsize", "image", "lapic", "vcpus", NULL };
    7.13 +                                "memsize", "image", "lapic", "vcpus", "acpi",NULL };
    7.14  
    7.15 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
    7.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list,
    7.17                                        &dom, &control_evtchn, &store_evtchn,
    7.18 -                                      &memsize, &image, &lapic, &vcpus) )
    7.19 +                                      &memsize, &image, &lapic, &vcpus,&acpi) )
    7.20          return NULL;
    7.21  
    7.22      if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
    7.23 -                      lapic, vcpus, store_evtchn, &store_mfn) != 0 )
    7.24 +                      lapic, vcpus, acpi, store_evtchn, &store_mfn) != 0 )
    7.25          return PyErr_SetFromErrno(xc_error);
    7.26  
    7.27      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
     8.1 --- a/tools/python/xen/xend/image.py	Tue Jan 03 13:03:35 2006 +0000
     8.2 +++ b/tools/python/xen/xend/image.py	Tue Jan 03 13:04:59 2006 +0000
     8.3 @@ -214,6 +214,8 @@ class VmxImageHandler(ImageHandler):
     8.4          if not lapic is None:
     8.5              self.lapic = int(lapic)
     8.6  
     8.7 +        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
     8.8 +        
     8.9      def buildDomain(self):
    8.10          # Create an event channel
    8.11          self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
    8.12 @@ -229,6 +231,7 @@ class VmxImageHandler(ImageHandler):
    8.13          log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
    8.14          log.debug("lapic          = %d", self.lapic)
    8.15          log.debug("vcpus          = %d", self.vm.getVCpuCount())
    8.16 +        log.debug("acpi           = %d", self.acpi)
    8.17  
    8.18          return xc.vmx_build(dom            = self.vm.getDomid(),
    8.19                              image          = self.kernel,
    8.20 @@ -236,9 +239,9 @@ class VmxImageHandler(ImageHandler):
    8.21                              store_evtchn   = store_evtchn,
    8.22                              memsize        = self.vm.getMemoryTarget() / 1024,
    8.23                              lapic          = self.lapic,
    8.24 +                            acpi           = self.acpi,
    8.25                              vcpus          = self.vm.getVCpuCount())
    8.26  
    8.27 -
    8.28      # Return a list of cmd line args to the device models based on the
    8.29      # xm config file
    8.30      def parseDeviceModelArgs(self, imageConfig, deviceConfig):
    8.31 @@ -269,44 +272,44 @@ class VmxImageHandler(ImageHandler):
    8.32          nics = 0
    8.33          for (name, info) in deviceConfig:
    8.34              if name == 'vbd':
    8.35 -               uname = sxp.child_value(info, 'uname')
    8.36 -               typedev = sxp.child_value(info, 'dev')
    8.37 -               (_, vbdparam) = string.split(uname, ':', 1)
    8.38 -               if re.match('^ioemu:', typedev):
    8.39 -                  (emtype, vbddev) = string.split(typedev, ':', 1)
    8.40 -               else:
    8.41 -                  emtype = 'vbd'
    8.42 -                  vbddev = typedev
    8.43 -               if emtype != 'ioemu':
    8.44 -                  continue;
    8.45 -               vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
    8.46 -               if vbddev not in vbddev_list:
    8.47 -                  raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
    8.48 -               ret.append("-%s" % vbddev)
    8.49 -               ret.append("%s" % vbdparam)
    8.50 +                uname = sxp.child_value(info, 'uname')
    8.51 +                typedev = sxp.child_value(info, 'dev')
    8.52 +                (_, vbdparam) = string.split(uname, ':', 1)
    8.53 +                if 'ioemu:' in typedev:
    8.54 +                    (emtype, vbddev) = string.split(typedev, ':', 1)
    8.55 +                else:
    8.56 +                    emtype = 'vbd'
    8.57 +                    vbddev = typedev
    8.58 +                if emtype == 'vbd':
    8.59 +                    continue;
    8.60 +                vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
    8.61 +                if vbddev not in vbddev_list:
    8.62 +                    raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
    8.63 +                ret.append("-%s" % vbddev)
    8.64 +                ret.append("%s" % vbdparam)
    8.65              if name == 'vif':
    8.66 -               type = sxp.child_value(info, 'type')
    8.67 -               if type != 'ioemu':
    8.68 -                   continue
    8.69 -               nics += 1
    8.70 -               if mac != None:
    8.71 -                   continue
    8.72 -               mac = sxp.child_value(info, 'mac')
    8.73 -               bridge = sxp.child_value(info, 'bridge')
    8.74 -               if mac == None:
    8.75 -                   mac = randomMAC()
    8.76 -               if bridge == None:
    8.77 -                   bridge = 'xenbr0'
    8.78 -               ret.append("-macaddr")
    8.79 -               ret.append("%s" % mac)
    8.80 -               ret.append("-bridge")
    8.81 -               ret.append("%s" % bridge)
    8.82 +                type = sxp.child_value(info, 'type')
    8.83 +                if type != 'ioemu':
    8.84 +                    continue
    8.85 +                nics += 1
    8.86 +                if mac != None:
    8.87 +                    continue
    8.88 +                mac = sxp.child_value(info, 'mac')
    8.89 +                bridge = sxp.child_value(info, 'bridge')
    8.90 +                if mac == None:
    8.91 +                    mac = randomMAC()
    8.92 +                if bridge == None:
    8.93 +                    bridge = 'xenbr0'
    8.94 +                ret.append("-macaddr")
    8.95 +                ret.append("%s" % mac)
    8.96 +                ret.append("-bridge")
    8.97 +                ret.append("%s" % bridge)
    8.98              if name == 'vtpm':
    8.99 -               instance = sxp.child_value(info, 'pref_instance')
   8.100 -               ret.append("-instance")
   8.101 -               ret.append("%s" % instance)
   8.102 +                instance = sxp.child_value(info, 'pref_instance')
   8.103 +                ret.append("-instance")
   8.104 +                ret.append("%s" % instance)
   8.105          ret.append("-nics")
   8.106 -        ret.append("%d" % nics) 
   8.107 +        ret.append("%d" % nics)
   8.108          return ret
   8.109  
   8.110      def configVNC(self, config):
     9.1 --- a/tools/python/xen/xend/server/blkif.py	Tue Jan 03 13:03:35 2006 +0000
     9.2 +++ b/tools/python/xen/xend/server/blkif.py	Tue Jan 03 13:04:59 2006 +0000
     9.3 @@ -31,7 +31,7 @@ class BlkifController(DevController):
     9.4      """Block device interface controller. Handles all block devices
     9.5      for a domain.
     9.6      """
     9.7 -    
     9.8 +
     9.9      def __init__(self, vm):
    9.10          """Create a block device controller.
    9.11          """
    9.12 @@ -40,9 +40,9 @@ class BlkifController(DevController):
    9.13  
    9.14      def getDeviceDetails(self, config):
    9.15          """@see DevController.getDeviceDetails"""
    9.16 -        
    9.17 +
    9.18          dev = sxp.child_value(config, 'dev')
    9.19 -        if re.match('^ioemu:', dev):
    9.20 +        if 'ioemu:' in dev:
    9.21              return (None,{},{})
    9.22  
    9.23          devid = blkif.blkdev_name_to_number(dev)
    10.1 --- a/tools/python/xen/xm/create.py	Tue Jan 03 13:03:35 2006 +0000
    10.2 +++ b/tools/python/xen/xm/create.py	Tue Jan 03 13:04:59 2006 +0000
    10.3 @@ -164,6 +164,10 @@ gopts.var('lapic', val='LAPIC',
    10.4            fn=set_int, default=0,
    10.5            use="Disable or enable local APIC of VMX domain.")
    10.6  
    10.7 +gopts.var('acpi', val='ACPI',
    10.8 +          fn=set_int, default=0,
    10.9 +          use="Disable or enable ACPI of VMX domain.")
   10.10 +
   10.11  gopts.var('vcpus', val='VCPUS',
   10.12            fn=set_int, default=1,
   10.13            use="# of Virtual CPUS in domain.")
   10.14 @@ -531,7 +535,7 @@ def configure_vmx(config_image, vals):
   10.15      args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
   10.16               'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
   10.17               'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic',
   10.18 -             'xauthority' ]
   10.19 +             'xauthority', 'acpi' ]
   10.20      for a in args:
   10.21          if (vals.__dict__[a]):
   10.22              config_image.append([a, vals.__dict__[a]])