~ubuntu-branches/ubuntu/vivid/slurm-llnl/vivid

« back to all changes in this revision

Viewing changes to src/slurmd/slurmstepd/io.c

  • Committer: Bazaar Package Importer
  • Author(s): Gennaro Oliva
  • Date: 2009-09-24 23:28:15 UTC
  • mfrom: (1.1.11 upstream) (3.2.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090924232815-enh65jn32q1ebg07
Tags: 2.0.5-1
* New upstream release 
* Changed dependecy from lib-mysqlclient15 to lib-mysqlclient 
* Added Default-Start for runlevel 2 and 4 and $remote_fs requirement in
  init.d scripts (Closes: #541252)
* Postinst checks for wrong runlevels 2 and 4 links
* Upgraded to standard version 3.8.3
* Add lintian overrides for missing slurm-llnl-configurator.html in doc
  base registration
* modified postrm scripts to ignore pkill return value in order to avoid
  postrm failure when no slurm process is running
* Checking for slurmctld.pid before cancelling running and pending
  jobs during package removal 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************\
2
2
 * src/slurmd/slurmstepd/io.c - Standard I/O handling routines for slurmstepd
3
 
 * $Id: io.c 13672 2008-03-19 23:10:58Z jette $
 
3
 * $Id: io.c 17962 2009-06-24 19:41:49Z da $
4
4
 *****************************************************************************
5
5
 *  Copyright (C) 2002 The Regents of the University of California.
6
6
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
7
7
 *  Written by Mark Grondona <mgrondona@llnl.gov>.
8
 
 *  LLNL-CODE-402394.
 
8
 *  CODE-OCEC-09-009. All rights reserved.
9
9
 *  
10
10
 *  This file is part of SLURM, a resource management program.
11
 
 *  For details, see <http://www.llnl.gov/linux/slurm/>.
 
11
 *  For details, see <https://computing.llnl.gov/linux/slurm/>.
 
12
 *  Please also read the included file: DISCLAIMER.
12
13
 *  
13
14
 *  SLURM is free software; you can redistribute it and/or modify it under
14
15
 *  the terms of the GNU General Public License as published by the Free
79
80
#include "src/common/xmalloc.h"
80
81
#include "src/common/xsignal.h"
81
82
#include "src/common/xstring.h"
 
83
#include "src/common/write_labelled_message.h"
82
84
 
83
85
#include "src/slurmd/slurmd/slurmd.h"
84
86
#include "src/slurmd/slurmstepd/io.h"
118
120
        struct io_buf *out_msg;
119
121
        int32_t out_remaining;
120
122
        bool out_eof;
121
 
};
 
123
 
 
124
        /* For clients that only write stdout or stderr, and/or only
 
125
           write for one task. -1 means accept output from any task. */
 
126
        int  ltaskid_stdout, ltaskid_stderr;
 
127
        bool labelio;
 
128
        int  label_width;
 
129
 
 
130
        /* true if writing to a file, false if writing to a socket */
 
131
        bool is_local_file;
 
132
};
 
133
 
 
134
 
 
135
static bool _local_file_writable(eio_obj_t *);
 
136
static int  _local_file_write(eio_obj_t *, List);
 
137
 
 
138
struct io_operations local_file_ops = {
 
139
        writable:       &_local_file_writable,
 
140
        handle_write:   &_local_file_write,
 
141
};
 
142
 
122
143
 
123
144
/**********************************************************************
124
145
 * Task write declarations
452
473
        return SLURM_SUCCESS;
453
474
}
454
475
 
 
476
 
 
477
static bool 
 
478
_local_file_writable(eio_obj_t *obj)
 
479
{
 
480
        struct client_io_info *client = (struct client_io_info *) obj->arg;
 
481
 
 
482
        xassert(client->magic == CLIENT_IO_MAGIC);
 
483
 
 
484
        if (client->out_eof == true)
 
485
                return false;
 
486
 
 
487
        if (client->out_msg != NULL || !list_is_empty(client->msg_queue))
 
488
                return true;
 
489
 
 
490
        return false;
 
491
}
 
492
 
 
493
 
 
494
/*
 
495
 * The slurmstepd writes I/O to a file, possibly adding a label.
 
496
 */
 
497
static int
 
498
_local_file_write(eio_obj_t *obj, List objs)
 
499
{
 
500
        struct client_io_info *client = (struct client_io_info *) obj->arg;
 
501
        void *buf;
 
502
        int n;
 
503
        struct slurm_io_header header;
 
504
        Buf header_tmp_buf;
 
505
 
 
506
        xassert(client->magic == CLIENT_IO_MAGIC);
 
507
        /*
 
508
         * If we aren't already in the middle of sending a message, get the
 
509
         * next message from the queue.
 
510
         */
 
511
        if (client->out_msg == NULL) {
 
512
                client->out_msg = list_dequeue(client->msg_queue);
 
513
                if (client->out_msg == NULL) {
 
514
                        return SLURM_SUCCESS;
 
515
                }
 
516
                client->out_remaining = client->out_msg->length - 
 
517
                                        io_hdr_packed_size();
 
518
        }
 
519
 
 
520
        /* This code to make a buffer, fill it, unpack its contents, and free
 
521
           it is just used to read the header to get the global task id. */
 
522
        header_tmp_buf = create_buf(client->out_msg->data, 
 
523
                                    client->out_msg->length);
 
524
        io_hdr_unpack(&header, header_tmp_buf);
 
525
        header_tmp_buf->head = NULL;
 
526
        free_buf(header_tmp_buf);
 
527
 
 
528
        /* A zero-length message indicates the end of a stream from one
 
529
           of the tasks.  Just free the message and return. */
 
530
        if (header.length == 0) {
 
531
                _free_outgoing_msg(client->out_msg, client->job);
 
532
                client->out_msg = NULL;
 
533
                return SLURM_SUCCESS;
 
534
        }
 
535
 
 
536
        /* Write the message to the file. */
 
537
        buf = client->out_msg->data + 
 
538
                (client->out_msg->length - client->out_remaining);
 
539
 
 
540
        n = write_labelled_message(obj->fd, buf, client->out_remaining, 
 
541
                                   header.gtaskid, client->labelio, 
 
542
                                   client->label_width);
 
543
        if (n < 0) {
 
544
                client->out_eof = true;
 
545
                _free_all_outgoing_msgs(client->msg_queue, client->job);
 
546
                return SLURM_ERROR;
 
547
        }
 
548
 
 
549
        client->out_remaining -= n;
 
550
        if (client->out_remaining == 0) {
 
551
                _free_outgoing_msg(client->out_msg, client->job);
 
552
                client->out_msg = NULL;
 
553
        }
 
554
        return SLURM_SUCCESS;
 
555
}
 
556
 
 
557
 
 
558
 
 
559
 
455
560
/**********************************************************************
456
561
 * Task write functions
457
562
 **********************************************************************/
541
646
        }
542
647
 
543
648
        /*
544
 
         * Write message to socket.
 
649
         * Write message to pipe.
545
650
         */
546
651
        buf = in->msg->data + (in->msg->length - in->remaining);
547
652
again:
798
903
static int
799
904
_init_task_stdio_fds(slurmd_task_info_t *task, slurmd_job_t *job)
800
905
{
801
 
        slurm_ctl_conf_t *conf;
802
 
        int file_flags;
803
 
 
804
 
        /* set files for opening stdout/err */
805
 
        if (job->open_mode == OPEN_MODE_APPEND)
806
 
                file_flags = O_CREAT|O_WRONLY|O_APPEND;
807
 
        else if (job->open_mode == OPEN_MODE_TRUNCATE)
808
 
                file_flags = O_CREAT|O_WRONLY|O_APPEND|O_TRUNC;
809
 
        else {
810
 
                conf = slurm_conf_lock();
811
 
                if (conf->job_file_append)
812
 
                        file_flags = O_CREAT|O_WRONLY|O_APPEND;
813
 
                else
814
 
                        file_flags = O_CREAT|O_WRONLY|O_APPEND|O_TRUNC;
815
 
                slurm_conf_unlock();
816
 
        }
 
906
        int file_flags = io_get_file_flags(job);
817
907
 
818
908
        /*
819
909
         *  Initialize stdin
855
945
                /* open file on task's stdin */
856
946
                debug5("  stdin file name = %s", task->ifname);
857
947
                if ((task->stdin_fd = open(task->ifname, O_RDONLY)) == -1) {
858
 
                        error("Could not open stdin file: %m");
 
948
                        error("Could not open stdin file %s: %m", task->ifname);
859
949
                        return SLURM_ERROR;
860
950
                }
861
951
                fd_set_close_on_exec(task->stdin_fd);
899
989
                        fd_set_close_on_exec(task->stdout_fd);
900
990
                        task->from_stdout = -1;  /* not used */
901
991
                }
902
 
        } else if (task->ofname != NULL) {
 
992
        } else if (task->ofname != NULL && 
 
993
                   (!job->labelio || strcmp(task->ofname, "/dev/null")==0)) {
903
994
#else
904
 
        if (task->ofname != NULL) {
 
995
        if (task->ofname != NULL && 
 
996
            (!job->labelio || strcmp(task->ofname, "/dev/null")==0) ) {
905
997
#endif
906
998
                /* open file on task's stdout */
907
999
                debug5("  stdout file name = %s", task->ofname);
908
1000
                task->stdout_fd = open(task->ofname, file_flags, 0666);
909
1001
                if (task->stdout_fd == -1) {
910
 
                        error("Could not open stdout file: %m");
911
 
                        xfree(task->ofname);
912
 
                        task->ofname = fname_create(job, "slurm-%J.out", 0);
913
 
                        task->stdout_fd = open(task->ofname, file_flags, 0666);
914
 
                        if (task->stdout_fd == -1)
915
 
                                return SLURM_ERROR;
 
1002
                        error("Could not open stdout file %s: %m",
 
1003
                              task->ofname);
 
1004
                        return SLURM_ERROR;
916
1005
                }
917
1006
                fd_set_close_on_exec(task->stdout_fd);
918
1007
                task->from_stdout = -1; /* not used */
941
1030
#ifdef HAVE_PTY_H
942
1031
        if (job->pty) {
943
1032
                if (task->gtid == 0) {
 
1033
                        /* Make a file descriptor for the task to write to, but
 
1034
                           don't make a separate one read from, because in pty 
 
1035
                           mode we can't distinguish between stdout and stderr
 
1036
                           coming from the remote shell.  Both streams from the
 
1037
                           shell will go to task->stdout_fd, which is okay in 
 
1038
                           pty mode because any output routed through the stepd
 
1039
                           will be displayed. */
944
1040
                        task->stderr_fd = dup(task->stdin_fd);
945
1041
                        fd_set_close_on_exec(task->stderr_fd);
946
 
                        task->from_stderr = dup(task->to_stdin);
947
 
                        fd_set_close_on_exec(task->from_stderr);
948
 
                        fd_set_nonblocking(task->from_stderr);
949
 
                        task->err = _create_task_out_eio(task->from_stderr,
950
 
                                                 SLURM_IO_STDERR, job, task);
951
 
                        list_append(job->stderr_eio_objs, (void *)task->err);
952
 
                        eio_new_initial_obj(job->eio, (void *)task->err);
 
1042
                        task->from_stderr = -1;
953
1043
                } else {
954
1044
                        xfree(task->efname);
955
1045
                        task->efname = xstrdup("/dev/null");
957
1047
                        fd_set_close_on_exec(task->stderr_fd);
958
1048
                        task->from_stderr = -1;  /* not used */
959
1049
                }
960
 
        } else if (task->efname != NULL) {
 
1050
        } else if (task->efname != NULL && 
 
1051
                   (!job->labelio || strcmp(task->efname, "/dev/null")==0)) {
961
1052
#else
962
 
        if (task->efname != NULL) {
 
1053
        if (task->efname != NULL && 
 
1054
            (!job->labelio || strcmp(task->efname, "/dev/null")==0) ) {
963
1055
#endif
964
1056
                /* open file on task's stdout */
965
1057
                debug5("  stderr file name = %s", task->efname);
966
1058
                task->stderr_fd = open(task->efname, file_flags, 0666);
967
1059
                if (task->stderr_fd == -1) {
968
 
                        error("Could not open stderr file: %m");
969
 
                        xfree(task->efname);
970
 
                        task->efname = fname_create(job, "slurm-%J.err", 0);
971
 
                        task->stderr_fd = open(task->efname, file_flags, 0666);
972
 
                        if (task->stderr_fd == -1)
973
 
                                return SLURM_ERROR;
 
1060
                        error("Could not open stderr file %s: %m",
 
1061
                              task->efname);
 
1062
                        return SLURM_ERROR;
974
1063
                }
975
1064
                fd_set_close_on_exec(task->stderr_fd);
976
1065
                task->from_stderr = -1; /* not used */
999
1088
int
1000
1089
io_init_tasks_stdio(slurmd_job_t *job)
1001
1090
{
1002
 
        int i;
 
1091
        int i, rc = SLURM_SUCCESS, tmprc;
1003
1092
 
1004
1093
        for (i = 0; i < job->ntasks; i++) {
1005
 
                _init_task_stdio_fds(job->task[i], job);
 
1094
                tmprc = _init_task_stdio_fds(job->task[i], job);
 
1095
                if (tmprc != SLURM_SUCCESS)
 
1096
                        rc = tmprc;
1006
1097
        }
1007
1098
 
1008
 
        return 0;
 
1099
        return rc;
1009
1100
}
1010
1101
 
1011
1102
int
1070
1161
                if (msg == NULL)
1071
1162
                        return;
1072
1163
 
1073
 
/*              debug5("\"%s\"", msg->data + io_hdr_packed_size()); */
1074
 
 
1075
1164
                /* Add message to the msg_queue of all clients */
1076
1165
                clients = list_iterator_create(out->job->clients);
1077
1166
                while((eio = list_next(clients))) {
1078
1167
                        client = (struct client_io_info *)eio->arg;
1079
1168
                        if (client->out_eof == true)
1080
1169
                                continue;
 
1170
 
 
1171
                        /* Some clients only take certain I/O streams */
 
1172
                        if (out->type==SLURM_IO_STDOUT) {
 
1173
                                if (client->ltaskid_stdout != -1 && 
 
1174
                                    client->ltaskid_stdout != out->ltaskid)
 
1175
                                        continue;
 
1176
                        }
 
1177
                        if (out->type==SLURM_IO_STDERR) {
 
1178
                                if (client->ltaskid_stderr != -1 && 
 
1179
                                    client->ltaskid_stderr != out->ltaskid)
 
1180
                                        continue;
 
1181
                        }
 
1182
 
1081
1183
                        debug5("======================== Enqueued message");
1082
1184
                        xassert(client->magic == CLIENT_IO_MAGIC);
1083
1185
                        if (list_enqueue(client->msg_queue, msg))
1180
1282
         *  and log facility may still try to write to stderr.
1181
1283
         */
1182
1284
        if ((devnull = open("/dev/null", O_RDWR)) < 0) {
1183
 
                error("Unable to open /dev/null: %m");
 
1285
                error("Could not open /dev/null: %m");
1184
1286
        } else {
1185
1287
                if (dup2(devnull, STDERR_FILENO) < 0)
1186
1288
                        error("Unable to dup /dev/null onto stderr\n");
1192
1294
        eio_signal_shutdown(job->eio);
1193
1295
}
1194
1296
 
 
1297
void 
 
1298
io_close_local_fds(slurmd_job_t *job)
 
1299
{
 
1300
        ListIterator clients;
 
1301
        eio_obj_t *eio;
 
1302
        int rc;
 
1303
        struct client_io_info *client;
 
1304
 
 
1305
        if (job == NULL || job->clients == NULL)
 
1306
                return;
 
1307
 
 
1308
        clients = list_iterator_create(job->clients);
 
1309
        while((eio = list_next(clients))) {
 
1310
                client = (struct client_io_info *)eio->arg;
 
1311
                if (client->is_local_file) {
 
1312
                        if (eio->fd >= 0) {
 
1313
                                do {
 
1314
                                        rc = close(eio->fd);
 
1315
                                } while (rc == -1 && errno == EINTR);
 
1316
                                eio->fd = -1;
 
1317
                        }
 
1318
                }
 
1319
        }
 
1320
}
 
1321
 
 
1322
 
 
1323
 
1195
1324
static void *
1196
1325
_io_thr(void *arg)
1197
1326
{
1198
1327
        slurmd_job_t *job = (slurmd_job_t *) arg;
1199
1328
        sigset_t set;
 
1329
        int rc;
1200
1330
 
1201
1331
        /* A SIGHUP signal signals a reattach to the mgr thread.  We need
1202
1332
         * to block SIGHUP from being delivered to this thread so the mgr
1208
1338
        pthread_sigmask(SIG_BLOCK, &set, NULL);
1209
1339
 
1210
1340
        debug("IO handler started pid=%lu", (unsigned long) getpid());
1211
 
        eio_handle_mainloop(job->eio);
1212
 
        debug("IO handler exited");
 
1341
        rc = eio_handle_mainloop(job->eio);
 
1342
        debug("IO handler exited, rc=%d", rc);
1213
1343
        return (void *)1;
1214
1344
}
1215
1345
 
 
1346
/*
 
1347
 *  Add a client to the job's client list that will write stdout and/or
 
1348
 *  stderr from the slurmstepd.  The slurmstepd handles the write when
 
1349
 *  a file is created per node or per task, and the output needs to be
 
1350
 *  modified in some way, like labelling lines with the task number.
 
1351
 */
 
1352
int
 
1353
io_create_local_client(const char *filename, int file_flags, 
 
1354
                       slurmd_job_t *job, bool labelio,
 
1355
                       int stdout_tasks, int stderr_tasks)
 
1356
{
 
1357
        int fd = -1;
 
1358
        struct client_io_info *client;
 
1359
        eio_obj_t *obj;
 
1360
        int tmp;
 
1361
 
 
1362
        fd = open(filename, file_flags, 0666);
 
1363
        if (fd == -1) {
 
1364
                return ESLURMD_IO_ERROR;
 
1365
        }
 
1366
        fd_set_close_on_exec(fd);
 
1367
 
 
1368
        /* Now set up the eio object */
 
1369
        client = xmalloc(sizeof(struct client_io_info));
 
1370
#ifndef NDEBUG
 
1371
        client->magic = CLIENT_IO_MAGIC;
 
1372
#endif
 
1373
        client->job = job;
 
1374
        client->msg_queue = list_create(NULL); /* FIXME - destructor */
 
1375
 
 
1376
        client->ltaskid_stdout = stdout_tasks;
 
1377
        client->ltaskid_stderr = stderr_tasks;
 
1378
        client->labelio = labelio;
 
1379
        client->is_local_file = true;
 
1380
 
 
1381
        client->label_width = 1;
 
1382
        tmp = job->ntasks-1;
 
1383
        while ((tmp /= 10) > 0)
 
1384
                client->label_width++;
 
1385
 
 
1386
 
 
1387
        obj = eio_obj_create(fd, &local_file_ops, (void *)client);
 
1388
        list_append(job->clients, (void *)obj);
 
1389
        eio_new_initial_obj(job->eio, (void *)obj);
 
1390
        debug5("Now handling %d IO Client object(s)", list_count(job->clients));
 
1391
 
 
1392
        return SLURM_SUCCESS;
 
1393
}
 
1394
 
1216
1395
/* 
1217
1396
 * Create the initial TCP connection back to a waiting client (e.g. srun).
1218
1397
 *
1224
1403
 * an IO stream.
1225
1404
 */
1226
1405
int
1227
 
io_initial_client_connect(srun_info_t *srun, slurmd_job_t *job)
 
1406
io_initial_client_connect(srun_info_t *srun, slurmd_job_t *job, 
 
1407
                          int stdout_tasks, int stderr_tasks)
1228
1408
{
1229
1409
        int sock = -1;
1230
1410
        struct client_io_info *client;
1267
1447
        client->job = job;
1268
1448
        client->msg_queue = list_create(NULL); /* FIXME - destructor */
1269
1449
 
 
1450
        client->ltaskid_stdout = stdout_tasks;
 
1451
        client->ltaskid_stderr = stderr_tasks;
 
1452
        client->labelio = false;
 
1453
        client->label_width = 0;
 
1454
        client->is_local_file = false;
 
1455
 
1270
1456
        obj = eio_obj_create(sock, &client_ops, (void *)client);
1271
1457
        list_append(job->clients, (void *)obj);
1272
1458
        eio_new_initial_obj(job->eio, (void *)obj);
1320
1506
#endif
1321
1507
        client->job = job;
1322
1508
        client->msg_queue = NULL; /* initialized in _client_writable */
 
1509
 
 
1510
        client->ltaskid_stdout = -1;     /* accept from all tasks */
 
1511
        client->ltaskid_stderr = -1;     /* accept from all tasks */
 
1512
        client->labelio = false;
 
1513
        client->label_width = 0;
 
1514
        client->is_local_file = false;
 
1515
 
1323
1516
        /* client object adds itself to job->clients in _client_writable */
1324
1517
 
1325
1518
        obj = eio_obj_create(sock, &client_ops, (void *)client);
1426
1619
                client = (struct client_io_info *)eio->arg;
1427
1620
                debug5("======================== Enqueued eof message");
1428
1621
                xassert(client->magic == CLIENT_IO_MAGIC);
 
1622
 
 
1623
                /* Some clients only take certain I/O streams */
 
1624
                if (out->type==SLURM_IO_STDOUT) {
 
1625
                        if (client->ltaskid_stdout != -1 && 
 
1626
                            client->ltaskid_stdout != out->ltaskid)
 
1627
                                continue;
 
1628
                }
 
1629
                if (out->type==SLURM_IO_STDERR) {
 
1630
                        if (client->ltaskid_stderr != -1 && 
 
1631
                            client->ltaskid_stderr != out->ltaskid)
 
1632
                                continue;
 
1633
                }
 
1634
 
1429
1635
                if (list_enqueue(client->msg_queue, msg))
1430
1636
                        msg->ref_count++;
1431
1637
        }
1624
1830
        return SLURM_SUCCESS;
1625
1831
}
1626
1832
 
 
1833
 
 
1834
void
 
1835
io_find_filename_pattern( slurmd_job_t *job, 
 
1836
                          slurmd_filename_pattern_t *outpattern, 
 
1837
                          slurmd_filename_pattern_t *errpattern,
 
1838
                          bool *same_out_err_files )
 
1839
{
 
1840
        int ii, jj;
 
1841
        int of_num_null = 0, ef_num_null = 0;
 
1842
        int of_num_devnull = 0, ef_num_devnull = 0;
 
1843
        int of_lastnull = -1, ef_lastnull = -1;
 
1844
        bool of_all_same = true, ef_all_same = true;
 
1845
        bool of_all_unique = true, ef_all_unique = true;
 
1846
 
 
1847
        *outpattern = SLURMD_UNKNOWN;
 
1848
        *errpattern = SLURMD_UNKNOWN;
 
1849
        *same_out_err_files = false;
 
1850
 
 
1851
        for (ii = 0; ii < job->ntasks; ii++) {
 
1852
                if (job->task[ii]->ofname == NULL) {
 
1853
                        of_num_null++;
 
1854
                        of_lastnull = ii;
 
1855
                } else if (strcmp(job->task[ii]->ofname, "/dev/null")==0) {
 
1856
                        of_num_devnull++;
 
1857
                }
 
1858
 
 
1859
                if (job->task[ii]->efname == NULL) {
 
1860
                        ef_num_null++;
 
1861
                        ef_lastnull = ii;
 
1862
                } else if (strcmp(job->task[ii]->efname, "/dev/null")==0) {
 
1863
                        ef_num_devnull++;
 
1864
                }
 
1865
        }
 
1866
        if (of_num_null == job->ntasks)
 
1867
                *outpattern = SLURMD_ALL_NULL;
 
1868
 
 
1869
        if (ef_num_null == job->ntasks)
 
1870
                *errpattern = SLURMD_ALL_NULL;
 
1871
 
 
1872
        if (of_num_null == 1 && of_num_devnull == job->ntasks-1)
 
1873
                *outpattern = SLURMD_ONE_NULL;
 
1874
 
 
1875
        if (ef_num_null == 1 && ef_num_devnull == job->ntasks-1)
 
1876
                *errpattern = SLURMD_ONE_NULL;
 
1877
 
 
1878
        if (*outpattern == SLURMD_ALL_NULL && *errpattern == SLURMD_ALL_NULL)
 
1879
                *same_out_err_files = true;
 
1880
 
 
1881
        if (*outpattern == SLURMD_ONE_NULL && *errpattern == SLURMD_ONE_NULL &&
 
1882
            of_lastnull == ef_lastnull)
 
1883
                *same_out_err_files = true;
 
1884
 
 
1885
        if (*outpattern != SLURMD_UNKNOWN && *errpattern != SLURMD_UNKNOWN)
 
1886
                return;
 
1887
 
 
1888
        for (ii = 1; ii < job->ntasks; ii++) {
 
1889
                if (!job->task[ii]->ofname || !job->task[0]->ofname ||
 
1890
                    strcmp(job->task[ii]->ofname, job->task[0]->ofname) != 0)
 
1891
                        of_all_same = false;
 
1892
 
 
1893
                if (!job->task[ii]->efname || !job->task[0]->efname ||
 
1894
                    strcmp(job->task[ii]->efname, job->task[0]->efname) != 0)
 
1895
                        ef_all_same = false;
 
1896
        }
 
1897
 
 
1898
        if (of_all_same && *outpattern == SLURMD_UNKNOWN)
 
1899
                *outpattern = SLURMD_ALL_SAME;
 
1900
 
 
1901
        if (ef_all_same && *errpattern == SLURMD_UNKNOWN)
 
1902
                *errpattern = SLURMD_ALL_SAME;
 
1903
 
 
1904
        if (job->task[0]->ofname && job->task[0]->efname &&
 
1905
            strcmp(job->task[0]->ofname, job->task[0]->efname)==0)
 
1906
                *same_out_err_files = true;
 
1907
 
 
1908
        if (*outpattern != SLURMD_UNKNOWN && *errpattern != SLURMD_UNKNOWN)
 
1909
                return;
 
1910
 
 
1911
        for (ii = 0; ii < job->ntasks-1; ii++) {
 
1912
                for (jj = ii+1; jj < job->ntasks; jj++) {
 
1913
 
 
1914
                        if (!job->task[ii]->ofname || !job->task[jj]->ofname ||
 
1915
                            strcmp(job->task[ii]->ofname, 
 
1916
                                   job->task[jj]->ofname) == 0)
 
1917
                                of_all_unique = false;
 
1918
 
 
1919
                        if (!job->task[ii]->efname || !job->task[jj]->efname ||
 
1920
                            strcmp(job->task[ii]->efname, 
 
1921
                                   job->task[jj]->efname) == 0)
 
1922
                                ef_all_unique = false;
 
1923
                }
 
1924
        }
 
1925
 
 
1926
        if (of_all_unique)
 
1927
                *outpattern = SLURMD_ALL_UNIQUE;
 
1928
 
 
1929
        if (ef_all_unique)
 
1930
                *errpattern = SLURMD_ALL_UNIQUE;
 
1931
 
 
1932
        if (of_all_unique && ef_all_unique) {
 
1933
                *same_out_err_files = true;
 
1934
                for (ii = 0; ii < job->ntasks; ii++) {
 
1935
                        if (job->task[ii]->ofname && 
 
1936
                            job->task[ii]->efname &&
 
1937
                            strcmp(job->task[ii]->ofname,
 
1938
                                   job->task[ii]->efname) != 0) {
 
1939
                                *same_out_err_files = false;
 
1940
                                break;
 
1941
                        }
 
1942
                }
 
1943
        }
 
1944
}
 
1945
 
 
1946
 
 
1947
int
 
1948
io_get_file_flags(slurmd_job_t *job)
 
1949
{
 
1950
        slurm_ctl_conf_t *conf;
 
1951
        int file_flags;
 
1952
 
 
1953
        /* set files for opening stdout/err */
 
1954
        if (job->open_mode == OPEN_MODE_APPEND)
 
1955
                file_flags = O_CREAT|O_WRONLY|O_APPEND;
 
1956
        else if (job->open_mode == OPEN_MODE_TRUNCATE)
 
1957
                file_flags = O_CREAT|O_WRONLY|O_APPEND|O_TRUNC;
 
1958
        else {
 
1959
                conf = slurm_conf_lock();
 
1960
                if (conf->job_file_append)
 
1961
                        file_flags = O_CREAT|O_WRONLY|O_APPEND;
 
1962
                else
 
1963
                        file_flags = O_CREAT|O_WRONLY|O_APPEND|O_TRUNC;
 
1964
                slurm_conf_unlock();
 
1965
        }
 
1966
        return file_flags;
 
1967
}
 
1968
 
 
1969
 
 
1970