3 #include "log_storage.h"
16 #include <linux/limits.h>
17 #include <sys/epoll.h>
18 #include <sys/socket.h>
20 #include <sys/resource.h>
22 #include <sys/types.h>
26 #include <logconfig.h>
27 #include <ptrs_list.h>
28 #include <sd-daemon.h>
29 #include <backend_androidlogger.h>
30 #include <queued_entry_timestamp.h>
32 /* supported main() return codes */
34 DLOG_EXIT_SUCCESS = 0,
39 /* Size in bytes of the pipe given to libdlog clients.
40 * The default size (1 page, usually 4 kiB) is fairly small
41 * which leads programs that log a lot to easily clog the
42 * pipe. On the other hand, the amount of memory allocated
43 * to pipes specifically can be limited and on most relevant
44 * targets seems to be set to 16ki pages (64 MiB raw memory)
45 * so pipes should not be too large so as not to waste it. */
46 #define PIPE_REQUESTED_SIZE (64 * 1024) // 16 pages at 4 kiB per page
48 /* Dumping readers should ideally get a larger pipe than clients
49 * so that it doesn't get easily clogged by the odd spammer.
50 * We can afford more generosity here because these are invoked
51 * quite rarely yet require handling priority, either because
52 * they are called by a developer manually or because a crashing
53 * program caused a system state dump. */
54 #define DUMPING_READER_PIPE_SIZE (4 * PIPE_REQUESTED_SIZE)
56 #define FILE_PATH_SIZE (256)
57 #define MAX_CONNECTION_Q 100
59 #define CONF_PREFIX "dlog_logger_conf_"
62 BUF_PARAM_TIME_MIN = 0,
63 BUF_PARAM_TIME_MAX = 3600,
64 BUF_PARAM_TIME_DEFAULT = 1,
68 BUF_PARAM_BYTES_MIN = 0,
69 BUF_PARAM_BYTES_MAX = 65536,
70 BUF_PARAM_BYTES_DEFAULT = 100
74 LOGGER_DEVICE_THROTTLING_DEFAULT = 100,
83 * @brief Event handler
84 * @details Receives and handles an event
85 * @param[in] server The logger server
86 * @param[in] event The received event
88 typedef void (*dispatch_event_t)(struct logger *server, struct epoll_event *event);
91 dispatch_event_t dispatch_event;
92 struct epoll_event event;
97 * @brief Service a writer
98 * @details Specific handler that event is delegated to, according to writers type
99 * @param[in] server The logger server
100 * @param[in] wr The writer to handle the request
101 * @param[in] event The relevant event on file descriptor
102 * @return 0 on success, else -errno
104 typedef int (*service_writer_t)(struct logger* server, struct writer* wr, struct epoll_event* event);
107 * @brief Service socket request
108 * @details Handle request on socket in respect to msg request type
109 * @param[in] server The logger server
110 * @param[in] wr The writer to handle the request on the socket
111 * @param[in] msg The message containing the request
112 * @return 0 on success, else -errno
114 typedef int (*service_socket_t)(struct logger *server, struct writer *wr, struct dlog_control_msg *msg);
117 /* Writers and readers can be a bit confusing in what they refer to.
118 * Something that does write() calls is usually actually a reader,
119 * and something that read()s is typically a writer. This is because
120 * the terminology is from the point of view of the primary log storage
121 * and not the daemon itself. Additionally, under the Android Logger
122 * the situation is even more complex because there's a hybrid structure
123 * that sits at both edges of the daemon at the same time and read()s,
124 * then immediately write()s data. Nevertheless it is classified as a
125 * reader because of its relationship with the primary log storage.
127 * Here's a picture for Pipe backend:
129 * ╔══════════════════════ daemon ════════════════════╗
130 * ┌─────────┐ ║ ┌────────┐ ┌─────────────────┐ ┌────────┐ ║ ┌─────────────────┐
131 * │ libdlog ├─╫─>│ struct ├───>│ primary storage ├───>│ struct ├─╫─>│ /var/log/dlog/x │
132 * │ client │ ║ │ writer │ │ char buffer[N]; │ │ reader │ ║ │ or dlogutil │
133 * └─────────┘ ║ └────────┘ └─────────────────┘ └────────┘ ║ └─────────────────┘
134 * ╚══════════════════════════════════════════════════╝
136 * And here's one for the Android Logger backend:
139 * ┌─────────┐ ┌─────────────────┐ ║ ┌────────┐ ║ ┌─────────────────┐
140 * │ libdlog ├─────────────────>│ primary storage ├─╫─>│ struct ├─╫─>│ /var/log/dlog/x │
141 * │ client │ │ /dev/log_x │ ║ │ reader │ ║ │ │
142 * └─────────┘ └─────────────────┘ ║ └────────┘ ║ └─────────────────┘
147 #define LARGEST_STRUCT(a, b) (sizeof(struct a) > sizeof(struct b) ? sizeof(struct a) : sizeof(struct b))
149 struct fd_entity fd_entity;
150 struct log_buffer* buf_ptr;
152 service_writer_t service_writer;
153 service_socket_t service_socket;
154 char buffer[LOG_MAX_PAYLOAD_SIZE + LARGEST_STRUCT(android_logger_entry, pipe_logger_entry)];
156 #undef LARGEST_STRUCT
159 * @brief Service reader
160 * @details Passes the reader to a more specific servicing handler
161 * @param[in] server The logger server
162 * @param[in] reader The reader being serviced
163 * @return Positive integer if the reader is to be removed, else a nonpositive one
165 typedef int (*service_reader_t)(struct reader *reader);
168 struct fd_entity fd_entity_sink;
169 struct fd_entity fd_entity_source;
170 struct log_file file;
171 dlogutil_filter_options_s* filter;
172 struct log_buffer* buf_ptr;
175 struct timespec last_read_time;
176 int partial_log_size;
177 char partial_log[sizeof(struct dlogutil_entry_with_msg)];
178 service_reader_t service_reader;
179 log_storage_reader *log_storage_reader;
184 struct fd_entity fd_entity;
185 struct log_buffer* buf_ptr;
186 struct epoll_event event;
187 service_socket_t service_socket;
191 struct sock_data sock_wr;
192 struct sock_data sock_ctl;
195 dlogutil_sorting_order_e sort_by;
196 log_storage *log_storage;
209 list_head extra_readers;
210 struct log_buffer* buffers[LOG_ID_MAX];
211 struct buf_params buf_params;
216 struct socket_config_data {
218 char path[MAX_CONF_VAL_LEN];
221 struct buffer_config_data {
223 struct socket_config_data write_socket;
224 struct socket_config_data ctl_socket;
225 dlogutil_sorting_order_e sort_by;
228 struct logger_config_data {
229 struct buf_params buf_params;
230 list_head logfile_configs;
232 int is_buffer_enabled[LOG_ID_MAX];
233 struct buffer_config_data buffers[LOG_ID_MAX];