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: 2003 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
33
#include "sge_thread_jvm.h"
41
#include "basis_types.h"
42
#include "sge_qmaster_threads.h"
44
#include "sge_mt_init.h"
47
#include "sge_unistd.h"
48
#include "sge_answer.h"
49
#include "setup_qmaster.h"
50
#include "sge_security.h"
51
#include "sge_manop.h"
52
#include "sge_mtutil.h"
54
#include "sge_qmaster_process_message.h"
55
#include "sge_event_master.h"
56
#include "sge_persistence_qmaster.h"
57
#include "sge_reporting_qmaster.h"
58
#include "sge_qmaster_timed_event.h"
59
#include "sge_host_qmaster.h"
60
#include "sge_userprj_qmaster.h"
61
#include "sge_give_jobs.h"
62
#include "sge_all_listsL.h"
63
#include "sge_calendar_qmaster.h"
66
#include "qmaster_heartbeat.h"
68
#include "sge_spool.h"
69
#include "cl_commlib.h"
70
#include "sge_uidgid.h"
71
#include "sge_bootstrap.h"
72
#include "msg_common.h"
73
#include "msg_qmaster.h"
74
#include "msg_daemons_common.h"
75
#include "msg_utilib.h" /* remove once 'sge_daemonize_qmaster' did become 'sge_daemonize' */
77
#include "sge_qmod_qmaster.h"
78
#include "reschedule.h"
79
#include "sge_job_qmaster.h"
80
#include "sge_profiling.h"
81
#include "sgeobj/sge_conf.h"
83
#include "setup_path.h"
84
#include "sge_advance_reservation_qmaster.h"
85
#include "sge_sched_process_events.h"
86
#include "sge_follow.h"
87
#include "sge_thread_main.h"
88
#include "uti/sge_os.h"
89
#include "uti/sge_thread_ctrl.h"
90
#include "sge_advance_reservation_qmaster.h"
91
#include "uti/sge_string.h"
93
/****** qmaster/sge_qmaster_main/sge_gdi_kill_master() *************************
95
* sge_gdi_kill_master() -- Shutdown qmaster via GDI
98
* void sge_gdi_kill_master(sge_gdi_packet_class_t *packet, sge_gdi_task_class_t *task);
101
* Shutdown qmaster by means of a GDI request. This operation is only
102
* permitted for a user of type 'manager'.
105
* sge_gdi_packet_class_t *packet - request packet
106
* sge_gdi_task_class_t *task - request task
112
* MT-NOTE: sge_gdi_kill_master() is not MT safe.
114
* MT-NOTE: This is acceptable for now, because this function is currently
115
* MT-NOTE: only invoked from the message thread.
117
* TODO-AD: make this function thread safe. 'manop_is_manager()' is NOT MT
120
*******************************************************************************/
121
void sge_gdi_kill_master(sge_gdi_packet_class_t *packet, sge_gdi_task_class_t *task)
128
DENTER(GDI_LAYER, "sge_gdi_kill_master");
130
if (sge_gdi_packet_parse_auth_info(packet, &(task->answer_list), &uid, username, sizeof(username),
131
&gid, groupname, sizeof(groupname)) == -1) {
132
ERROR((SGE_EVENT, MSG_GDI_FAILEDTOEXTRACTAUTHINFO));
133
answer_list_add(&(task->answer_list), SGE_EVENT, STATUS_ENOMGR, ANSWER_QUALITY_ERROR);
138
DPRINTF(("uid/username = %d/%s, gid/groupname = %d/%s\n", (int) uid, username, (int) gid, groupname));
140
if (!manop_is_manager(username)) {
141
ERROR((SGE_EVENT, MSG_SHUTDOWN_SHUTTINGDOWNQMASTERREQUIRESMANAGERPRIVILEGES));
142
answer_list_add(&(task->answer_list), SGE_EVENT, STATUS_ENOMGR, ANSWER_QUALITY_ERROR);
147
if (sge_qmaster_shutdown_via_signal_thread(0) == 0) {
148
INFO((SGE_EVENT, MSG_SGETEXT_KILL_SSS, username, packet->host, prognames[QMASTER]));
149
answer_list_add(&(task->answer_list), SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO);
151
ERROR((SGE_EVENT, MSG_SGETEXT_KILL_FAILED_SSS, username, packet->host, prognames[QMASTER]));
152
answer_list_add(&(task->answer_list), SGE_EVENT, STATUS_ERROR1, ANSWER_QUALITY_ERROR);
157
} /* sge_gdi_kill_master() */
159
/****** qmaster/sge_qmaster_main/sge_daemonize_qmaster() ***************************
161
* sge_daemonize_qmaster() -- Turn qmaster into a daemon.
164
* static void sge_daemonize_qmaster(void)
167
* If the environment variable 'SGE_ND' is set, the functions does return
170
* First, we call 'fork()'. If the process was started as a shell command in
171
* the foreground, when the parent terminates, the shell thinks the command
172
* is done. This automatically runs the child process in the background.
173
* Also, the child inherits the process group ID from the parent but gets
174
* its own process ID. This guarantees that the child is not a process group
177
* We call 'setsid()' to create a new session. The process becomes the
178
* session leader of the new session, becomes the process group leader of a
179
* new process group, and has no controlling terminal.
181
* By calling 'fork()' a second time, we guarantee the the daemon (second
182
* child) is no longer a session leader, so it cannot acquire a controlling
183
* terminal. We must ignore 'SIGHUP' because when the session leader
184
* terminates (the first child), all processes in the session (our second
185
* child) receive the 'SIGHUP' signal.
187
* We close any open descriptors that are inherited from the process that
188
* executed 'sge_qmaster', normally a shell. We redirect 'stdin', 'stdout'
189
* and 'stderr' to '/dev/null'. The reason for opening these descriptors
190
* is so that any library function called by 'sge_qmaster' that assumes it
191
* can read from standard input or write to either standard ouput or
192
* standard error will not fail.
201
* MT-NOTE: sge_daemonize_qmaster() is not MT safe
203
*******************************************************************************/
204
bool sge_daemonize_qmaster()
209
DENTER(TOP_LAYER, "sge_daemonize_qmaster");
211
if (getenv("SGE_ND") != NULL) {
212
DPRINTF(("sge_qmaster is not daemonized\n"));
217
if((pid = fork()) != 0) {
219
CRITICAL((SGE_EVENT, MSG_PROC_FIRSTFORKFAILED_S , strerror(errno)));
221
exit(0); /* parent terminates */
226
signal(SIGHUP, SIG_IGN);
228
if((pid = fork()) != 0) {
230
CRITICAL((SGE_EVENT, MSG_PROC_SECONDFORKFAILED_S , strerror(errno)));
232
exit(0); /* child 1 terminates */
235
sge_close_all_fds(NULL);
237
failed_fd = sge_occupy_first_three();
238
if (failed_fd != -1) {
239
CRITICAL((SGE_EVENT, MSG_CANNOT_REDIRECT_STDINOUTERR_I, failed_fd));
245
} /* sge_daemonize_qmaster() */
247
/****** qmaster/sge_qmaster_main/sge_become_admin_user() ***************************
249
* sge_become_admin_user() -- Become admin user.
252
* static void sge_become_admin_user(void)
255
* Get admin user from bootstrap configuration. Set admin user and change
256
* the effective UID/GID to the admin user UID/GID.
258
* Note: The effective UID does determine file access permissions.
267
* MT-NOTE: sge_become_admin_user() is not MT safe
269
*******************************************************************************/
270
void sge_become_admin_user(const char *admin_user)
274
DENTER(TOP_LAYER, "sge_become_admin_user");
276
if (sge_set_admin_username(admin_user, str) == -1) {
277
CRITICAL((SGE_EVENT, str));
281
if (sge_switch2admin_user()) {
282
CRITICAL((SGE_EVENT, MSG_ERROR_CANTSWITCHTOADMINUSER));
288
} /* sge_become_admin_user() */
290
/****** qmaster/sge_qmaster_main/sge_exit_func() **********************************
292
* sge_exit_func() -- qmaster exit function
295
* static void sge_exit_func(int anExitValue)
298
* qmaster exit function. This function should be used BEFORE qmaster
299
* did change its working directory to be the spool directory. This
300
* exit function does NOT lock the qmaster lock file.
303
* int anExitValue - exit value
312
* MT-NOTE: sge_exit_func() is MT safe.
314
*******************************************************************************/
315
void sge_exit_func(void **ctx_ref, int anExitValue)
317
DENTER(TOP_LAYER, "sge_exit_func");
318
sge_gdi2_shutdown(ctx_ref);
322
} /* sge_exit_func */