1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
38
#include <Xm/ToggleB.h>
39
#include <Xm/DialogS.h>
40
#include <Xm/DrawingA.h>
41
#include <Xm/DrawnB.h>
48
#include <Xmt/Create.h>
49
#include <Xmt/Pixmap.h>
50
#include <Xmt/Layout.h>
51
#include <Xmt/Dialogs.h>
52
#include <Xmt/SetValue.h>
54
#include "sge_all_listsL.h"
56
#include "sge_sched.h"
57
#include "qmon_rmon.h"
58
#include "qmon_queue.h"
59
#include "qmon_qaction.h"
60
#include "qmon_submit.h"
61
#include "qmon_menus.h"
62
#include "qmon_comm.h"
63
#include "qmon_timer.h"
64
#include "qmon_globals.h"
65
#include "qmon_init.h"
66
#include "qmon_ticket.h"
67
#include "qmon_util.h"
68
#include "qmon_appres.h"
69
#include "qmon_message.h"
70
#include "qmon_browser.h"
71
#include "qmon_qcustom.h"
72
#include "qmon_jobcustom.h"
73
#include "sge_feature.h"
74
#include "sge_qinstance.h"
75
#include "sge_qinstance_state.h"
77
#include "sge_cqueue.h"
78
#include "sge_complex_schedd.h"
80
#include "load_correction.h"
82
/*-------------------------------------------------------------------------*/
83
static void qmonBuildQBG(Widget parent, XtPointer cld, XtPointer cad);
84
static void qmonQueuePopdown(Widget w, XtPointer cld, XtPointer cad);
85
static void qmonQueueStartUpdate(Widget w, XtPointer cld, XtPointer cad);
86
static void qmonQueueStopUpdate(Widget w, XtPointer cld, XtPointer cad);
87
static void qmonQueueHash(lList *qlp, lList *hl);
88
static void qmonQueueSetPos(lList *qlp);
89
static void qmonQueueRemove(tQueueIcon *qI);
90
static char *qmonQueueGetArch(const char *qhostname);
91
static char *qmonQueueGetSymbol(char *arch);
92
static String qmonQueueShowBrowserInfo(lListElem *qep);
93
static void qmonDrawQueueButton(Widget w, XtPointer cld, XtPointer cad);
94
static void qmonQueueModify(Widget w, XtPointer cld, XtPointer cad);
95
static void qmonQueueDeleteQuick(Widget w, XtPointer cld, XtPointer cad);
96
static void qmonQueueChangeState(Widget w, XtPointer cld, XtPointer cad);
97
static void qmonChangeBackground(Widget w, int selected);
98
static void HandleButtonPress(Widget w, XtPointer cld, XEvent *event, Boolean *continue_to_dispatch);
99
static void HandleEnter(Widget w, XtPointer cld, XEvent *event, Boolean *continue_to_dispatch);
100
static void qmonCreateQueueControl(Widget w);
101
static void qmonQueueSetLoad(Widget matrix, lListElem *qep);
102
static void qmonQueueShowLoadEvent(Widget w, XtPointer cld, XEvent *event);
103
/* static void showQueueHashTable(XmtHashTable table, XtPointer key, XtPointer *data); */
105
/*-------------------------------------------------------------------------*/
106
static Widget qmon_queue = 0;
107
static Widget queue_da = 0;
108
static Widget queue_customize = 0;
110
static XmtHashTable QueueHashTable = NULL;
111
static tQueueButton* QBG[QUEUE_MAX_VERT];
113
static XmtMenuItem queue_popup_items[] = {
114
{XmtMenuItemLabel, "@{@fBQUEUE ACTIONS}"},
115
{XmtMenuItemSeparator},
116
{XmtMenuItemPushButton, "@{Add}", 'A', "Meta<Key>A", "Meta+A",
118
{XmtMenuItemPushButton, "@{Modify}", 'M', "Meta<Key>M", "Meta+M",
119
qmonQueueModify, NULL},
120
/* {XmtMenuItemPushButton, "DeleteDialog", 'l', "Meta<Key>L", "Meta+L", */
121
/* qmonQCPopup, (XtPointer)QC_DELETE }, */
122
{XmtMenuItemPushButton, "@{Delete}", 'D', "Meta<Key>D", "Meta+D",
123
qmonQueueDeleteQuick, NULL},
124
{XmtMenuItemPushButton, "@{Suspend}", 'S', "Meta<Key>S", "Meta+S",
125
qmonQueueChangeState, (XtPointer)QI_DO_SUSPEND},
126
{XmtMenuItemPushButton, "@{Resume}", 'R', "Meta<Key>R", "Meta+R",
127
qmonQueueChangeState, (XtPointer)QI_DO_UNSUSPEND},
128
{XmtMenuItemPushButton, "@{Disable}", 'i', "Meta<Key>I", "Meta+I",
129
qmonQueueChangeState, (XtPointer)QI_DO_DISABLE},
130
{XmtMenuItemPushButton, "@{Enable}", 'E', "Meta<Key>E", "Meta+E",
131
qmonQueueChangeState, (XtPointer)QI_DO_ENABLE}
135
#define WIDTH "%s%-30.30s"
137
/*-------------------------------------------------------------------------*/
138
/* P U B L I C F U N C T I O N S */
139
/*-------------------------------------------------------------------------*/
140
void qmonQueuePopup(Widget w, XtPointer cld, XtPointer cad)
144
DENTER(GUI_LAYER, "qmonQueuePopup");
146
/* set busy cursor */
147
XmtDisplayBusyCursor(w);
149
qmonMirrorMultiAnswer(CQUEUE_T | EXECHOST_T | CENTRY_T, &alp);
151
qmonMessageBox(w, alp, 0);
153
/* set busy cursor */
154
XmtDisplayDefaultCursor(w);
161
qmonCreateQueueControl(AppShell);
164
** create queue customize dialog
166
/* qmonCreateQCU(qmon_queue, NULL); */
169
** set the close button callback
170
** set the icon and icon name
172
XmtCreatePixmapIcon(qmon_queue, qmonGetIcon("toolbar_queue"), None);
173
XtVaSetValues(qmon_queue, XtNiconName, "qmon:Queue Control", NULL);
174
XmtAddDeleteCallback(qmon_queue, XmDO_NOTHING, qmonQueuePopdown, NULL);
175
XtAddEventHandler(qmon_queue, StructureNotifyMask, False,
176
SetMinShellSize, NULL);
177
XtAddEventHandler(qmon_queue, StructureNotifyMask, False,
178
SetMaxShellSize, (XtPointer) SHELL_WIDTH);
182
xmui_manage(qmon_queue);
183
/* ForceUpdate(qmon_queue); */
189
** workaround for display problem of DrawingArea under some WMs
191
XtUnmapWidget(queue_da);
192
XtMapWidget(queue_da);
195
/* set busy cursor */
196
XmtDisplayDefaultCursor(w);
201
/*-------------------------------------------------------------------------*/
202
void updateQueueList(void)
208
lEnumeration *whatall = NULL;
209
lCondition *where = NULL;
210
static Boolean filter_on = False;
212
DENTER(GUI_LAYER, "updateQueueList");
214
cl = qmonMirrorList(SGE_CENTRY_LIST);
218
hl = lCopyList("HL", qmonMirrorList(SGE_EXECHOST_LIST));
222
** select a subset of the whole queue list (->where)
223
** and get the list sorted
227
where = lWhere("%T(%I!=%s)", QU_Type, QU_qname, QU_TEMPLATE);
228
whatall = lWhat("%T(ALL)", QU_Type);
230
whatall = lWhat("%T(ALL)", CQ_Type);
232
qlp = lSelect("SQL", qmonMirrorList(SGE_CQUEUE_LIST), where, whatall);
238
** additional filtering
240
rl = qmonQFilterRequest();
243
setButtonLabel(queue_customize, "@{Customize +}");
246
match_queue(&qlp, rl, cl, hl);
250
setButtonLabel(queue_customize, "@{Customize}");
256
** sort the queues according to sequence number and alphabetically
258
lPSortList(qlp, "%I+ %I+ %I+", QU_seq_no, QU_qhostname, QU_qname);
261
** save the queue in hash table
263
qmonQueueHash(qlp, hl);
265
qmonQueueSetPos(qlp);
267
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
268
** qlp must not be freed it is referenced in qmonHashQueue
275
/*-------------------------------------------------------------------------*/
276
void updateQueueListCB(Widget w, XtPointer cld, XtPointer cad)
282
qmonMirrorMultiAnswer(CQUEUE_T | EXECHOST_T | CENTRY_T, &alp);
284
qmonMessageBox(w, alp, 0);
292
/*-------------------------------------------------------------------------*/
293
/* P R I V A T E F U N C T I O N S */
294
/*-------------------------------------------------------------------------*/
295
static void qmonQueuePopdown(Widget w, XtPointer cld, XtPointer cad)
297
DENTER(GUI_LAYER, "qmonQueuePopdown");
299
qmonQCPopdown(w, NULL, NULL);
300
xmui_unmanage(qmon_queue);
305
/*-------------------------------------------------------------------------*/
306
static void qmonQueueStartUpdate(Widget w, XtPointer cld, XtPointer cad)
308
DENTER(GUI_LAYER, "qmonQueueStartUpdate");
311
* register the update procedure
312
* start queue timer for queue info and exechost timer for infos
313
* of host that the queue is attached to
315
qmonTimerAddUpdateProc(CQUEUE_T, "updateQueueList", updateQueueList);
316
qmonStartTimer(CQUEUE_T | EXECHOST_T | CENTRY_T);
322
/*-------------------------------------------------------------------------*/
323
static void qmonQueueStopUpdate(Widget w, XtPointer cld, XtPointer cad)
325
DENTER(GUI_LAYER, "qmonQueueStopUpdate");
328
* remove the update procedure
329
* stop queue timer for queue info and exechost timer for infos
330
* of host that the queue is attached to
332
qmonStopTimer(CQUEUE_T | EXECHOST_T | CENTRY_T);
333
qmonTimerRmUpdateProc(CQUEUE_T, "updateQueueList");
338
/*-------------------------------------------------------------------------*/
339
static void qmonCreateQueueControl(
342
Widget queue_add, queue_modify, queue_update,
343
queue_delete, queue_done, queue_suspend, queue_unsuspend,
344
queue_enable, queue_disable, queue_reschedule,
345
queue_error, queue_tickets, queue_main_link;
347
DENTER(GUI_LAYER, "qmonCreateQueueControl");
349
qmon_queue = XmtBuildQueryToplevel( parent, "qmon_queue",
350
"queue_da", &queue_da,
351
"queue_add", &queue_add,
352
"queue_modify", &queue_modify,
353
"queue_customize", &queue_customize,
354
"queue_done", &queue_done,
355
"queue_update", &queue_update,
356
"queue_delete", &queue_delete,
357
"queue_suspend", &queue_suspend,
358
"queue_unsuspend", &queue_unsuspend,
359
"queue_enable", &queue_enable,
360
"queue_disable", &queue_disable,
361
"queue_reschedule", &queue_reschedule,
362
"queue_error", &queue_error,
363
"queue_tickets", &queue_tickets,
364
"queue_main_link", &queue_main_link,
368
XtAddCallback(queue_tickets, XmNactivateCallback,
369
qmonPopupTicketOverview, NULL);
371
XtAddCallback(queue_add, XmNactivateCallback,
373
XtAddCallback(queue_modify, XmNactivateCallback,
374
qmonQueueModify, NULL);
375
XtAddCallback(queue_customize, XmNactivateCallback,
377
XtAddCallback(queue_done, XmNactivateCallback,
378
qmonQueuePopdown, NULL);
379
XtAddCallback(queue_main_link, XmNactivateCallback,
380
qmonMainControlRaise, NULL);
381
XtAddCallback(queue_update, XmNactivateCallback,
382
updateQueueListCB, NULL);
383
XtAddCallback(queue_delete, XmNactivateCallback,
384
qmonQueueDeleteQuick, NULL);
385
XtAddCallback(queue_suspend, XmNactivateCallback,
386
qmonQueueChangeState, (XtPointer)QI_DO_SUSPEND);
387
XtAddCallback(queue_unsuspend, XmNactivateCallback,
388
qmonQueueChangeState, (XtPointer)QI_DO_UNSUSPEND);
389
XtAddCallback(queue_disable, XmNactivateCallback,
390
qmonQueueChangeState, (XtPointer)QI_DO_DISABLE);
391
XtAddCallback(queue_enable, XmNactivateCallback,
392
qmonQueueChangeState, (XtPointer)QI_DO_ENABLE);
393
XtAddCallback(queue_reschedule, XmNactivateCallback,
394
qmonQueueChangeState, (XtPointer)QI_DO_RESCHEDULE);
395
XtAddCallback(queue_error, XmNactivateCallback,
396
qmonQueueChangeState, (XtPointer)QI_DO_CLEARERROR);
397
/* XtAddCallback(queue_load, XmNvalueChangedCallback, */
398
/* qmonQueueToggleLoad, NULL); */
401
/* start the needed timers and the corresponding update routines */
402
XtAddCallback(qmon_queue, XmNpopupCallback,
403
qmonQueueStartUpdate, NULL);
404
XtAddCallback(qmon_queue, XmNpopdownCallback,
405
qmonQueueStopUpdate, NULL);
408
/* register event handler for queue popup */
409
qmonCreatePopup(queue_da, "QueuePopup", queue_popup_items,
410
XtNumber(queue_popup_items));
411
qmonBuildQBG(queue_da, NULL, NULL);
412
XtManageChild(queue_da);
419
/*-------------------------------------------------------------------------*
421
* In order to bypass annoying flickering effects, we manage a whole
422
* bunch of PushB's, but they are all unmapped. By looping through
423
* the actual list we give the actual queue a grid position and
424
* map the corresponding PushB, changing its labelString or labelPixmap
425
* We register an enter/leave Event Handler to have the ability to
426
* show some additional useful information about the queue (->Browser)
427
* The handle to the information is a Quark build from qhostname and qname
428
* therefore we need the same qname/qhostname in distinct accesses to the
429
* hash table through the quark mechanism. (->tolower(qhostname),if there
430
* are several versions of qhostname (FRODO.adomain, frodo.adomain))
431
* The QueueButtonGrid (QBG) sizes are settable through resources at startup
432
* of the application.
434
*-------------------------------------------------------------------------*/
435
static void qmonBuildQBG(
442
int x0 = (QUEUE_GRID_WIDTH - QUEUE_BUTTON_WIDTH) / 2;
443
int y0 = (QUEUE_GRID_HEIGHT - QUEUE_BUTTON_HEIGHT) / 2;
445
DENTER(GUI_LAYER, "qmonBuildQBG");
447
for (i=0; i<QUEUE_MAX_VERT; i++) {
448
QBG[i] = (tQueueButton*) XtMalloc(sizeof(tQueueButton) *
452
for (i=0; i<QUEUE_MAX_VERT; i++) {
453
for (j=0; j< QUEUE_MAX_HORIZ; j++) {
454
x = QUEUE_GRID_XOFFSET + j * QUEUE_GRID_WIDTH;
455
y = QUEUE_GRID_YOFFSET + i * QUEUE_GRID_HEIGHT;
458
QBG[i][j].bgid = XtVaCreateWidget(
460
xmDrawingAreaWidgetClass,
467
XmNheight, QUEUE_GRID_HEIGHT,
468
XmNwidth, QUEUE_GRID_WIDTH,
469
XmNresizePolicy, XmRESIZE_NONE,
470
XmNshadowThickness, 0,
471
XmNhighlightThickness, 0,
474
XtAddEventHandler(QBG[i][j].bgid,
476
False, HandleButtonPress,
477
(XtPointer)&QBG[i][j]);
479
QBG[i][j].id = XtVaCreateManagedWidget("QBG",
480
xmDrawnButtonWidgetClass,
482
XmNmappedWhenManaged, False,
485
XmNheight, QUEUE_BUTTON_HEIGHT,
486
XmNwidth, QUEUE_BUTTON_WIDTH,
487
XmNrecomputeSize, False,
489
XtAddCallback( QBG[i][j].id,
492
(XtPointer)&QBG[i][j]);
494
XtAddEventHandler(QBG[i][j].id,
496
False, HandleButtonPress,
497
(XtPointer)&QBG[i][j]);
499
XtAddEventHandler(QBG[i][j].id,
500
EnterWindowMask | LeaveWindowMask,
502
(XtPointer)&QBG[i][j]);
504
/* XtRealizeWidget(QBG[i][j].bgid); */
505
XtManageChild(QBG[i][j].bgid);
508
XtAddCallback(QBG[i][j].id, XmNarmCallback,
509
qmonQueueShowLoadCB, (XtPointer)&QBG[i][j]);
510
XtAddCallback(QBG[i][j].id, XmNdisarmCallback,
511
qmonQueueShowLoadCB, (XtPointer)&QBG[i][j]);
520
/*-------------------------------------------------------------------------*/
521
static void qmonQueueHash(
526
static lList *prev_ql = NULL;
527
static lList *prev_hl = NULL;
529
tQueueIcon *queueIcon;
531
const char *qname, *qhostname;
532
Boolean already_hashed;
534
DENTER(GUI_LAYER, "qmonQueueHash");
536
/* Create QueueHashTable if necessary */
538
QueueHashTable = XmtHashTableCreate(5);
540
for_each(qep, new_ql) {
542
qname = lGetString(qep, CQ_name);
543
/* quarkify CQ_name */
544
id = (long) XrmStringToQuark(qname);
547
* if the queue has already been hashed XmtHashTableLookup()
551
already_hashed = XmtHashTableLookup(QueueHashTable,
553
(XtPointer*) &queueIcon);
554
if (already_hashed) {
557
if (!queueIcon->arch)
558
queueIcon->arch = qmonQueueGetArch(qhostname);
562
/* create a new tQueueIcon structure */
563
queueIcon = (tQueueIcon *)XtMalloc(sizeof(tQueueIcon));
565
queueIcon->quark = id;
566
queueIcon->grid_x = 0;
567
queueIcon->grid_y = 0;
568
queueIcon->selected = False;
569
queueIcon->deleted = False;
570
queueIcon->pixmap = 0;
571
queueIcon->arch = "solaris"; /* qmonQueueGetArch(qhostname); */
573
XmtHashTableStore(QueueHashTable,
575
(XtPointer) queueIcon);
578
/* remove element from previous ql */
579
lDelElemStr(&prev_ql, CQ_name, qname);
583
** remove the no longer used Hash entries
584
** free the tQueueIcon structs
586
for_each(qep, prev_ql) {
587
qname = lGetString(qep, CQ_name);
588
id = (long) XrmStringToQuark(qname);
589
if (XmtHashTableLookup( QueueHashTable, (XtPointer) id,
590
(XtPointer *)&queueIcon)) {
591
qmonQueueRemove(queueIcon);
596
** free the previously referenced queue elements
601
/* now the new_ql becomes the prev_ql */
605
/* XmtHashTableForEach(QueueHashTable, showQueueHashTable); */
610
/*-------------------------------------------------------------------------*/
611
static void qmonQueueRemove(
614
DENTER(GUI_LAYER, "qmonQueueRemove");
616
XmtHashTableDelete(QueueHashTable, (XtPointer)qI->quark);
619
** free architecture entry
623
XtFree((char*) qI->arch);
628
** release reference to queue element
629
** queue element is freed in qmonQueueHash
634
** free tQueueIcon struct
642
/*-------------------------------------------------------------------------*/
643
static void qmonQueueSetPos(
646
lListElem *ep = NULL;
650
const char *qname = NULL;
651
tQueueIcon *qI = NULL;
655
DENTER(GUI_LAYER, "qmonQueueSetPos");
658
* every element in the list is attached to a special grid position
662
** delete previously attached queues
663
** we release here only the references, the corresponding data
664
** are freed in qmonQueueHash
666
for (i=0; i<QUEUE_MAX_VERT; i++)
667
for (j=0; j<QUEUE_MAX_HORIZ; j++)
673
** FIXME: workaround for exceeding the max number of queues
674
** exceeding queues are not displayed
677
if (max_count >= QUEUE_MAX_HORIZ * QUEUE_MAX_VERT)
680
/* lookup queue struct qI */
681
qname = lGetString(ep, CQ_name);
682
q = (long) XrmStringToQuark(qname);
683
/* printf("----> q = %ld\n", q); */
684
/* XmtHashTableForEach(QueueHashTable, showQueueHashTable); */
685
/* printf("---->\n"); */
687
if (!XmtHashTableLookup(QueueHashTable, (XtPointer) q, (XtPointer*) &qI))
688
fprintf(stderr, "++++++++++++Hash Table Failure++++++++++++++++\n");
690
/* the algorithm to attach the q to a special pos */
691
if (grid_x == QUEUE_MAX_HORIZ) {
697
qI->grid_x = grid_x++;
699
/* map/unmap Buttons if qI is set/NULL; reset selection state */
700
QBG[qI->grid_y][qI->grid_x].qI = qI;
704
/* loop through the button list and map/unmap */
705
for (i=0; i<QUEUE_MAX_VERT; i++) {
706
for (j=0; j<QUEUE_MAX_HORIZ; j++) {
708
XtSetMappedWhenManaged(QBG[i][j].id, True);
710
XtSetMappedWhenManaged(QBG[i][j].id, False);
712
if (QBG[i][j].qI && QBG[i][j].qI->selected
713
&& XtWindow(QBG[i][j].bgid))
714
qmonChangeBackground(QBG[i][j].bgid, True);
716
qmonChangeBackground(QBG[i][j].bgid, False);
717
/* we need qI->deleted in qmonDrawQueueButton */
718
if (QBG[i][j].qI && XtWindow(QBG[i][j].id))
719
qmonDrawQueueButton(QBG[i][j].id,
720
(XtPointer) &QBG[i][j],
723
if (QBG[i][j].qI && QBG[i][j].qI->deleted)
724
XtSetSensitive(QBG[i][j].id, False);
726
XtSetSensitive(QBG[i][j].id, True);
729
XmUpdateDisplay(AppShell);
731
/* XmtHashTableForEach(QueueHashTable, showQueueHashTable); */
737
/*-------------------------------------------------------------------------*/
738
static void HandleEnter(
744
tQueueButton *qB = (tQueueButton*)cld;
750
DENTER(GUI_LAYER, "HandleEnter");
752
if (ev->type == EnterNotify) {
754
if (qmonBrowserObjectEnabled(BROWSE_QUEUE)) {
755
sprintf(info, "+++++++++++++++++++++++++++++++++++++++++++\n");
756
qmonBrowserShow(info);
759
for_each(qp, lGetList(qB->qI->qp, CQ_qinstances)) {
760
browser_info = qmonQueueShowBrowserInfo(qp);
763
qmonBrowserShow(browser_info);
764
sprintf(info, "+++++++++++++++++++++++++++++++++++++++++++\n");
765
qmonBrowserShow(info);
769
qmonQueueShowLoadEvent(w, cld, ev);
776
if (ev->type == LeaveNotify) {
777
qmonQueueDeleteLoadEvent(w, cld, ev);
784
/*-------------------------------------------------------------------------*/
785
static void qmonQueueShowLoadEvent(
790
tQueueButton *qb = (tQueueButton*) cld;
792
static Widget lmon=0;
793
static Widget matrix;
795
DENTER(GUI_LAYER, "qmonQueueShowLoadEvent");
802
parent = XmtNameToWidget(w, "~*queue_sw");
805
lmon = XmtBuildQueryDialog(parent, "lmon_shell",
807
"lmon_matrix", &matrix,
811
qmonQueueSetLoad(matrix, qb->qI->qp);
814
updateQueueListCB(w, NULL, NULL);
816
qmonQueueSetLoad(matrix, qb->qI->qp);
819
XtAddEventHandler(XtParent(lmon), StructureNotifyMask, False,
820
SetMinShellSize, (XtPointer) SHELL_WIDTH);
821
XtAddEventHandler(XtParent(lmon), StructureNotifyMask, False,
822
SetMaxShellSize, (XtPointer) SHELL_WIDTH);
827
/*-------------------------------------------------------------------------*/
828
static void qmonQueueSetLoad(
832
static char info[10000];
837
StringConst new_row[3];
842
DENTER(GUI_LAYER, "qmonQueueSetLoad");
844
ehl = qmonMirrorList(SGE_EXECHOST_LIST);
845
cl = qmonMirrorList(SGE_CENTRY_LIST);
847
correct_capacities(ehl, cl);
848
queue_complexes2scheduler(&ncl, qep, ehl, cl);
850
sprintf(info, "%s %s", XmtLocalize(matrix, "Attributes for queue", "Attributes for queue"), lGetString(qep, QU_qname));
852
xstr = XmtCreateXmString(info);
853
XtVaSetValues(XtParent(matrix), XmNdialogTitle, xstr, NULL);
856
rows = XbaeMatrixNumRows(matrix);
857
XbaeMatrixDeleteRows(matrix, 0, rows);
860
for_each_rev (ep, ncl) {
865
StringConst slot_limit;
866
StringConst job_limit;
867
if (!(name = lGetString(ep, CE_name)))
869
/* don't view value entry from complex */
870
slot_limit = (lGetUlong(ep, CE_dominant)&DOMINANT_TYPE_VALUE)?
871
NULL:lGetString(ep, CE_stringval);
872
type = lGetUlong(ep, CE_valtype);
873
if (slot_limit && (type == TYPE_MEM || type == TYPE_DOUBLE) &&
874
(n=sscanf(slot_limit, "%f%c", &fval, &unit))>=1) {
875
sprintf(info, "%8.3f%c", fval, (n>1) ? unit : '\0');
876
lSetString(ep, CE_stringval, info);
877
slot_limit = lGetString(ep, CE_stringval);
880
while (*slot_limit && isspace(*slot_limit))
883
job_limit = lGetString(ep, CE_pj_stringval);
884
type = lGetUlong(ep, CE_valtype);
885
if (job_limit && (type == TYPE_MEM || type == TYPE_DOUBLE) &&
886
(n = sscanf(job_limit, "%f%c", &fval, &unit))>=1) {
887
sprintf(info, "%8.3f%c", fval, (n>1) ? unit : '\0');
888
lSetString(ep, CE_pj_stringval, info);
889
job_limit = lGetString(ep, CE_pj_stringval);
893
while (*job_limit && isspace(*job_limit))
897
new_row[1] = slot_limit ? slot_limit : "";
898
new_row[2] = job_limit ? job_limit : "";
900
XbaeMatrixAddRows(matrix, 0, (String*) new_row, NULL, NULL, 1);
910
/*-------------------------------------------------------------------------*/
911
static String qmonQueueShowBrowserInfo(
915
static char info[60000];
918
const char *str, *str2;
920
DENTER(GUI_LAYER, "qmonQueueShowBrowserInfo");
922
sprintf(info, WIDTH"%s\n", "\n","Queue:", lGetString(qep, QU_full_name));
924
qtype = lGetUlong(qep, QU_qtype);
927
dstring type_buffer = DSTRING_INIT;
929
qinstance_print_qtype_to_dstring(qep, &type_buffer, false);
930
sprintf(info, WIDTH"%s\n", info, "Type:",
931
sge_dstring_get_string(&type_buffer));
932
sge_dstring_free(&type_buffer);
934
sprintf(info, WIDTH"%d\n", info, "Sequence Nr:",
935
(int)lGetUlong(qep, QU_seq_no));
937
str = lGetString(qep, QU_tmpdir);
938
sprintf(info, WIDTH"%s\n", info, "tmpdir:", str ? str : "");
939
str = lGetString(qep, QU_shell);
940
sprintf(info, WIDTH"%s\n", info, "Shell:", str ? str : "");
941
sprintf(info, WIDTH"%d\n", info, "Job Slots:",
942
(int)lGetUlong(qep, QU_job_slots));
943
sprintf(info, WIDTH"%d\n", info, "Job Slots Used:", qinstance_slots_used(qep));
944
str = lGetString(qep, QU_priority);
945
sprintf(info, WIDTH"%s\n", info, "Priority:", str?str:"");
946
sprintf(info, WIDTH"", info, "Load Thresholds:");
947
for_each(ep, lGetList(qep, QU_load_thresholds)) {
948
str = lGetString(ep, CE_name);
949
str2 = lGetString(ep, CE_stringval);
950
sprintf(info, "%s%s = %s ", info, str?str:"", str2?str2:"");
952
sprintf(info, "%s\n", info);
954
sprintf(info, WIDTH"%s\n", info, "Rerun Job:",
955
lGetBool(qep, QU_rerun) ? "True" : "False");
957
str = lGetString(qep, QU_notify);
958
sprintf(info, WIDTH"%s\n", info, "Notify Job Interval:", str ? str : "");
960
str = lGetString(qep, QU_processors);
961
sprintf(info, WIDTH"%s\n", info, "Processors:", str ? str : "");
963
str = lGetString(qep, QU_s_rt);
964
sprintf(info, WIDTH"%s\n", info, "Soft Real Time:", str ? str : "");
965
str = lGetString(qep, QU_h_rt);
966
sprintf(info, WIDTH"%s\n", info, "Hard Real Time:", str ? str : "");
967
str = lGetString(qep, QU_s_cpu);
968
sprintf(info, WIDTH"%s\n", info, "Soft Cpu:", str ? str : "");
969
str = lGetString(qep, QU_h_cpu);
970
sprintf(info, WIDTH"%s\n", info, "Hard Cpu:", str ? str : "");
971
str = lGetString(qep, QU_s_fsize);
972
sprintf(info, WIDTH"%s\n", info, "Soft File Size:", str ? str : "");
973
str = lGetString(qep, QU_h_fsize);
974
sprintf(info, WIDTH"%s\n", info, "Hard File Size:", str ? str : "");
975
str = lGetString(qep, QU_s_data);
976
sprintf(info, WIDTH"%s\n", info, "Soft Data Size:", str ? str : "");
977
str = lGetString(qep, QU_h_data);
978
sprintf(info, WIDTH"%s\n", info, "Hard Data Size:", str ? str : "");
979
str = lGetString(qep, QU_s_stack);
980
sprintf(info, WIDTH"%s\n", info, "Soft Stack Size:", str ? str : "");
981
str = lGetString(qep, QU_h_stack);
982
sprintf(info, WIDTH"%s\n", info, "Hard Stack Size:", str ? str : "");
983
str = lGetString(qep, QU_s_core);
984
sprintf(info, WIDTH"%s\n", info, "Soft Core Size:", str ? str : "");
985
str = lGetString(qep, QU_h_core);
986
sprintf(info, WIDTH"%s\n", info, "Hard Core Size:", str ? str : "");
987
str = lGetString(qep, QU_s_rss);
988
sprintf(info, WIDTH"%s\n", info, "Soft Resident Set Size:", str ? str : "");
989
str = lGetString(qep, QU_h_rss);
990
sprintf(info, WIDTH"%s\n", info, "Hard Resident Set Size:", str ? str : "");
992
str = lGetString(qep, QU_min_cpu_interval);
993
sprintf(info, WIDTH"%s\n", info, "Min Cpu Interval:", str ? str : "");
995
sprintf(info, WIDTH"", info, "Access List:");
996
for_each(ep, lGetList(qep, QU_acl)) {
997
sprintf(info, "%s%s ", info, lGetString(ep, US_name));
999
sprintf(info, "%s\n", info);
1000
sprintf(info, WIDTH"", info, "No Access List:");
1001
for_each(ep, lGetList(qep, QU_xacl)) {
1002
sprintf(info, "%s%s ", info, lGetString(ep, US_name));
1004
sprintf(info, "%s\n", info);
1006
DPRINTF(("info is %d long\n", strlen(info)));
1012
/*-------------------------------------------------------------------------*/
1013
static void HandleButtonPress(
1019
tQueueButton *qB = (tQueueButton*) cld;
1021
DENTER(GUI_LAYER, "HandleButtonPress");
1025
switch ( ev->xbutton.button ) {
1027
if (ev->xbutton.state & ShiftMask) {
1028
qmonQueueShowLoadEvent(w, cld, ev);
1030
else if (ev->xbutton.state & ControlMask) {
1031
char hostname[SGE_PATH_MAX];
1033
strcpy(hostname, "global");
1034
if (qB && qB->qI && qB->qI->qp) {
1035
sge_strlcpy(hostname, lGetHost(qB->qI->qp, QU_qhostname),
1037
strtok(hostname, ".");
1039
qmonBrowserMessages(w, (XtPointer)hostname, NULL);
1043
qB->qI->selected = !(qB->qI->selected);
1044
qmonChangeBackground(qB->bgid, qB->qI->selected );
1054
** call no other event handler
1061
/*-------------------------------------------------------------------------*/
1062
static void qmonChangeBackground(
1066
static int first_time = 1;
1067
static Pixel background;
1069
DENTER(BASIS_LAYER, "qmonChangeBackground");
1074
XmNbackground, &background,
1079
XmNbackground, selected ? QueueSelectedPixel : background,
1086
/*-------------------------------------------------------------------------*/
1087
static void qmonDrawQueueButton(Widget w, XtPointer cld, XtPointer cad)
1089
static XmFontList defaultFontList = NULL;
1090
tQueueButton *qB = (tQueueButton*) cld;
1091
Dimension ht, st, bw, width, height, sw, sh;
1094
unsigned int border_width, depth;
1096
XmString str = NULL;
1100
const char *qname = NULL, *qhostname = NULL;
1101
unsigned long job_slots = 0, job_slots_used = 0;
1102
unsigned long alarm_set = 0, suspend_threshold_alarm = 0;
1104
u_long32 is_load_available = 0;
1107
u_long32 suspend_manual = 0;
1108
u_long32 suspend_threshold = 0;
1109
u_long32 suspend_on_subordinate = 0;
1110
u_long32 suspend_calendar = 0;
1111
u_long32 unknown = 0;
1112
u_long32 load_alarm = 0;
1113
u_long32 disabled_manual = 0;
1114
u_long32 disabled_calendar = 0;
1115
u_long32 ambiguous = 0;
1116
u_long32 orphaned = 0;
1118
u_long32 available = 0;
1119
u_long32 temp_disabled = 0;
1120
u_long32 manual_intervention = 0;
1125
lListElem *q = NULL;
1127
DENTER(GUI_LAYER, "qmonDrawQueueButton");
1129
if (!defaultFontList) {
1130
XmFontList theFontList = NULL;
1131
XmFontContext fc = NULL;
1132
XtVaGetValues(w, XmNfontList, &theFontList, NULL);
1133
if (XmFontListInitFontContext(&fc, theFontList)) {
1134
XmFontListEntry entry;
1135
while ((entry = XmFontListNextEntry(fc))) {
1136
char *tag = XmFontListEntryGetTag(entry);
1137
DPRINTF(("tag = %s\n", tag ? tag : ""));
1138
if (!strcmp(tag, "QUEUEICON")){
1139
defaultFontList = XmFontListAppendEntry(NULL, entry);
1143
XmFontListFreeFontContext(fc);
1145
if (!defaultFontList) {
1146
XmFontListEntry entry = XmFontListEntryLoad(XtDisplay(w),
1147
"-*-helvetica-medium-r-*-*-*-60-*-*-*-*-*-*",
1149
XmFONTLIST_DEFAULT_TAG);
1150
defaultFontList = XmFontListAppendEntry(NULL, entry);
1151
XmFontListEntryFree(&entry);
1155
/* Button active ? */
1158
** get info from queue
1161
ehl = qmonMirrorList(SGE_EXECHOST_LIST);
1162
cl = qmonMirrorList(SGE_CENTRY_LIST);
1165
qname = lGetString(q, CQ_name);
1167
cqueue_calculate_summary(q, ehl, cl,
1168
&load, &is_load_available, &used, &total,
1169
&suspend_manual, &suspend_threshold,
1170
&suspend_on_subordinate, &suspend_calendar,
1171
&unknown, &load_alarm, &disabled_manual,
1172
&disabled_calendar, &ambiguous, &orphaned,
1173
&error, &available, &temp_disabled,
1174
&manual_intervention);
1176
DPRINTF(("<<Queue: %s/%f/%d/%d>>\n", qname, load, used, total);
1180
DPRINTF(("Queue Button Grid corrupted\n"));
1186
** get the right pixmap and get the size
1188
qB->qI->pixmap = qmonGetIcon(qmonQueueGetSymbol(qB->qI->arch));
1189
XGetGeometry( XtDisplay(qB->id),
1191
&root, &(qB->qI->x), &(qB->qI->y),
1192
&(qB->qI->icon_width), &(qB->qI->icon_height),
1193
&border_width, &depth );
1195
** get the dimensions of the button
1200
XmNborderWidth, &bw,
1201
XmNhighlightThickness, &ht,
1202
XmNshadowThickness, &st,
1211
** Clear the effective drawing area
1213
XClearArea(XtDisplay(w), XtWindow(w), bw, bw, width-2*bw,
1214
height-2*bw, False);
1217
** Center the icon horizontally
1219
x = (width - qB->qI->icon_width)/2;
1220
XCopyArea( XtDisplay(w), qB->qI->pixmap, XtWindow(w),
1221
DefaultGCOfScreen(XtScreen(w)),
1222
0, 0, qB->qI->icon_width - bw, qB->qI->icon_height - bw,
1225
/* draw a string into the pixmap */
1226
sprintf(buf, "@f[SMALL]%s\nSlots: " sge_u32 "("sge_u32")",
1227
qname, used, total);
1229
str = XmtCreateXmString(buf);
1230
XmStringExtent(defaultFontList, str, &sw, &sh);
1233
rect.width = width - 2 * bw;
1234
rect.height = height - 2 * bw;
1237
/* if string is to long use unqualified hostname */
1238
if (sw > rect.width) {
1240
for (i=0; qhostname[i] != '.' && i < strlen(qhostname) && i<128; i++)
1241
hostname[i] = qhostname[i];
1243
sprintf(buf,"@f[SMALL]%s\n%s\nSlots: %ld (%ld)",
1244
qname, hostname, job_slots_used,
1246
str = XmtCreateXmString(buf);
1247
XmStringExtent(defaultFontList, str, &sw, &sh);
1252
** draw the status bar if necessary
1254
sbh = (width - 2 * bw - qB->qI->icon_height - sh)/2;
1255
sbw = (width - 2 * bw)/9;
1258
y = height - 2 * bw - sbh;
1261
if (!qinstance_state_is_unknown(q)) {
1263
for (i=0; i<7; i++) {
1264
XDrawRectangle(XtDisplay(w), XtWindow(w), qb_gc,
1269
/* jobs are running */
1271
XFillRectangle(XtDisplay(w), XtWindow(w), running_gc,
1275
/* queue suspended */
1276
if (qinstance_state_is_susp_on_sub(q))
1277
XFillRectangle(XtDisplay(w), XtWindow(w), suspend_gc,
1278
x + 1 * sbw + 1, y + 1,
1279
sbw - 2, (sbh/2 + sbh % 2));
1281
/* queue suspended */
1282
if (suspend_threshold_alarm) {
1283
XFillRectangle(XtDisplay(w), XtWindow(w), suspend_gc,
1284
x + 1 * sbw + 1, y + (sbh/2 + sbh % 2),
1285
sbw - 2, (sbh/2 + sbh % 2 - 1));
1287
/* queue suspended */
1288
if (qinstance_state_is_manual_suspended(q))
1289
XFillRectangle(XtDisplay(w), XtWindow(w), suspend_gc,
1290
x + 1 * sbw + 1, y + 1,
1293
/* queue disabled */
1294
if (qinstance_state_is_manual_disabled(q))
1295
XFillRectangle(XtDisplay(w), XtWindow(w), disable_gc,
1296
x + 2 * sbw + 1, y + 1,
1299
XFillRectangle(XtDisplay(w), XtWindow(w), alarm_gc,
1300
x + 3 * sbw + 1, y + 1,
1303
if (qinstance_state_is_error(q))
1304
XFillRectangle(XtDisplay(w), XtWindow(w), error_gc,
1305
x + 4 * sbw + 1, y + 1,
1308
if (qinstance_state_is_cal_suspended(q))
1309
XFillRectangle(XtDisplay(w), XtWindow(w), calsuspend_gc,
1310
x + 5 * sbw + 1, y + 1,
1313
if (qinstance_state_is_cal_disabled(q))
1314
XFillRectangle(XtDisplay(w), XtWindow(w), caldisable_gc,
1315
x + 6 * sbw + 1, y + 1,
1321
x = rect.x + (rect.width - sw)/2;
1322
y = height - sh - 2 * sbh - bw;
1324
if (qinstance_state_is_unknown(q))
1330
qmonXmStringDraw( XtDisplay(w), XtWindow(w), draw_gc, x, y,
1331
defaultFontList, str, XmALIGNMENT_CENTER ,
1334
if (qB->qI->deleted) {
1338
p[1].x = width - bw;
1339
p[1].y = height - bw;
1340
p[2].x = width - bw;
1343
p[3].y = height - bw;
1344
/* XSetForeground(XtDisplay(w), qb_gc, 50); */
1345
XDrawLines( XtDisplay(w), XtWindow(w), qb_gc,
1346
p, XtNumber(p), CoordModeOrigin );
1352
/*-------------------------------------------------------------------------*/
1353
static void qmonQueueModify(Widget w, XtPointer cld, XtPointer cad)
1358
DENTER(GUI_LAYER, "qmonQueueModify");
1361
** get the selected queues
1363
for (i=0; i<QUEUE_MAX_VERT; i++) {
1364
for (j=0; j<QUEUE_MAX_HORIZ; j++) {
1365
if (QBG[i][j].qI && QBG[i][j].qI->selected) {
1367
lp = lCreateList("DQ", CQ_Type);
1369
lAppendElem(lp, lCopyElem(QBG[i][j].qI->qp));
1374
if (lp && ((n = lGetNumberOfElem(lp)) == 1)) {
1376
** open up the queue configuration dialog and give him a list
1377
** of queues to modify
1379
qmonQCPopup(w, (XtPointer)lGetString(lFirst(lp), CQ_name), NULL);
1383
qmonMessageShow(w, True, "@{Select only one queue !}");
1385
qmonMessageShow(w, True, "@{To modify a queue select this queue !}");
1392
/*-------------------------------------------------------------------------*/
1393
static void qmonQueueDeleteQuick(Widget w, XtPointer cld, XtPointer cad)
1398
static lEnumeration *what = NULL;
1399
Boolean status, answer;
1402
DENTER(GUI_LAYER, "qmonQueueDeleteQuick");
1406
** we need only the queue name
1409
what = lWhat("%T(%I)", CQ_Type, CQ_name);
1412
** get the selected queues
1414
for (i=0; i<QUEUE_MAX_VERT; i++) {
1415
for (j=0; j<QUEUE_MAX_HORIZ; j++) {
1416
if (QBG[i][j].qI && QBG[i][j].qI->selected) {
1418
lp = lCreateList("DQ", CQ_Type);
1420
lAppendElem(lp, lCopyElem(QBG[i][j].qI->qp));
1425
if (lp && (lGetNumberOfElem(lp) > 0)) {
1426
status = XmtAskForBoolean(w, "xmtBooleanDialog",
1427
"@{queue.askdel.Do you really want to\ndelete the selected queues ?}",
1428
"@{Delete}", "@{Cancel}", NULL, XmtNoButton, XmDIALOG_WARNING,
1429
False, &answer, NULL);
1432
alp = qmonDelList(SGE_CQUEUE_LIST, qmonMirrorListRef(SGE_CQUEUE_LIST),
1433
CQ_name, &lp, NULL, what);
1435
qmonMessageBox(w, alp, 0);
1448
/*-------------------------------------------------------------------------*/
1449
static void qmonQueueChangeState(Widget w, XtPointer cld, XtPointer cad)
1454
lListElem *qep = NULL;
1456
long action = (long) cld;
1457
Widget force_toggle;
1459
DENTER(GUI_LAYER, "qmonQueueChangeState");
1462
** cld contains the action we need, check if a force is involved
1464
force_toggle = XmtNameToWidget(w, "*queue_force");
1465
force = XmToggleButtonGetState(force_toggle);
1468
** get the selected queues
1470
for (i=0; i<QUEUE_MAX_VERT; i++) {
1471
for (j=0; j<QUEUE_MAX_HORIZ; j++) {
1472
if (QBG[i][j].qI && QBG[i][j].qI->selected) {
1474
ql = lCreateList("CQ", ST_Type);
1476
qep = lCreateElem(ST_Type);
1477
lSetString(qep, ST_name, lGetString(QBG[i][j].qI->qp, CQ_name));
1478
lAppendElem(ql, qep);
1484
alp = qmonChangeStateList(SGE_CQUEUE_LIST, ql, force, action);
1486
qmonMessageBox(w, alp, 0);
1499
/*-------------------------------------------------------------------------*/
1500
static char *qmonQueueGetArch(
1501
const char *qhostname
1504
lListElem *ehp = NULL;
1505
lListElem *lep = NULL;
1508
DENTER(GUI_LAYER, "qmonQueueGetArch");
1511
DPRINTF(("no qhostname\n"));
1516
ehl = qmonMirrorList(SGE_EXECHOST_LIST);
1517
ehp = host_list_locate(ehl, qhostname);
1519
lep = lGetSubStr(ehp, HL_name, "arch", EH_load_list);
1522
DPRINTF(("no load arch\n"));
1527
arch = XtNewString(lGetString(lep, HL_value));
1533
/*-------------------------------------------------------------------------*/
1534
static char *qmonQueueGetSymbol(
1537
static char *ICONS[] = {
1551
DENTER(GUI_LAYER, "qmonQueueGetSymbol");
1558
if (!strncmp(arch, "irix", 4))
1560
else if (!strncmp(arch, "sgi", 3))
1562
else if (!strncmp(arch, "osf", 3))
1564
else if (!strncmp(arch, "sun", 3))
1566
else if (!strncmp(arch, "axp", 3))
1568
else if (!strncmp(arch, "solaris", 7))
1570
else if (!strncmp(arch, "hp", 2))
1572
else if (!strncmp(arch, "linux", 5))
1574
else if (!strncmp(arch, "alinux", 6))
1576
else if (!strncmp(arch, "glinux", 6))
1578
else if (!strncmp(arch, "slinux", 6))
1580
else if (!strncmp(arch, "rs6000", 6))
1582
else if (!strncmp(arch, "aix4", 4))
1584
else if (!strncmp(arch, "unicos", 6))
1586
else if (!strncmp(arch, "cray", 4))
1591
DPRINTF(("+++++++++++ARCH: %s, %d\n", arch, index));
1594
return ICONS[index];
1598
/* don't remove this function */
1599
static void showQueueHashTable(XmtHashTable table, XtPointer key, XtPointer *data)
1601
printf("%s(%ld)\n", XrmQuarkToString((long)key), (long)key);