summaryrefslogtreecommitdiffstats
path: root/src/journal/journalctl-varlink.c
blob: 89aed05334c64418a59c20280b0ecfff6646c46c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "errno-util.h"
#include "journal-internal.h"
#include "journal-vacuum.h"
#include "journalctl.h"
#include "journalctl-util.h"
#include "journalctl-varlink.h"
#include "varlink.h"

static int varlink_connect_journal(Varlink **ret) {
        _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
        const char *address;
        int r;

        assert(ret);

        address = arg_namespace ?
                  strjoina("/run/systemd/journal.", arg_namespace, "/io.systemd.journal") :
                  "/run/systemd/journal/io.systemd.journal";

        r = varlink_connect_address(&vl, address);
        if (r < 0)
                return r;

        (void) varlink_set_description(vl, "journal");
        (void) varlink_set_relative_timeout(vl, USEC_INFINITY);

        *ret = TAKE_PTR(vl);
        return 0;
}

int action_flush_to_var(void) {
        _cleanup_(varlink_flush_close_unrefp) Varlink *link = NULL;
        int r;

        assert(arg_action == ACTION_FLUSH);

        if (arg_machine || arg_namespace)
                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                       "--flush is not supported in conjunction with %s.",
                                       arg_machine ? "--machine=" : "--namespace=");

        if (access("/run/systemd/journal/flushed", F_OK) >= 0)
                return 0; /* Already flushed, no need to contact journald */
        if (errno != ENOENT)
                return log_error_errno(errno, "Unable to check for existence of /run/systemd/journal/flushed: %m");

        r = varlink_connect_journal(&link);
        if (r < 0)
                return log_error_errno(r, "Failed to connect to Varlink socket: %m");

        return varlink_call_and_log(link, "io.systemd.Journal.FlushToVar", /* parameters= */ NULL, /* ret_parameters= */ NULL);
}

int action_relinquish_var(void) {
        _cleanup_(varlink_flush_close_unrefp) Varlink *link = NULL;
        int r;

        assert(arg_action == ACTION_RELINQUISH_VAR);

        if (arg_machine || arg_namespace)
                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                       "--(smart-)relinquish-var is not supported in conjunction with %s.",
                                       arg_machine ? "--machine=" : "--namespace=");

        r = varlink_connect_journal(&link);
        if (r < 0)
                return log_error_errno(r, "Failed to connect to Varlink socket: %m");

        return varlink_call_and_log(link, "io.systemd.Journal.RelinquishVar", /* parameters= */ NULL, /* ret_parameters= */ NULL);
}

int action_rotate(void) {
        _cleanup_(varlink_flush_close_unrefp) Varlink *link = NULL;
        int r;

        assert(IN_SET(arg_action, ACTION_ROTATE, ACTION_ROTATE_AND_VACUUM));

        if (arg_machine)
                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                       "--rotate is not supported in conjunction with --machine=.");

        r = varlink_connect_journal(&link);
        if (r < 0)
                return log_error_errno(r, "Failed to connect to Varlink socket: %m");

        return varlink_call_and_log(link, "io.systemd.Journal.Rotate", /* parameters= */ NULL, /* ret_parameters= */ NULL);
}

int action_vacuum(void) {
        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
        Directory *d;
        int r, ret = 0;

        assert(IN_SET(arg_action, ACTION_VACUUM, ACTION_ROTATE_AND_VACUUM));

        r = acquire_journal(&j);
        if (r < 0)
                return r;

        HASHMAP_FOREACH(d, j->directories_by_path) {
                r = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL, !arg_quiet);
                if (r < 0)
                        RET_GATHER(ret, log_error_errno(r, "Failed to vacuum %s: %m", d->path));
        }

        return ret;
}

int action_rotate_and_vacuum(void) {
        int r;

        assert(arg_action == ACTION_ROTATE_AND_VACUUM);

        r = action_rotate();
        if (r < 0)
                return r;

        return action_vacuum();
}

int action_sync(void) {
        _cleanup_(varlink_flush_close_unrefp) Varlink *link = NULL;
        int r;

        assert(arg_action == ACTION_SYNC);

        if (arg_machine)
                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                       "--sync is not supported in conjunction with --machine=.");

        r = varlink_connect_journal(&link);
        if (ERRNO_IS_NEG_DISCONNECT(r) && arg_namespace)
                /* If the namespaced sd-journald instance was shut down due to inactivity, it should already
                 * be synchronized */
                return 0;
        if (r < 0)
                return log_error_errno(r, "Failed to connect to Varlink socket: %m");

        return varlink_call_and_log(link, "io.systemd.Journal.Synchronize", /* parameters= */ NULL, /* ret_parameters= */ NULL);
}