ia64/xen-unstable

changeset 8207:2dcfb85f5bac

Merge with xen-ia64-unstable.hg
author kaf24@firebug.cl.cam.ac.uk
date Sat Dec 03 10:44:38 2005 +0100 (2005-12-03)
parents 3a4589331504 5ff5117291ad
children 773735517d9d
files
line diff
     1.1 --- a/docs/man/xmdomain.cfg.pod.5	Fri Dec 02 15:52:41 2005 -0600
     1.2 +++ b/docs/man/xmdomain.cfg.pod.5	Sat Dec 03 10:44:38 2005 +0100
     1.3 @@ -156,6 +156,16 @@ Specifies which CPU the domain should be
     1.4  the first cpu, 1 the second, and so on.  This defaults to -1, which
     1.5  means Xen is free to pick which CPU to start on.
     1.6  
     1.7 +=item B<cpus>
     1.8 +
     1.9 +Specifies a list of CPUs on which the domains' VCPUs are allowed to
    1.10 +execute upon.  The syntax supports ranges (0-3), and negation, ^1.
    1.11 +For instance:
    1.12 +
    1.13 +    cpus = "0-3,5,^1"
    1.14 +
    1.15 +Will result in CPUs 0, 2, 3, 5 being available for use by the domain.
    1.16 +
    1.17  =item B<extra>
    1.18  
    1.19  Extra information to append to the end of the kernel parameter line.
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Fri Dec 02 15:52:41 2005 -0600
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Sat Dec 03 10:44:38 2005 +0100
     2.3 @@ -560,7 +560,8 @@ irqreturn_t timer_interrupt(int irq, voi
     2.4  	}
     2.5  	while (!time_values_up_to_date(cpu));
     2.6  
     2.7 -	if (unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0)) {
     2.8 +	if ((unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0))
     2.9 +	    && printk_ratelimit()) {
    2.10  		printk("Timer ISR/%d: Time went backwards: "
    2.11  		       "delta=%lld cpu_delta=%lld shadow=%lld "
    2.12  		       "off=%lld processed=%lld cpu_processed=%lld\n",
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Dec 02 15:52:41 2005 -0600
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Sat Dec 03 10:44:38 2005 +0100
     3.3 @@ -59,6 +59,8 @@ extern struct semaphore xenwatch_mutex;
     3.4  
     3.5  #define streq(a, b) (strcmp((a), (b)) == 0)
     3.6  
     3.7 +static char *kasprintf(const char *fmt, ...);
     3.8 +
     3.9  static struct notifier_block *xenstore_chain;
    3.10  
    3.11  /* If something in array of ids matches this device, return it. */
    3.12 @@ -226,8 +228,11 @@ static int xenbus_hotplug_backend(struct
    3.13  				  int num_envp, char *buffer, int buffer_size)
    3.14  {
    3.15  	struct xenbus_device *xdev;
    3.16 +	struct xenbus_driver *drv = NULL;
    3.17  	int i = 0;
    3.18  	int length = 0;
    3.19 +	char *basepath_end;
    3.20 +	char *frontend_id;
    3.21  
    3.22  	DPRINTK("");
    3.23  
    3.24 @@ -238,6 +243,9 @@ static int xenbus_hotplug_backend(struct
    3.25  	if (xdev == NULL)
    3.26  		return -ENODEV;
    3.27  
    3.28 +	if (dev->driver)
    3.29 +		drv = to_xenbus_driver(dev->driver);
    3.30 +
    3.31  	/* stuff we want to pass to /sbin/hotplug */
    3.32  	add_hotplug_env_var(envp, num_envp, &i,
    3.33  			    buffer, buffer_size, &length,
    3.34 @@ -247,6 +255,25 @@ static int xenbus_hotplug_backend(struct
    3.35  			    buffer, buffer_size, &length,
    3.36  			    "XENBUS_PATH=%s", xdev->nodename);
    3.37  
    3.38 +	add_hotplug_env_var(envp, num_envp, &i,
    3.39 +			    buffer, buffer_size, &length,
    3.40 +			    "XENBUS_BASE_PATH=%s", xdev->nodename);
    3.41 +
    3.42 +	basepath_end = strrchr(envp[i - 1], '/');
    3.43 +	length -= strlen(basepath_end);
    3.44 +	*basepath_end = '\0';
    3.45 +	basepath_end = strrchr(envp[i - 1], '/');
    3.46 +	length -= strlen(basepath_end);
    3.47 +	*basepath_end = '\0';
    3.48 +
    3.49 +	basepath_end++;
    3.50 +	frontend_id = kmalloc(strlen(basepath_end) + 1, GFP_KERNEL);
    3.51 +	strcpy(frontend_id, basepath_end);
    3.52 +	add_hotplug_env_var(envp, num_envp, &i,
    3.53 +			    buffer, buffer_size, &length,
    3.54 +			    "XENBUS_FRONTEND_ID=%s", frontend_id);
    3.55 +	kfree(frontend_id);
    3.56 +
    3.57  	/* terminate, set to next free slot, shrink available space */
    3.58  	envp[i] = NULL;
    3.59  	envp = &envp[i];
    3.60 @@ -254,9 +281,9 @@ static int xenbus_hotplug_backend(struct
    3.61  	buffer = &buffer[length];
    3.62  	buffer_size -= length;
    3.63  
    3.64 -	if (dev->driver && to_xenbus_driver(dev->driver)->hotplug)
    3.65 -		return to_xenbus_driver(dev->driver)->hotplug
    3.66 -			(xdev, envp, num_envp, buffer, buffer_size);
    3.67 +	if (drv && drv->hotplug)
    3.68 +		return drv->hotplug(xdev, envp, num_envp, buffer,
    3.69 +				    buffer_size);
    3.70  
    3.71  	return 0;
    3.72  }
     4.1 --- a/tools/examples/block	Fri Dec 02 15:52:41 2005 -0600
     4.2 +++ b/tools/examples/block	Sat Dec 03 10:44:38 2005 +0100
     4.3 @@ -89,39 +89,54 @@ check_sharing()
     4.4      fi
     4.5    done
     4.6  
     4.7 -##
     4.8 -## XXX SMH: the below causes live migration on localhost to fail sometimes
     4.9 -## since the source domain may still appear to be using a local device. 
    4.10 -## For now simply comment it out - a proper fix will come in due course. 
    4.11 +  for dom in $(xenstore-list "$XENBUS_BASE_PATH")
    4.12 +  do
    4.13 +    for dev in $(xenstore-list "$XENBUS_BASE_PATH/$dom")
    4.14 +    do
    4.15 +      d=$(xenstore_read_default \
    4.16 +            "$XENBUS_BASE_PATH/$dom/$dev/physical-device" "")
    4.17  
    4.18 -#   for file in /sys/devices/xen-backend/*/physical_device
    4.19 -#   do
    4.20 -#     if [ -e "$file" ] # Cope with no devices, i.e. the * above did not expand.
    4.21 -#     then
    4.22 -#       local d=$(cat "$file")
    4.23 -#       if [ "$d" == "$devmm" ]
    4.24 -#       then
    4.25 -#         if [ "$mode" == 'w' ]
    4.26 -#         then
    4.27 -#           echo 'guest'
    4.28 -#           return
    4.29 -#         else
    4.30 -#           local m=$(cat "${file/physical_device/mode}")
    4.31 +      if [ "$d" == "$devmm" ]
    4.32 +      then
    4.33 +        if [ "$mode" == 'w' ]
    4.34 +        then
    4.35 +          if ! same_vm $dom
    4.36 +          then
    4.37 +            echo 'guest'
    4.38 +            return
    4.39 +          fi
    4.40 +        else
    4.41 +          local m=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$dev/mode")
    4.42 +          m=$(canonicalise_mode "$m")
    4.43  
    4.44 -#           if expr index "$m" 'w' >/dev/null
    4.45 -#           then
    4.46 -#             echo 'guest'
    4.47 -#             return
    4.48 -#           fi
    4.49 -#         fi
    4.50 -#       fi
    4.51 -#     fi
    4.52 -#   done
    4.53 +          if [ "$m" == 'w' ]
    4.54 +          then
    4.55 +            if ! same_vm $dom
    4.56 +            then
    4.57 +              echo 'guest'
    4.58 +              return
    4.59 +            fi
    4.60 +          fi
    4.61 +        fi
    4.62 +      fi
    4.63 +    done
    4.64 +  done
    4.65  
    4.66    echo 'ok'
    4.67  }
    4.68  
    4.69  
    4.70 +same_vm()
    4.71 +{
    4.72 +  local thisdom="$XENBUS_FRONTEND_ID"
    4.73 +  local otherdom="$1"
    4.74 +  local thisvm=$(xenstore-read "/local/domain/$thisdom/vm")
    4.75 +  local othervm=$(xenstore-read "/local/domain/otherdom/vm")
    4.76 +
    4.77 +  return [ "$thisvm" == "$othervm" ]
    4.78 +}
    4.79 +
    4.80 +
    4.81  ##
    4.82  # check_device_sharing dev mode
    4.83  #
    4.84 @@ -200,6 +215,7 @@ do_ebusy()
    4.85      m2='read-only '
    4.86    fi
    4.87  
    4.88 +  release_lock "block"
    4.89    ebusy \
    4.90  "${prefix}${m1}in ${dom}domain,
    4.91  and so cannot be mounted ${m2}${when}."
    4.92 @@ -224,79 +240,106 @@ case "$command" in
    4.93      case $t in 
    4.94        phy)
    4.95          dev=$(expand_dev $p)
    4.96 +        claim_lock "block"
    4.97          check_device_sharing "$dev" "$mode"
    4.98  	write_dev "$dev"
    4.99 +        release_lock "block"
   4.100  	exit 0
   4.101  	;;
   4.102  
   4.103        file)
   4.104          # Canonicalise the file, for sharing check comparison, and the mode
   4.105          # for ease of use here.
   4.106 -        file=$(readlink -f "$p")
   4.107 +        file=$(readlink -f "$p") || fatal "$p does not exist."
   4.108          mode=$(canonicalise_mode "$mode")
   4.109  
   4.110 +        claim_lock "block"
   4.111 +
   4.112          if [ "$mode" == 'w' ] && ! stat "$file" -c %A | grep -q w
   4.113          then
   4.114 +          release_lock "block"
   4.115            ebusy \
   4.116  "File $file is read-only, and so I will not
   4.117  mount it read-write in a guest domain."
   4.118          fi
   4.119  
   4.120 +        loopdev=''
   4.121 +        for dev in /dev/loop*
   4.122 +        do
   4.123 +          if [ ! -b "$dev" ]
   4.124 +          then
   4.125 +            continue
   4.126 +          fi
   4.127  
   4.128 -	while true
   4.129 -        do 
   4.130 -          loopdev=''
   4.131 -          for dev in /dev/loop*
   4.132 -          do
   4.133 -            if [ ! -b "$dev" ]
   4.134 +          f=$(losetup "$dev" 2>/dev/null) || f=''
   4.135 +
   4.136 +          if [ "$f" ]
   4.137 +          then
   4.138 +            # $dev is in use.  Check sharing.
   4.139 +            if [ "$mode" == '!' ]
   4.140              then
   4.141                continue
   4.142              fi
   4.143  
   4.144 -            f=$(losetup "$dev" 2>/dev/null) || f='()'
   4.145              f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g')
   4.146  
   4.147 -            log err "$file $f $dev"
   4.148 -
   4.149 -            if [ "$f" ]
   4.150 +            # $f is the filename, as read from losetup, but the loopback
   4.151 +            # driver truncates filenames at 64 characters, so we need to go
   4.152 +            # trawling through the store if it's longer than that.  Truncation
   4.153 +            # is indicated by an asterisk at the end of the filename.
   4.154 +            if expr index "$f" '*' >/dev/null
   4.155              then
   4.156 -              # $dev is in use.  Check sharing.
   4.157 -              if [ "$mode" == '!' ]
   4.158 +              found=""
   4.159 +              for dom in $(xenstore-list "$XENBUS_BASE_PATH")
   4.160 +              do
   4.161 +                for domdev in $(xenstore-list "$XENBUS_BASE_PATH/$dom")
   4.162 +                do
   4.163 +                  d=$(xenstore_read_default \
   4.164 +                        "$XENBUS_BASE_PATH/$dom/$domdev/node" "")
   4.165 +                  if [ "$d" == "$dev" ]
   4.166 +                  then
   4.167 +                    f=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$domdev/params")
   4.168 +                    found=1
   4.169 +                    break 2
   4.170 +                  fi
   4.171 +                done
   4.172 +              done
   4.173 +
   4.174 +              if [ ! "$found" ]
   4.175                then
   4.176 +                # This loopback device is in use by someone else, so skip it.
   4.177 +                log debug "Loopback sharing check skips device $dev."
   4.178                  continue
   4.179                fi
   4.180 +            fi
   4.181  
   4.182 -              f=$(readlink -f "$f")
   4.183 +            f=$(readlink -f "$f")
   4.184  
   4.185 -              if [ "$f" == "$file" ]
   4.186 -              then
   4.187 -                check_file_sharing "$file" "$dev" "$mode"
   4.188 -              fi
   4.189 -            else
   4.190 -              # $dev is not in use, so we'll remember it for use later; we want
   4.191 -              # to finish the sharing check first.
   4.192 -              
   4.193 -              if [ "$loopdev" == '' ]
   4.194 -              then
   4.195 -                loopdev="$dev"
   4.196 -              fi
   4.197 +            if [ "$f" == "$file" ]
   4.198 +            then
   4.199 +              check_file_sharing "$file" "$dev" "$mode"
   4.200              fi
   4.201 -          done
   4.202 +          else
   4.203 +            # $dev is not in use, so we'll remember it for use later; we want
   4.204 +            # to finish the sharing check first.
   4.205  
   4.206 -          if [ "$loopdev" == '' ]
   4.207 -          then
   4.208 -            fatal 'Failed to find an unused loop device'
   4.209 +            if [ "$loopdev" == '' ]
   4.210 +            then
   4.211 +              loopdev="$dev"
   4.212 +            fi
   4.213            fi
   4.214 -          if losetup "$loopdev" "$file"
   4.215 -          then
   4.216 -	    log err "mapped $file using $loopdev"
   4.217 -            xenstore_write "$XENBUS_PATH/node" "$loopdev"
   4.218 -            write_dev "$loopdev"
   4.219 -            exit 0
   4.220 -          else
   4.221 -            log err "losetup $loopdev $file failed, retry"
   4.222 -          fi
   4.223 -	done
   4.224 +        done
   4.225 +
   4.226 +        if [ "$loopdev" == '' ]
   4.227 +        then
   4.228 +          fatal 'Failed to find an unused loop device'
   4.229 +        fi
   4.230 +
   4.231 +        do_or_die losetup "$loopdev" "$file"
   4.232 +        xenstore_write "$XENBUS_PATH/node" "$loopdev"
   4.233 +        write_dev "$loopdev"
   4.234 +        release_lock "block"
   4.235 +        exit 0
   4.236  	;;
   4.237      esac
   4.238      ;;
     5.1 --- a/tools/examples/vif-nat	Fri Dec 02 15:52:41 2005 -0600
     5.2 +++ b/tools/examples/vif-nat	Sat Dec 03 10:44:38 2005 +0100
     5.3 @@ -91,8 +91,6 @@ vif_int=$(( $(echo "((($vif_ip" | sed -e
     5.4  netmask=$(dotted_quad $intmask)
     5.5  network=$(dotted_quad $(( $vif_int & $intmask )) )
     5.6  
     5.7 -main_ip=$(dom0_ip)
     5.8 -
     5.9  
    5.10  dhcp_remove_entry()
    5.11  {
    5.12 @@ -140,7 +138,7 @@ case "$command" in
    5.13  
    5.14          do_or_die ip link set "$vif" up arp on
    5.15          do_or_die ip addr add "$router_ip" dev "$vif"
    5.16 -        do_or_die ip route add "$vif_ip" dev "$vif" src "$main_ip"
    5.17 +        do_or_die ip route add "$vif_ip" dev "$vif" src "$router_ip"
    5.18          echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp
    5.19          [ "$dhcp" != 'no' ] && dhcp_up
    5.20          ;;
     6.1 --- a/tools/examples/xen-hotplug-common.sh	Fri Dec 02 15:52:41 2005 -0600
     6.2 +++ b/tools/examples/xen-hotplug-common.sh	Sat Dec 03 10:44:38 2005 +0100
     6.3 @@ -19,6 +19,8 @@
     6.4  dir=$(dirname "$0")
     6.5  . "$dir/xen-script-common.sh"
     6.6  
     6.7 +exec 2>>/var/log/xen-hotplug.log
     6.8 +
     6.9  export PATH="/sbin:/bin:/usr/bin:/usr/sbin:$PATH"
    6.10  export LANG="POSIX"
    6.11  unset $(set | grep ^LC_ | cut -d= -f1)
    6.12 @@ -45,7 +47,7 @@ do_or_die() {
    6.13  }
    6.14  
    6.15  sigerr() {
    6.16 -  fatal "$0" "$@" "failed; error detected."
    6.17 +  fatal "$0 failed; error detected."
    6.18  }
    6.19  
    6.20  trap sigerr ERR
    6.21 @@ -86,4 +88,88 @@ xenstore_write() {
    6.22    xenstore-write "$@" || fatal "Writing $@ to xenstore failed."
    6.23  }
    6.24  
    6.25 +
    6.26 +#
    6.27 +# Serialisation
    6.28 +#
    6.29 +
    6.30 +LOCK_SLEEPTIME=1
    6.31 +LOCK_SPINNING_RETRIES=5
    6.32 +LOCK_RETRIES=10
    6.33 +LOCK_BASEDIR=/var/run/xen-hotplug
    6.34 +
    6.35 +
    6.36 +claim_lock()
    6.37 +{
    6.38 +  local lockdir="$LOCK_BASEDIR/$1"
    6.39 +  mkdir -p "$LOCK_BASEDIR"
    6.40 +  _claim_lock "$lockdir"
    6.41 +}
    6.42 +
    6.43 +
    6.44 +release_lock()
    6.45 +{
    6.46 +  _release_lock "$LOCK_BASEDIR/$1"
    6.47 +}
    6.48 +
    6.49 +
    6.50 +_claim_lock()
    6.51 +{
    6.52 +  local lockdir="$1"
    6.53 +  local owner=$(_lock_owner "$lockdir")
    6.54 +  local retries=0
    6.55 +
    6.56 +  while expr $retries '<' $LOCK_RETRIES
    6.57 +  do
    6.58 +    mkdir "$lockdir" && trap "release_lock $1; sigerr" ERR &&
    6.59 +      _update_lock_info "$lockdir" && return
    6.60 +
    6.61 +    local new_owner=$(_lock_owner "$lockdir")
    6.62 +    if [ "$new_owner" != "$owner" ]
    6.63 +    then
    6.64 +      owner="$new_owner"
    6.65 +      retries=0
    6.66 +    fi
    6.67 +
    6.68 +    if expr $retries '>' $LOCK_SPINNING_RETRIES
    6.69 +    then
    6.70 +      sleep $LOCK_SLEEPTIME
    6.71 +    else
    6.72 +      sleep 0
    6.73 +    fi
    6.74 +    retries=$(($retries + 1))
    6.75 +  done
    6.76 +  _steal_lock "$lockdir"
    6.77 +}
    6.78 +
    6.79 +
    6.80 +_release_lock()
    6.81 +{
    6.82 +  trap sigerr ERR
    6.83 +  rm -rf "$1" || true
    6.84 +}
    6.85 +
    6.86 +
    6.87 +_steal_lock()
    6.88 +{
    6.89 +  local lockdir="$1"
    6.90 +  local owner=$(cat "$lockdir/owner" 2>/dev/null || echo "unknown")
    6.91 +  log err "Forced to steal lock on $lockdir from $owner!"
    6.92 +  _release_lock "$lockdir"
    6.93 +  _claim_lock "$lockdir"
    6.94 +}
    6.95 +
    6.96 +
    6.97 +_lock_owner()
    6.98 +{
    6.99 +  cat "$1/owner" 2>/dev/null || echo "unknown"
   6.100 +}
   6.101 +
   6.102 +
   6.103 +_update_lock_info()
   6.104 +{
   6.105 +  echo "$$: $0" >"$1/owner"
   6.106 +}
   6.107 +
   6.108 +
   6.109  log debug "$@" "XENBUS_PATH=$XENBUS_PATH"
     7.1 --- a/tools/examples/xen-network-common.sh	Fri Dec 02 15:52:41 2005 -0600
     7.2 +++ b/tools/examples/xen-network-common.sh	Sat Dec 03 10:44:38 2005 +0100
     7.3 @@ -93,5 +93,5 @@ find_dhcpd_conf_file()
     7.4  
     7.5  find_dhcpd_init_file()
     7.6  {
     7.7 -  first_file -x /etc/init.d/dhcp3-server /etc/init.d/dhcp
     7.8 +  first_file -x /etc/init.d/{dhcp3-server,dhcp,dhcpd}
     7.9  }
     8.1 --- a/tools/examples/xmexample.vmx	Fri Dec 02 15:52:41 2005 -0600
     8.2 +++ b/tools/examples/xmexample.vmx	Sat Dec 03 10:44:38 2005 +0100
     8.3 @@ -30,8 +30,10 @@ name = "ExampleVMXDomain"
     8.4  # the number of cpus guest platform has, default=1
     8.5  vcpus=1
     8.6  
     8.7 -# Which CPU to start domain on? 
     8.8 -#cpu = -1   # leave to Xen to pick
     8.9 +# List of which CPUS this domain is allowed to use, default Xen picks
    8.10 +#cpus = ""         # leave to Xen to pick
    8.11 +#cpus = "0"        # all vcpus run on CPU0
    8.12 +#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
    8.13  
    8.14  # Optionally define mac and/or bridge for the network interfaces.
    8.15  # Random MACs are assigned if not given.
     9.1 --- a/tools/examples/xmexample.vti	Fri Dec 02 15:52:41 2005 -0600
     9.2 +++ b/tools/examples/xmexample.vti	Sat Dec 03 10:44:38 2005 +0100
     9.3 @@ -23,8 +23,10 @@ memory = 256
     9.4  # A name for your domain. All domains must have different names.
     9.5  name = "ExampleVMXDomain"
     9.6  
     9.7 -# Which CPU to start domain on? 
     9.8 -#cpu = -1   # leave to Xen to pick
     9.9 +# List of which CPUS this domain is allowed to use, default Xen picks
    9.10 +#cpus = ""         # leave to Xen to pick
    9.11 +#cpus = "0"        # all vcpus run on CPU0
    9.12 +#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
    9.13  
    9.14  # Disable vif for now
    9.15  nics=0
    10.1 --- a/tools/examples/xmexample1	Fri Dec 02 15:52:41 2005 -0600
    10.2 +++ b/tools/examples/xmexample1	Sat Dec 03 10:44:38 2005 +0100
    10.3 @@ -22,8 +22,10 @@ memory = 64
    10.4  # A name for your domain. All domains must have different names.
    10.5  name = "ExampleDomain"
    10.6  
    10.7 -# Which CPU to start domain on? 
    10.8 -#cpu = -1   # leave to Xen to pick
    10.9 +# List of which CPUS this domain is allowed to use, default Xen picks
   10.10 +#cpus = ""         # leave to Xen to pick
   10.11 +#cpus = "0"        # all vcpus run on CPU0
   10.12 +#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
   10.13  
   10.14  # Number of Virtual CPUS to use, default is 1
   10.15  #vcpus = 1
    11.1 --- a/tools/examples/xmexample2	Fri Dec 02 15:52:41 2005 -0600
    11.2 +++ b/tools/examples/xmexample2	Sat Dec 03 10:44:38 2005 +0100
    11.3 @@ -51,9 +51,11 @@ memory = 64
    11.4  # so we use the vmid to create a name.
    11.5  name = "VM%d" % vmid
    11.6  
    11.7 -# Which CPU to start domain on? 
    11.8 -#cpu = -1   # leave to Xen to pick
    11.9 -cpu = vmid  # set based on vmid (mod number of CPUs)
   11.10 +# List of which CPUS this domain is allowed to use, default Xen picks
   11.11 +#cpus = ""         # leave to Xen to pick
   11.12 +#cpus = "0"        # all vcpus run on CPU0
   11.13 +#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
   11.14 +#cpus = "%s" % vmid # set based on vmid (mod number of CPUs)
   11.15  
   11.16  # Number of Virtual CPUS to use, default is 1
   11.17  #vcpus = 1
    12.1 --- a/tools/examples/xmexample3	Fri Dec 02 15:52:41 2005 -0600
    12.2 +++ b/tools/examples/xmexample3	Sat Dec 03 10:44:38 2005 +0100
    12.3 @@ -51,9 +51,11 @@ memory = 64
    12.4  # so we use the vmid to create a name.
    12.5  name = "VM%d" % vmid
    12.6  
    12.7 -# Which CPU to start domain on? 
    12.8 -#cpu = -1   # leave to Xen to pick
    12.9 -cpu = vmid  # set based on vmid (mod number of CPUs)
   12.10 +# List of which CPUS this domain is allowed to use, default Xen picks
   12.11 +#cpus = ""         # leave to Xen to pick
   12.12 +#cpus = "0"        # all vcpus run on CPU0
   12.13 +#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
   12.14 +cpus = "%s" % vmid # set based on vmid (mod number of CPUs)
   12.15  
   12.16  #----------------------------------------------------------------------------
   12.17  # Define network interfaces.
    13.1 --- a/tools/python/xen/util/bugtool.py	Fri Dec 02 15:52:41 2005 -0600
    13.2 +++ b/tools/python/xen/util/bugtool.py	Sat Dec 03 10:44:38 2005 +0100
    13.3 @@ -41,9 +41,10 @@ ATTACH_PATTERN = \
    13.4  
    13.5  TITLE_RE = re.compile(r'<title>(.*)</title>')
    13.6  
    13.7 -FILES_TO_SEND = [ '/var/log/syslog', '/var/log/messages', '/var/log/debug',
    13.8 -                  '/var/log/xend.log', '/var/log/xend-debug.log',
    13.9 -                  '/var/log/xenstored-trace.log' ]
   13.10 +FILES_TO_SEND = [ '/var/log/' + x for x in 
   13.11 +                  [ 'syslog', 'messages', 'debug',
   13.12 +                    'xend.log', 'xend-debug.log', 'xenstored-trace.log',
   13.13 +                    'xen-hotplug.log' ] ]
   13.14  #FILES_TO_SEND = [  ]
   13.15  
   13.16  
    14.1 --- a/tools/python/xen/xend/XendDomain.py	Fri Dec 02 15:52:41 2005 -0600
    14.2 +++ b/tools/python/xen/xend/XendDomain.py	Sat Dec 03 10:44:38 2005 +0100
    14.3 @@ -36,6 +36,7 @@ from xen.xend import XendRoot
    14.4  from xen.xend import XendCheckpoint
    14.5  from xen.xend.XendError import XendError
    14.6  from xen.xend.XendLogging import log
    14.7 +from xen.xend.xenstore.xstransact import xstransact
    14.8  from xen.xend.xenstore.xswatch import xswatch
    14.9  
   14.10  
   14.11 @@ -46,6 +47,8 @@ xroot = XendRoot.instance()
   14.12  __all__ = [ "XendDomain" ]
   14.13  
   14.14  PRIV_DOMAIN = 0
   14.15 +VMROOT = '/vm/'
   14.16 +
   14.17  
   14.18  class XendDomain:
   14.19      """Index of all domains. Singleton.
   14.20 @@ -64,6 +67,9 @@ class XendDomain:
   14.21      # instance() must be able to return a valid instance of this class even
   14.22      # during this initialisation.
   14.23      def init(self):
   14.24 +        xstransact.Mkdir(VMROOT)
   14.25 +        xstransact.SetPermissions(VMROOT, { 'dom' : PRIV_DOMAIN })
   14.26 +
   14.27          self.domains_lock.acquire()
   14.28          try:
   14.29              self._add_domain(
    15.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Dec 02 15:52:41 2005 -0600
    15.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Sat Dec 03 10:44:38 2005 +0100
    15.3 @@ -43,7 +43,7 @@ import XendRoot
    15.4  from xen.xend.XendBootloader import bootloader
    15.5  from xen.xend.XendError import XendError, VmError
    15.6  
    15.7 -from xen.xend.xenstore.xstransact import xstransact
    15.8 +from xen.xend.xenstore.xstransact import xstransact, complete
    15.9  from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
   15.10  from xen.xend.xenstore.xswatch import xswatch
   15.11  
   15.12 @@ -84,8 +84,6 @@ STATE_DOM_SHUTDOWN = 2
   15.13  
   15.14  SHUTDOWN_TIMEOUT = 30
   15.15  
   15.16 -VMROOT  = '/vm/'
   15.17 -
   15.18  ZOMBIE_PREFIX = 'Zombie-'
   15.19  
   15.20  """Minimum time between domain restarts in seconds."""
   15.21 @@ -234,7 +232,7 @@ def recreate(xeninfo, priv):
   15.22              log.warn(str(exn))
   15.23  
   15.24          vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
   15.25 -        vm.removeDom()
   15.26 +        vm.recreateDom()
   15.27          vm.removeVm()
   15.28          vm.storeVmDetails()
   15.29          vm.storeDomDetails()
   15.30 @@ -288,6 +286,7 @@ def parseConfig(config):
   15.31          result[e[0]] = get_cfg(e[0], e[1])
   15.32  
   15.33      result['cpu']       = get_cfg('cpu',       int)
   15.34 +    result['cpus']      = get_cfg('cpus',      str)
   15.35      result['image']     = get_cfg('image')
   15.36  
   15.37      try:
   15.38 @@ -301,6 +300,43 @@ def parseConfig(config):
   15.39              'Invalid configuration setting: vcpus = %s: %s' %
   15.40              (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
   15.41  
   15.42 +    try:
   15.43 +        # support legacy config files with 'cpu' parameter
   15.44 +        # NB: prepending to list to support previous behavior
   15.45 +        #     where 'cpu' parameter pinned VCPU0.
   15.46 +        if result['cpu']:
   15.47 +           if result['cpus']:
   15.48 +               result['cpus'] = "%s,%s" % (str(result['cpu']), result['cpus'])
   15.49 +           else:
   15.50 +               result['cpus'] = str(result['cpu'])
   15.51 +
   15.52 +        # convert 'cpus' string to list of ints
   15.53 +        # 'cpus' supports a list of ranges (0-3), seperated by
   15.54 +        # commas, and negation, (^1).  
   15.55 +        # Precedence is settled by  order of the string:
   15.56 +        #     "0-3,^1"   -> [0,2,3]
   15.57 +        #     "0-3,^1,1" -> [0,1,2,3]
   15.58 +        if result['cpus']:
   15.59 +            cpus = []
   15.60 +            for c in result['cpus'].split(','):
   15.61 +                if c.find('-') != -1:             
   15.62 +                    (x,y) = c.split('-')
   15.63 +                    for i in range(int(x),int(y)+1):
   15.64 +                        cpus.append(int(i))
   15.65 +                else:
   15.66 +                    # remove this element from the list 
   15.67 +                    if c[0] == '^':
   15.68 +                        cpus = [x for x in cpus if x != int(c[1])]
   15.69 +                    else:
   15.70 +                        cpus.append(int(c))
   15.71 +
   15.72 +            result['cpus'] = cpus
   15.73 +        
   15.74 +    except ValueError, exn:
   15.75 +        raise VmError(
   15.76 +            'Invalid configuration setting: cpus = %s: %s' %
   15.77 +            (result['cpus'], exn))
   15.78 +
   15.79      result['backend'] = []
   15.80      for c in sxp.children(config, 'backend'):
   15.81          result['backend'].append(sxp.name(sxp.child0(c)))
   15.82 @@ -385,7 +421,7 @@ class XendDomainInfo:
   15.83          else:
   15.84              self.domid = None
   15.85  
   15.86 -        self.vmpath  = VMROOT + self.info['uuid']
   15.87 +        self.vmpath  = XendDomain.VMROOT + self.info['uuid']
   15.88          self.dompath = dompath
   15.89  
   15.90          if augment:
   15.91 @@ -488,6 +524,7 @@ class XendDomainInfo:
   15.92              defaultInfo('on_reboot',    lambda: "restart")
   15.93              defaultInfo('on_crash',     lambda: "restart")
   15.94              defaultInfo('cpu',          lambda: None)
   15.95 +            defaultInfo('cpus',         lambda: [])
   15.96              defaultInfo('cpu_weight',   lambda: 1.0)
   15.97  
   15.98              # some domains don't have a config file (e.g. dom0 )
   15.99 @@ -570,6 +607,14 @@ class XendDomainInfo:
  15.100      def removeDom(self, *args):
  15.101          return xstransact.Remove(self.dompath, *args)
  15.102  
  15.103 +    def recreateDom(self):
  15.104 +        complete(self.dompath, lambda t: self._recreateDom(t))
  15.105 +
  15.106 +    def _recreateDom(self, t):
  15.107 +        t.remove()
  15.108 +        t.mkdir()
  15.109 +        t.set_permissions({ 'dom' : self.domid })
  15.110 +
  15.111  
  15.112      ## private:
  15.113  
  15.114 @@ -769,7 +814,10 @@ class XendDomainInfo:
  15.115                      if reason == 'suspend':
  15.116                          self.state_set(STATE_DOM_SHUTDOWN)
  15.117                          # Don't destroy the domain.  XendCheckpoint will do
  15.118 -                        # this once it has finished.
  15.119 +                        # this once it has finished.  However, stop watching
  15.120 +                        # the VM path now, otherwise we will end up with one
  15.121 +                        # watch for the old domain, and one for the new.
  15.122 +                        self.unwatchVm()
  15.123                      elif reason in ['poweroff', 'reboot']:
  15.124                          restart_reason = reason
  15.125                      else:
  15.126 @@ -968,9 +1016,9 @@ class XendDomainInfo:
  15.127          if self.infoIsSet('image'):
  15.128              sxpr.append(['image', self.info['image']])
  15.129  
  15.130 -        if self.infoIsSet('device'):
  15.131 -            for (_, c) in self.info['device']:
  15.132 -                sxpr.append(['device', c])
  15.133 +        for cls in controllerClasses:
  15.134 +            for config in self.getDeviceConfigurations(cls):
  15.135 +                sxpr.append(['device', config])
  15.136  
  15.137          def stateChar(name):
  15.138              if name in self.info:
  15.139 @@ -1084,7 +1132,7 @@ class XendDomainInfo:
  15.140  
  15.141          self.dompath = GetDomainPath(self.domid)
  15.142  
  15.143 -        self.removeDom()
  15.144 +        self.recreateDom()
  15.145  
  15.146          # Set maximum number of vcpus in domain
  15.147          xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
  15.148 @@ -1121,9 +1169,15 @@ class XendDomainInfo:
  15.149              xc.domain_setmaxmem(self.domid, m)
  15.150              xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
  15.151  
  15.152 -            cpu = self.info['cpu']
  15.153 -            if cpu is not None and cpu != -1:
  15.154 -                xc.domain_pincpu(self.domid, 0, 1 << cpu)
  15.155 +            # repin domain vcpus if a restricted cpus list is provided
  15.156 +            # this is done prior to memory allocation to aide in memory
  15.157 +            # distribution for NUMA systems.
  15.158 +            cpus = self.info['cpus']
  15.159 +            if cpus is not None and len(cpus) > 0:
  15.160 +                for v in range(0, self.info['max_vcpu_id']+1):
  15.161 +                    # pincpu takes a list of ints
  15.162 +                    cpu = [ int( cpus[v % len(cpus)] ) ]
  15.163 +                    xc.domain_pincpu(self.domid, v, cpu)
  15.164  
  15.165              self.createChannels()
  15.166  
  15.167 @@ -1179,18 +1233,31 @@ class XendDomainInfo:
  15.168      def cleanupVm(self):
  15.169          """Cleanup VM resources.  Idempotent.  Nothrow guarantee."""
  15.170  
  15.171 +        self.unwatchVm()
  15.172 +
  15.173 +        try:
  15.174 +            self.removeVm()
  15.175 +        except:
  15.176 +            log.exception("Removing VM path failed.")
  15.177 +
  15.178 +
  15.179 +    ## private:
  15.180 +
  15.181 +    def unwatchVm(self):
  15.182 +        """Remove the watch on the VM path, if any.  Idempotent.  Nothrow
  15.183 +        guarantee."""
  15.184 +
  15.185          try:
  15.186              try:
  15.187                  if self.vmWatch:
  15.188                      self.vmWatch.unwatch()
  15.189 +            finally:
  15.190                  self.vmWatch = None
  15.191 -            except:
  15.192 -                log.exception("Unwatching VM path failed.")
  15.193 +        except:
  15.194 +            log.exception("Unwatching VM path failed.")
  15.195  
  15.196 -            self.removeVm()
  15.197 -        except:
  15.198 -            log.exception("Removing VM path failed.")
  15.199  
  15.200 +    ## public:
  15.201  
  15.202      def destroy(self):
  15.203          """Cleanup VM and destroy domain.  Nothrow guarantee."""
  15.204 @@ -1345,6 +1412,7 @@ class XendDomainInfo:
  15.205              if rename:
  15.206                  self.preserveForRestart()
  15.207              else:
  15.208 +                self.unwatchVm()
  15.209                  self.destroyDomain()
  15.210  
  15.211              # new_dom's VM will be the same as this domain's VM, except where
  15.212 @@ -1381,10 +1449,11 @@ class XendDomainInfo:
  15.213          log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
  15.214                   self.info['name'], self.domid, self.info['uuid'],
  15.215                   new_name, new_uuid)
  15.216 +        self.unwatchVm()
  15.217          self.release_devices()
  15.218          self.info['name'] = new_name
  15.219          self.info['uuid'] = new_uuid
  15.220 -        self.vmpath = VMROOT + new_uuid
  15.221 +        self.vmpath = XendDomain.VMROOT + new_uuid
  15.222          self.storeVmDetails()
  15.223          self.preserve()
  15.224  
  15.225 @@ -1392,6 +1461,7 @@ class XendDomainInfo:
  15.226      def preserve(self):
  15.227          log.info("Preserving dead domain %s (%d).", self.info['name'],
  15.228                   self.domid)
  15.229 +        self.unwatchVm()
  15.230          self.storeDom('xend/shutdown_completed', 'True')
  15.231          self.state_set(STATE_DOM_SHUTDOWN)
  15.232  
    16.1 --- a/tools/python/xen/xend/server/DevController.py	Fri Dec 02 15:52:41 2005 -0600
    16.2 +++ b/tools/python/xen/xend/server/DevController.py	Sat Dec 03 10:44:38 2005 +0100
    16.3 @@ -22,7 +22,7 @@ from xen.xend import sxp
    16.4  from xen.xend.XendError import VmError
    16.5  from xen.xend.XendLogging import log
    16.6  
    16.7 -from xen.xend.xenstore.xstransact import xstransact
    16.8 +from xen.xend.xenstore.xstransact import xstransact, complete
    16.9  from xen.xend.xenstore.xswatch import xswatch
   16.10  
   16.11  DEVICE_CREATE_TIMEOUT = 10
   16.12 @@ -85,6 +85,8 @@ class DevController:
   16.13          (backpath, frontpath) = self.addStoreEntries(config, devid, back,
   16.14                                                       front)
   16.15  
   16.16 +        import xen.xend.XendDomain
   16.17 +        count = 0
   16.18          while True:
   16.19              t = xstransact()
   16.20              try:
   16.21 @@ -97,19 +99,31 @@ class DevController:
   16.22                      
   16.23                      raise VmError("Device %s is already connected." % dev_str)
   16.24  
   16.25 -                log.debug('DevController: writing %s to %s.', str(front),
   16.26 -                          frontpath)
   16.27 -                log.debug('DevController: writing %s to %s.', str(back),
   16.28 -                          backpath)
   16.29 +                if count == 0:
   16.30 +                    log.debug('DevController: writing %s to %s.', str(front),
   16.31 +                              frontpath)
   16.32 +                    log.debug('DevController: writing %s to %s.', str(back),
   16.33 +                              backpath)
   16.34 +                elif count % 50 == 0:
   16.35 +                    log.debug(
   16.36 +                      'DevController: still waiting to write device entries.')
   16.37  
   16.38                  t.remove(frontpath)
   16.39                  t.remove(backpath)
   16.40  
   16.41 +                t.mkdir(backpath)
   16.42 +                t.set_permissions(backpath,
   16.43 +                                  {'dom': xen.xend.XendDomain.PRIV_DOMAIN },
   16.44 +                                  {'dom'  : self.vm.getDomid(),
   16.45 +                                   'read' : True })
   16.46 +
   16.47                  t.write2(frontpath, front)
   16.48                  t.write2(backpath,  back)
   16.49  
   16.50                  if t.commit():
   16.51                      return devid
   16.52 +
   16.53 +                count += 1
   16.54              except:
   16.55                  t.abort()
   16.56                  raise
   16.57 @@ -266,20 +280,17 @@ class DevController:
   16.58          the device configuration instead.
   16.59          """
   16.60          path = self.frontendMiscPath()
   16.61 -        while True:
   16.62 -            t = xstransact(path)
   16.63 -            try:
   16.64 -                result = t.read("nextDeviceID")
   16.65 -                if result:
   16.66 -                    result = int(result)
   16.67 -                else:
   16.68 -                    result = 0
   16.69 -                t.write("nextDeviceID", str(result + 1))
   16.70 -                if t.commit():
   16.71 -                    return result
   16.72 -            except:
   16.73 -                t.abort()
   16.74 -                raise
   16.75 +        return complete(path, self._allocateDeviceID)
   16.76 +
   16.77 +
   16.78 +    def _allocateDeviceID(self, t):
   16.79 +        result = t.read("nextDeviceID")
   16.80 +        if result:
   16.81 +            result = int(result)
   16.82 +        else:
   16.83 +            result = 0
   16.84 +        t.write("nextDeviceID", str(result + 1))
   16.85 +        return result
   16.86  
   16.87  
   16.88      def readBackend(self, devid, *args):
    17.1 --- a/tools/python/xen/xend/xenstore/xstransact.py	Fri Dec 02 15:52:41 2005 -0600
    17.2 +++ b/tools/python/xen/xend/xenstore/xstransact.py	Sat Dec 03 10:44:38 2005 +0100
    17.3 @@ -213,6 +213,27 @@ class xstransact:
    17.4                  self._write(key, fmt % val)
    17.5  
    17.6  
    17.7 +    def mkdir(self, *args):
    17.8 +        if len(args) == 0:
    17.9 +            xshandle().mkdir(self.transaction, self.path)
   17.10 +        else:
   17.11 +            for key in args:
   17.12 +                xshandle().mkdir(self.transaction, self.prependPath(key))
   17.13 +
   17.14 +
   17.15 +    def set_permissions(self, *args):
   17.16 +        if len(args) == 0:
   17.17 +            raise TypeError
   17.18 +        elif isinstance(args[0], str):
   17.19 +            self.callRebased(args[0], self.set_permissions, *args[1:])
   17.20 +        else:
   17.21 +            if not self.path:
   17.22 +                raise RuntimeError('Cannot set permissions on the root')
   17.23 +
   17.24 +            xshandle().set_permissions(self.transaction, self.path,
   17.25 +                                       list(args))
   17.26 +
   17.27 +
   17.28      def remove2(self, middlePath, *args):
   17.29          self.callRebased(middlePath, self.remove, *args)
   17.30  
   17.31 @@ -245,29 +266,11 @@ class xstransact:
   17.32          given path, and return a list composed of the values at each of those
   17.33          instead.  This operation is performed inside a transaction.
   17.34          """
   17.35 -        while True:
   17.36 -            t = cls(path)
   17.37 -            try:
   17.38 -                v = t.read(*args)
   17.39 -                t.abort()
   17.40 -                return v
   17.41 -            except:
   17.42 -                t.abort()
   17.43 -                raise
   17.44 -
   17.45 +        return complete(path, lambda t: t.read(*args))
   17.46      Read = classmethod(Read)
   17.47  
   17.48      def Write(cls, path, *args):
   17.49 -        while True:
   17.50 -            t = cls(path)
   17.51 -            try:
   17.52 -                t.write(*args)
   17.53 -                if t.commit():
   17.54 -                    return
   17.55 -            except:
   17.56 -                t.abort()
   17.57 -                raise
   17.58 -
   17.59 +        complete(path, lambda t: t.write(*args))
   17.60      Write = classmethod(Write)
   17.61  
   17.62      def Remove(cls, path, *args):
   17.63 @@ -275,16 +278,7 @@ class xstransact:
   17.64          each further argument as a subpath to the given path, and remove each
   17.65          of those instead.  This operation is performed inside a transaction.
   17.66          """
   17.67 -        while True:
   17.68 -            t = cls(path)
   17.69 -            try:
   17.70 -                t.remove(*args)
   17.71 -                if t.commit():
   17.72 -                    return
   17.73 -            except:
   17.74 -                t.abort()
   17.75 -                raise
   17.76 -
   17.77 +        complete(path, lambda t: t.remove(*args))
   17.78      Remove = classmethod(Remove)
   17.79  
   17.80      def List(cls, path, *args):
   17.81 @@ -294,16 +288,7 @@ class xstransact:
   17.82          and return the cumulative listing of each of those instead.  This
   17.83          operation is performed inside a transaction.
   17.84          """
   17.85 -        while True:
   17.86 -            t = cls(path)
   17.87 -            try:
   17.88 -                v = t.list(*args)
   17.89 -                if t.commit():
   17.90 -                    return v
   17.91 -            except:
   17.92 -                t.abort()
   17.93 -                raise
   17.94 -
   17.95 +        return complete(path, lambda t: t.list(*args))
   17.96      List = classmethod(List)
   17.97  
   17.98      def ListRecursive(cls, path, *args):
   17.99 @@ -313,40 +298,33 @@ class xstransact:
  17.100          subpath to the given path, and return the cumulative listing of each
  17.101          of those instead.  This operation is performed inside a transaction.
  17.102          """
  17.103 -        while True:
  17.104 -            t = cls(path)
  17.105 -            try:
  17.106 -                v = t.list_recursive(*args)
  17.107 -                if t.commit():
  17.108 -                    return v
  17.109 -            except:
  17.110 -                t.abort()
  17.111 -                raise
  17.112 -
  17.113 +        return complete(path, lambda t: t.list_recursive(*args))
  17.114      ListRecursive = classmethod(ListRecursive)
  17.115  
  17.116      def Gather(cls, path, *args):
  17.117 -        while True:
  17.118 -            t = cls(path)
  17.119 -            try:
  17.120 -                v = t.gather(*args)
  17.121 -                if t.commit():
  17.122 -                    return v
  17.123 -            except:
  17.124 -                t.abort()
  17.125 -                raise
  17.126 -
  17.127 +        return complete(path, lambda t: t.gather(*args))
  17.128      Gather = classmethod(Gather)
  17.129  
  17.130      def Store(cls, path, *args):
  17.131 -        while True:
  17.132 -            t = cls(path)
  17.133 -            try:
  17.134 -                v = t.store(*args)
  17.135 -                if t.commit():
  17.136 -                    return v
  17.137 -            except:
  17.138 -                t.abort()
  17.139 -                raise
  17.140 +        complete(path, lambda t: t.store(*args))
  17.141 +    Store = classmethod(Store)
  17.142 +
  17.143 +    def SetPermissions(cls, path, *args):
  17.144 +        complete(path, lambda t: t.set_permissions(*args))
  17.145 +    SetPermissions = classmethod(SetPermissions)
  17.146 +
  17.147 +    def Mkdir(cls, path, *args):
  17.148 +        complete(path, lambda t: t.mkdir(*args))
  17.149 +    Mkdir = classmethod(Mkdir)
  17.150  
  17.151 -    Store = classmethod(Store)
  17.152 +
  17.153 +def complete(path, f):
  17.154 +    while True:
  17.155 +        t = xstransact(path)
  17.156 +        try:
  17.157 +            result = f(t)
  17.158 +            if t.commit():
  17.159 +                return result
  17.160 +        except:
  17.161 +            t.abort()
  17.162 +            raise
    18.1 --- a/tools/python/xen/xm/create.py	Fri Dec 02 15:52:41 2005 -0600
    18.2 +++ b/tools/python/xen/xm/create.py	Sat Dec 03 10:44:38 2005 +0100
    18.3 @@ -154,7 +154,11 @@ gopts.var('maxmem', val='MEMORY',
    18.4  
    18.5  gopts.var('cpu', val='CPU',
    18.6            fn=set_int, default=None,
    18.7 -          use="CPU to run the domain on.")
    18.8 +          use="CPU to run the VCPU0 on.")
    18.9 +
   18.10 +gopts.var('cpus', val='CPUS',
   18.11 +          fn=set_int, default=None,
   18.12 +          use="CPUS to run the domain on.")
   18.13  
   18.14  gopts.var('lapic', val='LAPIC',
   18.15            fn=set_int, default=0,
   18.16 @@ -572,6 +576,8 @@ def make_config(vals):
   18.17      
   18.18      if vals.cpu is not None:
   18.19          config.append(['cpu', vals.cpu])
   18.20 +    if vals.cpus is not None:
   18.21 +        config.append(['cpus', vals.cpus])
   18.22      if vals.cpu_weight is not None:
   18.23          config.append(['cpu_weight', vals.cpu_weight])
   18.24      if vals.blkif:
    19.1 --- a/tools/python/xen/xm/main.py	Fri Dec 02 15:52:41 2005 -0600
    19.2 +++ b/tools/python/xen/xm/main.py	Sat Dec 03 10:44:38 2005 +0100
    19.3 @@ -459,7 +459,9 @@ def xm_vcpu_list(args):
    19.4              for x in server.xend_node()[1:]:
    19.5                  if len(x) > 1 and x[0] == 'nr_cpus':
    19.6                      nr_cpus = int(x[1])
    19.7 -                    cpumap = filter(lambda x: x < nr_cpus, cpumap)
    19.8 +                    # normalize cpumap by modulus nr_cpus, and drop duplicates
    19.9 +                    cpumap = dict.fromkeys(
   19.10 +                                map(lambda x: x % nr_cpus, cpumap)).keys()
   19.11                      if len(cpumap) == nr_cpus:
   19.12                          return "any cpu"
   19.13                      break
    20.1 --- a/tools/xenstore/xenstored_core.c	Fri Dec 02 15:52:41 2005 -0600
    20.2 +++ b/tools/xenstore/xenstored_core.c	Sat Dec 03 10:44:38 2005 +0100
    20.3 @@ -1401,7 +1401,7 @@ void dump_connection(void)
    20.4  static void manual_node(const char *name, const char *child)
    20.5  {
    20.6  	struct node *node;
    20.7 -	struct xs_permissions perms = { .id = 0, .perms = XS_PERM_READ };
    20.8 +	struct xs_permissions perms = { .id = 0, .perms = XS_PERM_NONE };
    20.9  
   20.10  	node = talloc(NULL, struct node);
   20.11  	node->name = name;
   20.12 @@ -1442,6 +1442,7 @@ static void setup_structure(void)
   20.13  		   the balloon driver, this can be fatal.
   20.14  		*/
   20.15  		internal_rm("/local");
   20.16 +		manual_node("/", "local");
   20.17  	}
   20.18  	else {
   20.19  		tdb_ctx = tdb_open(tdbname, 7919, TDB_FLAGS, O_RDWR|O_CREAT,
    21.1 --- a/tools/xenstore/xenstored_domain.c	Fri Dec 02 15:52:41 2005 -0600
    21.2 +++ b/tools/xenstore/xenstored_domain.c	Sat Dec 03 10:44:38 2005 +0100
    21.3 @@ -287,6 +287,7 @@ static struct domain *new_domain(void *c
    21.4  
    21.5  	domain->conn = new_connection(writechn, readchn);
    21.6  	domain->conn->domain = domain;
    21.7 +	domain->conn->id = domid;
    21.8  
    21.9  	domain->remote_port = port;
   21.10  	domain->mfn = mfn;
    22.1 --- a/tools/xm-test/tests/network-attach/network_utils.py	Fri Dec 02 15:52:41 2005 -0600
    22.2 +++ b/tools/xm-test/tests/network-attach/network_utils.py	Sat Dec 03 10:44:38 2005 +0100
    22.3 @@ -28,7 +28,7 @@ def network_detach(domain_name, console,
    22.4      eths_before = count_eth(console)
    22.5      status, output = traceCommand("xm network-detach %s %d" % (domain_name, num))
    22.6      if status != 0:
    22.7 -        return -1, "xm network-attach returned invalid %i != 0" % status
    22.8 +        return -1, "xm network-detach returned invalid %i != 0" % status
    22.9  
   22.10      eths_after = count_eth(console)
   22.11      if eths_after != (eths_before-1):
    23.1 --- a/xen/arch/x86/Makefile	Fri Dec 02 15:52:41 2005 -0600
    23.2 +++ b/xen/arch/x86/Makefile	Sat Dec 03 10:44:38 2005 +0100
    23.3 @@ -37,7 +37,8 @@ endif
    23.4  default: $(TARGET)
    23.5  
    23.6  $(TARGET): $(TARGET)-syms boot/mkelf32
    23.7 -	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000
    23.8 +	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
    23.9 +	`nm $(TARGET)-syms | sort | tail -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
   23.10  
   23.11  $(CURDIR)/arch.o: $(OBJS)
   23.12  	$(LD) $(LDFLAGS) -r -o $@ $(OBJS)
    24.1 --- a/xen/arch/x86/boot/mkelf32.c	Fri Dec 02 15:52:41 2005 -0600
    24.2 +++ b/xen/arch/x86/boot/mkelf32.c	Sat Dec 03 10:44:38 2005 +0100
    24.3 @@ -222,6 +222,7 @@ static void do_read(int fd, void *data, 
    24.4  
    24.5  int main(int argc, char **argv)
    24.6  {
    24.7 +    u64        final_exec_addr;
    24.8      u32        loadbase, dat_siz, mem_siz;
    24.9      char      *inimage, *outimage;
   24.10      int        infd, outfd;
   24.11 @@ -234,15 +235,17 @@ int main(int argc, char **argv)
   24.12      Elf64_Ehdr in64_ehdr;
   24.13      Elf64_Phdr in64_phdr;
   24.14  
   24.15 -    if ( argc != 4 )
   24.16 +    if ( argc != 5 )
   24.17      {
   24.18 -        fprintf(stderr, "Usage: mkelf32 <in-image> <out-image> <load-base>\n");
   24.19 +        fprintf(stderr, "Usage: mkelf32 <in-image> <out-image> "
   24.20 +                "<load-base> <final-exec-addr>\n");
   24.21          return 1;
   24.22      }
   24.23  
   24.24      inimage  = argv[1];
   24.25      outimage = argv[2];
   24.26      loadbase = strtoul(argv[3], NULL, 16);
   24.27 +    final_exec_addr = strtoul(argv[4], NULL, 16);
   24.28  
   24.29      infd = open(inimage, O_RDONLY);
   24.30      if ( infd == -1 )
   24.31 @@ -286,7 +289,10 @@ int main(int argc, char **argv)
   24.32  
   24.33          (void)lseek(infd, in32_phdr.p_offset, SEEK_SET);
   24.34          dat_siz = (u32)in32_phdr.p_filesz;
   24.35 -        mem_siz = (u32)in32_phdr.p_memsz;
   24.36 +
   24.37 +        /* Do not use p_memsz: it does not include BSS alignment padding. */
   24.38 +        /*mem_siz = (u32)in32_phdr.p_memsz;*/
   24.39 +        mem_siz = (u32)(final_exec_addr - in32_phdr.p_vaddr);
   24.40          break;
   24.41  
   24.42      case ELFCLASS64:
   24.43 @@ -314,7 +320,10 @@ int main(int argc, char **argv)
   24.44  
   24.45          (void)lseek(infd, in64_phdr.p_offset, SEEK_SET);
   24.46          dat_siz = (u32)in64_phdr.p_filesz;
   24.47 -        mem_siz = (u32)in64_phdr.p_memsz;
   24.48 +
   24.49 +        /* Do not use p_memsz: it does not include BSS alignment padding. */
   24.50 +        /*mem_siz = (u32)in64_phdr.p_memsz;*/
   24.51 +        mem_siz = (u32)(final_exec_addr - in64_phdr.p_vaddr);
   24.52          break;
   24.53  
   24.54      default:
    25.1 --- a/xen/arch/x86/boot/x86_32.S	Fri Dec 02 15:52:41 2005 -0600
    25.2 +++ b/xen/arch/x86/boot/x86_32.S	Sat Dec 03 10:44:38 2005 +0100
    25.3 @@ -74,10 +74,6 @@ 1:      lss     stack_start-__PAGE_OFFSE
    25.4          cmp     $0x2BADB002,%eax
    25.5          jne     not_multiboot
    25.6  
    25.7 -        /* Save the Multiboot info structure for later use. */
    25.8 -	add     $__PAGE_OFFSET,%ebx
    25.9 -        push    %ebx
   25.10 -
   25.11          /* Initialize BSS (no nasty surprises!) */
   25.12          mov     $__bss_start-__PAGE_OFFSET,%edi
   25.13          mov     $_end-__PAGE_OFFSET,%ecx
   25.14 @@ -85,6 +81,10 @@ 1:      lss     stack_start-__PAGE_OFFSE
   25.15          xor     %eax,%eax
   25.16          rep     stosb
   25.17  
   25.18 +        /* Save the Multiboot info structure for later use. */
   25.19 +        add     $__PAGE_OFFSET,%ebx
   25.20 +        push    %ebx
   25.21 +
   25.22  #ifdef CONFIG_X86_PAE
   25.23          /* Initialize low and high mappings of all memory with 2MB pages */
   25.24          mov     $idle_pg_table_l2-__PAGE_OFFSET,%edi
   25.25 @@ -238,27 +238,28 @@ ENTRY(gdt_table)
   25.26          .fill 2*NR_CPUS,8,0          /* space for TSS and LDT per CPU    */
   25.27  
   25.28          .org 0x2000
   25.29 -/* Maximum STACK_ORDER for x86/32 is 1. We must therefore ensure that the */
   25.30 -/* CPU0 stack is aligned on an even page boundary!                        */
   25.31 -ENTRY(cpu0_stack)
   25.32 -        .org 0x2000 + STACK_SIZE
   25.33  
   25.34  #ifdef CONFIG_X86_PAE
   25.35 -
   25.36  ENTRY(idle_pg_table)
   25.37  ENTRY(idle_pg_table_l3)
   25.38 -        .quad 0x100000 + 0x2000 + STACK_SIZE + 1*PAGE_SIZE + 0x01
   25.39 -        .quad 0x100000 + 0x2000 + STACK_SIZE + 2*PAGE_SIZE + 0x01
   25.40 -        .quad 0x100000 + 0x2000 + STACK_SIZE + 3*PAGE_SIZE + 0x01
   25.41 -        .quad 0x100000 + 0x2000 + STACK_SIZE + 4*PAGE_SIZE + 0x01
   25.42 -        .org 0x2000 + STACK_SIZE + 1*PAGE_SIZE
   25.43 +        .long idle_pg_table_l2 + 0*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
   25.44 +        .long idle_pg_table_l2 + 1*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
   25.45 +        .long idle_pg_table_l2 + 2*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
   25.46 +        .long idle_pg_table_l2 + 3*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
   25.47 +.section ".bss.page_aligned","w"
   25.48  ENTRY(idle_pg_table_l2)
   25.49 -        .org 0x2000 + STACK_SIZE + 5*PAGE_SIZE
   25.50 +        .fill 4*PAGE_SIZE,1,0
   25.51 +#else
   25.52 +.section ".bss.page_aligned","w"
   25.53 +ENTRY(idle_pg_table)
   25.54 +ENTRY(idle_pg_table_l2)
   25.55 +        .fill 1*PAGE_SIZE,1,0
   25.56 +#endif
   25.57  
   25.58 -#else /* CONFIG_X86_PAE */
   25.59 -
   25.60 -ENTRY(idle_pg_table)
   25.61 -ENTRY(idle_pg_table_l2) # Initial page directory is 4kB
   25.62 -        .org 0x2000 + STACK_SIZE + PAGE_SIZE
   25.63 -
   25.64 -#endif /* CONFIG_X86_PAE */
   25.65 +#if (STACK_ORDER == 0)
   25.66 +.section ".bss.page_aligned","w"
   25.67 +#else
   25.68 +.section ".bss.twopage_aligned","w"
   25.69 +#endif
   25.70 +ENTRY(cpu0_stack)
   25.71 +        .fill STACK_SIZE,1,0
    26.1 --- a/xen/arch/x86/boot/x86_64.S	Fri Dec 02 15:52:41 2005 -0600
    26.2 +++ b/xen/arch/x86/boot/x86_64.S	Sat Dec 03 10:44:38 2005 +0100
    26.3 @@ -249,13 +249,8 @@ ENTRY(idle_pg_table_4)
    26.4  ENTRY(idle_pg_table_l3)
    26.5          .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
    26.6  
    26.7 +/* Initial PDE -- level-2 page table. Maps first 64MB physical memory. */
    26.8          .org 0x4000
    26.9 -/* Maximum STACK_ORDER for x86/64 is 2. We must therefore ensure that the */
   26.10 -/* CPU0 stack is aligned on a 4-page boundary.                            */
   26.11 -ENTRY(cpu0_stack)
   26.12 -
   26.13 -/* Initial PDE -- level-2 page table. Maps first 64MB physical memory. */
   26.14 -        .org 0x4000 + STACK_SIZE
   26.15  ENTRY(idle_pg_table_l2)
   26.16          .macro identmap from=0, count=32
   26.17          .if \count-1
   26.18 @@ -265,7 +260,15 @@ ENTRY(idle_pg_table_l2)
   26.19          .quad 0x00000000000001e3 + \from
   26.20          .endif
   26.21          .endm
   26.22 -        identmap /* Too orangey for crows :-) */
   26.23 +        identmap
   26.24 +
   26.25 +        .org 0x4000 + PAGE_SIZE
   26.26 +        .code64
   26.27  
   26.28 -        .org 0x4000 + STACK_SIZE + PAGE_SIZE
   26.29 -        .code64
   26.30 +#if (STACK_ORDER == 0)
   26.31 +.section ".bss.page_aligned","w"
   26.32 +#else
   26.33 +.section ".bss.twopage_aligned","w"
   26.34 +#endif
   26.35 +ENTRY(cpu0_stack)
   26.36 +        .fill STACK_SIZE,1,0
    27.1 --- a/xen/arch/x86/mm.c	Fri Dec 02 15:52:41 2005 -0600
    27.2 +++ b/xen/arch/x86/mm.c	Sat Dec 03 10:44:38 2005 +0100
    27.3 @@ -128,8 +128,9 @@ static int mod_l1_entry(l1_pgentry_t *, 
    27.4  
    27.5  /* Used to defer flushing of memory structures. */
    27.6  static struct {
    27.7 -#define DOP_FLUSH_TLB   (1<<0) /* Flush the TLB.                 */
    27.8 -#define DOP_RELOAD_LDT  (1<<1) /* Reload the LDT shadow mapping. */
    27.9 +#define DOP_FLUSH_TLB      (1<<0) /* Flush the local TLB.                    */
   27.10 +#define DOP_FLUSH_ALL_TLBS (1<<1) /* Flush TLBs of all VCPUs of current dom. */
   27.11 +#define DOP_RELOAD_LDT     (1<<2) /* Reload the LDT shadow mapping.          */
   27.12      unsigned int   deferred_ops;
   27.13      /* If non-NULL, specifies a foreign subject domain for some operations. */
   27.14      struct domain *foreign;
   27.15 @@ -1323,14 +1324,28 @@ void free_page_type(struct pfn_info *pag
   27.16      struct domain *owner = page_get_owner(page);
   27.17      unsigned long gpfn;
   27.18  
   27.19 -    if ( unlikely((owner != NULL) && shadow_mode_enabled(owner)) )
   27.20 +    if ( likely(owner != NULL) )
   27.21      {
   27.22 -        mark_dirty(owner, page_to_pfn(page));
   27.23 -        if ( unlikely(shadow_mode_refcounts(owner)) )
   27.24 -            return;
   27.25 -        gpfn = __mfn_to_gpfn(owner, page_to_pfn(page));
   27.26 -        ASSERT(VALID_M2P(gpfn));
   27.27 -        remove_shadow(owner, gpfn, type & PGT_type_mask);
   27.28 +        /*
   27.29 +         * We have to flush before the next use of the linear mapping
   27.30 +         * (e.g., update_va_mapping()) or we could end up modifying a page
   27.31 +         * that is no longer a page table (and hence screw up ref counts).
   27.32 +         */
   27.33 +        percpu_info[smp_processor_id()].deferred_ops |= DOP_FLUSH_ALL_TLBS;
   27.34 +
   27.35 +        if ( unlikely(shadow_mode_enabled(owner)) )
   27.36 +        {
   27.37 +            /* Raw page tables are rewritten during save/restore. */
   27.38 +            if ( !shadow_mode_translate(owner) )
   27.39 +                mark_dirty(owner, page_to_pfn(page));
   27.40 +
   27.41 +            if ( shadow_mode_refcounts(owner) )
   27.42 +                return;
   27.43 +
   27.44 +            gpfn = __mfn_to_gpfn(owner, page_to_pfn(page));
   27.45 +            ASSERT(VALID_M2P(gpfn));
   27.46 +            remove_shadow(owner, gpfn, type & PGT_type_mask);
   27.47 +        }
   27.48      }
   27.49  
   27.50      switch ( type & PGT_type_mask )
   27.51 @@ -1600,11 +1615,14 @@ static void process_deferred_ops(unsigne
   27.52      deferred_ops = percpu_info[cpu].deferred_ops;
   27.53      percpu_info[cpu].deferred_ops = 0;
   27.54  
   27.55 -    if ( deferred_ops & DOP_FLUSH_TLB )
   27.56 +    if ( deferred_ops & (DOP_FLUSH_ALL_TLBS|DOP_FLUSH_TLB) )
   27.57      {
   27.58          if ( shadow_mode_enabled(d) )
   27.59              shadow_sync_all(d);
   27.60 -        local_flush_tlb();
   27.61 +        if ( deferred_ops & DOP_FLUSH_ALL_TLBS )
   27.62 +            flush_tlb_mask(d->cpumask);
   27.63 +        else
   27.64 +            local_flush_tlb();
   27.65      }
   27.66          
   27.67      if ( deferred_ops & DOP_RELOAD_LDT )
    28.1 --- a/xen/arch/x86/x86_32/xen.lds	Fri Dec 02 15:52:41 2005 -0600
    28.2 +++ b/xen/arch/x86/x86_32/xen.lds	Sat Dec 03 10:44:38 2005 +0100
    28.3 @@ -23,7 +23,6 @@ SECTIONS
    28.4    _etext = .;			/* End of text section */
    28.5  
    28.6    .rodata : { *(.rodata) *(.rodata.*) } :text
    28.7 -  .kstrtab : { *(.kstrtab) } :text
    28.8  
    28.9    . = ALIGN(32);		/* Exception table */
   28.10    __start___ex_table = .;
   28.11 @@ -35,24 +34,11 @@ SECTIONS
   28.12    __pre_ex_table : { *(__pre_ex_table) } :text
   28.13    __stop___pre_ex_table = .;
   28.14  
   28.15 -  __start___ksymtab = .;	/* Kernel symbol table */
   28.16 -  __ksymtab : { *(__ksymtab) } :text
   28.17 -  __stop___ksymtab = .;
   28.18 -
   28.19 -  __start___kallsyms = .;	/* All kernel symbols */
   28.20 -  __kallsyms : { *(__kallsyms) } :text
   28.21 -  __stop___kallsyms = .;
   28.22 -
   28.23    .data : {			/* Data */
   28.24  	*(.data)
   28.25  	CONSTRUCTORS
   28.26  	} :text
   28.27  
   28.28 -  _edata = .;			/* End of data section */
   28.29 -
   28.30 -  . = ALIGN(8192);		/* init_task */
   28.31 -  .data.init_task : { *(.data.init_task) } :text
   28.32 -
   28.33    . = ALIGN(4096);		/* Init code and data */
   28.34    __init_begin = .;
   28.35    .text.init : { *(.text.init) } :text
   28.36 @@ -64,10 +50,13 @@ SECTIONS
   28.37    __initcall_start = .;
   28.38    .initcall.init : { *(.initcall.init) } :text
   28.39    __initcall_end = .;
   28.40 +  . = ALIGN(8192);
   28.41    __init_end = .;
   28.42  
   28.43    __bss_start = .;		/* BSS */
   28.44    .bss : {
   28.45 +	*(.bss.twopage_aligned)
   28.46 +	*(.bss.page_aligned)
   28.47  	*(.bss)
   28.48  	} :text
   28.49    _end = . ;
    29.1 --- a/xen/arch/x86/x86_64/xen.lds	Fri Dec 02 15:52:41 2005 -0600
    29.2 +++ b/xen/arch/x86/x86_64/xen.lds	Sat Dec 03 10:44:38 2005 +0100
    29.3 @@ -21,7 +21,6 @@ SECTIONS
    29.4    _etext = .;			/* End of text section */
    29.5  
    29.6    .rodata : { *(.rodata) *(.rodata.*) } :text
    29.7 -  .kstrtab : { *(.kstrtab) } :text
    29.8  
    29.9    . = ALIGN(32);		/* Exception table */
   29.10    __start___ex_table = .;
   29.11 @@ -33,24 +32,11 @@ SECTIONS
   29.12    __pre_ex_table : { *(__pre_ex_table) } :text
   29.13    __stop___pre_ex_table = .;
   29.14  
   29.15 -  __start___ksymtab = .;	/* Kernel symbol table */
   29.16 -  __ksymtab : { *(__ksymtab) } :text
   29.17 -  __stop___ksymtab = .;
   29.18 -
   29.19 -  __start___kallsyms = .;	/* All kernel symbols */
   29.20 -  __kallsyms : { *(__kallsyms) } :text
   29.21 -  __stop___kallsyms = .;
   29.22 -
   29.23    .data : {			/* Data */
   29.24  	*(.data)
   29.25  	CONSTRUCTORS
   29.26  	} :text
   29.27  
   29.28 -  _edata = .;			/* End of data section */
   29.29 -
   29.30 -  . = ALIGN(8192);		/* init_task */
   29.31 -  .data.init_task : { *(.data.init_task) } :text
   29.32 -
   29.33    . = ALIGN(4096);		/* Init code and data */
   29.34    __init_begin = .;
   29.35    .text.init : { *(.text.init) } :text
   29.36 @@ -62,10 +48,13 @@ SECTIONS
   29.37    __initcall_start = .;
   29.38    .initcall.init : { *(.initcall.init) } :text
   29.39    __initcall_end = .;
   29.40 +  . = ALIGN(8192);
   29.41    __init_end = .;
   29.42  
   29.43    __bss_start = .;		/* BSS */
   29.44    .bss : {
   29.45 +	*(.bss.twopage_aligned)
   29.46 +	*(.bss.page_aligned)
   29.47  	*(.bss)
   29.48  	} :text
   29.49    _end = . ;