Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 544114
Collapse All | Expand All

(-)file_not_specified_in_diff (-349 / +65 lines)
Line  Link Here
0
-- b/src/journal/journald-server.c
0
++ a/src/journal/journald-server.c
Lines 1466-1472 Link Here
1466
}
1462
}
1467
1463
1468
int server_init(Server *s) {
1464
int server_init(Server *s) {
1469
        _cleanup_fdset_free_ FDSet *fds = NULL;
1470
        int n, r, fd;
1465
        int n, r, fd;
1471
1466
1472
        assert(s);
1467
        assert(s);
Lines 1563-1595 Link Here
1563
                        s->audit_fd = fd;
1558
                        s->audit_fd = fd;
1564
1559
1565
                } else {
1560
                } else {
1561
                        log_warning("Unknown socket passed as file descriptor %d, ignoring.", fd);
1566
1562
1567
                        if (!fds) {
1563
                        /* Let's close the fd, better be safe than
1568
                                fds = fdset_new();
1564
                           sorry. The fd might reference some resource
1569
                                if (!fds)
1565
                           that we really want to release if we don't
1570
                                        return log_oom();
1566
                           make use of it. */
1571
                        }
1572
1567
1573
                        r = fdset_put(fds, fd);
1568
                        safe_close(fd);
1574
                        if (r < 0)
1575
                                return log_oom();
1576
                }
1569
                }
1577
        }
1570
        }
1578
1571
1579
        r = server_open_stdout_socket(s, fds);
1572
        r = server_open_syslog_socket(s);
1580
        if (r < 0)
1573
        if (r < 0)
1581
                return r;
1574
                return r;
1582
1575
1583
        if (fdset_size(fds) > 0) {
1576
        r = server_open_native_socket(s);
1584
                log_warning("%u unknown file descriptors passed, closing.", fdset_size(fds));
1585
                fds = fdset_free(fds);
1586
        }
1587
1588
        r = server_open_syslog_socket(s);
1589
        if (r < 0)
1577
        if (r < 0)
1590
                return r;
1578
                return r;
1591
1579
1592
        r = server_open_native_socket(s);
1580
        r = server_open_stdout_socket(s);
1593
        if (r < 0)
1581
        if (r < 0)
1594
                return r;
1582
                return r;
1595
1583
1596
-- b/src/journal/journald-stream.c
1584
++ a/src/journal/journald-stream.c
Lines 28-38 Link Here
28
#endif
28
#endif
29
29
30
#include "sd-event.h"
30
#include "sd-event.h"
31
#include "sd-daemon.h"
32
#include "socket-util.h"
31
#include "socket-util.h"
33
#include "selinux-util.h"
32
#include "selinux-util.h"
34
#include "mkdir.h"
35
#include "fileio.h"
36
#include "journald-server.h"
33
#include "journald-server.h"
37
#include "journald-stream.h"
34
#include "journald-stream.h"
38
#include "journald-syslog.h"
35
#include "journald-syslog.h"
Lines 72-224 Link Here
72
        bool forward_to_kmsg:1;
69
        bool forward_to_kmsg:1;
73
        bool forward_to_console:1;
70
        bool forward_to_console:1;
74
71
75
        bool fdstore:1;
76
77
        char buffer[LINE_MAX+1];
72
        char buffer[LINE_MAX+1];
78
        size_t length;
73
        size_t length;
79
74
80
        sd_event_source *event_source;
75
        sd_event_source *event_source;
81
76
82
        char *state_file;
83
84
        LIST_FIELDS(StdoutStream, stdout_stream);
77
        LIST_FIELDS(StdoutStream, stdout_stream);
85
};
78
};
86
79
87
void stdout_stream_free(StdoutStream *s) {
88
        if (!s)
89
                return;
90
91
        if (s->server) {
92
                assert(s->server->n_stdout_streams > 0);
93
                s->server->n_stdout_streams --;
94
                LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
95
        }
96
97
        if (s->event_source) {
98
                sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF);
99
                s->event_source = sd_event_source_unref(s->event_source);
100
        }
101
102
        safe_close(s->fd);
103
104
#ifdef HAVE_SELINUX
105
        if (s->security_context)
106
                freecon(s->security_context);
107
#endif
108
109
        free(s->identifier);
110
        free(s->unit_id);
111
        free(s->state_file);
112
113
        free(s);
114
}
115
116
DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);
117
118
static void stdout_stream_destroy(StdoutStream *s) {
119
        if (!s)
120
                return;
121
122
        if (s->state_file)
123
                unlink(s->state_file);
124
125
        stdout_stream_free(s);
126
}
127
128
static int stdout_stream_save(StdoutStream *s) {
129
        _cleanup_free_ char *temp_path = NULL;
130
        _cleanup_fclose_ FILE *f = NULL;
131
        int r;
132
133
        assert(s);
134
135
        if (s->state != STDOUT_STREAM_RUNNING)
136
                return 0;
137
138
        if (!s->state_file) {
139
                struct stat st;
140
141
                r = fstat(s->fd, &st);
142
                if (r < 0)
143
                        return log_warning_errno(errno, "Failed to stat connected stream: %m");
144
145
                /* We use device and inode numbers as identifier for the stream */
146
                if (asprintf(&s->state_file, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
147
                        return log_oom();
148
        }
149
150
        mkdir_p("/run/systemd/journal/streams", 0755);
151
152
        r = fopen_temporary(s->state_file, &f, &temp_path);
153
        if (r < 0)
154
                goto finish;
155
156
        fprintf(f,
157
                "# This is private data. Do not parse\n"
158
                "PRIORITY=%i\n"
159
                "LEVEL_PREFIX=%i\n"
160
                "FORWARD_TO_SYSLOG=%i\n"
161
                "FORWARD_TO_KMSG=%i\n"
162
                "FORWARD_TO_CONSOLE=%i\n",
163
                s->priority,
164
                s->level_prefix,
165
                s->forward_to_syslog,
166
                s->forward_to_kmsg,
167
                s->forward_to_console);
168
169
        if (!isempty(s->identifier)) {
170
                _cleanup_free_ char *escaped;
171
172
                escaped = cescape(s->identifier);
173
                if (!escaped) {
174
                        r = -ENOMEM;
175
                        goto finish;
176
                }
177
178
                fprintf(f, "IDENTIFIER=%s\n", escaped);
179
        }
180
181
        if (!isempty(s->unit_id)) {
182
                _cleanup_free_ char *escaped;
183
184
                escaped = cescape(s->unit_id);
185
                if (!escaped) {
186
                        r = -ENOMEM;
187
                        goto finish;
188
                }
189
190
                fprintf(f, "UNIT=%s\n", escaped);
191
        }
192
193
        r = fflush_and_check(f);
194
        if (r < 0)
195
                goto finish;
196
197
        if (rename(temp_path, s->state_file) < 0) {
198
                r = -errno;
199
                goto finish;
200
        }
201
202
        free(temp_path);
203
        temp_path = NULL;
204
205
        /* Store the connection fd in PID 1, so that we get it passed
206
         * in again on next start */
207
        if (!s->fdstore) {
208
                sd_pid_notify_with_fds(0, false, "FDSTORE=1", &s->fd, 1);
209
                s->fdstore = true;
210
        }
211
212
finish:
213
        if (temp_path)
214
                unlink(temp_path);
215
216
        if (r < 0)
217
                log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
218
219
        return r;
220
}
221
222
static int stdout_stream_log(StdoutStream *s, const char *p) {
80
static int stdout_stream_log(StdoutStream *s, const char *p) {
223
        struct iovec iovec[N_IOVEC_META_FIELDS + 5];
81
        struct iovec iovec[N_IOVEC_META_FIELDS + 5];
224
        int priority;
82
        int priority;
Lines 371-379 Link Here
371
229
372
                s->forward_to_console = !!r;
230
                s->forward_to_console = !!r;
373
                s->state = STDOUT_STREAM_RUNNING;
231
                s->state = STDOUT_STREAM_RUNNING;
374
375
                /* Try to save the stream, so that journald can be restarted and we can recover */
376
                (void) stdout_stream_save(s);
377
                return 0;
232
                return 0;
378
233
379
        case STDOUT_STREAM_RUNNING:
234
        case STDOUT_STREAM_RUNNING:
Lines 468-530 Link Here
468
        return 1;
323
        return 1;
469
324
470
terminate:
325
terminate:
471
        stdout_stream_destroy(s);
326
        stdout_stream_free(s);
472
        return 0;
327
        return 0;
473
}
328
}
474
329
475
static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
330
void stdout_stream_free(StdoutStream *s) {
476
        _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
477
        int r;
478
479
        assert(s);
331
        assert(s);
480
        assert(fd >= 0);
481
332
482
        stream = new0(StdoutStream, 1);
333
        if (s->server) {
483
        if (!stream)
334
                assert(s->server->n_stdout_streams > 0);
484
                return log_oom();
335
                s->server->n_stdout_streams --;
336
                LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
337
        }
485
338
486
        stream->fd = -1;
339
        if (s->event_source) {
487
        stream->priority = LOG_INFO;
340
                sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF);
341
                s->event_source = sd_event_source_unref(s->event_source);
342
        }
488
343
489
        r = getpeercred(fd, &stream->ucred);
344
        safe_close(s->fd);
490
        if (r < 0)
491
                return log_error_errno(r, "Failed to determine peer credentials: %m");
492
345
493
#ifdef HAVE_SELINUX
346
#ifdef HAVE_SELINUX
494
        if (mac_selinux_use()) {
347
        if (s->security_context)
495
                if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT)
348
                freecon(s->security_context);
496
                        log_error_errno(errno, "Failed to determine peer security context: %m");
497
        }
498
#endif
349
#endif
499
350
500
        (void) shutdown(fd, SHUT_WR);
351
        free(s->identifier);
501
352
        free(s->unit_id);
502
        r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
353
        free(s);
503
        if (r < 0)
504
                return log_error_errno(r, "Failed to add stream to event loop: %m");
505
506
        r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
507
        if (r < 0)
508
                return log_error_errno(r, "Failed to adjust stdout event source priority: %m");
509
510
        stream->fd = fd;
511
512
        stream->server = s;
513
        LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
514
        s->n_stdout_streams ++;
515
516
        if (ret)
517
                *ret = stream;
518
519
        stream = NULL;
520
521
        return 0;
522
}
354
}
523
355
524
static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
356
static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
525
        _cleanup_close_ int fd = -1;
526
        Server *s = userdata;
357
        Server *s = userdata;
527
        int r;
358
        StdoutStream *stream;
359
        int fd, r;
528
360
529
        assert(s);
361
        assert(s);
530
362
Lines 544-706 Link Here
544
376
545
        if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
377
        if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
546
                log_warning("Too many stdout streams, refusing connection.");
378
                log_warning("Too many stdout streams, refusing connection.");
379
                safe_close(fd);
547
                return 0;
380
                return 0;
548
        }
381
        }
549
382
550
        r = stdout_stream_install(s, fd, NULL);
383
        stream = new0(StdoutStream, 1);
551
        if (r < 0)
384
        if (!stream) {
552
                return r;
385
                safe_close(fd);
553
386
                return log_oom();
554
        fd = -1;
555
        return 0;
556
}
557
558
static int stdout_stream_load(StdoutStream *stream, const char *fname) {
559
        _cleanup_free_ char
560
                *priority = NULL,
561
                *level_prefix = NULL,
562
                *forward_to_syslog = NULL,
563
                *forward_to_kmsg = NULL,
564
                *forward_to_console = NULL;
565
        int r;
566
567
        assert(stream);
568
        assert(fname);
569
570
        if (!stream->state_file) {
571
                stream->state_file = strappend("/run/systemd/journal/streams/", fname);
572
                if (!stream->state_file)
573
                        return log_oom();
574
        }
387
        }
575
388
576
        r = parse_env_file(stream->state_file, NEWLINE,
389
        stream->fd = fd;
577
                           "PRIORITY", &priority,
578
                           "LEVEL_PREFIX", &level_prefix,
579
                           "FORWARD_TO_SYSLOG", &forward_to_syslog,
580
                           "FORWARD_TO_KMSG", &forward_to_kmsg,
581
                           "FORWARD_TO_CONSOLE", &forward_to_console,
582
                           "IDENTIFIER", &stream->identifier,
583
                           "UNIT", &stream->unit_id,
584
                           NULL);
585
        if (r < 0)
586
                return log_error_errno(r, "Failed to read: %s", stream->state_file);
587
390
588
        if (priority) {
391
        r = getpeercred(fd, &stream->ucred);
589
                int p;
392
        if (r < 0) {
590
393
                log_error_errno(errno, "Failed to determine peer credentials: %m");
591
                p = log_level_from_string(priority);
394
                goto fail;
592
                if (p >= 0)
593
                        stream->priority = p;
594
        }
395
        }
595
396
596
        if (level_prefix) {
397
#ifdef HAVE_SELINUX
597
                r = parse_boolean(level_prefix);
398
        if (mac_selinux_use()) {
598
                if (r >= 0)
399
                if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT)
599
                        stream->level_prefix = r;
400
                        log_error_errno(errno, "Failed to determine peer security context: %m");
600
        }
401
        }
402
#endif
601
403
602
        if (forward_to_syslog) {
404
        if (shutdown(fd, SHUT_WR) < 0) {
603
                r = parse_boolean(forward_to_syslog);
405
                log_error_errno(errno, "Failed to shutdown writing side of socket: %m");
604
                if (r >= 0)
406
                goto fail;
605
                        stream->forward_to_syslog = r;
606
        }
407
        }
607
408
608
        if (forward_to_kmsg) {
409
        r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
609
                r = parse_boolean(forward_to_kmsg);
410
        if (r < 0) {
610
                if (r >= 0)
411
                log_error_errno(r, "Failed to add stream to event loop: %m");
611
                        stream->forward_to_kmsg = r;
412
                goto fail;
612
        }
413
        }
613
414
614
        if (forward_to_console) {
415
        r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
615
                r = parse_boolean(forward_to_console);
416
        if (r < 0) {
616
                if (r >= 0)
417
                log_error_errno(r, "Failed to adjust stdout event source priority: %m");
617
                        stream->forward_to_console = r;
418
                goto fail;
618
        }
419
        }
619
420
620
        return 0;
421
        stream->server = s;
621
}
422
        LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
622
423
        s->n_stdout_streams ++;
623
static int stdout_stream_restore(Server *s, const char *fname, int fd) {
624
        StdoutStream *stream;
625
        int r;
626
627
        assert(s);
628
        assert(fname);
629
        assert(fd >= 0);
630
631
        if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
632
                log_warning("Too many stdout streams, refusing restoring of stream.");
633
                return -ENOBUFS;
634
        }
635
636
        r = stdout_stream_install(s, fd, &stream);
637
        if (r < 0)
638
                return r;
639
640
        stream->state = STDOUT_STREAM_RUNNING;
641
        stream->fdstore = true;
642
643
        /* Ignore all parsing errors */
644
        (void) stdout_stream_load(stream, fname);
645
424
646
        return 0;
425
        return 0;
647
}
648
649
static int server_restore_streams(Server *s, FDSet *fds) {
650
        _cleanup_closedir_ DIR *d = NULL;
651
        struct dirent *de;
652
        int r;
653
654
        d = opendir("/run/systemd/journal/streams");
655
        if (!d) {
656
                if (errno == ENOENT)
657
                        return 0;
658
659
                return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m");
660
        }
661
662
        FOREACH_DIRENT(de, d, goto fail) {
663
                unsigned long st_dev, st_ino;
664
                bool found = false;
665
                Iterator i;
666
                int fd;
667
668
                if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
669
                        continue;
670
671
                FDSET_FOREACH(fd, fds, i) {
672
                        struct stat st;
673
674
                        if (fstat(fd, &st) < 0)
675
                                return log_error_errno(errno, "Failed to stat %s: %m", de->d_name);
676
677
                        if (S_ISSOCK(st.st_mode) && st.st_dev == st_dev && st.st_ino == st_ino) {
678
                                found = true;
679
                                break;
680
                        }
681
                }
682
683
                if (!found) {
684
                        /* No file descriptor? Then let's delete the state file */
685
                        log_debug("Cannot restore stream file %s", de->d_name);
686
                        unlinkat(dirfd(d), de->d_name, 0);
687
                        continue;
688
                }
689
690
                fdset_remove(fds, fd);
691
692
                r = stdout_stream_restore(s, de->d_name, fd);
693
                if (r < 0)
694
                        safe_close(fd);
695
        }
696
426
427
fail:
428
        stdout_stream_free(stream);
697
        return 0;
429
        return 0;
698
699
fail:
700
        return log_error_errno(errno, "Failed to read streams directory: %m");
701
}
430
}
702
431
703
int server_open_stdout_socket(Server *s, FDSet *fds) {
432
int server_open_stdout_socket(Server *s) {
704
        int r;
433
        int r;
705
434
706
        assert(s);
435
        assert(s);
Lines 736-743 Link Here
736
        if (r < 0)
465
        if (r < 0)
737
                return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m");
466
                return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m");
738
467
739
        /* Try to restore streams, but don't bother if this fails */
740
        (void) server_restore_streams(s, fds);
741
742
        return 0;
468
        return 0;
743
}
469
}
744
-- b/src/journal/journald-stream.h
470
++ a/src/journal/journald-stream.h
Lines 21-29 Link Here
21
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
21
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
22
***/
22
***/
23
23
24
#include "fdset.h"
25
#include "journald-server.h"
24
#include "journald-server.h"
26
25
27
int server_open_stdout_socket(Server *s, FDSet *fds);
26
int server_open_stdout_socket(Server *s);
28
27
29
void stdout_stream_free(StdoutStream *s);
28
void stdout_stream_free(StdoutStream *s);
30
-- b/units/systemd-journald.service.in
29
++ a/units/systemd-journald.service.in
Lines 23-29 Link Here
23
StandardOutput=null
23
StandardOutput=null
24
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
24
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
25
WatchdogSec=1min
25
WatchdogSec=1min
26
FileDescriptorStoreMax=1024
27
26
28
# Increase the default a bit in order to allow many simultaneous
27
# Increase the default a bit in order to allow many simultaneous
29
# services being run since we keep one fd open per service.
28
# services being run since we keep one fd open per service.

Return to bug 544114