chiark / gitweb /
man,journal: add note about sd_journal_get_cutoff_monotonic_usec return value
[elogind.git] / src / journal / journal-send.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #include <errno.h>
25 #include <stddef.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <printf.h>
29
30 #define SD_JOURNAL_SUPPRESS_LOCATION
31
32 #include "sd-journal.h"
33 #include "util.h"
34 #include "socket-util.h"
35
36 #define SNDBUF_SIZE (8*1024*1024)
37
38 #define ALLOCA_CODE_FUNC(f, func)                 \
39         do {                                      \
40                 size_t _fl;                       \
41                 const char *_func = (func);       \
42                 char **_f = &(f);                 \
43                 _fl = strlen(_func) + 1;          \
44                 *_f = alloca(_fl + 10);           \
45                 memcpy(*_f, "CODE_FUNC=", 10);    \
46                 memcpy(*_f + 10, _func, _fl);     \
47         } while(false)
48
49 /* We open a single fd, and we'll share it with the current process,
50  * all its threads, and all its subprocesses. This means we need to
51  * initialize it atomically, and need to operate on it atomically
52  * never assuming we are the only user */
53
54 static int journal_fd(void) {
55         int fd;
56         static int fd_plus_one = 0;
57
58 retry:
59         if (fd_plus_one > 0)
60                 return fd_plus_one - 1;
61
62         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
63         if (fd < 0)
64                 return -errno;
65
66         fd_inc_sndbuf(fd, SNDBUF_SIZE);
67
68         if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) {
69                 safe_close(fd);
70                 goto retry;
71         }
72
73         return fd;
74 }
75
76 _public_ int sd_journal_print(int priority, const char *format, ...) {
77         int r;
78         va_list ap;
79
80         va_start(ap, format);
81         r = sd_journal_printv(priority, format, ap);
82         va_end(ap);
83
84         return r;
85 }
86
87 _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
88
89         /* FIXME: Instead of limiting things to LINE_MAX we could do a
90            C99 variable-length array on the stack here in a loop. */
91
92         char buffer[8 + LINE_MAX], p[11]; struct iovec iov[2];
93
94         assert_return(priority >= 0, -EINVAL);
95         assert_return(priority <= 7, -EINVAL);
96         assert_return(format, -EINVAL);
97
98         snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
99         char_array_0(p);
100
101         memcpy(buffer, "MESSAGE=", 8);
102         vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
103         char_array_0(buffer);
104
105         zero(iov);
106         IOVEC_SET_STRING(iov[0], buffer);
107         IOVEC_SET_STRING(iov[1], p);
108
109         return sd_journal_sendv(iov, 2);
110 }
111
112 _printf_(1, 0) static int fill_iovec_sprintf(const char *format, va_list ap, int extra, struct iovec **_iov) {
113         PROTECT_ERRNO;
114         int r, n = 0, i = 0, j;
115         struct iovec *iov = NULL;
116
117         assert(_iov);
118
119         if (extra > 0) {
120                 n = MAX(extra * 2, extra + 4);
121                 iov = malloc0(n * sizeof(struct iovec));
122                 if (!iov) {
123                         r = -ENOMEM;
124                         goto fail;
125                 }
126
127                 i = extra;
128         }
129
130         while (format) {
131                 struct iovec *c;
132                 char *buffer;
133                 va_list aq;
134
135                 if (i >= n) {
136                         n = MAX(i*2, 4);
137                         c = realloc(iov, n * sizeof(struct iovec));
138                         if (!c) {
139                                 r = -ENOMEM;
140                                 goto fail;
141                         }
142
143                         iov = c;
144                 }
145
146                 va_copy(aq, ap);
147                 if (vasprintf(&buffer, format, aq) < 0) {
148                         va_end(aq);
149                         r = -ENOMEM;
150                         goto fail;
151                 }
152                 va_end(aq);
153
154                 VA_FORMAT_ADVANCE(format, ap);
155
156                 IOVEC_SET_STRING(iov[i++], buffer);
157
158                 format = va_arg(ap, char *);
159         }
160
161         *_iov = iov;
162
163         return i;
164
165 fail:
166         for (j = 0; j < i; j++)
167                 free(iov[j].iov_base);
168
169         free(iov);
170
171         return r;
172 }
173
174 _public_ int sd_journal_send(const char *format, ...) {
175         int r, i, j;
176         va_list ap;
177         struct iovec *iov = NULL;
178
179         va_start(ap, format);
180         i = fill_iovec_sprintf(format, ap, 0, &iov);
181         va_end(ap);
182
183         if (_unlikely_(i < 0)) {
184                 r = i;
185                 goto finish;
186         }
187
188         r = sd_journal_sendv(iov, i);
189
190 finish:
191         for (j = 0; j < i; j++)
192                 free(iov[j].iov_base);
193
194         free(iov);
195
196         return r;
197 }
198
199 _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
200         PROTECT_ERRNO;
201         int fd;
202         _cleanup_close_ int buffer_fd = -1;
203         struct iovec *w;
204         uint64_t *l;
205         int i, j = 0;
206         struct sockaddr_un sa = {
207                 .sun_family = AF_UNIX,
208                 .sun_path = "/run/systemd/journal/socket",
209         };
210         struct msghdr mh = {
211                 .msg_name = &sa,
212                 .msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path),
213         };
214         ssize_t k;
215         union {
216                 struct cmsghdr cmsghdr;
217                 uint8_t buf[CMSG_SPACE(sizeof(int))];
218         } control;
219         struct cmsghdr *cmsg;
220         bool have_syslog_identifier = false;
221
222         assert_return(iov, -EINVAL);
223         assert_return(n > 0, -EINVAL);
224
225         w = alloca(sizeof(struct iovec) * n * 5 + 3);
226         l = alloca(sizeof(uint64_t) * n);
227
228         for (i = 0; i < n; i++) {
229                 char *c, *nl;
230
231                 if (_unlikely_(!iov[i].iov_base || iov[i].iov_len <= 1))
232                         return -EINVAL;
233
234                 c = memchr(iov[i].iov_base, '=', iov[i].iov_len);
235                 if (_unlikely_(!c || c == iov[i].iov_base))
236                         return -EINVAL;
237
238                 have_syslog_identifier = have_syslog_identifier ||
239                         (c == (char *) iov[i].iov_base + 17 &&
240                          startswith(iov[i].iov_base, "SYSLOG_IDENTIFIER"));
241
242                 nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
243                 if (nl) {
244                         if (_unlikely_(nl < c))
245                                 return -EINVAL;
246
247                         /* Already includes a newline? Bummer, then
248                          * let's write the variable name, then a
249                          * newline, then the size (64bit LE), followed
250                          * by the data and a final newline */
251
252                         w[j].iov_base = iov[i].iov_base;
253                         w[j].iov_len = c - (char*) iov[i].iov_base;
254                         j++;
255
256                         IOVEC_SET_STRING(w[j++], "\n");
257
258                         l[i] = htole64(iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1);
259                         w[j].iov_base = &l[i];
260                         w[j].iov_len = sizeof(uint64_t);
261                         j++;
262
263                         w[j].iov_base = c + 1;
264                         w[j].iov_len = iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1;
265                         j++;
266
267                 } else
268                         /* Nothing special? Then just add the line and
269                          * append a newline */
270                         w[j++] = iov[i];
271
272                 IOVEC_SET_STRING(w[j++], "\n");
273         }
274
275         if (!have_syslog_identifier &&
276             string_is_safe(program_invocation_short_name)) {
277
278                 /* Implicitly add program_invocation_short_name, if it
279                  * is not set explicitly. We only do this for
280                  * program_invocation_short_name, and nothing else
281                  * since everything else is much nicer to retrieve
282                  * from the outside. */
283
284                 IOVEC_SET_STRING(w[j++], "SYSLOG_IDENTIFIER=");
285                 IOVEC_SET_STRING(w[j++], program_invocation_short_name);
286                 IOVEC_SET_STRING(w[j++], "\n");
287         }
288
289         fd = journal_fd();
290         if (_unlikely_(fd < 0))
291                 return fd;
292
293         mh.msg_iov = w;
294         mh.msg_iovlen = j;
295
296         k = sendmsg(fd, &mh, MSG_NOSIGNAL);
297         if (k >= 0)
298                 return 0;
299
300         /* Fail silently if the journal is not available */
301         if (errno == ENOENT)
302                 return 0;
303
304         if (errno != EMSGSIZE && errno != ENOBUFS)
305                 return -errno;
306
307         /* Message doesn't fit... Let's dump the data in a temporary
308          * file and just pass a file descriptor of it to the other
309          * side.
310          *
311          * We use /dev/shm instead of /tmp here, since we want this to
312          * be a tmpfs, and one that is available from early boot on
313          * and where unprivileged users can create files. */
314         buffer_fd = open_tmpfile("/dev/shm", O_RDWR | O_CLOEXEC);
315         if (buffer_fd < 0)
316                 return buffer_fd;
317
318         n = writev(buffer_fd, w, j);
319         if (n < 0)
320                 return -errno;
321
322         mh.msg_iov = NULL;
323         mh.msg_iovlen = 0;
324
325         zero(control);
326         mh.msg_control = &control;
327         mh.msg_controllen = sizeof(control);
328
329         cmsg = CMSG_FIRSTHDR(&mh);
330         cmsg->cmsg_level = SOL_SOCKET;
331         cmsg->cmsg_type = SCM_RIGHTS;
332         cmsg->cmsg_len = CMSG_LEN(sizeof(int));
333         memcpy(CMSG_DATA(cmsg), &buffer_fd, sizeof(int));
334
335         mh.msg_controllen = cmsg->cmsg_len;
336
337         k = sendmsg(fd, &mh, MSG_NOSIGNAL);
338         if (k < 0)
339                 return -errno;
340
341         return 0;
342 }
343
344 static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) {
345         PROTECT_ERRNO;
346         size_t n, k;
347
348         k = isempty(message) ? 0 : strlen(message) + 2;
349         n = 8 + k + 256 + 1;
350
351         for (;;) {
352                 char buffer[n];
353                 char* j;
354
355                 errno = 0;
356                 j = strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k);
357                 if (errno == 0) {
358                         char error[6 + 10 + 1]; /* for a 32bit value */
359
360                         if (j != buffer + 8 + k)
361                                 memmove(buffer + 8 + k, j, strlen(j)+1);
362
363                         memcpy(buffer, "MESSAGE=", 8);
364
365                         if (k > 0) {
366                                 memcpy(buffer + 8, message, k - 2);
367                                 memcpy(buffer + 8 + k - 2, ": ", 2);
368                         }
369
370                         snprintf(error, sizeof(error), "ERRNO=%u", _saved_errno_);
371                         char_array_0(error);
372
373                         IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3");
374                         IOVEC_SET_STRING(iov[skip+1], buffer);
375                         IOVEC_SET_STRING(iov[skip+2], error);
376
377                         return sd_journal_sendv(iov, skip + 3);
378                 }
379
380                 if (errno != ERANGE)
381                         return -errno;
382
383                 n *= 2;
384         }
385 }
386
387 _public_ int sd_journal_perror(const char *message) {
388         struct iovec iovec[3];
389
390         return fill_iovec_perror_and_send(message, 0, iovec);
391 }
392
393 _public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
394         union sockaddr_union sa = {
395                 .un.sun_family = AF_UNIX,
396                 .un.sun_path = "/run/systemd/journal/stdout",
397         };
398         _cleanup_close_ int fd = -1;
399         char *header;
400         size_t l;
401         int r;
402
403         assert_return(priority >= 0, -EINVAL);
404         assert_return(priority <= 7, -EINVAL);
405
406         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
407         if (fd < 0)
408                 return -errno;
409
410         r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
411         if (r < 0)
412                 return -errno;
413
414         if (shutdown(fd, SHUT_RD) < 0)
415                 return -errno;
416
417         fd_inc_sndbuf(fd, SNDBUF_SIZE);
418
419         if (!identifier)
420                 identifier = "";
421
422         l = strlen(identifier);
423         header = alloca(l + 1 + 1 + 2 + 2 + 2 + 2 + 2);
424
425         memcpy(header, identifier, l);
426         header[l++] = '\n';
427         header[l++] = '\n'; /* unit id */
428         header[l++] = '0' + priority;
429         header[l++] = '\n';
430         header[l++] = '0' + !!level_prefix;
431         header[l++] = '\n';
432         header[l++] = '0';
433         header[l++] = '\n';
434         header[l++] = '0';
435         header[l++] = '\n';
436         header[l++] = '0';
437         header[l++] = '\n';
438
439         r = (int) loop_write(fd, header, l, false);
440         if (r < 0)
441                 return r;
442
443         if ((size_t) r != l)
444                 return -errno;
445
446         r = fd;
447         fd = -1;
448         return r;
449 }
450
451 _public_ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) {
452         int r;
453         va_list ap;
454
455         va_start(ap, format);
456         r = sd_journal_printv_with_location(priority, file, line, func, format, ap);
457         va_end(ap);
458
459         return r;
460 }
461
462 _public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) {
463         char buffer[8 + LINE_MAX], p[11];
464         struct iovec iov[5];
465         char *f;
466
467         assert_return(priority >= 0, -EINVAL);
468         assert_return(priority <= 7, -EINVAL);
469         assert_return(format, -EINVAL);
470
471         snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
472         char_array_0(p);
473
474         memcpy(buffer, "MESSAGE=", 8);
475         vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
476         char_array_0(buffer);
477
478         /* func is initialized from __func__ which is not a macro, but
479          * a static const char[], hence cannot easily be prefixed with
480          * CODE_FUNC=, hence let's do it manually here. */
481         ALLOCA_CODE_FUNC(f, func);
482
483         zero(iov);
484         IOVEC_SET_STRING(iov[0], buffer);
485         IOVEC_SET_STRING(iov[1], p);
486         IOVEC_SET_STRING(iov[2], file);
487         IOVEC_SET_STRING(iov[3], line);
488         IOVEC_SET_STRING(iov[4], f);
489
490         return sd_journal_sendv(iov, ELEMENTSOF(iov));
491 }
492
493 _public_ int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) {
494         int r, i, j;
495         va_list ap;
496         struct iovec *iov = NULL;
497         char *f;
498
499         va_start(ap, format);
500         i = fill_iovec_sprintf(format, ap, 3, &iov);
501         va_end(ap);
502
503         if (_unlikely_(i < 0)) {
504                 r = i;
505                 goto finish;
506         }
507
508         ALLOCA_CODE_FUNC(f, func);
509
510         IOVEC_SET_STRING(iov[0], file);
511         IOVEC_SET_STRING(iov[1], line);
512         IOVEC_SET_STRING(iov[2], f);
513
514         r = sd_journal_sendv(iov, i);
515
516 finish:
517         for (j = 3; j < i; j++)
518                 free(iov[j].iov_base);
519
520         free(iov);
521
522         return r;
523 }
524
525 _public_ int sd_journal_sendv_with_location(
526                 const char *file, const char *line,
527                 const char *func,
528                 const struct iovec *iov, int n) {
529
530         struct iovec *niov;
531         char *f;
532
533         assert_return(iov, -EINVAL);
534         assert_return(n > 0, -EINVAL);
535
536         niov = alloca(sizeof(struct iovec) * (n + 3));
537         memcpy(niov, iov, sizeof(struct iovec) * n);
538
539         ALLOCA_CODE_FUNC(f, func);
540
541         IOVEC_SET_STRING(niov[n++], file);
542         IOVEC_SET_STRING(niov[n++], line);
543         IOVEC_SET_STRING(niov[n++], f);
544
545         return sd_journal_sendv(niov, n);
546 }
547
548 _public_ int sd_journal_perror_with_location(
549                 const char *file, const char *line,
550                 const char *func,
551                 const char *message) {
552
553         struct iovec iov[6];
554         char *f;
555
556         ALLOCA_CODE_FUNC(f, func);
557
558         IOVEC_SET_STRING(iov[0], file);
559         IOVEC_SET_STRING(iov[1], line);
560         IOVEC_SET_STRING(iov[2], f);
561
562         return fill_iovec_perror_and_send(message, 3, iov);
563 }