Index: /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/CheckIdleHost.c
===================================================================
--- /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/CheckIdleHost.c	(revision 29420)
+++ /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/CheckIdleHost.c	(revision 29421)
@@ -60,4 +60,6 @@
     if (strcasecmp (job[0].hostname, host[0].hostname)) continue;
 
+    if (!CheckMachineJobs (host, job)) continue;
+
     /* we have found an appropriate job; link it to the host and send to StartJob */
     job[0].host = (struct Host *) host;
@@ -80,4 +82,6 @@
     ASSERT (job[0].hostname != NULL, "WANTHOST hostname missing");
     if (strcasecmp (job[0].hostname, host[0].hostname)) continue;
+
+    if (!CheckMachineJobs (host, job)) continue;
 
     /* we have found an appropriate job; link it to the host and send to StartJob */
Index: /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/JobOps.c
===================================================================
--- /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/JobOps.c	(revision 29420)
+++ /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/JobOps.c	(revision 29421)
@@ -195,5 +195,5 @@
 }
 
-IDtype AddJob (char *hostname, JobMode mode, int timeout, int argc, char **argv) {
+IDtype AddJob (char *hostname, JobMode mode, int timeout, int argc, char **argv, int Nxhosts, char **xhosts) {
 
   int JobID;
@@ -228,4 +228,7 @@
   job[0].host     = NULL;
 
+  job[0].xhosts = xhosts;
+  job[0].Nxhosts = Nxhosts;
+
   JobID = job[0].JobID;
 
@@ -257,4 +260,9 @@
   FREE (job[0].argv);
 
+  for (i = 0; i < job[0].Nxhosts; i++) {
+    FREE (job[0].xhosts[i]);
+  }
+  FREE (job[0].xhosts);
+
   FreeIOBuffer (&job[0].stdout_buf.buffer);
   FreeIOBuffer (&job[0].stderr_buf.buffer);
Index: /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/MachineOps.c
===================================================================
--- /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/MachineOps.c	(revision 29420)
+++ /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/MachineOps.c	(revision 29421)
@@ -1,3 +1,4 @@
 # include "pcontrol.h"
+# define DEBUG 0
 
 static int MAX_UNWANTED_HOST_JOBS = 5;
@@ -107,4 +108,5 @@
 int AddMachineJob (Host *host, Job *job) {
 
+  int i;
   Machine *machine;
 
@@ -114,7 +116,14 @@
   machine[0].NjobsRealhost ++;
 
-  // skip jobs that do not have a targeted host
-  if (job[0].hostname == NULL) {
-    return (TRUE);
+  // skip jobs that do not have a targeted host or any xhosts
+  if (!job[0].hostname && !job[0].Nxhosts) {
+    return (TRUE);
+  }
+
+  for (i = 0; i < job[0].Nxhosts; i++) {
+    // find machine matching the xhost name (these count against the unwanted host total)
+    machine = FindMachineByName (job[0].xhosts[i]); // Can this fail?
+    if (!machine) continue;
+    machine[0].NjobsWanthost ++;
   }
 
@@ -134,4 +143,5 @@
 int DelMachineJob (Host *host, Job *job) {
 
+  int i;
   Machine *machine;
 
@@ -141,7 +151,14 @@
   machine[0].NjobsRealhost --;
 
-  // skip jobs that do not have a targeted host
-  if (job[0].hostname == NULL) {
-    return (TRUE);
+  // skip jobs that do not have a targeted host or any xhosts
+  if (!job[0].hostname && !job[0].Nxhosts) {
+    return (TRUE);
+  }
+
+  for (i = 0; i < job[0].Nxhosts; i++) {
+    // find machine matching the xhost name (these count against the unwanted host total)
+    machine = FindMachineByName (job[0].xhosts[i]); // Can this fail?
+    if (!machine) continue;
+    machine[0].NjobsWanthost --;
   }
 
@@ -175,21 +192,36 @@
 int CheckMachineJobs (Host *host, Job *job) {
 
+  int i;
   Machine *machine;
 
   machine = FindMachineByName (job[0].hostname);
-  if (machine == NULL) return (TRUE);
-  // fprintf (stderr, "wanthost: %s, Ntotal: %d, Nmax: %d\n", job[0].hostname, machine[0].NjobsWanthost + machine[0].NjobsRealhost, machine[0].Nhosts + MAX_UNWANTED_HOST_JOBS);
-  // if (machine[0].NjobsWanthost + machine[0].NjobsRealhost >= machine[0].Nhosts + MAX_UNWANTED_HOST_JOBS) {
-  if (machine[0].NjobsWanthost >= MAX_UNWANTED_HOST_JOBS) {
-    // fprintf (stderr, "too many outstanding jobs wanting host %s, delay job %s for now\n", job[0].hostname, job[0].argv[0]);
-    return (FALSE);
-  }
+  if (machine) {
+    if (DEBUG) fprintf (stderr, "wanthost: %s, Ntotal: %d, Nmax: %d\n", machine[0].name, machine[0].NjobsWanthost + machine[0].NjobsRealhost, machine[0].Nhosts + MAX_UNWANTED_HOST_JOBS);
+    if (machine[0].NjobsWanthost >= MAX_UNWANTED_HOST_JOBS) {
+      if (DEBUG) fprintf (stderr, "too many outstanding jobs wanting host %s, delay job %s for now\n", machine[0].name, job[0].argv[0]);
+      return (FALSE);
+    }
+  }
+
+  for (i = 0; i < job[0].Nxhosts; i++) {
+    machine = FindMachineByName (job[0].xhosts[i]);
+    if (machine) {
+      if (DEBUG) fprintf (stderr, "xhost: %s, Ntotal: %d, Nmax: %d\n", machine[0].name, machine[0].NjobsWanthost + machine[0].NjobsRealhost, machine[0].Nhosts + MAX_UNWANTED_HOST_JOBS);
+      if (machine[0].NjobsWanthost >= MAX_UNWANTED_HOST_JOBS) {
+	if (DEBUG) fprintf (stderr, "too many outstanding jobs wanting host %s, delay job %s for now\n", machine[0].name, job[0].argv[0]);
+	return (FALSE);
+      }
+    }
+  }    
 
   machine = FindMachineByName (host[0].hostname);
-  // fprintf (stderr, "realhost: %s, Ntotal: %d, Nmax: %d\n", host[0].hostname, machine[0].NjobsWanthost + machine[0].NjobsRealhost, machine[0].Nhosts + MAX_UNWANTED_HOST_JOBS);
-  if (machine[0].NjobsWanthost >= MAX_UNWANTED_HOST_JOBS) {
-    // fprintf (stderr, "too many outstanding jobs wanting host %s, delay job %s for now\n", job[0].hostname, job[0].argv[0]);
-    return (FALSE);
-  }
+  if (machine) {
+    if (DEBUG) fprintf (stderr, "realhost: %s, Ntotal: %d, Nmax: %d\n", machine[0].name, machine[0].NjobsWanthost + machine[0].NjobsRealhost, machine[0].Nhosts + MAX_UNWANTED_HOST_JOBS);
+    if (machine[0].NjobsWanthost >= MAX_UNWANTED_HOST_JOBS) {
+      if (DEBUG) fprintf (stderr, "too many outstanding jobs wanting host %s, delay job %s for now\n", machine[0].name, job[0].argv[0]);
+      return (FALSE);
+    }
+  }
+
   return (TRUE);
 }
Index: /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/job.c
===================================================================
--- /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/job.c	(revision 29420)
+++ /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/job.c	(revision 29421)
@@ -6,4 +6,6 @@
   int i, N, Mode, targc, Timeout;
   IDtype JobID;
+  char **xhosts;
+  int Nxhosts, NXHOSTS;
 
   if (get_argument (argc, argv, "-host") && get_argument (argc, argv, "+host")) {
@@ -39,4 +41,21 @@
   }
 
+  xhosts = NULL;
+  Nxhosts = 0;
+  NXHOSTS = 10;
+  while ((N = get_argument (argc, argv, "-xhost"))) {
+    if (xhosts == NULL) {
+      ALLOCATE (xhosts, char *, NXHOSTS);
+    }
+    remove_argument (N, &argc, argv);
+    xhosts[Nxhosts] = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+    Nxhosts ++;
+    if (Nxhosts == NXHOSTS) {
+      NXHOSTS += 10;
+      REALLOCATE (xhosts, char *, NXHOSTS);
+    }
+  }
+
   if (argc < 2) {
     FREE (Host);
@@ -51,5 +70,5 @@
 
   // a JobID < 0 mean the job was not accepted
-  JobID = AddJob (Host, Mode, Timeout, targc, targv);
+  JobID = AddJob (Host, Mode, Timeout, targc, targv, Nxhosts, xhosts);
   gprint (GP_LOG, "JobID: %d\n", (int) JobID);
   return (TRUE);
@@ -57,6 +76,12 @@
  usage:
     gprint (GP_ERR, "USAGE: job [options] (arg0) (arg1) ... (argN)\n");
-    gprint (GP_ERR, "  options: -host, +host, -timeout\n");
+    gprint (GP_ERR, "  options: -host, +host, -timeout, -xhost (host)\n");
     gprint (GP_ERR, "  arguments of the form @MAX_THREADS@ will be replaced when the job is launched\n");
+
+    FREE (Host);
+    for (i = 0; i < Nxhosts; i++) {
+      FREE (xhosts[i]);
+    }
+    FREE (xhosts);
     return (FALSE);
 }
Index: /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/test/machines.sh
===================================================================
--- /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/test/machines.sh	(revision 29420)
+++ /branches/eam_branches/ipp-20100823/Ohana/src/opihi/pcontrol/test/machines.sh	(revision 29421)
@@ -10,4 +10,6 @@
   host add ipp022
   host add ipp022
+  host add ipp002
+  host off ipp002
 
   machines
@@ -23,4 +25,26 @@
   job -host pikake sleep 10
   job -host pikake sleep 10
+end
+
+macro load.xhost
+  job -host pikake -xhost ipp002 sleep 10
+  job -host pikake -xhost ipp002 sleep 10
+  job -host ipp022 -xhost ipp002 sleep 10
+  job -host ipp022 -xhost ipp002 sleep 10
+  job -host pikake -xhost ipp002 sleep 10
+  job -host pikake -xhost ipp002 sleep 10
+  job -host ipp022 -xhost ipp002 sleep 10
+  job -host ipp022 -xhost ipp002 sleep 10
+end
+
+macro load.2xhost
+  job -host pikake -xhost ipp002 -xhost ipp022 sleep 10
+  job -host pikake -xhost ipp002 -xhost ipp022 sleep 10
+  job -host ipp022 -xhost ipp002 -xhost ipp022 sleep 10
+  job -host ipp022 -xhost ipp002 -xhost ipp022 sleep 10
+  job -host pikake -xhost ipp002 -xhost ipp022 sleep 10
+  job -host pikake -xhost ipp002 -xhost ipp022 sleep 10
+  job -host ipp022 -xhost ipp002 -xhost ipp022 sleep 10
+  job -host ipp022 -xhost ipp002 -xhost ipp022 sleep 10
 end
 
