| /*****************************************************************************\ |
| * 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; |
| } |
| |