firehose_server_private.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  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. #ifndef __FIREHOSE_SERVER_PRIVATE__
  21. #define __FIREHOSE_SERVER_PRIVATE__
  22. #include <os/base.h>
  23. #include <dispatch/dispatch.h>
  24. #include "firehose_buffer_private.h"
  25. #if OS_FIREHOSE_SPI
  26. /*!
  27. * @group Firehose SPI
  28. * SPI intended for logd only
  29. */
  30. #pragma mark - Firehose Client
  31. /*!
  32. * @typedef firehose_client_t
  33. *
  34. * @abstract
  35. * Represents a firehose client.
  36. *
  37. * @discussion
  38. * Firehose client objects are os_object_t's, and it's legal to retain/release
  39. * them with os_retain / os_release.
  40. */
  41. OS_OBJECT_DECL_CLASS(firehose_client);
  42. /*!
  43. * @typedef firehose_event_t
  44. *
  45. * @const FIREHOSE_EVENT_NONE
  46. * Never passed to callbacks, meaningful for
  47. * firehose_client_metadata_stream_peek.
  48. *
  49. * @const FIREHOSE_EVENT_CLIENT_CONNECTED
  50. * A new client has connected
  51. *
  52. * This is the first event delivered, and no event is delivered until
  53. * the handler of that event returns
  54. *
  55. * The `page` argument is really a firehose_client_connected_info_t. The
  56. * `fc_pos` argument is not meaningful.
  57. *
  58. * @const FIREHOSE_EVENT_CLIENT_DIED
  59. * The specified client is gone and will not flush new buffers
  60. *
  61. * This is the last event delivered, it is never called before all other
  62. * event handlers have returned. This event is generated even when a
  63. * FIREHOSE_EVENT_CLIENT_CORRUPTED event has been generated.
  64. *
  65. * @const FIREHOSE_EVENT_IO_BUFFER_RECEIVED
  66. * A new buffer needs to be pushed; `page` is set to that buffer, and `fc_pos`
  67. * to its chunk position header.
  68. *
  69. * This event can be sent concurrently wrt FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
  70. * events.
  71. *
  72. * @const FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
  73. * A new buffer needs to be pushed; `page` is set to that buffer, and `fc_pos`
  74. * to its chunk position header.
  75. *
  76. * This event can be sent concurrently wrt FIREHOSE_EVENT_IO_BUFFER_RECEIVED
  77. * events.
  78. *
  79. * @const FIREHOSE_EVENT_CLIENT_CORRUPTED
  80. * This event is received when a client is found being corrupted.
  81. * `page` is set to the buffer header page, and `fc_pos` is not meaningful. When
  82. * this event is received, logs have likely been lost for this client.
  83. *
  84. * This buffer isn't really a proper firehose buffer page, but its content may
  85. * be useful for debugging purposes.
  86. *
  87. * @const FIREHOSE_EVENT_CLIENT_FINALIZE
  88. * This event is received when a firehose client structure is about to be
  89. * destroyed. Only firehose_client_get_context() can ever be called with
  90. * the passed firehose client. The `page` argument is NULL for this event, and
  91. * the `fc_pos` argument is not meaningful.
  92. *
  93. * The event is sent from the context that is dropping the last refcount
  94. * of the client.
  95. */
  96. OS_ENUM(firehose_event, unsigned long,
  97. FIREHOSE_EVENT_NONE = 0,
  98. FIREHOSE_EVENT_CLIENT_CONNECTED,
  99. FIREHOSE_EVENT_CLIENT_DIED,
  100. FIREHOSE_EVENT_IO_BUFFER_RECEIVED,
  101. FIREHOSE_EVENT_MEM_BUFFER_RECEIVED,
  102. FIREHOSE_EVENT_CLIENT_CORRUPTED,
  103. FIREHOSE_EVENT_CLIENT_FINALIZE,
  104. );
  105. #define FIREHOSE_CLIENT_CONNECTED_INFO_VERSION 1
  106. /*!
  107. * @typedef firehose_client_connected_info
  108. *
  109. * @abstract
  110. * Type of the data passed to CLIENT_CONNECTED events.
  111. */
  112. typedef struct firehose_client_connected_info_s {
  113. unsigned long fcci_version;
  114. // version 1
  115. const void *fcci_data;
  116. size_t fcci_size;
  117. } *firehose_client_connected_info_t;
  118. /*!
  119. * @function firehose_client_get_unique_pid
  120. *
  121. * @abstract
  122. * Returns the unique pid of the specified firehose client
  123. *
  124. * @param client
  125. * The specified client.
  126. *
  127. * @param pid
  128. * The pid for this client.
  129. *
  130. * @returns
  131. * The unique pid of the specified client.
  132. */
  133. OS_NOTHROW OS_NONNULL1
  134. uint64_t
  135. firehose_client_get_unique_pid(firehose_client_t client, pid_t *pid);
  136. /*!
  137. * @function firehose_client_get_pid_version
  138. *
  139. * @abstract
  140. * Returns the pid version for that client.
  141. *
  142. * @param client
  143. * The specified client.
  144. */
  145. OS_NOTHROW OS_NONNULL1
  146. int
  147. firehose_client_get_pid_version(firehose_client_t client);
  148. /*!
  149. * @function firehose_client_get_euid
  150. *
  151. * @abstract
  152. * Returns the EUID for that client as discovered at connect time.
  153. *
  154. * @param client
  155. * The specified client.
  156. */
  157. OS_NOTHROW OS_NONNULL1
  158. uid_t
  159. firehose_client_get_euid(firehose_client_t client);
  160. /*!
  161. * @function firehose_client_get_metadata_buffer
  162. *
  163. * @abstract
  164. * Returns the metadata buffer for the specified firehose client
  165. *
  166. * @param client
  167. * The specified client.
  168. *
  169. * @param size
  170. * The size of the metadata buffer.
  171. *
  172. * @returns
  173. * The pointer to the buffer.
  174. */
  175. OS_NOTHROW OS_NONNULL_ALL
  176. void *
  177. firehose_client_get_metadata_buffer(firehose_client_t client, size_t *size);
  178. /*!
  179. * @function firehose_client_get_context
  180. *
  181. * @abstract
  182. * Gets the context for the specified client.
  183. *
  184. * @param client
  185. * The specified client.
  186. *
  187. * @returns
  188. * The context set for the client with firehose_client_set_context
  189. */
  190. OS_NOTHROW OS_NONNULL1
  191. void *
  192. firehose_client_get_context(firehose_client_t client);
  193. /*!
  194. * @function firehose_client_set_strings_cached
  195. *
  196. * @abstract
  197. * Marks a given client as having strings cached already.
  198. *
  199. * @param client
  200. * The specified client.
  201. */
  202. OS_NOTHROW OS_NONNULL1
  203. void
  204. firehose_client_set_strings_cached(firehose_client_t client);
  205. /*!
  206. * @function firehose_client_set_context
  207. *
  208. * @abstract
  209. * Sets the context for the specified client.
  210. *
  211. * @discussion
  212. * Setting the context exchanges the context pointer, but the client must
  213. * ensure proper synchronization with possible getters.
  214. *
  215. * The lifetime of the context is under the control of the API user,
  216. * it is suggested to destroy the context when the CLIENT_DIED event is
  217. * received.
  218. *
  219. * @param client
  220. * The specified client.
  221. *
  222. * @param ctxt
  223. * The new context to set.
  224. *
  225. * @returns
  226. * The previous context set for the client.
  227. */
  228. OS_NOTHROW OS_NONNULL1
  229. void *
  230. firehose_client_set_context(firehose_client_t client, void *ctxt);
  231. /*!
  232. * @function firehose_client_initiate_quarantine
  233. *
  234. * @abstract
  235. * Starts the procedure to move the given client to the high volume quarantine
  236. *
  237. * @discussion
  238. * When the client is in the high volume quarantine, their firehose chunks
  239. * have the fcp_quarantined bit set to 1.
  240. *
  241. * @param client
  242. * The specified client.
  243. */
  244. OS_NOTHROW OS_NONNULL1
  245. void
  246. firehose_client_initiate_quarantine(firehose_client_t client);
  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. #pragma mark - Firehose Server
  283. /*!
  284. * @typedef firehose_handler_t
  285. *
  286. * @abstract
  287. * Type of the handler block for firehose_server_init()
  288. */
  289. typedef void (^firehose_handler_t)(firehose_client_t client,
  290. firehose_event_t event, firehose_chunk_t page,
  291. firehose_chunk_pos_u fc_pos);
  292. /*!
  293. * @function firehose_server_init
  294. *
  295. * @abstract
  296. * Initializes the firehose MiG server
  297. *
  298. * @discussion
  299. * Initializes the firehose MiG server by boostrap registering the services
  300. * and creating dispatch_sources for the same.
  301. */
  302. OS_NOTHROW
  303. void
  304. firehose_server_init(mach_port_t firehose_comm_port,
  305. firehose_handler_t handler);
  306. /*!
  307. * @function firehose_server_assert_spi_version
  308. *
  309. * @abstract
  310. * Checks that libdispatch and firehose components all match
  311. *
  312. * @discussion
  313. * Will assert that all the components have the same SPI versions
  314. */
  315. OS_NOTHROW
  316. void
  317. firehose_server_assert_spi_version(uint32_t spi_version);
  318. /*!
  319. * @function firehose_server_has_ever_flushed_pages
  320. *
  321. * @abstract
  322. * Checks whether the firehose server has ever flushed any pages this boot.
  323. *
  324. * @discussion
  325. * Must be called after firehose_server_init() and before calling
  326. * firehose_server_resume().
  327. */
  328. OS_NOTHROW
  329. bool
  330. firehose_server_has_ever_flushed_pages(void);
  331. /*!
  332. * @function firehose_server_resume
  333. *
  334. * @abstract
  335. * Allows firehose events to flow
  336. *
  337. * @discussion
  338. * Must be called after firehose_server_init()
  339. */
  340. OS_NOTHROW
  341. void
  342. firehose_server_resume(void);
  343. /*!
  344. * @function firehose_server_cancel
  345. *
  346. * @abstract
  347. * Cancels the server, disconnects all clients, and prevents new connections.
  348. */
  349. OS_NOTHROW
  350. void
  351. firehose_server_cancel(void);
  352. /*!
  353. * @function firehose_server_set_logging_prefs
  354. *
  355. * @abstract
  356. * Publishes a new preferences buffer.
  357. *
  358. * @description
  359. * The server will take ownership of this buffer and will
  360. * call munmap() on the previous one that was stored.
  361. */
  362. OS_NOTHROW
  363. void
  364. firehose_server_set_logging_prefs(void *pointer, size_t length,
  365. os_block_t block);
  366. /*!
  367. * @typedef firehose_server_queue_t
  368. *
  369. * @abstract
  370. * Values to pass to firehose_server_get_queue()
  371. */
  372. OS_ENUM(firehose_server_queue, unsigned long,
  373. FIREHOSE_SERVER_QUEUE_UNKNOWN,
  374. FIREHOSE_SERVER_QUEUE_IO,
  375. FIREHOSE_SERVER_QUEUE_MEMORY,
  376. );
  377. /*!
  378. * @function firehose_server_copy_queue
  379. *
  380. * @abstract
  381. * Returns internal queues to the firehose server subsystem.
  382. */
  383. OS_NOTHROW OS_OBJECT_RETURNS_RETAINED
  384. dispatch_queue_t
  385. firehose_server_copy_queue(firehose_server_queue_t which);
  386. /*!
  387. * @function firehose_server_quarantined_suspend
  388. *
  389. * @abstract
  390. * Suspends processing of quarantined clients until
  391. * firehose_server_quarantined_resume() is called for the same queue.
  392. *
  393. * @discussion
  394. * Suspending processing of quarantined clients causes firehose_snapshot()
  395. * to block until the processing is enabled again.
  396. *
  397. * However if this is used to pace the processing, it is a good idea to disable
  398. * this pacing until the snapshot has completed.
  399. *
  400. * Similarly, quarantine suspension must be off during shutdown.
  401. */
  402. OS_NOTHROW
  403. void
  404. firehose_server_quarantined_suspend(firehose_server_queue_t q);
  405. /*!
  406. * @function firehose_server_quarantined_resume
  407. *
  408. * @abstract
  409. * Resumes processing of quarantined clients.
  410. */
  411. OS_NOTHROW
  412. void
  413. firehose_server_quarantined_resume(firehose_server_queue_t q);
  414. #pragma mark - Firehose Snapshot
  415. /*!
  416. * @typedef firehose_snapshot_event
  417. */
  418. OS_ENUM(firehose_snapshot_event, unsigned long,
  419. FIREHOSE_SNAPSHOT_EVENT_IO_START = 1,
  420. FIREHOSE_SNAPSHOT_EVENT_MEM_START,
  421. FIREHOSE_SNAPSHOT_EVENT_IO_BUFFER,
  422. FIREHOSE_SNAPSHOT_EVENT_MEM_BUFFER,
  423. FIREHOSE_SNAPSHOT_EVENT_COMPLETE,
  424. );
  425. /*!
  426. * @typedef firehose_snapshot_handler_t
  427. *
  428. * @abstract
  429. * Type of the handler block for firehose_snapshot
  430. */
  431. typedef void (^firehose_snapshot_handler_t)(firehose_client_t client,
  432. firehose_snapshot_event_t event, firehose_chunk_t page,
  433. firehose_chunk_pos_u fc_pos);
  434. /*!
  435. * @function firehose_snapshot
  436. *
  437. * @abstract
  438. * Gather a snapshot for the current firehose state.
  439. *
  440. * @discussion
  441. * This function can be called several times, in which case snapshots are taken
  442. * one after the other. If coalescing is desired, it has to be built around this
  443. * call.
  444. */
  445. OS_NOTHROW
  446. void
  447. firehose_snapshot(firehose_snapshot_handler_t handler);
  448. #endif // OS_FIREHOSE_SPI
  449. #endif // __FIREHOSE_SERVER_PRIVATE__