blob: b05b3b7d4b4dd522bda2406dbb88a1d598d12a1c [file] [log] [blame] [edit]
/*****************************************************************************\
* job_info.c - Functions related to job display
* mode of sview.
*****************************************************************************
* Copyright (C) 2004-2006 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@llnl.gov>
*
* UCRL-CODE-226842.
*
* This file is part of SLURM, a resource management program.
* For details, see <http://www.llnl.gov/linux/slurm/>.
*
* SLURM is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with SLURM; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "src/common/uid.h"
#include "src/common/node_select.h"
#include "src/sview/sview.h"
#include "src/common/parse_time.h"
#include <grp.h>
#define _DEBUG 0
#define MAX_CANCEL_RETRY 10
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
/* Collection of data for printing reports. Like data is combined here */
typedef struct {
job_info_t *job_ptr;
char *nodes;
int node_cnt;
char *color;
List step_list;
} sview_job_info_t;
enum {
EDIT_SIGNAL = 1,
EDIT_SIGNAL_USER,
EDIT_CANCEL,
EDIT_CANCEL_USER,
EDIT_SUSPEND,
EDIT_EDIT
};
/* These need to be in alpha order (except POS and CNT) */
enum {
SORTID_POS = POS_LOC,
SORTID_ACCOUNT,
SORTID_ACTION,
SORTID_ALLOC,
SORTID_ALLOC_NODE,
SORTID_BATCH,
#ifdef HAVE_BG
SORTID_BLRTSIMAGE,
SORTID_NODELIST,
SORTID_BLOCK,
#endif
SORTID_COMMENT,
#ifdef HAVE_BG
SORTID_CONNECTION,
#endif
SORTID_CONTIGUOUS,
SORTID_DEPENDENCY,
SORTID_CPUS_PER_TASK,
SORTID_END_TIME,
SORTID_EXC_NODELIST,
SORTID_FEATURES,
SORTID_EXIT_CODE,
#ifdef HAVE_BG
SORTID_GEOMETRY,
#endif
SORTID_GROUP,
SORTID_JOBID,
#ifdef HAVE_BG
SORTID_LINUXIMAGE,
#endif
SORTID_MAX_CORES,
SORTID_MAX_MEM,
SORTID_MAX_NODES,
SORTID_MAX_SOCKETS,
#ifdef HAVE_BG
SORTID_MAX_PROCS,
#endif
SORTID_MAX_THREADS,
SORTID_MIN_CORES,
SORTID_MIN_MEM,
SORTID_MIN_NODES,
SORTID_MIN_PROCS,
SORTID_MIN_SOCKETS,
SORTID_MIN_THREADS,
#ifdef HAVE_BG
SORTID_MLOADERIMAGE,
#endif
SORTID_NAME,
SORTID_NETWORK,
SORTID_NICE,
#ifndef HAVE_BG
SORTID_NODELIST,
#endif
SORTID_NODES,
SORTID_NTASKS_PER_CORE,
SORTID_NTASKS_PER_NODE,
SORTID_NTASKS_PER_SOCKET,
SORTID_NUM_PROCS,
SORTID_PARTITION,
SORTID_PRIORITY,
#ifdef HAVE_BG
SORTID_RAMDISKIMAGE,
#endif
SORTID_REASON,
SORTID_REQ_NODELIST,
SORTID_REQ_PROCS,
#ifdef HAVE_BG
SORTID_ROTATE,
#endif
SORTID_SHARED,
#ifdef HAVE_BG
SORTID_START,
#endif
SORTID_START_TIME,
SORTID_STATE,
SORTID_STATE_NUM,
SORTID_SUBMIT_TIME,
SORTID_SUSPEND_TIME,
SORTID_TASKS,
SORTID_TIME,
SORTID_TIMELIMIT,
SORTID_TMP_DISK,
SORTID_UPDATED,
SORTID_USER,
SORTID_CNT
};
/* extra field here is for choosing the type of edit you that will
* take place. If you choose EDIT_MODEL (means only display a set of
* known options) create it in function create_model_*.
*/
static display_data_t display_data_job[] = {
{G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_INT, SORTID_JOBID, "JobID", TRUE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_ACTION, "Action", FALSE,
EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_INT, SORTID_ALLOC, NULL, FALSE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_PARTITION, "Partition", TRUE,
EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
#ifdef HAVE_BG
{G_TYPE_STRING, SORTID_BLOCK, "BG Block", TRUE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_GEOMETRY, "Geometry",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_START, "Start",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_ROTATE, "Rotate",
FALSE, EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_CONNECTION, "Connection",
FALSE, EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_BLRTSIMAGE, "Blrts Image",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_LINUXIMAGE, "linux Image",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MLOADERIMAGE, "Mloader Image",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_RAMDISKIMAGE, "Ramdisk Image",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
#endif
{G_TYPE_STRING, SORTID_USER, "User", TRUE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_GROUP, "Group", FALSE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NAME, "Name", TRUE, EDIT_TEXTBOX, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_STATE, "State", TRUE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_INT, SORTID_STATE_NUM, NULL, FALSE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_TIME, "Running Time", TRUE,
EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_SUBMIT_TIME, "Submit Time", FALSE,
EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_START_TIME, "Start Time", FALSE,
EDIT_TEXTBOX, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_END_TIME, "End Time", FALSE,
EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_SUSPEND_TIME, "Suspended Time", FALSE,
EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_TIMELIMIT, "Time Limit", FALSE,
EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
#ifdef HAVE_BG
{G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE, EDIT_NONE,
refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_REQ_NODELIST, "Requested BP List",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_EXC_NODELIST, "Excluded BP List",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
#else
{G_TYPE_STRING, SORTID_NODELIST, "Nodelist", TRUE,
EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_REQ_NODELIST, "Requested NodeList",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_EXC_NODELIST, "Excluded NodeList",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
#endif
{G_TYPE_STRING, SORTID_CONTIGUOUS, "Contiguous", FALSE, EDIT_MODEL,
refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_PRIORITY, "Priority", FALSE,
EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_EXIT_CODE, "Exit Code", FALSE,
EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_BATCH, "Batch Flag", FALSE,
EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NUM_PROCS, "Num Processors",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_TASKS, "Num Tasks",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_SHARED, "Shared", FALSE,
EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_CPUS_PER_TASK, "Cpus per Task",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_REQ_PROCS, "Requested Procs",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MIN_NODES, "Min Nodes",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MAX_NODES, "Max Nodes",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MIN_PROCS, "Min Procs",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
#ifdef HAVE_BG
{G_TYPE_STRING, SORTID_MAX_PROCS, "Max Procs",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
#endif
{G_TYPE_STRING, SORTID_MIN_SOCKETS, "Min Sockets",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MAX_SOCKETS, "Max Sockets",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MIN_CORES, "Min Cores",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MAX_CORES, "Max Cores",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MIN_THREADS, "Min Threads",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MAX_THREADS, "Max Threads",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MIN_MEM, "Min Memory",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_MAX_MEM, "Max Memory",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_TMP_DISK, "Tmp Disk",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NICE, "Nice",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_ACCOUNT, "Account Charged",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_REASON, "Wait Reason",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_FEATURES, "Features",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_DEPENDENCY, "Dependency",
FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_ALLOC_NODE, "Alloc Node : Sid",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NTASKS_PER_NODE, "Num tasks per Node",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NTASKS_PER_SOCKET, "Num tasks per Socket",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NTASKS_PER_CORE, "Num tasks per Core",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_NETWORK, "Network",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_STRING, SORTID_COMMENT, "Comment",
FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
{G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, EDIT_NONE, refresh_job,
create_model_job, admin_edit_job},
{G_TYPE_NONE, EDIT_NONE, NULL, FALSE, EDIT_NONE}
};
static display_data_t options_data_job[] = {
{G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE},
{G_TYPE_STRING, INFO_PAGE, "Full Info", TRUE, JOB_PAGE},
{G_TYPE_STRING, JOB_PAGE, "Signal", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, JOB_PAGE, "Cancel", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, JOB_PAGE, "Suspend/Resume", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, JOB_PAGE, "Edit Job", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Partition", TRUE, JOB_PAGE},
#ifdef HAVE_BG
{G_TYPE_STRING, BLOCK_PAGE, "Block", TRUE, JOB_PAGE},
{G_TYPE_STRING, NODE_PAGE, "Base Partitions", TRUE, JOB_PAGE},
#else
{G_TYPE_STRING, NODE_PAGE, "Nodes", TRUE, JOB_PAGE},
#endif
{G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
};
struct signv {
char *name;
uint16_t val;
} sig_name_num[ ] = {
{ "HUP", SIGHUP },
{ "INT", SIGINT },
{ "QUIT", SIGQUIT },
{ "ABRT", SIGABRT },
{ "KILL", SIGKILL },
{ "ALRM", SIGALRM },
{ "TERM", SIGTERM },
{ "USR1", SIGUSR1 },
{ "USR2", SIGUSR2 },
{ "CONT", SIGCONT },
{ "STOP", SIGSTOP },
{ "TSTP", SIGTSTP },
{ "TTIN", SIGTTIN },
{ "TTOU", SIGTTOU },
{ "SIGHUP", SIGHUP },
{ "SIGINT", SIGINT },
{ "SIGQUIT", SIGQUIT },
{ "SIGABRT", SIGABRT },
{ "SIGKILL", SIGKILL },
{ "SIGALRM", SIGALRM },
{ "SIGTERM", SIGTERM },
{ "SIGUSR1", SIGUSR1 },
{ "SIGUSR2", SIGUSR2 },
{ "SIGCONT", SIGCONT },
{ "SIGSTOP", SIGSTOP },
{ "SIGTSTP", SIGTSTP },
{ "SIGTTIN", SIGTTIN },
{ "SIGTTOU", SIGTTOU }
};
static display_data_t *local_display_data = NULL;
static char *got_edit_signal = NULL;
static void _update_info_step(sview_job_info_t *sview_job_info_ptr,
GtkTreeModel *model,
GtkTreeIter *step_iter,
GtkTreeIter *iter);
/* translate name name to number */
static uint16_t _xlate_signal_name(const char *signal_name)
{
uint16_t sig_num = (uint16_t)NO_VAL;
char *end_ptr, *sig_names = NULL;
int i;
sig_num = (uint16_t) strtol(signal_name, &end_ptr, 10);
if ((*end_ptr == '\0') && (sig_num != 0))
return sig_num;
for (i=0; i<SIZE(sig_name_num); i++) {
if (strcasecmp(sig_name_num[i].name, signal_name) == 0) {
xfree(sig_names);
return sig_name_num[i].val;
}
if (i == 0)
sig_names = xstrdup(sig_name_num[i].name);
else {
xstrcat(sig_names, ",");
xstrcat(sig_names, sig_name_num[i].name);
}
}
xfree(sig_names);
return (uint16_t)NO_VAL;
}
static void _cancel_job_id (uint32_t job_id, uint16_t signal)
{
int error_code = SLURM_SUCCESS, i;
char *temp = NULL;
for (i=0; i<MAX_CANCEL_RETRY; i++) {
if ((signal == (uint16_t)-1) || (signal == SIGKILL)) {
signal = 9;
error_code = slurm_kill_job(job_id, SIGKILL,
false);
} else {
error_code = slurm_signal_job(job_id, signal);
}
if (error_code == 0
|| (errno != ESLURM_TRANSITION_STATE_NO_UPDATE
&& errno != ESLURM_JOB_PENDING))
break;
temp = g_strdup_printf("Sending signal %u to job %u",
signal, job_id);
display_edit_note(temp);
g_free(temp);
sleep ( 5 + i );
}
if (error_code) {
error_code = slurm_get_errno();
if ((error_code != ESLURM_ALREADY_DONE) &&
(error_code != ESLURM_INVALID_JOB_ID)) {
temp = g_strdup_printf(
"Kill job error on job id %u: %s",
job_id, slurm_strerror(slurm_get_errno()));
display_edit_note(temp);
g_free(temp);
} else {
display_edit_note(slurm_strerror(slurm_get_errno()));
}
} else {
temp = g_strdup_printf("Signal successfully sent to job %u",
job_id);
display_edit_note(temp);
g_free(temp);
}
}
static void _cancel_step_id(uint32_t job_id, uint32_t step_id,
uint16_t signal)
{
int error_code = SLURM_SUCCESS, i;
char *temp = NULL;
for (i=0; i<MAX_CANCEL_RETRY; i++) {
if (signal == (uint16_t)-1 || (signal == SIGKILL)) {
signal = 9;
error_code = slurm_terminate_job_step(job_id, step_id);
} else {
error_code = slurm_signal_job_step(job_id, step_id,
signal);
}
if (error_code == 0
|| (errno != ESLURM_TRANSITION_STATE_NO_UPDATE
&& errno != ESLURM_JOB_PENDING))
break;
temp = g_strdup_printf("Sending signal %u to job step %u.%u",
signal, job_id, step_id);
display_edit_note(temp);
g_free(temp);
sleep ( 5 + i );
}
if (error_code) {
error_code = slurm_get_errno();
if (error_code != ESLURM_ALREADY_DONE) {
temp = g_strdup_printf(
"Kill job error on job step id %u.%u: %s",
job_id, step_id,
slurm_strerror(slurm_get_errno()));
display_edit_note(temp);
g_free(temp);
} else {
display_edit_note(slurm_strerror(slurm_get_errno()));
}
} else {
temp = g_strdup_printf(
"Signal successfully sent to job step %u.%u",
job_id, step_id);
display_edit_note(temp);
g_free(temp);
}
}
static void _set_active_combo_job(GtkComboBox *combo,
GtkTreeModel *model, GtkTreeIter *iter,
int type)
{
char *temp_char = NULL;
int action = 0;
gtk_tree_model_get(model, iter, type, &temp_char, -1);
if(!temp_char)
goto end_it;
switch(type) {
case SORTID_ACTION:
if(!strcmp(temp_char, "none"))
action = 0;
else if(!strcmp(temp_char, "cancel"))
action = 1;
else if(!strcmp(temp_char, "suspend"))
action = 2;
else if(!strcmp(temp_char, "resume"))
action = 3;
else if(!strcmp(temp_char, "checkpoint"))
action = 4;
else if(!strcmp(temp_char, "requeue"))
action = 5;
else
action = 0;
break;
case SORTID_SHARED:
if(!strcmp(temp_char, "yes"))
action = 0;
else if(!strcmp(temp_char, "no"))
action = 1;
else
action = 0;
break;
case SORTID_CONTIGUOUS:
if(!strcmp(temp_char, "yes"))
action = 0;
else if(!strcmp(temp_char, "no"))
action = 1;
else
action = 0;
break;
#ifdef HAVE_BG
case SORTID_ROTATE:
if(!strcmp(temp_char, "yes"))
action = 0;
else if(!strcmp(temp_char, "no"))
action = 1;
else
action = 0;
break;
case SORTID_CONNECTION:
if(!strcmp(temp_char, "torus"))
action = 0;
else if(!strcmp(temp_char, "mesh"))
action = 1;
else if(!strcmp(temp_char, "nav"))
action = 2;
else
action = 0;
break;
#endif
default:
break;
}
g_free(temp_char);
end_it:
gtk_combo_box_set_active(combo, action);
}
/* don't free this char */
static const char *_set_job_msg(job_desc_msg_t *job_msg, const char *new_text,
int column)
{
char *type = NULL;
int temp_int = 0;
#ifdef HAVE_BG
uint16_t rotate;
uint16_t conn_type;
char* token, *delimiter = ",x", *next_ptr;
int j;
uint16_t geo[SYSTEM_DIMENSIONS];
char* geometry_tmp = xstrdup(new_text);
char* original_ptr = geometry_tmp;
#endif
if(!job_msg)
return NULL;
switch(column) {
case SORTID_ACTION:
xfree(got_edit_signal);
if(!strcasecmp(new_text, "None"))
got_edit_signal = NULL;
else
got_edit_signal = xstrdup(new_text);
break;
case SORTID_TIMELIMIT:
if(!strcasecmp(new_text, "infinite"))
temp_int = INFINITE;
else
temp_int = time_str2mins((char *)new_text);
type = "timelimit";
if(temp_int <= 0 && temp_int != INFINITE)
goto return_error;
job_msg->time_limit = (uint32_t)temp_int;
break;
case SORTID_PRIORITY:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "priority";
if(temp_int < 0)
goto return_error;
job_msg->priority = (uint32_t)temp_int;
break;
case SORTID_NICE:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "nice";
if (abs(temp_int) > NICE_OFFSET) {
//error("Invalid nice value, must be between "
// "-%d and %d", NICE_OFFSET, NICE_OFFSET);
goto return_error;
}
job_msg->nice = NICE_OFFSET + temp_int;
break;
case SORTID_REQ_PROCS:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "requested procs";
if(temp_int <= 0)
goto return_error;
job_msg->num_procs = (uint32_t)temp_int;
break;
case SORTID_MIN_NODES:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "min nodes";
if(temp_int <= 0)
goto return_error;
job_msg->min_nodes = (uint32_t)temp_int;
break;
case SORTID_MAX_NODES:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "max nodes";
if(temp_int <= 0)
goto return_error;
job_msg->max_nodes = (uint32_t)temp_int;
break;
case SORTID_MIN_PROCS:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "min procs";
if(temp_int <= 0)
goto return_error;
job_msg->job_min_procs = (uint32_t)temp_int;
break;
case SORTID_MIN_MEM:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "min memory";
if(temp_int <= 0)
goto return_error;
job_msg->job_min_memory = (uint32_t)temp_int;
break;
case SORTID_TMP_DISK:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "min tmp disk";
if(temp_int <= 0)
goto return_error;
job_msg->job_min_tmp_disk = (uint32_t)temp_int;
break;
case SORTID_PARTITION:
job_msg->partition = xstrdup(new_text);
type = "partition";
break;
case SORTID_NAME:
job_msg->name = xstrdup(new_text);
type = "name";
break;
case SORTID_SHARED:
if (!strcasecmp(new_text, "yes")) {
job_msg->shared = 1;
} else {
job_msg->shared = 0;
}
type = "shared";
break;
case SORTID_CONTIGUOUS:
if (!strcasecmp(new_text, "yes")) {
job_msg->contiguous = 1;
} else {
job_msg->contiguous = 0;
}
type = "contiguous";
break;
case SORTID_REQ_NODELIST:
job_msg->req_nodes = xstrdup(new_text);
type = "requested nodelist";
break;
case SORTID_EXC_NODELIST:
job_msg->exc_nodes = xstrdup(new_text);
type = "excluded nodelist";
break;
case SORTID_FEATURES:
job_msg->features = xstrdup(new_text);
type = "features";
break;
case SORTID_ACCOUNT:
job_msg->account = xstrdup(new_text);
type = "account";
break;
case SORTID_DEPENDENCY:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "dependency";
if(temp_int <= 0)
goto return_error;
job_msg->dependency = (uint32_t)temp_int;
break;
#ifdef HAVE_BG
case SORTID_GEOMETRY:
type = "geometry";
token = strtok_r(geometry_tmp, delimiter, &next_ptr);
for (j=0; j<SYSTEM_DIMENSIONS; j++)
geo[j] = (uint16_t) NO_VAL;
for (j=0; j<SYSTEM_DIMENSIONS; j++) {
if (token == NULL) {
//error("insufficient dimensions in "
// "Geometry");
goto return_error;
}
geo[j] = (uint16_t) atoi(token);
if (geo[j] <= 0) {
//error("invalid --geometry argument");
xfree(original_ptr);
goto return_error;
break;
}
geometry_tmp = next_ptr;
token = strtok_r(geometry_tmp, delimiter,
&next_ptr);
}
if (token != NULL) {
//error("too many dimensions in Geometry");
xfree(original_ptr);
goto return_error;
}
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_GEOMETRY,
(void *) &geo);
break;
case SORTID_START:
type = "start";
token = strtok_r(geometry_tmp, delimiter, &next_ptr);
for (j=0; j<SYSTEM_DIMENSIONS; j++)
geo[j] = (uint16_t) NO_VAL;
for (j=0; j<SYSTEM_DIMENSIONS; j++) {
if (token == NULL) {
//error("insufficient dimensions in "
// "Geometry");
goto return_error;
}
geo[j] = (uint16_t) atoi(token);
if (geo[j] <= 0) {
//error("invalid --geometry argument");
xfree(original_ptr);
goto return_error;
break;
}
geometry_tmp = next_ptr;
token = strtok_r(geometry_tmp, delimiter,
&next_ptr);
}
if (token != NULL) {
//error("too many dimensions in Geometry");
xfree(original_ptr);
goto return_error;
}
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_START,
(void *) &geo);
break;
case SORTID_ROTATE:
type = "rotate";
if (!strcasecmp(new_text, "yes")) {
rotate = 1;
} else {
rotate = 0;
}
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_ROTATE,
(void *) &rotate);
break;
case SORTID_CONNECTION:
type = "connection";
if (!strcasecmp(new_text, "torus")) {
conn_type = SELECT_TORUS;
} else if (!strcasecmp(new_text, "mesh")) {
conn_type = SELECT_MESH;
} else {
conn_type = SELECT_NAV;
}
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_CONN_TYPE,
(void *) &conn_type);
break;
case SORTID_BLRTSIMAGE:
type = "BlrtsImage";
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_BLRTS_IMAGE,
(void *) new_text);
break;
case SORTID_LINUXIMAGE:
type = "LinuxImage";
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_LINUX_IMAGE,
(void *) new_text);
break;
case SORTID_MLOADERIMAGE:
type = "MloaderImage";
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_MLOADER_IMAGE,
(void *) new_text);
break;
case SORTID_RAMDISKIMAGE:
type = "RamdiskImage";
if(!job_msg->select_jobinfo)
select_g_alloc_jobinfo(&job_msg->select_jobinfo);
select_g_set_jobinfo(job_msg->select_jobinfo,
SELECT_DATA_RAMDISK_IMAGE,
(void *) new_text);
break;
#endif
case SORTID_START_TIME:
job_msg->begin_time = parse_time((char *)new_text);
type = "start time";
break;
default:
type = "unknown";
break;
}
#ifdef HAVE_BG
xfree(geometry_tmp);
#endif
return type;
return_error:
#ifdef HAVE_BG
xfree(geometry_tmp);
#endif
errno = 1;
return type;
}
static void _admin_edit_combo_box_job(GtkComboBox *combo,
job_desc_msg_t *job_msg)
{
GtkTreeModel *model = NULL;
GtkTreeIter iter;
int column = 0;
char *name = NULL;
if(!job_msg)
return;
if(!gtk_combo_box_get_active_iter(combo, &iter)) {
g_print("nothing selected\n");
return;
}
model = gtk_combo_box_get_model(combo);
if(!model) {
g_print("nothing selected\n");
return;
}
gtk_tree_model_get(model, &iter, 0, &name, -1);
gtk_tree_model_get(model, &iter, 1, &column, -1);
_set_job_msg(job_msg, name, column);
g_free(name);
}
static gboolean _admin_focus_out_job(GtkEntry *entry,
GdkEventFocus *event,
job_desc_msg_t *job_msg)
{
int type = gtk_entry_get_max_length(entry);
const char *name = gtk_entry_get_text(entry);
type -= DEFAULT_ENTRY_LENGTH;
_set_job_msg(job_msg, name, type);
return false;
}
static GtkWidget *_admin_full_edit_job(job_desc_msg_t *job_msg,
GtkTreeModel *model, GtkTreeIter *iter)
{
GtkScrolledWindow *window = create_scrolled_window();
GtkBin *bin = NULL;
GtkViewport *view = NULL;
GtkTable *table = NULL;
GtkWidget *label = NULL;
GtkWidget *entry = NULL;
GtkTreeModel *model2 = NULL;
GtkCellRenderer *renderer = NULL;
int i = 0, row = 0;
char *temp_char = NULL;
gtk_scrolled_window_set_policy(window,
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
bin = GTK_BIN(&window->container);
view = GTK_VIEWPORT(bin->child);
bin = GTK_BIN(&view->bin);
table = GTK_TABLE(bin->child);
gtk_table_resize(table, SORTID_CNT, 2);
gtk_table_set_homogeneous(table, FALSE);
for(i = 0; i < SORTID_CNT; i++) {
if(display_data_job[i].extra == EDIT_MODEL) {
/* edittable items that can only be known
values */
model2 = GTK_TREE_MODEL(
create_model_job(display_data_job[i].id));
if(!model2) {
g_print("no model set up for %d(%s)\n",
display_data_job[i].id,
display_data_job[i].name);
continue;
}
entry = gtk_combo_box_new_with_model(model2);
g_object_unref(model2);
_set_active_combo_job(GTK_COMBO_BOX(entry), model,
iter, display_data_job[i].id);
g_signal_connect(entry, "changed",
G_CALLBACK(_admin_edit_combo_box_job),
job_msg);
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(entry),
renderer, TRUE);
gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(entry),
renderer, "text", 0);
} else if(display_data_job[i].extra == EDIT_TEXTBOX) {
/* other edittable items that are unknown */
entry = create_entry();
gtk_tree_model_get(model, iter, display_data_job[i].id,
&temp_char, -1);
gtk_entry_set_max_length(GTK_ENTRY(entry),
(DEFAULT_ENTRY_LENGTH +
display_data_job[i].id));
if(temp_char) {
gtk_entry_set_text(GTK_ENTRY(entry),
temp_char);
g_free(temp_char);
}
g_signal_connect(entry, "focus-out-event",
G_CALLBACK(_admin_focus_out_job),
job_msg);
} else /* others can't be altered by the user */
continue;
label = gtk_label_new(display_data_job[i].name);
gtk_table_attach(table, label, 0, 1, row, row+1,
GTK_FILL | GTK_EXPAND, GTK_SHRINK,
0, 0);
gtk_table_attach(table, entry, 1, 2, row, row+1,
GTK_FILL, GTK_SHRINK,
0, 0);
row++;
}
gtk_table_resize(table, row, 2);
return GTK_WIDGET(window);
}
static int _nodes_in_list(char *node_list)
{
hostset_t host_set = hostset_create(node_list);
int count = hostset_count(host_set);
hostset_destroy(host_set);
return count;
}
static int _get_node_cnt(job_info_t * job)
{
int node_cnt = 0;
bool completing = job->job_state & JOB_COMPLETING;
uint16_t base_job_state = job->job_state & (~JOB_COMPLETING);
if (base_job_state == JOB_PENDING || completing) {
node_cnt = _nodes_in_list(job->req_nodes);
node_cnt = MAX(node_cnt, job->num_nodes);
} else
node_cnt = _nodes_in_list(job->nodes);
return node_cnt;
}
/* this needs to be freed by xfree() */
static void _convert_char_to_job_and_step(const char *data,
int *jobid, int *stepid)
{
int i = 0;
if(!data)
return;
*jobid = atoi(data);
*stepid = NO_VAL;
while(data[i]) {
if(data[i] == '.') {
i++;
if(data[i])
*stepid = atoi(&data[i]);
break;
}
i++;
}
return;
}
static void _layout_job_record(GtkTreeView *treeview,
sview_job_info_t *sview_job_info_ptr,
int update)
{
char *nodes = NULL, *uname = NULL;
char tmp_char[50];
time_t now_time = time(NULL);
job_info_t *job_ptr = sview_job_info_ptr->job_ptr;
struct group *group_info = NULL;
uint16_t term_sig = 0;
GtkTreeIter iter;
GtkTreeStore *treestore =
GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
if(!treestore)
return;
if(!job_ptr->nodes || !strcasecmp(job_ptr->nodes,"waiting...")) {
sprintf(tmp_char,"0:00:00");
nodes = "waiting...";
} else {
if (job_ptr->job_state == JOB_SUSPENDED)
now_time = job_ptr->pre_sus_time;
else {
if ((job_ptr->job_state != JOB_RUNNING)
&& (job_ptr->end_time != 0))
now_time = job_ptr->end_time;
if (job_ptr->suspend_time)
now_time = (difftime(now_time,
job_ptr->suspend_time)
+ job_ptr->pre_sus_time);
now_time = difftime(now_time, job_ptr->start_time);
}
secs2time_str(now_time, tmp_char, sizeof(tmp_char));
nodes = sview_job_info_ptr->nodes;
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_TIME),
tmp_char);
slurm_make_time_str((time_t *)&job_ptr->submit_time, tmp_char,
sizeof(tmp_char));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_SUBMIT_TIME),
tmp_char);
slurm_make_time_str((time_t *)&job_ptr->start_time, tmp_char,
sizeof(tmp_char));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_START_TIME),
tmp_char);
if ((job_ptr->time_limit == INFINITE) &&
(job_ptr->end_time > time(NULL)))
sprintf(tmp_char, "NONE");
else
slurm_make_time_str((time_t *)&job_ptr->end_time, tmp_char,
sizeof(tmp_char));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_END_TIME),
tmp_char);
secs2time_str(job_ptr->suspend_time, tmp_char, sizeof(tmp_char));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_SUSPEND_TIME),
tmp_char);
if (job_ptr->time_limit == NO_VAL)
sprintf(tmp_char, "Partition Limit");
else
secs2time_str((job_ptr->time_limit * 60),
tmp_char, sizeof(tmp_char));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_TIMELIMIT),
tmp_char);
snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->job_id);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_JOBID),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_PARTITION),
job_ptr->partition);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NODELIST),
nodes);
#ifdef HAVE_BG
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_BLOCK),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_BG_ID));
#endif
uname = uid_to_string((uid_t)job_ptr->user_id);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_USER), uname);
xfree(uname);
group_info = getgrgid((gid_t) job_ptr->group_id );
if ( group_info && group_info->gr_name[ 0 ] ) {
snprintf(tmp_char, sizeof(tmp_char), "%s",
group_info->gr_name);
} else {
snprintf(tmp_char, sizeof(tmp_char), "%u",
job_ptr->group_id );
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_GROUP),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NAME),
job_ptr->name);
sprintf(tmp_char, "%u", job_ptr->priority);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_PRIORITY),
tmp_char);
if(job_ptr->batch_flag)
sprintf(tmp_char, "yes");
else
sprintf(tmp_char, "no");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_BATCH),
tmp_char);
if (WIFSIGNALED(job_ptr->exit_code))
term_sig = WTERMSIG(job_ptr->exit_code);
snprintf(tmp_char, sizeof(tmp_char), "%u:%u",
WEXITSTATUS(job_ptr->exit_code), term_sig);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_EXIT_CODE),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_STATE),
job_state_string(job_ptr->job_state));
#ifdef HAVE_BG
convert_num_unit((float)sview_job_info_ptr->node_cnt,
tmp_char, sizeof(tmp_char), UNIT_NONE);
#else
snprintf(tmp_char, sizeof(tmp_char), "%u",
sview_job_info_ptr->node_cnt);
#endif
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NODES),
tmp_char);
#ifdef HAVE_BG
convert_num_unit((float)job_ptr->num_procs, tmp_char, sizeof(tmp_char),
UNIT_NONE);
#else
snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->num_procs);
#endif
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NUM_PROCS),
tmp_char);
snprintf(tmp_char, sizeof(tmp_char), "%s:%u",
job_ptr->alloc_node, job_ptr->alloc_sid);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_ALLOC_NODE),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_REQ_NODELIST),
job_ptr->req_nodes);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_EXC_NODELIST),
job_ptr->exc_nodes);
#ifdef HAVE_BG
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_BLOCK),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_BG_ID));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_CONNECTION),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_CONNECTION));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_ROTATE),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_ROTATE));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_GEOMETRY),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_GEOMETRY));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_START),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_START));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_MAX_PROCS),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_MAX_PROCS));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_BLRTSIMAGE),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_BLRTS_IMAGE));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_LINUXIMAGE),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_LINUX_IMAGE));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_MLOADERIMAGE),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_MLOADER_IMAGE));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_RAMDISKIMAGE),
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_RAMDISK_IMAGE));
#endif
if(job_ptr->contiguous)
sprintf(tmp_char, "yes");
else
sprintf(tmp_char, "no");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_CONTIGUOUS),
tmp_char);
if(job_ptr->shared)
sprintf(tmp_char, "yes");
else
sprintf(tmp_char, "no");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_SHARED),
tmp_char);
if(job_ptr->cpus_per_task > 0)
sprintf(tmp_char, "%u", job_ptr->cpus_per_task);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_CPUS_PER_TASK),
tmp_char);
if(job_ptr->job_min_procs > 0)
sprintf(tmp_char, "%u", job_ptr->job_min_procs);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_MIN_PROCS),
tmp_char);
if(job_ptr->job_min_sockets > 0)
sprintf(tmp_char, "%u", job_ptr->job_min_sockets);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_MIN_SOCKETS),
tmp_char);
if(job_ptr->job_min_cores > 0)
sprintf(tmp_char, "%u", job_ptr->job_min_cores);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_MIN_CORES),
tmp_char);
if(job_ptr->job_min_threads > 0)
sprintf(tmp_char, "%u", job_ptr->job_min_threads);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_MIN_THREADS),
tmp_char);
if(job_ptr->job_min_memory > 0)
sprintf(tmp_char, "%u", job_ptr->job_min_memory);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_MIN_MEM),
tmp_char);
if(job_ptr->job_min_tmp_disk > 0)
sprintf(tmp_char, "%u", job_ptr->job_min_tmp_disk);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_TMP_DISK),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_FEATURES),
job_ptr->features);
if(job_ptr->dependency > 0)
sprintf(tmp_char, "%u", job_ptr->dependency);
else
sprintf(tmp_char, " ");
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_DEPENDENCY),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_ACCOUNT),
job_ptr->account);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_REASON),
job_reason_string(job_ptr->state_reason));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NETWORK),
job_ptr->network);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_COMMENT),
job_ptr->comment);
}
static void _update_job_record(sview_job_info_t *sview_job_info_ptr,
GtkTreeStore *treestore,
GtkTreeIter *iter)
{
char *nodes = NULL, *uname = NULL;
char tmp_char[50];
time_t now_time = time(NULL);
GtkTreeIter step_iter;
int childern = 0;
job_info_t *job_ptr = sview_job_info_ptr->job_ptr;
struct group *group_info = NULL;
uint16_t term_sig = 0;
gtk_tree_store_set(treestore, iter, SORTID_UPDATED, 1, -1);
if(!job_ptr->nodes || !strcasecmp(job_ptr->nodes,"waiting...")) {
sprintf(tmp_char,"0:00:00");
nodes = "waiting...";
} else {
if (job_ptr->job_state == JOB_SUSPENDED)
now_time = job_ptr->pre_sus_time;
else {
if ((job_ptr->job_state != JOB_RUNNING)
&& (job_ptr->end_time != 0))
now_time = job_ptr->end_time;
if (job_ptr->suspend_time)
now_time = (difftime(now_time,
job_ptr->suspend_time)
+ job_ptr->pre_sus_time);
now_time = difftime(now_time, job_ptr->start_time);
}
secs2time_str(now_time, tmp_char, sizeof(tmp_char));
nodes = sview_job_info_ptr->nodes;
}
gtk_tree_store_set(treestore, iter, SORTID_TIME, tmp_char, -1);
slurm_make_time_str((time_t *)&job_ptr->submit_time, tmp_char,
sizeof(tmp_char));
gtk_tree_store_set(treestore, iter, SORTID_SUBMIT_TIME, tmp_char, -1);
slurm_make_time_str((time_t *)&job_ptr->start_time, tmp_char,
sizeof(tmp_char));
gtk_tree_store_set(treestore, iter, SORTID_START_TIME, tmp_char, -1);
if ((job_ptr->time_limit == INFINITE) &&
(job_ptr->end_time > time(NULL)))
sprintf(tmp_char, "NONE");
else
slurm_make_time_str((time_t *)&job_ptr->end_time, tmp_char,
sizeof(tmp_char));
gtk_tree_store_set(treestore, iter, SORTID_END_TIME, tmp_char, -1);
slurm_make_time_str((time_t *)&job_ptr->suspend_time, tmp_char,
sizeof(tmp_char));
gtk_tree_store_set(treestore, iter, SORTID_SUSPEND_TIME, tmp_char, -1);
if (job_ptr->time_limit == NO_VAL)
sprintf(tmp_char, "Partition Limit");
else
secs2time_str((job_ptr->time_limit * 60),
tmp_char, sizeof(tmp_char));
gtk_tree_store_set(treestore, iter, SORTID_TIMELIMIT, tmp_char, -1);
gtk_tree_store_set(treestore, iter, SORTID_ALLOC, 1, -1);
gtk_tree_store_set(treestore, iter, SORTID_JOBID, job_ptr->job_id, -1);
gtk_tree_store_set(treestore, iter,
SORTID_PARTITION, job_ptr->partition, -1);
snprintf(tmp_char, sizeof(tmp_char), "%s:%u",
job_ptr->alloc_node, job_ptr->alloc_sid);
gtk_tree_store_set(treestore, iter, SORTID_ALLOC_NODE, tmp_char, -1);
#ifdef HAVE_BG
gtk_tree_store_set(treestore, iter,
SORTID_BLOCK,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_BG_ID), -1);
gtk_tree_store_set(treestore, iter,
SORTID_CONNECTION,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_CONNECTION), -1);
gtk_tree_store_set(treestore, iter,
SORTID_ROTATE,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_ROTATE), -1);
gtk_tree_store_set(treestore, iter,
SORTID_GEOMETRY,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_GEOMETRY), -1);
gtk_tree_store_set(treestore, iter,
SORTID_START,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_START), -1);
gtk_tree_store_set(treestore, iter,
SORTID_MAX_PROCS,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_MAX_PROCS), -1);
gtk_tree_store_set(treestore, iter,
SORTID_BLRTSIMAGE,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_BLRTS_IMAGE), -1);
gtk_tree_store_set(treestore, iter,
SORTID_LINUXIMAGE,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_LINUX_IMAGE), -1);
gtk_tree_store_set(treestore, iter,
SORTID_MLOADERIMAGE,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_MLOADER_IMAGE), -1);
gtk_tree_store_set(treestore, iter,
SORTID_RAMDISKIMAGE,
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
tmp_char,
sizeof(tmp_char),
SELECT_PRINT_RAMDISK_IMAGE), -1);
#endif
uname = uid_to_string((uid_t)job_ptr->user_id);
gtk_tree_store_set(treestore, iter,
SORTID_USER, uname, -1);
xfree(uname);
group_info = getgrgid((gid_t) job_ptr->group_id );
if ( group_info && group_info->gr_name[ 0 ] ) {
snprintf(tmp_char, sizeof(tmp_char), "%s",
group_info->gr_name);
} else {
snprintf(tmp_char, sizeof(tmp_char), "%u",
job_ptr->group_id );
}
gtk_tree_store_set(treestore, iter,
SORTID_GROUP,
tmp_char, -1);
gtk_tree_store_set(treestore, iter, SORTID_NAME, job_ptr->name, -1);
gtk_tree_store_set(treestore, iter,
SORTID_STATE,
job_state_string(job_ptr->job_state), -1);
gtk_tree_store_set(treestore, iter,
SORTID_STATE_NUM,
job_ptr->job_state, -1);
#ifdef HAVE_BG
convert_num_unit((float)sview_job_info_ptr->node_cnt,
tmp_char, sizeof(tmp_char), UNIT_NONE);
#else
sprintf(tmp_char, "%u", sview_job_info_ptr->node_cnt);
#endif
gtk_tree_store_set(treestore, iter,
SORTID_NODES, tmp_char, -1);
#ifdef HAVE_BG
convert_num_unit((float)job_ptr->num_procs, tmp_char, sizeof(tmp_char),
UNIT_NONE);
#else
snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->num_procs);
#endif
gtk_tree_store_set(treestore, iter,
SORTID_NUM_PROCS, tmp_char, -1);
gtk_tree_store_set(treestore, iter, SORTID_NODELIST, nodes, -1);
gtk_tree_store_set(treestore, iter, SORTID_REQ_NODELIST,
job_ptr->req_nodes, -1);
gtk_tree_store_set(treestore, iter, SORTID_EXC_NODELIST,
job_ptr->exc_nodes, -1);
if(job_ptr->contiguous)
sprintf(tmp_char, "yes");
else
sprintf(tmp_char, "no");
gtk_tree_store_set(treestore, iter,
SORTID_CONTIGUOUS, tmp_char, -1);
if(job_ptr->shared)
sprintf(tmp_char, "yes");
else
sprintf(tmp_char, "no");
gtk_tree_store_set(treestore, iter,
SORTID_SHARED, tmp_char, -1);
if(job_ptr->batch_flag)
sprintf(tmp_char, "yes");
else
sprintf(tmp_char, "no");
gtk_tree_store_set(treestore, iter,
SORTID_BATCH, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->num_nodes);
gtk_tree_store_set(treestore, iter,
SORTID_MIN_NODES, tmp_char, -1);
if(job_ptr->max_nodes > 0) {
sprintf(tmp_char, "%u", job_ptr->max_nodes);
gtk_tree_store_set(treestore, iter,
SORTID_MAX_NODES, tmp_char, -1);
}
if(job_ptr->cpus_per_task > 0) {
sprintf(tmp_char, "%u", job_ptr->cpus_per_task);
gtk_tree_store_set(treestore, iter,
SORTID_CPUS_PER_TASK, tmp_char, -1);
}
sprintf(tmp_char, "%u", job_ptr->job_min_procs);
gtk_tree_store_set(treestore, iter,
SORTID_REQ_PROCS, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->min_sockets);
gtk_tree_store_set(treestore, iter,
SORTID_MIN_SOCKETS, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->max_sockets);
gtk_tree_store_set(treestore, iter,
SORTID_MAX_SOCKETS, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->min_cores);
gtk_tree_store_set(treestore, iter,
SORTID_MIN_CORES, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->max_cores);
gtk_tree_store_set(treestore, iter,
SORTID_MAX_CORES, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->min_threads);
gtk_tree_store_set(treestore, iter,
SORTID_MIN_THREADS, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->max_threads);
gtk_tree_store_set(treestore, iter,
SORTID_MAX_THREADS, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->job_min_memory);
gtk_tree_store_set(treestore, iter,
SORTID_MIN_MEM, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->job_max_memory);
gtk_tree_store_set(treestore, iter,
SORTID_MAX_MEM, tmp_char, -1);
sprintf(tmp_char, "%u", job_ptr->job_min_tmp_disk);
gtk_tree_store_set(treestore, iter,
SORTID_TMP_DISK, tmp_char, -1);
gtk_tree_store_set(treestore, iter,
SORTID_ACCOUNT, job_ptr->account, -1);
if(job_ptr->dependency > 0) {
sprintf(tmp_char, "%u", job_ptr->dependency);
gtk_tree_store_set(treestore, iter,
SORTID_DEPENDENCY, tmp_char, -1);
}
sprintf(tmp_char, "%u", job_ptr->priority);
gtk_tree_store_set(treestore, iter,
SORTID_PRIORITY, tmp_char, -1);
if(WIFSIGNALED(job_ptr->exit_code))
term_sig = WTERMSIG(job_ptr->exit_code);
snprintf(tmp_char, sizeof(tmp_char), "%u:%u",
WEXITSTATUS(job_ptr->exit_code), term_sig);
gtk_tree_store_set(treestore, iter,
SORTID_EXIT_CODE, tmp_char, -1);
gtk_tree_store_set(treestore, iter,
SORTID_FEATURES, job_ptr->features, -1);
gtk_tree_store_set(treestore, iter,
SORTID_REASON,
job_reason_string(job_ptr->state_reason), -1);
gtk_tree_store_set(treestore, iter,
SORTID_NETWORK, job_ptr->network, -1);
gtk_tree_store_set(treestore, iter,
SORTID_COMMENT, job_ptr->comment, -1);
childern = gtk_tree_model_iter_children(GTK_TREE_MODEL(treestore),
&step_iter, iter);
if(gtk_tree_model_iter_children(GTK_TREE_MODEL(treestore),
&step_iter, iter))
_update_info_step(sview_job_info_ptr,
GTK_TREE_MODEL(treestore), &step_iter, iter);
else
_update_info_step(sview_job_info_ptr,
GTK_TREE_MODEL(treestore), NULL, iter);
return;
}
static void _layout_step_record(GtkTreeView *treeview,
job_step_info_t *step_ptr,
int update)
{
char *nodes = NULL, *uname;
char tmp_char[50];
char tmp_time[50];
time_t now_time = time(NULL);
GtkTreeIter iter;
enum job_states state;
GtkTreeStore *treestore =
GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
if(!treestore)
return;
if(!step_ptr->nodes
|| !strcasecmp(step_ptr->nodes,"waiting...")) {
sprintf(tmp_time,"0:00:00");
nodes = "waiting...";
state = JOB_PENDING;
} else {
now_time -= step_ptr->start_time;
secs2time_str(now_time, tmp_time, sizeof(tmp_time));
nodes = step_ptr->nodes;
#ifdef HAVE_BG
convert_num_unit((float)step_ptr->num_tasks,
tmp_char, sizeof(tmp_char), UNIT_NONE);
#else
convert_num_unit((float)_nodes_in_list(nodes),
tmp_char, sizeof(tmp_char), UNIT_NONE);
#endif
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NODES),
tmp_char);
state = JOB_RUNNING;
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_STATE),
job_state_string(state));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_TIME),
tmp_time);
snprintf(tmp_char, sizeof(tmp_char), "%u.%u",
step_ptr->job_id,
step_ptr->step_id);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_JOBID),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_PARTITION),
step_ptr->partition);
/* #ifdef HAVE_BG */
/* add_display_treestore_line(update, treestore, &iter, */
/* find_col_name(display_data_job, SORTID_BLOCK), */
/* select_g_sprint_jobinfo( */
/* step_ptr->select_jobinfo, */
/* tmp_char, */
/* sizeof(tmp_char), */
/* SELECT_PRINT_BG_ID)); */
/* #endif */
uname = uid_to_string((uid_t)step_ptr->user_id);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_USER), uname);
xfree(uname);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NAME),
step_ptr->name);
convert_num_unit((float)step_ptr->num_tasks, tmp_char, sizeof(tmp_char),
UNIT_NONE);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_TASKS),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NUM_PROCS),
tmp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_job,
SORTID_NODELIST),
nodes);
}
static void _update_step_record(job_step_info_t *step_ptr,
GtkTreeStore *treestore,
GtkTreeIter *iter)
{
char *nodes = NULL, *uname = NULL;
char tmp_char[50];
char tmp_time[50];
time_t now_time = time(NULL);
enum job_states state;
gtk_tree_store_set(treestore, iter, SORTID_UPDATED, 1, -1);
if(!step_ptr->nodes
|| !strcasecmp(step_ptr->nodes,"waiting...")) {
sprintf(tmp_char,"0:00:00");
nodes = "waiting...";
state = JOB_PENDING;
} else {
now_time -= step_ptr->start_time;
secs2time_str(now_time, tmp_time, sizeof(tmp_time));
nodes = step_ptr->nodes;
#ifdef HAVE_BG
convert_num_unit((float)step_ptr->num_tasks,
tmp_char, sizeof(tmp_char), UNIT_NONE);
#else
convert_num_unit((float)_nodes_in_list(nodes),
tmp_char, sizeof(tmp_char), UNIT_NONE);
#endif
gtk_tree_store_set(treestore, iter,
SORTID_NODES, tmp_char, -1);
state = JOB_RUNNING;
}
gtk_tree_store_set(treestore, iter,
SORTID_STATE,
job_state_string(state), -1);
gtk_tree_store_set(treestore, iter,
SORTID_TIME, tmp_time, -1);
gtk_tree_store_set(treestore, iter, SORTID_ALLOC, 0, -1);
gtk_tree_store_set(treestore, iter,
SORTID_JOBID, step_ptr->step_id, -1);
gtk_tree_store_set(treestore, iter,
SORTID_PARTITION, step_ptr->partition, -1);
/* #ifdef HAVE_BG */
/* gtk_tree_store_set(treestore, iter, */
/* SORTID_BLOCK, */
/* select_g_sprint_jobinfo( */
/* step_ptr->select_jobinfo, */
/* tmp_char, */
/* sizeof(tmp_char), */
/* SELECT_PRINT_BG_ID), -1); */
/* #endif */
uname = uid_to_string((uid_t)step_ptr->user_id);
gtk_tree_store_set(treestore, iter,
SORTID_USER, uname, -1);
xfree(uname);
gtk_tree_store_set(treestore, iter,
SORTID_NAME, step_ptr->name, -1);
convert_num_unit((float)step_ptr->num_tasks, tmp_char, sizeof(tmp_char),
UNIT_NONE);
gtk_tree_store_set(treestore, iter,
SORTID_TASKS, tmp_char, -1);
gtk_tree_store_set(treestore, iter,
SORTID_NUM_PROCS, tmp_char, -1);
gtk_tree_store_set(treestore, iter,
SORTID_NODELIST, nodes, -1);
return;
}
static void _append_job_record(sview_job_info_t *sview_job_info_ptr,
GtkTreeStore *treestore, GtkTreeIter *iter,
int line)
{
gtk_tree_store_append(treestore, iter, NULL);
gtk_tree_store_set(treestore, iter, SORTID_POS, line, -1);
_update_job_record(sview_job_info_ptr, treestore, iter);
}
static void _append_step_record(job_step_info_t *step_ptr,
GtkTreeStore *treestore, GtkTreeIter *iter,
int jobid)
{
GtkTreeIter step_iter;
gtk_tree_store_append(treestore, &step_iter, iter);
gtk_tree_store_set(treestore, &step_iter, SORTID_POS, jobid, -1);
_update_step_record(step_ptr, treestore, &step_iter);
}
static void _update_info_step(sview_job_info_t *sview_job_info_ptr,
GtkTreeModel *model,
GtkTreeIter *step_iter,
GtkTreeIter *iter)
{
int stepid = 0;
int i;
GtkTreeIter first_step_iter;
int set = 0;
ListIterator itr = NULL;
job_step_info_t *step_ptr = NULL;
memset(&first_step_iter, 0, sizeof(GtkTreeIter));
/* make sure all the steps are still here */
if (step_iter) {
first_step_iter = *step_iter;
while(1) {
gtk_tree_store_set(GTK_TREE_STORE(model), step_iter,
SORTID_UPDATED, 0, -1);
if(!gtk_tree_model_iter_next(model, step_iter)) {
break;
}
}
memcpy(step_iter, &first_step_iter, sizeof(GtkTreeIter));
set = 1;
}
itr = list_iterator_create(sview_job_info_ptr->step_list);
while((step_ptr = list_next(itr))) {
/* get the iter, or find out the list is empty goto add */
if (!step_iter) {
goto adding;
} else {
memcpy(step_iter, &first_step_iter,
sizeof(GtkTreeIter));
}
while(1) {
/* search for the jobid and check to see if
it is in the list */
gtk_tree_model_get(model, step_iter, SORTID_JOBID,
&stepid, -1);
if(stepid == (int)step_ptr->step_id) {
/* update with new info */
_update_step_record(step_ptr,
GTK_TREE_STORE(model),
step_iter);
goto found;
}
if(!gtk_tree_model_iter_next(model, step_iter)) {
step_iter = NULL;
break;
}
}
adding:
_append_step_record(step_ptr, GTK_TREE_STORE(model),
iter, sview_job_info_ptr->job_ptr->job_id);
found:
;
}
list_iterator_destroy(itr);
if(set) {
step_iter = &first_step_iter;
/* clear all steps that aren't active */
while(1) {
gtk_tree_model_get(model, step_iter,
SORTID_UPDATED, &i, -1);
if(!i) {
if(!gtk_tree_store_remove(
GTK_TREE_STORE(model),
step_iter))
break;
else
continue;
}
if(!gtk_tree_model_iter_next(model, step_iter)) {
break;
}
}
}
return;
}
static void _update_info_job(List info_list,
GtkTreeView *tree_view)
{
GtkTreePath *path = gtk_tree_path_new_first();
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
GtkTreeIter iter;
int jobid = 0;
job_info_t *job_ptr = NULL;
int line = 0;
char *host = NULL;
ListIterator itr = NULL;
sview_job_info_t *sview_job_info = NULL;
/* make sure all the jobs are still here */
if (gtk_tree_model_get_iter(model, &iter, path)) {
while(1) {
gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
SORTID_UPDATED, 0, -1);
if(!gtk_tree_model_iter_next(model, &iter)) {
break;
}
}
}
itr = list_iterator_create(info_list);
while ((sview_job_info = (sview_job_info_t*) list_next(itr))) {
job_ptr = sview_job_info->job_ptr;
/* get the iter, or find out the list is empty goto add */
if (!gtk_tree_model_get_iter(model, &iter, path)) {
goto adding;
}
while(1) {
/* search for the jobid and check to see if
it is in the list */
gtk_tree_model_get(model, &iter, SORTID_JOBID,
&jobid, -1);
if(jobid == job_ptr->job_id) {
/* update with new info */
_update_job_record(sview_job_info,
GTK_TREE_STORE(model),
&iter);
goto found;
}
/* see what line we were on to add the next one
to the list */
gtk_tree_model_get(model, &iter, SORTID_POS,
&line, -1);
if(!gtk_tree_model_iter_next(model, &iter)) {
line++;
break;
}
}
adding:
_append_job_record(sview_job_info, GTK_TREE_STORE(model),
&iter, line);
found:
;
}
list_iterator_destroy(itr);
if(host)
free(host);
gtk_tree_path_free(path);
/* remove all old jobs */
remove_old(model, SORTID_UPDATED);
return;
}
static void _job_info_list_del(void *object)
{
sview_job_info_t *sview_job_info = (sview_job_info_t *)object;
if (sview_job_info) {
xfree(sview_job_info->nodes);
if(sview_job_info->step_list)
list_destroy(sview_job_info->step_list);
xfree(sview_job_info);
}
}
static List _create_job_info_list(job_info_msg_t *job_info_ptr,
job_step_info_response_msg_t *step_info_ptr,
int changed, int want_odd_states)
{
static List info_list = NULL;
static List odd_info_list = NULL;
int i = 0, j = 0;
sview_job_info_t *sview_job_info_ptr = NULL;
job_info_t *job_ptr = NULL;
job_step_info_t *step_ptr = NULL;
#ifdef HAVE_BG
char *ionodes = NULL;
char tmp_char[50];
#endif
#ifdef HAVE_FRONT_END
int count = 0;
#endif
if(!changed && info_list) {
goto update_color;
}
if(info_list) {
list_destroy(info_list);
list_destroy(odd_info_list);
}
info_list = list_create(NULL);
odd_info_list = list_create(_job_info_list_del);
if (!info_list || !odd_info_list) {
g_print("malloc error\n");
return NULL;
}
for(i=0; i<job_info_ptr->record_count; i++) {
job_ptr = &(job_info_ptr->job_array[i]);
sview_job_info_ptr = xmalloc(sizeof(sview_job_info_t));
sview_job_info_ptr->job_ptr = job_ptr;
sview_job_info_ptr->step_list = list_create(NULL);
sview_job_info_ptr->node_cnt = 0;
sview_job_info_ptr->nodes = NULL;
#ifdef HAVE_BG
select_g_get_jobinfo(job_ptr->select_jobinfo,
SELECT_DATA_IONODES,
&ionodes);
select_g_get_jobinfo(job_ptr->select_jobinfo,
SELECT_DATA_NODE_CNT,
&sview_job_info_ptr->node_cnt);
if(ionodes) {
snprintf(tmp_char, sizeof(tmp_char), "%s[%s]",
job_ptr->nodes, ionodes);
xfree(ionodes);
sview_job_info_ptr->nodes = xstrdup(tmp_char);
}
#endif
if(!sview_job_info_ptr->nodes)
sview_job_info_ptr->nodes = xstrdup(job_ptr->nodes);
if(!sview_job_info_ptr->node_cnt)
sview_job_info_ptr->node_cnt = _get_node_cnt(job_ptr);
#ifdef HAVE_FRONT_END
/* set this up to copy it if we are on a front end
system */
count = 0;
while(job_ptr->node_inx[count] != -1)
count++;
#endif
for(j = 0; j < step_info_ptr->job_step_count; j++) {
step_ptr = &(step_info_ptr->job_steps[j]);
if(step_ptr->job_id == job_ptr->job_id) {
#ifdef HAVE_FRONT_END
/* On front end systems the steps are only
* given the first node to run off of
* so we need to make them appear like
* they are running on the entire
* space (which they really are).
*/
xfree(step_ptr->nodes);
step_ptr->nodes =
xstrdup(sview_job_info_ptr->nodes);
step_ptr->num_tasks =
sview_job_info_ptr->node_cnt;
xfree(step_ptr->node_inx);
step_ptr->node_inx =
xmalloc(sizeof(int) * count);
memcpy(step_ptr->node_inx, job_ptr->node_inx,
sizeof(int) * count);
#endif
list_push(sview_job_info_ptr->step_list,
step_ptr);
}
}
list_append(odd_info_list, sview_job_info_ptr);
if((job_ptr->job_state != JOB_PENDING)
&& (job_ptr->job_state != JOB_RUNNING)
&& (job_ptr->job_state != JOB_SUSPENDED)
&& (!(job_ptr->job_state
& JOB_COMPLETING))) {
continue;
}
list_append(info_list, sview_job_info_ptr);
}
update_color:
if(want_odd_states)
return odd_info_list;
else
return info_list;
}
void _display_info_job(List info_list, popup_info_t *popup_win)
{
job_step_info_t *step_ptr;
specific_info_t *spec_info = popup_win->spec_info;
ListIterator itr = NULL;
sview_job_info_t *sview_job_info = NULL;
int found = 0;
GtkTreeView *treeview = NULL;
int update = 0;
int i = -1, j = 0;
int first_time = 0;
if(spec_info->search_info->int_data == NO_VAL) {
/* info = xstrdup("No pointer given!"); */
goto finished;
}
if(!list_count(popup_win->grid_button_list))
first_time = 1;
need_refresh:
if(!spec_info->display_widget) {
treeview = create_treeview_2cols_attach_to_table(
popup_win->table);
spec_info->display_widget =
gtk_widget_ref(GTK_WIDGET(treeview));
} else {
treeview = GTK_TREE_VIEW(spec_info->display_widget);
update = 1;
}
itr = list_iterator_create(info_list);
while((sview_job_info = (sview_job_info_t*) list_next(itr))) {
i++;
if(sview_job_info->job_ptr->job_id ==
spec_info->search_info->int_data)
break;
}
list_iterator_destroy(itr);
if(!sview_job_info) {
/* not found */
} else if(spec_info->search_info->int_data2 == NO_VAL) {
j=0;
while(sview_job_info->job_ptr->node_inx[j] >= 0) {
if(!first_time)
change_grid_color(
popup_win->grid_button_list,
sview_job_info->job_ptr->node_inx[j],
sview_job_info->job_ptr->node_inx[j+1],
i);
else
get_button_list_from_main(
&popup_win->grid_button_list,
sview_job_info->job_ptr->node_inx[j],
sview_job_info->job_ptr->node_inx[j+1],
i);
j += 2;
}
_layout_job_record(treeview, sview_job_info, update);
found = 1;
} else {
itr = list_iterator_create(sview_job_info->step_list);
i=-1;
while ((step_ptr = list_next(itr))) {
i++;
if(step_ptr->step_id ==
spec_info->search_info->int_data2) {
j=0;
while(step_ptr->node_inx[j] >= 0) {
if(!first_time)
change_grid_color(
popup_win->
grid_button_list,
step_ptr->node_inx[j],
step_ptr->
node_inx[j+1],
i);
else
get_button_list_from_main(
&popup_win->
grid_button_list,
step_ptr->node_inx[j],
step_ptr->
node_inx[j+1],
i);
j += 2;
}
_layout_step_record(treeview,
step_ptr, update);
found = 1;
break;
}
}
list_iterator_destroy(itr);
}
if(!found) {
if(!popup_win->not_found) {
char *temp = "JOB ALREADY FINISHED OR NOT FOUND\n";
GtkTreeIter iter;
GtkTreeModel *model = NULL;
/* only time this will be run so no update */
model = gtk_tree_view_get_model(treeview);
add_display_treestore_line(0,
GTK_TREE_STORE(model),
&iter,
temp, "");
if(spec_info->search_info->int_data2 != NO_VAL)
add_display_treestore_line(
1,
GTK_TREE_STORE(model),
&iter,
find_col_name(display_data_job,
SORTID_STATE),
job_state_string(JOB_COMPLETE));
}
popup_win->not_found = true;
} else {
if(popup_win->not_found) {
popup_win->not_found = false;
gtk_widget_destroy(spec_info->display_widget);
goto need_refresh;
}
put_buttons_in_table(popup_win->grid_table,
popup_win->grid_button_list);
}
gtk_widget_show_all(spec_info->display_widget);
finished:
return;
}
extern void refresh_job(GtkAction *action, gpointer user_data)
{
popup_info_t *popup_win = (popup_info_t *)user_data;
xassert(popup_win != NULL);
xassert(popup_win->spec_info != NULL);
xassert(popup_win->spec_info->title != NULL);
popup_win->force_refresh = 1;
specific_info_job(popup_win);
}
extern int get_new_info_job(job_info_msg_t **info_ptr,
int force)
{
static job_info_msg_t *job_info_ptr = NULL, *new_job_ptr = NULL;
uint16_t show_flags = 0;
int error_code = SLURM_NO_CHANGE_IN_DATA;
time_t now = time(NULL);
static time_t last;
static bool changed = 0;
if(!force && ((now - last) < global_sleep_time)) {
error_code = SLURM_NO_CHANGE_IN_DATA;
*info_ptr = job_info_ptr;
if(changed)
return SLURM_SUCCESS;
return error_code;
}
last = now;
show_flags |= SHOW_ALL;
if (job_info_ptr) {
error_code = slurm_load_jobs(job_info_ptr->last_update,
&new_job_ptr, show_flags);
if (error_code == SLURM_SUCCESS) {
slurm_free_job_info_msg(job_info_ptr);
changed = 1;
} else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) {
error_code = SLURM_NO_CHANGE_IN_DATA;
new_job_ptr = job_info_ptr;
changed = 0;
}
} else {
error_code = slurm_load_jobs((time_t) NULL, &new_job_ptr,
show_flags);
changed = 1;
}
job_info_ptr = new_job_ptr;
*info_ptr = new_job_ptr;
return error_code;
}
extern int get_new_info_job_step(job_step_info_response_msg_t **info_ptr,
int force)
{
static job_step_info_response_msg_t *old_step_ptr = NULL;
static job_step_info_response_msg_t *new_step_ptr = NULL;
uint16_t show_flags = 0;
int error_code = SLURM_NO_CHANGE_IN_DATA;
time_t now = time(NULL);
static time_t last;
if(!force && ((now - last) < global_sleep_time)) {
error_code = SLURM_NO_CHANGE_IN_DATA;
*info_ptr = old_step_ptr;
return error_code;
}
last = now;
show_flags |= SHOW_ALL;
if (old_step_ptr) {
error_code = slurm_get_job_steps(old_step_ptr->last_update,
0, 0, &new_step_ptr,
show_flags);
if (error_code == SLURM_SUCCESS)
slurm_free_job_step_info_response_msg(old_step_ptr);
else if (slurm_get_errno () == SLURM_NO_CHANGE_IN_DATA) {
error_code = SLURM_NO_CHANGE_IN_DATA;
new_step_ptr = old_step_ptr;
}
} else
error_code = slurm_get_job_steps((time_t) NULL, 0, 0,
&new_step_ptr, show_flags);
old_step_ptr = new_step_ptr;
*info_ptr = new_step_ptr;
return error_code;
}
extern GtkListStore *create_model_job(int type)
{
GtkListStore *model = NULL;
GtkTreeIter iter;
switch(type) {
case SORTID_ACTION:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
1, SORTID_ACTION,
0, "None",
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
1, SORTID_ACTION,
0, "Cancel",
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
1, SORTID_ACTION,
0, "Suspend/Resume",
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
1, SORTID_ACTION,
0, "Checkpoint",
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
1, SORTID_ACTION,
0, "requeue",
-1);
break;
case SORTID_SHARED:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "yes",
1, SORTID_SHARED,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "no",
1, SORTID_SHARED,
-1);
break;
case SORTID_CONTIGUOUS:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "yes",
1, SORTID_CONTIGUOUS,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "no",
1, SORTID_CONTIGUOUS,
-1);
break;
#ifdef HAVE_BG
case SORTID_ROTATE:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "yes",
1, SORTID_ROTATE,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "no",
1, SORTID_ROTATE,
-1);
break;
case SORTID_CONNECTION:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "torus",
1, SORTID_CONNECTION,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "mesh",
1, SORTID_CONNECTION,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "nav",
1, SORTID_CONNECTION,
-1);
break;
#endif
default:
break;
}
return model;
}
extern void admin_edit_job(GtkCellRendererText *cell,
const char *path_string,
const char *new_text,
gpointer data)
{
GtkTreeStore *treestore = GTK_TREE_STORE(data);
GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
GtkTreeIter iter;
job_desc_msg_t *job_msg = xmalloc(sizeof(job_desc_msg_t));
char *temp = NULL;
char *old_text = NULL;
const char *type = NULL;
int stepid = NO_VAL;
int column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell),
"column"));
if(!new_text || !strcmp(new_text, ""))
goto no_input;
gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path);
slurm_init_job_desc_msg(job_msg);
gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
SORTID_JOBID, &job_msg->job_id,
column, &old_text,
-1);
gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
SORTID_ALLOC, &stepid, -1);
if(stepid)
stepid = NO_VAL;
else {
stepid = job_msg->job_id;
gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
SORTID_POS, &job_msg->job_id, -1);
}
type = _set_job_msg(job_msg, new_text, column);
if(errno)
goto print_error;
if(got_edit_signal) {
temp = got_edit_signal;
got_edit_signal = NULL;
admin_job(GTK_TREE_MODEL(treestore), &iter, temp);
xfree(temp);
goto no_input;
}
if(old_text && !strcmp(old_text, new_text)) {
temp = g_strdup_printf("No change in value.");
display_edit_note(temp);
g_free(temp);
} else if(slurm_update_job(job_msg) == SLURM_SUCCESS) {
gtk_tree_store_set(treestore, &iter, column, new_text, -1);
temp = g_strdup_printf("Job %d %s changed to %s",
job_msg->job_id,
type,
new_text);
display_edit_note(temp);
g_free(temp);
} else {
print_error:
temp = g_strdup_printf("Job %d %s can't be "
"set to %s",
job_msg->job_id,
type,
new_text);
display_edit_note(temp);
g_free(temp);
}
no_input:
slurm_free_job_desc_msg(job_msg);
gtk_tree_path_free (path);
g_free(old_text);
g_static_mutex_unlock(&sview_mutex);
}
extern void get_info_job(GtkTable *table, display_data_t *display_data)
{
int job_error_code = SLURM_SUCCESS;
int step_error_code = SLURM_SUCCESS;
static int view = -1;
static job_info_msg_t *job_info_ptr = NULL;
static job_step_info_response_msg_t *step_info_ptr = NULL;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
static GtkWidget *display_widget = NULL;
List info_list = NULL;
int changed = 1;
int i = 0, j = 0;
sview_job_info_t *sview_job_info_ptr = NULL;
job_info_t *job_ptr = NULL;
ListIterator itr = NULL;
if(display_data)
local_display_data = display_data;
if(!table) {
display_data_job->set_menu = local_display_data->set_menu;
return;
}
if(display_widget && toggled) {
gtk_widget_destroy(display_widget);
display_widget = NULL;
goto display_it;
}
if((job_error_code = get_new_info_job(&job_info_ptr, force_refresh))
== SLURM_NO_CHANGE_IN_DATA){
} else if (job_error_code != SLURM_SUCCESS) {
if(view == ERROR_VIEW)
goto end_it;
if(display_widget)
gtk_widget_destroy(display_widget);
view = ERROR_VIEW;
sprintf(error_char, "slurm_load_job: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
gtk_widget_show(label);
display_widget = gtk_widget_ref(GTK_WIDGET(label));
goto end_it;
}
if((step_error_code = get_new_info_job_step(&step_info_ptr,
force_refresh))
== SLURM_NO_CHANGE_IN_DATA){
if((!display_widget || view == ERROR_VIEW)
|| (job_error_code != SLURM_NO_CHANGE_IN_DATA))
goto display_it;
changed = 0;
} else if (step_error_code != SLURM_SUCCESS) {
if(view == ERROR_VIEW)
goto end_it;
if(display_widget)
gtk_widget_destroy(display_widget);
view = ERROR_VIEW;
sprintf(error_char, "slurm_load_job_step: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
gtk_widget_show(label);
display_widget = gtk_widget_ref(GTK_WIDGET(label));
goto end_it;
}
display_it:
info_list = _create_job_info_list(job_info_ptr, step_info_ptr,
changed, 0);
if(!info_list)
return;
i=0;
/* set up the grid */
itr = list_iterator_create(info_list);
while ((sview_job_info_ptr = list_next(itr))) {
job_ptr = sview_job_info_ptr->job_ptr;
j=0;
while(job_ptr->node_inx[j] >= 0) {
sview_job_info_ptr->color =
change_grid_color(grid_button_list,
job_ptr->node_inx[j],
job_ptr->node_inx[j+1],
i);
j += 2;
}
i++;
}
list_iterator_destroy(itr);
if(view == ERROR_VIEW && display_widget) {
gtk_widget_destroy(display_widget);
display_widget = NULL;
}
if(!display_widget) {
tree_view = create_treeview(local_display_data);
display_widget = gtk_widget_ref(GTK_WIDGET(tree_view));
gtk_table_attach_defaults(GTK_TABLE(table),
GTK_WIDGET(tree_view),
0, 1, 0, 1);
/* since this function sets the model of the tree_view
to the treestore we don't really care about
the return value */
create_treestore(tree_view, display_data_job, SORTID_CNT);
}
view = INFO_VIEW;
_update_info_job(info_list, GTK_TREE_VIEW(display_widget));
end_it:
toggled = FALSE;
force_refresh = FALSE;
return;
}
extern void specific_info_job(popup_info_t *popup_win)
{
int job_error_code = SLURM_SUCCESS;
int step_error_code = SLURM_SUCCESS;
static job_info_msg_t *job_info_ptr = NULL;
static job_step_info_response_msg_t *step_info_ptr = NULL;
specific_info_t *spec_info = popup_win->spec_info;
sview_search_info_t *search_info = spec_info->search_info;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
List info_list = NULL;
List send_info_list = NULL;
int changed = 1;
int j=0, i=-1;
sview_job_info_t *sview_job_info_ptr = NULL;
job_info_t *job_ptr = NULL;
ListIterator itr = NULL;
char name[30], *uname = NULL;
char *host = NULL, *host2 = NULL;
hostlist_t hostlist = NULL;
int found = 0, name_diff;
if(!spec_info->display_widget)
setup_popup_info(popup_win, display_data_job, SORTID_CNT);
if(spec_info->display_widget && popup_win->toggled) {
gtk_widget_destroy(spec_info->display_widget);
spec_info->display_widget = NULL;
goto display_it;
}
if((job_error_code =
get_new_info_job(&job_info_ptr, popup_win->force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
} else if (job_error_code != SLURM_SUCCESS) {
if(spec_info->view == ERROR_VIEW)
goto end_it;
spec_info->view = ERROR_VIEW;
if(spec_info->display_widget)
gtk_widget_destroy(spec_info->display_widget);
sprintf(error_char, "slurm_load_job: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
gtk_table_attach_defaults(GTK_TABLE(popup_win->table),
label,
0, 1, 0, 1);
gtk_widget_show(label);
spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(label));
goto end_it;
}
if((step_error_code =
get_new_info_job_step(&step_info_ptr, popup_win->force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
if((!spec_info->display_widget
|| spec_info->view == ERROR_VIEW)
|| (job_error_code != SLURM_NO_CHANGE_IN_DATA))
goto display_it;
changed = 0;
} else if (step_error_code != SLURM_SUCCESS) {
if(spec_info->view == ERROR_VIEW)
goto end_it;
if(spec_info->display_widget)
gtk_widget_destroy(spec_info->display_widget);
spec_info->view = ERROR_VIEW;
sprintf(error_char, "slurm_load_job_step: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
gtk_table_attach_defaults(popup_win->table, label,
0, 1, 0, 1);
gtk_widget_show(label);
spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(label));
goto end_it;
}
display_it:
info_list = _create_job_info_list(job_info_ptr, step_info_ptr,
changed, 1);
if(!info_list)
return;
if(spec_info->view == ERROR_VIEW && spec_info->display_widget) {
gtk_widget_destroy(spec_info->display_widget);
spec_info->display_widget = NULL;
}
if(spec_info->type != INFO_PAGE && !spec_info->display_widget) {
tree_view = create_treeview(local_display_data);
spec_info->display_widget =
gtk_widget_ref(GTK_WIDGET(tree_view));
gtk_table_attach_defaults(popup_win->table,
GTK_WIDGET(tree_view),
0, 1, 0, 1);
/* since this function sets the model of the tree_view
to the treestore we don't really care about
the return value */
create_treestore(tree_view, popup_win->display_data,
SORTID_CNT);
}
if(popup_win->grid_button_list) {
list_destroy(popup_win->grid_button_list);
}
#ifdef HAVE_BG
popup_win->grid_button_list = copy_main_button_list();
#else
popup_win->grid_button_list = list_create(destroy_grid_button);
#endif
spec_info->view = INFO_VIEW;
if(spec_info->type == INFO_PAGE) {
_display_info_job(info_list, popup_win);
goto end_it;
}
/* just linking to another list, don't free the inside, just
the list */
send_info_list = list_create(NULL);
itr = list_iterator_create(info_list);
i = -1;
while ((sview_job_info_ptr = list_next(itr))) {
i++;
job_ptr = sview_job_info_ptr->job_ptr;
switch(spec_info->type) {
case JOB_PAGE:
switch(search_info->search_type) {
case SEARCH_JOB_ID:
if(search_info->int_data
== NO_VAL) {
if(!search_info->gchar_data)
continue;
_convert_char_to_job_and_step(
search_info->gchar_data,
&search_info->int_data,
&search_info->int_data2);
}
if(job_ptr->job_id != search_info->int_data) {
continue;
}
/* if we ever want to display just the step
this is where we would do it */
/* if(spec_info->search_info->int_data2 */
/* == NO_VAL) */
/* break; */
/* step_itr = list_iterator_create( */
/* sview_job_info->step_list); */
/* while ((step_ptr = list_next(itr))) { */
/* if(step_ptr->step_id */
/* == spec_info->search_info->int_data2) { */
/* break; */
/* } */
/* } */
break;
case SEARCH_JOB_USER:
if(!search_info->gchar_data)
continue;
uname = uid_to_string(job_ptr->user_id);
name_diff = strcmp(uname,
search_info->gchar_data);
xfree(uname);
if(name_diff)
continue;
break;
case SEARCH_JOB_STATE:
if(search_info->int_data == NO_VAL)
continue;
if(job_ptr->job_state != search_info->int_data)
continue;
break;
default:
break;
}
break;
case PART_PAGE:
if(strcmp(search_info->gchar_data,
job_ptr->partition))
continue;
break;
case BLOCK_PAGE:
select_g_sprint_jobinfo(
job_ptr->select_jobinfo,
name,
sizeof(name),
SELECT_PRINT_BG_ID);
if(strcmp(search_info->gchar_data, name))
continue;
break;
case NODE_PAGE:
if(!job_ptr->nodes)
continue;
hostlist = hostlist_create(search_info->gchar_data);
host = hostlist_shift(hostlist);
hostlist_destroy(hostlist);
if(!host)
continue;
hostlist = hostlist_create(job_ptr->nodes);
found = 0;
while((host2 = hostlist_shift(hostlist))) {
if(!strcmp(host, host2)) {
free(host2);
found = 1;
break;
}
free(host2);
}
hostlist_destroy(hostlist);
if(!found)
continue;
break;
default:
continue;
}
list_push(send_info_list, sview_job_info_ptr);
j=0;
while(job_ptr->node_inx[j] >= 0) {
#ifdef HAVE_BG
change_grid_color(
popup_win->grid_button_list,
job_ptr->node_inx[j],
job_ptr->node_inx[j+1], i);
#else
get_button_list_from_main(
&popup_win->grid_button_list,
job_ptr->node_inx[j],
job_ptr->node_inx[j+1], i);
#endif
j += 2;
}
}
list_iterator_destroy(itr);
put_buttons_in_table(popup_win->grid_table,
popup_win->grid_button_list);
_update_info_job(send_info_list,
GTK_TREE_VIEW(spec_info->display_widget));
list_destroy(send_info_list);
end_it:
popup_win->toggled = 0;
popup_win->force_refresh = 0;
return;
}
extern void set_menus_job(void *arg, GtkTreePath *path,
GtkMenu *menu, int type)
{
GtkTreeView *tree_view = (GtkTreeView *)arg;
popup_info_t *popup_win = (popup_info_t *)arg;
switch(type) {
case TAB_CLICKED:
make_fields_menu(menu, display_data_job, SORTID_CNT);
break;
case ROW_CLICKED:
make_options_menu(tree_view, path, menu, options_data_job);
break;
case POPUP_CLICKED:
make_popup_fields_menu(popup_win, menu);
break;
default:
g_error("UNKNOWN type %d given to set_fields\n", type);
}
}
extern void popup_all_job(GtkTreeModel *model, GtkTreeIter *iter, int id)
{
char *name = NULL;
char title[100];
ListIterator itr = NULL;
popup_info_t *popup_win = NULL;
int jobid = NO_VAL;
int stepid = NO_VAL;
GError *error = NULL;
gtk_tree_model_get(model, iter, SORTID_JOBID, &jobid, -1);
gtk_tree_model_get(model, iter, SORTID_ALLOC, &stepid, -1);
if(stepid)
stepid = NO_VAL;
else {
stepid = jobid;
gtk_tree_model_get(model, iter, SORTID_POS, &jobid, -1);
}
switch(id) {
case PART_PAGE:
if(stepid == NO_VAL)
snprintf(title, 100, "Partition with job %d", jobid);
else
snprintf(title, 100, "Partition with job %d.%d",
jobid, stepid);
break;
case NODE_PAGE:
if(stepid == NO_VAL) {
#ifdef HAVE_BG
snprintf(title, 100,
"Base partition(s) running job %d", jobid);
#else
snprintf(title, 100, "Node(s) running job %d", jobid);
#endif
} else {
#ifdef HAVE_BG
snprintf(title, 100,
"Base partition(s) running job %d.%d",
jobid, stepid);
#else
snprintf(title, 100, "Node(s) running job %d.%d",
jobid, stepid);
#endif
}
break;
case BLOCK_PAGE:
if(stepid == NO_VAL)
snprintf(title, 100, "Block with job %d", jobid);
else
snprintf(title, 100, "Block with job %d.%d",
jobid, stepid);
break;
case SUBMIT_PAGE:
if(stepid == NO_VAL)
snprintf(title, 100, "Submit job on job %d", jobid);
else
snprintf(title, 100, "Submit job on job %d.%d",
jobid, stepid);
break;
case INFO_PAGE:
if(stepid == NO_VAL)
snprintf(title, 100, "Full info for job %d", jobid);
else
snprintf(title, 100, "Full info for job %d.%d",
jobid, stepid);
break;
default:
g_print("jobs got id %d\n", id);
}
itr = list_iterator_create(popup_list);
while((popup_win = list_next(itr))) {
if(popup_win->spec_info)
if(!strcmp(popup_win->spec_info->title, title)) {
break;
}
}
list_iterator_destroy(itr);
if(!popup_win) {
if(id == INFO_PAGE)
popup_win = create_popup_info(id, JOB_PAGE, title);
else
popup_win = create_popup_info(JOB_PAGE, id, title);
} else {
gtk_window_present(GTK_WINDOW(popup_win->popup));
return;
}
switch(id) {
case NODE_PAGE:
gtk_tree_model_get(model, iter, SORTID_NODELIST, &name, -1);
popup_win->spec_info->search_info->gchar_data = name;
break;
case PART_PAGE:
gtk_tree_model_get(model, iter, SORTID_PARTITION, &name, -1);
popup_win->spec_info->search_info->gchar_data = name;
break;
#ifdef HAVE_BG
case BLOCK_PAGE:
gtk_tree_model_get(model, iter, SORTID_BLOCK, &name, -1);
popup_win->spec_info->search_info->gchar_data = name;
break;
#endif
case SUBMIT_PAGE:
break;
case INFO_PAGE:
popup_win->spec_info->search_info->int_data = jobid;
popup_win->spec_info->search_info->int_data2 = stepid;
break;
default:
g_print("jobs got %d\n", id);
}
if (!g_thread_create((gpointer)popup_thr, popup_win, FALSE, &error))
{
g_printerr ("Failed to create part popup thread: %s\n",
error->message);
return;
}
}
extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, char *type)
{
int jobid = NO_VAL;
int stepid = NO_VAL;
int state = 0;
int response = 0;
char tmp_char[255];
char *tmp_char_ptr = NULL;
int edit_type = 0;
uint16_t signal = SIGKILL;
job_desc_msg_t *job_msg = xmalloc(sizeof(job_desc_msg_t));
GtkWidget *label = NULL;
GtkWidget *entry = NULL;
GtkWidget *popup = gtk_dialog_new_with_buttons(
type,
GTK_WINDOW(main_window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
NULL);
gtk_window_set_transient_for(GTK_WINDOW(popup), NULL);
gtk_tree_model_get(model, iter, SORTID_JOBID, &jobid, -1);
gtk_tree_model_get(model, iter, SORTID_ALLOC, &stepid, -1);
if(stepid)
stepid = NO_VAL;
else {
stepid = jobid;
gtk_tree_model_get(model, iter, SORTID_POS, &jobid, -1);
}
slurm_init_job_desc_msg(job_msg);
if(!strcasecmp("Signal", type)) {
label = gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_OK, GTK_RESPONSE_OK);
gtk_window_set_default(GTK_WINDOW(popup), label);
gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
entry = create_entry();
label = gtk_label_new("Signal?");
edit_type = EDIT_SIGNAL;
} else if(!strcasecmp("Cancel", type)) {
label = gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_YES, GTK_RESPONSE_OK);
gtk_window_set_default(GTK_WINDOW(popup), label);
gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
if(stepid != NO_VAL)
snprintf(tmp_char, sizeof(tmp_char),
"Are you sure you want to cancel job %u.%u?",
jobid, stepid);
else
snprintf(tmp_char, sizeof(tmp_char),
"Are you sure you want to cancel job %u?",
jobid);
label = gtk_label_new(tmp_char);
edit_type = EDIT_CANCEL;
} else if(!strcasecmp("Suspend/Resume", type)) {
label = gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_YES, GTK_RESPONSE_OK);
gtk_window_set_default(GTK_WINDOW(popup), label);
gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
gtk_tree_model_get(model, iter, SORTID_STATE_NUM, &state, -1);
if(state == JOB_SUSPENDED)
tmp_char_ptr = "resume";
else
tmp_char_ptr = "suspend";
if(stepid != NO_VAL)
snprintf(tmp_char, sizeof(tmp_char),
"Are you sure you want to %s job %u.%u?",
tmp_char_ptr, jobid, stepid);
else
snprintf(tmp_char, sizeof(tmp_char),
"Are you sure you want to %s job %u?",
tmp_char_ptr, jobid);
label = gtk_label_new(tmp_char);
edit_type = EDIT_SUSPEND;
} else {
label = gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_OK, GTK_RESPONSE_OK);
gtk_window_set_default(GTK_WINDOW(popup), label);
gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
gtk_window_set_default_size(GTK_WINDOW(popup), 200, 400);
snprintf(tmp_char, sizeof(tmp_char),
"Editing job %u think before you type",
jobid);
label = gtk_label_new(tmp_char);
edit_type = EDIT_EDIT;
job_msg->job_id = jobid;
entry = _admin_full_edit_job(job_msg, model, iter);
}
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
label, FALSE, FALSE, 0);
if(entry)
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
entry, TRUE, TRUE, 0);
gtk_widget_show_all(popup);
response = gtk_dialog_run (GTK_DIALOG(popup));
if (response == GTK_RESPONSE_OK) {
switch(edit_type) {
case EDIT_SIGNAL:
signal = _xlate_signal_name(
gtk_entry_get_text(GTK_ENTRY(entry)));
if(signal == (uint16_t)NO_VAL) {
tmp_char_ptr = g_strdup_printf(
"%s is not a valid signal.",
gtk_entry_get_text(GTK_ENTRY(entry)));
display_edit_note(tmp_char_ptr);
g_free(tmp_char_ptr);
break;
}
/* fall through to the cancel now the signal
* is set (Default is SIGKILL from above for
* just a regular cancel).
*/
case EDIT_CANCEL:
if(stepid == NO_VAL)
_cancel_job_id(jobid, signal);
else
_cancel_step_id(jobid, stepid, signal);
break;
case EDIT_SUSPEND:
if(state == JOB_SUSPENDED)
response = slurm_resume(jobid);
else
response = slurm_suspend(jobid);
if(response) {
tmp_char_ptr = g_strdup_printf(
"Error happened trying to %s job %u.",
tmp_char_ptr, jobid);
display_edit_note(tmp_char_ptr);
g_free(tmp_char_ptr);
} else {
if(state == JOB_SUSPENDED)
tmp_char_ptr = "resumed";
else
tmp_char_ptr = "suspended";
tmp_char_ptr = g_strdup_printf(
"Job %s %u successfully.",
tmp_char_ptr, jobid);
display_edit_note(tmp_char_ptr);
g_free(tmp_char_ptr);
}
break;
case EDIT_EDIT:
if(got_edit_signal)
goto end_it;
if(slurm_update_job(job_msg) == SLURM_SUCCESS) {
tmp_char_ptr = g_strdup_printf(
"Job %u updated successfully",
jobid);
} else {
tmp_char_ptr = g_strdup_printf(
"Problem updating job %u.",
jobid);
}
display_edit_note(tmp_char_ptr);
g_free(tmp_char_ptr);
break;
default:
break;
}
}
end_it:
slurm_free_job_desc_msg(job_msg);
gtk_widget_destroy(popup);
if(got_edit_signal) {
type = got_edit_signal;
got_edit_signal = NULL;
admin_job(model, iter, type);
xfree(type);
}
return;
}