Beispiel #1
0
int
bqc (int argc, char *argv[], int opCode)
{
    struct queueInfoEnt *queueInfo;
    char **queueList=NULL, **queues ;
    int numQueues, all = FALSE;
    int i;

    queues = NULL;
    if (argc == optind)
        numQueues =1;
    else {
        numQueues = getNames (argc, argv, optind, &queueList, &all, "queueC");
        if (!all)
            queues = queueList;
    }

    if ((queueInfo = lsb_queueinfo(queues, &numQueues, NULL, NULL, 0))
        == NULL) {
        if (lsberrno == LSBE_BAD_QUEUE
            && queues && queues[numQueues])
            lsb_perror(queues[numQueues]);
        else
            lsb_perror(NULL);
        return (-1);
    }

    for (i = 0; i < numQueues; i++) {
        ctrlQueue (queueInfo[i].queue, opCode);
    }
    return (exitrc);
}
Beispiel #2
0
int
main(int argc, char **argv)
{
    int numQueues;
    char **queues;
    struct queueInfoEnt *queueInfo;
    char lflag = FALSE;
    int cc;
    char *host;
    char *user;

    numQueues = 0;
    user = host = NULL;

    if (lsb_init(argv[0]) < 0) {
        lsb_perror("lsb_init");
        return -1;
    }

    while ((cc = getopt(argc, argv, "Vhlwm:u:")) != EOF) {
        switch (cc) {
            case 'l':
                lflag = TRUE;
                if (wflag) {
                    usage(argv[0]);
                    return -1;
                }
                break;
            case 'w':
                wflag = TRUE;
                if (lflag) {
                    usage(argv[0]);
                    return -1;
                }
                break;
            case 'm':
                if (host != NULL || *optarg == '\0')
                    usage(argv[0]);
                host = optarg;
                break;
            case 'u':
                if (user != NULL || *optarg == '\0')
                    usage(argv[0]);
                user = optarg;
                break;
            case 'V':
                fputs(_LS_VERSION_, stderr);
                return 0;
            case 'h':
            default:
                usage(argv[0]);
            return -1;
        }
    }

    queues = NULL;
    numQueues = 0;

    if (optind < argc) {
        numQueues = argc - optind;
        queues = calloc(argc - optind, sizeof(char *));
        for (cc = 0; cc < argc - optind; cc++)
            queues[cc] = argv[optind + cc];
    }

    TIMEIT(0, (queueInfo = lsb_queueinfo(queues,
                                         &numQueues,
                                         host,
                                         user,
                                         0)), "lsb_queueinfo");

    if (!queueInfo) {
        if (lsberrno == LSBE_BAD_QUEUE && queues)
            lsb_perror(queues[numQueues]);
        else {
            switch (lsberrno) {
                case LSBE_BAD_HOST   :
                case LSBE_QUEUE_HOST :
                    lsb_perror(host);
                    break;
                case LSBE_BAD_USER   :
                case LSBE_QUEUE_USE  :
                    lsb_perror(user);
                    break;
                default :
                    lsb_perror(NULL);
            }
        }
        _free_(queues);
        return -1;
    }

    if (lflag)
        prtQueuesLong(numQueues, queueInfo);
    else
        prtQueuesShort(numQueues, queueInfo);

    _free_(queues);

    return 0;
}
int main(int argc, char** argv)
{
  // Initialise our connection to LSF
  if (lsb_init(argv[0]) < 0) {
    lsb_perror("lsb_init() failed");
    return -1;
  }

  // If queue argument isn't defined then just show data from normal job queue
  char* queues;
  if (argc < 2) {
    queues = strdup("normal");
  }
  else {
    queues = argv[1];
  }

  // Query LSF
  int num_queues = 1;
  struct queueInfoEnt *info = lsb_queueinfo(&queues, &num_queues, NULL, NULL, 0);
  // For each queue in output (should only be one) process data
  for (int i = 0; i < num_queues; i++) {
    struct queueInfoEnt *curr_info = &info[i];
    std::map<std::string, float> parent_map;
    std::list<ShareAcct*> accounts;
    // SKUNKWORKS SOLUTION
    for (int j = 1; j < curr_info->numOfSAccts; j++) {
      struct shareAcctInfoEnt *curr_share = &curr_info->shareAccts[j];
      ShareAcct* acct = new ShareAcct( curr_share );
      std::string parent = std::string(acct->getParent());
      // If the parent is already in the map, sum the shares. Otherwise, add it in with the shares of the first child.
      if (parent_map.count(parent) > 0) {
        parent_map[parent] += acct->getShares();
      } else {
        parent_map[parent] = acct->getShares();
      }

      accounts.push_back(acct);
    }

    // Now walk back through the accounts (reverse order) and first normalise shares,
    // then multiply that by the value we calculated for the parents. We do this recursively until
    // we hit the bottom.
    std::map<std::string, float> share_map;
    // Try doing the same for priority.
    std::map<std::string, float> priority_map;
    for (auto it = accounts.begin(); it != accounts.end(); it++) {
      ShareAcct* a = *it;
      if (parent_map.count(a->getParent()) > 0) {
        if (share_map.count(a->getParent()) > 0) {
          share_map[a->getGroup()] = ((a->getShares() / parent_map[a->getParent()]) * share_map[a->getParent()]);
          priority_map[a->getGroup()] = (a->getPriority() * priority_map[a->getParent()]);
        } else {
          share_map[a->getGroup()] = (a->getShares() / parent_map[a->getParent()]);
          priority_map[a->getGroup()] = a->getPriority();
        }
      } else {
        share_map[a->getGroup()] = 1;
      }

      a->setProportion(share_map[a->getGroup()]);
      a->setPriority(priority_map[a->getGroup()]);

    }


    // /SKUNKWORKS SOLUTION
    std::string root = accounts.front()->getParent();

    // If there are actually any share accounts defined for this queue write result
    // It's done this way because JSON doesn't support commas at the end of the last list item
    if (curr_info->numOfSAccts > 0) {
      printf("[\n");
      ShareAcct::print_structure();
      // Write the root node
      printf("\n,\n['%s','' , 1, 1]", root.c_str());
      // Write elements
      for (auto it = accounts.begin(); it != accounts.end(); it++) {
        printf(",\n");
        (*it)->print(parent_map.count((*it)->getGroup()) > 0);
      }
      printf("]\n");
    }
  }
  return 0;
}
Beispiel #4
0
int
main(int argc, char **argv)
{
    int numQueues;
    char **queueNames=NULL, **queues = NULL;
    struct queueInfoEnt *queueInfo;
    char lflag = FALSE;
    int cc, defaultQ = FALSE;
    char *host = NULL, *user = NULL;
    int rc;

    numQueues = 0;

    rc = _i18n_init ( I18N_CAT_MIN );

    if (lsb_init(argv[0]) < 0) {
        lsb_perror("lsb_init");
        exit(-1);
    }

    while ((cc = getopt(argc, argv, "Vhlwm:u:")) != EOF) {
        switch (cc) {
        case 'l':
            lflag = TRUE;
            if (wflag)
                usage(argv[0]);
            break;
        case 'w':
            wflag = TRUE;
            if (lflag)
                usage(argv[0]);
            break;
        case 'm':
            if (host != NULL || *optarg == '\0')
                usage(argv[0]);
            host = optarg;
            break;
        case 'u':
            if (user != NULL || *optarg == '\0')
                usage(argv[0]);
            user = optarg;
            break;
        case 'V':
            fputs(_LS_VERSION_, stderr);
            exit(0);
        case 'h':
        default:
            usage(argv[0]);
        }
    }

    numQueues = getNames(argc,
                         argv,
                         optind,
                         &queueNames,
                         &defaultQ,
                         "queue");
    if (!defaultQ && numQueues != 0)
        queues = queueNames;
    else
        queues = NULL;

    TIMEIT(0, (queueInfo = lsb_queueinfo(queues,
                                         &numQueues,
                                         host,
                                         user,
                                         0)), "lsb_queueinfo");

    if (!queueInfo) {
        if (lsberrno == LSBE_BAD_QUEUE && queues)
            lsb_perror(queues[numQueues]);
        else {
            switch (lsberrno) {
            case LSBE_BAD_HOST   :
            case LSBE_QUEUE_HOST :
                lsb_perror (host);
                break;
            case LSBE_BAD_USER   :
            case LSBE_QUEUE_USE  :
                lsb_perror (user);
                break;
            default :
                lsb_perror (NULL);
            }
        }
        return -1;
    }

    if (lflag)
        prtQueuesLong(numQueues, queueInfo);
    else
        prtQueuesShort(numQueues, queueInfo);

    return 0;
}
Beispiel #5
0
/* Summarizes aspect of cluster currently being polled for jobs */
void print_summary(char *inp_queue, char *user, char *inp_hosts, int numcoresq, int numnodesq) {
	struct jobInfoEnt *job;     /* detailed job info */
	struct queueInfoEnt *que;   /* detailed queue info */
	struct queueInfoEnt *que2;   /* detailed queue info */
	struct hostInfoEnt *hos;    /* detailed host info */
  	int numQueues, numQueues2;  /* number of Queues to query about */
	int numHosts; /* number of Hosts */
	int i,j,k,ii; /* counters */
	int totHosts=0, totClosedAdm=0, totUnavail=0, totUsed=0; /* counters for total number of nodes, total closed by the Admin, total Unavailable and total used*/
	int totCores=0, totCoresUsed=0; /* counters for total number of cores and number of cores used. */
	float perutil; /* work variable */
	char *hostlist;         /* Array of Hosts */
	char quehostlist[1000]; /* list of hosts for a specific queue */
	char *token; /* Used for parsing */
	char *delimiters = " "; /* Used for parsing */
	char *slash = "/"; /* Used for parsing */
	char *saveptr1; /* Used for parsing */
	char queuelistcheck[100][20]; /* Stores what queues we have already checked */
	char hostlistcheck[10000][20]; /* Stores what hosts we have already checked */
	char hostscheck[100000][20];  /* Stores what hostlists we have alredy checked */
	int numhlc,numhc,numoqc, alreadycounted; /* Number of entires for the above arrays plus a logical for whether or not the variable has already be checked. */


	/* If there is a queue we are pooling use this summary */
	if (inp_queue != NULL) {
		printf("Queue Summary\n");

		/* First let's get information on the queue in question */
		numQueues=1;
		que = lsb_queueinfo(&inp_queue,&numQueues,NULL,NULL,0);

		/* Copy the hostlist to the a temporary file */
		strcpy(quehostlist,que->hostList);

		/* Iterate through the host list which is seperated by spaces */

		numoqc=0;

		i=0;

		for(;;) {
			/* Parses the hostlist based on the defined delimiters */
			if (i == 0){
				token = strtok(quehostlist,delimiters);
				}
			else{
				token = strtok(NULL,delimiters);
			}

			if (token == NULL) break;

			/* We need to trim off slashes */
			saveptr1=strpbrk(token,slash);

			if (saveptr1 != NULL) {
				token[strlen(token)-1]='\0';
			}
				

			/* We will first poll the hosts available to this queue and see what is going on */

			hostlist=token;

			numHosts=1;

			hos = lsb_hostinfo(&hostlist, &numHosts);

			totHosts=totHosts+numHosts;

			/* Now we are going to check each host for what state it is in */
			/* We will also collect statistics regarding the usage of the host at the same time */
			for (j=0;j<numHosts;j++){
				if (hos[j].hStatus & HOST_STAT_UNLICENSED) {
      					}/* unlicensed */
				else if (hos[j].hStatus & HOST_STAT_UNAVAIL) {
					totUnavail++; /* LIM and sbatchd are unavailable */
					}
    				else if (hos[j].hStatus & HOST_STAT_UNREACH) {
      					totUnavail++; /* sbatchd is unreachable */
					}
    				else if (hos[j].hStatus & HOST_CLOSED_BY_ADMIN) {
					totClosedAdm++; /* host closed by administrator */
					}
				else if (hos[j].hStatus & ( HOST_STAT_WIND | HOST_STAT_DISABLED | HOST_STAT_NO_LIM)) {
      					}
    				else if (hos[j].hStatus & ( HOST_STAT_BUSY | HOST_STAT_FULL | HOST_STAT_LOCKED )) {
					/* Host is full */
					totUsed++;
					totCoresUsed=hos[j].numRUN+totCoresUsed;
					totCores=hos[j].maxJobs+totCores;
					}
				else {
					/* Host is partially used */
					if (hos[j].numRUN > 0) {
						totUsed++;
					}

					totCoresUsed=hos[j].numRUN+totCoresUsed;
					totCores=hos[j].maxJobs+totCores;
				}
			}


			/* Check what other queues are pointing to this host */
			numQueues2=0;

			que2 = lsb_queueinfo(NULL,&numQueues2,hos->host,NULL,0);

			for (k=0;k<numQueues2;k++){
				/* Check and see that the queue is not the one we are currently interested in */
				if (strcmp(inp_queue,que2[k].queue) != 0) {

					/* We need to check that we aren't double counting queues */
					alreadycounted=0;

					for(ii=0;ii<numoqc;ii++){
						if (strcmp(que2[k].queue,queuelistcheck[ii]) == 0) {
							alreadycounted=1;
							break;
						}
					}

					/* If we've already been counted break out of this loop if not counted then store that data */
					if (alreadycounted == 0) {
						strcpy(queuelistcheck[numoqc],que2[k].queue);
						numoqc++;
					}
				}

			}

			i=i+1;
		}


		/* Now to print what we found */
		/* First Data on this Specific Queue */
		/* Calculate the percentage of cores used */
		perutil=(float)numcoresq/(float)totCores*100;

		printf("%4i of %4i Cores Used (%4.2f%%)\n", numcoresq, totCores, perutil);

		/* Calculate the percentage of nodes used */
		perutil=(float)numnodesq/(float)totHosts*100;

		printf("%4i of %4i Nodes Used (%4.2f%%)\n", numnodesq, totHosts, perutil);

		/* Now for all the nodes accessible by the queue */
		printf("\n");

		printf("Overall Statistics for Nodes Available to this Queue\n");

		/* Calculate the percentage of cores used */
		perutil=(float)totCoresUsed/(float)totCores*100;

		printf("%4i of %4i Cores Used (%4.2f%%)\n", totCoresUsed, totCores, perutil);

		/* Calculate the percentage of nodess used */
		perutil=(float)totUsed/(float)totHosts*100;

		printf("%4i of %4i Nodes Used (%4.2f%%), %2i Nodes Closed by Admin, %2i Nodes Unavailable\n", totUsed, totHosts, perutil, totClosedAdm, totUnavail);

		printf("\n");

		/* Print out which other queues can submit to these hosts */

		printf("Other Queues Which Submit To The Hosts For This Queue: ");

		j=0;

		for (k=0;k<numoqc;k++) {
			if (k == numoqc-1) {
				printf("%4s", queuelistcheck[k]);
				}
			else {
				printf("%4s, ", queuelistcheck[k]);
			}

			j++;
			/* Word wraps if line is too long */
			if (j == 4) {
				printf("\n");
				j=0;
			}
		}

		printf("\n");

		}
	else if (inp_hosts != NULL) {
		printf("Host Summary\n");
		/* First let's get information on the host in question */

		hostlist=inp_hosts;

		numHosts=1;

		hos = lsb_hostinfo(&hostlist, &numHosts);

		totHosts=totHosts+numHosts;

		/* Now we are going to check each host for what state it is in */
		/* We will also collect statistics regarding the usage of the host at the same time */
		for (j=0;j<numHosts;j++){
			if (hos[j].hStatus & HOST_STAT_UNLICENSED) {
      				}/* unlicensed */
			else if (hos[j].hStatus & HOST_STAT_UNAVAIL) {
				totUnavail++; /* LIM and sbatchd are unavailable */
				}
    			else if (hos[j].hStatus & HOST_STAT_UNREACH) {
      				totUnavail++; /* sbatchd is unreachable */
				}
    			else if (hos[j].hStatus & HOST_CLOSED_BY_ADMIN) {
				totClosedAdm++; /* host closed by administrator */
				}
			else if (hos[j].hStatus & ( HOST_STAT_WIND | HOST_STAT_DISABLED | HOST_STAT_NO_LIM)) {
      				}
    			else if (hos[j].hStatus & ( HOST_STAT_BUSY | HOST_STAT_FULL | HOST_STAT_LOCKED )) {
				/* Host is full */
				totUsed++;
				totCoresUsed=hos[j].numRUN+totCoresUsed;
				totCores=hos[j].maxJobs+totCores;

				}
			else {
				/* Host is partially used */
				if (hos[j].numRUN > 0) {
					totUsed++;
				}

				totCoresUsed=hos[j].numRUN+totCoresUsed;
				totCores=hos[j].maxJobs+totCores;
			}

		}

		/* Check what queues are pointing to this host */
		numoqc=0;
		numQueues2=0;
		que2 = lsb_queueinfo(NULL,&numQueues2,hos->host,NULL,0);

		for (k=0;k<numQueues2;k++){
			/* We need to check that we aren't double counting queues */
			alreadycounted=0;

			for(ii=0;ii<numoqc;ii++){
				if (strcmp(que2[k].queue,queuelistcheck[ii]) == 0) {
					alreadycounted=1;
					break;
				}
			}

			/* If we've already been counted break out of this loop if not counted then store that data */
			if (alreadycounted == 0) {
				strcpy(queuelistcheck[numoqc],que2[k].queue);
				numoqc++;
			}
		}
		

		/* Now to print what we found */
		/* Calculate the percentage of cores used */
		perutil=(float)totCoresUsed/(float)totCores*100;

		printf("%4i of %4i Cores Used (%4.2f%%)\n", totCoresUsed, totCores, perutil);

		/* Calculate the percentage of nodes used */
		perutil=(float)totUsed/(float)totHosts*100;

		printf("%4i of %4i Nodes Used (%4.2f%%), %2i Nodes Closed by Admin, %2i Nodes Unavailable\n", totUsed, totHosts, perutil, totClosedAdm, totUnavail);

		printf("\n");

		/* List the queues that access these hosts */

		printf("Queues That Run On These Hosts: ");

		j=0;

		for (k=0;k<numoqc;k++) {
			if (k == numoqc-1) {
				printf("%4s", queuelistcheck[k]);
				}
			else {
				printf("%4s, ", queuelistcheck[k]);
			}

			/* Word wrap if list is too long */
			j++;
			if (j == 8) {
				printf("\n");
				j=0;
			}
		}

		printf("\n");
		}
	else if (inp_queue == NULL && inp_hosts == NULL) {
		printf("User Summary\n");

		/* First lets get information on the Queues the User has access to */

		numQueues=0;
		que = lsb_queueinfo(NULL,&numQueues,NULL,user,0);

		numhc=0;
		numhlc=0;

		/* Iterate through the queue list */
		for(k=0;k<numQueues;k++) {

			/* Iterate through the host list which is seperated by spaces */

			i=0;

			for(;;) {

				/* Parse the host list based on predefined delimiters */
				if (i == 0){
					token = strtok(que[k].hostList,delimiters);
					}
				else{
					token = strtok(NULL,delimiters);
				}

				if (token == NULL) break;

				/* We need to trim off slashes */
				saveptr1=strpbrk(token,slash);

				if (saveptr1 != NULL) {
					token[strlen(token)-1]='\0';
				}
				

				/* We will first poll the hosts available to this queue and see what is going on */

				hostlist=token;

				/* We need to check that we aren't double counting host groups */
				alreadycounted=0;

				for(j=0;j<numhlc;j++){
					if (strcmp(hostlist,hostlistcheck[j]) == 0) {
						alreadycounted=1;
						break;
					}
				}

				/* If we've already been counted break out of this loop if not counted then store that data */
				if (alreadycounted == 0) {
					strcpy(hostlistcheck[numhlc],hostlist);
					numhlc++;
					}
				else {
					break;
				}

				/* Query for hostlist information */
				numHosts=1;

				hos = lsb_hostinfo(&hostlist, &numHosts);

				/* Now we are going to check each host for what state it is in */
				/* We will also collect statistics regarding the usage of the host at the same time */
				for (j=0;j<numHosts;j++){
					/* Some hosts lists contain redundant hosts so to make sure we aren't double counting we will check again */

					alreadycounted=0;

					for(ii=0;ii<numhc;ii++){
						if (strcmp(hos[j].host,hostscheck[ii]) == 0) {
							alreadycounted=1;
							break;
						}
					}

					/* If we've already been counted break out of this loop if not counted then store that data */
					if (alreadycounted == 0) {
						strcpy(hostscheck[numhc],hos[j].host);
						numhc++;
						}
					else {
						break;
					}

					totHosts++;

					if (hos[j].hStatus & HOST_STAT_UNLICENSED) {
      						} /* unlicensed */
					else if (hos[j].hStatus & HOST_STAT_UNAVAIL) {
						totUnavail++; /* LIM and sbatchd are unavailable */
						}
    					else if (hos[j].hStatus & HOST_STAT_UNREACH) {
      						totUnavail++; /* sbatchd is unreachable */
						}
    					else if (hos[j].hStatus & HOST_CLOSED_BY_ADMIN) {
						totClosedAdm++; /* host closed by administrator */
						}
					else if (hos[j].hStatus & ( HOST_STAT_WIND | HOST_STAT_DISABLED | HOST_STAT_NO_LIM)) {
      						}
    					else if (hos[j].hStatus & ( HOST_STAT_BUSY | HOST_STAT_FULL | HOST_STAT_LOCKED )) {
						/* Host is full */
						totUsed++;
						totCoresUsed=hos[j].numRUN+totCoresUsed;
						totCores=hos[j].maxJobs+totCores;

						}
					else {
						/* Host is partially used */
						if (hos[j].numRUN > 0) {
							totUsed++;
						}
	
						totCoresUsed=hos[j].numRUN+totCoresUsed;
						totCores=hos[j].maxJobs+totCores;
					}
				}
	
				i=i+1;
			}
		}

		printf("Overall Statistics for Available Queues\n");

		/* Now to print what we found */
		/* Calculate the percentage of cores used */
		perutil=(float)totCoresUsed/(float)totCores*100;

		printf("%4i of %4i Cores Used (%4.2f%%)\n", totCoresUsed, totCores, perutil);

		/* Calculate the percentage of nodes used */
		perutil=(float)totUsed/(float)totHosts*100;

		printf("%4i of %4i Nodes Used (%4.2f%%), %2i Nodes Closed by Admin, %2i Nodes Unavailable\n", totUsed, totHosts, perutil, totClosedAdm, totUnavail);

		printf("\n");

		/* List what queues are available to the user */
		printf("Available Queues: ");

		j=0;

		for (k=0;k<numQueues;k++) {
			if (k == numQueues-1) {
				printf("%4s", que[k].queue);
				}
			else {
				printf("%4s, ", que[k].queue);
				}
			j++;
			/* Word wrap if list is too long */
			if (j == 8) {
				printf("\n");
				j=0;
			}
		}

		printf("\n");
	}
}
Beispiel #6
0
/* Prints out information about the jobs running that fit the defined parameters */
struct numq print_section( int options, char *inp_queue, char *user, char *inp_hosts, int numcoresq, int numnodesq) {

	/* variables for simulating bjobs command */
  	struct jobInfoEnt *job;     /* detailed job info */
  	struct queueInfoEnt *que;   /* detailed queue info */
  	struct numq nq;	      /* information about the queue being polled by the user that we wish to pass on to other routines */
  	int tot_jobs;               /* total jobs */
  	int more;                   /* number of remaining jobs unread */
  	int nodenum;                /* Node number counter */
  	int i,j;		      /* counter*/
  	int alreadycounted;	      /* Logical flag used to figure out if the quantity in question has already been counted*/
  	int numQueues = 1;	      /* number of Queues to poll queue info about */
  	int t;		      /* Time remaining */
  	int tdays;		      /* Time remaining in days */
  	int thrs;		      /* Time remaining in hours */
  	int tmin;		      /* Time remaining in minutes */
  	int tsec;		      /* Time remaining in seconds */	
  	char *targetqueue;       /* array for the queue names to poll queue info about */
  	char startstr[14];          /* string of date when job started */
  	char submitstr[14];         /* string of data when job was submitted */
  	char statstr[5];            /* string of status */  
  	char exclus;		      /* exclusive flag */
  	char nodelistcheck[10000][20]; /* a list of node names that we will compare against to test uniqueness*/
  
  	/* Initialize struct values */
  	nq.cores=numcoresq;
  	nq.nodes=numnodesq;
  
  	/* gets the total number of jobs. Exits if failure */
  	tot_jobs = lsb_openjobinfo(0, NULL, user, inp_queue, inp_hosts, options);
  
  	/* Sanity Checks */
  	if (tot_jobs < 0) { 
    		printf("No matching jobs found\n");
    		return nq;
	}

  	if (tot_jobs<0){ 
    		lsb_perror("lsb_openjobinfo");
    		exit(-1);
	}

  	/* Print header for section */
  	printf("%-12s %-8.8s %-6.6s %-7.7s %-4s  %-14s   %-14s %-14s\n",	\
		 "JOBID", "USER", "STAT", "QUEUE", "CORES/NODES", "TIME REMAINING",		\
		 "SUBMIT TIME", "START TIME");

  	/* Loop over jobs until complete */
  	for (;;) {
    		job = lsb_readjobinfo(&more);   /* get the job details */

    		/* Sanity Check */
    		if (job == NULL) {
      			lsb_perror("lsb_readjobinfo");
      			exit(-1);
    		}

    		/* Store our current target queue */
    		targetqueue=job->submit.queue;

    		/* Grab information about that queue */
    		que = lsb_queueinfo(&targetqueue,&numQueues,NULL,NULL,0);


    		/* Sanity check */
    		if (que == NULL){
			lsb_perror("lsb_queueinfo");
			exit(-1);
    		}


    		/* Detects if the job is running in exclusive mode */
    		exclus=' ';
    		if (job->submit.options & SUB_EXCLUSIVE) {
			exclus='X';
		}

    		/* Counts the Number of nodes */
    		nodenum=1;
    		if (job->numExHosts > 0) {
			for(i=0;i < job->numExHosts-1; i++) {
				if(strcmp(job->exHosts[i],job->exHosts[i+1]) != 0){
					nodenum++; 
				}
			}
		}

    		/* Finds the jobs status */
    		if (job->status == JOB_STAT_RUN){
			strcpy(statstr,"RUN");
			}
    		else if(job->status == JOB_STAT_PEND){
      			strcpy(statstr,"PEND");
			} 
    		else if(job->status == JOB_STAT_PSUSP){
      			strcpy(statstr,"PSUSP");
			} 
    		else if(job->status == JOB_STAT_SSUSP){
      			strcpy(statstr,"SSUSP");
		}

    		/* Test if there is a queue that the user is interested in */
    		if (inp_queue != NULL) {

			/* Stores the number of processors and nodes used by this queue for later use */
			if (job->status == JOB_STAT_RUN && strcmp(inp_queue,targetqueue) == 0) {
				numcoresq=job->submit.numProcessors+numcoresq;

				/* Count the number of unique nodes are used by this queue */
				for (i=0;i < job->numExHosts;i++){
					/* We need to check that we aren't double counting nodes */
					alreadycounted=0;
	
					for(j=0;j<numnodesq;j++){
						if (strcmp(job->exHosts[i],nodelistcheck[j]) == 0) {
							alreadycounted=1;
							break;
						}
					}

					/* If we've already been counted break out of this loop if not counted then store that data */
					if (alreadycounted == 0) {
						strcpy(nodelistcheck[numnodesq],job->exHosts[i]);
						numnodesq++;
					}
				}
			}
		}

    		/* Figures out what time the job was submitted at and when it started running*/    
    		strftime(submitstr,14,"%b %d %R",&(*localtime(&job->submitTime)));
    		strftime(startstr,14,"%b %d %R",&(*localtime(&job->startTime)));

    		/* Calculates Time Remaining */
    		t=que->rLimits[LSF_RLIMIT_RUN]-job->runTime;

    		/* Checks to see if ther termination time is other than the queue limit */
    		if (job->submit.rLimits[LSF_RLIMIT_RUN] > 0) {
			t=job->submit.rLimits[LSF_RLIMIT_RUN]-job->runTime;
		}

    		/* Calculates the Time remaining in Days, Hours, Minutes and Seconds */
    		tdays=t/24/60/60;

    		thrs=t/60/60-24*tdays;

    		tmin=t/60-24*60*tdays-60*thrs;

    		tsec=t-24*60*60*tdays-60*60*thrs-60*tmin;

    		/* Prints out job data */	
    		printf("%-12s %-8.8s %-6.6s %-8.8s %4i%1s%2i%1c       %2i%1s%-2.2i%1s%2.2i%1s%2.2i  %-14s",	\
    			lsb_jobid2str(job->jobId), job->user, statstr, job->submit.queue, \
    			job->submit.numProcessors, "/",nodenum,exclus, tdays,":", thrs,":",tmin,":",tsec ,submitstr);

    		/* Prints out start time if the job is not pending */
    		if (options != PEND_JOB) {
			printf("%-14s",startstr);
		}
	
    		printf ("\n");

    		/* Checks to see if there are more jobs to do. */	
    		if (!more) break;
    	}

	/* Prints the total number of jobs in the section */
  	printf("%-i total jobs\n",tot_jobs);

	/* Store number of cores and nodes used by the queue.  These will have nonzero values if the queue is the one being polled by the user. */
  	nq.cores=numcoresq;
  	nq.nodes=numnodesq;

	/* Transmit that data out of the function */
  	return nq;

}