]> git.saurik.com Git - apple/libdispatch.git/blob - os/firehose_server_private.h
libdispatch-913.30.4.tar.gz
[apple/libdispatch.git] / os / firehose_server_private.h
1 /*
2 * Copyright (c) 2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 #ifndef __FIREHOSE_SERVER_PRIVATE__
22 #define __FIREHOSE_SERVER_PRIVATE__
23
24 #include <os/base.h>
25 #include <dispatch/dispatch.h>
26 #include "firehose_buffer_private.h"
27
28 #if OS_FIREHOSE_SPI
29 /*!
30 * @group Firehose SPI
31 * SPI intended for logd only
32 */
33
34 #pragma mark - Firehose Client
35
36 /*!
37 * @typedef firehose_client_t
38 *
39 * @abstract
40 * Represents a firehose client.
41 *
42 * @discussion
43 * Firehose client objects are os_object_t's, and it's legal to retain/release
44 * them with os_retain / os_release.
45 */
46 OS_OBJECT_DECL_CLASS(firehose_client);
47
48 /*!
49 * @typedef firehose_event_t
50 *
51 * @const FIREHOSE_EVENT_NONE
52 * Never passed to callbacks, meaningful for
53 * firehose_client_metadata_stream_peek.
54 *
55 * @const FIREHOSE_EVENT_CLIENT_CONNECTED
56 * A new client has connected
57 *
58 * This is the first event delivered, and no event is delivered until
59 * the handler of that event returns
60 *
61 * The `page` argument really is really a firehose_client_connected_info_t.
62 *
63 * @const FIREHOSE_EVENT_CLIENT_DIED
64 * The specified client is gone and will not flush new buffers
65 *
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.
69 *
70 * @const FIREHOSE_EVENT_IO_BUFFER_RECEIVED
71 * A new buffer needs to be pushed, `page` is set to that buffer.
72 *
73 * This event can be sent concurrently wrt FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
74 * events.
75 *
76 * @const FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
77 * A new buffer needs to be pushed, `page` is set to that buffer.
78 *
79 * This event can be sent concurrently wrt FIREHOSE_EVENT_IO_BUFFER_RECEIVED
80 * events.
81 *
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.
86 *
87 * This buffer isn't really a proper firehose buffer page, but its content may
88 * be useful for debugging purposes.
89 *
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.
94 *
95 * The event is sent from the context that is dropping the last refcount
96 * of the client.
97 */
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,
106 );
107
108 #define FIREHOSE_CLIENT_CONNECTED_INFO_VERSION 1
109
110 /*!
111 * @typedef firehose_client_connected_info
112 *
113 * @abstract
114 * Type of the data passed to CLIENT_CONNECTED events.
115 */
116 typedef struct firehose_client_connected_info_s {
117 unsigned long fcci_version;
118 // version 1
119 const void *fcci_data;
120 size_t fcci_size;
121 } *firehose_client_connected_info_t;
122
123 /*!
124 * @function firehose_client_get_unique_pid
125 *
126 * @abstract
127 * Returns the unique pid of the specified firehose client
128 *
129 * @param client
130 * The specified client.
131 *
132 * @param pid
133 * The pid for this client.
134 *
135 * @returns
136 * The unique pid of the specified client.
137 */
138 OS_NOTHROW OS_NONNULL1
139 uint64_t
140 firehose_client_get_unique_pid(firehose_client_t client, pid_t *pid);
141
142 /*!
143 * @function firehose_client_get_pid_version
144 *
145 * @abstract
146 * Returns the pid version for that client.
147 *
148 * @param client
149 * The specified client.
150 */
151 OS_NOTHROW OS_NONNULL1
152 int
153 firehose_client_get_pid_version(firehose_client_t client);
154
155 /*!
156 * @function firehose_client_get_euid
157 *
158 * @abstract
159 * Returns the EUID for that client as discovered at connect time.
160 *
161 * @param client
162 * The specified client.
163 */
164 OS_NOTHROW OS_NONNULL1
165 uid_t
166 firehose_client_get_euid(firehose_client_t client);
167
168 /*!
169 * @function firehose_client_get_metadata_buffer
170 *
171 * @abstract
172 * Returns the metadata buffer for the specified firehose client
173 *
174 * @param client
175 * The specified client.
176 *
177 * @param size
178 * The size of the metadata buffer.
179 *
180 * @returns
181 * The pointer to the buffer.
182 */
183 OS_NOTHROW OS_NONNULL_ALL
184 void *
185 firehose_client_get_metadata_buffer(firehose_client_t client, size_t *size);
186
187 /*!
188 * @function firehose_client_get_context
189 *
190 * @abstract
191 * Gets the context for the specified client.
192 *
193 * @param client
194 * The specified client.
195 *
196 * @returns
197 * The context set for the client with firehose_client_set_context
198 */
199 OS_NOTHROW OS_NONNULL1
200 void *
201 firehose_client_get_context(firehose_client_t client);
202
203 /*!
204 * @function firehose_client_set_context
205 *
206 * @abstract
207 * Sets the context for the specified client.
208 *
209 * @discussion
210 * Setting the context exchanges the context pointer, but the client must
211 * ensure proper synchronization with possible getters.
212 *
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
215 * received.
216 *
217 * @param client
218 * The specified client.
219 *
220 * @param ctxt
221 * The new context to set.
222 *
223 * @returns
224 * The previous context set for the client.
225 */
226 OS_NOTHROW OS_NONNULL1
227 void *
228 firehose_client_set_context(firehose_client_t client, void *ctxt);
229
230 /*!
231 * @function firehose_client_initiate_quarantine
232 *
233 * @abstract
234 * Starts the procedure to move the given client to the high volume quarantine
235 *
236 * @discussion
237 * When the client is in the high volume quarantine, their firehose chunks
238 * have the fcp_quarantined bit set to 1.
239 *
240 * @param client
241 * The specified client.
242 */
243 OS_NOTHROW OS_NONNULL1
244 void
245 firehose_client_initiate_quarantine(firehose_client_t client);
246
247 /*!
248 * @function firehose_client_metadata_stream_peek
249 *
250 * @abstract
251 * Peek at the metadata stream in flight buffers for a given client
252 *
253 * @discussion
254 * This function should never be called from the context of a snapshot
255 * handler.
256 *
257 * @param client
258 * The specified client
259 *
260 * @param context
261 * If this function is called synchronously from the handler passed to
262 * firehose_server_init, then `context` should be the event being processed.
263 * Else pass FIREHOSE_EVENT_NONE.
264 *
265 * @param peek_should_start
266 * Handler that is called prior to peeking to solve the race of metadata
267 * buffers not beeing processed yet at first lookup time, and being processed
268 * before the peek enumeration starts.
269 *
270 * If the handler returns false, then the enumeration doesn't start.
271 * If the race cannot happen, pass NULL.
272 *
273 * @param peek
274 * Handler that will receive all the live metadata buffers for this process.
275 * If the handler returns false, the enumeration is interrupted.
276 */
277 OS_NOTHROW OS_NONNULL1 OS_NONNULL4
278 void
279 firehose_client_metadata_stream_peek(firehose_client_t client,
280 firehose_event_t context, OS_NOESCAPE bool (^peek_should_start)(void),
281 OS_NOESCAPE bool (^peek)(firehose_chunk_t fbc));
282
283 #pragma mark - Firehose Server
284
285 /*!
286 * @typedef firehose_handler_t
287 *
288 * @abstract
289 * Type of the handler block for firehose_server_init()
290 */
291 typedef void (^firehose_handler_t)(firehose_client_t client,
292 firehose_event_t event, firehose_chunk_t page);
293
294 /*!
295 * @function firehose_server_init
296 *
297 * @abstract
298 * Initializes the firehose MiG server
299 *
300 * @discussion
301 * Initializes the firehose MiG server by boostrap registering the services
302 * and creating dispatch_sources for the same.
303 */
304 OS_NOTHROW
305 void
306 firehose_server_init(mach_port_t firehose_comm_port,
307 firehose_handler_t handler);
308
309 /*!
310 * @function firehose_server_assert_spi_version
311 *
312 * @abstract
313 * Checks that libdispatch and firehose components all match
314 *
315 * @discussion
316 * Will assert that all the components have the same SPI versions
317 */
318 OS_NOTHROW
319 void
320 firehose_server_assert_spi_version(uint32_t spi_version);
321
322 /*!
323 * @function firehose_server_has_ever_flushed_pages
324 *
325 * @abstract
326 * Checks whether the firehose server has ever flushed any pages this boot.
327 *
328 * @discussion
329 * Must be called after firehose_server_init() and before calling
330 * firehose_server_resume().
331 */
332 OS_NOTHROW
333 bool
334 firehose_server_has_ever_flushed_pages(void);
335
336 /*!
337 * @function firehose_server_resume
338 *
339 * @abstract
340 * Allows firehose events to flow
341 *
342 * @discussion
343 * Must be called after firehose_server_init()
344 */
345 OS_NOTHROW
346 void
347 firehose_server_resume(void);
348
349 /*!
350 * @function firehose_server_cancel
351 *
352 * @abstract
353 * Cancels the server, disconnects all clients, and prevents new connections.
354 */
355 OS_NOTHROW
356 void
357 firehose_server_cancel(void);
358
359 /*!
360 * @typedef firehose_server_queue_t
361 *
362 * @abstract
363 * Values to pass to firehose_server_get_queue()
364 */
365 OS_ENUM(firehose_server_queue, unsigned long,
366 FIREHOSE_SERVER_QUEUE_UNKNOWN,
367 FIREHOSE_SERVER_QUEUE_IO,
368 FIREHOSE_SERVER_QUEUE_MEMORY,
369 );
370
371 /*!
372 * @function firehose_server_copy_queue
373 *
374 * @abstract
375 * Returns internal queues to the firehose server subsystem.
376 */
377 OS_NOTHROW OS_OBJECT_RETURNS_RETAINED
378 dispatch_queue_t
379 firehose_server_copy_queue(firehose_server_queue_t which);
380
381 /*!
382 * @function firehose_server_quarantined_suspend
383 *
384 * @abstract
385 * Suspends processing of quarantined clients until
386 * firehose_server_quarantined_resume() is called for the same queue.
387 *
388 * @discussion
389 * Suspending processing of quarantined clients causes firehose_snapshot()
390 * to block until the processing is enabled again.
391 *
392 * However if this is used to pace the processing, it is a good idea to disable
393 * this pacing until the snapshot has completed.
394 *
395 * Similarly, quarantine suspension must be off during shutdown.
396 */
397 OS_NOTHROW
398 void
399 firehose_server_quarantined_suspend(firehose_server_queue_t q);
400
401 /*!
402 * @function firehose_server_quarantined_resume
403 *
404 * @abstract
405 * Resumes processing of quarantined clients.
406 */
407 OS_NOTHROW
408 void
409 firehose_server_quarantined_resume(firehose_server_queue_t q);
410
411 #pragma mark - Firehose Snapshot
412
413 /*!
414 * @typedef firehose_snapshot_event
415 */
416 OS_ENUM(firehose_snapshot_event, unsigned long,
417 FIREHOSE_SNAPSHOT_EVENT_IO_START = 1,
418 FIREHOSE_SNAPSHOT_EVENT_MEM_START,
419 FIREHOSE_SNAPSHOT_EVENT_IO_BUFFER,
420 FIREHOSE_SNAPSHOT_EVENT_MEM_BUFFER,
421 FIREHOSE_SNAPSHOT_EVENT_COMPLETE,
422 );
423
424 /*!
425 * @typedef firehose_snapshot_handler_t
426 *
427 * @abstract
428 * Type of the handler block for firehose_snapshot
429 */
430 typedef void (^firehose_snapshot_handler_t)(firehose_client_t client,
431 firehose_snapshot_event_t event, firehose_chunk_t page);
432
433 /*!
434 * @function firehose_snapshot
435 *
436 * @abstract
437 * Gather a snapshot for the current firehose state.
438 *
439 * @discussion
440 * This function can be called several times, in which case snapshots are taken
441 * one after the other. If coalescing is desired, it has to be built around this
442 * call.
443 */
444 OS_NOTHROW
445 void
446 firehose_snapshot(firehose_snapshot_handler_t handler);
447
448 #endif // OS_FIREHOSE_SPI
449
450 #endif // __FIREHOSE_SERVER_PRIVATE__