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
************************************************************************/
34
#include "sge_resource_quota_qconf.h"
35
#include "msg_common.h"
36
#include "msg_clients_common.h"
38
#include "uti/sge_log.h"
39
#include "uti/sge_edit.h"
40
#include "rmon/sgermon.h"
41
#include "gdi/sge_gdi.h"
42
#include "uti/sge_prog.h"
44
#include "sgeobj/sge_utility.h"
45
#include "sgeobj/sge_resource_quota.h"
46
#include "sgeobj/sge_answer.h"
47
#include "spool/flatfile/sge_flatfile.h"
48
#include "spool/flatfile/sge_flatfile_obj.h"
50
static bool rqs_provide_modify_context(sge_gdi_ctx_class_t *ctx,
51
lList **rqs_list, lList **answer_list,
52
bool ignore_unchanged_message);
55
/****** resource_quota_qconf/rqs_show() *********************************
57
* rqs_show() -- show resource quota sets
60
* bool rqs_show(lList **answer_list, const char *name)
63
* This funtion gets the selected resource quota sets from GDI and
64
* writes they out on stdout
67
* lList **answer_list - answer list
68
* const char *name - comma separated list of resource quota set names
71
* bool - true on success
75
* MT-NOTE: rqs_show() is MT safe
77
*******************************************************************************/
78
bool rqs_show(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *name)
80
lList *rqs_list = NULL;
83
DENTER(TOP_LAYER, "rqs_show");
86
lList *rqsref_list = NULL;
88
lString2List(name, &rqsref_list, RQS_Type, RQS_name, ", ");
89
ret = rqs_get_via_gdi(ctx, answer_list, rqsref_list, &rqs_list);
90
lFreeList(&rqsref_list);
92
ret = rqs_get_all_via_gdi(ctx, answer_list, &rqs_list);
95
if (ret && lGetNumberOfElem(rqs_list)) {
97
filename = spool_flatfile_write_list(answer_list, rqs_list, RQS_fields,
99
SP_DEST_STDOUT, SP_FORM_ASCII, NULL,
103
if (lGetNumberOfElem(rqs_list) == 0) {
104
answer_list_add(answer_list, MSG_NORQSFOUND, STATUS_EEXIST, ANSWER_QUALITY_WARNING);
108
lFreeList(&rqs_list);
113
/****** resource_quota_qconf/rqs_get_via_gdi() **************************
115
* rqs_get_via_gdi() -- get resource quota sets from GDI
118
* bool rqs_get_via_gdi(lList **answer_list, const lList
119
* *rqsref_list, lList **rqs_list)
122
* This function gets the selected resource quota sets from qmaster. The selection
123
* is done in the string list rqsref_list.
126
* lList **answer_list - answer list
127
* const lList *rqsref_list - resource quota sets selection
128
* lList **rqs_list - copy of the selected rule sets
131
* bool - true on success
135
* MT-NOTE: rqs_get_via_gdi() is MT safe
137
*******************************************************************************/
138
bool rqs_get_via_gdi(sge_gdi_ctx_class_t *ctx, lList **answer_list, const lList *rqsref_list,
143
DENTER(TOP_LAYER, "rqs_get_via_gdi");
144
if (rqsref_list != NULL) {
145
lListElem *rqsref = NULL;
146
lCondition *where = NULL;
147
lEnumeration *what = NULL;
149
what = lWhat("%T(ALL)", RQS_Type);
151
for_each(rqsref, rqsref_list) {
152
lCondition *add_where = NULL;
153
add_where = lWhere("%T(%I p= %s)", RQS_Type, RQS_name, lGetString(rqsref, RQS_name));
157
where = lOrWhere(where, add_where);
160
*answer_list = ctx->gdi(ctx, SGE_RQS_LIST, SGE_GDI_GET, rqs_list, where, what);
161
if (!answer_list_has_error(answer_list)) {
172
/****** resource_quota_qconf/rqs_get_all_via_gdi() **********************
174
* rqs_get_all_via_gdi() -- get all resource quota sets from GDI
177
* bool rqs_get_all_via_gdi(lList **answer_list, lList **rqs_list)
180
* This function gets all resource quota sets known by qmaster
183
* lList **answer_list - answer list
184
* lList **rqs_list - copy of all resource quota sets
187
* bool - true on success
191
* MT-NOTE: rqs_get_all_via_gdi() is MT safe
193
*******************************************************************************/
194
bool rqs_get_all_via_gdi(sge_gdi_ctx_class_t *ctx, lList **answer_list, lList **rqs_list)
197
lEnumeration *what = lWhat("%T(ALL)", RQS_Type);
199
DENTER(TOP_LAYER, "rqs_get_all_via_gdi");
201
*answer_list = ctx->gdi(ctx, SGE_RQS_LIST, SGE_GDI_GET, rqs_list, NULL, what);
202
if (!answer_list_has_error(answer_list)) {
211
/****** resource_quota_qconf/rqs_add() ******************************
213
* rqs_add() -- add resource quota set list
216
* bool rqs_add(lList **answer_list, const char *name)
219
* This function provide a modify context for qconf to add new resource
220
* quota sets. If no name is given a template rule set is shown
223
* lList **answer_list - answer list
224
* const char *name - comma seperated list of rule sets to add
227
* bool - true on success
231
* MT-NOTE: rqs_add() is MT safe
233
*******************************************************************************/
234
bool rqs_add(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *name)
238
DENTER(TOP_LAYER, "rqs_list_add");
240
lList *rqs_list = NULL;
241
lListElem *rqs = NULL;
243
lString2List(name, &rqs_list, RQS_Type, RQS_name, ", ");
244
for_each (rqs, rqs_list) {
245
rqs = rqs_set_defaults(rqs);
248
ret = rqs_provide_modify_context(ctx, &rqs_list, answer_list, true);
251
ret = rqs_add_del_mod_via_gdi(ctx, rqs_list, answer_list, SGE_GDI_ADD | SGE_GDI_SET_ALL);
254
lFreeList(&rqs_list);
260
/****** resource_quota_qconf/rqs_modify() ***************************
262
* rqs_modify() -- modify resource quota sets
265
* bool rqs_modify(lList **answer_list, const char *name)
268
* This function provides a modify context for qconf to modify resource
272
* lList **answer_list - answer list
273
* const char *name - comma seperated list of rule sets to modify
276
* bool - true on success
280
* MT-NOTE: rqs_modify() is MT safe
282
*******************************************************************************/
283
bool rqs_modify(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *name)
286
lList *rqs_list = NULL;
287
u_long32 gdi_command = 0;
289
DENTER(TOP_LAYER, "rqs_modify");
292
lList *rqsref_list = NULL;
294
gdi_command = SGE_GDI_MOD | SGE_GDI_SET_ALL;
296
lString2List(name, &rqsref_list, RQS_Type, RQS_name, ", ");
297
ret = rqs_get_via_gdi(ctx, answer_list, rqsref_list, &rqs_list);
298
lFreeList(&rqsref_list);
300
gdi_command = SGE_GDI_REPLACE;
301
ret = rqs_get_all_via_gdi(ctx, answer_list, &rqs_list);
305
ret = rqs_provide_modify_context(ctx, &rqs_list, answer_list, false);
308
ret = rqs_add_del_mod_via_gdi(ctx, rqs_list, answer_list,
312
lFreeList(&rqs_list);
317
/****** resource_quota_qconf/rqs_add_from_file() ********************
319
* rqs_add_from_file() -- add resource quota set from file
322
* bool rqs_add_from_file(lList **answer_list, const char
326
* This function add new resource quota sets from file.
329
* lList **answer_list - answer list
330
* const char *filename - filename of new resource quota sets
333
* bool - true on success
337
* MT-NOTE: rqs_add_from_file() is MT safe
339
*******************************************************************************/
340
bool rqs_add_from_file(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *filename)
344
DENTER(TOP_LAYER, "rqs_add_from_file");
345
if (filename != NULL) {
346
lList *rqs_list = NULL;
348
/* fields_out field does not work for rqs because of duplicate entry */
349
rqs_list = spool_flatfile_read_list(answer_list, RQS_Type, RQS_fields,
350
NULL, true, &qconf_rqs_sfi,
351
SP_FORM_ASCII, NULL, filename);
352
if (!answer_list_has_error(answer_list)) {
353
ret = rqs_add_del_mod_via_gdi(ctx, rqs_list, answer_list,
354
SGE_GDI_ADD | SGE_GDI_SET_ALL);
357
lFreeList(&rqs_list);
362
/****** resource_quota_qconf/rqs_provide_modify_context() ***********
364
* rqs_provide_modify_context() -- provide qconf modify context
367
* bool rqs_provide_modify_context(lList **rqs_list, lList
368
* **answer_list, bool ignore_unchanged_message)
371
* This function provides a editor session to edit the selected resource quota
372
* sets interactively.
375
* lList **rqs_list - resource quota sets to modify
376
* lList **answer_list - answer list
377
* bool ignore_unchanged_message - ignore unchanged message
380
* bool - true on success
384
* MT-NOTE: rqs_provide_modify_context() is MT safe
386
*******************************************************************************/
387
static bool rqs_provide_modify_context(sge_gdi_ctx_class_t *ctx, lList **rqs_list, lList **answer_list,
388
bool ignore_unchanged_message)
392
const char *filename = NULL;
393
uid_t uid = ctx->get_uid(ctx);
394
gid_t gid = ctx->get_gid(ctx);
396
DENTER(TOP_LAYER, "rqs_provide_modify_context");
398
if (rqs_list == NULL) {
399
answer_list_add(answer_list, MSG_PARSE_NULLPOINTERRECEIVED,
400
STATUS_ERROR1, ANSWER_QUALITY_ERROR);
404
if (*rqs_list == NULL) {
405
*rqs_list = lCreateList("", RQS_Type);
408
filename = spool_flatfile_write_list(answer_list, *rqs_list, RQS_fields,
409
&qconf_rqs_sfi, SP_DEST_TMP,
410
SP_FORM_ASCII, filename, false);
412
if (answer_list_has_error(answer_list)) {
418
status = sge_edit(filename, uid, gid);
421
lList *new_rqs_list = NULL;
423
/* fields_out field does not work for rqs because of duplicate entry */
424
new_rqs_list = spool_flatfile_read_list(answer_list, RQS_Type, RQS_fields,
425
NULL, true, &qconf_rqs_sfi,
426
SP_FORM_ASCII, NULL, filename);
427
if (answer_list_has_error(answer_list)) {
428
lFreeList(&new_rqs_list);
430
if (new_rqs_list != NULL) {
431
if (ignore_unchanged_message || object_list_has_differences(new_rqs_list, answer_list, *rqs_list, false)) {
433
*rqs_list = new_rqs_list;
436
lFreeList(&new_rqs_list);
437
answer_list_add(answer_list, MSG_FILE_NOTCHANGED,
438
STATUS_ERROR1, ANSWER_QUALITY_ERROR);
441
answer_list_add(answer_list, MSG_FILE_ERRORREADINGINFILE,
442
STATUS_ERROR1, ANSWER_QUALITY_ERROR);
444
} else if (status == 1) {
445
answer_list_add(answer_list, MSG_FILE_FILEUNCHANGED,
446
STATUS_ERROR1, ANSWER_QUALITY_ERROR);
448
answer_list_add(answer_list, MSG_PARSE_EDITFAILED,
449
STATUS_ERROR1, ANSWER_QUALITY_ERROR);
457
/****** resource_quota_qconf/rqs_add_del_mod_via_gdi() **************
459
* rqs_add_del_mod_via_gdi/rqs_add_del_mod_via_gdi() -- modfies qmaster resource quota sets
462
* bool rqs_add_del_mod_via_gdi(lList *rqs_list, lList
463
* **answer_list, u_long32 gdi_command)
466
* This function modifies via GDI the qmaster copy of the resource quota sets.
469
* lList *rqs_list - resource quota sets to modify on qmaster
470
* lList **answer_list - answer list from qmaster
471
* u_long32 gdi_command - commands what to do
474
* bool - true on success
478
* MT-NOTE: rqs_add_del_mod_via_gdi() is MT safe
480
*******************************************************************************/
481
bool rqs_add_del_mod_via_gdi(sge_gdi_ctx_class_t *ctx, lList *rqs_list, lList **answer_list,
482
u_long32 gdi_command)
486
DENTER(TOP_LAYER, "rqs_add_del_mod_via_gdi");
488
if (rqs_list != NULL) {
489
u_long32 operation = SGE_GDI_GET_OPERATION(gdi_command);
490
bool do_verify = (operation == SGE_GDI_MOD) || (operation == SGE_GDI_ADD
491
|| (operation == SGE_GDI_REPLACE)) ? true : false;
494
ret = rqs_list_verify_attributes(rqs_list, answer_list, false);
497
lList *my_answer_list = ctx->gdi(ctx, SGE_RQS_LIST, gdi_command, &rqs_list, NULL, NULL);
498
if (my_answer_list != NULL) {
499
answer_list_append_list(answer_list, &my_answer_list);
506
/****** resource_quota_qconf/rqs_modify_from_file() *****************
508
* rqs_modify_from_file() -- modifies resource quota sets from file
511
* bool rqs_modify_from_file(lList **answer_list, const char
512
* *filename, const char* name)
515
* This function allows to modify one or all resource quota sets from a file
518
* lList **answer_list - answer list
519
* const char *filename - filename with the resource quota sets to change
520
* const char* name - comma separated list of rule sets to change
523
* bool - true on success
527
* MT-NOTE: rqs_modify_from_file() is MT safe
529
*******************************************************************************/
530
bool rqs_modify_from_file(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *filename, const char* name)
533
u_long32 gdi_command = 0;
535
DENTER(TOP_LAYER, "rqs_modify_from_file");
536
if (filename != NULL) {
537
lList *rqs_list = NULL;
539
/* fields_out field does not work for rqs because of duplicate entry */
540
rqs_list = spool_flatfile_read_list(answer_list, RQS_Type, RQS_fields,
541
NULL, true, &qconf_rqs_sfi,
542
SP_FORM_ASCII, NULL, filename);
543
if (rqs_list != NULL) {
545
if (name != NULL && strlen(name) > 0 ) {
546
lList *selected_rqs_list = NULL;
547
lListElem *tmp_rqs = NULL;
548
lList *found_rqs_list = lCreateList("rqs_list", RQS_Type);
550
gdi_command = SGE_GDI_MOD | SGE_GDI_SET_ALL;
552
lString2List(name, &selected_rqs_list, RQS_Type, RQS_name, ", ");
553
for_each(tmp_rqs, selected_rqs_list) {
554
lListElem *found = rqs_list_locate(rqs_list, lGetString(tmp_rqs, RQS_name));
556
lAppendElem(found_rqs_list, lCopyElem(found));
558
sprintf(SGE_EVENT, MSG_RQSNOTFOUNDINFILE_SS, lGetString(tmp_rqs, RQS_name), filename);
559
answer_list_add(answer_list, SGE_EVENT, STATUS_ERROR1, ANSWER_QUALITY_ERROR);
560
lFreeList(&found_rqs_list);
564
lFreeList(&selected_rqs_list);
565
lFreeList(&rqs_list);
566
rqs_list = found_rqs_list;
568
gdi_command = SGE_GDI_REPLACE;
571
if (rqs_list != NULL) {
572
ret = rqs_add_del_mod_via_gdi(ctx, rqs_list, answer_list,
576
lFreeList(&rqs_list);