~ubuntu-branches/ubuntu/precise/torque/precise-updates

« back to all changes in this revision

Viewing changes to src/server/pbsd_main.c

  • Committer: Bazaar Package Importer
  • Author(s): Dominique Belhachemi
  • Date: 2010-05-17 20:56:46 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100517205646-yjsoqs5r1s9xpnu9
Tags: upstream-2.4.8+dfsg
ImportĀ upstreamĀ versionĀ 2.4.8+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
 
87
87
#include <pbs_config.h>   /* the master config generated by configure */
88
88
 
 
89
#include <sys/wait.h>
 
90
#include <utime.h>
89
91
#include <sys/types.h>
90
92
#include <sys/stat.h>
91
93
#if (PLOCK_DAEMONS & 1)
108
110
#include "log.h"
109
111
#include "server_limits.h"
110
112
#include "attribute.h"
111
 
#include "job.h"
 
113
#include "pbs_job.h"
112
114
#include "queue.h"
113
115
#include "server.h"
114
116
#include "pbs_nodes.h"
123
125
#include "dis_init.h"
124
126
#include "batch_request.h"
125
127
#include "pbs_proto.h"
 
128
#ifdef USE_HA_THREADS
 
129
#include <pthread.h>
 
130
#endif /* USE_HA_THREADS */
126
131
 
127
132
 
128
133
#define TSERVER_HA_CHECK_TIME  1  /* 1 second sleep time between checks on the lock file for high availability */
141
146
extern void acct_close(void);
142
147
extern int  svr_startjob A_((job *, struct batch_request *, char *, char *));
143
148
extern int RPPConfigure(int, int);
 
149
extern void acct_cleanup(long);
144
150
#ifdef NO_SIGCHLD
145
151
extern void check_children();
146
152
#endif
147
153
 
 
154
#ifndef MAX_LINE
 
155
#define MAX_LINE 1024
 
156
#endif
 
157
#ifndef MAX_PATH_LEN
 
158
#define MAX_PATH_LEN 256
 
159
#endif
 
160
#ifndef MAX_NAME
 
161
#define MAX_NAME 64
 
162
#endif
 
163
#ifndef DEF_USPERSECOND
 
164
#define DEF_USPERSECOND 1000000
 
165
#endif
 
166
#ifndef bool_t
 
167
#define bool_t unsigned char
 
168
#endif
 
169
#ifndef SUCCESS
 
170
#define SUCCESS 1
 
171
#endif 
 
172
#ifndef FAILURE
 
173
#define FAILURE 0
 
174
#endif
 
175
#define ISEMPTYSTR(STR)  ((STR)[0] == '\0')
 
176
#ifndef MAX_CMD_ARGS
 
177
#define MAX_CMD_ARGS 10
 
178
#endif
 
179
 
 
180
#ifdef USE_HA_THREADS
 
181
static void lock_out_ha A_(());
 
182
#else
 
183
static void lock_out A_((int,int));
 
184
static int try_lock_out A_((int,int));
 
185
#endif
148
186
 
149
187
/* external data items */
150
188
 
151
189
extern int    svr_chngNodesfile;
152
190
extern int    svr_totnodes;
153
191
 
 
192
/* External Functions */
 
193
 
 
194
extern int    get_svr_attr (int);
 
195
 
154
196
/* Local Private Functions */
155
197
 
156
198
static int    get_port A_((char *, unsigned int *, pbs_net_t *));
157
 
static time_t next_task A_(());
158
 
static int    start_hot_jobs();
159
 
static void   lock_out A_((int, int));
160
 
static int   try_lock_out A_((int, int));
 
199
static int    daemonize_server A_((int, pid_t *));
 
200
int mutex_lock A_((mutex_t *));
 
201
int mutex_unlock A_((mutex_t *));
 
202
int get_file_info A_((char *,unsigned long *,long *,bool_t *,bool_t *));
 
203
int get_full_path A_((char *,char *,int));
 
204
int svr_restart();
 
205
void          restore_attr_default A_((struct attribute *));
161
206
 
162
207
/* Global Data Items */
163
208
 
164
 
int           high_availability_mode = FALSE;
 
209
int          high_availability_mode = FALSE;
165
210
char        *acct_file = NULL;
166
211
char        *log_file  = NULL;
167
212
char        *path_home = PBS_SERVER_HOME;
168
213
char        *path_acct;
169
214
char         path_log[MAXPATHLEN + 1];
170
 
char        *path_priv;
 
215
char        *path_priv = NULL;
171
216
char        *path_arrays;
172
217
char        *path_jobs;
173
218
char        *path_queues;
174
219
char        *path_spool;
175
 
char        *path_svrdb;
 
220
char        *path_svrdb = NULL;
176
221
char        *path_svrdb_new;
177
 
char         *path_track;
 
222
char        *path_svrlog;
 
223
char        *path_track;
178
224
char        *path_nodes;
179
225
char        *path_nodes_new;
180
226
char        *path_nodestate;
181
227
char        *path_nodenote;
182
228
char        *path_nodenote_new;
 
229
char        *path_checkpoint;
 
230
char        *ArgV[MAX_CMD_ARGS];
183
231
extern char    *msg_daemonname;
184
232
extern char *msg_info_server; /* Server information message   */
185
233
extern int pbs_errno;
193
241
unsigned int pbs_server_port_dis;
194
242
listener_connection listener_conns[MAXLISTENERS];
195
243
int  queue_rank = 0;
 
244
int a_opt_init = -1;
 
245
/* HA global data items */
 
246
long      HALockCheckTime = 0;
 
247
long      HALockUpdateTime = 0;
 
248
char      HALockFile[MAXPATHLEN+1];
 
249
char      OriginalPath[MAXPATHLEN+1];
 
250
mutex_t   EUIDMutex; /* prevents thread from trying to lock the file 
 
251
                        from a different euid */
 
252
int HALockFD;
 
253
/* END HA global data items */
196
254
 
197
255
struct server server;  /* the server structure */
198
256
char         server_host[PBS_MAXHOSTNAME + 1]; /* host_name */
209
267
tlist_head task_list_immed;
210
268
tlist_head task_list_timed;
211
269
tlist_head task_list_event;
 
270
pid_t    sid;
212
271
 
213
272
time_t  time_now = 0;
214
273
 
283
342
    {
284
343
    /* FAILURE */
285
344
 
 
345
    /* This error case may be associated with IP communication
 
346
     * problems such as may happen with multi-homed servers.
 
347
     */
 
348
 
286
349
    if (LOGLEVEL >= 1)
287
350
      {
288
351
 
290
353
 
291
354
      extern tree *streams;        /* tree of stream numbers */
292
355
 
293
 
      /* NOTE:  report IP associated w/stream - NYI */
294
 
 
295
356
      node = tfind((u_long)stream, &streams);
296
357
 
297
 
      sprintf(log_buffer, "corrupt rpp request received on stream %d (node: %s) - invalid protocol - rc=%d (%s)",
 
358
      sprintf(log_buffer, "corrupt rpp request received on stream %d (node: \"%s\", %s) - invalid protocol - rc=%d (%s)",
298
359
              stream,
299
360
              (node != NULL) ? node->nd_name : "NULL",
 
361
              netaddr(rpp_getaddr(stream)),
300
362
              ret,
301
363
              dis_emsg[ret]);
302
364
 
479
541
  }  /* END PBSShowUsage() */
480
542
 
481
543
 
482
 
 
483
 
 
484
 
 
485
 
/*
486
 
 * main - the initialization and main loop of pbs_daemon
 
544
/**
 
545
 * parse_command_line
 
546
 *
 
547
 * parse the parameters from the command line
487
548
 */
488
 
 
489
 
int main(
490
 
 
491
 
  int   argc,    /* I */
492
 
  char *argv[])  /* I */
493
 
 
 
549
void parse_command_line(int argc, char *argv[])
494
550
  {
 
551
  extern int   optind;
 
552
  extern char *optarg;
 
553
  char *pc = NULL;
495
554
  int  c;
496
 
  FILE  *dummyfile;
497
555
  int  i;
498
 
  int  lockfds;
499
 
  int  rppfd;   /* fd to receive is HELLO's */
500
 
  int  privfd;  /* fd to send is messages */
501
 
  uint  tryport;
502
 
  char  lockfile[MAXPATHLEN + 1];
503
 
  char *pc = NULL;
504
 
  char  *ptr;
505
 
  job *pjob;
506
 
  pbs_queue *pque;
 
556
 
 
557
  char   EMsg[1024];
507
558
  char *servicename = NULL;
508
559
  pbs_net_t def_pbs_server_addr;
509
 
  pid_t  sid;
510
 
  long  *state;
511
 
  time_t waittime;
512
 
  time_t last_jobstat_time;
513
 
  int    when;
514
560
  pbs_net_t listener_addr;
515
561
  unsigned int listener_port;
516
562
 
517
 
  void ping_nodes A_((struct work_task *));
518
 
  void check_nodes A_((struct work_task *));
519
 
  void check_log A_((struct work_task *));
520
 
 
521
 
  char   EMsg[1024];
522
 
 
523
563
  static struct
524
564
    {
525
565
    char *it_name;
534
574
    { "", RECOV_Invalid }
535
575
    };
536
576
 
537
 
  extern int   optind;
538
 
  extern char *optarg;
539
 
  extern char *msg_svrdown; /* log message   */
540
 
  extern char *msg_startup1; /* log message   */
541
 
  extern char *msg_startup2; /* log message   */
542
 
 
543
 
  ProgName = argv[0];
544
 
 
545
 
  strcpy(pbs_current_user, "PBS_Server");
546
 
 
547
 
  msg_daemonname = strdup(pbs_current_user);
548
 
 
549
 
  /* set standard umask */
550
 
 
551
 
  umask(022);
552
 
 
553
 
  time_now = time((time_t *)0);
554
 
 
555
 
  last_jobstat_time = time_now;
556
 
 
557
 
  /* close files for security purposes */
558
 
 
559
 
  i = sysconf(_SC_OPEN_MAX);
560
 
 
561
 
  while (--i < 2)
562
 
    close(i);  /* close any file desc left open by parent */
563
 
 
564
 
  /* find out who we are (hostname) */
565
 
 
566
 
  server_host[0] = '\0';
567
 
 
568
 
  EMsg[0] = '\0';
569
 
 
570
 
  if (((server_host[0] == '\0') && (gethostname(server_host, PBS_MAXHOSTNAME) == -1)) ||
571
 
      (get_fullhostname(server_host, server_host, PBS_MAXHOSTNAME, EMsg) == -1))
572
 
    {
573
 
    /* FAILURE - shutdown */
574
 
 
575
 
    if (EMsg[0] != '\0')
576
 
      {
577
 
      char tmpLine[1024];
578
 
 
579
 
      snprintf(tmpLine, sizeof(tmpLine), "unable to determine local server hostname - %s",
580
 
               EMsg);
581
 
 
582
 
      log_err(-1, "pbsd_main", tmpLine);
583
 
      }
584
 
    else
585
 
      {
586
 
      log_err(-1, "pbsd_main", "unable to determine local server hostname");
587
 
      }
588
 
 
589
 
    exit(1);
590
 
    }
591
 
 
592
 
  /* initialize service port numbers for self, Scheduler, and MOM */
593
 
 
594
 
  ptr = getenv("PBS_BATCH_SERVICE_PORT");
595
 
 
596
 
  if (ptr != NULL)
597
 
    {
598
 
    pbs_server_port_dis = (int)strtol(ptr, NULL, 10);
599
 
    }
600
 
 
601
 
  if (pbs_server_port_dis <= 0)
602
 
    {
603
 
    pbs_server_port_dis = get_svrport(
604
 
                            PBS_BATCH_SERVICE_NAME,
605
 
                            "tcp",
606
 
                            PBS_BATCH_SERVICE_PORT_DIS);
607
 
    }
608
 
 
609
 
  ptr = getenv("PBS_SCHEDULER_SERVICE_PORT");
610
 
 
611
 
  if (ptr != NULL)
612
 
    {
613
 
    pbs_scheduler_port = (int)strtol(ptr, NULL, 10);
614
 
    }
615
 
 
616
 
  if (pbs_scheduler_port <= 0)
617
 
    {
618
 
    pbs_scheduler_port = get_svrport(
619
 
                           PBS_SCHEDULER_SERVICE_NAME,
620
 
                           "tcp",
621
 
                           PBS_SCHEDULER_SERVICE_PORT);
622
 
    }
623
 
 
624
 
  ptr = getenv("PBS_MOM_SERVICE_PORT");
625
 
 
626
 
  if (ptr != NULL)
627
 
    {
628
 
    pbs_mom_port = (int)strtol(ptr, NULL, 10);
629
 
    }
630
 
 
631
 
  if (pbs_mom_port <= 0)
632
 
    {
633
 
    pbs_mom_port = get_svrport(
634
 
                     PBS_MOM_SERVICE_NAME,
635
 
                     "tcp",
636
 
                     PBS_MOM_SERVICE_PORT);
637
 
    }
638
 
 
639
 
  ptr = getenv("PBS_MANAGER_SERVICE_PORT");
640
 
 
641
 
  if (ptr != NULL)
642
 
    {
643
 
    pbs_rm_port = (int)strtol(ptr, NULL, 10);
644
 
    }
645
 
 
646
 
  if (pbs_rm_port <= 0)
647
 
    {
648
 
    pbs_rm_port = get_svrport(
649
 
                    PBS_MANAGER_SERVICE_NAME,
650
 
                    "tcp",
651
 
                    PBS_MANAGER_SERVICE_PORT);
652
 
    }
653
 
 
654
 
  strcpy(server_name, server_host); /* by default server = host */
655
 
 
656
 
  pbs_server_addr    = get_hostaddr(server_host);
657
 
  pbs_mom_addr       = pbs_server_addr;   /* assume on same host */
658
 
  pbs_scheduler_addr = pbs_server_addr;   /* assume on same host */
659
 
 
660
 
  clear_listeners();  /* make sure listeners is cleared */
661
 
 
662
 
  /* parse the parameters from the command line */
 
577
 
663
578
 
664
579
  while ((c = getopt(argc, argv, "A:a:d:DfhH:L:l:M:p:R:S:t:v-:")) != -1)
665
580
    {
734
649
 
735
650
          exit(1);
736
651
          }
 
652
        a_opt_init = server.sv_attr[(int)SRV_ATR_scheduling].at_val.at_long;
737
653
 
738
654
        break;
739
655
 
998
914
 
999
915
    exit(1);
1000
916
    }
1001
 
 
1002
 
  /* if we are not running with real and effective uid of 0, forget it */
1003
 
 
1004
 
  if ((getuid() != 0) || (geteuid() != 0))
1005
 
    {
1006
 
    fprintf(stderr, "%s: must be run by root\n",
1007
 
            ProgName);
1008
 
 
1009
 
    return(1);
1010
 
    }
1011
 
 
1012
 
 
1013
 
  /* make sure no other server is running with this home directory */
1014
 
 
1015
 
  sprintf(lockfile, "%s/%s/server.lock",
1016
 
          path_home,
1017
 
          PBS_SVR_PRIVATE);
1018
 
 
1019
 
  if ((lockfds = open(lockfile, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0)
1020
 
    {
1021
 
    sprintf(log_buffer, "%s: unable to open lock file '%s'",
1022
 
            msg_daemonname,
1023
 
            lockfile);
1024
 
 
1025
 
    fprintf(stderr, "%s\n",
1026
 
            log_buffer);
1027
 
 
1028
 
    log_err(errno, msg_daemonname, log_buffer);
1029
 
 
1030
 
    exit(2);
1031
 
    }
1032
 
 
1033
 
 
1034
 
  if (high_availability_mode)
1035
 
    {
1036
 
    /* This will allow multiple instance of the pbs_server to be
1037
 
     * running.  This must be done before setting up the client
1038
 
     * sockets interface, reading the config file, and contacting
1039
 
     * the compute nodes.
1040
 
     */
1041
 
 
1042
 
    if (TDoBackground == 1)
1043
 
      {
1044
 
      if (fork() > 0)
1045
 
        {
1046
 
        /* parent goes away */
1047
 
        exit(0);
1048
 
        }
1049
 
      }
1050
 
 
1051
 
    while (try_lock_out(lockfds, F_WRLCK))
1052
 
      sleep(TSERVER_HA_CHECK_TIME); /* Relinquish */
1053
 
    }
1054
 
  else
1055
 
    {
1056
 
    lock_out(lockfds, F_WRLCK);
1057
 
    }
1058
 
 
 
917
  }
 
918
 
 
919
 
 
920
 
 
921
/*
 
922
 * next_task - look for the next work task to perform:
 
923
 * 1. If svr_delay_entry is set, then a delayed task is ready so
 
924
 *    find and process it.
 
925
 * 2. All items on the immediate list, then
 
926
 * 3. All items on the timed task list which have expired times
 
927
 *
 
928
 * Returns: amount of time till next task
 
929
 */
 
930
 
 
931
static time_t next_task()
 
932
 
 
933
  {
 
934
  time_t      delay;
 
935
 
 
936
  struct work_task  *nxt;
 
937
 
 
938
  struct work_task  *ptask;
 
939
  time_t      tilwhen = server.sv_attr[(int)SRV_ATR_schedule_iteration].at_val.at_long;
 
940
 
 
941
  time_now = time((time_t *)0);
 
942
 
 
943
  if (svr_delay_entry)
 
944
    {
 
945
    ptask = (struct work_task *)GET_NEXT(task_list_event);
 
946
 
 
947
    while (ptask != NULL)
 
948
      {
 
949
      nxt = (struct work_task *)GET_NEXT(ptask->wt_linkall);
 
950
 
 
951
      if (ptask->wt_type == WORK_Deferred_Cmp)
 
952
        dispatch_task(ptask);
 
953
 
 
954
      ptask = nxt;
 
955
      }
 
956
 
 
957
    svr_delay_entry = 0;
 
958
    }
 
959
 
 
960
  while ((ptask = (struct work_task *)GET_NEXT(task_list_immed)) != NULL)
 
961
    dispatch_task(ptask);
 
962
 
 
963
  while ((ptask = (struct work_task *)GET_NEXT(task_list_timed)) != NULL)
 
964
    {
 
965
    if ((delay = ptask->wt_event - time_now) > 0)
 
966
      {
 
967
      if (tilwhen > delay)
 
968
        tilwhen = delay;
 
969
 
 
970
      break;
 
971
      }
 
972
    else
 
973
      {
 
974
      dispatch_task(ptask); /* will delete link */
 
975
      }
 
976
    }
 
977
 
 
978
  /* should the scheduler be run?  If so, adjust the delay time  */
 
979
 
 
980
  if ((delay = server.sv_next_schedule - time_now) <= 0)
 
981
    svr_do_schedule = SCH_SCHEDULE_TIME;
 
982
  else if (delay < tilwhen)
 
983
    tilwhen = delay;
 
984
 
 
985
  return(tilwhen);
 
986
  }  /* END next_task() */
 
987
 
 
988
 
 
989
 
 
990
/*
 
991
 * start_hot_jobs - place any job which is state QUEUED and has the
 
992
 * HOT start flag set into execution.
 
993
 *
 
994
 * Returns the number of jobs to be hot started.
 
995
 */
 
996
 
 
997
static int start_hot_jobs(void)
 
998
 
 
999
  {
 
1000
  int  ct = 0;
 
1001
  job *pjob;
 
1002
 
 
1003
  for (pjob = (job *)GET_NEXT(svr_alljobs);
 
1004
       pjob != NULL;
 
1005
       pjob = (job *)GET_NEXT(pjob->ji_alljobs))
 
1006
    {
 
1007
    if ((pjob->ji_qs.ji_substate == JOB_SUBSTATE_QUEUED) &&
 
1008
        (pjob->ji_qs.ji_svrflags & JOB_SVFLG_HOTSTART))
 
1009
      {
 
1010
      log_event(
 
1011
        PBSEVENT_SYSTEM,
 
1012
        PBS_EVENTCLASS_JOB,
 
1013
        pjob->ji_qs.ji_jobid,
 
1014
        "attempting to hot start job");
 
1015
 
 
1016
      svr_startjob(pjob, NULL, NULL, NULL);
 
1017
 
 
1018
      ct++;
 
1019
      }
 
1020
    }
 
1021
 
 
1022
  return(ct);
 
1023
  }  /* END start_hot_jobs() */
 
1024
 
 
1025
 
 
1026
 
 
1027
 
 
1028
 
 
1029
 
 
1030
 
 
1031
void
 
1032
main_loop(void)
 
1033
  {
 
1034
  int  c;
 
1035
  long  *state;
 
1036
  time_t waittime;
 
1037
  pbs_queue *pque;
 
1038
  job *pjob;
 
1039
  time_t last_jobstat_time;
 
1040
  int    when;
 
1041
 
 
1042
  void ping_nodes A_((struct work_task *));
 
1043
  void check_nodes A_((struct work_task *));
 
1044
  void check_log A_((struct work_task *));
 
1045
  void check_acct_log A_((struct work_task *));
 
1046
 
 
1047
  extern char *msg_startup2; /* log message   */
 
1048
 
 
1049
  last_jobstat_time = time_now;
1059
1050
  server.sv_started = time(&time_now); /* time server started */
1060
1051
 
1061
 
  /*
1062
 
   * Open the log file so we can start recording events
1063
 
   *
1064
 
   * set log_event_mask to point to the log_event attribute value so
1065
 
   * it controls which events are logged.
1066
 
   */
1067
 
 
1068
 
  log_event_mask = &server.sv_attr[SRV_ATR_log_events].at_val.at_long;
1069
 
 
1070
 
  sprintf(path_log, "%s/%s",
1071
 
          path_home,
1072
 
          PBS_LOGFILES);
1073
 
 
1074
 
  log_open(log_file, path_log);
1075
 
 
1076
 
  sprintf(log_buffer, msg_startup1, server_name, server_init_type);
1077
 
 
1078
 
  log_event(
1079
 
    PBSEVENT_SYSTEM | PBSEVENT_ADMIN | PBSEVENT_FORCE,
1080
 
    PBS_EVENTCLASS_SERVER,
1081
 
    msg_daemonname,
1082
 
    log_buffer);
1083
 
 
1084
 
  /* initialize the server objects and perform specified recovery */
1085
 
  /* will be left in the server's private directory  */
1086
 
 
1087
 
  if ((plogenv = getenv("PBSLOGLEVEL")) != NULL)
1088
 
    {
1089
 
    LOGLEVEL = (int)strtol(plogenv, NULL, 10);
1090
 
    }
1091
 
 
1092
 
  if ((pc = getenv("PBSDEBUG")) != NULL)
1093
 
    {
1094
 
    DEBUGMODE = 1;
1095
 
    TDoBackground = 0;
1096
 
    }
1097
 
 
1098
 
  /* NOTE:  env cleared in pbsd_init() */
1099
 
 
1100
 
  if (pbsd_init(server_init_type) != 0)
1101
 
    {
1102
 
    log_err(-1, msg_daemonname, "pbsd_init failed");
1103
 
 
1104
 
    exit(3);
1105
 
    }
1106
 
 
1107
 
  /* initialize the network interface */
1108
 
 
1109
 
  sprintf(log_buffer, "Using ports Server:%d  Scheduler:%d  MOM:%d",
1110
 
          pbs_server_port_dis,
1111
 
          pbs_scheduler_port,
1112
 
          pbs_mom_port);
1113
 
 
1114
 
  log_event(
1115
 
    PBSEVENT_SYSTEM | PBSEVENT_ADMIN,
1116
 
    PBS_EVENTCLASS_SERVER,
1117
 
    msg_daemonname,
1118
 
    log_buffer);
1119
 
 
1120
 
  if (init_network(pbs_server_port_dis, process_request) != 0)
1121
 
    {
1122
 
    perror("pbs_server: network");
1123
 
 
1124
 
    log_err(-1, msg_daemonname, "init_network failed dis");
1125
 
 
1126
 
    exit(3);
1127
 
    }
1128
 
 
1129
 
  if (init_network(0, process_request) != 0)
1130
 
    {
1131
 
    perror("pbs_server: unix domain socket");
1132
 
 
1133
 
    log_err(-1, msg_daemonname, "init_network failed unix domain socket");
1134
 
 
1135
 
    exit(3);
1136
 
    }
1137
 
 
1138
 
  if (TDoBackground == 1)
1139
 
    {
1140
 
    /* go into the background and become own session/process group */
1141
 
 
1142
 
    lock_out(lockfds, F_UNLCK);
1143
 
 
1144
 
    if (fork() > 0)
1145
 
      {
1146
 
      /* parent goes away */
1147
 
 
1148
 
      exit(0);
1149
 
      }
1150
 
 
1151
 
    if ((sid = setsid()) == -1)
1152
 
      {
1153
 
      log_err(errno, msg_daemonname, "setsid failed");
1154
 
 
1155
 
      exit(2);
1156
 
      }
1157
 
 
1158
 
    lock_out(lockfds, F_WRLCK);
1159
 
 
1160
 
    fclose(stdin);
1161
 
    fclose(stdout);
1162
 
    fclose(stderr);
1163
 
 
1164
 
    dummyfile = fopen("/dev/null", "r");
1165
 
    assert((dummyfile != 0) && (fileno(dummyfile) == 0));
1166
 
 
1167
 
    dummyfile = fopen("/dev/null", "w");
1168
 
    assert((dummyfile != 0) && (fileno(dummyfile) == 1));
1169
 
 
1170
 
    dummyfile = fopen("/dev/null", "w");
1171
 
    assert((dummyfile != 0) && (fileno(dummyfile) == 2));
1172
 
    }  /* END if (TDoBackground == 1) */
1173
 
  else
1174
 
    {
1175
 
    if ((plogenv != NULL) && isdigit(plogenv[0]))
1176
 
      LOGLEVEL = (int)strtol(plogenv, NULL, 0);
1177
 
 
1178
 
    sid = getpid();
1179
 
 
1180
 
    setvbuf(stdout, NULL, _IOLBF, 0);
1181
 
 
1182
 
    setvbuf(stderr, NULL, _IOLBF, 0);
1183
 
    }
1184
 
 
1185
 
  sprintf(log_buffer, "%ld\n",
1186
 
 
1187
 
          (long)sid);
1188
 
 
1189
 
  if (write(lockfds, log_buffer, strlen(log_buffer)) !=
1190
 
      (ssize_t)strlen(log_buffer))
1191
 
    {
1192
 
    log_err(errno, msg_daemonname, "failed to write pid to lockfile");
1193
 
 
1194
 
    exit(-1);
1195
 
    }
1196
 
 
1197
 
#if (PLOCK_DAEMONS & 1)
1198
 
  plock(PROCLOCK);
1199
 
 
1200
 
#endif
1201
 
 
1202
 
  if ((rppfd = rpp_bind(pbs_server_port_dis)) == -1)
1203
 
    {
1204
 
    log_err(errno, msg_daemonname, "rpp_bind");
1205
 
 
1206
 
    exit(1);
1207
 
    }
1208
 
 
1209
 
  rpp_fd = -1;  /* force rpp_bind() to get another socket */
1210
 
 
1211
 
  tryport = IPPORT_RESERVED;
1212
 
 
1213
 
  privfd = -1;
1214
 
 
1215
 
  while (--tryport > 0)
1216
 
    {
1217
 
    if ((privfd = rpp_bind(tryport)) != -1)
1218
 
      break;
1219
 
 
1220
 
    if ((errno != EADDRINUSE) && (errno != EADDRNOTAVAIL))
1221
 
      break;
1222
 
    }
1223
 
 
1224
 
  if (privfd == -1)
1225
 
    {
1226
 
    log_err(errno, msg_daemonname, "no privileged ports");
1227
 
 
1228
 
    exit(1);
1229
 
    }
1230
 
 
1231
 
  if (LOGLEVEL >= 5)
1232
 
    {
1233
 
    log_event(
1234
 
      PBSEVENT_SYSTEM | PBSEVENT_FORCE,
1235
 
      PBS_EVENTCLASS_SERVER,
1236
 
      msg_daemonname,
1237
 
      "creating rpp and private interfaces");
1238
 
    }
1239
 
 
1240
 
  add_conn(rppfd, Primary, (pbs_net_t)0, 0, PBS_SOCK_INET, rpp_request);
1241
 
 
1242
 
  add_conn(privfd, Primary, (pbs_net_t)0, 0, PBS_SOCK_INET, rpp_request);
1243
1052
 
1244
1053
  /* record the fact that we are up and running */
1245
1054
 
1281
1090
 
1282
1091
  set_task(WORK_Timed, time_now + 5, check_log, NULL);
1283
1092
 
 
1093
  set_task(WORK_Timed,time_now + 10,check_acct_log,NULL);
 
1094
 
1284
1095
  /*
1285
1096
   * Now at last, we are ready to do some batch work.  The
1286
1097
   * following section constitutes the "main" loop of the server
1330
1141
      /* Are there HOT jobs to rerun */
1331
1142
      /* only try every _CYCLE seconds */
1332
1143
 
 
1144
      c = 0;
 
1145
 
1333
1146
      if (time_now > server.sv_hotcycle + SVR_HOT_CYCLE)
1334
1147
        {
1335
1148
        server.sv_hotcycle = time_now + SVR_HOT_CYCLE;
1349
1162
 
1350
1163
    /* any jobs to route today */
1351
1164
 
1352
 
    pque = (pbs_queue *)GET_NEXT(svr_queues);
1353
 
 
1354
 
    while (pque != NULL)
 
1165
    for (pque = (pbs_queue *)GET_NEXT(svr_queues);
 
1166
         pque != NULL;
 
1167
         pque = (pbs_queue *)GET_NEXT(pque->qu_link))
1355
1168
      {
1356
1169
      if (pque->qu_qs.qu_type == QTYPE_RoutePush)
1357
1170
        queue_route(pque);
1358
 
 
1359
 
      pque = (pbs_queue *)GET_NEXT(pque->qu_link);
1360
1171
      }
1361
1172
 
1362
1173
#ifdef NO_SIGCHLD
1366
1177
      {
1367
1178
      check_children();
1368
1179
      }
1369
 
 
1370
1180
#endif
1371
1181
 
1372
1182
    /* touch the rpp streams that need to send */
1373
1183
 
1374
 
    rpp_request(42);
 
1184
    rpp_request(0);
1375
1185
 
1376
1186
    /* wait for a request and process it */
1377
1187
 
1384
1194
     * we use the new value if PBSLOGLEVEL was not specified
1385
1195
     */
1386
1196
 
1387
 
    if (plogenv == NULL)
 
1197
    if (plogenv == NULL) /* If no specification of loglevel from env */
1388
1198
      LOGLEVEL = server.sv_attr[(int)SRV_ATR_LogLevel].at_val.at_long;
1389
1199
 
1390
1200
    /* any running jobs need a status update? */
1456
1266
 
1457
1267
    update_nodes_file();
1458
1268
    }
 
1269
  }
 
1270
 
 
1271
 
 
1272
/**
 
1273
 * initialize_globals
 
1274
 *
 
1275
 * Set the intial state of global variables.
 
1276
 */
 
1277
 
 
1278
void
 
1279
initialize_globals(void)
 
1280
  {
 
1281
  strcpy(pbs_current_user, "PBS_Server");
 
1282
 
 
1283
  msg_daemonname = strdup(pbs_current_user);
 
1284
  }
 
1285
 
 
1286
 
 
1287
 
 
1288
/**
 
1289
 * set_globals_from_environment
 
1290
 *
 
1291
 * Set the intial state of global variables based on
 
1292
 * the program environment variables.
 
1293
 */
 
1294
 
 
1295
void
 
1296
set_globals_from_environment(void)
 
1297
 
 
1298
  {
 
1299
  char  *ptr;
 
1300
 
 
1301
  /* initialize service port numbers for self, Scheduler, and MOM */
 
1302
 
 
1303
  if ((ptr = getenv("PBS_BATCH_SERVICE_PORT")) != NULL)
 
1304
    {
 
1305
    pbs_server_port_dis = (int)strtol(ptr, NULL, 10);
 
1306
    }
 
1307
 
 
1308
  if ((ptr = getenv("PBS_SCHEDULER_SERVICE_PORT")) != NULL)
 
1309
    {
 
1310
    pbs_scheduler_port = (int)strtol(ptr, NULL, 10);
 
1311
    }
 
1312
 
 
1313
  if ((ptr = getenv("PBS_MOM_SERVICE_PORT")) != NULL)
 
1314
    {
 
1315
    pbs_mom_port = (int)strtol(ptr, NULL, 10);
 
1316
    }
 
1317
 
 
1318
  if ((ptr = getenv("PBS_MANAGER_SERVICE_PORT")) != NULL)
 
1319
    {
 
1320
    pbs_rm_port = (int)strtol(ptr, NULL, 10);
 
1321
    }
 
1322
 
 
1323
  if ((plogenv = getenv("PBSLOGLEVEL")) != NULL)
 
1324
    {
 
1325
    /* Note the plogenv is global and is tested in main_loop */
 
1326
    LOGLEVEL = (int)strtol(plogenv, NULL, 10);
 
1327
    }
 
1328
 
 
1329
  if ((ptr = getenv("PBSDEBUG")) != NULL)
 
1330
    {
 
1331
    DEBUGMODE = 1;
 
1332
    TDoBackground = 0;
 
1333
    }
 
1334
 
 
1335
  return;
 
1336
  }  /* END set_globals_from_environment() */
 
1337
 
 
1338
 
 
1339
 
 
1340
 
 
1341
 
 
1342
/*
 
1343
 * main - the initialization and main loop of pbs_daemon
 
1344
 */
 
1345
 
 
1346
int main(
 
1347
 
 
1348
  int   argc,    /* I */
 
1349
  char *argv[])  /* I */
 
1350
 
 
1351
  {
 
1352
  int  i;
 
1353
  int  lockfds = -1;
 
1354
  int  rppfd;   /* fd to receive is HELLO's */
 
1355
  int  privfd;  /* fd to send is messages */
 
1356
  uint  tryport;
 
1357
  char  lockfile[MAXPATHLEN + 1];
 
1358
  char *pc = NULL;
 
1359
  char *pathPtr = NULL;
 
1360
  char   EMsg[MAX_LINE];
 
1361
  char tmpLine[MAX_LINE];
 
1362
 
 
1363
  extern char *msg_svrdown; /* log message   */
 
1364
  extern char *msg_startup1; /* log message   */
 
1365
 
 
1366
  ProgName = argv[0];
 
1367
 
 
1368
  initialize_globals();
 
1369
  time_now = time((time_t *)0);
 
1370
  set_globals_from_environment();
 
1371
 
 
1372
  /* set standard umask */
 
1373
 
 
1374
  umask(022);
 
1375
 
 
1376
  /* save argv and the path for later use */
 
1377
  for (i = 0;i < argc;i++)
 
1378
    {
 
1379
    ArgV[i] = (char *)malloc(sizeof(char) * (strlen(argv[i])+1));
 
1380
 
 
1381
    if (ArgV[i] == NULL)
 
1382
      {
 
1383
      printf("ERROR:      failed to allocate memory to save argv, shutting down\n");
 
1384
 
 
1385
      exit(-1);
 
1386
      }
 
1387
 
 
1388
    strcpy(ArgV[i],argv[i]);
 
1389
    }
 
1390
 
 
1391
  /* save the path before we go into the background.  If we don't do this
 
1392
   * we can't restart the server because the path will change */
 
1393
  pathPtr = getenv("PATH");
 
1394
  snprintf(OriginalPath,sizeof(OriginalPath),"%s",pathPtr);
 
1395
 
 
1396
  /* close files for security purposes */
 
1397
  /* do the following before getuid() and geteuid() can trigger
 
1398
     nss_ldap into opening a socket to the LDAP server */
 
1399
 
 
1400
  i = sysconf(_SC_OPEN_MAX);
 
1401
 
 
1402
  while (--i > 2)
 
1403
    close(i);  /* close any file desc left open by parent */
 
1404
 
 
1405
  /* find out the name of this machine (hostname) */
 
1406
 
 
1407
  EMsg[0] = '\0';
 
1408
 
 
1409
  if ((gethostname(server_host, PBS_MAXHOSTNAME) == -1) ||
 
1410
      (get_fullhostname(server_host, server_host, PBS_MAXHOSTNAME, EMsg) == -1))
 
1411
    {
 
1412
    snprintf(tmpLine, sizeof(tmpLine), "unable to determine local server hostname %c %s",
 
1413
             EMsg[0] ? '-' : ' ',
 
1414
             EMsg);
 
1415
 
 
1416
    log_err(-1, "pbsd_main", tmpLine);
 
1417
 
 
1418
    exit(1);    /* FAILURE - shutdown */
 
1419
    }
 
1420
 
 
1421
  strcpy(server_name, server_host); /* by default server = host */
 
1422
 
 
1423
  pbs_server_addr    = get_hostaddr(server_host);
 
1424
  pbs_mom_addr       = pbs_server_addr;   /* assume on same host */
 
1425
  pbs_scheduler_addr = pbs_server_addr;   /* assume on same host */
 
1426
 
 
1427
  /* The following port numbers might have been initialized in set_globals_from_environment() above. */
 
1428
 
 
1429
  if (pbs_server_port_dis <= 0)
 
1430
    pbs_server_port_dis = get_svrport(PBS_BATCH_SERVICE_NAME, "tcp", PBS_BATCH_SERVICE_PORT_DIS);
 
1431
 
 
1432
  if (pbs_scheduler_port <= 0)
 
1433
    pbs_scheduler_port = get_svrport(PBS_SCHEDULER_SERVICE_NAME, "tcp", PBS_SCHEDULER_SERVICE_PORT);
 
1434
 
 
1435
  if (pbs_mom_port <= 0)
 
1436
    pbs_mom_port = get_svrport(PBS_MOM_SERVICE_NAME, "tcp", PBS_MOM_SERVICE_PORT);
 
1437
 
 
1438
  if (pbs_rm_port <= 0)
 
1439
    pbs_rm_port = get_svrport(PBS_MANAGER_SERVICE_NAME, "tcp", PBS_MANAGER_SERVICE_PORT);
 
1440
 
 
1441
  parse_command_line(argc, argv);
 
1442
 
 
1443
  /* if we are not running with real and effective uid of 0, forget it */
 
1444
 
 
1445
  if ((getuid() != 0) || (geteuid() != 0))
 
1446
    {
 
1447
    fprintf(stderr, "%s: must be run by root\n",
 
1448
            ProgName);
 
1449
 
 
1450
    return(1);
 
1451
    }
 
1452
 
 
1453
  /*
 
1454
   * Read in server attributes so they are available to be used
 
1455
   * Attributes will not be read in on a pbs_server -t create
 
1456
   */
 
1457
 
 
1458
  if (get_svr_attr(server_init_type) == -1)
 
1459
    {
 
1460
    fprintf(stderr,"%s: failed to get server attributes\n", 
 
1461
      ProgName);
 
1462
 
 
1463
    return(1);
 
1464
    }
 
1465
 
 
1466
  /*
 
1467
   * make sure no other server is running with this home directory.
 
1468
   * If server lockfile attribute has been set use it.
 
1469
   * If not use default location for it
 
1470
   */
 
1471
   
 
1472
  if ((server.sv_attr[(int)SRV_ATR_lockfile].at_flags & ATR_VFLAG_SET) &&
 
1473
               (server.sv_attr[(int)SRV_ATR_lockfile].at_val.at_str))
 
1474
    {
 
1475
    char *LockfilePtr = server.sv_attr[(int)SRV_ATR_lockfile].at_val.at_str;
 
1476
 
 
1477
    /* check if an absolute path is specified or not */
 
1478
 
 
1479
    if (LockfilePtr[0] == '/')
 
1480
      {
 
1481
      snprintf(lockfile,sizeof(lockfile),"%s",LockfilePtr);     
 
1482
      }
 
1483
    else
 
1484
      {
 
1485
      snprintf(lockfile,sizeof(lockfile),"%s/%s/%s",
 
1486
        path_home,
 
1487
        PBS_SVR_PRIVATE,
 
1488
        LockfilePtr);
 
1489
      }
 
1490
    }
 
1491
  else
 
1492
    {
 
1493
    sprintf(lockfile,"%s/%s/server.lock",
 
1494
      path_home,
 
1495
      PBS_SVR_PRIVATE);
 
1496
    }
 
1497
 
 
1498
#ifndef USE_HA_THREADS
 
1499
  if ((lockfds = open(lockfile, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0)
 
1500
    {
 
1501
    sprintf(log_buffer, "%s: unable to open lock file '%s'",
 
1502
            msg_daemonname,
 
1503
            lockfile);
 
1504
 
 
1505
    fprintf(stderr, "%s\n",
 
1506
            log_buffer);
 
1507
 
 
1508
    log_err(errno, msg_daemonname, log_buffer);
 
1509
 
 
1510
    exit(2);
 
1511
    }
 
1512
#endif /* !USE_HA_THREADS */
 
1513
 
 
1514
  /* HA EVENTS MUST HAPPEN HERE */
 
1515
 
 
1516
  strcpy(HALockFile,lockfile);
 
1517
  HALockCheckTime = server.sv_attr[(int)SRV_ATR_LockfileCheckTime].at_val.at_long;
 
1518
  HALockUpdateTime = server.sv_attr[(int)SRV_ATR_LockfileUpdateTime].at_val.at_long;
 
1519
 
 
1520
  /* apply HA defaults */
 
1521
 
 
1522
  if (HALockCheckTime == 0)
 
1523
    HALockCheckTime = PBS_LOCKFILE_CHECK_TIME;
 
1524
 
 
1525
  if (HALockUpdateTime == 0)
 
1526
    HALockUpdateTime = PBS_LOCKFILE_UPDATE_TIME;
 
1527
 
 
1528
  if ((pc = getenv("PBSDEBUG")) != NULL)
 
1529
    {
 
1530
    DEBUGMODE = 1;
 
1531
    TDoBackground = 0;
 
1532
    }
 
1533
 
 
1534
  /* handle running in the background or not if we're debugging */
 
1535
 
 
1536
  if(high_availability_mode)
 
1537
    {
 
1538
    if (daemonize_server(TDoBackground, &sid) == FAILURE)
 
1539
      {
 
1540
      exit(2);
 
1541
      }
 
1542
    }
 
1543
 
 
1544
#ifdef OS_LOSES_FD_OVER_FORK
 
1545
  /* NOTE:  file descriptors may be lost across forks in SLES 10 SP1 */
 
1546
 
 
1547
#ifndef USE_HA_THREADS
 
1548
  close(lockfds);
 
1549
 
 
1550
  if ((lockfds = open(lockfile, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0)
 
1551
    {
 
1552
    sprintf(log_buffer, "%s: unable to open lock file '%s'",
 
1553
      msg_daemonname,
 
1554
      lockfile);
 
1555
 
 
1556
    fprintf(stderr, "%s\n",log_buffer);
 
1557
 
 
1558
    log_err(errno, msg_daemonname, log_buffer);
 
1559
 
 
1560
    exit(2);
 
1561
    }
 
1562
 
 
1563
#endif /* !USE_HA_THREADS */
 
1564
  /* no file descriptor was held if we're using ha threads */
 
1565
#endif /* OS_LOSES_FD_OVER_FORK */
 
1566
 
 
1567
#ifdef USE_HA_THREADS
 
1568
  if (high_availability_mode)
 
1569
    {
 
1570
    lock_out_ha();
 
1571
    }
 
1572
  else
 
1573
    {
 
1574
    if ((lockfds = open(lockfile,O_CREAT|O_TRUNC|O_WRONLY,0600)) < 0)
 
1575
      {
 
1576
      sprintf(log_buffer,"%s: unable to open lock file '%s'",
 
1577
        msg_daemonname,
 
1578
        lockfile);
 
1579
 
 
1580
      fprintf(stderr,"%s\n",log_buffer);
 
1581
 
 
1582
      log_err(errno,msg_daemonname,log_buffer);
 
1583
 
 
1584
      exit(2);
 
1585
      }
 
1586
    }
 
1587
#else
 
1588
  if (high_availability_mode)
 
1589
    {
 
1590
    /* This will allow multiple instance of the pbs_server to be
 
1591
     * running.  This must be done before setting up the client
 
1592
     * sockets interface, reading the config file, and contacting
 
1593
     * the compute nodes.
 
1594
     */
 
1595
 
 
1596
    while (try_lock_out(lockfds, F_WRLCK))
 
1597
      sleep(TSERVER_HA_CHECK_TIME); /* Relinquish */
 
1598
    }  /* END if (high_availability_mode) */
 
1599
  else
 
1600
    {
 
1601
    lock_out(lockfds, F_WRLCK);
 
1602
    }
 
1603
#endif
 
1604
 
 
1605
  /*
 
1606
   * Open the log file so we can start recording events
 
1607
   *
 
1608
   * set log_event_mask to point to the log_event attribute value so
 
1609
   * it controls which events are logged.
 
1610
   */
 
1611
 
 
1612
  log_event_mask = &server.sv_attr[SRV_ATR_log_events].at_val.at_long;
 
1613
 
 
1614
  sprintf(path_log, "%s/%s",
 
1615
          path_home,
 
1616
          PBS_LOGFILES);
 
1617
 
 
1618
  log_open(log_file, path_log);
 
1619
 
 
1620
  sprintf(log_buffer, msg_startup1, server_name, server_init_type);
 
1621
 
 
1622
  log_event(
 
1623
    PBSEVENT_SYSTEM | PBSEVENT_ADMIN | PBSEVENT_FORCE,
 
1624
    PBS_EVENTCLASS_SERVER,
 
1625
    msg_daemonname,
 
1626
    log_buffer);
 
1627
 
 
1628
  /* initialize the server objects and perform specified recovery */
 
1629
  /* will be left in the server's private directory  */
 
1630
  /* NOTE:  env cleared in pbsd_init() */
 
1631
 
 
1632
  if (pbsd_init(server_init_type) != 0)
 
1633
    {
 
1634
    log_err(-1, msg_daemonname, "pbsd_init failed");
 
1635
 
 
1636
    exit(3);
 
1637
    }
 
1638
 
 
1639
  /* initialize the network interface */
 
1640
 
 
1641
  sprintf(log_buffer, "Using ports Server:%d  Scheduler:%d  MOM:%d (server: '%s')",
 
1642
          pbs_server_port_dis,
 
1643
          pbs_scheduler_port,
 
1644
          pbs_mom_port,
 
1645
          server_host);
 
1646
 
 
1647
  log_event(
 
1648
    PBSEVENT_SYSTEM | PBSEVENT_ADMIN,
 
1649
    PBS_EVENTCLASS_SERVER,
 
1650
    msg_daemonname,
 
1651
    log_buffer);
 
1652
 
 
1653
  if (init_network(pbs_server_port_dis, process_request) != 0)
 
1654
    {
 
1655
    perror("pbs_server: network");
 
1656
 
 
1657
    log_err(-1, msg_daemonname, "init_network failed dis");
 
1658
 
 
1659
    exit(3);
 
1660
    }
 
1661
 
 
1662
  if (init_network(0, process_request) != 0)
 
1663
    {
 
1664
    perror("pbs_server: unix domain socket");
 
1665
 
 
1666
    log_err(-1, msg_daemonname, "init_network failed unix domain socket");
 
1667
 
 
1668
    exit(3);
 
1669
    }
 
1670
 
 
1671
 
 
1672
  /* handle running in the background or not if we're debugging */
 
1673
 
 
1674
  if(!high_availability_mode)
 
1675
    {
 
1676
    if (daemonize_server(TDoBackground,&sid) == FAILURE)
 
1677
      {
 
1678
      exit(2);
 
1679
      }
 
1680
    }
 
1681
 
 
1682
  sprintf(log_buffer, "%ld\n", (long)sid);
 
1683
 
 
1684
  if (!high_availability_mode)
 
1685
    {
 
1686
    if (write(lockfds, log_buffer, strlen(log_buffer)) !=
 
1687
        (ssize_t)strlen(log_buffer))
 
1688
      {
 
1689
      log_err(errno, msg_daemonname, "failed to write pid to lockfile");
 
1690
 
 
1691
      exit(-1);
 
1692
      }
 
1693
    }
 
1694
 
 
1695
#if (PLOCK_DAEMONS & 1)
 
1696
  plock(PROCLOCK);
 
1697
 
 
1698
#endif
 
1699
 
 
1700
  if ((rppfd = rpp_bind(pbs_server_port_dis)) == -1)
 
1701
    {
 
1702
    log_err(errno, msg_daemonname, "rpp_bind");
 
1703
 
 
1704
    exit(1);
 
1705
    }
 
1706
 
 
1707
  rpp_fd = -1;  /* force rpp_bind() to get another socket */
 
1708
 
 
1709
  tryport = IPPORT_RESERVED;
 
1710
 
 
1711
  privfd = -1;
 
1712
 
 
1713
  while (--tryport > 0)
 
1714
    {
 
1715
    if ((privfd = rpp_bind(tryport)) != -1)
 
1716
      break;
 
1717
 
 
1718
    if ((errno != EADDRINUSE) && (errno != EADDRNOTAVAIL))
 
1719
      break;
 
1720
    }
 
1721
 
 
1722
  if (privfd == -1)
 
1723
    {
 
1724
    log_err(errno, msg_daemonname, "no privileged ports");
 
1725
 
 
1726
    exit(1);
 
1727
    }
 
1728
 
 
1729
  if (LOGLEVEL >= 5)
 
1730
    {
 
1731
    log_event(
 
1732
      PBSEVENT_SYSTEM | PBSEVENT_FORCE,
 
1733
      PBS_EVENTCLASS_SERVER,
 
1734
      msg_daemonname,
 
1735
      "creating rpp and private interfaces");
 
1736
    }
 
1737
 
 
1738
  add_conn(rppfd, Primary, (pbs_net_t)0, 0, PBS_SOCK_INET, rpp_request);
 
1739
 
 
1740
  add_conn(privfd, Primary, (pbs_net_t)0, 0, PBS_SOCK_INET, rpp_request);
 
1741
 
 
1742
  /*==========*/
 
1743
  main_loop();
 
1744
  /*==========*/
1459
1745
 
1460
1746
  RPPConfigure(1, 0); /* help rpp_shutdown go a bit faster */
1461
 
 
1462
1747
  rpp_shutdown();
1463
1748
 
1464
1749
  shutdown_ack();
1492
1777
  {
1493
1778
  long depth = 1;
1494
1779
 
 
1780
 /* remove logs older than LogKeepDays */
 
1781
 
 
1782
 if ((server.sv_attr[(int)SRV_ATR_LogKeepDays].at_flags 
 
1783
     & ATR_VFLAG_SET) != 0)
 
1784
   {
 
1785
   snprintf(log_buffer,sizeof(log_buffer),"checking for old pbs_server logs in dir '%s' (older than %ld days)",
 
1786
     path_svrlog,
 
1787
     server.sv_attr[(int)SRV_ATR_LogKeepDays].at_val.at_long);
 
1788
 
 
1789
   log_event(
 
1790
     PBSEVENT_SYSTEM | PBSEVENT_FORCE,
 
1791
     PBS_EVENTCLASS_SERVER,
 
1792
     msg_daemonname,
 
1793
     log_buffer);
 
1794
 
 
1795
   if (log_remove_old(path_svrlog,server.sv_attr[(int)SRV_ATR_LogKeepDays].at_val.at_long * SECS_PER_DAY) != 0)
 
1796
     {
 
1797
     log_err(-1,"check_log","failure occurred when checking for old pbs_server logs");
 
1798
     }
 
1799
   }
 
1800
 
1495
1801
  if ((server.sv_attr[(int)SRV_ATR_LogFileMaxSize].at_flags
1496
1802
       & ATR_VFLAG_SET) != 0)
1497
1803
    {
1539
1845
 
1540
1846
 
1541
1847
 
 
1848
void check_acct_log(
 
1849
 
 
1850
 struct work_task *ptask) /* I */
 
1851
 
 
1852
 {
 
1853
  if (((server.sv_attr[(int)SRV_ATR_AcctKeepDays].at_flags & ATR_VFLAG_SET) != 0)
 
1854
       && (server.sv_attr[(int)SRV_ATR_AcctKeepDays].at_val.at_long >= 0))
 
1855
    {
 
1856
    sprintf(log_buffer,"Checking accounting files - keep days = %ld",
 
1857
      server.sv_attr[(int)SRV_ATR_AcctKeepDays].at_val.at_long);
 
1858
 
 
1859
    log_event(
 
1860
      PBSEVENT_SYSTEM | PBSEVENT_FORCE,
 
1861
      PBS_EVENTCLASS_SERVER,
 
1862
      msg_daemonname,
 
1863
      log_buffer);
 
1864
     
 
1865
    acct_cleanup(server.sv_attr[(int)SRV_ATR_AcctKeepDays].at_val.at_long);
 
1866
    
 
1867
    }
 
1868
 
 
1869
  set_task(WORK_Timed,time_now + PBS_ACCT_CHECK_RATE,check_acct_log,NULL);
 
1870
 
 
1871
  return;
 
1872
  } /* END check_acct_log */
 
1873
 
 
1874
 
1542
1875
 
1543
1876
 
1544
1877
 
1594
1927
 
1595
1928
 
1596
1929
 
1597
 
 
1598
 
/*
1599
 
 * next_task - look for the next work task to perform:
1600
 
 * 1. If svr_delay_entry is set, then a delayed task is ready so
1601
 
 *    find and process it.
1602
 
 * 2. All items on the immediate list, then
1603
 
 * 3. All items on the timed task list which have expired times
1604
 
 *
1605
 
 * Returns: amount of time till next task
1606
 
 */
1607
 
 
1608
 
static time_t next_task()
1609
 
 
1610
 
  {
1611
 
  static char id[] = "next_task";
1612
 
  time_t      delay;
1613
 
 
1614
 
  struct work_task  *nxt;
1615
 
 
1616
 
  struct work_task  *ptask;
1617
 
  time_t      tilwhen = server.sv_attr[(int)SRV_ATR_schedule_iteration].at_val.at_long;
1618
 
 
1619
 
  time_now = time((time_t *)0);
1620
 
 
1621
 
  if (svr_delay_entry)
1622
 
    {
1623
 
    if (LOGLEVEL >= 7)
1624
 
      {
1625
 
      log_record(
1626
 
        PBSEVENT_SCHED,
1627
 
        PBS_EVENTCLASS_REQUEST,
1628
 
        id,
1629
 
        "CHECKING svr_delay_entry");
1630
 
      }
1631
 
 
1632
 
    ptask = (struct work_task *)GET_NEXT(task_list_event);
1633
 
 
1634
 
    while (ptask != NULL)
1635
 
      {
1636
 
      nxt = (struct work_task *)GET_NEXT(ptask->wt_linkall);
1637
 
 
1638
 
      if (ptask->wt_type == WORK_Deferred_Cmp)
1639
 
        {
1640
 
        if (LOGLEVEL >= 7)
1641
 
          {
1642
 
          sprintf(log_buffer,
1643
 
                  "DISPATCH Task WORK_Deferred_Cmp type %d, wt_event %ld, wt_aux %d",
1644
 
                  ptask->wt_type, ptask->wt_event, ptask->wt_aux);
1645
 
 
1646
 
          log_record(
1647
 
            PBSEVENT_SCHED,
1648
 
            PBS_EVENTCLASS_REQUEST,
1649
 
            id,
1650
 
            log_buffer);
1651
 
 
1652
 
          }
1653
 
 
1654
 
        dispatch_task(ptask);
1655
 
        }
1656
 
 
1657
 
      ptask = nxt;
1658
 
      }
1659
 
 
1660
 
    svr_delay_entry = 0;
1661
 
    }
1662
 
 
1663
 
  while ((ptask = (struct work_task *)GET_NEXT(task_list_immed)) != NULL)
1664
 
    {
1665
 
    if (LOGLEVEL >= 7)
1666
 
      {
1667
 
      sprintf(log_buffer,
1668
 
              "DISPATCH Task #1 type %d, wt_event %ld, wt_aux %d",
1669
 
              ptask->wt_type, ptask->wt_event, ptask->wt_aux);
1670
 
 
1671
 
      log_record(
1672
 
        PBSEVENT_SCHED,
1673
 
        PBS_EVENTCLASS_REQUEST,
1674
 
        id,
1675
 
        log_buffer);
1676
 
 
1677
 
      }
1678
 
 
1679
 
    dispatch_task(ptask);
1680
 
    }
1681
 
 
1682
 
  while ((ptask = (struct work_task *)GET_NEXT(task_list_timed)) != NULL)
1683
 
    {
1684
 
    if ((delay = ptask->wt_event - time_now) > 0)
1685
 
      {
1686
 
      if (tilwhen > delay)
1687
 
        tilwhen = delay;
1688
 
 
1689
 
      break;
1690
 
      }
1691
 
    else
1692
 
      {
1693
 
      if (LOGLEVEL >= 7)
1694
 
        {
1695
 
        sprintf(log_buffer,
1696
 
                "DISPATCH Task #2 type %d, wt_event %ld, wt_aux %d",
1697
 
                ptask->wt_type, ptask->wt_event, ptask->wt_aux);
1698
 
 
1699
 
        log_record(
1700
 
          PBSEVENT_SCHED,
1701
 
          PBS_EVENTCLASS_REQUEST,
1702
 
          id,
1703
 
          log_buffer);
1704
 
        }
1705
 
 
1706
 
      dispatch_task(ptask); /* will delete link */
1707
 
      }
1708
 
    }
1709
 
 
1710
 
  /* should the scheduler be run?  If so, adjust the delay time  */
1711
 
 
1712
 
  if ((delay = server.sv_next_schedule - time_now) <= 0)
1713
 
    svr_do_schedule = SCH_SCHEDULE_TIME;
1714
 
  else if (delay < tilwhen)
1715
 
    tilwhen = delay;
1716
 
 
1717
 
  return(tilwhen);
1718
 
  }  /* END next_task() */
1719
 
 
1720
 
 
1721
 
 
1722
 
 
1723
 
 
1724
 
/*
1725
 
 * start_hot_jobs - place any job which is state QUEUED and has the
1726
 
 * HOT start flag set into execution.
1727
 
 *
1728
 
 * Returns the number of jobs to be hot started.
1729
 
 */
1730
 
 
1731
 
static int start_hot_jobs(void)
1732
 
 
1733
 
  {
1734
 
  int  ct = 0;
1735
 
  job *pjob;
1736
 
 
1737
 
  pjob = (job *)GET_NEXT(svr_alljobs);
1738
 
 
1739
 
  while (pjob != NULL)
1740
 
    {
1741
 
    if ((pjob->ji_qs.ji_substate == JOB_SUBSTATE_QUEUED) &&
1742
 
        (pjob->ji_qs.ji_svrflags & JOB_SVFLG_HOTSTART))
1743
 
      {
1744
 
      log_event(
1745
 
        PBSEVENT_SYSTEM,
1746
 
        PBS_EVENTCLASS_JOB,
1747
 
        pjob->ji_qs.ji_jobid,
1748
 
        "attempting to hot start job");
1749
 
 
1750
 
      svr_startjob(pjob, NULL, NULL, NULL);
1751
 
 
1752
 
      ct++;
1753
 
      }
1754
 
 
1755
 
    pjob = (job *)GET_NEXT(pjob->ji_alljobs);
1756
 
    }  /* END while (pjob != NULL) */
1757
 
 
1758
 
  return(ct);
1759
 
  }  /* END start_hot_jobs() */
1760
 
 
1761
 
 
1762
 
 
1763
 
 
1764
 
 
1765
 
/**
1766
 
 * Try to lock
1767
 
 * @return Zero on success, one on failure
1768
 
 */
 
1930
/**
 
1931
 * This function will extract the directory portion of 
 
1932
 * the given path and copy it into the Dir parameter
 
1933
 *
 
1934
 * @param FullPath (I)
 
1935
 * @param Dir (O)
 
1936
 * @param DirSize
 
1937
 */
 
1938
 
 
1939
char *extract_dir(
 
1940
 
 
1941
  char *FullPath,
 
1942
  char *Dir,
 
1943
  int   DirSize)
 
1944
 
 
1945
  {
 
1946
  char *ptr;
 
1947
 
 
1948
  if ((FullPath == NULL) ||
 
1949
      (Dir == NULL))
 
1950
    {
 
1951
    return(NULL);
 
1952
    }
 
1953
 
 
1954
  Dir[0] = '\0';
 
1955
 
 
1956
  snprintf(Dir,sizeof(Dir),"%s",FullPath);
 
1957
 
 
1958
  ptr = strrchr(Dir,'/');
 
1959
 
 
1960
  if (ptr != NULL)
 
1961
    {
 
1962
    *ptr = '\0';
 
1963
    }
 
1964
 
 
1965
  return(Dir);
 
1966
  }  /* END extract_dir() */
 
1967
 
 
1968
 
 
1969
 
 
1970
 
 
1971
/**
 
1972
 * Checks to see if HALockFile is defined, exists, and can be properly
 
1973
 * opened, etc.
 
1974
 *
 
1975
 * @return TRUE if HALockFile is valid for use
 
1976
 */
 
1977
int is_ha_lock_file_valid(
 
1978
 
 
1979
  char *lockfile)
 
1980
 
 
1981
  {
 
1982
  char        LockDir[MAX_PATH_LEN];
 
1983
  char        ErrorString[MAX_LINE];
 
1984
  char        id[] = "is_ha_lock_file_valid";
 
1985
  struct stat Stat;
 
1986
  bool_t      GoodPermissions = FALSE;
 
1987
 
 
1988
  if (HALockFile[0] == '\0')
 
1989
    {
 
1990
    return(FALSE);
 
1991
    }
 
1992
 
 
1993
  extract_dir(HALockFile,LockDir,sizeof(LockDir));
 
1994
 
 
1995
  if (stat(LockDir,&Stat) != 0)
 
1996
    {
 
1997
    char tmpLine[MAX_LINE];
 
1998
 
 
1999
    /* stat failed */
 
2000
    strerror_r(errno,ErrorString,sizeof(ErrorString));
 
2001
 
 
2002
    snprintf(tmpLine,sizeof(tmpLine),"could not stat the lockfile dir '%s': %s",
 
2003
      LockDir,
 
2004
      ErrorString);
 
2005
 
 
2006
    log_err(errno,id,tmpLine);
 
2007
 
 
2008
    return(FALSE);
 
2009
    }
 
2010
 
 
2011
  /* directory must be owned by the TORQUE user and must have
 
2012
   * read/write/exec permissions */
 
2013
  if ((Stat.st_uid == getuid()) &&
 
2014
      (Stat.st_mode & (S_IRUSR | S_IWUSR | S_IXUSR)))
 
2015
    {
 
2016
    /* we can write to this directory */
 
2017
 
 
2018
    GoodPermissions = TRUE;
 
2019
    }
 
2020
  else if ((Stat.st_gid == getgid()) &&
 
2021
           (Stat.st_mode & (S_IRGRP | S_IWGRP | S_IXGRP)))
 
2022
    {
 
2023
    GoodPermissions = TRUE;
 
2024
    }
 
2025
  else if (Stat.st_mode & (S_IROTH | S_IWOTH | S_IXOTH))
 
2026
    {
 
2027
    GoodPermissions = TRUE;
 
2028
    }
 
2029
 
 
2030
  if (GoodPermissions == FALSE)
 
2031
    {
 
2032
    log_err(-1,id,"could not obtain the needed permissions for the lock file");
 
2033
    }
 
2034
 
 
2035
  return(GoodPermissions);
 
2036
  }  /* END is_ha_lock_file_valid() */
 
2037
 
 
2038
 
 
2039
      
 
2040
/**
 
2041
 * Try to release a lock on the given file
 
2042
 *
 
2043
 * @param LockFile (I) Name of the file to unlock
 
2044
 * @param LockFD (I) file descriptor to unlock [modified]
 
2045
 *
 
2046
 * @return SUCCESS if the lock is released, FAILURE otherwise.
 
2047
 */
 
2048
int release_file_lock(
 
2049
 
 
2050
  char *Lockfile,
 
2051
  int  *LockFD)
 
2052
 
 
2053
  {
 
2054
  struct flock flock;
 
2055
  int fds;
 
2056
 
 
2057
  if ((Lockfile == NULL) ||
 
2058
      (LockFD == NULL))
 
2059
    {
 
2060
    return(FAILURE);
 
2061
    }
 
2062
 
 
2063
  if (ISEMPTYSTR(Lockfile))
 
2064
    {
 
2065
    return(FAILURE);
 
2066
    }
 
2067
 
 
2068
  if (*LockFD > 0)
 
2069
    {
 
2070
    fds = *LockFD;
 
2071
    }
 
2072
  else
 
2073
    {
 
2074
    fds = open(Lockfile,O_CREAT|O_TRUNC|O_WRONLY,0600);
 
2075
    }
 
2076
 
 
2077
  if (fds < 0)
 
2078
    {
 
2079
    /* could not open lock file */
 
2080
 
 
2081
    return(FAILURE);
 
2082
    }
 
2083
 
 
2084
  flock.l_type   = F_UNLCK;
 
2085
  flock.l_whence = SEEK_SET;
 
2086
  flock.l_start  = 0;
 
2087
  flock.l_len    = 0;
 
2088
 
 
2089
  if (fcntl(fds,F_SETLK,&flock) != 0)
 
2090
    {
 
2091
    close(fds);
 
2092
 
 
2093
    return(FAILURE);
 
2094
    }
 
2095
 
 
2096
  close(fds);
 
2097
 
 
2098
  *LockFD = 0;
 
2099
 
 
2100
  return(SUCCESS);
 
2101
  } /* END release_file_lock() */
 
2102
 
 
2103
 
 
2104
 
 
2105
 
 
2106
/** 
 
2107
 * Try to acquire a lock on the given file
 
2108
 *
 
2109
 * @param LockFile (I) the name of the file to lock.
 
2110
 * @param LockFD (I/O) File descriptor for the lock file.
 
2111
 * @param FileType (I) For logging (type of file lock)
 
2112
 *
 
2113
 * @return SUCCESS if the lock is acquired, FAILURE otherwise
 
2114
 */
 
2115
int acquire_file_lock(
 
2116
 
 
2117
  char *LockFile,
 
2118
  int  *LockFD,
 
2119
  char *FileType)
 
2120
 
 
2121
  {
 
2122
  struct flock flock;
 
2123
  int          fds;
 
2124
  char         id[] = "acquire_file_lock";
 
2125
 
 
2126
  if ((LockFile == NULL) ||
 
2127
      (LockFD == NULL) || 
 
2128
      (FileType == NULL))
 
2129
    {
 
2130
    return(FAILURE);
 
2131
    }
 
2132
 
 
2133
  if (LockFile[0] == '\0')
 
2134
    {
 
2135
    sprintf(log_buffer,"ALERT:   empty %s lock filename\n",
 
2136
      FileType);
 
2137
    log_err(-1,id,log_buffer);
 
2138
 
 
2139
    return(FAILURE);
 
2140
    }
 
2141
 
 
2142
  fds = open(LockFile,O_CREAT|O_RDWR,0600);
 
2143
 
 
2144
  if (fds < 0)
 
2145
    {
 
2146
    /* could not open lock file */
 
2147
 
 
2148
    sprintf(log_buffer,"ALERT:   could not open %s lock file '%s' (errno: %d:%s)\n",
 
2149
      FileType,
 
2150
      LockFile,
 
2151
      errno,
 
2152
      strerror(errno));
 
2153
    log_err(errno,id,log_buffer);
 
2154
 
 
2155
    return(FAILURE);
 
2156
    }
 
2157
 
 
2158
  flock.l_type   = F_WRLCK;
 
2159
  flock.l_whence = SEEK_SET;
 
2160
  flock.l_start  = 0;
 
2161
  flock.l_len    = 0;
 
2162
  flock.l_pid    = getpid();
 
2163
 
 
2164
  if (fcntl(fds,F_SETLK,&flock) != 0)
 
2165
    {
 
2166
    close(fds);
 
2167
 
 
2168
    sprintf(log_buffer,"ALERT   could not create lock on file '%s' (errno: %d:%s)\n",
 
2169
      LockFile,
 
2170
      errno,
 
2171
      strerror(errno));
 
2172
 
 
2173
    log_err(errno,id,log_buffer);
 
2174
 
 
2175
    return(FAILURE);
 
2176
    }
 
2177
 
 
2178
  /* don't close file; closing would lose the lock */
 
2179
 
 
2180
  *LockFD = fds;
 
2181
 
 
2182
  return(SUCCESS);
 
2183
  } /* END acquire_file_lock() */
 
2184
 
 
2185
 
 
2186
 
 
2187
 
 
2188
/**
 
2189
 *"Touch" the lockfile so that if locks are failing
 
2190
 * other processes can see we still have possession
 
2191
 * of the file. Also, we need to check that we can still
 
2192
 * acccess the file.
 
2193
 *
 
2194
 * @param Arg (I)
 
2195
 *
 
2196
 * @return FAILURE if we don't have possession of the lock file anymore
 
2197
 */
 
2198
void *update_ha_lock_thread(
 
2199
 
 
2200
  void *Arg) /* I */
 
2201
 
 
2202
  {
 
2203
  char EMsg[MAX_LINE];
 
2204
 
 
2205
  int LocalErrno = 0;
 
2206
  int rc = 0;
 
2207
  struct stat statbuf;
 
2208
  struct utimbuf timebuf;
 
2209
  static long LastModifyTime = 0;
 
2210
  char  id[] = "update_ha_lock_thread";
 
2211
 
 
2212
  if (ISEMPTYSTR(HALockFile))
 
2213
    {
 
2214
    /* locking HA not enabled */
 
2215
 
 
2216
    return(NULL);
 
2217
    }
 
2218
 
 
2219
  EMsg[0] = '\0';
 
2220
 
 
2221
  while (TRUE)
 
2222
    {
 
2223
    usleep(DEF_USPERSECOND * HALockUpdateTime);
 
2224
 
 
2225
    rc = 0;
 
2226
    LocalErrno = 0;
 
2227
    
 
2228
    mutex_lock(&EUIDMutex);
 
2229
    
 
2230
    errno = 0;
 
2231
    if (stat(HALockFile,&statbuf) == 0)
 
2232
      {
 
2233
      /* check to make sure that no other process has modified this file
 
2234
       * since the last time we did */
 
2235
      
 
2236
      if ((LastModifyTime > 0) && (LastModifyTime != statbuf.st_mtime))
 
2237
        {
 
2238
        snprintf(EMsg,sizeof(EMsg),"update time changed unexpectedly");
 
2239
 
 
2240
        rc = -1;
 
2241
        }
 
2242
      else
 
2243
        {
 
2244
        /* no one has touched this file since we last did--continue */
 
2245
 
 
2246
        LastModifyTime  = time(NULL);
 
2247
        timebuf.actime  = LastModifyTime;
 
2248
        timebuf.modtime = LastModifyTime;
 
2249
        
 
2250
        errno = 0;
 
2251
        rc = utime(HALockFile,&timebuf);
 
2252
        LocalErrno = errno;
 
2253
 
 
2254
        }
 
2255
      }
 
2256
    else
 
2257
      {
 
2258
      LocalErrno = errno;
 
2259
      rc = -1;
 
2260
 
 
2261
      snprintf(EMsg,sizeof(EMsg),"could not stat file");
 
2262
      }
 
2263
 
 
2264
    mutex_unlock(&EUIDMutex);
 
2265
 
 
2266
    /* NOTE: HALockFile is emptied out when we delete the file during shutdown */
 
2267
 
 
2268
    if ((rc == -1) && !ISEMPTYSTR(HALockFile))
 
2269
      {
 
2270
      char ErrorString[MAX_LINE];
 
2271
      /* error occurred--immediate shutdown needed */
 
2272
 
 
2273
      if (LocalErrno != 0)
 
2274
        {
 
2275
        strerror_r(LocalErrno,ErrorString,sizeof(ErrorString));
 
2276
 
 
2277
        sprintf(log_buffer,"could not update HA lock file '%s' in heartbeat thread (%s - errno %d:%s)",
 
2278
          HALockFile,
 
2279
          EMsg,
 
2280
          LocalErrno,
 
2281
          ErrorString);
 
2282
        
 
2283
        log_err(LocalErrno,id,log_buffer);
 
2284
        }
 
2285
      else
 
2286
        {
 
2287
        sprintf(log_buffer,"could not update HA lock file '%s' in heartbeat thread (%s)",
 
2288
          HALockFile,
 
2289
          EMsg);
 
2290
        
 
2291
        log_err(-1,id,log_buffer);
 
2292
        }
 
2293
 
 
2294
      /* restart pbs_server */
 
2295
 
 
2296
      svr_restart();
 
2297
      }
 
2298
    }  /* END while (TRUE) */
 
2299
 
 
2300
  /* NOTREACHED */
 
2301
  return(NULL);
 
2302
  } /* END update_ha_lock_thread() */
 
2303
 
 
2304
 
 
2305
 
 
2306
 
 
2307
 
 
2308
int start_update_ha_lock_thread()
 
2309
 
 
2310
  {
 
2311
#ifndef USE_HA_THREADS
 
2312
  /* not compiled with threads */
 
2313
 
 
2314
  log_err(-1,"start_update_ha_lock_thread",
 
2315
      "WARNING:   cannot create HA update thread - pthreads not enabled\n");
 
2316
 
 
2317
  return(FAILURE);
 
2318
#else /* USE_HA_THREADS is defined */
 
2319
 
 
2320
  pthread_t      HALockThread;
 
2321
  pthread_attr_t HALockThreadAttr;
 
2322
 
 
2323
  int rc;
 
2324
  int fds;
 
2325
 
 
2326
  char smallBuf[MAX_LINE];
 
2327
  char id[] = "start_update_ha_lock_thread";
 
2328
 
 
2329
  /* write the pid to the lockfile for correctness */
 
2330
  fds = open(HALockFile,O_TRUNC|O_WRONLY,0600);
 
2331
 
 
2332
  if (fds < 0)
 
2333
    {
 
2334
    log_err(-1,id,"Couldn't write the pid to the lockfile\n");
 
2335
 
 
2336
    return(FAILURE);
 
2337
    }
 
2338
 
 
2339
  snprintf(smallBuf,sizeof(smallBuf),"%ld\n",(long)sid); 
 
2340
  if (write(fds,smallBuf,strlen(smallBuf)) != (ssize_t)strlen(smallBuf))
 
2341
    {
 
2342
    log_err(-1,id,"Couldn't write the pid to the lockfile\n");
 
2343
 
 
2344
    return(FAILURE);
 
2345
    }
 
2346
 
 
2347
  /* we don't need an open handle on the lockfile, just correct update times */
 
2348
  close(fds);
 
2349
 
 
2350
  pthread_attr_init(&HALockThreadAttr);
 
2351
 
 
2352
  rc = pthread_create(&HALockThread,&HALockThreadAttr,update_ha_lock_thread,NULL);
 
2353
 
 
2354
  if (rc != 0)
 
2355
    {
 
2356
    /* error creating thread */
 
2357
 
 
2358
    log_err(-1,id,"Could not create HA Lock Thread\n");
 
2359
 
 
2360
    return(FAILURE);
 
2361
    }
 
2362
 
 
2363
  log_record(
 
2364
    PBSEVENT_SYSTEM,
 
2365
    PBS_EVENTCLASS_SERVER,
 
2366
    id,
 
2367
    "HA Lock update thread is now created\n");
 
2368
#endif /* ifndef USE_HA_THREADS */
 
2369
 
 
2370
  return(SUCCESS);
 
2371
  } /* END start_update_ha_lock_thread() */
 
2372
 
 
2373
 
 
2374
 
 
2375
 
 
2376
int mutex_lock(
 
2377
 
 
2378
  mutex_t *Mutex) /* I */
 
2379
 
 
2380
  {
 
2381
#ifdef USE_HA_THREADS
 
2382
  if (pthread_mutex_lock(Mutex) != 0)
 
2383
    {
 
2384
    log_err(-1,"mutex_lock","ALERT:   cannot lock mutex!\n");
 
2385
 
 
2386
    return(FAILURE);
 
2387
    }
 
2388
#endif /* ifdef USE_HA_THREADS */
 
2389
 
 
2390
  return(SUCCESS);
 
2391
  } /* END mutex_lock() */
 
2392
 
 
2393
 
 
2394
 
 
2395
 
 
2396
int mutex_unlock(
 
2397
 
 
2398
  mutex_t *Mutex) /* I */
 
2399
 
 
2400
  {
 
2401
#ifdef USE_HA_THREADS
 
2402
  if (pthread_mutex_unlock(Mutex) != 0)
 
2403
    {
 
2404
    log_err(-1,"mutex_unlock","ALERT:   cannot unlock mutex!\n");
 
2405
 
 
2406
    return(FAILURE);
 
2407
    }
 
2408
#endif /* ifdef USE_HA_THREADS */
 
2409
 
 
2410
  return(SUCCESS);
 
2411
  } /* END mutex_unlock() */
 
2412
 
 
2413
 
 
2414
 
 
2415
 
 
2416
 
 
2417
#ifdef USE_HA_THREADS
 
2418
/*
 
2419
 *  * lock_out_ha - lock out using moab style high availability
 
2420
 *   */
 
2421
static void lock_out_ha()
 
2422
 
 
2423
  {
 
2424
  bool_t     UseFLock = TRUE;
 
2425
  bool_t     FilePossession = FALSE;
 
2426
  bool_t     FileIsMissing = FALSE;
 
2427
 
 
2428
  char        MutexLockFile[MAX_NAME];
 
2429
  char        id[] = "lock_out_ha";
 
2430
 
 
2431
  int         MutexLockFD = -1;
 
2432
  int         NumChecks = 0;
 
2433
 
 
2434
  struct stat StatBuf;
 
2435
 
 
2436
  snprintf(MutexLockFile,sizeof(MutexLockFile),"%s.mutex",
 
2437
    HALockFile);
 
2438
 
 
2439
  time_now = time(NULL);
 
2440
 
 
2441
  while (!FilePossession)
 
2442
    {
 
2443
    if (NumChecks > 0)
 
2444
      {
 
2445
      usleep(DEF_USPERSECOND * HALockCheckTime);
 
2446
 
 
2447
      time_now = time(NULL);
 
2448
      
 
2449
      UseFLock = FALSE;
 
2450
      if (MutexLockFD > 0)
 
2451
        close(MutexLockFD);
 
2452
      }
 
2453
 
 
2454
    NumChecks++;
 
2455
 
 
2456
    if (is_ha_lock_file_valid(HALockFile) == FALSE)
 
2457
      {
 
2458
      UseFLock = TRUE;
 
2459
      }
 
2460
 
 
2461
    if (UseFLock == TRUE)
 
2462
      {
 
2463
      /* try to get a filesystem lock on the "mutex" file */
 
2464
 
 
2465
      while (acquire_file_lock(MutexLockFile,&MutexLockFD,"HA") == FAILURE)
 
2466
        {
 
2467
        strcpy(log_buffer,"Could not acquire HA flock--trying again in 1 second\n");
 
2468
        
 
2469
        usleep(DEF_USPERSECOND);
 
2470
        }
 
2471
      }
 
2472
    
 
2473
    /* check if file lock exists */
 
2474
 
 
2475
    if (stat(HALockFile,&StatBuf) == 0)
 
2476
      {
 
2477
      /* file DOES exist--check time */
 
2478
 
 
2479
      FileIsMissing = FALSE;
 
2480
 
 
2481
      if ((time_now - StatBuf.st_mtime) < HALockCheckTime)
 
2482
        {
 
2483
        /* someone else probably has the lock */
 
2484
 
 
2485
        continue;
 
2486
        }
 
2487
 
 
2488
      /* update the file to mark it as ours */
 
2489
 
 
2490
      utime(HALockFile,NULL);
 
2491
      
 
2492
      FilePossession = TRUE;
 
2493
      }
 
2494
    else
 
2495
      {
 
2496
      /* file doesn't exist--wait required amount of time and check again */
 
2497
      
 
2498
      if (FileIsMissing == FALSE)
 
2499
        {
 
2500
        FileIsMissing = TRUE;
 
2501
        
 
2502
        /* if we don't have a mutex to protect file creation
 
2503
         * race conditions, we need to wait and check again:
 
2504
         * otherwise we can safely create it immediately */
 
2505
        
 
2506
        if (UseFLock == FALSE)
 
2507
          continue;
 
2508
        }
 
2509
 
 
2510
      /* this is not the first time the file has been missing--we are
 
2511
       * probably safe to create it */
 
2512
 
 
2513
      HALockFD = open(HALockFile,O_CREAT|O_EXCL|O_RDONLY,0600);
 
2514
      
 
2515
      if (HALockFD < 0)
 
2516
        {
 
2517
        sprintf(log_buffer,"could not create HA lock file '%s'--errno %d:%s",
 
2518
          HALockFile,
 
2519
          errno,
 
2520
          strerror(errno));
 
2521
        
 
2522
        continue;
 
2523
        }
 
2524
      
 
2525
      FilePossession = TRUE;
 
2526
      }
 
2527
    
 
2528
    if (FilePossession == TRUE)
 
2529
      {
 
2530
      /* start heartbeat thread */
 
2531
      
 
2532
      start_update_ha_lock_thread();
 
2533
      }
 
2534
    
 
2535
    if (UseFLock == TRUE)
 
2536
      close(MutexLockFD); /* unlock file mutex */
 
2537
    } /* END while (!FilePossession) */
 
2538
  
 
2539
  /* we have the file lock--go ahead and log this fact */
 
2540
  
 
2541
  log_record(
 
2542
    PBSEVENT_SYSTEM,
 
2543
    PBS_EVENTCLASS_SERVER,
 
2544
    id,
 
2545
    "high availability file lock obtained");
 
2546
  } /* END lock_out_ha() */
 
2547
#endif /* USE_HA_THREADS */
 
2548
 
 
2549
 
 
2550
 
 
2551
 
 
2552
/**
 
2553
 * daemonize_server()
 
2554
 * figures out, based on the mode, whether or not to run in the background and does so
 
2555
 *
 
2556
 * @param DoBackground - (I) indicates whether or not we should run in the background
 
2557
 * @param sid - (O) set to the correct pid
 
2558
 * @return success unless we could not run in the background and we're supposed to
 
2559
 */
 
2560
static int daemonize_server(
 
2561
 
 
2562
  int  DoBackground,  /* I */
 
2563
  pid_t *sid)           /* O */
 
2564
 
 
2565
  {
 
2566
  int    pid;          
 
2567
  FILE  *dummyfile;
 
2568
  
 
2569
  char   id[] = "daemonize_server";
 
2570
  
 
2571
  if (!DoBackground)
 
2572
    {  
 
2573
    /* handle foreground (i.e. debug mode) */
 
2574
    
 
2575
    *sid = getpid();
 
2576
    
 
2577
    setvbuf(stdout,NULL,_IOLBF,0);
 
2578
    setvbuf(stderr,NULL,_IOLBF,0);
 
2579
    
 
2580
    return(SUCCESS);
 
2581
    }
 
2582
  
 
2583
  /* run pbs_server in the background */
 
2584
  
 
2585
  /* fork to disconnect from terminal */
 
2586
  
 
2587
  if ((pid = fork()) == -1)
 
2588
    {
 
2589
    log_err(errno,id,"cannot fork into background");
 
2590
    
 
2591
    return(FAILURE);
 
2592
   }
 
2593
  
 
2594
  
 
2595
  if (pid != 0)
 
2596
    {        
 
2597
     /* exit if parent */
 
2598
 
 
2599
     log_event(
 
2600
       PBSEVENT_SYSTEM,
 
2601
       PBS_EVENTCLASS_SERVER,
 
2602
       id,
 
2603
       "INFO:      parent is exiting");
 
2604
   
 
2605
     exit(0);
 
2606
    }
 
2607
 
 
2608
  /* NOTE: setsid() disconnects from controlling-terminal */
 
2609
  
 
2610
  if ((*sid = setsid()) == -1)
 
2611
    {
 
2612
    log_err(errno,id,"Could not disconnect from controlling terminal");
 
2613
 
 
2614
    return(FAILURE);
 
2615
    }    
 
2616
 
 
2617
  /* disconnect stdin,stdout,stderr */
 
2618
 
 
2619
  fclose(stdin);
 
2620
  fclose(stdout);
 
2621
  fclose(stderr);
 
2622
    
 
2623
  dummyfile = fopen("/dev/null","r");
 
2624
  assert((dummyfile != 0) && (fileno(dummyfile) == 0));
 
2625
    
 
2626
  dummyfile = fopen("/dev/null","w");
 
2627
  assert((dummyfile != 0) && (fileno(dummyfile) == 1));
 
2628
 
 
2629
  dummyfile = fopen("/dev/null","w");
 
2630
  assert((dummyfile != 0) && (fileno(dummyfile) == 2));
 
2631
    
 
2632
  if ((pid = fork()) == -1)
 
2633
    {
 
2634
    log_err(errno,id,"cannot fork into background");
 
2635
      
 
2636
    return(FAILURE);
 
2637
    }
 
2638
    
 
2639
  if (pid != 0)
 
2640
    {
 
2641
    /* exit if parent */
 
2642
 
 
2643
    log_event(
 
2644
      PBSEVENT_SYSTEM,
 
2645
      PBS_EVENTCLASS_SERVER,
 
2646
      id,
 
2647
      "INFO:      parent is exiting");
 
2648
      
 
2649
    exit(0);
 
2650
    }
 
2651
  
 
2652
  /* update the sid (pid written to the lock file) so that
 
2653
   * the correct pid is present */
 
2654
  *sid = getpid();
 
2655
 
 
2656
  log_event(
 
2657
    PBSEVENT_SYSTEM,
 
2658
    PBS_EVENTCLASS_SERVER,
 
2659
    id,
 
2660
    "INFO:      child process in background");
 
2661
    
 
2662
  return(SUCCESS);
 
2663
  } /* END daemonize_server() */
 
2664
 
 
2665
 
 
2666
 
 
2667
#ifndef USE_HA_THREADS
 
2668
/*
 
2669
 * lock_out - lock out other daemons from this directory.
 
2670
 */
 
2671
static void lock_out(
 
2672
 
 
2673
  int fds,
 
2674
  int op)   /* F_WRLCK  or  F_UNLCK */
 
2675
 
 
2676
  {
 
2677
  if (try_lock_out(fds,op))
 
2678
    {
 
2679
    strcpy(log_buffer,"pbs_server: another server running\n");
 
2680
   
 
2681
    
 
2682
    log_err(errno,msg_daemonname,log_buffer);
 
2683
    
 
2684
    fprintf(stderr,"%s", log_buffer);
 
2685
    
 
2686
    exit(1);
 
2687
    }
 
2688
  }
 
2689
 
 
2690
 
 
2691
/**
 
2692
 *  * Try to lock
 
2693
 *   * @return Zero on success, one on failure
 
2694
 *    */
1769
2695
static int try_lock_out(
1770
2696
 
1771
2697
  int fds,
1772
 
  int op)  /* F_WRLCK  or  F_UNLCK */
 
2698
  int op)   /* F_WRLCK  or  F_UNLCK */
1773
2699
 
1774
2700
  {
1775
 
 
1776
2701
  struct flock flock;
1777
 
 
 
2702
  
1778
2703
  flock.l_type   = op;
1779
2704
  flock.l_whence = SEEK_SET;
1780
2705
  flock.l_start  = 0;
1781
2706
  flock.l_len    = 0;
1782
 
 
1783
 
  return(fcntl(fds, F_SETLK, &flock) != 0);
1784
 
  }
1785
 
 
1786
 
 
1787
 
/*
1788
 
 * lock_out - lock out other daemons from this directory.
1789
 
 */
1790
 
static void lock_out(
1791
 
 
1792
 
  int fds,
1793
 
  int op)  /* F_WRLCK  or  F_UNLCK */
1794
 
 
1795
 
  {
1796
 
  if (try_lock_out(fds, op))
1797
 
    {
1798
 
    strcpy(log_buffer, "pbs_server: another server running\n");
1799
 
 
1800
 
    log_err(errno, msg_daemonname, log_buffer);
1801
 
 
1802
 
    fprintf(stderr, "%s", log_buffer);
1803
 
 
1804
 
    exit(1);
1805
 
    }
1806
 
  }
 
2707
  
 
2708
  return(fcntl(fds,F_SETLK,&flock) != 0);
 
2709
  }
 
2710
#endif /* !USE_HA_THREADS */
 
2711
 
 
2712
 
 
2713
 
 
2714
 
 
2715
/**
 
2716
 * gets attributes for the specified file/directory
 
2717
 *
 
2718
 * @param FileName (I)
 
2719
 * @param ModifyTime (O) [optional]
 
2720
 * @param FileSize   (O) [optional]
 
2721
 * @param IsExe      (O) [optional]
 
2722
 * @param IsDir      (O) [optional]
 
2723
 */
 
2724
 
 
2725
int get_file_info(
 
2726
 
 
2727
    char          *FileName,    /* I */
 
2728
    unsigned long *ModifyTime,  /* O (optional */
 
2729
    long          *FileSize,    /* O (optional */
 
2730
    bool_t        *IsExe,       /* O (optional */
 
2731
    bool_t        *IsDir)       /* O (optional */
 
2732
    
 
2733
  {
 
2734
  int   rc;
 
2735
  char *ptr;
 
2736
  char *id = "get_file_info";
 
2737
  
 
2738
  struct stat sbuf;
 
2739
  
 
2740
  if (IsExe != NULL)
 
2741
    *IsExe = FALSE;
 
2742
 
 
2743
  if (ModifyTime != NULL)
 
2744
    *ModifyTime = 0;
 
2745
  
 
2746
  if (FileSize != NULL)
 
2747
    *FileSize = 0;
 
2748
  
 
2749
  if (IsDir != NULL)
 
2750
    *IsDir = FALSE;
 
2751
  
 
2752
  if ((FileName == NULL) || (FileName[0] == '\0'))
 
2753
    {
 
2754
    return(FAILURE);   
 
2755
    }
 
2756
 
 
2757
  /* FORMAT:   <FILENAME>[ <ARG>]... */
 
2758
  
 
2759
  /* NOTE:  mask off, then restore possible args */
 
2760
  ptr = strchr(FileName,' ');
 
2761
  
 
2762
  if (ptr != NULL)
 
2763
    *ptr = '\0';
 
2764
  
 
2765
  rc = stat(FileName,&sbuf);
 
2766
 
 
2767
  if (rc == -1)
 
2768
    {
 
2769
    sprintf(log_buffer,"INFO:      cannot stat file '%s', errno: %d (%s)\n",
 
2770
      FileName,
 
2771
      errno,
 
2772
      strerror(errno));
 
2773
    
 
2774
    log_err(errno,id,log_buffer);
 
2775
    
 
2776
    return(FAILURE);
 
2777
    }
 
2778
  
 
2779
  if (ModifyTime != NULL)
 
2780
    {
 
2781
    *ModifyTime = (unsigned long)sbuf.st_mtime;
 
2782
    }
 
2783
  
 
2784
  if (FileSize != NULL)
 
2785
    {
 
2786
    *FileSize = (long)sbuf.st_size;
 
2787
    }
 
2788
  
 
2789
  if (IsExe != NULL)
 
2790
    {
 
2791
    if (sbuf.st_mode & S_IXUSR)
 
2792
      *IsExe = TRUE;
 
2793
    else
 
2794
      *IsExe = FALSE;
 
2795
    }
 
2796
  
 
2797
  if (IsDir != NULL)
 
2798
   {
 
2799
   if (sbuf.st_mode & S_IFDIR)
 
2800
     *IsDir = TRUE;
 
2801
   else
 
2802
     *IsDir = FALSE;
 
2803
   }
 
2804
  
 
2805
  return(SUCCESS);
 
2806
  } /* end get_file_info() */
 
2807
 
 
2808
 
 
2809
 
 
2810
 
 
2811
/**
 
2812
 * gets the full path for command
 
2813
 *
 
2814
 * @return SUCCESS if the path is found, FAILURE otherwise
 
2815
 */
 
2816
 
 
2817
int get_full_path(
 
2818
 
 
2819
  char *Cmd,         /* I */
 
2820
  char *GoodCmd,     /* O */
 
2821
  int   GoodCmdLen)  /* O */
 
2822
 
 
2823
  {
 
2824
  char   *TokPtr = NULL;
 
2825
  char   *Delims = ":;"; /* windows and unix path deliminators */
 
2826
  char   *PathLocation;
 
2827
  char    tmpPath[MAX_LINE];
 
2828
  bool_t  IsExe = FALSE;
 
2829
  bool_t  IsDir = FALSE;
 
2830
  
 
2831
  if (Cmd[0] == '/')
 
2832
    {
 
2833
    /* absolute path specified */
 
2834
    
 
2835
    if (get_file_info(Cmd,NULL,NULL,&IsExe,&IsDir) == FAILURE)
 
2836
      {
 
2837
      return(FAILURE);
 
2838
      }
 
2839
    
 
2840
    if ((IsExe == FALSE) && (IsDir == FALSE))
 
2841
      {
 
2842
      return(FAILURE);
 
2843
      }
 
2844
 
 
2845
    snprintf(GoodCmd,GoodCmdLen,"%s",Cmd);
 
2846
 
 
2847
    return(SUCCESS);
 
2848
    }
 
2849
    
 
2850
  PathLocation = strtok_r(OriginalPath,Delims,&TokPtr);
 
2851
 
 
2852
  while (PathLocation != NULL)
 
2853
    {
 
2854
    if (strlen(PathLocation) <= 0)
 
2855
      {
 
2856
      PathLocation = strtok_r(NULL,Delims,&TokPtr);
 
2857
      
 
2858
      continue;
 
2859
      }
 
2860
    
 
2861
    if (PathLocation[strlen(PathLocation) - 1] == '/')
 
2862
      {
 
2863
      sprintf(tmpPath,"%s%s",
 
2864
        PathLocation,
 
2865
        Cmd);
 
2866
      }
 
2867
    else
 
2868
      {
 
2869
      sprintf(tmpPath,"%s/%s",
 
2870
        PathLocation,
 
2871
        Cmd);
 
2872
      }
 
2873
    
 
2874
    if (get_file_info(tmpPath,NULL,NULL,&IsExe,NULL) == FAILURE)
 
2875
      {
 
2876
      PathLocation = strtok_r(NULL,Delims,&TokPtr);
 
2877
      
 
2878
      continue;
 
2879
     }
 
2880
    
 
2881
    if (IsExe == FALSE)
 
2882
      {
 
2883
      PathLocation = strtok_r(NULL,Delims,&TokPtr);
 
2884
      
 
2885
      continue;
 
2886
      }
 
2887
    
 
2888
    snprintf(GoodCmd,GoodCmdLen,"%s",tmpPath);
 
2889
    
 
2890
    return(SUCCESS);
 
2891
    } /* END while (PathLocation != NULL) */
 
2892
  
 
2893
  return(FAILURE);
 
2894
  } /* END get_full_path() */
 
2895
 
 
2896
 
 
2897
 
 
2898
 
 
2899
/**
 
2900
 *  * Restarts the pbs_server
 
2901
 *   */
 
2902
 
 
2903
int svr_restart()
 
2904
 
 
2905
  {
 
2906
  int   rc;
 
2907
  
 
2908
  char  FullCmd[MAX_LINE];
 
2909
  char *id = "svr_restart";
 
2910
  
 
2911
  if (get_full_path(
 
2912
        ArgV[0],
 
2913
        FullCmd,
 
2914
        sizeof(FullCmd)) == FAILURE)
 
2915
    {
 
2916
    sprintf(log_buffer,"ALERT:      cannot locate full path for '%s'\n",
 
2917
      ArgV[0]);
 
2918
    
 
2919
    log_err(-1,id,log_buffer);
 
2920
 
 
2921
    exit(-10);
 
2922
    }
 
2923
  
 
2924
  /* shut down network connections and rpp */
 
2925
 
 
2926
  RPPConfigure(1,0);  /* help rpp_shutdown go a bit faster */
 
2927
  rpp_shutdown();
 
2928
  
 
2929
  net_close(-1);   /* close all network connections */
 
2930
  
 
2931
  /* copying FullCmd to ArV[0] is necessary for multiple restarts because 
 
2932
   * the path changes when we run pbs_server in the background. */
 
2933
  
 
2934
  if (strcmp(FullCmd,ArgV[0]) != 0)
 
2935
    {
 
2936
    free(ArgV[0]);
 
2937
    
 
2938
    ArgV[0] = malloc(sizeof(char) * (strlen(FullCmd) + 1));
 
2939
    
 
2940
    if (ArgV[0] == NULL)
 
2941
      {
 
2942
      /* could not malloc */
 
2943
      
 
2944
      log_err(errno,id,"ERROR:     cannot allocate memory for full command, cannot restart\n");
 
2945
      
 
2946
      exit(-10);
 
2947
      }
 
2948
    
 
2949
    strcpy(ArgV[0],FullCmd);
 
2950
    }
 
2951
 
 
2952
  sprintf(log_buffer,"INFO:     about to exec '%s'\n",ArgV[0]);
 
2953
 
 
2954
  log_event(
 
2955
    PBSEVENT_SYSTEM,
 
2956
    PBS_EVENTCLASS_SERVER,
 
2957
    id,
 
2958
    log_buffer);
 
2959
  
 
2960
  log_close(1);
 
2961
  
 
2962
  if ((rc = execv(FullCmd,ArgV)) == -1)
 
2963
    {
 
2964
    /* exec failed */
 
2965
    
 
2966
    exit(-10);
 
2967
    }
 
2968
  
 
2969
  /* NOT REACHED */
 
2970
  
 
2971
  exit(0);
 
2972
  
 
2973
  return(SUCCESS);
 
2974
  }  /* END svr_restart() */
 
2975
 
 
2976
 
 
2977
 
 
2978
/**
 
2979
 *
 
2980
 * restores this attribute to its default where supported/possible
 
2981
 */
 
2982
 
 
2983
void restore_attr_default(
 
2984
 
 
2985
  struct attribute *attr) /* I */
 
2986
 
 
2987
  {
 
2988
  int index;
 
2989
 
 
2990
  index = (int)(attr - server.sv_attr);
 
2991
 
 
2992
  attr->at_flags &= ~ATR_VFLAG_SET;
 
2993
 
 
2994
  switch (index)
 
2995
    {
 
2996
    case SRV_ATR_log_events:
 
2997
 
 
2998
      server.sv_attr[(int)SRV_ATR_log_events].at_val.at_long = PBSEVENT_MASK;
 
2999
 
 
3000
      break;
 
3001
 
 
3002
    case SRV_ATR_tcp_timeout:
 
3003
 
 
3004
      server.sv_attr[(int)SRV_ATR_tcp_timeout].at_val.at_long = PBS_TCPTIMEOUT;
 
3005
 
 
3006
      break;
 
3007
 
 
3008
    case SRV_ATR_JobStatRate:
 
3009
 
 
3010
      server.sv_attr[(int)SRV_ATR_JobStatRate].at_val.at_long = PBS_RESTAT_JOB;
 
3011
 
 
3012
      break;
 
3013
 
 
3014
    case SRV_ATR_PollJobs:
 
3015
 
 
3016
      server.sv_attr[(int)SRV_ATR_PollJobs].at_val.at_long = PBS_POLLJOBS;
 
3017
 
 
3018
      break;
 
3019
 
 
3020
    case SRV_ATR_LogLevel:
 
3021
 
 
3022
      server.sv_attr[(int)SRV_ATR_LogLevel].at_val.at_long = 0;
 
3023
 
 
3024
      break; 
 
3025
 
 
3026
    default:
 
3027
 
 
3028
      /* should never get here, but if we do then reset the flags so the user knows 
 
3029
       * that the value hasn't been cleared */
 
3030
 
 
3031
      attr->at_flags |= ATR_VFLAG_SET;
 
3032
 
 
3033
      break;
 
3034
    }
 
3035
 
 
3036
  } /* END restore_attr_default() */
 
3037
 
1807
3038
 
1808
3039
/* END pbsd_main.c */
1809
3040