| 307 | } |
| 308 | |
| 309 | apr_status_t md_renew_start_watching(md_mod_conf_t *mc, server_rec *s, apr_pool_t *p) |
| 310 | { |
| 311 | apr_allocator_t *allocator; |
| 312 | md_renew_ctx_t *dctx; |
| 313 | apr_pool_t *dctxp; |
| 314 | apr_status_t rv; |
| 315 | md_t *md; |
| 316 | md_job_t *job; |
| 317 | int i; |
| 318 | |
| 319 | /* We use mod_watchdog to run a single thread in one of the child processes |
| 320 | * to monitor the MDs marked as watched, using the const data in the list |
| 321 | * mc->mds of our MD structures. |
| 322 | * |
| 323 | * The data in mc cannot be changed, as we may spawn copies in new child processes |
| 324 | * of the original data at any time. The child which hosts the watchdog thread |
| 325 | * may also die or be recycled, which causes a new watchdog thread to run |
| 326 | * in another process with the original data. |
| 327 | * |
| 328 | * Instead, we use our store to persist changes in group STAGING. This is |
| 329 | * kept writable to child processes, but the data stored there is not live. |
| 330 | * However, mod_watchdog makes sure that we only ever have a single thread in |
| 331 | * our server (on this machine) that writes there. Other processes, e.g. informing |
| 332 | * the user about progress, only read from there. |
| 333 | * |
| 334 | * All changes during driving an MD are stored as files in MG_SG_STAGING/<MD.name>. |
| 335 | * All will have "md.json" and "job.json". There may be a range of other files used |
| 336 | * by the protocol obtaining the certificate/keys. |
| 337 | * |
| 338 | * |
| 339 | */ |
| 340 | wd_get_instance = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_get_instance); |
| 341 | wd_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback); |
| 342 | wd_set_interval = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_set_callback_interval); |
| 343 | |
| 344 | if (!wd_get_instance || !wd_register_callback || !wd_set_interval) { |
| 345 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(10061) "mod_watchdog is required"); |
| 346 | return !OK; |
| 347 | } |
| 348 | |
| 349 | /* We want our own pool with own allocator to keep data across watchdog invocations. |
| 350 | * Since we'll run in a single watchdog thread, using our own allocator will prevent |
| 351 | * any confusion in the parent pool. */ |
| 352 | apr_allocator_create(&allocator); |
| 353 | apr_allocator_max_free_set(allocator, 1); |
| 354 | rv = apr_pool_create_ex(&dctxp, p, NULL, allocator); |
| 355 | if (rv != APR_SUCCESS) { |
| 356 | ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10062) "md_renew_watchdog: create pool"); |
| 357 | return rv; |
| 358 | } |
| 359 | apr_allocator_owner_set(allocator, dctxp); |
| 360 | apr_pool_tag(dctxp, "md_renew_watchdog"); |
| 361 | |
| 362 | dctx = apr_pcalloc(dctxp, sizeof(*dctx)); |
| 363 | dctx->p = dctxp; |
| 364 | dctx->s = s; |
| 365 | dctx->mc = mc; |
| 366 |
no test coverage detected