ia64/xen-unstable

changeset 10718:3cdb93867f81

Domain ID/index mapping in xenmon.

This patch addresses the problem of xenbaked/xenmon not dealing with
large domain ID's. Xen Domain ID's increase monotonically as domains
are created; The ID's are not (often) recycled. Xenbaked was using the
domain
ID's as indices to arrays of data, and this scheme blows up as soon as
a domain ID exceeds the array size. Code has been changed in xenbaked
and xenmon to isolate domain id's from array indices, so everything is
indirect. Users should not notice any difference in behavior.

From: Rob Gardner <rob.gardner@hp.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Jul 10 16:09:20 2006 +0100 (2006-07-10)
parents b875c036839f
children e05d60be5adb
files tools/xenmon/xenbaked.c tools/xenmon/xenmon.py
line diff
     1.1 --- a/tools/xenmon/xenbaked.c	Mon Jul 10 16:05:44 2006 +0100
     1.2 +++ b/tools/xenmon/xenbaked.c	Mon Jul 10 16:09:20 2006 +0100
     1.3 @@ -95,6 +95,8 @@ int dom0_flips = 0;
     1.4  _new_qos_data *new_qos;
     1.5  _new_qos_data **cpu_qos_data;
     1.6  
     1.7 +int global_cpu;
     1.8 +uint64_t global_now;
     1.9  
    1.10  // array of currently running domains, indexed by cpu
    1.11  int *running = NULL;
    1.12 @@ -678,7 +680,7 @@ const struct argp parser_def =
    1.13  };
    1.14  
    1.15  
    1.16 -const char *argp_program_version     = "xenbaked v1.3";
    1.17 +const char *argp_program_version     = "xenbaked v1.4";
    1.18  const char *argp_program_bug_address = "<rob.gardner@hp.com>";
    1.19  
    1.20  
    1.21 @@ -715,16 +717,117 @@ int main(int argc, char **argv)
    1.22      return ret;
    1.23  }
    1.24  
    1.25 +void qos_init_domain(int domid, int idx)
    1.26 +{
    1.27 +  int i;
    1.28 +
    1.29 +  memset(&new_qos->domain_info[idx], 0, sizeof(_domain_info));
    1.30 +  new_qos->domain_info[idx].last_update_time = global_now;
    1.31 +  //  runnable_start_time[idx] = 0;
    1.32 +  new_qos->domain_info[idx].runnable_start_time = 0; // invalidate
    1.33 +  new_qos->domain_info[idx].in_use = 1;
    1.34 +  new_qos->domain_info[idx].blocked_start_time = 0;
    1.35 +  new_qos->domain_info[idx].id = domid;
    1.36 +  if (domid == IDLE_DOMAIN_ID)
    1.37 +    sprintf(new_qos->domain_info[idx].name, "Idle Task%d", global_cpu);
    1.38 +  else
    1.39 +    sprintf(new_qos->domain_info[idx].name, "Domain#%d", domid);
    1.40 +  
    1.41 +  for (i=0; i<NSAMPLES; i++) {
    1.42 +    new_qos->qdata[i].ns_gotten[idx] = 0;
    1.43 +    new_qos->qdata[i].ns_allocated[idx] = 0;
    1.44 +    new_qos->qdata[i].ns_waiting[idx] = 0;
    1.45 +    new_qos->qdata[i].ns_blocked[idx] = 0;
    1.46 +    new_qos->qdata[i].switchin_count[idx] = 0;
    1.47 +    new_qos->qdata[i].io_count[idx] = 0;
    1.48 +  }
    1.49 +}
    1.50 +
    1.51 +void global_init_domain(int domid, int idx) 
    1.52 +{
    1.53 +  int cpu;
    1.54 +  _new_qos_data *saved_qos;
    1.55 +  
    1.56 +  saved_qos = new_qos;
    1.57 +  
    1.58 +  for (cpu=0; cpu<NCPU; cpu++) {
    1.59 +    new_qos = cpu_qos_data[cpu];
    1.60 +    qos_init_domain(domid, idx);
    1.61 +  }
    1.62 +  new_qos = saved_qos;
    1.63 +}
    1.64 +
    1.65 +
    1.66 +// give index of this domain in the qos data array
    1.67 +int indexof(int domid)
    1.68 +{
    1.69 +  int idx;
    1.70 +  xc_dominfo_t dominfo[NDOMAINS];
    1.71 +  int xc_handle, ndomains;
    1.72 +  extern void qos_kill_thread(int domid);
    1.73 +  
    1.74 +  if (domid < 0 || domid >= NDOMAINS) {	// shouldn't happen
    1.75 +    if (domid != IDLE_DOMAIN_ID) {
    1.76 +      printf("bad domain id: %d\r\n", domid);
    1.77 +      return 0;
    1.78 +    }
    1.79 +  }
    1.80 +
    1.81 +  for (idx=0; idx<NDOMAINS; idx++)
    1.82 +    if ( (new_qos->domain_info[idx].id == domid) && new_qos->domain_info[idx].in_use)
    1.83 +      return idx;
    1.84 +
    1.85 +  // not found, make a new entry
    1.86 +  for (idx=0; idx<NDOMAINS; idx++)
    1.87 +    if (new_qos->domain_info[idx].in_use == 0) {
    1.88 +      global_init_domain(domid, idx);
    1.89 +      return idx;
    1.90 +    }
    1.91 +
    1.92 +  // call domaininfo hypercall to try and garbage collect unused entries
    1.93 +  xc_handle = xc_interface_open();
    1.94 +  ndomains = xc_domain_getinfo(xc_handle, 0, NDOMAINS, dominfo);
    1.95 +  xc_interface_close(xc_handle);
    1.96 +
    1.97 +  // for each domain in our data, look for it in the system dominfo structure
    1.98 +  // and purge the domain's data from our state if it does not exist in the
    1.99 +  // dominfo structure
   1.100 +  for (idx=0; idx<NDOMAINS; idx++) {
   1.101 +    int domid = new_qos->domain_info[idx].id;
   1.102 +    int jdx;
   1.103 +    
   1.104 +    for (jdx=0; jdx<ndomains; jdx++) {
   1.105 +      if (dominfo[jdx].domid == domid)
   1.106 +	break;
   1.107 +    }
   1.108 +    if (jdx == ndomains)        // we didn't find domid in the dominfo struct
   1.109 +      if (domid != IDLE_DOMAIN_ID) // exception for idle domain, which is not
   1.110 +	                           // contained in dominfo
   1.111 +	qos_kill_thread(domid);	// purge our stale data
   1.112 +  }
   1.113 +  
   1.114 +  // look again for a free slot
   1.115 +  for (idx=0; idx<NDOMAINS; idx++)
   1.116 +    if (new_qos->domain_info[idx].in_use == 0) {
   1.117 +      global_init_domain(domid, idx);
   1.118 +      return idx;
   1.119 +    }
   1.120 +
   1.121 +  // still no space found, so bail
   1.122 +  fprintf(stderr, "out of space in domain table, increase NDOMAINS\r\n");
   1.123 +  exit(2);
   1.124 +}
   1.125 +
   1.126  int domain_runnable(int domid)
   1.127  {
   1.128 -    return new_qos->domain_info[ID(domid)].runnable;
   1.129 +    return new_qos->domain_info[indexof(domid)].runnable;
   1.130  }
   1.131  
   1.132  
   1.133  void update_blocked_time(int domid, uint64_t now)
   1.134  {
   1.135      uint64_t t_blocked;
   1.136 -    int id = ID(domid);
   1.137 +    int id = indexof(domid);
   1.138  
   1.139      if (new_qos->domain_info[id].blocked_start_time != 0) {
   1.140          if (now >= new_qos->domain_info[id].blocked_start_time)
   1.141 @@ -734,7 +837,7 @@ void update_blocked_time(int domid, uint
   1.142          new_qos->qdata[new_qos->next_datapoint].ns_blocked[id] += t_blocked;
   1.143      }
   1.144  
   1.145 -    if (domain_runnable(id))
   1.146 +    if (domain_runnable(domid))
   1.147          new_qos->domain_info[id].blocked_start_time = 0;
   1.148      else
   1.149          new_qos->domain_info[id].blocked_start_time = now;
   1.150 @@ -773,7 +876,7 @@ void qos_update_thread(int cpu, int domi
   1.151      uint64_t last_update_time, start;
   1.152      int64_t time_since_update, run_time = 0;
   1.153  
   1.154 -    id = ID(domid);
   1.155 +    id = indexof(domid);
   1.156  
   1.157      n = new_qos->next_datapoint;
   1.158      last_update_time = new_qos->domain_info[id].last_update_time;
   1.159 @@ -851,7 +954,7 @@ void qos_update_all(uint64_t now, int cp
   1.160  
   1.161      for (i=0; i<NDOMAINS; i++)
   1.162          if (new_qos->domain_info[i].in_use)
   1.163 -            qos_update_thread(cpu, i, now);
   1.164 +            qos_update_thread(cpu, new_qos->domain_info[i].id, now); 
   1.165  }
   1.166  
   1.167  
   1.168 @@ -866,69 +969,37 @@ void qos_update_thread_stats(int cpu, in
   1.169  }
   1.170  
   1.171  
   1.172 -void qos_init_domain(int cpu, int domid, uint64_t now)
   1.173 -{
   1.174 -    int i, id;
   1.175 -
   1.176 -    id = ID(domid);
   1.177 -
   1.178 -    if (new_qos->domain_info[id].in_use)
   1.179 -        return;
   1.180 -
   1.181 -
   1.182 -    memset(&new_qos->domain_info[id], 0, sizeof(_domain_info));
   1.183 -    new_qos->domain_info[id].last_update_time = now;
   1.184 -    //  runnable_start_time[id] = 0;
   1.185 -    new_qos->domain_info[id].runnable_start_time = 0; // invalidate
   1.186 -    new_qos->domain_info[id].in_use = 1;
   1.187 -    new_qos->domain_info[id].blocked_start_time = 0;
   1.188 -    new_qos->domain_info[id].id = id;
   1.189 -    if (domid == IDLE_DOMAIN_ID)
   1.190 -        sprintf(new_qos->domain_info[id].name, "Idle Task%d", cpu);
   1.191 -    else
   1.192 -        sprintf(new_qos->domain_info[id].name, "Domain#%d", domid);
   1.193 -
   1.194 -    for (i=0; i<NSAMPLES; i++) {
   1.195 -        new_qos->qdata[i].ns_gotten[id] = 0;
   1.196 -        new_qos->qdata[i].ns_allocated[id] = 0;
   1.197 -        new_qos->qdata[i].ns_waiting[id] = 0;
   1.198 -        new_qos->qdata[i].ns_blocked[id] = 0;
   1.199 -        new_qos->qdata[i].switchin_count[id] = 0;
   1.200 -        new_qos->qdata[i].io_count[id] = 0;
   1.201 -    }
   1.202 -}
   1.203 -
   1.204  
   1.205  // called when a new thread gets the cpu
   1.206  void qos_switch_in(int cpu, int domid, uint64_t now, unsigned long ns_alloc, unsigned long ns_waited)
   1.207  {
   1.208 -    int id = ID(domid);
   1.209 +    int idx = indexof(domid);
   1.210  
   1.211 -    new_qos->domain_info[id].runnable = 1;
   1.212 +    new_qos->domain_info[idx].runnable = 1;
   1.213      update_blocked_time(domid, now);
   1.214 -    new_qos->domain_info[id].blocked_start_time = 0; // invalidate
   1.215 -    new_qos->domain_info[id].runnable_start_time = 0; // invalidate
   1.216 -    //runnable_start_time[id] = 0;
   1.217 +    new_qos->domain_info[idx].blocked_start_time = 0; // invalidate
   1.218 +    new_qos->domain_info[idx].runnable_start_time = 0; // invalidate
   1.219 +    //runnable_start_time[idx] = 0;
   1.220  
   1.221 -    new_qos->domain_info[id].start_time = now;
   1.222 -    new_qos->qdata[new_qos->next_datapoint].switchin_count[id]++;
   1.223 -    new_qos->qdata[new_qos->next_datapoint].ns_allocated[id] += ns_alloc;
   1.224 -    new_qos->qdata[new_qos->next_datapoint].ns_waiting[id] += ns_waited;
   1.225 +    new_qos->domain_info[idx].start_time = now;
   1.226 +    new_qos->qdata[new_qos->next_datapoint].switchin_count[idx]++;
   1.227 +    new_qos->qdata[new_qos->next_datapoint].ns_allocated[idx] += ns_alloc;
   1.228 +    new_qos->qdata[new_qos->next_datapoint].ns_waiting[idx] += ns_waited;
   1.229      qos_update_thread_stats(cpu, domid, now);
   1.230 -    set_current(cpu, id);
   1.231 +    set_current(cpu, domid);
   1.232  
   1.233      // count up page flips for dom0 execution
   1.234 -    if (id == 0)
   1.235 +    if (domid == 0)
   1.236        dom0_flips = 0;
   1.237  }
   1.238  
   1.239  // called when the current thread is taken off the cpu
   1.240  void qos_switch_out(int cpu, int domid, uint64_t now, unsigned long gotten)
   1.241  {
   1.242 -    int id = ID(domid);
   1.243 +    int idx = indexof(domid);
   1.244      int n;
   1.245  
   1.246 -    if (!is_current(id, cpu)) {
   1.247 +    if (!is_current(domid, cpu)) {
   1.248          //    printf("switching out domain %d but it is not current. gotten=%ld\r\n", id, gotten);
   1.249      }
   1.250  
   1.251 @@ -943,18 +1014,18 @@ void qos_switch_out(int cpu, int domid, 
   1.252  
   1.253      n = new_qos->next_datapoint;
   1.254  #if 0
   1.255 -    new_qos->qdata[n].ns_gotten[id] += gotten;
   1.256 +    new_qos->qdata[n].ns_gotten[idx] += gotten;
   1.257      if (gotten > new_qos->qdata[n].ns_passed)
   1.258        printf("inconsistency #257, diff = %lld\n",
   1.259  	    gotten - new_qos->qdata[n].ns_passed );
   1.260  #endif
   1.261 -    new_qos->domain_info[id].ns_oncpu_since_boot += gotten;
   1.262 -    new_qos->domain_info[id].runnable_start_time = now;
   1.263 +    new_qos->domain_info[idx].ns_oncpu_since_boot += gotten;
   1.264 +    new_qos->domain_info[idx].runnable_start_time = now;
   1.265      //  runnable_start_time[id] = now;
   1.266 -    qos_update_thread_stats(cpu, id, now);
   1.267 +    qos_update_thread_stats(cpu, domid, now);
   1.268  
   1.269      // process dom0 page flips
   1.270 -    if (id == 0)
   1.271 +    if (domid == 0)
   1.272        if (dom0_flips == 0)
   1.273  	new_qos->qdata[n].flip_free_periods++;
   1.274  }
   1.275 @@ -963,23 +1034,30 @@ void qos_switch_out(int cpu, int domid, 
   1.276  // when thread is already asleep
   1.277  void qos_state_sleeping(int cpu, int domid, uint64_t now) 
   1.278  {
   1.279 -    int id = ID(domid);
   1.280 +    int idx;
   1.281  
   1.282 -    if (!domain_runnable(id))	// double call?
   1.283 +    if (!domain_runnable(domid))	// double call?
   1.284          return;
   1.285  
   1.286 -    new_qos->domain_info[id].runnable = 0;
   1.287 -    new_qos->domain_info[id].blocked_start_time = now;
   1.288 -    new_qos->domain_info[id].runnable_start_time = 0; // invalidate
   1.289 -    //  runnable_start_time[id] = 0; // invalidate
   1.290 +    idx = indexof(domid);
   1.291 +    new_qos->domain_info[idx].runnable = 0;
   1.292 +    new_qos->domain_info[idx].blocked_start_time = now;
   1.293 +    new_qos->domain_info[idx].runnable_start_time = 0; // invalidate
   1.294 +    //  runnable_start_time[idx] = 0; // invalidate
   1.295      qos_update_thread_stats(cpu, domid, now);
   1.296  }
   1.297  
   1.298  
   1.299  
   1.300 +// domain died, presume it's dead on all cpu's, not just mostly dead
   1.301  void qos_kill_thread(int domid)
   1.302  {
   1.303 -    new_qos->domain_info[ID(domid)].in_use = 0;
   1.304 +  int cpu;
   1.305 +  
   1.306 +  for (cpu=0; cpu<NCPU; cpu++) {
   1.307 +    cpu_qos_data[cpu]->domain_info[indexof(domid)].in_use = 0;
   1.308 +  }
   1.309 +  
   1.310  }
   1.311  
   1.312  
   1.313 @@ -987,30 +1065,33 @@ void qos_kill_thread(int domid)
   1.314  // when thread is already runnable
   1.315  void qos_state_runnable(int cpu, int domid, uint64_t now)
   1.316  {
   1.317 -    int id = ID(domid);
   1.318 +   int idx;
   1.319 +  
   1.320  
   1.321      qos_update_thread_stats(cpu, domid, now);
   1.322  
   1.323 -    if (domain_runnable(id))	// double call?
   1.324 +    if (domain_runnable(domid))	// double call?
   1.325          return;
   1.326 -    new_qos->domain_info[id].runnable = 1;
   1.327 +
   1.328 +    idx = indexof(domid);
   1.329 +    new_qos->domain_info[idx].runnable = 1;
   1.330      update_blocked_time(domid, now);
   1.331  
   1.332 -    new_qos->domain_info[id].blocked_start_time = 0; /* invalidate */
   1.333 -    new_qos->domain_info[id].runnable_start_time = now;
   1.334 +    new_qos->domain_info[idx].blocked_start_time = 0; /* invalidate */
   1.335 +    new_qos->domain_info[idx].runnable_start_time = now;
   1.336      //  runnable_start_time[id] = now;
   1.337  }
   1.338  
   1.339  
   1.340  void qos_count_packets(domid_t domid, uint64_t now)
   1.341  {
   1.342 -  int i, id = ID(domid);
   1.343 +  int i, idx = indexof(domid);
   1.344    _new_qos_data *cpu_data;
   1.345  
   1.346    for (i=0; i<NCPU; i++) {
   1.347      cpu_data = cpu_qos_data[i];
   1.348 -    if (cpu_data->domain_info[id].in_use) {
   1.349 -      cpu_data->qdata[cpu_data->next_datapoint].io_count[id]++;
   1.350 +    if (cpu_data->domain_info[idx].in_use) {
   1.351 +      cpu_data->qdata[cpu_data->next_datapoint].io_count[idx]++;
   1.352      }
   1.353    }
   1.354  
   1.355 @@ -1019,77 +1100,57 @@ void qos_count_packets(domid_t domid, ui
   1.356  }
   1.357  
   1.358  
   1.359 -int domain_ok(int cpu, int domid, uint64_t now)
   1.360 -{
   1.361 -    if (domid == IDLE_DOMAIN_ID)
   1.362 -        domid = NDOMAINS-1;
   1.363 -    if (domid < 0 || domid >= NDOMAINS) {
   1.364 -        printf("bad domain id: %d\r\n", domid);
   1.365 -        return 0;
   1.366 -    }
   1.367 -    if (new_qos->domain_info[domid].in_use == 0)
   1.368 -        qos_init_domain(cpu, domid, now);
   1.369 -    return 1;
   1.370 -}
   1.371 -
   1.372 -
   1.373  void process_record(int cpu, struct t_rec *r)
   1.374  {
   1.375    uint64_t now;
   1.376  
   1.377 -
   1.378    new_qos = cpu_qos_data[cpu];
   1.379  
   1.380    rec_count++;
   1.381  
   1.382    now = ((double)r->cycles) / (opts.cpu_freq / 1000.0);
   1.383  
   1.384 +  global_now = now;
   1.385 +  global_cpu = cpu;
   1.386 +
   1.387    log_event(r->event);
   1.388  
   1.389    switch (r->event) {
   1.390  
   1.391    case TRC_SCHED_SWITCH_INFPREV:
   1.392      // domain data[0] just switched out and received data[1] ns of cpu time
   1.393 -    if (domain_ok(cpu, r->data[0], now))
   1.394 -      qos_switch_out(cpu, r->data[0], now, r->data[1]);
   1.395 +    qos_switch_out(cpu, r->data[0], now, r->data[1]);
   1.396      //    printf("ns_gotten %ld\n", r->data[1]);
   1.397      break;
   1.398      
   1.399    case TRC_SCHED_SWITCH_INFNEXT:
   1.400      // domain data[0] just switched in and
   1.401      // waited data[1] ns, and was allocated data[2] ns of cpu time
   1.402 -    if (domain_ok(cpu, r->data[0], now))
   1.403 -      qos_switch_in(cpu, r->data[0], now, r->data[2], r->data[1]);
   1.404 +    qos_switch_in(cpu, r->data[0], now, r->data[2], r->data[1]);
   1.405      break;
   1.406      
   1.407    case TRC_SCHED_DOM_ADD:
   1.408 -    if (domain_ok(cpu, r->data[0], now))
   1.409 -      qos_init_domain(cpu, r->data[0],  now);
   1.410 +    (void) indexof(r->data[0]);
   1.411      break;
   1.412      
   1.413    case TRC_SCHED_DOM_REM:
   1.414 -    if (domain_ok(cpu, r->data[0], now))
   1.415 -      qos_kill_thread(r->data[0]);
   1.416 +    qos_kill_thread(r->data[0]);
   1.417      break;
   1.418      
   1.419    case TRC_SCHED_SLEEP:
   1.420 -    if (domain_ok(cpu, r->data[0], now))
   1.421 -      qos_state_sleeping(cpu, r->data[0], now);
   1.422 +    qos_state_sleeping(cpu, r->data[0], now);
   1.423      break;
   1.424      
   1.425    case TRC_SCHED_WAKE:
   1.426 -    if (domain_ok(cpu, r->data[0], now))
   1.427 -      qos_state_runnable(cpu, r->data[0], now);
   1.428 +    qos_state_runnable(cpu, r->data[0], now);
   1.429      break;
   1.430      
   1.431    case TRC_SCHED_BLOCK:
   1.432 -    if (domain_ok(cpu, r->data[0], now))
   1.433 -      qos_state_sleeping(cpu, r->data[0], now);
   1.434 +    qos_state_sleeping(cpu, r->data[0], now);
   1.435      break;
   1.436      
   1.437    case TRC_MEM_PAGE_GRANT_TRANSFER:
   1.438 -    if (domain_ok(cpu, r->data[0], now))
   1.439 -      qos_count_packets(r->data[0], now);
   1.440 +    qos_count_packets(r->data[0], now);
   1.441      break;
   1.442      
   1.443    default:
     2.1 --- a/tools/xenmon/xenmon.py	Mon Jul 10 16:05:44 2006 +0100
     2.2 +++ b/tools/xenmon/xenmon.py	Mon Jul 10 16:09:20 2006 +0100
     2.3 @@ -36,10 +36,10 @@ import sys
     2.4  # constants
     2.5  NSAMPLES = 100
     2.6  NDOMAINS = 32
     2.7 -IDLE_DOMAIN = 31 # idle domain's ID
     2.8 +IDLE_DOMAIN = -1 # idle domain's ID
     2.9  
    2.10  # the struct strings for qos_info
    2.11 -ST_DOM_INFO = "6Q4i32s"
    2.12 +ST_DOM_INFO = "6Q3i2H32s"
    2.13  ST_QDATA = "%dQ" % (6*NDOMAINS + 4)
    2.14  
    2.15  # size of mmaped file
    2.16 @@ -297,6 +297,7 @@ def show_livestats(cpu):
    2.17              samples = []
    2.18              doms = []
    2.19              dom_in_use = []
    2.20 +            domain_id = []
    2.21  
    2.22              # read in data
    2.23              for i in range(0, NSAMPLES):
    2.24 @@ -311,9 +312,13 @@ def show_livestats(cpu):
    2.25                  doms.append(dom)
    2.26  #		(last_update_time, start_time, runnable_start_time, blocked_start_time,
    2.27  #		 ns_since_boot, ns_oncpu_since_boot, runnable_at_last_update,
    2.28 -#		 runnable, in_use, domid, name) = dom
    2.29 +#		 runnable, in_use, domid, junk, name) = dom
    2.30  #		dom_in_use.append(in_use)
    2.31                  dom_in_use.append(dom[8])
    2.32 +                domid = dom[9]
    2.33 +                if domid == 32767 :
    2.34 +                    domid = IDLE_DOMAIN
    2.35 +                domain_id.append(domid)
    2.36                  idx += len
    2.37  #            print "dom_in_use(cpu=%d): " % cpuidx, dom_in_use
    2.38  
    2.39 @@ -366,16 +371,16 @@ def show_livestats(cpu):
    2.40              if not dom_in_use[dom]:
    2.41                  continue
    2.42  
    2.43 -            if h1[dom][0][1] > 0 or dom == NDOMAINS - 1:
    2.44 +            if h1[dom][0][1] > 0 or domain_id[dom] == IDLE_DOMAIN:
    2.45                  # display gotten
    2.46                  row += 1 
    2.47                  col = 2
    2.48 -                display_domain_id(stdscr, row, col, dom)
    2.49 +                display_domain_id(stdscr, row, col, domain_id[dom])
    2.50                  col += 4
    2.51                  display(stdscr, row, col, "%s" % time_scale(h2[dom][0][0]))
    2.52                  col += 12
    2.53                  display(stdscr, row, col, "%3.2f%%" % h2[dom][0][1])
    2.54 -                if dom != NDOMAINS - 1:
    2.55 +                if dom != IDLE_DOMAIN:
    2.56                      cpu_10sec_usage += h2[dom][0][1]
    2.57                  col += 12
    2.58                  display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][0][2]))
    2.59 @@ -388,14 +393,14 @@ def show_livestats(cpu):
    2.60                  col += 18
    2.61                  display(stdscr, row, col, "Gotten")
    2.62  
    2.63 -                if dom != NDOMAINS - 1:
    2.64 +                if dom != IDLE_DOMAIN:
    2.65                      cpu_1sec_usage = cpu_1sec_usage + h1[dom][0][1]
    2.66      
    2.67                  # display allocated
    2.68                  if options.allocated:
    2.69                      row += 1
    2.70                      col = 2
    2.71 -                    display_domain_id(stdscr, row, col, dom)
    2.72 +                    display_domain_id(stdscr, row, col, domain_id[dom])
    2.73                      col += 28
    2.74                      display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][1]))
    2.75                      col += 42
    2.76 @@ -407,7 +412,7 @@ def show_livestats(cpu):
    2.77                  if options.blocked:
    2.78                      row += 1
    2.79                      col = 2
    2.80 -                    display_domain_id(stdscr, row, col, dom)
    2.81 +                    display_domain_id(stdscr, row, col, domain_id[dom])
    2.82                      col += 4
    2.83                      display(stdscr, row, col, "%s" % time_scale(h2[dom][2][0]))
    2.84                      col += 12
    2.85 @@ -427,7 +432,7 @@ def show_livestats(cpu):
    2.86                  if options.waited:
    2.87                      row += 1
    2.88                      col = 2
    2.89 -                    display_domain_id(stdscr, row, col, dom)
    2.90 +                    display_domain_id(stdscr, row, col, domain_id[dom])
    2.91                      col += 4
    2.92                      display(stdscr, row, col, "%s" % time_scale(h2[dom][3][0]))
    2.93                      col += 12
    2.94 @@ -447,7 +452,7 @@ def show_livestats(cpu):
    2.95                  if options.excount:
    2.96                      row += 1
    2.97                      col = 2
    2.98 -                    display_domain_id(stdscr, row, col, dom)
    2.99 +                    display_domain_id(stdscr, row, col, domain_id[dom])
   2.100                      
   2.101                      col += 28
   2.102                      display(stdscr, row, col, "%d/s" % h2[dom][4])
   2.103 @@ -460,7 +465,7 @@ def show_livestats(cpu):
   2.104                  if options.iocount:
   2.105                      row += 1
   2.106                      col = 2
   2.107 -                    display_domain_id(stdscr, row, col, dom)
   2.108 +                    display_domain_id(stdscr, row, col, domain_id[dom])
   2.109                      col += 4
   2.110                      display(stdscr, row, col, "%d/s" % h2[dom][5][0])
   2.111                      col += 24
   2.112 @@ -544,6 +549,9 @@ class Delayed(file):
   2.113              self.file.write(self.delay_data)
   2.114  	self.file.write(str)
   2.115  
   2.116 +    def rename(self, name):
   2.117 +        self.filename = name
   2.118 +
   2.119      def flush(self):
   2.120          if  self.opened:
   2.121              self.file.flush()
   2.122 @@ -567,10 +575,7 @@ def writelog():
   2.123      curr = last = time.time()
   2.124      outfiles = {}
   2.125      for dom in range(0, NDOMAINS):
   2.126 -        if dom == IDLE_DOMAIN:
   2.127 -            outfiles[dom] = Delayed("%s-idle.log" % options.prefix, 'w')
   2.128 -        else:
   2.129 -            outfiles[dom] = Delayed("%s-dom%d.log" % (options.prefix, dom), 'w')
   2.130 +        outfiles[dom] = Delayed("%s-dom%d.log" % (options.prefix, dom), 'w')
   2.131          outfiles[dom].delayed_write("# passed cpu dom cpu(tot) cpu(%) cpu/ex allocated/ex blocked(tot) blocked(%) blocked/io waited(tot) waited(%) waited/ex ex/s io(tot) io/ex\n")
   2.132  
   2.133      while options.duration == 0 or interval < (options.duration * 1000):
   2.134 @@ -582,6 +587,7 @@ def writelog():
   2.135              samples = []
   2.136              doms = []
   2.137              dom_in_use = []
   2.138 +            domain_id = []
   2.139  
   2.140              for i in range(0, NSAMPLES):
   2.141                  len = struct.calcsize(ST_QDATA)
   2.142 @@ -595,8 +601,16 @@ def writelog():
   2.143  #                doms.append(dom)
   2.144  #		(last_update_time, start_time, runnable_start_time, blocked_start_time,
   2.145  #		 ns_since_boot, ns_oncpu_since_boot, runnable_at_last_update,
   2.146 -#		 runnable, in_use, domid, name) = dom
   2.147 +#		 runnable, in_use, domid, junk, name) = dom
   2.148                  dom_in_use.append(dom[8])
   2.149 +                domid = dom[9]
   2.150 +                if domid == 32767:
   2.151 +                    domid = IDLE_DOMAIN
   2.152 +                domain_id.append(domid)
   2.153 +                if domid == IDLE_DOMAIN:
   2.154 +                    outfiles[i].rename("%s-idle.log" % options.prefix)
   2.155 +                else:
   2.156 +                    outfiles[i].rename("%s-dom%d.log" % (options.prefix, domid))
   2.157                  idx += len
   2.158  
   2.159              len = struct.calcsize("4i")
   2.160 @@ -617,9 +631,9 @@ def writelog():
   2.161              for dom in range(0, NDOMAINS):
   2.162                  if not dom_in_use[dom]:
   2.163                      continue
   2.164 -                if h1[dom][0][1] > 0 or dom == NDOMAINS - 1:
   2.165 +                if h1[dom][0][1] > 0 or dom == IDLE_DOMAIN:
   2.166                      outfiles[dom].write("%.3f %d %d %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n" %
   2.167 -                                     (interval, cpuidx, dom,
   2.168 +                                     (interval, cpuidx, domain_id[dom],
   2.169                                       h1[dom][0][0], h1[dom][0][1], h1[dom][0][2],
   2.170                                       h1[dom][1],
   2.171                                       h1[dom][2][0], h1[dom][2][1], h1[dom][2][2],