~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/daemons/qmaster/sge_qmaster_threads.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
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
 
16
 * 
 
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.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2003 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
 
 
33
#include "sge_thread_jvm.h"
 
34
 
 
35
#include <signal.h>
 
36
#include <pthread.h>
 
37
#include <string.h>
 
38
#include <errno.h>
 
39
#include <fcntl.h>
 
40
 
 
41
#include "basis_types.h"
 
42
#include "sge_qmaster_threads.h"
 
43
#include "sgermon.h"
 
44
#include "sge_mt_init.h"
 
45
#include "sge_prog.h"
 
46
#include "sge_log.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"
 
53
#include "sge_lock.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"
 
64
#include "sge_time.h"
 
65
#include "lock.h"
 
66
#include "qmaster_heartbeat.h"
 
67
#include "shutdown.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' */
 
76
#include "sge.h"
 
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"
 
82
#include "qm_name.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"
 
92
 
 
93
/****** qmaster/sge_qmaster_main/sge_gdi_kill_master() *************************
 
94
*  NAME
 
95
*     sge_gdi_kill_master() -- Shutdown qmaster via GDI
 
96
*
 
97
*  SYNOPSIS
 
98
*     void sge_gdi_kill_master(sge_gdi_packet_class_t *packet, sge_gdi_task_class_t *task);
 
99
*
 
100
*  FUNCTION
 
101
*     Shutdown qmaster by means of a GDI request. This operation is only
 
102
*     permitted for a user of type 'manager'.
 
103
*
 
104
*  INPUTS
 
105
*     sge_gdi_packet_class_t *packet - request packet
 
106
*     sge_gdi_task_class_t *task     - request task
 
107
*
 
108
*  RESULT
 
109
*     void - none
 
110
*
 
111
*  NOTES
 
112
*     MT-NOTE: sge_gdi_kill_master() is not MT safe.
 
113
*     MT-NOTE:
 
114
*     MT-NOTE: This is acceptable for now, because this function is currently
 
115
*     MT-NOTE: only invoked from the message thread.
 
116
*
 
117
*     TODO-AD: make this function thread safe. 'manop_is_manager()' is NOT MT
 
118
*     TODO-AD  safe.
 
119
*
 
120
*******************************************************************************/
 
121
void sge_gdi_kill_master(sge_gdi_packet_class_t *packet, sge_gdi_task_class_t *task)
 
122
{
 
123
   uid_t uid;
 
124
   gid_t gid;
 
125
   char username[128];
 
126
   char groupname[128];
 
127
 
 
128
   DENTER(GDI_LAYER, "sge_gdi_kill_master");
 
129
 
 
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);
 
134
      DEXIT;
 
135
      return;
 
136
   }
 
137
 
 
138
   DPRINTF(("uid/username = %d/%s, gid/groupname = %d/%s\n", (int) uid, username, (int) gid, groupname));
 
139
 
 
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);
 
143
      DEXIT;
 
144
      return;
 
145
   }
 
146
 
 
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);
 
150
   } else {
 
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);
 
153
   }
 
154
 
 
155
   DEXIT;
 
156
   return;
 
157
} /* sge_gdi_kill_master() */
 
158
 
 
159
/****** qmaster/sge_qmaster_main/sge_daemonize_qmaster() ***************************
 
160
*  NAME
 
161
*     sge_daemonize_qmaster() -- Turn qmaster into a daemon. 
 
162
*
 
163
*  SYNOPSIS
 
164
*     static void sge_daemonize_qmaster(void) 
 
165
*
 
166
*  FUNCTION
 
167
*     If the environment variable 'SGE_ND' is set, the functions does return
 
168
*     immediately.
 
169
*
 
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
 
175
*     leader. 
 
176
*
 
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.
 
180
*
 
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.
 
186
*
 
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.
 
193
*
 
194
*  INPUTS
 
195
*     void - none 
 
196
*
 
197
*  RESULT
 
198
*     void - none 
 
199
*
 
200
*  NOTES
 
201
*     MT-NOTE: sge_daemonize_qmaster() is not MT safe 
 
202
*
 
203
*******************************************************************************/
 
204
bool sge_daemonize_qmaster()
 
205
{
 
206
   pid_t pid = -1;
 
207
   int failed_fd;
 
208
 
 
209
   DENTER(TOP_LAYER, "sge_daemonize_qmaster");
 
210
 
 
211
   if (getenv("SGE_ND") != NULL) {
 
212
      DPRINTF(("sge_qmaster is not daemonized\n"));
 
213
      DEXIT;
 
214
      return false;
 
215
   }
 
216
 
 
217
   if((pid = fork()) != 0) {
 
218
      if (pid < 0) {
 
219
         CRITICAL((SGE_EVENT, MSG_PROC_FIRSTFORKFAILED_S , strerror(errno)));
 
220
      }
 
221
      exit(0); /* parent terminates */
 
222
   }
 
223
 
 
224
   setsid();
 
225
 
 
226
   signal(SIGHUP, SIG_IGN);
 
227
 
 
228
   if((pid = fork()) != 0) {
 
229
      if (pid < 0) {
 
230
         CRITICAL((SGE_EVENT, MSG_PROC_SECONDFORKFAILED_S , strerror(errno)));
 
231
      }
 
232
      exit(0); /* child 1 terminates */
 
233
   }
 
234
 
 
235
   sge_close_all_fds(NULL);
 
236
 
 
237
   failed_fd = sge_occupy_first_three();
 
238
   if (failed_fd  != -1) {
 
239
      CRITICAL((SGE_EVENT, MSG_CANNOT_REDIRECT_STDINOUTERR_I, failed_fd));
 
240
      SGE_EXIT(NULL, 0);
 
241
   }
 
242
 
 
243
   DEXIT;
 
244
   return true;
 
245
} /* sge_daemonize_qmaster() */
 
246
 
 
247
/****** qmaster/sge_qmaster_main/sge_become_admin_user() ***************************
 
248
*  NAME
 
249
*     sge_become_admin_user() -- Become admin user. 
 
250
*
 
251
*  SYNOPSIS
 
252
*     static void sge_become_admin_user(void) 
 
253
*
 
254
*  FUNCTION
 
255
*     Get admin user from bootstrap configuration. Set admin user and change
 
256
*     the effective UID/GID to the admin user UID/GID. 
 
257
*
 
258
*     Note: The effective UID does determine file access permissions.
 
259
*
 
260
*  INPUTS
 
261
*     void - none
 
262
*
 
263
*  RESULT
 
264
*     void - none 
 
265
*
 
266
*  NOTES
 
267
*     MT-NOTE: sge_become_admin_user() is not MT safe 
 
268
*
 
269
*******************************************************************************/
 
270
void sge_become_admin_user(const char *admin_user)
 
271
{
 
272
   char str[1024];
 
273
 
 
274
   DENTER(TOP_LAYER, "sge_become_admin_user");
 
275
 
 
276
   if (sge_set_admin_username(admin_user, str) == -1) {
 
277
      CRITICAL((SGE_EVENT, str));
 
278
      SGE_EXIT(NULL, 1);
 
279
   }
 
280
 
 
281
   if (sge_switch2admin_user()) {
 
282
      CRITICAL((SGE_EVENT, MSG_ERROR_CANTSWITCHTOADMINUSER));
 
283
      SGE_EXIT(NULL, 1);
 
284
   }
 
285
 
 
286
   DEXIT;
 
287
   return;
 
288
} /* sge_become_admin_user() */
 
289
 
 
290
/****** qmaster/sge_qmaster_main/sge_exit_func() **********************************
 
291
*  NAME
 
292
*     sge_exit_func() -- qmaster exit function
 
293
*
 
294
*  SYNOPSIS
 
295
*     static void sge_exit_func(int anExitValue) 
 
296
*
 
297
*  FUNCTION
 
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.
 
301
*
 
302
*  INPUTS
 
303
*     int anExitValue - exit value 
 
304
*
 
305
*  RESULT
 
306
*     void - none 
 
307
*
 
308
*  EXAMPLE
 
309
*     ??? 
 
310
*
 
311
*  NOTES
 
312
*     MT-NOTE: sge_exit_func() is MT safe.
 
313
*
 
314
*******************************************************************************/
 
315
void sge_exit_func(void **ctx_ref, int anExitValue)
 
316
{
 
317
   DENTER(TOP_LAYER, "sge_exit_func");
 
318
   sge_gdi2_shutdown(ctx_ref);
 
319
 
 
320
   DEXIT;
 
321
   return;
 
322
} /* sge_exit_func */
 
323