Esempio n. 1
0
extern void print_fields_header(List print_fields_list)
{
	ListIterator itr = NULL;
	print_field_t *field = NULL;
	int curr_inx = 1;
	int field_count = 0;

	if (!print_fields_list || !print_fields_have_header)
		return;

	field_count = list_count(print_fields_list);

	itr = list_iterator_create(print_fields_list);
	while ((field = list_next(itr))) {
		if (print_fields_parsable_print
		   == PRINT_FIELDS_PARSABLE_NO_ENDING
		   && (curr_inx == field_count))
			printf("%s", field->name);
		else if (print_fields_parsable_print
			 && fields_delimiter) {
			printf("%s%s", field->name, fields_delimiter);
		} else if (print_fields_parsable_print
			 && !fields_delimiter) {
			printf("%s|", field->name);

		} else {
			int abs_len = abs(field->len);
			printf("%*.*s ", abs_len, abs_len, field->name);
		}
		curr_inx++;
	}
	list_iterator_reset(itr);
	printf("\n");
	if (print_fields_parsable_print)
		return;
	while ((field = list_next(itr))) {
		int abs_len = abs(field->len);
		printf("%*.*s ", abs_len, abs_len,
		       "-----------------------------------------------------");
	}
	list_iterator_destroy(itr);
	printf("\n");
}
Esempio n. 2
0
/**
 * Destroys a connection, as well as all the transactions it contains. It is
 * not possible to destroy a connection structure yet leave any of its
 * transactions intact. This is because transactions need its connection and
 * connection structures hold little data anyway. The opposite is true, though
 * it is possible to delete a transaction but leave its connection alive.
 *
 * @param conn
 */
void htp_conn_destroy(htp_conn_t *conn) {
    if (conn == NULL) return;
    
    // Destroy individual transactions. Do note that iterating
    // using the iterator does not work here because some of the
    // list element may be NULL (and with the iterator it is impossible
    // to distinguish a NULL element from the end of the list).
    if (conn->transactions != NULL) {
        size_t i;
        for (i = 0; i < list_size(conn->transactions); i++) {
            htp_tx_t *tx = (htp_tx_t *)list_get(conn->transactions, i);
            if (tx != NULL) {
                htp_tx_destroy(tx);
            }
        }

        list_destroy(conn->transactions);
    }

    // Destroy individual messages
    if (conn->messages != NULL) {
        htp_log_t *l = NULL;
        list_iterator_reset(conn->messages);
        while ((l = list_iterator_next(conn->messages)) != NULL) {
            free((void *)l->msg);
            free(l);
        }

        list_destroy(conn->messages);
    }

    if (conn->local_addr != NULL) {
        free(conn->local_addr);
    }

    if (conn->remote_addr != NULL) {
        free(conn->remote_addr);
    }
   
    // Finally, destroy the connection
    // structure itself.
    free(conn);
}
Esempio n. 3
0
static int _check_status()
{
	ListIterator itr = list_iterator_create(block_list);
	int i=0;
	block_info_msg_t *block_ptr = NULL;
	char *block_name = NULL;

	while (list_count(block_list)) {
		info("waiting for %d bgblocks to free...",
		     list_count(block_list));
		if (_get_new_info_block(&block_ptr)
		    == SLURM_SUCCESS) {
			while ((block_name = list_next(itr))) {
				for (i=0; i<block_ptr->record_count;
				     i++) {
					if (!xstrcmp(block_name,
						     block_ptr->
						     block_array[i].
						     bg_block_id)) {
						if (block_ptr->
						    block_array[i].
						    state == BG_BLOCK_FREE)
							list_delete_item(itr);
						break;
					}
				}
				/* Here if we didn't find the record
				   it is gone so we just will delete it. */
				if (i >= block_ptr->record_count)
					list_delete_item(itr);
			}
			list_iterator_reset(itr);
		}
		sleep(1);
	}
	list_iterator_destroy(itr);
	return SLURM_SUCCESS;
}
Esempio n. 4
0
static int query_consoles_via_globbing(
    server_conf_t *conf, req_t *req, List matches)
{
/*  Match request patterns against console names using shell-style globbing.
 *  This is less efficient than matching via regular expressions
 *    since the console list must be traversed for each pattern, and the
 *    matches list must be traversed for each match to prevent duplicates.
 */
    char *p;
    ListIterator i, j;
    char *pat;
    obj_t *obj;

    /*  An empty list for the QUERY command matches all consoles.
     */
    if (list_is_empty(req->consoles)) {
        p = create_string("*");
        list_append(req->consoles, p);
    }

    /*  Search objs for console names matching console patterns in the request.
     */
    i = list_iterator_create(req->consoles);
    j = list_iterator_create(conf->objs);
    while ((pat = list_next(i))) {
        list_iterator_reset(j);
        while ((obj = list_next(j))) {
            if (!is_console_obj(obj))
                continue;
            if (!fnmatch(pat, obj->name, 0)
              && !list_find_first(matches, (ListFindF) find_obj, obj))
                list_append(matches, obj);
        }
    }
    list_iterator_destroy(i);
    list_iterator_destroy(j);
    return(0);
}
Esempio n. 5
0
VALUE rbhtp_conn_transactions( VALUE self )
{
	htp_conn_t* conn = NULL;
	Data_Get_Struct( rb_iv_get( self, "@conn" ), htp_conn_t, conn );
	
	if ( conn->transactions == NULL ) return Qnil;
	
	VALUE connp = rb_iv_get( self, "@connp" );
	VALUE cfg = rb_iv_get( connp, "@cfg" );
	
	htp_tx_t* v;
	VALUE r = rb_ary_new();
	list_iterator_reset( conn->transactions );
	while ( ( v = list_iterator_next( conn->transactions ) ) != NULL ) {
		rb_ary_push( r,
			rb_funcall( cTx, rb_intern( "new" ), 3,
				Data_Wrap_Struct( rb_cObject, 0, 0, v ),
				cfg,
				connp
			)
		);
	}
	return r;
}
extern int as_mysql_hourly_rollup(mysql_conn_t *mysql_conn,
				  char *cluster_name,
				  time_t start, time_t end,
				  uint16_t archive_data)
{
	int rc = SLURM_SUCCESS;
	int add_sec = 3600;
	int i=0;
	time_t now = time(NULL);
	time_t curr_start = start;
	time_t curr_end = curr_start + add_sec;
	char *query = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	ListIterator a_itr = NULL;
	ListIterator c_itr = NULL;
	ListIterator w_itr = NULL;
	ListIterator r_itr = NULL;
	List assoc_usage_list = list_create(_destroy_local_id_usage);
	List cluster_down_list = list_create(_destroy_local_cluster_usage);
	List wckey_usage_list = list_create(_destroy_local_id_usage);
	List resv_usage_list = list_create(_destroy_local_resv_usage);
	uint16_t track_wckey = slurm_get_track_wckey();
	/* char start_char[20], end_char[20]; */

	char *job_req_inx[] = {
		"job.job_db_inx",
		"job.id_job",
		"job.id_assoc",
		"job.id_wckey",
		"job.array_task_pending",
		"job.time_eligible",
		"job.time_start",
		"job.time_end",
		"job.time_suspended",
		"job.cpus_alloc",
		"job.cpus_req",
		"job.id_resv",
		"SUM(step.consumed_energy)"
	};
	char *job_str = NULL;
	enum {
		JOB_REQ_DB_INX,
		JOB_REQ_JOBID,
		JOB_REQ_ASSOCID,
		JOB_REQ_WCKEYID,
		JOB_REQ_ARRAY_PENDING,
		JOB_REQ_ELG,
		JOB_REQ_START,
		JOB_REQ_END,
		JOB_REQ_SUSPENDED,
		JOB_REQ_ACPU,
		JOB_REQ_RCPU,
		JOB_REQ_RESVID,
		JOB_REQ_ENERGY,
		JOB_REQ_COUNT
	};

	char *suspend_req_inx[] = {
		"time_start",
		"time_end"
	};
	char *suspend_str = NULL;
	enum {
		SUSPEND_REQ_START,
		SUSPEND_REQ_END,
		SUSPEND_REQ_COUNT
	};

	char *resv_req_inx[] = {
		"id_resv",
		"assoclist",
		"cpus",
		"flags",
		"time_start",
		"time_end"
	};
	char *resv_str = NULL;
	enum {
		RESV_REQ_ID,
		RESV_REQ_ASSOCS,
		RESV_REQ_CPU,
		RESV_REQ_FLAGS,
		RESV_REQ_START,
		RESV_REQ_END,
		RESV_REQ_COUNT
	};

	i=0;
	xstrfmtcat(job_str, "%s", job_req_inx[i]);
	for(i=1; i<JOB_REQ_COUNT; i++) {
		xstrfmtcat(job_str, ", %s", job_req_inx[i]);
	}

	i=0;
	xstrfmtcat(suspend_str, "%s", suspend_req_inx[i]);
	for(i=1; i<SUSPEND_REQ_COUNT; i++) {
		xstrfmtcat(suspend_str, ", %s", suspend_req_inx[i]);
	}

	i=0;
	xstrfmtcat(resv_str, "%s", resv_req_inx[i]);
	for(i=1; i<RESV_REQ_COUNT; i++) {
		xstrfmtcat(resv_str, ", %s", resv_req_inx[i]);
	}

/* 	info("begin start %s", slurm_ctime(&curr_start)); */
/* 	info("begin end %s", slurm_ctime(&curr_end)); */
	a_itr = list_iterator_create(assoc_usage_list);
	c_itr = list_iterator_create(cluster_down_list);
	w_itr = list_iterator_create(wckey_usage_list);
	r_itr = list_iterator_create(resv_usage_list);
	while (curr_start < end) {
		int last_id = -1;
		int last_wckeyid = -1;
		int seconds = 0;
		int tot_time = 0;
		local_cluster_usage_t *loc_c_usage = NULL;
		local_cluster_usage_t *c_usage = NULL;
		local_resv_usage_t *r_usage = NULL;
		local_id_usage_t *a_usage = NULL;
		local_id_usage_t *w_usage = NULL;

		if (debug_flags & DEBUG_FLAG_DB_USAGE)
			DB_DEBUG(mysql_conn->conn,
				 "%s curr hour is now %ld-%ld",
				 cluster_name, curr_start, curr_end);
/* 		info("start %s", slurm_ctime(&curr_start)); */
/* 		info("end %s", slurm_ctime(&curr_end)); */

		c_usage = _setup_cluster_usage(mysql_conn, cluster_name,
					       curr_start, curr_end,
					       cluster_down_list);

		// now get the reservations during this time
		/* If a reservation has the IGNORE_JOBS flag we don't
		 * have an easy way to distinguish the cpus a job not
		 * running in the reservation, but on it's cpus.
		 * So we will just ignore these reservations for
		 * accounting purposes.
		 */
		query = xstrdup_printf("select %s from \"%s_%s\" where "
				       "(time_start < %ld && time_end >= %ld) "
				       "&& !(flags & %u)"
				       "order by time_start",
				       resv_str, cluster_name, resv_table,
				       curr_end, curr_start,
				       RESERVE_FLAG_IGN_JOBS);

		if (debug_flags & DEBUG_FLAG_DB_USAGE)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		if (!(result = mysql_db_query_ret(
			      mysql_conn, query, 0))) {
			xfree(query);
			_destroy_local_cluster_usage(c_usage);
			return SLURM_ERROR;
		}
		xfree(query);

		/* If a reservation overlaps another reservation we
		   total up everything here as if they didn't but when
		   calculating the total time for a cluster we will
		   remove the extra time received.  This may result in
		   unexpected results with association based reports
		   since the association is given the total amount of
		   time of each reservation, thus equaling more time
		   than is available.  Job/Cluster/Reservation reports
		   should be fine though since we really don't over
		   allocate resources.  The issue with us not being
		   able to handle overlapping reservations here is
		   unless the reservation completely overlaps the
		   other reservation we have no idea how many cpus
		   should be removed since this could be a
		   heterogeneous system.  This same problem exists
		   when a reservation is created with the ignore_jobs
		   option which will allow jobs to continue to run in the
		   reservation that aren't suppose to.
		*/
		while ((row = mysql_fetch_row(result))) {
			time_t row_start = slurm_atoul(row[RESV_REQ_START]);
			time_t row_end = slurm_atoul(row[RESV_REQ_END]);
			uint32_t row_cpu = slurm_atoul(row[RESV_REQ_CPU]);
			uint32_t row_flags = slurm_atoul(row[RESV_REQ_FLAGS]);

			if (row_start < curr_start)
				row_start = curr_start;

			if (!row_end || row_end > curr_end)
				row_end = curr_end;

			/* Don't worry about it if the time is less
			 * than 1 second.
			 */
			if ((row_end - row_start) < 1)
				continue;

			r_usage = xmalloc(sizeof(local_resv_usage_t));
			r_usage->id = slurm_atoul(row[RESV_REQ_ID]);

			r_usage->local_assocs = list_create(slurm_destroy_char);
			slurm_addto_char_list(r_usage->local_assocs,
					      row[RESV_REQ_ASSOCS]);

			r_usage->total_time = (row_end - row_start) * row_cpu;
			r_usage->start = row_start;
			r_usage->end = row_end;
			list_append(resv_usage_list, r_usage);

			/* Since this reservation was added to the
			   cluster and only certain people could run
			   there we will use this as allocated time on
			   the system.  If the reservation was a
			   maintenance then we add the time to planned
			   down time.
			*/


			/* only record time for the clusters that have
			   registered.  This continue should rarely if
			   ever happen.
			*/
			if (!c_usage)
				continue;
			else if (row_flags & RESERVE_FLAG_MAINT)
				c_usage->pd_cpu += r_usage->total_time;
			else
				c_usage->a_cpu += r_usage->total_time;
			/* slurm_make_time_str(&r_usage->start, start_char, */
			/* 		    sizeof(start_char)); */
			/* slurm_make_time_str(&r_usage->end, end_char, */
			/* 		    sizeof(end_char)); */
			/* info("adding this much %lld to cluster %s " */
			/*      "%d %d %s - %s", */
			/*      r_usage->total_time, c_usage->name, */
			/*      (row_flags & RESERVE_FLAG_MAINT),  */
			/*      r_usage->id, start_char, end_char); */
		}
		mysql_free_result(result);

		/* now get the jobs during this time only  */
		query = xstrdup_printf("select %s from \"%s_%s\" as job "
				       "left outer join \"%s_%s\" as step on "
				       "job.job_db_inx=step.job_db_inx "
				       "and (step.id_step>=0) "
				       "where (job.time_eligible < %ld && "
				       "(job.time_end >= %ld || "
				       "job.time_end = 0)) "
				       "group by job.job_db_inx "
				       "order by job.id_assoc, "
				       "job.time_eligible",
				       job_str, cluster_name, job_table,
				       cluster_name, step_table,
				       curr_end, curr_start);

		if (debug_flags & DEBUG_FLAG_DB_USAGE)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		if (!(result = mysql_db_query_ret(
			      mysql_conn, query, 0))) {
			xfree(query);
			_destroy_local_cluster_usage(c_usage);
			return SLURM_ERROR;
		}
		xfree(query);

		while ((row = mysql_fetch_row(result))) {
			uint32_t job_id = slurm_atoul(row[JOB_REQ_JOBID]);
			uint32_t assoc_id = slurm_atoul(row[JOB_REQ_ASSOCID]);
			uint32_t wckey_id = slurm_atoul(row[JOB_REQ_WCKEYID]);
			uint32_t array_pending =
				slurm_atoul(row[JOB_REQ_ARRAY_PENDING]);
			uint32_t resv_id = slurm_atoul(row[JOB_REQ_RESVID]);
			time_t row_eligible = slurm_atoul(row[JOB_REQ_ELG]);
			time_t row_start = slurm_atoul(row[JOB_REQ_START]);
			time_t row_end = slurm_atoul(row[JOB_REQ_END]);
			uint32_t row_acpu = slurm_atoul(row[JOB_REQ_ACPU]);
			uint32_t row_rcpu = slurm_atoul(row[JOB_REQ_RCPU]);
			uint64_t row_energy = 0;
			int loc_seconds = 0;
			seconds = 0;

			if (row[JOB_REQ_ENERGY])
				row_energy = slurm_atoull(row[JOB_REQ_ENERGY]);
			if (row_start && (row_start < curr_start))
				row_start = curr_start;

			if (!row_start && row_end)
				row_start = row_end;

			if (!row_end || row_end > curr_end)
				row_end = curr_end;

			if (!row_start || ((row_end - row_start) < 1))
				goto calc_cluster;

			seconds = (row_end - row_start);

			if (slurm_atoul(row[JOB_REQ_SUSPENDED])) {
				MYSQL_RES *result2 = NULL;
				MYSQL_ROW row2;
				/* get the suspended time for this job */
				query = xstrdup_printf(
					"select %s from \"%s_%s\" where "
					"(time_start < %ld && (time_end >= %ld "
					"|| time_end = 0)) && job_db_inx=%s "
					"order by time_start",
					suspend_str, cluster_name,
					suspend_table,
					curr_end, curr_start,
					row[JOB_REQ_DB_INX]);

				debug4("%d(%s:%d) query\n%s",
				       mysql_conn->conn, THIS_FILE,
				       __LINE__, query);
				if (!(result2 = mysql_db_query_ret(
					      mysql_conn,
					      query, 0))) {
					xfree(query);
					_destroy_local_cluster_usage(c_usage);
					return SLURM_ERROR;
				}
				xfree(query);
				while ((row2 = mysql_fetch_row(result2))) {
					time_t local_start = slurm_atoul(
						row2[SUSPEND_REQ_START]);
					time_t local_end = slurm_atoul(
						row2[SUSPEND_REQ_END]);

					if (!local_start)
						continue;

					if (row_start > local_start)
						local_start = row_start;
					if (row_end < local_end)
						local_end = row_end;
					tot_time = (local_end - local_start);
					if (tot_time < 1)
						continue;

					seconds -= tot_time;
				}
				mysql_free_result(result2);
			}
			if (seconds < 1) {
				debug4("This job (%u) was suspended "
				       "the entire hour", job_id);
				continue;
			}

			if (last_id != assoc_id) {
				a_usage = xmalloc(sizeof(local_id_usage_t));
				a_usage->id = assoc_id;
				list_append(assoc_usage_list, a_usage);
				last_id = assoc_id;
			}

			a_usage->a_cpu += seconds * row_acpu;
			a_usage->energy += row_energy;

			if (!track_wckey)
				goto calc_cluster;

			/* do the wckey calculation */
			if (last_wckeyid != wckey_id) {
				list_iterator_reset(w_itr);
				while ((w_usage = list_next(w_itr)))
					if (w_usage->id == wckey_id)
						break;

				if (!w_usage) {
					w_usage = xmalloc(
						sizeof(local_id_usage_t));
					w_usage->id = wckey_id;
					list_append(wckey_usage_list,
						    w_usage);
				}

				last_wckeyid = wckey_id;
			}
			w_usage->a_cpu += seconds * row_acpu;
			w_usage->energy += row_energy;
			/* do the cluster allocated calculation */
		calc_cluster:

			/* Now figure out there was a disconnected
			   slurmctld durning this job.
			*/
			list_iterator_reset(c_itr);
			while ((loc_c_usage = list_next(c_itr))) {
				int temp_end = row_end;
				int temp_start = row_start;
				if (loc_c_usage->start > temp_start)
					temp_start = loc_c_usage->start;
				if (loc_c_usage->end < temp_end)
					temp_end = loc_c_usage->end;
				loc_seconds = (temp_end - temp_start);
				if (loc_seconds < 1)
					continue;

				loc_seconds *= row_acpu;
				/* info(" Job %u was running for " */
				/*      "%d seconds while " */
				/*      "cluster %s's slurmctld " */
				/*      "wasn't responding", */
				/*      job_id, loc_seconds, cluster_name); */
				if (loc_seconds >= loc_c_usage->total_time)
					loc_c_usage->total_time = 0;
				else {
					loc_c_usage->total_time -=
						loc_seconds * row_acpu;
				}
			}

			/* first figure out the reservation */
			if (resv_id) {
				if (seconds <= 0)
					continue;
				/* Since we have already added the
				   entire reservation as used time on
				   the cluster we only need to
				   calculate the used time for the
				   reservation and then divy up the
				   unused time over the associations
				   able to run in the reservation.
				   Since the job was to run, or ran a
				   reservation we don't care about
				   eligible time since that could
				   totally skew the clusters reserved time
				   since the job may be able to run
				   outside of the reservation. */
				list_iterator_reset(r_itr);
				while ((r_usage = list_next(r_itr))) {
					/* since the reservation could
					   have changed in some way,
					   thus making a new
					   reservation record in the
					   database, we have to make
					   sure all the reservations
					   are checked to see if such
					   a thing has happened */
					if (r_usage->id == resv_id) {
						int temp_end = row_end;
						int temp_start = row_start;
						if (r_usage->start > temp_start)
							temp_start =
								r_usage->start;
						if (r_usage->end < temp_end)
							temp_end = r_usage->end;

						if ((temp_end - temp_start)
						    > 0) {
							r_usage->a_cpu +=
								(temp_end
								 - temp_start)
								* row_acpu;
						}
					}
				}
				continue;
			}

			/* only record time for the clusters that have
			   registered.  This continue should rarely if
			   ever happen.
			*/
			if (!c_usage)
				continue;

			if (row_start && (seconds > 0)) {
				/* info("%d assoc %d adds " */
				/*      "(%d)(%d-%d) * %d = %d " */
				/*      "to %d", */
				/*      job_id, */
				/*      a_usage->id, */
				/*      seconds, */
				/*      row_end, row_start, */
				/*      row_acpu, */
				/*      seconds * row_acpu, */
				/*      row_acpu); */

				c_usage->a_cpu += seconds * row_acpu;
				c_usage->energy += row_energy;
			}

			/* now reserved time */
			if (!row_start || (row_start >= c_usage->start)) {
				int temp_end = row_start;
				int temp_start = row_eligible;
				if (c_usage->start > temp_start)
					temp_start = c_usage->start;
				if (c_usage->end < temp_end)
					temp_end = c_usage->end;
				loc_seconds = (temp_end - temp_start);
				if (loc_seconds > 0) {
					/* If we have pending jobs in
					   an array they haven't been
					   inserted into the database
					   yet as proper job records,
					   so handle them here.
					*/
					if (array_pending)
						loc_seconds *= array_pending;

					/* info("%d assoc %d reserved " */
					/*      "(%d)(%d-%d) * %d * %d = %d " */
					/*      "to %d", */
					/*      job_id, */
					/*      assoc_id, */
					/*      temp_end - temp_start, */
					/*      temp_end, temp_start, */
					/*      row_rcpu, */
					/*      array_pending, */
					/*      loc_seconds, */
					/*      row_rcpu); */

					c_usage->r_cpu +=
						loc_seconds * row_rcpu;
				}
			}
		}
		mysql_free_result(result);

		/* now figure out how much more to add to the
		   associations that could had run in the reservation
		*/
		list_iterator_reset(r_itr);
		while ((r_usage = list_next(r_itr))) {
			int64_t idle = r_usage->total_time - r_usage->a_cpu;
			char *assoc = NULL;
			ListIterator tmp_itr = NULL;

			if (idle <= 0)
				continue;

			/* now divide that time by the number of
			   associations in the reservation and add
			   them to each association */
			seconds = idle / list_count(r_usage->local_assocs);
/* 			info("resv %d got %d for seconds for %d assocs", */
/* 			     r_usage->id, seconds, */
/* 			     list_count(r_usage->local_assocs)); */
			tmp_itr = list_iterator_create(r_usage->local_assocs);
			while ((assoc = list_next(tmp_itr))) {
				uint32_t associd = slurm_atoul(assoc);
				if (last_id != associd) {
					list_iterator_reset(a_itr);
					while ((a_usage = list_next(a_itr))) {
						if (a_usage->id == associd) {
							last_id = a_usage->id;
							break;
						}
					}
				}

				if (!a_usage) {
					a_usage = xmalloc(
						sizeof(local_id_usage_t));
					a_usage->id = associd;
					list_append(assoc_usage_list, a_usage);
					last_id = associd;
				}

				a_usage->a_cpu += seconds;
			}
			list_iterator_destroy(tmp_itr);
		}

		/* now apply the down time from the slurmctld disconnects */
		if (c_usage) {
			list_iterator_reset(c_itr);
			while ((loc_c_usage = list_next(c_itr)))
				c_usage->d_cpu += loc_c_usage->total_time;

			if ((rc = _process_cluster_usage(
				     mysql_conn, cluster_name, curr_start,
				     curr_end, now, c_usage))
			    != SLURM_SUCCESS) {
				_destroy_local_cluster_usage(c_usage);
				goto end_it;
			}
		}

		list_iterator_reset(a_itr);
		while ((a_usage = list_next(a_itr))) {
/* 			info("association (%d) %d alloc %d", */
/* 			     a_usage->id, last_id, */
/* 			     a_usage->a_cpu); */
			if (query) {
				xstrfmtcat(query,
					   ", (%ld, %ld, %d, %ld, %"PRIu64", "
					   "%"PRIu64")",
					   now, now,
					   a_usage->id, curr_start,
					   a_usage->a_cpu, a_usage->energy);
			} else {
				xstrfmtcat(query,
					   "insert into \"%s_%s\" "
					   "(creation_time, "
					   "mod_time, id_assoc, time_start, "
					   "alloc_cpu_secs, consumed_energy) "
					   "values "
					   "(%ld, %ld, %d, %ld, %"PRIu64", "
					   "%"PRIu64")",
					   cluster_name, assoc_hour_table,
					   now, now,
					   a_usage->id, curr_start,
					   a_usage->a_cpu, a_usage->energy);
			}
		}
		if (query) {
			xstrfmtcat(query,
				   " on duplicate key update "
				   "mod_time=%ld, "
				   "alloc_cpu_secs=VALUES(alloc_cpu_secs), "
				   "consumed_energy=VALUES(consumed_energy);",
				   now);

			if (debug_flags & DEBUG_FLAG_DB_USAGE)
				DB_DEBUG(mysql_conn->conn, "query\n%s", query);
			rc = mysql_db_query(mysql_conn, query);
			xfree(query);
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add assoc hour rollup");
				_destroy_local_cluster_usage(c_usage);
				goto end_it;
			}
		}

		if (!track_wckey)
			goto end_loop;

		list_iterator_reset(w_itr);
		while ((w_usage = list_next(w_itr))) {
/* 			info("association (%d) %d alloc %d", */
/* 			     w_usage->id, last_id, */
/* 			     w_usage->a_cpu); */
			if (query) {
				xstrfmtcat(query,
					   ", (%ld, %ld, %d, %ld, "
					   "%"PRIu64", %"PRIu64")",
					   now, now,
					   w_usage->id, curr_start,
					   w_usage->a_cpu, w_usage->energy);
			} else {
				xstrfmtcat(query,
					   "insert into \"%s_%s\" "
					   "(creation_time, "
					   "mod_time, id_wckey, time_start, "
					   "alloc_cpu_secs, consumed_energy) "
					   "values "
					   "(%ld, %ld, %d, %ld, "
					   "%"PRIu64", %"PRIu64")",
					   cluster_name, wckey_hour_table,
					   now, now,
					   w_usage->id, curr_start,
					   w_usage->a_cpu, w_usage->energy);
			}
		}
		if (query) {
			xstrfmtcat(query,
				   " on duplicate key update "
				   "mod_time=%ld, "
				   "alloc_cpu_secs=VALUES(alloc_cpu_secs), "
				   "consumed_energy=VALUES(consumed_energy);",
				   now);

			if (debug_flags & DEBUG_FLAG_DB_USAGE)
				DB_DEBUG(mysql_conn->conn, "query\n%s", query);
			rc = mysql_db_query(mysql_conn, query);
			xfree(query);
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add wckey hour rollup");
				_destroy_local_cluster_usage(c_usage);
				goto end_it;
			}
		}

	end_loop:
		_destroy_local_cluster_usage(c_usage);
		list_flush(assoc_usage_list);
		list_flush(cluster_down_list);
		list_flush(wckey_usage_list);
		list_flush(resv_usage_list);
		curr_start = curr_end;
		curr_end = curr_start + add_sec;
	}
end_it:
	xfree(suspend_str);
	xfree(job_str);
	xfree(resv_str);
	list_iterator_destroy(a_itr);
	list_iterator_destroy(c_itr);
	list_iterator_destroy(w_itr);
	list_iterator_destroy(r_itr);

	list_destroy(assoc_usage_list);
	list_destroy(cluster_down_list);
	list_destroy(wckey_usage_list);
	list_destroy(resv_usage_list);

/* 	info("stop start %s", slurm_ctime(&curr_start)); */
/* 	info("stop end %s", slurm_ctime(&curr_end)); */

	/* go check to see if we archive and purge */

	if (rc == SLURM_SUCCESS)
		rc = _process_purge(mysql_conn, cluster_name, archive_data,
				    SLURMDB_PURGE_HOURS);

	return rc;
}
Esempio n. 7
0
/* sacctmgr_list_tres()
 */
int
sacctmgr_list_tres(int argc, char **argv)
{
        List tres_list;
        ListIterator itr;
	ListIterator itr2;
	List format_list;
	List print_fields_list;
        slurmdb_tres_cond_t cond;
        slurmdb_tres_rec_t *tres;
	int field_count;
	print_field_t *field;

	format_list = list_create(slurm_destroy_char);
	/* Append to the format list the fields
	 * we want to print, these are the data structure
	 * members of the type returned by slurmdbd
	 */
	slurm_addto_char_list(format_list, "Type,Name%15,ID");

	if (exit_code) {
		FREE_NULL_LIST(format_list);
		return SLURM_ERROR;
	}

	/* Process the format list creating a list of
	 * print field_t structures
	 */
	print_fields_list = sacctmgr_process_format_list(format_list);
	FREE_NULL_LIST(format_list);

	/* Call slurmdbd to get all tres with not
	 * condition
	 */
        memset(&cond, 0, sizeof(slurmdb_tres_cond_t));
        tres_list = acct_storage_g_get_tres(db_conn, my_uid, &cond);

        itr = list_iterator_create(tres_list);
	itr2 = list_iterator_create(print_fields_list);
	print_fields_header(print_fields_list);
	field_count = list_count(print_fields_list);

	/* For each tres prints the data structure members
	 */
        while ((tres = list_next(itr))) {
		while ((field = list_next(itr2))) {
			switch (field->type) {
				case PRINT_NAME:
					field->print_routine(field,
							     tres->name,
							     field_count);
					break;
				case PRINT_ID:
					field->print_routine(field,
							     tres->id,
							     field_count);
					break;
				case PRINT_TYPE:
					field->print_routine(field,
							     tres->type,
							     field_count);
					break;
			}
		}
		list_iterator_reset(itr2);
		printf("\n");
        }
	list_iterator_destroy(itr);
	list_iterator_destroy(itr2);
	FREE_NULL_LIST(tres_list);
	FREE_NULL_LIST(print_fields_list);

        return 0;
}
Esempio n. 8
0
static List _process_grouped_report(
	void *db_conn, slurmdb_job_cond_t *job_cond, List grouping_list,
	bool flat_view, bool wckey_type, bool both)
{
	int exit_code = 0;
	void *object = NULL, *object2 = NULL;

	ListIterator itr = NULL, itr2 = NULL;
	ListIterator cluster_itr = NULL;
	ListIterator local_itr = NULL;
	ListIterator acct_itr = NULL;
	ListIterator group_itr = NULL;

	slurmdb_job_rec_t *job = NULL;
	slurmdb_report_cluster_grouping_t *cluster_group = NULL;
	slurmdb_report_acct_grouping_t *acct_group = NULL;
	slurmdb_report_job_grouping_t *job_group = NULL;

	List job_list = NULL;
	List cluster_list = NULL;
	List object_list = NULL, object2_list = NULL;

	List tmp_acct_list = NULL;
	bool destroy_job_cond = 0;
	bool destroy_grouping_list = 0;
	bool individual = 0;

	uid_t my_uid = getuid();

	/* we don't want to actually query by accounts in the jobs
	   here since we may be looking for sub accounts of a specific
	   account.
	*/
	if (!job_cond) {
		destroy_job_cond = 1;
		job_cond = xmalloc(sizeof(slurmdb_job_cond_t));
	}
	if (!grouping_list) {
		destroy_grouping_list = 1;
		grouping_list = list_create(slurm_destroy_char);
		slurm_addto_char_list(grouping_list, "50,250,500,1000");
	}

	tmp_acct_list = job_cond->acct_list;
	job_cond->acct_list = NULL;

	job_list = jobacct_storage_g_get_jobs_cond(db_conn, my_uid, job_cond);
	job_cond->acct_list = tmp_acct_list;
	tmp_acct_list = NULL;

	if (!job_list) {
		exit_code=1;
		fprintf(stderr, " Problem with job query.\n");
		goto end_it;
	}

	group_itr = list_iterator_create(grouping_list);
	/* make a group for each job size we find. */
	if (!list_count(grouping_list)) {
		char *group = NULL;
		char *tmp = NULL;
		individual = 1;
		itr = list_iterator_create(job_list);
		while((job = list_next(itr))) {
			if (!job->elapsed || !job->alloc_cpus)
				continue;
			tmp = xstrdup_printf("%u", job->alloc_cpus);
			while((group = list_next(group_itr))) {
				if (!strcmp(group, tmp)) {
					break;
				}
			}
			if (!group)
				list_append(grouping_list, tmp);
			else
				xfree(tmp);
			list_iterator_reset(group_itr);
		}
		list_iterator_destroy(itr);
		list_sort(grouping_list, (ListCmpF)_sort_group_asc);
	}

	cluster_list = list_create(slurmdb_destroy_report_cluster_grouping);

	cluster_itr = list_iterator_create(cluster_list);

	if (flat_view)
		goto no_objects;

	if (!wckey_type || both) {
		slurmdb_association_cond_t assoc_cond;
		memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
		assoc_cond.id_list = job_cond->associd_list;
		assoc_cond.cluster_list = job_cond->cluster_list;
		/* don't limit associations to having the partition_list */
		//assoc_cond.partition_list = job_cond->partition_list;
		if (!job_cond->acct_list || !list_count(job_cond->acct_list)) {
			if (job_cond->acct_list)
				list_destroy(job_cond->acct_list);
			job_cond->acct_list = list_create(NULL);
			list_append(job_cond->acct_list, "root");
		}
		assoc_cond.parent_acct_list = job_cond->acct_list;
		object_list = acct_storage_g_get_associations(db_conn, my_uid,
							      &assoc_cond);
	}

	if (wckey_type || both) {
		slurmdb_wckey_cond_t wckey_cond;
		memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t));
		wckey_cond.name_list = job_cond->wckey_list;
		wckey_cond.cluster_list = job_cond->cluster_list;

		object2_list = acct_storage_g_get_wckeys(db_conn, my_uid,
							 &wckey_cond);
		if (!object_list) {
			object_list = object2_list;
			object2_list = NULL;
		}
	}

	if (!object_list) {
		debug2(" No join list given.\n");
		goto no_objects;
	}

	itr = list_iterator_create(object_list);
	if (object2_list)
		itr2 = list_iterator_create(object2_list);
	while((object = list_next(itr))) {
		char *cluster = NULL;
		slurmdb_wckey_rec_t *wckey = (slurmdb_wckey_rec_t *)object;
		slurmdb_association_rec_t *assoc =
			(slurmdb_association_rec_t *)object;
		if (!itr2) {
			char *name = NULL;
			if (wckey_type) {
				cluster = wckey->cluster;
				name = wckey->name;
			} else {
				cluster = assoc->cluster;
				name = assoc->acct;
			}
			_check_create_grouping(cluster_list, group_itr,
					       cluster, name, object,
					       individual, wckey_type);
			continue;
		}

		while((object2 = list_next(itr2))) {
			slurmdb_wckey_rec_t *wckey2 =
				(slurmdb_wckey_rec_t *)object2;
			slurmdb_association_rec_t *assoc2 =
				(slurmdb_association_rec_t *)object2;
			char name[200];
			if (!wckey_type) {
				if (strcmp(assoc->cluster, wckey2->cluster))
					continue;
				cluster = assoc->cluster;
				snprintf(name, sizeof(name), "%s:%s",
					 assoc->acct, wckey2->name);
			} else {
				if (strcmp(wckey->cluster, assoc2->cluster))
					continue;
				cluster = wckey->cluster;
				snprintf(name, sizeof(name), "%s:%s",
					 wckey2->name, assoc->acct);
			}
			_check_create_grouping(cluster_list, group_itr,
					       cluster, name, object,
					       individual, wckey_type);
		}
		list_iterator_reset(itr2);
	}
	list_iterator_destroy(itr);
	if (itr2)
		list_iterator_destroy(itr2);

no_objects:
	itr = list_iterator_create(job_list);

	while((job = list_next(itr))) {
		char *local_cluster = "UNKNOWN";
		char tmp_acct[200];

		if (!job->elapsed) {
			/* here we don't care about jobs that didn't
			 * really run here */
			continue;
		}
		if (job->cluster)
			local_cluster = job->cluster;

		if (!wckey_type) {
			if (both && job->wckey) {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s:%s",
					 job->account,
					 job->wckey);
			} else {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s", job->account);
			}
		} else {
			if (both && job->account) {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s:%s",
					 job->wckey,
					 job->account);
			} else {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s", job->wckey);
			}
		}

		list_iterator_reset(cluster_itr);
		while((cluster_group = list_next(cluster_itr))) {
			if (!strcmp(local_cluster, cluster_group->cluster))
				break;
		}
		if (!cluster_group) {
			/* here we are only looking for groups that
			 * were added with the associations above
			 */
			if (!flat_view)
				continue;
			cluster_group = xmalloc(
				sizeof(slurmdb_report_cluster_grouping_t));
			cluster_group->cluster = xstrdup(local_cluster);
			cluster_group->acct_list = list_create(
				slurmdb_destroy_report_acct_grouping);
			list_append(cluster_list, cluster_group);
		}

		acct_itr = list_iterator_create(cluster_group->acct_list);
		while((acct_group = list_next(acct_itr))) {
			if (wckey_type) {
				if (!strcmp(tmp_acct, acct_group->acct))
					break;
				continue;
			}

			if (!flat_view
			   && (acct_group->lft != (uint32_t)NO_VAL)
			   && (job->lft != (uint32_t)NO_VAL)) {
				/* keep separate since we don't want
				 * to so a strcmp if we don't have to
				 */
				if (job->lft > acct_group->lft
				    && job->lft < acct_group->rgt) {
					char *mywckey;
					if (!both)
						break;
					mywckey = strstr(acct_group->acct, ":");
					mywckey++;
					if (!job->wckey && !mywckey)
						break;
					else if (!mywckey || !job->wckey)
						continue;
					else if (!strcmp(mywckey, job->wckey))
						break;
				}
			} else if (!strcmp(acct_group->acct, tmp_acct))
				break;
		}
		list_iterator_destroy(acct_itr);

		if (!acct_group) {
			char *group = NULL;
			uint32_t last_size = 0;
			/* here we are only looking for groups that
			 * were added with the associations above
			 */
			if (!flat_view)
				continue;

			acct_group = xmalloc(
				sizeof(slurmdb_report_acct_grouping_t));
			acct_group->acct = xstrdup(tmp_acct);
			acct_group->groups = list_create(
				slurmdb_destroy_report_job_grouping);
			list_append(cluster_group->acct_list, acct_group);

			while((group = list_next(group_itr))) {
				job_group = xmalloc(
					sizeof(slurmdb_report_job_grouping_t));
				job_group->jobs = list_create(NULL);
				if (!individual)
					job_group->min_size = last_size;
				last_size = atoi(group);
				if (!individual)
					job_group->max_size = last_size-1;
				else
					job_group->min_size =
						job_group->max_size = last_size;
				list_append(acct_group->groups, job_group);
			}
			if (last_size && !individual) {
				job_group = xmalloc(
					sizeof(slurmdb_report_job_grouping_t));
				job_group->jobs = list_create(NULL);
				job_group->min_size = last_size;
				if (individual)
					job_group->max_size =
						job_group->min_size;
				else
					job_group->max_size = INFINITE;
				list_append(acct_group->groups, job_group);
			}
			list_iterator_reset(group_itr);
		}

		local_itr = list_iterator_create(acct_group->groups);
		while((job_group = list_next(local_itr))) {
			uint64_t total_secs = 0;
			if ((job->alloc_cpus < job_group->min_size)
			   || (job->alloc_cpus > job_group->max_size))
				continue;
			list_append(job_group->jobs, job);
			job_group->count++;
			acct_group->count++;
			cluster_group->count++;
			total_secs = (uint64_t)job->elapsed
				* (uint64_t)job->alloc_cpus;
			job_group->cpu_secs += total_secs;
			acct_group->cpu_secs += total_secs;
			cluster_group->cpu_secs += total_secs;
		}
		list_iterator_destroy(local_itr);
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(group_itr);
	list_iterator_reset(cluster_itr);
	while ((cluster_group = list_next(cluster_itr))) {
		ListIterator acct_itr;
		if (!cluster_group->count) {
			list_delete_item(cluster_itr);
			continue;
		}
		acct_itr = list_iterator_create(cluster_group->acct_list);
		while ((acct_group = list_next(acct_itr))) {
			if (!acct_group->count) {
				list_delete_item(acct_itr);
				continue;
			}
		}
		list_iterator_destroy(acct_itr);
	}
	list_iterator_destroy(cluster_itr);

end_it:
	if (object_list)
		list_destroy(object_list);

	if (object2_list)
		list_destroy(object2_list);

	if (destroy_job_cond)
		slurmdb_destroy_job_cond(job_cond);

	if (destroy_grouping_list && grouping_list)
		list_destroy(grouping_list);

	if (exit_code) {
		if (cluster_list) {
			list_destroy(cluster_list);
			cluster_list = NULL;
		}
	}

	return cluster_list;
}
Esempio n. 9
0
void print_fields(slurmdb_step_rec_t *step)
{
	print_field_t *field = NULL;
	int curr_inx = 1;
	char outbuf[FORMAT_STRING_SIZE];

	list_iterator_reset(print_fields_itr);
	while ((field = list_next(print_fields_itr))) {
		char *tmp_char = NULL;

		memset(&outbuf, 0, sizeof(outbuf));
		switch(field->type) {
		case PRINT_AVECPU:

			tmp_char = _elapsed_time((long)step->stats.cpu_ave, 0);

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_ACT_CPUFREQ:

			convert_num_unit2((double)step->stats.act_cpufreq,
					  outbuf, sizeof(outbuf), UNIT_KILO,
					  NO_VAL, 1000, params.convert_flags &
					  (~CONVERT_NUM_UNIT_EXACT));

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_CONSUMED_ENERGY:
			if (!fuzzy_equal(step->stats.consumed_energy, NO_VAL)) {
				convert_num_unit2((double)
						  step->stats.consumed_energy,
						  outbuf, sizeof(outbuf),
						  UNIT_NONE, NO_VAL, 1000,
						  params.convert_flags &
						  (~CONVERT_NUM_UNIT_EXACT));
			}
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_CONSUMED_ENERGY_RAW:
			field->print_routine(field,
					     step->stats.consumed_energy,
					     (curr_inx == field_count));
			break;
		case PRINT_AVEDISKREAD:
			_print_small_double(outbuf, sizeof(outbuf),
					    step->stats.disk_read_ave,
					    UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVEDISKWRITE:
			_print_small_double(outbuf, sizeof(outbuf),
					    step->stats.disk_write_ave,
					    UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVEPAGES:
			convert_num_unit((double)step->stats.pages_ave, outbuf,
					 sizeof(outbuf), UNIT_KILO, NO_VAL,
					 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVERSS:
			convert_num_unit((double)step->stats.rss_ave, outbuf,
					 sizeof(outbuf), UNIT_KILO, NO_VAL,
					 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_AVEVSIZE:
			convert_num_unit((double)step->stats.vsize_ave, outbuf,
					 sizeof(outbuf), UNIT_KILO, NO_VAL,
					 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_JOBID:
			if (step->stepid == SLURM_BATCH_SCRIPT)
				snprintf(outbuf, sizeof(outbuf), "%u.batch",
					 step->job_ptr->jobid);
			else if (step->stepid == SLURM_EXTERN_CONT)
				snprintf(outbuf, sizeof(outbuf), "%u.extern",
					 step->job_ptr->jobid);
			else
				snprintf(outbuf, sizeof(outbuf), "%u.%u",
					 step->job_ptr->jobid,
					 step->stepid);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKREAD:
			_print_small_double(outbuf, sizeof(outbuf),
					    step->stats.disk_read_max,
					    UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKREADNODE:
			tmp_char = find_hostname(
					step->stats.disk_read_max_nodeid,
					step->nodes);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXDISKREADTASK:
			field->print_routine(field,
					     step->stats.disk_read_max_taskid,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKWRITE:
			_print_small_double(outbuf, sizeof(outbuf),
					    step->stats.disk_write_max,
					    UNIT_MEGA);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXDISKWRITENODE:
			tmp_char = find_hostname(
					step->stats.disk_write_max_nodeid,
					step->nodes);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXDISKWRITETASK:
			field->print_routine(field,
					     step->stats.disk_write_max_taskid,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXPAGES:
			convert_num_unit((double)step->stats.pages_max, outbuf,
					 sizeof(outbuf), UNIT_KILO, NO_VAL,
					 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXPAGESNODE:
			tmp_char = find_hostname(
					step->stats.pages_max_nodeid,
					step->nodes);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXPAGESTASK:
			field->print_routine(field,
					     step->stats.pages_max_taskid,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXRSS:
			convert_num_unit((double)step->stats.rss_max, outbuf,
					 sizeof(outbuf), UNIT_KILO, NO_VAL,
					 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXRSSNODE:
			tmp_char = find_hostname(
					step->stats.rss_max_nodeid,
					step->nodes);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXRSSTASK:
			field->print_routine(field,
					     step->stats.rss_max_taskid,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXVSIZE:
			convert_num_unit((double)step->stats.vsize_max, outbuf,
					 sizeof(outbuf), UNIT_KILO, NO_VAL,
					 params.convert_flags);

			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_MAXVSIZENODE:
			tmp_char = find_hostname(
					step->stats.vsize_max_nodeid,
					step->nodes);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MAXVSIZETASK:
			field->print_routine(field,
					     step->stats.vsize_max_taskid,
					     (curr_inx == field_count));
			break;
		case PRINT_MINCPU:
			tmp_char = _elapsed_time((long)step->stats.cpu_min, 0);

			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MINCPUNODE:
			tmp_char = find_hostname(
					step->stats.cpu_min_nodeid,
					step->nodes);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MINCPUTASK:
			field->print_routine(field,
					     step->stats.cpu_min_taskid,
					     (curr_inx == field_count));
			break;
		case PRINT_NODELIST:
			field->print_routine(field,
					     step->nodes,
					     (curr_inx == field_count));
			break;
		case PRINT_NTASKS:
			field->print_routine(field,
					     step->ntasks,
					     (curr_inx == field_count));
			break;
		case PRINT_PIDS:
                        field->print_routine(field,
                                             step->pid_str,
                                             (curr_inx == field_count));
                        break;
		case PRINT_REQ_CPUFREQ_MIN:
			cpu_freq_to_string(outbuf, sizeof(outbuf),
					   step->req_cpufreq_min);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_CPUFREQ_MAX:
			cpu_freq_to_string(outbuf, sizeof(outbuf),
					   step->req_cpufreq_max);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		case PRINT_REQ_CPUFREQ_GOV:
			cpu_freq_to_string(outbuf, sizeof(outbuf),
					   step->req_cpufreq_gov);
			field->print_routine(field,
					     outbuf,
					     (curr_inx == field_count));
			break;
		default:
			break;
		}
		curr_inx++;
	}
	printf("\n");
}
Esempio n. 10
0
extern int sacctmgr_list_cluster(int argc, char **argv)
{
	int rc = SLURM_SUCCESS;
	slurmdb_cluster_cond_t *cluster_cond =
		xmalloc(sizeof(slurmdb_cluster_cond_t));
	List cluster_list;
	int i=0;
	ListIterator itr = NULL;
	ListIterator itr2 = NULL;
	slurmdb_cluster_rec_t *cluster = NULL;
	char *tmp_char = NULL;

	int field_count = 0;

	print_field_t *field = NULL;

	List format_list = list_create(slurm_destroy_char);
	List print_fields_list; /* types are of print_field_t */

	slurmdb_init_cluster_cond(cluster_cond, 0);
	cluster_cond->cluster_list = list_create(slurm_destroy_char);
	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;
		_set_cond(&i, argc, argv, cluster_cond, format_list);
	}

	if (exit_code) {
		slurmdb_destroy_cluster_cond(cluster_cond);
		FREE_NULL_LIST(format_list);
		return SLURM_ERROR;
	}

	if (!list_count(format_list)) {
		slurm_addto_char_list(format_list,
				      "Cl,Controlh,Controlp,RPC");
		if (!without_limits)
			slurm_addto_char_list(format_list,
					      "Fa,GrpJ,GrpTRES,GrpS,MaxJ,"
					      "MaxTRES,MaxS,MaxW,QOS,"
					      "DefaultQOS");
		if (with_fed)
			slurm_addto_char_list(format_list,
					      "Federation,ID,Weight,FedState");
	}

	cluster_cond->with_deleted = with_deleted;

	print_fields_list = sacctmgr_process_format_list(format_list);
	FREE_NULL_LIST(format_list);

	if (exit_code) {
		slurmdb_destroy_cluster_cond(cluster_cond);
		FREE_NULL_LIST(print_fields_list);
		return SLURM_ERROR;
	}

	cluster_list = acct_storage_g_get_clusters(db_conn, my_uid,
						   cluster_cond);
	slurmdb_destroy_cluster_cond(cluster_cond);

	if (!cluster_list) {
		exit_code=1;
		fprintf(stderr, " Problem with query.\n");
		FREE_NULL_LIST(print_fields_list);
		return SLURM_ERROR;
	}

	itr = list_iterator_create(cluster_list);
	itr2 = list_iterator_create(print_fields_list);
	print_fields_header(print_fields_list);

	field_count = list_count(print_fields_list);

	while ((cluster = list_next(itr))) {
		int curr_inx = 1;

		/* set up the working cluster rec so nodecnt's and node names
		 * are handled correctly */
		working_cluster_rec = cluster;
		while((field = list_next(itr2))) {
			switch(field->type) {
			case PRINT_CLUSTER:
				field->print_routine(field, cluster->name,
						     (curr_inx == field_count));
				break;
			case PRINT_CHOST:
				field->print_routine(field,
						     cluster->control_host,
						     (curr_inx == field_count));
				break;
			case PRINT_CPORT:
				field->print_routine(field,
						     cluster->control_port,
						     (curr_inx == field_count));
				break;
			case PRINT_CLASS:
				field->print_routine(field,
						     get_classification_str(
						     cluster->classification),
						     (curr_inx == field_count));
				break;
			case PRINT_FEDERATION:
				field->print_routine(field, cluster->fed.name,
						     (curr_inx == field_count));
				break;
			case PRINT_FEDSTATE:
			{
				char *tmp_str = slurmdb_cluster_fed_states_str(
							cluster->fed.state);
				field->print_routine(field, tmp_str,
						     (curr_inx == field_count));
				break;
			}
			case PRINT_FEDSTATERAW:
				field->print_routine(field, cluster->fed.state,
						     (curr_inx == field_count));
				break;
			case PRINT_ID:
				field->print_routine(field, cluster->fed.id,
						     (curr_inx == field_count));
				break;
			case PRINT_WEIGHT:
				field->print_routine(field, cluster->fed.weight,
						     (curr_inx == field_count));
				break;
			case PRINT_TRES:
				sacctmgr_initialize_g_tres_list();

				tmp_char = slurmdb_make_tres_string_from_simple(
					cluster->tres_str, g_tres_list, NO_VAL,
					CONVERT_NUM_UNIT_EXACT);
				field->print_routine(field, tmp_char,
						     (curr_inx == field_count));
				xfree(tmp_char);
				break;
			case PRINT_FLAGS:
			{
				char *tmp_char = slurmdb_cluster_flags_2_str(
							     cluster->flags);
				field->print_routine(field, tmp_char,
						     (curr_inx == field_count));
				xfree(tmp_char);
				break;
			}
			case PRINT_NODECNT:
			{
				hostlist_t hl = hostlist_create(cluster->nodes);
				int cnt = 0;
				if (hl) {
					cnt = hostlist_count(hl);
					hostlist_destroy(hl);
				}
				field->print_routine(
					field,
					cnt,
					(curr_inx == field_count));
				break;
			}
			case PRINT_CLUSTER_NODES:
				field->print_routine(
					field,
					cluster->nodes,
					(curr_inx == field_count));
				break;
			case PRINT_RPC_VERSION:
				field->print_routine(
					field,
					cluster->rpc_version,
					(curr_inx == field_count));
				break;
			case PRINT_SELECT:
				field->print_routine(
					field,
					cluster->plugin_id_select,
					(curr_inx == field_count));
				break;
			default:
				sacctmgr_print_assoc_rec(cluster->root_assoc,
							 field, NULL,
							 (curr_inx ==
							  field_count));
				break;
			}
			curr_inx++;
		}
		list_iterator_reset(itr2);
		printf("\n");
	}
	/* clear the working cluster rec */
	working_cluster_rec = NULL;

	list_iterator_destroy(itr2);
	list_iterator_destroy(itr);
	FREE_NULL_LIST(cluster_list);
	FREE_NULL_LIST(print_fields_list);

	return rc;
}
Esempio n. 11
0
static void _print_res_format(slurmdb_res_rec_t *res,
			      slurmdb_clus_res_rec_t *clus_res,
			      ListIterator itr,
			      int field_count)
{
	int curr_inx = 1;
	char *tmp_char;
	print_field_t *field = NULL;
	uint32_t count;

	xassert(itr);
	xassert(res);

	while ((field = list_next(itr))) {
		switch(field->type) {
		case PRINT_ALLOWED:
			field->print_routine(
				field, clus_res ? clus_res->percent_allowed : 0,
				(curr_inx == field_count));
			break;
		case PRINT_CLUSTER:
			field->print_routine(
				field, clus_res ? clus_res->cluster : NULL,
				(curr_inx == field_count));
			break;
		case PRINT_CALLOWED:
			if (clus_res)
				count = (res->count *
					 clus_res->percent_allowed) / 100;
			else
				count = 0;
			field->print_routine(field, count,
					     (curr_inx == field_count));
			break;
		case PRINT_CUSED:
			if (clus_res)
				count = (res->count * res->percent_used) / 100;
			else
				count = 0;
			field->print_routine(field, count,
					     (curr_inx == field_count));
			break;
		case PRINT_COUNT:
			field->print_routine(field,
					     res->count,
					     (curr_inx == field_count));
			break;
		case PRINT_DESC:
			field->print_routine(
				field, res->description,
				(curr_inx == field_count));
			break;
		case PRINT_ID:
			field->print_routine(
				field, res->id,
				(curr_inx == field_count));
			break;
		case PRINT_FLAGS:
			tmp_char = slurmdb_res_flags_str(res->flags);
			field->print_routine(
				field,
				tmp_char,
				(curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_MANAGER:
			field->print_routine(field,
					     res->manager,
					     (curr_inx == field_count));
			break;
		case PRINT_NAME:
			field->print_routine(
				field, res->name,
				(curr_inx == field_count));
			break;
		case PRINT_SERVER:
			field->print_routine(field,
					     res->server,
					     (curr_inx == field_count));
			break;
		case PRINT_TYPE:
			field->print_routine(field,
					     slurmdb_res_type_str(
						     res->type),
					     (curr_inx == field_count));
			break;
		case PRINT_USED:
			field->print_routine(
				field, res->percent_used,
				(curr_inx == field_count));
			break;
		default:
			field->print_routine(
				field, NULL,
				(curr_inx == field_count));
			break;
		}
		curr_inx++;
	}
	list_iterator_reset(itr);
	printf("\n");
}
Esempio n. 12
0
extern List filetxt_jobacct_process_get_jobs(slurmdb_job_cond_t *job_cond)
{
	char line[BUFFER_SIZE];
	char *f[MAX_RECORD_FIELDS+1];    /* End list with null entry and,
					    possibly, more data than we
					    expected */
	char *fptr = NULL, *filein = NULL;
	int i;
	FILE *fd = NULL;
	int lc = 0;
	int rec_type = -1;
	int job_id = 0, step_id = 0, uid = 0, gid = 0;
	filetxt_job_rec_t *filetxt_job = NULL;
	slurmdb_selected_step_t *selected_step = NULL;
	char *object = NULL;
	ListIterator itr = NULL, itr2 = NULL;
	int show_full = 0;
	List ret_job_list = list_create(slurmdb_destroy_job_rec);
	List job_list = list_create(_destroy_filetxt_job_rec);

	filein = slurm_get_accounting_storage_loc();

	if (job_cond) {
		if (!job_cond->duplicates)
			itr2 = list_iterator_create(ret_job_list);
	}

	fd = _open_log_file(filein);

	while (fgets(line, BUFFER_SIZE, fd)) {
		lc++;
		fptr = line;	/* break the record into NULL-
				   terminated strings */
		for (i = 0; i < MAX_RECORD_FIELDS; i++) {
			f[i] = fptr;
			fptr = strstr(fptr, " ");
			if (fptr == NULL) {
				fptr = strstr(f[i], "\n");
				if (fptr)
					*fptr = 0;
				break;
			} else {
				*fptr++ = 0;
			}
		}
		if (i < MAX_RECORD_FIELDS)
			i++;
		f[i] = 0;

		if (i < HEADER_LENGTH) {
			continue;
		}

		rec_type = atoi(f[F_RECTYPE]);
		job_id = atoi(f[F_JOB]);
		uid = atoi(f[F_UID]);
		gid = atoi(f[F_GID]);

		if (rec_type == JOB_STEP)
			step_id = atoi(f[F_JOBSTEP]);
		else
			step_id = NO_VAL;

		if (!job_cond) {
			show_full = 1;
			goto no_cond;
		}

		if (job_cond->userid_list
		    && list_count(job_cond->userid_list)) {
			itr = list_iterator_create(job_cond->userid_list);
			while((object = list_next(itr))) {
				if (atoi(object) == uid) {
					list_iterator_destroy(itr);
					goto founduid;
				}
			}
			list_iterator_destroy(itr);
			continue;	/* no match */
		}
	founduid:

		if (job_cond->groupid_list
		    && list_count(job_cond->groupid_list)) {
			itr = list_iterator_create(job_cond->groupid_list);
			while((object = list_next(itr))) {
				if (atoi(object) == gid) {
					list_iterator_destroy(itr);
					goto foundgid;
				}
			}
			list_iterator_destroy(itr);
			continue;	/* no match */
		}
	foundgid:

		if ((rec_type == JOB_START) && job_cond->jobname_list
		    && list_count(job_cond->jobname_list)) {
			itr = list_iterator_create(job_cond->jobname_list);
			while((object = list_next(itr))) {
				if (!strcasecmp(f[F_JOBNAME], object)) {
					list_iterator_destroy(itr);
					goto foundjobname;
				}
			}
			list_iterator_destroy(itr);
			continue;	/* no match */
		}
	foundjobname:

		if (job_cond->step_list
		    && list_count(job_cond->step_list)) {
			itr = list_iterator_create(job_cond->step_list);
			while((selected_step = list_next(itr))) {
				if (selected_step->jobid != job_id)
					continue;
				/* job matches; does the step? */
				if (selected_step->stepid == NO_VAL) {
					show_full = 1;
					list_iterator_destroy(itr);
					goto foundjob;
				} else if (rec_type != JOB_STEP
					   || selected_step->stepid
					   == step_id) {
					list_iterator_destroy(itr);
					goto foundjob;
				}
			}
			list_iterator_destroy(itr);
			continue;	/* no match */
		} else {
			show_full = 1;
		}
	foundjob:

		if ((rec_type == JOB_START) && job_cond->partition_list
		    && list_count(job_cond->partition_list)) {
			itr = list_iterator_create(job_cond->partition_list);
			while((object = list_next(itr)))
				if (!strcasecmp(f[F_PARTITION], object)) {
					list_iterator_destroy(itr);
					goto foundp;
				}
			list_iterator_destroy(itr);
			continue;	/* no match */
		}
	foundp:

	no_cond:

		/* Build suitable tables with all the data */
		switch(rec_type) {
		case JOB_START:
			if (i < F_JOB_ACCOUNT) {
				error("Bad data on a Job Start");
				_show_rec(f);
			} else
				_process_start(job_list, f, lc, show_full, i);
			break;
		case JOB_STEP:
			if (i < F_MAX_VSIZE) {
				error("Bad data on a Step entry");
				_show_rec(f);
			} else
				_process_step(job_list, f, lc, show_full, i);
			break;
		case JOB_SUSPEND:
			if (i < F_JOB_REQUID) {
				error("Bad data on a Suspend entry");
				_show_rec(f);
			} else
				_process_suspend(job_list, f, lc,
						 show_full, i);
			break;
		case JOB_TERMINATED:
			if (i < F_JOB_REQUID) {
				error("Bad data on a Job Term");
				_show_rec(f);
			} else
				_process_terminated(job_list, f, lc,
						    show_full, i);
			break;
		default:
			debug("Invalid record at line %d of input file", lc);
			_show_rec(f);
			break;
		}
	}

	if (ferror(fd)) {
		perror(filein);
		exit(1);
	}
	fclose(fd);

	itr = list_iterator_create(job_list);

	while((filetxt_job = list_next(itr))) {
		slurmdb_job_rec_t *slurmdb_job =
			_slurmdb_create_job_rec(filetxt_job, job_cond);
		if (slurmdb_job) {
			slurmdb_job_rec_t *curr_job = NULL;
			if (itr2) {
				list_iterator_reset(itr2);
				while((curr_job = list_next(itr2))) {
					if (curr_job->jobid ==
					    slurmdb_job->jobid) {
						list_delete_item(itr2);
						info("removing job %d",
						     slurmdb_job->jobid);
						break;
					}
				}
			}
			list_append(ret_job_list, slurmdb_job);
		}
	}

	if (itr2)
		list_iterator_destroy(itr2);

	list_iterator_destroy(itr);
	list_destroy(job_list);

	xfree(filein);

	return ret_job_list;
}
Esempio n. 13
0
/* sacctmgr_list_tres()
 */
int sacctmgr_list_tres(int argc, char **argv)
{
	List tres_list;
	ListIterator itr;
	ListIterator itr2;
	List format_list = list_create(slurm_destroy_char);
	List print_fields_list;
	slurmdb_tres_cond_t *tres_cond = xmalloc(sizeof(slurmdb_tres_cond_t));
	slurmdb_tres_rec_t *tres;
	int field_count, i;
	print_field_t *field;

    	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;
		_set_cond(&i, argc, argv, tres_cond, format_list);
	}

	if (exit_code) {
		slurmdb_destroy_tres_cond(tres_cond);
		FREE_NULL_LIST(format_list);
		return SLURM_ERROR;
	}

	if (!list_count(format_list)) {
		/* Append to the format list the fields
		 * we want to print, these are the data structure
		 * members of the type returned by slurmdbd
		 */
		slurm_addto_char_list(format_list, "Type,Name%15,ID");
	}

	tres_list = slurmdb_tres_get(db_conn, tres_cond);
	slurmdb_destroy_tres_cond(tres_cond);

	if (!tres_list) {
		exit_code=1;
		fprintf(stderr, " Problem with query.\n");
		FREE_NULL_LIST(format_list);
		return SLURM_ERROR;
	}


	/* Process the format list creating a list of
	 * print field_t structures
	 */
	print_fields_list = sacctmgr_process_format_list(format_list);
	FREE_NULL_LIST(format_list);

	itr = list_iterator_create(tres_list);
	itr2 = list_iterator_create(print_fields_list);
	print_fields_header(print_fields_list);
	field_count = list_count(print_fields_list);

	/* For each tres prints the data structure members
	 */
	while ((tres = list_next(itr))) {
		while ((field = list_next(itr2))) {
			switch (field->type) {
				case PRINT_NAME:
					field->print_routine(field,
							     tres->name,
							     field_count);
					break;
				case PRINT_ID:
					field->print_routine(field,
							     tres->id,
							     field_count);
					break;
				case PRINT_TYPE:
					field->print_routine(field,
							     tres->type,
							     field_count);
					break;
			}
		}
		list_iterator_reset(itr2);
		printf("\n");
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(itr2);
	FREE_NULL_LIST(tres_list);
	FREE_NULL_LIST(print_fields_list);

	return 0;
}
Esempio n. 14
0
static List _create_resv_info_list(reserve_info_msg_t *resv_info_ptr)
{
	static List info_list = NULL;
	List last_list = NULL;
	ListIterator last_list_itr = NULL;
	int i = 0;
	static reserve_info_msg_t *last_resv_info_ptr = NULL;
	sview_resv_info_t *sview_resv_info_ptr = NULL;
	reserve_info_t *resv_ptr = NULL;

	if (info_list && (resv_info_ptr == last_resv_info_ptr))
		goto update_color;

	last_resv_info_ptr = resv_info_ptr;

	if (info_list)
		last_list = info_list;

	info_list = list_create(_resv_info_list_del);
	if (!info_list) {
		g_print("malloc error\n");
		return NULL;
	}

	if (last_list)
		last_list_itr = list_iterator_create(last_list);
	for(i=0; i<resv_info_ptr->record_count; i++) {
		resv_ptr = &(resv_info_ptr->reservation_array[i]);

		sview_resv_info_ptr = NULL;

		if (last_list_itr) {
			while ((sview_resv_info_ptr =
				list_next(last_list_itr))) {
				if (!strcmp(sview_resv_info_ptr->resv_name,
					    resv_ptr->name)) {
					list_remove(last_list_itr);
					_resv_info_free(sview_resv_info_ptr);
					break;
				}
			}
			list_iterator_reset(last_list_itr);
		}
		if (!sview_resv_info_ptr)
			sview_resv_info_ptr =
				xmalloc(sizeof(sview_resv_info_t));
		sview_resv_info_ptr->resv_name = xstrdup(resv_ptr->name);
		sview_resv_info_ptr->pos = i;
		sview_resv_info_ptr->resv_ptr = resv_ptr;
		sview_resv_info_ptr->color_inx = i % sview_colors_cnt;
		list_append(info_list, sview_resv_info_ptr);
	}

	list_sort(info_list,
		  (ListCmpF)_sview_resv_sort_aval_dec);

	if (last_list) {
		list_iterator_destroy(last_list_itr);
		FREE_NULL_LIST(last_list);
	}

update_color:
	return info_list;
}
Esempio n. 15
0
static List _create_front_end_info_list(
	front_end_info_msg_t *front_end_info_ptr, int changed)
{
	char *upper = NULL;
	char user[32], time_str[32];
	static List info_list = NULL;
	List last_list = NULL;
	ListIterator last_list_itr = NULL;
	int i = 0;
	sview_front_end_info_t *sview_front_end_info_ptr = NULL;
	front_end_info_t *front_end_ptr = NULL;

	if (!changed && info_list)
		goto update_color;

	if (info_list)
		last_list = info_list;

	info_list = list_create(_front_end_info_list_del);

	if (last_list)
		last_list_itr = list_iterator_create(last_list);
	for (i = 0; i < front_end_info_ptr->record_count; i++) {
		front_end_ptr = &(front_end_info_ptr->front_end_array[i]);

		sview_front_end_info_ptr = NULL;

		if (last_list_itr) {
			while ((sview_front_end_info_ptr =
				list_next(last_list_itr))) {
				if (!xstrcmp(sview_front_end_info_ptr->
					     front_end_name,
					     front_end_ptr->name)) {
					list_remove(last_list_itr);
					_front_end_info_free(
						sview_front_end_info_ptr);
					break;
				}
			}
			list_iterator_reset(last_list_itr);
		}
		if (!sview_front_end_info_ptr)
			sview_front_end_info_ptr =
				xmalloc(sizeof(sview_front_end_info_t));
		sview_front_end_info_ptr->pos = i;
		sview_front_end_info_ptr->front_end_name = front_end_ptr->name;
		sview_front_end_info_ptr->front_end_ptr = front_end_ptr;
		sview_front_end_info_ptr->color_inx = i % sview_colors_cnt;
		if (g_node_info_ptr) {
			sview_front_end_info_ptr->node_inx[0] = 0;
			sview_front_end_info_ptr->node_inx[1] =
				g_node_info_ptr->record_count - 1;
			sview_front_end_info_ptr->node_inx[2] = -1;
		} else
			sview_front_end_info_ptr->node_inx[0] = -1;
		if (front_end_ptr->boot_time) {
			slurm_make_time_str(&front_end_ptr->boot_time,
					    time_str, sizeof(time_str));
			sview_front_end_info_ptr->boot_time =
				xstrdup(time_str);
		}
		if (front_end_ptr->slurmd_start_time) {
			slurm_make_time_str(&front_end_ptr->slurmd_start_time,
					    time_str, sizeof(time_str));
			sview_front_end_info_ptr->slurmd_start_time =
				xstrdup(time_str);
		}
		upper = node_state_string(front_end_ptr->node_state);
		sview_front_end_info_ptr->state = str_tolower(upper);

		if (front_end_ptr->reason && front_end_ptr->reason_time &&
		    (front_end_ptr->reason_uid != NO_VAL)) {
			struct passwd *pw = NULL;

			if ((pw=getpwuid(front_end_ptr->reason_uid)))
				snprintf(user, sizeof(user), "%s", pw->pw_name);
			else
				snprintf(user, sizeof(user), "Unk(%u)",
					 front_end_ptr->reason_uid);
			slurm_make_time_str(&front_end_ptr->reason_time,
					    time_str, sizeof(time_str));
			sview_front_end_info_ptr->reason =
				xstrdup_printf("%s [%s@%s]",
					       front_end_ptr->reason, user,
					       time_str);
		} else {
			sview_front_end_info_ptr->reason =
				xstrdup(front_end_ptr->reason);
		}

		list_append(info_list, sview_front_end_info_ptr);
	}

	if (last_list) {
		list_iterator_destroy(last_list_itr);
		FREE_NULL_LIST(last_list);
	}

update_color:
	return info_list;
}
Esempio n. 16
0
static int _addto_state_char_list(List char_list, char *names)
{
	int i=0, start=0;
	uint32_t c;
	char *name = NULL, *tmp_char = NULL;
	ListIterator itr = NULL;
	char quote_c = '\0';
	int quote = 0;
	int count = 0;

	if(!char_list) {
		error("No list was given to fill in");
		return 0;
	}

	itr = list_iterator_create(char_list);
	if(names) {
		if (names[i] == '\"' || names[i] == '\'') {
			quote_c = names[i];
			quote = 1;
			i++;
		}
		start = i;
		while(names[i]) {
			//info("got %d - %d = %d", i, start, i-start);
			if(quote && names[i] == quote_c)
				break;
			else if (names[i] == '\"' || names[i] == '\'')
				names[i] = '`';
			else if(names[i] == ',') {
				if((i-start) > 0) {
					name = xmalloc((i-start+1));
					memcpy(name, names+start, (i-start));
					c = _decode_node_state(name);
					if (c == NO_VAL)
						fatal("unrecognized job "
						      "state value");
					xfree(name);
					name = xstrdup_printf("%u", c);

					while((tmp_char = list_next(itr))) {
						if(!strcasecmp(tmp_char, name))
							break;
					}

					if(!tmp_char) {
						list_append(char_list, name);
						count++;
					} else
						xfree(name);
					list_iterator_reset(itr);
				}
				i++;
				start = i;
				if(!names[i]) {
					info("There is a problem with "
					     "your request.  It appears you "
					     "have spaces inside your list.");
					break;
				}
			}
			i++;
		}
		if((i-start) > 0) {
			name = xmalloc((i-start)+1);
			memcpy(name, names+start, (i-start));
			c = _decode_node_state(name);
			if (c == NO_VAL)
				fatal("unrecognized job state value");
			xfree(name);
			name = xstrdup_printf("%u", c);

			while((tmp_char = list_next(itr))) {
				if(!strcasecmp(tmp_char, name))
					break;
			}

			if(!tmp_char) {
				list_append(char_list, name);
				count++;
			} else
				xfree(name);
		}
	}
	list_iterator_destroy(itr);
	return count;
}
Esempio n. 17
0
/**
 * connect the given switch up with the given connections
 */
extern int configure_block_switches(bg_record_t * bg_record)
{
	int rc = SLURM_SUCCESS;
	ListIterator itr;
	ba_mp_t *ba_node = NULL;
#if defined HAVE_BG_FILES
	char *mpid = NULL;
	int first_mp=1;
	int first_switch=1;
	int i = 0;
	rm_BP_t *curr_mp = NULL;
	rm_switch_t *coord_switch[SYSTEM_DIMENSIONS];
#endif
	if (!bg_record->ba_mp_list) {
		error("There was no block_list given, can't create block");
		return SLURM_ERROR;
	}

	bg_record->switch_count = 0;
	bg_record->mp_count = 0;

	itr = list_iterator_create(bg_record->ba_mp_list);
	while ((ba_node = list_next(itr))) {
		if (ba_node->used) {
			bg_record->mp_count++;
		}
		bg_record->switch_count += _used_switches(ba_node);
	}
#if defined HAVE_BG_FILES
	if ((rc = bridge_set_data(bg_record->bg_block,
				  RM_PartitionBPNum,
				  &bg_record->mp_count))
	    != SLURM_SUCCESS) {
		fatal("bridge_set_data: RM_PartitionBPNum: %s",
		      bg_err_str(rc));
		rc = SLURM_ERROR;

		goto cleanup;
	}
	if ((rc = bridge_set_data(bg_record->bg_block,
				  RM_PartitionSwitchNum,
				  &bg_record->switch_count))
	    != SLURM_SUCCESS) {
		fatal("bridge_set_data: RM_PartitionSwitchNum: %s",
		      bg_err_str(rc));
		rc = SLURM_ERROR;

		goto cleanup;
	}
#endif
	if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_WIRES)
		info("MP count %d", bg_record->mp_count);
	if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_WIRES)
		info("switch count %d", bg_record->switch_count);

	list_iterator_reset(itr);
	while ((ba_node = list_next(itr))) {
#if defined HAVE_BG_FILES
		if (_get_mp_by_location(bg, ba_node->coord, &curr_mp)
		    == SLURM_ERROR) {
			rc = SLURM_ERROR;
			goto cleanup;
		}
#endif
		if (!ba_node->used) {
			if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_WIRES)
				info("%c%c%c is a passthrough, "
				     "not including in request",
				     alpha_num[ba_node->coord[X]],
				     alpha_num[ba_node->coord[Y]],
				     alpha_num[ba_node->coord[Z]]);
		} else {
			if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_WIRES)
				info("using node %c%c%c",
				     alpha_num[ba_node->coord[X]],
				     alpha_num[ba_node->coord[Y]],
				     alpha_num[ba_node->coord[Z]]);
#if defined HAVE_BG_FILES
			if (first_mp){
				if ((rc = bridge_set_data(bg_record->bg_block,
							  RM_PartitionFirstBP,
							  curr_mp))
				    != SLURM_SUCCESS) {
					list_iterator_destroy(itr);
					fatal("bridge_set_data("
					      "RM_PartitionFirstBP): %s",
					      bg_err_str(rc));
				}
				first_mp = 0;
			} else {
				if ((rc = bridge_set_data(bg_record->bg_block,
							  RM_PartitionNextBP,
							  curr_mp))
				    != SLURM_SUCCESS) {
					list_iterator_destroy(itr);
					fatal("bridge_set_data"
					      "(RM_PartitionNextBP): %s",
					      bg_err_str(rc));
				}
			}
#endif
		}
#if defined HAVE_BG_FILES
		if ((rc = bridge_get_data(curr_mp, RM_BPID, &mpid))
		    != SLURM_SUCCESS) {
			list_iterator_destroy(itr);
			fatal("bridge_get_data: RM_BPID: %s",
			      bg_err_str(rc));
		}

		if (!mpid) {
			error("No BP ID was returned from database");
			continue;
		}
		if (_get_switches_by_mpid(bg, mpid, coord_switch)
		    != SLURM_SUCCESS) {
			error("Didn't get all the switches for mp %s", mpid);
			free(mpid);
			continue;
		}
		free(mpid);
		for(i=0; i<SYSTEM_DIMENSIONS; i++) {
			if (_add_switch_conns(coord_switch[i],
					      &ba_node->axis_switch[i])
			    == SLURM_SUCCESS) {
				if (bg_conf->slurm_debug_flags
				    & DEBUG_FLAG_BG_WIRES)
					info("adding switch dim %d", i);
				if (first_switch){
					if ((rc = bridge_set_data(
						     bg_record->bg_block,
						     RM_PartitionFirstSwitch,
						     coord_switch[i]))
					    != SLURM_SUCCESS) {
						fatal("bridge_set_data("
						      "RM_PartitionFirst"
						      "Switch): %s",
						      bg_err_str(rc));
					}

					first_switch = 0;
				} else {
					if ((rc = bridge_set_data(
						     bg_record->bg_block,
						     RM_PartitionNextSwitch,
						     coord_switch[i]))
					    != SLURM_SUCCESS) {
						fatal("bridge_set_data("
						      "RM_PartitionNext"
						      "Switch): %s",
						      bg_err_str(rc));
					}
				}
			}
		}
#endif
	}
	rc = SLURM_SUCCESS;
#if defined HAVE_BG_FILES
cleanup:
#endif
	return rc;
}
Esempio n. 18
0
static void _print_overcommit(slurmdb_res_rec_t *res,
			      slurmdb_res_cond_t *res_cond)
{
	List res_list = NULL, cluster_list = NULL;
	ListIterator itr, clus_itr = NULL, found_clus_itr = NULL;
	slurmdb_res_rec_t *found_res;
	slurmdb_clus_res_rec_t *clus_res = NULL;
	char *cluster;

	if (res->percent_used == (uint16_t)NO_VAL)
		return;

	/* Don't use the global g_res_list since we are going to
	 * change the contents of this one.
	 */
	res_cond->with_clusters = 1;

	if (res_cond->cluster_list) {
		cluster_list = res_cond->cluster_list;
		res_cond->cluster_list = NULL;
	}

	res_list = acct_storage_g_get_res(db_conn, my_uid, res_cond);
	if (!res_list) {
		exit_code=1;
		fprintf(stderr, " Problem getting system resources "
			"from database.  Contact your admin.\n");
		return;
	}

	itr = list_iterator_create(res_list);
	while ((found_res = list_next(itr))) {
		int total = 0, percent_allowed;
		fprintf(stderr, "  %s@%s\n",
			found_res->name, found_res->server);
		if (cluster_list)
			clus_itr = list_iterator_create(cluster_list);
		if (found_res->clus_res_list) {
			found_clus_itr = list_iterator_create(
				found_res->clus_res_list);
			while ((clus_res = list_next(found_clus_itr))) {
				cluster = NULL;
				if (clus_itr) {
					while ((cluster = list_next(clus_itr)))
						if (!strcmp(cluster,
							    clus_res->cluster))
						    break;
					list_iterator_reset(clus_itr);
				} else /* This means we didn't specify
					  any clusters (All clusters
					  are overwritten with the
					  requested percentage) so
					  just put something there to
					  get the correct percent_allowed.
				       */
					cluster = "nothing";

				percent_allowed = cluster ? res->percent_used :
					clus_res->percent_allowed;
				total += percent_allowed;

				fprintf(stderr,
					"   Cluster - %s\t %u%%\n",
					clus_res->cluster,
					percent_allowed);
			}
		} else if (clus_itr) {
			while ((cluster = list_next(clus_itr))) {
				total += res->percent_used;
				if (clus_res) {
					fprintf(stderr,
						"   Cluster - %s\t %u%%\n",
						clus_res->cluster,
						res->percent_used);
				} else {
					error("%s: clus_res is NULL", __func__);
				}
			}
		}
		if (clus_itr)
			list_iterator_destroy(clus_itr);
		if (found_clus_itr)
			list_iterator_destroy(found_clus_itr);
		fprintf(stderr, "   total\t\t%u%%\n", total);
	}
	list_iterator_destroy(itr);

	if (cluster_list) {
		res_cond->cluster_list = cluster_list;
		cluster_list = NULL;
	}
}
Esempio n. 19
0
extern int sacctmgr_add_cluster(int argc, char **argv)
{
	int rc = SLURM_SUCCESS;
	int i = 0;
	slurmdb_cluster_rec_t *cluster = NULL;
	slurmdb_cluster_rec_t *start_cluster =
		xmalloc(sizeof(slurmdb_cluster_rec_t));
	List name_list = list_create(slurm_destroy_char);
	List cluster_list = NULL;
	slurmdb_assoc_rec_t start_assoc;

	int limit_set = 0;
	ListIterator itr = NULL, itr_c = NULL;
	char *name = NULL;

	slurmdb_init_assoc_rec(&start_assoc, 0);
	slurmdb_init_cluster_rec(start_cluster, 0);

	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;
		limit_set += _set_rec(&i, argc, argv,
				      name_list, &start_assoc, start_cluster);
	}
	if (exit_code) {
		FREE_NULL_LIST(name_list);
		slurmdb_destroy_cluster_rec(start_cluster);
		return SLURM_ERROR;
	} else if (!list_count(name_list)) {
		FREE_NULL_LIST(name_list);
		slurmdb_destroy_cluster_rec(start_cluster);
		exit_code=1;
		fprintf(stderr, " Need name of cluster to add.\n");
		return SLURM_ERROR;
	} else {
		List temp_list = NULL;
		slurmdb_cluster_cond_t cluster_cond;

		slurmdb_init_cluster_cond(&cluster_cond, 0);
		cluster_cond.cluster_list = name_list;
		cluster_cond.classification = start_cluster->classification;

		temp_list = acct_storage_g_get_clusters(db_conn, my_uid,
							&cluster_cond);
		if (!temp_list) {
			exit_code=1;
			fprintf(stderr,
				" Problem getting clusters from database.  "
				"Contact your admin.\n");
			slurmdb_destroy_cluster_rec(start_cluster);
			return SLURM_ERROR;
		}

		itr_c = list_iterator_create(name_list);
		itr = list_iterator_create(temp_list);
		while((name = list_next(itr_c))) {
			slurmdb_cluster_rec_t *cluster_rec = NULL;

			list_iterator_reset(itr);
			while((cluster_rec = list_next(itr))) {
				if (!xstrcasecmp(cluster_rec->name, name))
					break;
			}
			if (cluster_rec) {
				printf(" This cluster %s already exists.  "
				       "Not adding.\n", name);
				list_delete_item(itr_c);
			}
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(itr_c);
		FREE_NULL_LIST(temp_list);
		if (!list_count(name_list)) {
			FREE_NULL_LIST(name_list);
			slurmdb_destroy_cluster_rec(start_cluster);
			return SLURM_ERROR;
		}
	}

	if (start_cluster->fed.name) {
		int rc;
		List fed_list = list_create(slurm_destroy_char);
		list_append(fed_list, xstrdup(start_cluster->fed.name));
		rc = verify_federations_exist(fed_list);
		FREE_NULL_LIST(fed_list);
		if (rc) {
			slurmdb_destroy_cluster_rec(start_cluster);
			FREE_NULL_LIST(name_list);
			return SLURM_ERROR;
		}
	}

	printf(" Adding Cluster(s)\n");
	cluster_list = list_create(slurmdb_destroy_cluster_rec);
	itr = list_iterator_create(name_list);
	while((name = list_next(itr))) {
		if (!name[0]) {
			exit_code=1;
			fprintf(stderr, " No blank names are "
				"allowed when adding.\n");
			rc = SLURM_ERROR;
			continue;
		}
		cluster = xmalloc(sizeof(slurmdb_cluster_rec_t));
		slurmdb_init_cluster_rec(cluster, 0);

		list_append(cluster_list, cluster);
		slurmdb_copy_cluster_rec(cluster, start_cluster);
		cluster->name = xstrdup(name);
		printf("  Name           = %s\n", cluster->name);

		cluster->root_assoc =
			xmalloc(sizeof(slurmdb_assoc_rec_t));
		slurmdb_init_assoc_rec(cluster->root_assoc, 0);
		cluster->root_assoc->def_qos_id = start_assoc.def_qos_id;
		cluster->root_assoc->shares_raw = start_assoc.shares_raw;

		slurmdb_copy_assoc_rec_limits(
			cluster->root_assoc, &start_assoc);
	}
	list_iterator_destroy(itr);
	FREE_NULL_LIST(name_list);

	if (limit_set)
		printf(" Setting\n");
	if (limit_set & CLUS_REC_SET)
		sacctmgr_print_cluster(start_cluster);
	if (limit_set & CLUS_ASSOC_SET) {
		printf("  Default Limits:\n");
		sacctmgr_print_assoc_limits(&start_assoc);
		FREE_NULL_LIST(start_assoc.qos_list);
	}
	slurmdb_destroy_cluster_rec(start_cluster);

	if (!list_count(cluster_list)) {
		printf(" Nothing new added.\n");
		rc = SLURM_ERROR;
		goto end_it;
	}

	/* Since we are creating tables with add cluster that can't be
	   rolled back.  So we ask before hand if they are serious
	   about it so we can rollback if needed.
	*/
	if (commit_check("Would you like to commit changes?")) {
		notice_thread_init();
		rc = acct_storage_g_add_clusters(db_conn, my_uid, cluster_list);
		notice_thread_fini();
		if (rc == SLURM_SUCCESS) {
			acct_storage_g_commit(db_conn, 1);
		} else {
			exit_code=1;
			fprintf(stderr, " Problem adding clusters: %s\n",
				slurm_strerror(rc));
			/* this isn't really needed, but just to be safe */
			acct_storage_g_commit(db_conn, 0);
		}
	} else {
		printf(" Changes Discarded\n");
		/* this isn't really needed, but just to be safe */
		acct_storage_g_commit(db_conn, 0);
	}

end_it:
	FREE_NULL_LIST(cluster_list);

	return rc;
}
Esempio n. 20
0
extern int sacctmgr_add_res(int argc, char *argv[])

{
	int rc = SLURM_SUCCESS;
	int i=0, limit_set=0;
	ListIterator itr = NULL;
	ListIterator clus_itr = NULL;
	slurmdb_res_rec_t *res = NULL;
	slurmdb_res_rec_t *found_res = NULL;
	slurmdb_res_rec_t *start_res = xmalloc(sizeof(slurmdb_res_rec_t));
	List cluster_list = list_create(slurm_destroy_char);
	List name_list = list_create(slurm_destroy_char);
	char *name = NULL;
	List res_list = NULL;
	char *res_str = NULL;

	slurmdb_init_res_rec(start_res, 0);

	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;

		limit_set += _set_res_rec(&i, argc, argv, name_list,
					  cluster_list, start_res);
	}

	if (exit_code) {
		FREE_NULL_LIST(name_list);
		FREE_NULL_LIST(cluster_list);
		slurmdb_destroy_res_rec(start_res);
		return SLURM_ERROR;
	} else if (!list_count(name_list)) {
		FREE_NULL_LIST(name_list);
		FREE_NULL_LIST(cluster_list);
		slurmdb_destroy_res_rec(start_res);
		exit_code=1;
		fprintf(stderr, " Need name of resource to add.\n");
		return SLURM_SUCCESS;
	}

	if (!start_res->server) {
		/* assign some server name */
		start_res->server = xstrdup("slurmdb");
	}

	if (!g_res_list) {
		slurmdb_res_cond_t res_cond;
		slurmdb_init_res_cond(&res_cond, 0);
		res_cond.with_clusters = 1;
		g_res_list = acct_storage_g_get_res(db_conn, my_uid, &res_cond);
		if (!g_res_list) {
			exit_code=1;
			fprintf(stderr, " Problem getting system resources "
				"from database.  "
				"Contact your admin.\n");
			FREE_NULL_LIST(name_list);
			FREE_NULL_LIST(cluster_list);
			slurmdb_destroy_res_rec(start_res);
			return SLURM_ERROR;
		}
	}

	res_list = list_create(slurmdb_destroy_res_rec);

	itr = list_iterator_create(name_list);
	if (cluster_list)
		clus_itr = list_iterator_create(cluster_list);
	while ((name = list_next(itr))) {
		bool added = 0;
		found_res = sacctmgr_find_res_from_list(
			g_res_list, NO_VAL, name, start_res->server);
		if (!found_res) {
			if (start_res->type == SLURMDB_RESOURCE_NOTSET) {
				exit_code=1;
				fprintf(stderr,
					" Need to designate a resource "
					"type to initially add '%s'.\n", name);
				break;

			} else if (start_res->count == NO_VAL) {
				exit_code=1;
				fprintf(stderr,
					" Need to designate a resource "
					"count to initially add '%s'.\n", name);
				break;
			}
			added = 1;
			res = xmalloc(sizeof(slurmdb_res_rec_t));
			slurmdb_init_res_rec(res, 0);
			res->name = xstrdup(name);
			res->description =
				xstrdup(start_res->description ?
					start_res->description : name);
			res->manager = xstrdup(start_res->manager);
			res->server = xstrdup(start_res->server);
			res->count = start_res->count;
			res->flags = start_res->flags;
			res->type = start_res->type;

			xstrfmtcat(res_str, "  %s@%s\n",
				   res->name, res->server);
			list_append(res_list, res);
		}

		if (cluster_list && list_count(cluster_list)) {
			ListIterator found_itr = NULL;
			slurmdb_clus_res_rec_t *clus_res;
			char *cluster;
			uint16_t start_used = 0;

			if (found_res) {
				found_itr = list_iterator_create(
					found_res->clus_res_list);
				res = xmalloc(sizeof(slurmdb_res_rec_t));
				slurmdb_init_res_rec(res, 0);
				res->id = found_res->id;
				res->type = found_res->type;
				start_used = res->percent_used =
					found_res->percent_used;
			}

			res->clus_res_list = list_create(
				slurmdb_destroy_clus_res_rec);

			while ((cluster = list_next(clus_itr))) {
				clus_res = NULL;
				if (found_res) {
					while ((clus_res =
						list_next(found_itr))) {
						if (!strcmp(clus_res->cluster,
							    cluster))
							break;
					}
					list_iterator_reset(found_itr);
				}

				if (!clus_res) {
					if (!added) {
						added = 1;
						xstrfmtcat(res_str,
							   "  %s@%s\n", name,
							   res->server);
						list_append(res_list, res);
					}
					/* make sure we don't overcommit */
					res->percent_used +=
						start_res->percent_used;
					if (res->percent_used > 100) {
						exit_code=1;
						fprintf(stderr,
							" Adding this %d "
							"clusters to resource "
							"%s@%s at %u%% each "
							", with %u%% already "
							"used,  would go over "
							"100%%.  Please redo "
							"your math and "
							"resubmit.\n",
							list_count(
								cluster_list),
							res->name, res->server,
							start_res->percent_used,
							start_used);
						break;
					}
					clus_res = xmalloc(
						sizeof(slurmdb_clus_res_rec_t));
					list_append(res->clus_res_list,
						    clus_res);
					clus_res->cluster = xstrdup(cluster);
					clus_res->percent_allowed =
						start_res->percent_used;
					xstrfmtcat(res_str,
						   "   Cluster - %s\t%u%%\n",
						   cluster,
						   clus_res->percent_allowed);
					/* FIXME: make sure we don't
					   overcommit */
				}
			}
			if (res->percent_used > 100)
				break;

			if (found_res)
				list_iterator_destroy(found_itr);

			if (!added)
				slurmdb_destroy_res_rec(res);

			list_iterator_reset(clus_itr);
		}
	}

	if (cluster_list)
		list_iterator_destroy(clus_itr);

	list_iterator_destroy(itr);

	FREE_NULL_LIST(name_list);
	FREE_NULL_LIST(cluster_list);

	if (exit_code) {
		rc = SLURM_ERROR;
		goto end_it;
	}

	if (!list_count(res_list)) {
		printf(" Nothing new added.\n");
		rc = SLURM_ERROR;
		goto end_it;
	}

	if (res_str) {
		char *tmp_str;
		switch (res->type) {
		case SLURMDB_RESOURCE_LICENSE:
			tmp_str = "License";
			break;
		default:
			tmp_str = "Unknown";
		}
		printf(" Adding Resource(s)\n%s", res_str);
		printf(" Settings\n");
		if (res->name)
			printf("  Name           = %s\n", res->name);
		if (res->server)
			printf("  Server         = %s\n", res->server);
		if (res->description)
			printf("  Description    = %s\n", res->description);
		if (res->manager)
			printf("  Manager        = %s\n", res->manager);
		if (res->count != NO_VAL)
			printf("  Count          = %u\n", res->count);
		printf("  Type           = %s\n", tmp_str);

		xfree(res_str);
	}

	if (list_count(res_list)) {
		notice_thread_init();
		rc = acct_storage_g_add_res(db_conn, my_uid, res_list);
		notice_thread_fini();
	} else
		goto end_it;
	if (rc == SLURM_SUCCESS) {
		if (commit_check("Would you like to commit changes?")) {
			acct_storage_g_commit(db_conn, 1);
		} else {
			printf(" Changes Discarded\n");
			acct_storage_g_commit(db_conn, 0);
		}
	} else {
		exit_code=1;
		fprintf(stderr, " Problem adding system resource: %s\n",
			slurm_strerror(rc));
		rc = SLURM_ERROR;
	}

end_it:
	FREE_NULL_LIST(res_list);
	slurmdb_destroy_res_rec(start_res);
	return rc;
}
Esempio n. 21
0
/*
 * as_pg_get_accts - get accounts
 *
 * IN pg_conn: database connection
 * IN uid: user performing the get operation
 * IN acct_cond: accounts to get
 * RET: list of accounts
 */
extern List
as_pg_get_accts(pgsql_conn_t *pg_conn, uid_t uid,
		slurmdb_account_cond_t *acct_cond)
{
	DEF_VARS;
	char *cond = NULL;
	List acct_list = NULL;
	ListIterator itr = NULL;
	int set=0, is_admin=1;
	slurmdb_user_rec_t user;	/* no need to free lists */

	char *ga_fields = "name, description, organization";
	enum {
		F_NAME,
		F_DESC,
		F_ORG,
		F_COUNT
	};

	if (check_db_connection(pg_conn) != SLURM_SUCCESS)
		return NULL;

	if (check_user_op(pg_conn, uid, PRIVATE_DATA_ACCOUNTS,
			  &is_admin, &user) != SLURM_SUCCESS) {
		error("as/pg: user(%u) not found in db", uid);
		errno = ESLURM_USER_ID_MISSING;
		return NULL;
	}

	if (!is_admin && ! is_user_any_coord(pg_conn, &user)) {
		errno = ESLURM_ACCESS_DENIED;
		return NULL;
	}

	if(!acct_cond) {
		xstrcat(cond, "WHERE deleted=0");
		goto empty;
	}

	if(acct_cond->with_deleted)
		xstrcat(cond, "WHERE (deleted=0 OR deleted=1)");
	else
		xstrcat(cond, "WHERE deleted=0");

	if(acct_cond->assoc_cond)
		concat_cond_list(acct_cond->assoc_cond->acct_list,
				 NULL, "name", &cond);
	concat_cond_list(acct_cond->description_list,
			 NULL, "description", &cond);
	concat_cond_list(acct_cond->organization_list,
			 NULL, "organization", &cond);

empty:
	if(!is_admin) {
		slurmdb_coord_rec_t *coord = NULL;
		set = 0;
		itr = list_iterator_create(user.coord_accts);
		while((coord = list_next(itr))) {
			if(set) {
				xstrfmtcat(cond, " OR name='%s'",
					   coord->name);
			} else {
				set = 1;
				xstrfmtcat(cond, " AND (name='%s'",
					   coord->name);
			}
		}
		list_iterator_destroy(itr);
		if(set)
			xstrcat(cond,")");
	}

	query = xstrdup_printf("SELECT %s FROM %s %s",
			       ga_fields, acct_table, cond);
	xfree(cond);
	result = DEF_QUERY_RET;
	if (!result)
		return NULL;

	acct_list = list_create(slurmdb_destroy_account_rec);

	if(acct_cond && acct_cond->with_assocs) {
		if(!acct_cond->assoc_cond)
			acct_cond->assoc_cond = xmalloc(
				sizeof(slurmdb_association_cond_t));
		else if(acct_cond->assoc_cond->acct_list)
			list_destroy(acct_cond->assoc_cond->acct_list);
		acct_cond->assoc_cond->acct_list = list_create(NULL);
	}

	FOR_EACH_ROW {
		slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t));
		list_append(acct_list, acct);

		acct->name =  xstrdup(ROW(F_NAME));
		acct->description = xstrdup(ROW(F_DESC));
		acct->organization = xstrdup(ROW(F_ORG));
		if(acct_cond && acct_cond->with_coords)
			_get_account_coords(pg_conn, acct);
		if(acct_cond && acct_cond->with_assocs) {
			list_append(acct_cond->assoc_cond->acct_list,
				    acct->name);
		}
	} END_EACH_ROW;
	PQclear(result);

	/* get associations */
	if(acct_cond && acct_cond->with_assocs &&
	   list_count(acct_cond->assoc_cond->acct_list)) {
		ListIterator assoc_itr = NULL;
		slurmdb_account_rec_t *acct = NULL;
		slurmdb_association_rec_t *assoc = NULL;
		List assoc_list = acct_storage_p_get_associations(
			pg_conn, uid, acct_cond->assoc_cond);

		if(!assoc_list) {
			error("as/pg: get_accounts: no associations");
			return acct_list;
		}

		itr = list_iterator_create(acct_list);
		assoc_itr = list_iterator_create(assoc_list);
		while((acct = list_next(itr))) {
			while((assoc = list_next(assoc_itr))) {
				if(strcmp(assoc->acct, acct->name))
					continue;

				if(!acct->assoc_list)
					acct->assoc_list = list_create(
						slurmdb_destroy_association_rec);
				list_append(acct->assoc_list, assoc);
				list_remove(assoc_itr);
			}
			list_iterator_reset(assoc_itr);
			if(!acct->assoc_list) /* problem acct */
				list_remove(itr);
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(assoc_itr);
		list_destroy(assoc_list);
	}
	return acct_list;
}
Esempio n. 22
0
/* process job usage data */
static int
_process_job_usage(pgsql_conn_t *pg_conn, char *cluster, time_t start,
		   time_t end, List cu_list, List ru_list, List au_list,
		   List wu_list)
{
	DEF_VARS;
	PGresult *result2;
	ListIterator r_itr;
	int seconds = 0, last_id = -1, last_wckeyid = -1;
	local_cluster_usage_t *c_usage = NULL;
	local_resv_usage_t *r_usage = NULL;
	local_id_usage_t *a_usage = NULL, *w_usage = NULL;
	int track_wckey = slurm_get_track_wckey();

	char *gj_fields = "job_db_inx,id_job,id_assoc,id_wckey,time_eligible,"
		"time_start,time_end,time_suspended,cpus_alloc,cpus_req,"
		"id_resv";
	enum {
		F_DB_INX,
		F_JOBID,
		F_ASSOCID,
		F_WCKEYID,
		F_ELG,
		F_START,
		F_END,
		F_SUSPENDED,
		F_ACPU,
		F_RCPU,
		F_RESVID,
		F_COUNT
	};

	query = xstrdup_printf(
		"SELECT %s FROM %s.%s WHERE (time_eligible < %ld AND "
		"(time_end >= %ld OR time_end = 0)) ORDER BY id_assoc, "
		"time_eligible", gj_fields, cluster, job_table,
		(long)end, (long)start);
	result = DEF_QUERY_RET;
	if (!result) {
		error("failed to get jobs");
		return SLURM_ERROR;
	}

	r_itr = list_iterator_create(ru_list);
	FOR_EACH_ROW {
		int job_id = atoi(ROW(F_JOBID));
		int assoc_id = atoi(ROW(F_ASSOCID));
		int wckey_id = atoi(ROW(F_WCKEYID));
		int resv_id = atoi(ROW(F_RESVID));
		int row_eligible = atoi(ROW(F_ELG));
		int row_start = atoi(ROW(F_START));
		int row_end = atoi(ROW(F_END));
		int row_acpu = atoi(ROW(F_ACPU));
		int row_rcpu = atoi(ROW(F_RCPU));
		seconds = 0;

		if (row_start && (row_start < start))
			row_start = start;
		if (!row_start && row_end)
			row_start = row_end;
		if (!row_end || row_end > end)
			row_end = end;
		if (!row_start || ((row_end - row_start) < 1))
			goto calc_cluster;

		seconds = (row_end - row_start);

		if (strcmp(ROW(F_SUSPENDED), "0")) {
                        query = xstrdup_printf(
				"SELECT %s.get_job_suspend_time(%s, %ld, %ld);",
				cluster, ROW(F_DB_INX), start, end);
                        result2 = DEF_QUERY_RET;
			if (!result2) {
				list_iterator_destroy(r_itr);
                                return SLURM_ERROR;
			}
                        seconds -= atoi(PQgetvalue(result2, 0, 0));
                        PQclear(result2);
                }
                if (seconds < 1) {
			debug4("This job (%u) was suspended "
			       "the entire hour", job_id);
			/* TODO: how about resv usage? */
			continue;
		}

		if (last_id != assoc_id) { /* ORDER BY associd */
			a_usage = xmalloc(sizeof(local_id_usage_t));
			a_usage->id = assoc_id;
			list_append(au_list, a_usage);
			last_id = assoc_id;
		}
		a_usage->a_cpu += seconds * row_acpu;

		if (!track_wckey)
			goto calc_cluster;

		/* do the wckey calculation */
		if (last_wckeyid != wckey_id) {
			w_usage = list_find_first(wu_list, _cmp_local_id,
						  &wckey_id);
			if (!w_usage) {
				w_usage = xmalloc(sizeof(local_id_usage_t));
				w_usage->id = wckey_id;
				list_append(wu_list, w_usage);
			}
			last_wckeyid = wckey_id;
		}
		w_usage->a_cpu += seconds * row_acpu;

		/* do the cluster allocated calculation */
	calc_cluster:

		/* first figure out the reservation */
		if (resv_id) {
			if (seconds <= 0)
				continue;
			/* Since we have already added the
			   entire reservation as used time on
			   the cluster we only need to
			   calculate the used time for the
			   reservation and then divy up the
			   unused time over the associations
			   able to run in the reservation.
			   Since the job was to run, or ran a
			   reservation we don't care about eligible time
			   since that could totally skew the
			   clusters reserved time
			   since the job may be able to run
			   outside of the reservation. */
			list_iterator_reset(r_itr);
			while((r_usage = list_next(r_itr))) {
				/* since the reservation could
				   have changed in some way,
				   thus making a new
				   reservation record in the
				   database, we have to make
				   sure all the reservations
				   are checked to see if such
				   a thing has happened */
				if ((r_usage->id == resv_id)) {
					int temp_end = row_end;
					int temp_start = row_start;
					if (r_usage->start > temp_start)
						temp_start = r_usage->start;
					if (r_usage->end < temp_end)
						temp_end = r_usage->end;

					if ((temp_end - temp_start) > 0) {
						r_usage->a_cpu += row_acpu *
							(temp_end - temp_start);
					}
				}
			}
			/* entire resv already added to cluster usage */
			continue;
		}

		c_usage = list_peek(cu_list);
		/* only record time for the clusters that have
		   registered.  This continue should rarely if
		   ever happen.
		*/
		if (!c_usage)
			continue;

		if (row_start && (seconds > 0)) {
/* 					info("%d assoc %d adds " */
/* 					     "(%d)(%d-%d) * %d = %d " */
/* 					     "to %d", */
/* 					     job_id, */
/* 					     a_usage->id, */
/* 					     seconds, */
/* 					     row_end, row_start, */
/* 					     row_acpu, */
/* 					     seconds * row_acpu, */
/* 					     row_acpu); */

			c_usage->a_cpu += seconds * row_acpu;
		}
		/* now reserved time */
		/*
		 * job requesting for rcpu processors has been delayed
		 * by (start_time - eligible_time) seconds
		 * large r_cpu means cluster overload or bad scheduling?
		 */
		if (!row_start || (row_start >= c_usage->start)) {
			row_end = row_start;
			row_start = row_eligible;
			if (c_usage->start > row_start)
				row_start = c_usage->start;
			if (c_usage->end < row_end)
				row_end = c_usage->end;

			if ((row_end - row_start) > 0) {
				seconds = (row_end - row_start)
					* row_rcpu;

/* 					info("%d assoc %d reserved " */
/* 					     "(%d)(%d-%d) * %d = %d " */
/* 					     "to %d", */
/* 					     job_id, */
/* 					     assoc_id, */
/* 					     seconds, */
/* 					     row_end, row_start, */
/* 					     row_rcpu, */
/* 					     seconds * row_rcpu, */
/* 					     row_rcpu); */
				c_usage->r_cpu += seconds;
			}
		}
	} END_EACH_ROW;
	PQclear(result);
	list_iterator_destroy(r_itr);

	return SLURM_SUCCESS;
}
Esempio n. 23
0
extern List as_mysql_get_accts(mysql_conn_t *mysql_conn, uid_t uid,
			       slurmdb_account_cond_t *acct_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List acct_list = NULL;
	ListIterator itr = NULL;
	char *object = NULL;
	int set = 0;
	int i=0, is_admin=1;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	uint16_t private_data = 0;
	slurmdb_user_rec_t user;

	/* if this changes you will need to edit the corresponding enum */
	char *acct_req_inx[] = {
		"name",
		"description",
		"organization"
	};
	enum {
		SLURMDB_REQ_NAME,
		SLURMDB_REQ_DESC,
		SLURMDB_REQ_ORG,
		SLURMDB_REQ_COUNT
	};

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	memset(&user, 0, sizeof(slurmdb_user_rec_t));
	user.uid = uid;

	private_data = slurm_get_private_data();

	if (private_data & PRIVATE_DATA_ACCOUNTS) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			if (!is_user_any_coord(mysql_conn, &user)) {
				error("Only admins/coordinators "
				      "can look at account usage");
				errno = ESLURM_ACCESS_DENIED;
				return NULL;
			}
		}
	}

	if (!acct_cond) {
		xstrcat(extra, "where deleted=0");
		goto empty;
	}

	if (acct_cond->with_deleted)
		xstrcat(extra, "where (deleted=0 || deleted=1)");
	else
		xstrcat(extra, "where deleted=0");

	if (acct_cond->assoc_cond
	    && acct_cond->assoc_cond->acct_list
	    && list_count(acct_cond->assoc_cond->acct_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->assoc_cond->acct_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "name='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (acct_cond->description_list
	    && list_count(acct_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->description_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "description='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (acct_cond->organization_list
	    && list_count(acct_cond->organization_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->organization_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "organization='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

empty:

	xfree(tmp);
	xstrfmtcat(tmp, "%s", acct_req_inx[i]);
	for(i=1; i<SLURMDB_REQ_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", acct_req_inx[i]);
	}

	/* This is here to make sure we are looking at only this user
	 * if this flag is set.  We also include any accounts they may be
	 * coordinator of.
	 */
	if (!is_admin && (private_data & PRIVATE_DATA_ACCOUNTS)) {
		slurmdb_coord_rec_t *coord = NULL;
		set = 0;
		itr = list_iterator_create(user.coord_accts);
		while ((coord = list_next(itr))) {
			if (set) {
				xstrfmtcat(extra, " || name='%s'",
					   coord->name);
			} else {
				set = 1;
				xstrfmtcat(extra, " && (name='%s'",
					   coord->name);
			}
		}
		list_iterator_destroy(itr);
		if (set)
			xstrcat(extra,")");
	}

	query = xstrdup_printf("select %s from %s %s", tmp, acct_table, extra);
	xfree(tmp);
	xfree(extra);

	if (debug_flags & DEBUG_FLAG_DB_ASSOC)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}
	xfree(query);

	acct_list = list_create(slurmdb_destroy_account_rec);

	if (acct_cond && acct_cond->assoc_cond && acct_cond->with_assocs) {
		/* We are going to be freeing the inners of
		   this list in the acct->name so we don't
		   free it here
		*/
		if (acct_cond->assoc_cond->acct_list)
			list_destroy(acct_cond->assoc_cond->acct_list);
		acct_cond->assoc_cond->acct_list = list_create(NULL);
		acct_cond->assoc_cond->with_deleted = acct_cond->with_deleted;
	}

	while ((row = mysql_fetch_row(result))) {
		slurmdb_account_rec_t *acct =
			xmalloc(sizeof(slurmdb_account_rec_t));
		list_append(acct_list, acct);

		acct->name =  xstrdup(row[SLURMDB_REQ_NAME]);
		acct->description = xstrdup(row[SLURMDB_REQ_DESC]);
		acct->organization = xstrdup(row[SLURMDB_REQ_ORG]);

		if (acct_cond && acct_cond->with_coords) {
			_get_account_coords(mysql_conn, acct);
		}

		if (acct_cond && acct_cond->with_assocs) {
			if (!acct_cond->assoc_cond) {
				acct_cond->assoc_cond = xmalloc(
					sizeof(slurmdb_association_cond_t));
			}

			list_append(acct_cond->assoc_cond->acct_list,
				    acct->name);
		}
	}
	mysql_free_result(result);

	if (acct_cond && acct_cond->with_assocs && acct_cond->assoc_cond
	    && list_count(acct_cond->assoc_cond->acct_list)) {
		ListIterator assoc_itr = NULL;
		slurmdb_account_rec_t *acct = NULL;
		slurmdb_association_rec_t *assoc = NULL;
		List assoc_list = as_mysql_get_assocs(
			mysql_conn, uid, acct_cond->assoc_cond);

		if (!assoc_list) {
			error("no associations");
			return acct_list;
		}

		itr = list_iterator_create(acct_list);
		assoc_itr = list_iterator_create(assoc_list);
		while ((acct = list_next(itr))) {
			while ((assoc = list_next(assoc_itr))) {
				if (strcmp(assoc->acct, acct->name))
					continue;

				if (!acct->assoc_list)
					acct->assoc_list = list_create(
						slurmdb_destroy_association_rec);
				list_append(acct->assoc_list, assoc);
				list_remove(assoc_itr);
			}
			list_iterator_reset(assoc_itr);
			if (!acct->assoc_list)
				list_remove(itr);
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(assoc_itr);

		list_destroy(assoc_list);
	}

	return acct_list;
}
Esempio n. 24
0
/*
 * pgsql_hourly_rollup - rollup usage data per hour
 */
static int
pgsql_hourly_rollup(pgsql_conn_t *pg_conn, char *cluster,
		    time_t start, time_t end)
{
	int rc = SLURM_SUCCESS, add_sec = 3600;
	time_t now = time(NULL), curr_start = start,
		curr_end = curr_start + add_sec;
	char *query = NULL, *usage_recs = NULL;
	ListIterator a_itr = NULL, c_itr = NULL, w_itr = NULL, r_itr = NULL;
	List assoc_usage_list = list_create(_destroy_local_id_usage);
	List cluster_usage_list = list_create(_destroy_local_cluster_usage);
	List wckey_usage_list = list_create(_destroy_local_id_usage);
	List resv_usage_list = list_create(_destroy_local_resv_usage);
	uint16_t track_wckey = slurm_get_track_wckey();

	a_itr = list_iterator_create(assoc_usage_list);
	c_itr = list_iterator_create(cluster_usage_list);
	w_itr = list_iterator_create(wckey_usage_list);
	r_itr = list_iterator_create(resv_usage_list);
	while(curr_start < end) {
		local_cluster_usage_t *c_usage = NULL;
		local_id_usage_t *a_usage = NULL;
		local_id_usage_t *w_usage = NULL;

		debug3("curr hour is now %ld-%ld", curr_start, curr_end);

		rc = _process_event_usage(pg_conn, cluster, curr_start,
					  curr_end, cluster_usage_list);
                if (rc != SLURM_SUCCESS)
                        goto end_it;

		rc = _process_resv_usage(pg_conn, cluster, curr_start,
					 curr_end, cluster_usage_list,
					 resv_usage_list);
                if (rc != SLURM_SUCCESS)
                        goto end_it;

		rc = _process_job_usage(pg_conn, cluster, curr_start, curr_end,
					cluster_usage_list, resv_usage_list,
					assoc_usage_list, wckey_usage_list);
		if (rc != SLURM_SUCCESS)
			goto end_it;

		/* now figure out how much more to add to the
		   associations that could had run in the reservation
		*/
		rc = _process_resv_idle_time(resv_usage_list, assoc_usage_list);
		if (rc != SLURM_SUCCESS)
			goto end_it;

		/* Now put the lists into the usage tables */
		list_iterator_reset(c_itr);
		while((c_usage = list_next(c_itr))) {
			_cluster_usage_sanity_check(cluster, c_usage,
						    curr_start,curr_end);
/* 			info("cluster %s(%d) down %d alloc %d " */
/* 			     "resv %d idle %d over %d " */
/* 			     "total= %d = %d from %s", */
/* 			     c_usage->name, */
/* 			     c_usage->cpu_count, c_usage->d_cpu, */
/* 			     c_usage->a_cpu, */
/* 			     c_usage->r_cpu, c_usage->i_cpu, c_usage->o_cpu, */
/* 			     c_usage->d_cpu + c_usage->a_cpu + */
/* 			     c_usage->r_cpu + c_usage->i_cpu, */
/* 			     c_usage->total_time, */
/* 			     ctime(&c_usage->start)); */
/* 			info("to %s", ctime(&c_usage->end)); */
			if (usage_recs)
				xstrcat(usage_recs, ", ");
			xstrfmtcat(usage_recs,
				   "CAST((%ld, %ld, 0, %ld, %d, "
				   "%"PRIu64", %"PRIu64", %"PRIu64", "
				   "%"PRIu64", %"PRIu64", %"PRIu64")"
				   " AS %s.%s)",
				   now, now, curr_start, c_usage->cpu_count,
				   c_usage->a_cpu, c_usage->d_cpu,
				   c_usage->pd_cpu, c_usage->i_cpu,
				   c_usage->o_cpu, c_usage->r_cpu, cluster,
				   cluster_hour_table);
                }
                if (usage_recs) {
                        query = xstrdup_printf (
				"SELECT %s.add_cluster_hour_usages(ARRAY[%s]);",
				cluster, usage_recs);
			xfree(usage_recs);
			rc = DEF_QUERY_RET_RC;
			if (rc != SLURM_SUCCESS) {
				error("couldn't add cluster hour rollup");
				goto end_it;
			}
		}

		list_iterator_reset(a_itr);
		while((a_usage = list_next(a_itr))) {
/* 			info("association (%d) %d alloc %d", */
/* 			     a_usage->id, last_id, */
/* 			     a_usage->a_cpu); */
			if (usage_recs)
				xstrcat(usage_recs, ", ");
			xstrfmtcat(usage_recs,
				   "CAST((%ld, %ld, 0, %d, %ld, "
				   "%"PRIu64") AS %s.%s)",
                                   now, now, a_usage->id, curr_start,
				   a_usage->a_cpu, cluster, assoc_hour_table);
		}
		if (usage_recs) {
			query = xstrdup_printf(
				"SELECT %s.add_assoc_hour_usages(ARRAY[%s]);",
				cluster, usage_recs);
			xfree(usage_recs);
			rc = DEF_QUERY_RET_RC;
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add assoc hour rollup");
				goto end_it;
			}
		}

		if (!track_wckey)
			goto end_loop;

		list_iterator_reset(w_itr);
		while((w_usage = list_next(w_itr))) {
/* 			info("association (%d) %d alloc %d", */
/* 			     w_usage->id, last_id, */
/* 			     w_usage->a_cpu); */
			if (usage_recs)
				xstrcat(usage_recs, ", ");
			xstrfmtcat(usage_recs,
				   "CAST((%ld, %ld, 0, %d, %ld, "
				   "%"PRIu64", 0, 0) AS %s.%s)",
				   now, now, w_usage->id, curr_start,
				   w_usage->a_cpu, cluster, wckey_hour_table);
		}
		if (usage_recs) {
			query = xstrdup_printf(
				"SELECT %s.add_wckey_hour_usages(ARRAY[%s]);",
				cluster, usage_recs);
			xfree(usage_recs);
			rc = DEF_QUERY_RET_RC;
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add wckey hour rollup");
				goto end_it;
			}
		}

	end_loop:
		list_flush(assoc_usage_list);
		list_flush(cluster_usage_list);
		list_flush(wckey_usage_list);
		list_flush(resv_usage_list);
		curr_start = curr_end;
		curr_end = curr_start + add_sec;
	}
end_it:
	list_iterator_destroy(a_itr);
	list_iterator_destroy(c_itr);
	list_iterator_destroy(w_itr);
	list_iterator_destroy(r_itr);

	list_destroy(assoc_usage_list);
	list_destroy(cluster_usage_list);
	list_destroy(wckey_usage_list);
	list_destroy(resv_usage_list);

/* 	info("stop start %s", ctime(&curr_start)); */
/* 	info("stop end %s", ctime(&curr_end)); */
	return rc;
}
Esempio n. 25
0
static void _check_create_grouping(
	List cluster_list,  ListIterator group_itr,
	char *cluster, char *name, void *object,
	bool individual, bool wckey_type)
{
	ListIterator itr;
	slurmdb_wckey_rec_t *wckey = (slurmdb_wckey_rec_t *)object;
	slurmdb_association_rec_t *assoc = (slurmdb_association_rec_t *)object;
	slurmdb_report_cluster_grouping_t *cluster_group = NULL;
	slurmdb_report_acct_grouping_t *acct_group = NULL;
	slurmdb_report_job_grouping_t *job_group = NULL;

	itr = list_iterator_create(cluster_list);
	while((cluster_group = list_next(itr))) {
		if (!strcmp(cluster, cluster_group->cluster))
			break;
	}
	list_iterator_destroy(itr);

	if (!cluster_group) {
		cluster_group = xmalloc(
			sizeof(slurmdb_report_cluster_grouping_t));
		cluster_group->cluster = xstrdup(cluster);
		cluster_group->acct_list = list_create(
			slurmdb_destroy_report_acct_grouping);
		list_append(cluster_list, cluster_group);
	}

	itr = list_iterator_create(cluster_group->acct_list);
	while((acct_group = list_next(itr))) {
		if (!strcmp(name, acct_group->acct))
			break;
	}
	list_iterator_destroy(itr);

	if (!acct_group) {
		uint32_t last_size = 0;
		char *group = NULL;
		acct_group = xmalloc(sizeof(slurmdb_report_acct_grouping_t));

		acct_group->acct = xstrdup(name);
		if (wckey_type == 1 || wckey_type == 3)
			acct_group->lft = wckey->id;
		else {
			acct_group->lft = assoc->lft;
			acct_group->rgt = assoc->rgt;
		}
		acct_group->groups = list_create(
			slurmdb_destroy_report_job_grouping);
		list_append(cluster_group->acct_list, acct_group);
		while ((group = list_next(group_itr))) {
			job_group = xmalloc(
				sizeof(slurmdb_report_job_grouping_t));
			job_group->jobs = list_create(NULL);
			if (!individual)
				job_group->min_size = last_size;
			last_size = atoi(group);
			if (!individual)
				job_group->max_size = last_size-1;
			else
				job_group->min_size =
					job_group->max_size = last_size;
			list_append(acct_group->groups, job_group);
		}
		if (last_size && !individual) {
			job_group = xmalloc(
				sizeof(slurmdb_report_job_grouping_t));
			job_group->jobs = list_create(NULL);
			job_group->min_size = last_size;
			if (individual)
				job_group->max_size =
					job_group->min_size;
			else
				job_group->max_size = INFINITE;
			list_append(acct_group->groups, job_group);
		}
		list_iterator_reset(group_itr);
	}
}
Esempio n. 26
0
extern int as_mysql_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
				 List cluster_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_cluster_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *extra = NULL,
		*query = NULL, *tmp_extra = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	int affect_rows = 0;
	int added = 0;
	List assoc_list = NULL;
	slurmdb_assoc_rec_t *assoc = NULL;

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER))
		return ESLURM_ACCESS_DENIED;

	assoc_list = list_create(slurmdb_destroy_assoc_rec);

	user_name = uid_to_string((uid_t) uid);
	/* Since adding tables make it so you can't roll back, if
	   there is an error there is no way to easily remove entries
	   in the database, so we will create the tables first and
	   then after that works out then add them to the mix.
	*/
	itr = list_iterator_create(cluster_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]) {
			error("We need a cluster name to add.");
			rc = SLURM_ERROR;
			list_remove(itr);
			continue;
		}
		if ((rc = create_cluster_tables(mysql_conn,
						object->name))
		    != SLURM_SUCCESS) {
			xfree(extra);
			xfree(cols);
			xfree(vals);
			added = 0;
			if (mysql_errno(mysql_conn->db_conn)
			    == ER_WRONG_TABLE_NAME)
				rc = ESLURM_BAD_NAME;
			goto end_it;
		}
	}

	/* Now that all the tables were created successfully lets go
	   ahead and add it to the system.
	*/
	list_iterator_reset(itr);
	while ((object = list_next(itr))) {
		xstrcat(cols, "creation_time, mod_time, acct");
		xstrfmtcat(vals, "%ld, %ld, 'root'", now, now);
		xstrfmtcat(extra, ", mod_time=%ld", now);
		if (object->root_assoc)
			setup_assoc_limits(object->root_assoc, &cols,
					   &vals, &extra,
					   QOS_LEVEL_SET, 1);
		xstrfmtcat(query,
			   "insert into %s (creation_time, mod_time, "
			   "name, classification) "
			   "values (%ld, %ld, '%s', %u) "
			   "on duplicate key update deleted=0, mod_time=%ld, "
			   "control_host='', control_port=0, "
			   "classification=%u, flags=0",
			   cluster_table,
			   now, now, object->name, object->classification,
			   now, object->classification);
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add cluster %s", object->name);
			xfree(extra);
			xfree(cols);
			xfree(vals);
			added=0;
			break;
		}

		affect_rows = last_affected_rows(mysql_conn);

		if (!affect_rows) {
			debug2("nothing changed %d", affect_rows);
			xfree(extra);
			xfree(cols);
			xfree(vals);
			continue;
		}

		xstrfmtcat(query,
			   "insert into \"%s_%s\" (%s, lft, rgt) "
			   "values (%s, 1, 2) "
			   "on duplicate key update deleted=0, "
			   "id_assoc=LAST_INSERT_ID(id_assoc)%s;",
			   object->name, assoc_table, cols,
			   vals,
			   extra);

		xfree(cols);
		xfree(vals);
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);

		rc = mysql_db_query(mysql_conn, query);
		xfree(query);

		if (rc != SLURM_SUCCESS) {
			error("Couldn't add cluster root assoc");
			xfree(extra);
			added=0;
			break;
		}

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		xstrfmtcat(query,
			   "insert into %s "
			   "(timestamp, action, name, actor, info) "
			   "values (%ld, %u, '%s', '%s', '%s');",
			   txn_table, now, DBD_ADD_CLUSTERS,
			   object->name, user_name, tmp_extra);
		xfree(tmp_extra);
		xfree(extra);
		debug4("%d(%s:%d) query\n%s",
		       mysql_conn->conn, THIS_FILE, __LINE__, query);

		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add txn");
		} else {
			ListIterator check_itr;
			char *tmp_name;

			added++;
			/* add it to the list and sort */
			slurm_mutex_lock(&as_mysql_cluster_list_lock);
			check_itr = list_iterator_create(as_mysql_cluster_list);
			while ((tmp_name = list_next(check_itr))) {
				if (!strcmp(tmp_name, object->name))
					break;
			}
			list_iterator_destroy(check_itr);
			if (!tmp_name) {
				list_append(as_mysql_cluster_list,
					    xstrdup(object->name));
				list_sort(as_mysql_cluster_list,
					  (ListCmpF)slurm_sort_char_list_asc);
			} else
				error("Cluster %s(%s) appears to already be in "
				      "our cache list, not adding.", tmp_name,
				      object->name);
			slurm_mutex_unlock(&as_mysql_cluster_list_lock);
		}
		/* Add user root by default to run from the root
		 * association.  This gets popped off so we need to
		 * read it every time here.
		 */
		assoc = xmalloc(sizeof(slurmdb_assoc_rec_t));
		slurmdb_init_assoc_rec(assoc, 0);
		list_append(assoc_list, assoc);

		assoc->cluster = xstrdup(object->name);
		assoc->user = xstrdup("root");
		assoc->acct = xstrdup("root");
		assoc->is_def = 1;

		if (as_mysql_add_assocs(mysql_conn, uid, assoc_list)
		    == SLURM_ERROR) {
			error("Problem adding root user association");
			rc = SLURM_ERROR;
		}
	}
end_it:
	list_iterator_destroy(itr);
	xfree(user_name);

	FREE_NULL_LIST(assoc_list);

	if (!added)
		reset_mysql_conn(mysql_conn);

	return rc;
}
static local_cluster_usage_t *_setup_cluster_usage(mysql_conn_t *mysql_conn,
						   char *cluster_name,
						   time_t curr_start,
						   time_t curr_end,
						   List cluster_down_list)
{
	local_cluster_usage_t *c_usage = NULL;
	char *query = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	int i = 0;
	ListIterator c_itr = NULL;
	local_cluster_usage_t *loc_c_usage;

	char *event_req_inx[] = {
		"node_name",
		"cpu_count",
		"time_start",
		"time_end",
		"state",
	};
	char *event_str = NULL;
	enum {
		EVENT_REQ_NAME,
		EVENT_REQ_CPU,
		EVENT_REQ_START,
		EVENT_REQ_END,
		EVENT_REQ_STATE,
		EVENT_REQ_COUNT
	};

	xstrfmtcat(event_str, "%s", event_req_inx[i]);
	for(i=1; i<EVENT_REQ_COUNT; i++) {
		xstrfmtcat(event_str, ", %s", event_req_inx[i]);
	}

	/* first get the events during this time.  All that is
	 * except things with the maintainance flag set in the
	 * state.  We handle those later with the reservations.
	 */
	query = xstrdup_printf("select %s from \"%s_%s\" where "
			       "!(state & %d) && (time_start < %ld "
			       "&& (time_end >= %ld "
			       "|| time_end = 0)) "
			       "order by node_name, time_start",
			       event_str, cluster_name, event_table,
			       NODE_STATE_MAINT,
			       curr_end, curr_start);
	xfree(event_str);

	if (debug_flags & DEBUG_FLAG_DB_USAGE)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}
	xfree(query);
	c_itr = list_iterator_create(cluster_down_list);
	while ((row = mysql_fetch_row(result))) {
		time_t row_start = slurm_atoul(row[EVENT_REQ_START]);
		time_t row_end = slurm_atoul(row[EVENT_REQ_END]);
		uint32_t row_cpu = slurm_atoul(row[EVENT_REQ_CPU]);
		uint16_t state = slurm_atoul(row[EVENT_REQ_STATE]);
		if (row_start < curr_start)
			row_start = curr_start;

		if (!row_end || row_end > curr_end)
			row_end = curr_end;

		/* Don't worry about it if the time is less
		 * than 1 second.
		 */
		if ((row_end - row_start) < 1)
			continue;

		/* this means we are a cluster registration
		   entry */
		if (!row[EVENT_REQ_NAME][0]) {
			/* if the cpu count changes we will
			 * only care about the last cpu count but
			 * we will keep a total of the time for
			 * all cpus to get the correct cpu time
			 * for the entire period.
			 */
			if (state || !c_usage) {
				loc_c_usage = xmalloc(
					sizeof(local_cluster_usage_t));
				loc_c_usage->cpu_count = row_cpu;
				loc_c_usage->total_time =
					(row_end - row_start) * row_cpu;
				loc_c_usage->start = row_start;
				loc_c_usage->end = row_end;
				/* If this has a state it
				   means the slurmctld went
				   down and we should put this
				   on the list and remove any
				   jobs from this time that
				   were running later.
				*/
				if (state)
					list_append(cluster_down_list,
						    loc_c_usage);
				else
					c_usage = loc_c_usage;
				loc_c_usage = NULL;
			} else {
				c_usage->cpu_count = row_cpu;
				c_usage->total_time +=
					(row_end - row_start) * row_cpu;
				c_usage->end = row_end;
			}
			continue;
		}

		/* only record down time for the cluster we
		   are looking for.  If it was during this
		   time period we would already have it.
		*/
		if (c_usage) {
			time_t local_start = row_start;
			time_t local_end = row_end;
			int seconds;
			if (c_usage->start > local_start)
				local_start = c_usage->start;
			if (c_usage->end < local_end)
				local_end = c_usage->end;
			seconds = (local_end - local_start);
			if (seconds > 0) {
				/* info("%p node %s adds " */
				/*      "(%d)(%ld-%ld) * %d = %"PRIu64" " */
				/*      "to %"PRIu64" (%s - %s)", */
				/*      c_usage, */
				/*      row[EVENT_REQ_NAME], */
				/*      seconds, */
				/*      local_end, local_start, */
				/*      row_cpu, */
				/*      seconds * (uint64_t)row_cpu, */
				/*      c_usage->d_cpu, */
				/*      slurm_ctime(&local_start), */
				/*      slurm_ctime(&local_end)); */
				c_usage->d_cpu += seconds * (uint64_t)row_cpu;
				/* Now remove this time if there was a
				   disconnected slurmctld during the
				   down time.
				*/
				list_iterator_reset(c_itr);
				while ((loc_c_usage = list_next(c_itr))) {
					int temp_end = row_end;
					int temp_start = row_start;
					if (loc_c_usage->start > local_start)
						temp_start = loc_c_usage->start;
					if (loc_c_usage->end < temp_end)
						temp_end = loc_c_usage->end;
					seconds = (temp_end - temp_start);
					if (seconds < 1)
						continue;

					seconds *= row_cpu;
					if (seconds >= loc_c_usage->total_time)
						loc_c_usage->total_time = 0;
					else
						loc_c_usage->total_time -=
							seconds;

					/* info("Node %s was down for " */
					/*      "%d seconds while " */
					/*      "cluster %s's slurmctld " */
					/*      "wasn't responding %"PRIu64, */
					/*      row[EVENT_REQ_NAME], */
					/*      seconds, cluster_name, */
					/*      loc_c_usage->total_time); */
				}
			}
		}
	}
	mysql_free_result(result);
	list_iterator_destroy(c_itr);

	return c_usage;
}
Esempio n. 28
0
extern List as_mysql_get_clusters(mysql_conn_t *mysql_conn, uid_t uid,
				  slurmdb_cluster_cond_t *cluster_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List cluster_list = NULL;
	ListIterator itr = NULL;
	int i=0;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	slurmdb_assoc_cond_t assoc_cond;
	ListIterator assoc_itr = NULL;
	slurmdb_cluster_rec_t *cluster = NULL;
	slurmdb_assoc_rec_t *assoc = NULL;
	List assoc_list = NULL;

	/* if this changes you will need to edit the corresponding enum */
	char *cluster_req_inx[] = {
		"name",
		"classification",
		"control_host",
		"control_port",
		"rpc_version",
		"dimensions",
		"flags",
		"plugin_id_select"
	};
	enum {
		CLUSTER_REQ_NAME,
		CLUSTER_REQ_CLASS,
		CLUSTER_REQ_CH,
		CLUSTER_REQ_CP,
		CLUSTER_REQ_VERSION,
		CLUSTER_REQ_DIMS,
		CLUSTER_REQ_FLAGS,
		CLUSTER_REQ_PI_SELECT,
		CLUSTER_REQ_COUNT
	};

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;


	if (!cluster_cond) {
		xstrcat(extra, " where deleted=0");
		goto empty;
	}

	_setup_cluster_cond_limits(cluster_cond, &extra);

empty:

	xfree(tmp);
	i=0;
	xstrfmtcat(tmp, "%s", cluster_req_inx[i]);
	for(i=1; i<CLUSTER_REQ_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", cluster_req_inx[i]);
	}

	query = xstrdup_printf("select %s from %s%s",
			       tmp, cluster_table, extra);
	xfree(tmp);
	xfree(extra);

	if (debug_flags & DEBUG_FLAG_DB_ASSOC)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}
	xfree(query);

	cluster_list = list_create(slurmdb_destroy_cluster_rec);

	memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));

	if (cluster_cond) {
		/* I don't think we want the with_usage flag here.
		 * We do need the with_deleted though. */
		//assoc_cond.with_usage = cluster_cond->with_usage;
		assoc_cond.with_deleted = cluster_cond->with_deleted;
	}
	assoc_cond.cluster_list = list_create(NULL);

	while ((row = mysql_fetch_row(result))) {
		MYSQL_RES *result2 = NULL;
		MYSQL_ROW row2;
		cluster = xmalloc(sizeof(slurmdb_cluster_rec_t));
		list_append(cluster_list, cluster);

		cluster->name = xstrdup(row[CLUSTER_REQ_NAME]);

		list_append(assoc_cond.cluster_list, cluster->name);

		cluster->classification = slurm_atoul(row[CLUSTER_REQ_CLASS]);
		cluster->control_host = xstrdup(row[CLUSTER_REQ_CH]);
		cluster->control_port = slurm_atoul(row[CLUSTER_REQ_CP]);
		cluster->rpc_version = slurm_atoul(row[CLUSTER_REQ_VERSION]);
		cluster->dimensions = slurm_atoul(row[CLUSTER_REQ_DIMS]);
		cluster->flags = slurm_atoul(row[CLUSTER_REQ_FLAGS]);
		cluster->plugin_id_select =
			slurm_atoul(row[CLUSTER_REQ_PI_SELECT]);

		query = xstrdup_printf(
			"select tres, cluster_nodes from "
			"\"%s_%s\" where time_end=0 and node_name='' limit 1",
			cluster->name, event_table);
		if (debug_flags & DEBUG_FLAG_DB_TRES)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		if (!(result2 = mysql_db_query_ret(mysql_conn, query, 0))) {
			xfree(query);
			continue;
		}
		xfree(query);
		if ((row2 = mysql_fetch_row(result2))) {
			cluster->tres_str = xstrdup(row2[0]);
			if (row2[1] && row2[1][0])
				cluster->nodes = xstrdup(row2[1]);
		}
		mysql_free_result(result2);

		/* get the usage if requested */
		if (cluster_cond && cluster_cond->with_usage) {
			as_mysql_get_usage(
				mysql_conn, uid, cluster,
				DBD_GET_CLUSTER_USAGE,
				cluster_cond->usage_start,
				cluster_cond->usage_end);
		}

	}
	mysql_free_result(result);

	if (!list_count(assoc_cond.cluster_list)) {
		FREE_NULL_LIST(assoc_cond.cluster_list);
		return cluster_list;
	}

	assoc_cond.acct_list = list_create(NULL);
	list_append(assoc_cond.acct_list, "root");

	assoc_cond.user_list = list_create(NULL);
	list_append(assoc_cond.user_list, "");

	assoc_list = as_mysql_get_assocs(mysql_conn, uid, &assoc_cond);
	FREE_NULL_LIST(assoc_cond.cluster_list);
	FREE_NULL_LIST(assoc_cond.acct_list);
	FREE_NULL_LIST(assoc_cond.user_list);

	if (!assoc_list)
		return cluster_list;

	itr = list_iterator_create(cluster_list);
	assoc_itr = list_iterator_create(assoc_list);
	while ((cluster = list_next(itr))) {
		while ((assoc = list_next(assoc_itr))) {
			if (strcmp(assoc->cluster, cluster->name))
				continue;

			if (cluster->root_assoc) {
				debug("This cluster %s already has "
				      "an association.", cluster->name);
				continue;
			}
			cluster->root_assoc = assoc;
			list_remove(assoc_itr);
		}
		list_iterator_reset(assoc_itr);
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(assoc_itr);
	if (list_count(assoc_list))
		error("I have %d left over associations",
		      list_count(assoc_list));
	FREE_NULL_LIST(assoc_list);

	return cluster_list;
}
Esempio n. 29
0
static void *_track_freeing_blocks(void *args)
{
	bg_free_block_list_t *bg_free_list = (bg_free_block_list_t *)args;
	List track_list = bg_free_list->track_list;
	bool destroy = bg_free_list->destroy;
	uint32_t job_id = bg_free_list->job_id;
	int retry_cnt = 0;
	int free_cnt = 0, track_cnt = list_count(track_list);
	ListIterator itr = list_iterator_create(track_list);
	bg_record_t *bg_record;
	bool restore = true;

	debug("_track_freeing_blocks: Going to free %d for job %u",
	      track_cnt, job_id);
	while (retry_cnt < MAX_FREE_RETRIES) {
		free_cnt = 0;
		slurm_mutex_lock(&block_state_mutex);

		/* just to make sure state is updated */
		bridge_status_update_block_list_state(track_list);

		list_iterator_reset(itr);
		/* just incase this changes from the update function */
		track_cnt = list_count(track_list);
		while ((bg_record = list_next(itr))) {
			if (bg_record->magic != BLOCK_MAGIC) {
				/* update_block_list_state should
				   remove this already from the list
				   so we shouldn't ever have this.
				*/
				error("_track_freeing_blocks: block was "
				      "already destroyed %p", bg_record);
				xassert(0);
				free_cnt++;
				continue;
			}
#ifndef HAVE_BG_FILES
			/* Fake a free since we are n deallocating
			   state before this.
			*/
			if (!(bg_record->state & BG_BLOCK_ERROR_FLAG)
			    && (retry_cnt >= 3))
				bg_record->state = BG_BLOCK_FREE;
#endif
			if ((bg_record->state == BG_BLOCK_FREE)
			    || (bg_record->state & BG_BLOCK_ERROR_FLAG))
				free_cnt++;
			else if (bg_record->state != BG_BLOCK_TERM)
				bg_free_block(bg_record, 0, 1);
		}
		slurm_mutex_unlock(&block_state_mutex);
		if (free_cnt == track_cnt)
			break;
		debug("_track_freeing_blocks: freed %d of %d for job %u",
		      free_cnt, track_cnt, job_id);
		sleep(FREE_SLEEP_INTERVAL);
		retry_cnt++;
	}
	debug("_track_freeing_blocks: Freed them all for job %u", job_id);

	if (destroy)
		restore = false;

	/* If there is a block in error state we need to keep all
	 * these blocks around. */
	slurm_mutex_lock(&block_state_mutex);
	list_iterator_reset(itr);
	while ((bg_record = list_next(itr))) {
		/* block no longer exists */
		if (bg_record->magic != BLOCK_MAGIC)
			continue;
		if (bg_record->state != BG_BLOCK_FREE) {
			restore = true;
			break;
		}
	}

	list_iterator_reset(itr);
	while ((bg_record = list_next(itr)))
		_post_block_free(bg_record, restore);
	slurm_mutex_unlock(&block_state_mutex);
	last_bg_update = time(NULL);
	list_iterator_destroy(itr);
	FREE_NULL_LIST(track_list);
	xfree(bg_free_list);
	return NULL;
}
Esempio n. 30
0
/* returns number of objects added to list */
static int _addto_id_char_list(List char_list, char *names, bool gid)
{
	int i=0, start=0;
	char *name = NULL, *tmp_char = NULL;
	ListIterator itr = NULL;
	char quote_c = '\0';
	int quote = 0;
	int count = 0;

	if(!char_list) {
		error("No list was given to fill in");
		return 0;
	}

	itr = list_iterator_create(char_list);
	if(names) {
		if (names[i] == '\"' || names[i] == '\'') {
			quote_c = names[i];
			quote = 1;
			i++;
		}
		start = i;
		while(names[i]) {
			//info("got %d - %d = %d", i, start, i-start);
			if(quote && names[i] == quote_c)
				break;
			else if (names[i] == '\"' || names[i] == '\'')
				names[i] = '`';
			else if(names[i] == ',') {
				if((i-start) > 0) {
					name = xmalloc((i-start+1));
					memcpy(name, names+start, (i-start));
					//info("got %s %d", name, i-start);
					name = _convert_to_id( name, gid );

					while((tmp_char = list_next(itr))) {
						if(!strcasecmp(tmp_char, name))
							break;
					}

					if(!tmp_char) {
						list_append(char_list, name);
						count++;
					} else
						xfree(name);
					list_iterator_reset(itr);
				}
				i++;
				start = i;
				if(!names[i]) {
					info("There is a problem with "
					     "your request.  It appears you "
					     "have spaces inside your list.");
					break;
				}
			}
			i++;
		}
		if((i-start) > 0) {
			name = xmalloc((i-start)+1);
			memcpy(name, names+start, (i-start));
			name = _convert_to_id(name, gid);

			while((tmp_char = list_next(itr))) {
				if(!strcasecmp(tmp_char, name))
					break;
			}

			if(!tmp_char) {
				list_append(char_list, name);
				count++;
			} else
				xfree(name);
		}
	}
	list_iterator_destroy(itr);
	return count;
}