2 * Copyright (c) 2015 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
21 #ifndef __FIREHOSE_SERVER_PRIVATE__
22 #define __FIREHOSE_SERVER_PRIVATE__
25 #include <dispatch/dispatch.h>
26 #include "firehose_buffer_private.h"
31 * SPI intended for logd only
34 #pragma mark - Firehose Client
37 * @typedef firehose_client_t
40 * Represents a firehose client.
43 * Firehose client objects are os_object_t's, and it's legal to retain/release
44 * them with os_retain / os_release.
46 OS_OBJECT_DECL_CLASS(firehose_client
);
49 * @typedef firehose_event_t
51 * @const FIREHOSE_EVENT_NONE
52 * Never passed to callbacks, meaningful for
53 * firehose_client_metadata_stream_peek.
55 * @const FIREHOSE_EVENT_CLIENT_CONNECTED
56 * A new client has connected
58 * This is the first event delivered, and no event is delivered until
59 * the handler of that event returns
61 * The `page` argument really is really a firehose_client_connected_info_t.
63 * @const FIREHOSE_EVENT_CLIENT_DIED
64 * The specified client is gone and will not flush new buffers
66 * This is the last event delivered, it is never called before all other
67 * event handlers have returned. This event is generated even when a
68 * FIREHOSE_EVENT_CLIENT_CORRUPTED event has been generated.
70 * @const FIREHOSE_EVENT_IO_BUFFER_RECEIVED
71 * A new buffer needs to be pushed, `page` is set to that buffer.
73 * This event can be sent concurrently wrt FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
76 * @const FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
77 * A new buffer needs to be pushed, `page` is set to that buffer.
79 * This event can be sent concurrently wrt FIREHOSE_EVENT_IO_BUFFER_RECEIVED
82 * @const FIREHOSE_EVENT_CLIENT_CORRUPTED
83 * This event is received when a client is found being corrupted.
84 * `page` is set to the buffer header page. When this event is received,
85 * logs have likely been lost for this client.
87 * This buffer isn't really a proper firehose buffer page, but its content may
88 * be useful for debugging purposes.
90 * @const FIREHOSE_EVENT_CLIENT_FINALIZE
91 * This event is received when a firehose client structure is about to be
92 * destroyed. Only firehose_client_get_context() can ever be called with
93 * the passed firehose client. The `page` argument is NULL for this event.
95 * The event is sent from the context that is dropping the last refcount
98 OS_ENUM(firehose_event
, unsigned long,
99 FIREHOSE_EVENT_NONE
= 0,
100 FIREHOSE_EVENT_CLIENT_CONNECTED
,
101 FIREHOSE_EVENT_CLIENT_DIED
,
102 FIREHOSE_EVENT_IO_BUFFER_RECEIVED
,
103 FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
,
104 FIREHOSE_EVENT_CLIENT_CORRUPTED
,
105 FIREHOSE_EVENT_CLIENT_FINALIZE
,
108 #define FIREHOSE_CLIENT_CONNECTED_INFO_VERSION 1
111 * @typedef firehose_client_connected_info
114 * Type of the data passed to CLIENT_CONNECTED events.
116 typedef struct firehose_client_connected_info_s
{
117 unsigned long fcci_version
;
119 const void *fcci_data
;
121 } *firehose_client_connected_info_t
;
124 * @function firehose_client_get_unique_pid
127 * Returns the unique pid of the specified firehose client
130 * The specified client.
133 * The pid for this client.
136 * The unique pid of the specified client.
138 OS_NOTHROW OS_NONNULL1
140 firehose_client_get_unique_pid(firehose_client_t client
, pid_t
*pid
);
143 * @function firehose_client_get_pid_version
146 * Returns the pid version for that client.
149 * The specified client.
151 OS_NOTHROW OS_NONNULL1
153 firehose_client_get_pid_version(firehose_client_t client
);
156 * @function firehose_client_get_euid
159 * Returns the EUID for that client as discovered at connect time.
162 * The specified client.
164 OS_NOTHROW OS_NONNULL1
166 firehose_client_get_euid(firehose_client_t client
);
169 * @function firehose_client_get_metadata_buffer
172 * Returns the metadata buffer for the specified firehose client
175 * The specified client.
178 * The size of the metadata buffer.
181 * The pointer to the buffer.
183 OS_NOTHROW OS_NONNULL_ALL
185 firehose_client_get_metadata_buffer(firehose_client_t client
, size_t *size
);
188 * @function firehose_client_get_context
191 * Gets the context for the specified client.
194 * The specified client.
197 * The context set for the client with firehose_client_set_context
199 OS_NOTHROW OS_NONNULL1
201 firehose_client_get_context(firehose_client_t client
);
204 * @function firehose_client_set_context
207 * Sets the context for the specified client.
210 * Setting the context exchanges the context pointer, but the client must
211 * ensure proper synchronization with possible getters.
213 * The lifetime of the context is under the control of the API user,
214 * it is suggested to destroy the context when the CLIENT_DIED event is
218 * The specified client.
221 * The new context to set.
224 * The previous context set for the client.
226 OS_NOTHROW OS_NONNULL1
228 firehose_client_set_context(firehose_client_t client
, void *ctxt
);
231 * @function firehose_client_metadata_stream_peek
234 * Peek at the metadata stream in flight buffers for a given client
237 * This function should never be called from the context of a snapshot
241 * The specified client
244 * If this function is called synchronously from the handler passed to
245 * firehose_server_init, then `context` should be the event being processed.
246 * Else pass FIREHOSE_EVENT_NONE.
248 * @param peek_should_start
249 * Handler that is called prior to peeking to solve the race of metadata
250 * buffers not beeing processed yet at first lookup time, and being processed
251 * before the peek enumeration starts.
253 * If the handler returns false, then the enumeration doesn't start.
254 * If the race cannot happen, pass NULL.
257 * Handler that will receive all the live metadata buffers for this process.
258 * If the handler returns false, the enumeration is interrupted.
260 OS_NOTHROW OS_NONNULL1 OS_NONNULL4
262 firehose_client_metadata_stream_peek(firehose_client_t client
,
263 firehose_event_t context
, OS_NOESCAPE
bool (^peek_should_start
)(void),
264 OS_NOESCAPE
bool (^peek
)(firehose_chunk_t fbc
));
266 #pragma mark - Firehose Server
269 * @typedef firehose_handler_t
272 * Type of the handler block for firehose_server_init()
274 typedef void (^firehose_handler_t
)(firehose_client_t client
,
275 firehose_event_t event
, firehose_chunk_t page
);
278 * @function firehose_server_init
281 * Initializes the firehose MiG server
284 * Initializes the firehose MiG server by boostrap registering the services
285 * and creating dispatch_sources for the same.
289 firehose_server_init(mach_port_t firehose_comm_port
,
290 firehose_handler_t handler
);
293 * @function firehose_server_assert_spi_version
296 * Checks that libdispatch and firehose components all match
299 * Will assert that all the components have the same SPI versions
303 firehose_server_assert_spi_version(uint32_t spi_version
);
306 * @function firehose_server_has_ever_flushed_pages
309 * Checks whether the firehose server has ever flushed any pages this boot.
312 * Must be called after firehose_server_init() and before calling
313 * firehose_server_resume().
317 firehose_server_has_ever_flushed_pages(void);
320 * @function firehose_server_resume
323 * Allows firehose events to flow
326 * Must be called after firehose_server_init()
330 firehose_server_resume(void);
333 * @function firehose_server_cancel
336 * Cancels the server, disconnects all clients, and prevents new connections.
340 firehose_server_cancel(void);
343 * @typedef firehose_server_queue_t
346 * Values to pass to firehose_server_get_queue()
348 OS_ENUM(firehose_server_queue
, unsigned long,
349 FIREHOSE_SERVER_QUEUE_UNKNOWN
,
350 FIREHOSE_SERVER_QUEUE_IO
,
351 FIREHOSE_SERVER_QUEUE_MEMORY
,
355 * @function firehose_server_copy_queue
358 * Returns internal queues to the firehose server subsystem.
360 OS_NOTHROW OS_OBJECT_RETURNS_RETAINED
362 firehose_server_copy_queue(firehose_server_queue_t which
);
364 #pragma mark - Firehose Snapshot
367 * @typedef firehose_snapshot_event
369 OS_ENUM(firehose_snapshot_event
, unsigned long,
370 FIREHOSE_SNAPSHOT_EVENT_IO_START
= 1,
371 FIREHOSE_SNAPSHOT_EVENT_MEM_START
,
372 FIREHOSE_SNAPSHOT_EVENT_IO_BUFFER
,
373 FIREHOSE_SNAPSHOT_EVENT_MEM_BUFFER
,
374 FIREHOSE_SNAPSHOT_EVENT_COMPLETE
,
378 * @typedef firehose_snapshot_handler_t
381 * Type of the handler block for firehose_snapshot
383 typedef void (^firehose_snapshot_handler_t
)(firehose_client_t client
,
384 firehose_snapshot_event_t event
, firehose_chunk_t page
);
387 * @function firehose_snapshot
390 * Gather a snapshot for the current firehose state.
393 * This function can be called several times, in which case snapshots are taken
394 * one after the other. If coalescing is desired, it has to be built around this
399 firehose_snapshot(firehose_snapshot_handler_t handler
);
401 #endif // OS_FIREHOSE_SPI
403 #endif // __FIREHOSE_SERVER_PRIVATE__