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__*/
36
#include <sys/types.h>
39
#include "sge_answer.h"
40
#include "setup_path.h"
41
#include "sge_unistd.h"
42
#include "msg_common.h"
43
#include "msg_clients_common.h"
44
#include "sge_feature.h"
45
#include "sge_uidgid.h"
48
#include "parse_job_cull.h"
49
#include "parse_qsubL.h"
50
#include "parse_qsub.h"
51
#include "read_defaults.h"
52
#include "sgeobj/parse.h"
53
#include "sge_options.h"
54
#include "sgeobj/sge_job.h"
56
static char *get_cwd_defaults_file_path (lList **answer_list);
57
static void append_opts_from_default_files (u_long32 prog_number,
63
/****** sge/opt/opt_list_append_opts_from_default_files() *********************
65
* opt_list_append_opts_from_default_files() -- parse default files
68
* void opt_list_append_opts_from_default_files(
74
* This function reads the 3 defaults files if they exist and parses them
75
* into an options list.
78
* lList **pcmdline - pointer to SPA_Type list, if list is NULL, it is
79
* created if the files contain any options
80
* lList* - answer list, AN_Type or NULL if everything ok
82
* STATUS_ENOSUCHUSER - could not retrieve passwd info on me.user_name
83
* STATUS_EDISK - home directory for user is missing or cwd
84
* cannot be read or file could not be opened
86
* STATUS_EEXIST - (parse_script_file), (is just a warning)
87
* STATUS_EUNKNOWN - (parse_script_file), error opening or
88
* reading from existing file, (is just a warning)
89
* plus all other error stati returned by
90
* parse_script_file, see there
91
* char **envp - environment pointer
94
* MT-NOTE: opt_list_append_opts_from_default_files() is MT safe
95
*******************************************************************************/
96
void opt_list_append_opts_from_default_files(u_long32 prog_number,
97
const char* cell_root,
103
dstring req_file = DSTRING_INIT;
104
char *def_files[3 + 1];
106
DENTER(TOP_LAYER, "opt_list_append_opts_from_default_files");
108
lFreeList(answer_list);
110
/* the sge root defaults file */
111
get_root_file_path(&req_file, cell_root, SGE_COMMON_DEF_REQ_FILE);
112
def_files[0] = strdup(sge_dstring_get_string(&req_file));
115
* the defaults file in the user's home directory
117
get_user_home_file_path(&req_file, SGE_HOME_DEF_REQ_FILE, user, answer_list);
118
def_files[1] = strdup(sge_dstring_get_string(&req_file));
121
* the defaults file in the current working directory
123
def_files[2] = get_cwd_defaults_file_path(answer_list);
129
* now read all the defaults files, unaware of where they came from
131
append_opts_from_default_files(prog_number, pcmdline, answer_list, envp, def_files); /* MT-NOTE !!!! */
133
sge_dstring_free(&req_file);
138
/****** read_defaults/get_user_home_file_path() *****************************
140
* get_user_home_file_path() -- get absolut path name to file in user
144
* char *get_user_home_file_path (lList **answer_list)
147
* This function returns the path to the file in the user's home
151
* dstring - computed absoult filename
152
* const char *filename - file name
153
* const char *user - user name
154
* lList* - answer list, AN_Type or NULL if everything ok
156
* STATUS_ENOSUCHUSER - could not retrieve passwd info on me.user_name
157
* STATUS_EDISK - home directory for user is missing or cwd
158
* cannot be read or file could not be opened
159
* (is just a warning)
160
* STATUS_EEXIST - (parse_script_file), (is just a warning)
161
* STATUS_EUNKNOWN - (parse_script_file), error opening or
162
* reading from existing file, (is just a warning)
163
* plus all other error stati returned by
164
* parse_script_file, see there
167
* bool - true or false
169
* MT-NOTE: get_user_home_file_path() is MT safe
170
*******************************************************************************/
171
bool get_user_home_file_path(dstring *absolut_filename, const char *filename, const char *user, lList **answer_list)
175
DENTER (TOP_LAYER, "get_user_home_file_path");
177
if (absolut_filename != NULL && filename != NULL) {
179
sge_dstring_clear(absolut_filename);
181
if (get_user_home(absolut_filename, user, answer_list)) {
182
sge_dstring_append(absolut_filename, "/");
183
sge_dstring_append(absolut_filename, filename);
191
/****** sge/opt/get_cwd_defaults_file_path() ***********************************
193
* get_cwd_defaults_file_path() -- find cwd default file path
196
* char *get_cwd_defaults_file_path ()
199
* This function returns the path of the defaults file in the current working
203
* lList* - answer list, AN_Type or NULL if everything ok
205
* STATUS_ENOSUCHUSER - could not retrieve passwd info on me.user_name
206
* STATUS_EDISK - home directory for user is missing or cwd
207
* cannot be read or file could not be opened
208
* (is just a warning)
209
* STATUS_EEXIST - (parse_script_file), (is just a warning)
210
* STATUS_EUNKNOWN - (parse_script_file), error opening or
211
* reading from existing file, (is just a warning)
212
* plus all other error stati returned by
213
* parse_script_file, see there
214
* char * - cwd defaults file name with absolute path
216
* MT-NOTE: get_cwd_defaults_file_path() is MT safe
217
*******************************************************************************/
218
static char *get_cwd_defaults_file_path(lList **answer_list)
220
char cwd[SGE_PATH_MAX + 1];
224
DENTER (TOP_LAYER, "get_cwd_defaults_file_name");
226
if (!getcwd(cwd, sizeof(cwd))) {
227
sprintf(str, MSG_FILE_CANTREADCURRENTWORKINGDIR);
228
answer_list_add(answer_list, str, STATUS_EDISK, ANSWER_QUALITY_ERROR);
231
file = (char *)malloc(strlen(cwd) + strlen(SGE_HOME_DEF_REQ_FILE) + 2);
234
if (*file && (file[strlen(file) - 1] != '/')) {
237
strcat(file, SGE_HOME_DEF_REQ_FILE);
242
/****** sge/opt/append_opts_from_default_files() *******************************
244
* append_opts_from_default_files() -- parse default files
247
* void append_opts_from_default_files(lList **pcmdline,
248
* lList **answer_list
253
* This function reads the defaults files pointed to by def_files[] if they
254
* exist and parses them into an options list.
257
* lList **pcmdline - pointer to SPA_Type list, if list is NULL, it is
258
* created if the files contain any options
259
* lList* - answer list, AN_Type or NULL if everything ok
261
* STATUS_ENOSUCHUSER - could not retrieve passwd info on me.user_name
262
* STATUS_EDISK - home directory for user is missing or cwd
263
* cannot be read or file could not be opened
264
* (is just a warning)
265
* STATUS_EEXIST - (parse_script_file), (is just a warning)
266
* STATUS_EUNKNOWN - (parse_script_file), error opening or
267
* reading from existing file, (is just a warning)
268
* plus all other error stati returned by
269
* parse_script_file, see there
270
* char **envp - environment pointer
271
* char **def_files - paths to default files
273
*******************************************************************************/
274
static void append_opts_from_default_files(u_long32 prog_number,
287
DENTER(TOP_LAYER, "append_opts_from_default_files");
289
for (pstr = def_files; *pstr; pstr++) {
292
if (SGE_STAT(*pstr, &buf)<0) {
293
DPRINTF(("-- defaults file %s does not exist\n", *pstr));
298
for (ppstr = def_files; *ppstr != *pstr; ppstr++) {
299
if (!sge_filecmp(*ppstr, *pstr)) {
300
DPRINTF(("-- skipping %s as defaults file - already read as %s\n",
309
DPRINTF(("-- defaults file: %s\n", *pstr));
311
alp = parse_script_file(prog_number, *pstr, "", pcmdline, envp,
312
FLG_HIGHER_PRIOR | FLG_USE_NO_PSEUDOS);
316
answer_quality_t quality;
318
status = lGetUlong(aep, AN_status);
319
quality = (answer_quality_t)lGetUlong(aep, AN_quality);
321
if (quality == ANSWER_QUALITY_ERROR) {
322
DPRINTF(("%s", lGetString(aep, AN_text)));
323
if (status == STATUS_EDISK) {
325
** we turn this error into a warning here
327
quality = ANSWER_QUALITY_WARNING;
332
DPRINTF(("Warning: Error: %s\n", lGetString(aep, AN_text)));
334
answer_list_add(answer_list, lGetString(aep, AN_text), status,
340
for (pstr = def_files; *pstr; free(*pstr++)) {
348
for (pstr = def_files; *pstr; free(*pstr++)) {
354
/****** sge/opt/opt_list_append_opts_from_qsub_cmdline() **********************
356
* opt_list_append_opts_from_qsub_cmdline() -- parse opts from cmd line
359
* void opt_list_append_opts_from_qsub_cmdline(lList **opts_cmdline,
360
* lList **answer_list,
365
* Parse options from the qsub commandline given by "argv" and store
366
* the parsed objects in "opts_cmdline". If an error occures store
367
* the error/warning messages in the "answer_list".
368
* "envp" is a pointer to the process environment.
372
* lList **opts_cmdline - command line options
373
* lList **answer_list - AN_Type list
374
* char **argv - Argumente
375
* char **envp - Environment
379
*******************************************************************************/
380
void opt_list_append_opts_from_qsub_cmdline(u_long32 prog_number,
381
lList **opts_cmdline,
386
lFreeList(answer_list);
387
*answer_list = cull_parse_cmdline(prog_number, argv, envp, opts_cmdline, FLG_USE_PSEUDOS);
390
/****** sge/opt/opt_list_append_opts_from_qalter_cmdline() ********************
392
* opt_list_append_opts_from_qalter_cmdline() -- parse opts from cmd line
395
* void opt_list_append_opts_from_qalter_cmdline(lList **opts_cmdline,
396
* lList **answer_list,
401
* Parse options from the qalter commandline given by "argv" and store
402
* the parsed objects in "opts_cmdline". If an error occures store
403
* the error/warning messages in the "answer_list".
404
* "envp" is a pointer to the process environment.
408
* lList **opts_cmdline - command line options
409
* lList **answer_list - AN_Type list
410
* char **argv - Argumente
411
* char **envp - Environment
415
*******************************************************************************/
416
void opt_list_append_opts_from_qalter_cmdline(u_long32 prog_number,
417
lList **opts_cmdline,
422
lFreeList(answer_list);
423
*answer_list = cull_parse_cmdline(prog_number, argv, envp, opts_cmdline,
424
FLG_USE_PSEUDOS | FLG_QALTER);
427
/****** sge/opt/opt_list_append_opts_from_script() ****************************
429
* opt_list_append_opts_from_script() -- parse opts from scriptfile
432
* void opt_list_append_opts_from_script(lList **opts_scriptfile,
433
* lList **answer_list,
434
* const lList *opts_cmdline,
438
* This function parses the commandline options which are embedded
439
* in scriptfile (jobscript) and stores the parsed objects in
440
* opts_scriptfile. The filename of the scriptfile has to be
441
* contained in the list "opts_cmdline" which has been previously i
442
* created with opt_list_append_opts_from_*_cmdline(). "answer_list"
443
* will be used to store error/warning messages.
444
* "envp" is a pointer to the process environment.
447
* lList **opts_scriptfile - embedded command line options
448
* lList **answer_list - AN_Type list
449
* const lList *opts_cmdline - Argumente
450
* char **envp - Environment
454
*******************************************************************************/
455
void opt_list_append_opts_from_script(u_long32 prog_number,
456
lList **opts_scriptfile,
458
const lList *opts_cmdline,
461
lListElem *script_option = NULL;
462
lListElem *c_option = NULL;
463
const char *scriptfile = NULL;
464
const char *prefix = NULL;
466
script_option = lGetElemStr(opts_cmdline, SPA_switch, STR_PSEUDO_SCRIPT);
467
if (script_option != NULL) {
468
scriptfile = lGetString(script_option, SPA_argval_lStringT);
470
c_option = lGetElemStr(opts_cmdline, SPA_switch, "-C");
471
if (c_option != NULL) {
472
prefix = lGetString(c_option, SPA_argval_lStringT);
474
prefix = default_prefix;
476
lFreeList(answer_list);
477
*answer_list = parse_script_file(prog_number, scriptfile, prefix, opts_scriptfile,
478
envp, FLG_DONT_ADD_SCRIPT);
481
/****** sge/opt/opt_list_append_opts_from_script_path() ************************
483
* opt_list_append_opts_from_script_path() -- parse opts from scriptfile
486
* void opt_list_append_opts_from_script_path(lList **opts_scriptfile,
487
* char *path, lList **answer_list,
488
* const lList *opts_cmdline,
492
* This function parses the commandline options which are embedded
493
* in scriptfile (jobscript) and stores the parsed objects in
494
* opts_scriptfile. The filename of the scriptfile has to be
495
* contained in the list "opts_cmdline" which has been previously i
496
* created with opt_list_append_opts_from_*_cmdline(). If the filename of
497
* the scriptfile is not an absolute path, "path" will be prepended to it.
498
* "answer_list" will be used to store error/warning messages.
499
* "envp" is a pointer to the process environment.
502
* lList **opts_scriptfile - embedded command line options
503
* const char *path - the root path for the script file
504
* lList **answer_list - AN_Type list
505
* const lList *opts_cmdline - Argumente
506
* char **envp - Environment
510
*******************************************************************************/
511
void opt_list_append_opts_from_script_path(u_long32 prog_number,
512
lList **opts_scriptfile,
515
const lList *opts_cmdline,
518
lListElem *script_option = NULL;
519
lListElem *c_option = NULL;
520
const char *scriptfile = NULL;
521
char *scriptpath = NULL;
522
const char *prefix = NULL;
524
script_option = lGetElemStr(opts_cmdline, SPA_switch, STR_PSEUDO_SCRIPT);
526
if (script_option != NULL) {
527
scriptfile = lGetString(script_option, SPA_argval_lStringT);
529
/* If the scriptfile path isn't absolute (which includes starting with
530
$HOME), make it absolute relative to the given path.
531
If the script or path is NULL, let parse_script_file() catch it. */
532
if ((scriptfile != NULL) && (path != NULL) && (scriptfile[0] != '/') &&
533
(strncmp (scriptfile, "$HOME/", 6) != 0) &&
534
(strcmp (scriptfile, "$HOME") != 0)) {
535
/* Malloc space for the path, the filename, the \0, and perhaps a / */
536
scriptpath = (char *)malloc(sizeof(char) * (strlen(path) + strlen(scriptfile) + 2));
537
strcpy (scriptpath, path);
539
/* If the last character is not a slash, add one. */
540
if (scriptpath[strlen (scriptpath) - 1] != '/') {
541
strcat (scriptpath, "/");
544
strcat (scriptpath, scriptfile);
546
scriptpath = strdup (scriptfile);
550
c_option = lGetElemStr(opts_cmdline, SPA_switch, "-C");
552
if (c_option != NULL) {
553
prefix = lGetString(c_option, SPA_argval_lStringT);
555
prefix = default_prefix;
558
lFreeList(answer_list);
560
*answer_list = parse_script_file(prog_number, scriptpath, prefix, opts_scriptfile,
561
envp, FLG_DONT_ADD_SCRIPT);
566
/****** sge/opt/opt_list_merge_command_lines() ********************************
568
* opt_list_merge_command_lines() -- merge commandlines together
571
* void opt_list_merge_command_lines(lList **opts_all,
572
* lList **opts_defaults,
573
* lList **opts_scriptfile,
574
* lList **opts_cmdline)
577
* Merge "opts_defaults", "opts_scriptfile" and "opts_cmdline" into
580
* Options to a sge submit can come from different sources:
581
* - default settings (sge/sge_request)
582
* - special comments in scriptfiles (override default settings)
583
* - command line options (override default settings and special
587
* lList **opts_all - destination commandline
588
* lList **opts_defaults - opts from default files
589
* lList **opts_scriptfile - opts from the script
590
* lList **opts_cmdline - commandline options
594
*******************************************************************************/
595
void opt_list_merge_command_lines(lList **opts_all,
596
lList **opts_defaults,
597
lList **opts_scriptfile,
598
lList **opts_cmdline)
601
* Order is very important here
603
if (*opts_defaults != NULL) {
604
if (*opts_all == NULL) {
605
*opts_all = *opts_defaults;
607
lAddList(*opts_all, opts_defaults);
609
*opts_defaults = NULL;
611
if (*opts_scriptfile != NULL) {
612
if (*opts_all == NULL) {
613
*opts_all = *opts_scriptfile;
615
/* Override the queue (-q) values from defaults */
616
lOverrideStrList(*opts_all, *opts_scriptfile, SPA_switch, "-q");
618
*opts_scriptfile = NULL;
620
if (*opts_cmdline != NULL) {
621
if (*opts_all == NULL) {
622
*opts_all = *opts_cmdline;
624
/* Override queue (-q) values from both defaults and scriptfile */
625
lOverrideStrList(*opts_all, *opts_cmdline, SPA_switch, "-q");
627
*opts_cmdline = NULL;
630
/* If -ar was requested add -w if it was not explicit set */
631
if (lGetElemStr(*opts_all, SPA_switch, "-ar") != NULL) {
632
if (lGetElemStr(*opts_all, SPA_switch, "-w") == NULL) {
633
lListElem *ep_opt = sge_add_arg(opts_all, r_OPT, lIntT, "-w", "e");
634
lSetInt(ep_opt, SPA_argval_lIntT, ERROR_VERIFY);
639
/****** sge/opt/opt_list_has_X() **********************************************
641
* opt_list_has_X() -- is a certail option contained in list
644
* bool opt_list_has_X(lList *opts, const char *option)
647
* This function returns true (1) if the given 'option'
648
* (e.g. "-help") is contained in the list 'opts'.
651
* lList *opts - SPA_Type list
652
* const char *option - switch name
655
* bool - found switch?
660
* sge/opt/opt_list_is_X_true()
661
*******************************************************************************/
662
bool opt_list_has_X(lList *opts, const char *option)
667
opt = lGetElemStr(opts, SPA_switch, option);
674
/****** sge/opt/opt_list_is_X_true() ******************************************
676
* opt_list_is_X_true() -- check the state of a boolean switch
679
* bool opt_list_is_X_true(lList *opts, const char *option)
682
* This function returns true (1) if the given 'option'
683
* (e.g. "-b") is contained in the list 'opts' and if
684
* it was set to 'true'. If the value of the boolean switch
685
* is false than the function will also return false (0).
688
* lList *opts - SPA_Type list
689
* const char *option - switch name
692
* bool - found switch with value 'true'
697
* sge/opt/opt_list_has_X()
698
******************************************************************************/
699
bool opt_list_is_X_true(lList *opts, const char *option)
704
opt = lGetElemStr(opts, SPA_switch, option);
706
ret = (lGetInt(opt, SPA_argval_lIntT) == 1) ? true : false;
711
/****** read_defaults/get_root_file_path() *************************************
713
* get_root_file_path() -- creates absolute filename for file in SGE_ROOT
716
* const char* get_root_file_path(dstring *absolut_filename, const char
717
* *cell_root, const char *filename)
720
* Sets the absolut filename of a file in SGE_ROOT in the given dstring
723
* dstring *absolut_filename - created absolut filename
724
* const char *cell_root - sge root patch
725
* const char *filename - file name
728
* const char* - pointer to filename in absolut_filename
731
* MT-NOTE: get_root_file_path() is MT safe
733
*******************************************************************************/
734
const char *get_root_file_path(dstring *absolut_filename, const char *cell_root, const char *filename)
736
DENTER (TOP_LAYER, "get_root_file_path");
738
sge_dstring_sprintf(absolut_filename, "%s/%s", cell_root, filename);
740
DRETURN(sge_dstring_get_string(absolut_filename));
743
/****** read_defaults/get_user_home() ******************************************
745
* get_user_home() -- get absoult filename in users home dir
748
* bool get_user_home(dstring *home_dir, const char *user, lList
752
* Sets the absolut filename of a file in the users home directory
755
* dstring *home_dir - created absolut filename
756
* const char *user - user
757
* lList **answer_list - answer list
760
* bool - true on success
764
* MT-NOTE: get_user_home() is MT safe
766
*******************************************************************************/
767
bool get_user_home(dstring *home_dir, const char *user, lList **answer_list)
771
DENTER(TOP_LAYER, "get_user_home");
773
if (home_dir != NULL) {
775
struct passwd pw_struct;
779
size = get_pw_buffer_size();
780
buffer = sge_malloc(size);
781
pwd = sge_getpwnam_r(user, &pw_struct, buffer, size);
783
answer_list_add_sprintf(answer_list, STATUS_ENOSUCHUSER,
784
ANSWER_QUALITY_ERROR, MSG_USER_INVALIDNAMEX_S, user);
787
if (ret && !pwd->pw_dir) {
788
answer_list_add_sprintf(answer_list, STATUS_EDISK, ANSWER_QUALITY_ERROR,
789
MSG_USER_NOHOMEDIRFORUSERX_S, user);
793
sge_dstring_copy_string(home_dir, pwd->pw_dir);
797
/* should never happen */