Пример #1
0
/*
 *
 * decay_fairshare_tree - decay the usage information kept in the fair
 *          share tree
 *
 *   root - the root of the fairshare tree
 *
 * returns nothing
 *
 */
void decay_fairshare_tree(group_info *root)
  {
  if (root == NULL)
    return;

  decay_fairshare_tree(root -> sibling);

  decay_fairshare_tree(root -> child);

  root -> usage /= 2;

  if (root -> usage == 0)
    root -> usage = 1;
  }
Пример #2
0
int init_scheduling_cycle(server_info *sinfo)
  {
  group_info *user; /* the user for the running jobs of the last cycle */
  queue_info *qinfo; /* user to cycle through the queues to sort the jobs */
  char decayed = 0; /* boolean: have we decayed usage? */
  time_t t;  /* used in decaying fair share */
  int i, j;

  if (cstat.fair_share)
    {
    if (last_running != NULL)
      {
      /* add the usage which was accumulated between the last cycle and this
       * one and calculate a new value
       */

      for (i = 0; i < last_running_size ; i++)
        {
        job_info** jobs;
        user = last_running[i].ginfo;
#if HIGH_PRECISION_FAIRSHARE
        jobs = sinfo -> jobs; /* check all jobs (exiting, completed, running) */
#else
        jobs = sinfo -> running_jobs; /* check only running */
#endif

        for (j = 0; jobs[j] != NULL; j++)
          {
            if (jobs[j] -> is_completed || jobs[j] -> is_exiting ||
              jobs[j] -> is_running)
              if (!strcmp(last_running[i].name, jobs[j] -> name))
                break;
          }

        if (jobs[j] != NULL)
          {
          user -> usage +=
            calculate_usage_value(jobs[j] -> resused) -
            calculate_usage_value(last_running[i].resused);
          }
        }

      /* assign usage into temp usage since temp usage is used for usage
       * calculations.  Temp usage starts at usage and can be modified later.
       */
      for (i = 0; i < last_running_size; i++)
        last_running[i].ginfo -> temp_usage = last_running[i].ginfo -> usage;
      }

    /* The half life for the fair share tree might have passed since the last
     * scheduling cycle.  For that matter, several half lives could have
     * passed.  If this is the case, perform as many decays as necessary
     */

    t = cstat.current_time;

    while (t - last_decay > conf.half_life)
      {
      sched_log(PBSEVENT_DEBUG2, PBS_EVENTCLASS_SERVER, "", "Decaying Fairshare Tree");
      decay_fairshare_tree(conf.group_root);
      t -= conf.half_life;
      decayed = 1;
      }

    if (decayed)
      {
      /* set the time to the acuall the half-life should have occured */
      last_decay = cstat.current_time -
                   (cstat.current_time - last_decay) % conf.half_life;
      }

    if (cstat.current_time - last_sync > conf.sync_time)
      {
      write_usage();
      last_sync = cstat.current_time;
      sched_log(PBSEVENT_DEBUG2, PBS_EVENTCLASS_SERVER, "", "Usage Sync");
      }
    }

  if (cstat.help_starving_jobs)
    cstat.starving_job = update_starvation(sinfo -> jobs);

  /* sort queues by priority if requested */

  if (cstat.sort_queues)
    qsort(sinfo -> queues, sinfo -> num_queues, sizeof(queue_info *),
          cmp_queue_prio_dsc);


  if (cstat.sort_by[0].sort != NO_SORT)
    {
    if (cstat.by_queue || cstat.round_robin)
      {
      for (i = 0; i < sinfo -> num_queues; i++)
        {
        qinfo = sinfo -> queues[i];
        qsort(qinfo -> jobs, qinfo -> sc.total, sizeof(job_info *), cmp_sort);
        }
      }
    else
      qsort(sinfo -> jobs, sinfo -> sc.total, sizeof(job_info *), cmp_sort);
    }

  next_job(sinfo, INITIALIZE);

  return 1;  /* SUCCESS */
  }
Пример #3
0
/**
 * @brief
 * 		The entry point of pbsfs
 *
 * @return	int
 * @retval	0	: success
 * @retval	1	: something is wrong!
 */
int
main(int argc, char *argv[])
{
	char path_buf[256] = {0};
	char sched_name[PBS_MAXSCHEDNAME + 1] = "default";
	group_info *ginfo;
	group_info *ginfo2;
	int c;
	int flags = FS_PRINT;
	int flag1 = 0;
	double val;
	char *endp;
	char *testp;

	/* the real deal or output version and exit? */
	PRINT_VERSION_AND_EXIT(argc, argv);
	set_msgdaemonname("pbsfs");

#ifdef WIN32
	if (winsock_init()) {
		return 1;
	}
#endif


	if (pbs_loadconf(0) <= 0)
		exit(1);

	while ((c = getopt(argc, argv, "sgptdceI:-:")) != -1)
		switch (c) {
			case 'g':
				flags = FS_GET;
				break;
			case 's':
				flags = FS_SET | FS_WRITE_FILE;
				break;
			case 'p':
				flags = FS_PRINT;
				break;
			case 't':
				flags = FS_PRINT_TREE;
				break;
			case 'd':
				flags = FS_DECAY | FS_WRITE_FILE;
				break;
			case 'c':
				flags = FS_COMP;
				break;
			case 'e':
				flags = FS_TRIM_TREE | FS_WRITE_FILE;
				break;
			case 'I':
				snprintf(sched_name, sizeof(sched_name), "%s", optarg);
				break;
			case '-':
				flag1 = 1;
				break;
		}

	if (flag1 == 1) {
		fprintf(stderr, "Usage: pbsfs --version\n");
		exit(1);
	}
	if ((flags & (FS_PRINT | FS_PRINT_TREE)) && (argc - optind) != 0) {
		fprintf(stderr, "Usage: pbsfs -[ptdgcs] [-I sched_name]\n");
		exit(1);
	}
	else if ((flags & FS_GET)  && (argc - optind) != 1) {
		fprintf(stderr, "Usage: pbsfs [-I sched_name] -g <fairshare_entity>\n");
		exit(1);
	}
	else if ((flags & FS_SET) && (argc - optind) != 2) {
		fprintf(stderr, "Usage: pbsfs [-I sched_name] -s <fairshare_entity> <usage>\n");
		exit(1);
	}
	else if ((flags & FS_COMP) && (argc - optind) != 2) {
		fprintf(stderr, "Usage: pbsfs [-I sched_name] -c <entity1> <entity2>\n");
		exit(1);
	}

	if (strcmp(sched_name, "default") != 0) {
		int pbs_sd;
		struct batch_status *bs;
		struct batch_status *cur_bs;
		pbs_sd = pbs_connect(NULL);
		if (pbs_sd < 0) {
			fprintf(stderr, "Can't connect to the server\n");
			exit(1);
		}
		bs = pbs_statsched(pbs_sd, NULL, NULL);

		for (cur_bs = bs; cur_bs != NULL; cur_bs = cur_bs->next) {
			if (strcmp(cur_bs->name, sched_name) == 0) {
				struct attrl *cur_attrl;
				for (cur_attrl = cur_bs->attribs; cur_attrl != NULL; cur_attrl = cur_attrl->next) {
					if (strcmp(cur_attrl->name, ATTR_sched_priv) == 0) {
						strncpy(path_buf, cur_attrl->value, sizeof(path_buf));
						path_buf[sizeof(path_buf) - 1] = '\0';
						break;
					}
				}
				if (cur_attrl == NULL) {
					fprintf(stderr, "Scheduler %s does not have its sched_priv set\n", sched_name);
					exit(1);
				}
				break;
			}
		}
		if (cur_bs == NULL) {
			fprintf(stderr, "Scheduler %s does not exist\n", sched_name);
			exit(1);
		}
		pbs_disconnect(pbs_sd);

	} else
		snprintf(path_buf, sizeof(path_buf), "%s/sched_priv/", pbs_conf.pbs_home_path);

	if (chdir(path_buf) == -1) {
		perror("Unable to access fairshare data");
		exit(1);
	}
	init_config();
	parse_config(CONFIG_FILE);
	if ((conf.fairshare = preload_tree()) == NULL) {
		fprintf(stderr, "Error in preloading fairshare information\n");
		return 1;
	}
	if (parse_group(RESGROUP_FILE, conf.fairshare->root) == 0)
		return 1;

	if (flags & FS_TRIM_TREE)
		read_usage(USAGE_FILE, FS_TRIM, conf.fairshare);
	else
		read_usage(USAGE_FILE, 0, conf.fairshare);

	calc_fair_share_perc(conf.fairshare->root->child, UNSPECIFIED);
	calc_usage_factor(conf.fairshare);

	if (flags & FS_PRINT_TREE)
		print_fairshare(conf.fairshare->root, 0);
	else if (flags & FS_PRINT  ) {
		printf("Fairshare usage units are in: %s\n", conf.fairshare_res);
		print_fairshare(conf.fairshare->root, -1);
	}
	else if (flags & FS_DECAY)
		decay_fairshare_tree(conf.fairshare->root);
	else if (flags & (FS_GET | FS_SET | FS_COMP)) {
		ginfo = find_group_info(argv[optind], conf.fairshare->root);

		if (ginfo == NULL) {
			fprintf(stderr, "Fairshare Entity %s does not exist.\n", argv[optind]);
			return 1;
		}
		if (flags & FS_COMP) {
			ginfo2 = find_group_info(argv[optind + 1], conf.fairshare->root);

			if (ginfo2 == NULL) {
				fprintf(stderr, "Fairshare Entity %s does not exist.\n", argv[optind + 1]);
				return 1;
			}
			switch (compare_path(ginfo->gpath, ginfo2->gpath)) {
				case -1:
					printf("%s\n", ginfo->name);
					break;

				case 0:
					printf("%s == %s\n", ginfo->name, ginfo2->name);
					break;

				case 1:
					printf("%s\n", ginfo2->name);
			}
		}
		else if (flags & FS_GET)
			print_fairshare_entity(ginfo);
		else {
			testp = argv[optind + 1];
			val = strtod(testp, &endp);

			if (*endp == '\0')
				ginfo->usage = val;
		}
	}

	if (flags & FS_WRITE_FILE) {
		FILE *fp;
		/* make backup of database file */
		remove(USAGE_FILE ".bak");
		if (rename(USAGE_FILE, USAGE_FILE ".bak") < 0)
			perror("Could not backup usage database.");
		write_usage(USAGE_FILE, conf.fairshare);
		if ((fp = fopen(USAGE_TOUCH, "w")) != NULL)
			fclose(fp);
	}

	return 0;
}