1 /* 2 * Copyright (C) 2011 Citrix Ltd. 3 * Author Ian Jackson <ian.jackson@eu.citrix.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published 7 * by the Free Software Foundation; version 2.1 only. with the special 8 * exception on linking described in file LICENSE. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 */ 15 16 #ifndef LIBXL_EVENT_H 17 #define LIBXL_EVENT_H 18 19 #include <libxl.h> 20 #include <poll.h> 21 #include <sys/time.h> 22 23 /*======================================================================*/ 24 25 /* 26 * Domain event handling - getting Xen events from libxl 27 * 28 * (Callers inside libxl may not call libxl_event_check or _wait.) 29 */ 30 31 #define LIBXL_EVENTMASK_ALL (~(unsigned long)0) 32 33 typedef int libxl_event_predicate(const libxl_event*, void *user); 34 /* Return value is 0 if the event is unwanted or non-0 if it is. 35 * Predicates are not allowed to fail. 36 */ 37 38 int libxl_event_check(libxl_ctx *ctx, libxl_event **event_r, 39 uint64_t typemask, 40 libxl_event_predicate *predicate, void *predicate_user) 41 LIBXL_EXTERNAL_CALLERS_ONLY; 42 /* Searches for an event, already-happened, which matches typemask 43 * and predicate. predicate==0 matches any event. 44 * libxl_event_check returns the event, which must then later be 45 * freed by the caller using libxl_event_free. 46 * 47 * Returns ERROR_NOT_READY if no such event has happened. 48 */ 49 50 int libxl_event_wait(libxl_ctx *ctx, libxl_event **event_r, 51 uint64_t typemask, 52 libxl_event_predicate *predicate, void *predicate_user) 53 LIBXL_EXTERNAL_CALLERS_ONLY; 54 /* Like libxl_event_check but blocks if no suitable events are 55 * available, until some are. Uses libxl_osevent_beforepoll/ 56 * _afterpoll so may be inefficient if very many domains are being 57 * handled by a single program. 58 */ 59 60 void libxl_event_free(libxl_ctx *ctx, libxl_event *event); 61 62 63 /* Alternatively or additionally, the application may also use this: */ 64 65 typedef struct libxl_event_hooks { 66 uint64_t event_occurs_mask; 67 void (*event_occurs)(void *user, 68 #ifndef LIBXL_HAVE_NONCONST_EVENT_OCCURS_EVENT_ARG 69 const 70 #endif 71 libxl_event *event); 72 void (*disaster)(void *user, libxl_event_type type, 73 const char *msg, int errnoval); 74 } libxl_event_hooks; 75 76 void libxl_event_register_callbacks(libxl_ctx *ctx, 77 const libxl_event_hooks *hooks, void *user); 78 /* 79 * Arranges that libxl will henceforth call event_occurs for any 80 * events whose type is set in event_occurs_mask, rather than 81 * queueing the event for retrieval by libxl_event_check/wait. 82 * Events whose bit is clear in mask are not affected. 83 * 84 * event becomes owned by the application and must be freed, either 85 * by event_occurs or later. 86 * 87 * event_occurs may be NULL if mask is 0. 88 * 89 * libxl_event_register_callback also provides a way for libxl to 90 * report to the application that there was a problem reporting 91 * events; this can occur due to lack of host memory during event 92 * handling, or other wholly unrecoverable errors from system calls 93 * made by libxl. This will not happen for frivolous reasons - only 94 * if the system, or the Xen components of it, are badly broken. 95 * 96 * msg and errnoval will describe the action that libxl was trying 97 * to do, and type specifies the type of libxl events which may be 98 * missing. type may be 0 in which case events of all types may be 99 * missing. 100 * 101 * disaster may be NULL. If it is, or if _register_callbacks has 102 * not been called, errors of this kind are fatal to the entire 103 * application: libxl will print messages to its logs and to stderr 104 * and call exit(-1). 105 * 106 * If disaster returns, it may be the case that some or all future 107 * libxl calls will return errors; likewise it may be the case that 108 * no more events (of the specified type, if applicable) can be 109 * produced. An application which supplies a disaster function 110 * should normally react either by exiting, or by (when it has 111 * returned to its main event loop) shutting down libxl with 112 * libxl_ctx_free and perhaps trying to restart it with 113 * libxl_ctx_init. 114 * 115 * In any case before calling disaster, libxl will have logged a 116 * message with level XTL_CRITICAL. 117 * 118 * Reentrancy: it IS permitted to call libxl from within 119 * event_occurs. It is NOT permitted to call libxl from within 120 * disaster. The event_occurs and disaster callbacks may occur on 121 * any thread in which the application calls libxl. 122 * 123 * libxl_event_register_callbacks may be called as many times, with 124 * different parameters, as the application likes; the most recent 125 * call determines the libxl behaviour. However it is NOT safe to 126 * call _register_callbacks concurrently with, or reentrantly from, 127 * any other libxl function, nor while any event-generation 128 * facilities are enabled. 129 */ 130 131 132 /* 133 * Events are only generated if they have been requested. 134 * The following functions request the generation of specific events. 135 * 136 * Each set of functions for controlling event generation has this form: 137 * 138 * typedef struct libxl__evgen_FOO libxl__evgen_FOO; 139 * int libxl_evenable_FOO(libxl_ctx *ctx, FURTHER PARAMETERS, 140 * libxl_ev_user user, libxl__evgen_FOO **evgen_out); 141 * void libxl_evdisable_FOO(libxl_ctx *ctx, libxl__evgen_FOO *evgen); 142 * 143 * The evenable function arranges that the events (as described in the 144 * doc comment for the individual function) will start to be generated 145 * by libxl. On success, *evgen_out is set to a non-null pointer to 146 * an opaque struct. 147 * 148 * The user value is returned in the generated events and may be 149 * used by the caller for whatever it likes. The type ev_user is 150 * guaranteed to be an unsigned integer type which is at least 151 * as big as uint64_t and is also guaranteed to be big enough to 152 * contain any intptr_t value. 153 * 154 * If it becomes desirable to stop generation of the relevant events, 155 * or to reclaim the resources in libxl associated with the evgen 156 * structure, the same evgen value should be passed to the evdisable 157 * function. However, note that events which occurred prior to the 158 * evdisable call may still be returned. 159 * 160 * The caller may enable identical events more than once. If they do 161 * so, each actual occurrence will generate several events to be 162 * returned by libxl_event_check, with the appropriate user value(s). 163 * Aside from this, each occurrence of each event is returned by 164 * libxl_event_check exactly once. 165 * 166 * An evgen is associated with the libxl_ctx used for its creation. 167 * After libxl_ctx_free, all corresponding evgen handles become 168 * invalid and must no longer be passed to evdisable. 169 * 170 * Applications should ensure that they eventually retrieve every 171 * event using libxl_event_check or libxl_event_wait, since events 172 * which occur but are not retrieved by the application will be queued 173 * inside libxl indefinitely. libxl_event_check/_wait may be O(n) 174 * where n is the number of queued events which do not match the 175 * criteria specified in the arguments to check/wait. 176 */ 177 178 typedef struct libxl__evgen_domain_death libxl_evgen_domain_death; 179 int libxl_evenable_domain_death(libxl_ctx *ctx, uint32_t domid, 180 libxl_ev_user, libxl_evgen_domain_death **evgen_out); 181 void libxl_evdisable_domain_death(libxl_ctx *ctx, libxl_evgen_domain_death*); 182 /* Arranges for the generation of DOMAIN_SHUTDOWN and DOMAIN_DEATH 183 * events. A domain which is destroyed before it shuts down 184 * may generate only a DEATH event. 185 */ 186 187 typedef struct libxl__evgen_disk_eject libxl_evgen_disk_eject; 188 int libxl_evenable_disk_eject(libxl_ctx *ctx, uint32_t domid, const char *vdev, 189 libxl_ev_user, libxl_evgen_disk_eject **evgen_out); 190 void libxl_evdisable_disk_eject(libxl_ctx *ctx, libxl_evgen_disk_eject*); 191 /* Arranges for the generation of DISK_EJECT events. A copy of the 192 * string *vdev will be made for libxl's internal use, and a pointer 193 * to this (or some other) copy will be returned as the vdev 194 * member of event.u. 195 */ 196 197 198 /*======================================================================*/ 199 200 /* 201 * OS event handling - passing low-level OS events to libxl 202 * 203 * Event-driven programs must use these facilities to allow libxl 204 * to become aware of readability/writeability of file descriptors 205 * and the occurrence of timeouts. 206 * 207 * There are two approaches available. The first is appropriate for 208 * simple programs handling reasonably small numbers of domains: 209 * 210 * for (;;) { 211 * libxl_osevent_beforepoll(...) 212 * poll(); 213 * libxl_osevent_afterpoll(...); 214 * for (;;) { 215 * r = libxl_event_check(...); 216 * if (r==ERROR_NOT_READY) break; 217 * if (r) goto error_out; 218 * do something with the event; 219 * } 220 * } 221 * 222 * The second approach uses libxl_osevent_register_hooks and is 223 * suitable for programs which are already using a callback-based 224 * event library. 225 * 226 * An application may freely mix the two styles of interaction. 227 * 228 * (Callers inside libxl may not call libxl_osevent_... functions.) 229 */ 230 231 struct pollfd; 232 233 /* The caller should provide beforepoll with some space for libxl's 234 * fds, and tell libxl how much space is available by setting *nfds_io. 235 * fds points to the start of this space (and fds may be a pointer into 236 * a larger array, for example, if the application has some fds of 237 * its own that it is interested in). 238 * 239 * On return *nfds_io will in any case have been updated by libxl 240 * according to how many fds libxl wants to poll on. 241 * 242 * If the space was sufficient, libxl fills in fds[0..<new 243 * *nfds_io>] suitably for poll(2), updates *timeout_upd if needed, 244 * and returns ok. 245 * 246 * If space was insufficient, fds[0..<old *nfds_io>] is undefined on 247 * return; *nfds_io on return will be greater than the value on 248 * entry; *timeout_upd may or may not have been updated; and 249 * libxl_osevent_beforepoll returns ERROR_BUFERFULL. In this case 250 * the application needs to make more space (enough space for 251 * *nfds_io struct pollfd) and then call beforepoll again, before 252 * entering poll(2). Typically this will involve calling realloc. 253 * 254 * The application may call beforepoll with fds==NULL and 255 * *nfds_io==0 in order to find out how much space is needed. 256 * 257 * *timeout_upd is as for poll(2): it's in milliseconds, and 258 * negative values mean no timeout (infinity). 259 * libxl_osevent_beforepoll will only reduce the timeout, naturally. 260 */ 261 int libxl_osevent_beforepoll(libxl_ctx *ctx, int *nfds_io, 262 struct pollfd *fds, int *timeout_upd, 263 struct timeval now) 264 LIBXL_EXTERNAL_CALLERS_ONLY; 265 266 /* nfds and fds[0..nfds] must be from the most recent call to 267 * _beforepoll, as modified by poll. (It is therefore not possible 268 * to have multiple threads simultaneously polling using this 269 * interface.) 270 * 271 * This function actually performs all of the IO and other actions, 272 * and generates events (libxl_event), which are implied by either 273 * (a) the time of day or (b) both (i) the returned information from 274 * _beforepoll, and (ii) the results from poll specified in 275 * fds[0..nfds-1]. Generated events can then be retrieved by 276 * libxl_event_check. 277 */ 278 void libxl_osevent_afterpoll(libxl_ctx *ctx, int nfds, const struct pollfd *fds, 279 struct timeval now) 280 LIBXL_EXTERNAL_CALLERS_ONLY; 281 282 283 typedef struct libxl_osevent_hooks { 284 int (*fd_register)(void *user, int fd, void **for_app_registration_out, 285 short events, void *for_libxl); 286 int (*fd_modify)(void *user, int fd, void **for_app_registration_update, 287 short events); 288 void (*fd_deregister)(void *user, int fd, void *for_app_registration); 289 int (*timeout_register)(void *user, void **for_app_registration_out, 290 struct timeval abs, void *for_libxl); 291 int (*timeout_modify)(void *user, void **for_app_registration_update, 292 struct timeval abs) 293 /* only ever called with abs={0,0}, meaning ASAP */; 294 void (*timeout_deregister)(void *user, void *for_app_registration) 295 /* will never be called */; 296 } libxl_osevent_hooks; 297 298 /* The application which calls register_fd_hooks promises to 299 * maintain a register of fds and timeouts that libxl is interested 300 * in, and make calls into libxl (libxl_osevent_occurred_*) 301 * when those fd events and timeouts occur. This is more efficient 302 * than _beforepoll/_afterpoll if there are many fds (which can 303 * happen if the same libxl application is managing many domains). 304 * 305 * For an fd event, events is as for poll(). register or modify may 306 * be called with events==0, in which case it must still work 307 * normally, just not generate any events. 308 * 309 * For a timeout event, milliseconds is as for poll(). 310 * Specifically, negative values of milliseconds mean NO TIMEOUT. 311 * This is used by libxl to temporarily disable a timeout. 312 * 313 * If the register or modify hook succeeds it may update 314 * *for_app_registration_out/_update and must then return 0. 315 * On entry to register, *for_app_registration_out is always NULL. 316 * 317 * A registration or modification hook may fail, in which case it 318 * must leave the registration state of the fd or timeout unchanged. 319 * It may then either return ERROR_OSEVENT_REG_FAIL or any positive 320 * int. The value returned will be passed up through libxl and 321 * eventually returned back to the application. When register 322 * fails, any value stored into *for_registration_out is ignored by 323 * libxl; when modify fails, any changed value stored into 324 * *for_registration_update is honoured by libxl and will be passed 325 * to future modify or deregister calls. 326 * 327 * libxl may want to register more than one callback for any one fd; 328 * in that case: (i) each such registration will have at least one bit 329 * set in revents which is unique to that registration; (ii) if an 330 * event occurs which is relevant for multiple registrations the 331 * application's event system may call libxl_osevent_occurred_fd 332 * for one, some, or all of those registrations. 333 * 334 * If fd_modify is used, it is permitted for the application's event 335 * system to still make calls to libxl_osevent_occurred_fd for the 336 * "old" set of requested events; these will be safely ignored by 337 * libxl. 338 * 339 * libxl will remember the value stored in *for_app_registration_out 340 * (or *for_app_registration_update) by a successful call to 341 * register (or modify), and pass it to subsequent calls to modify 342 * or deregister. 343 * 344 * Note that the application must cope with a call from libxl to 345 * timeout_modify racing with its own call to 346 * libxl__osevent_occurred_timeout. libxl guarantees that 347 * timeout_modify will only be called with abs={0,0} but the 348 * application must still ensure that libxl's attempt to cause the 349 * timeout to occur immediately is safely ignored even the timeout is 350 * actually already in the process of occurring. 351 * 352 * timeout_deregister is not used because it forms part of a 353 * deprecated unsafe mode of use of the API. 354 * 355 * osevent_register_hooks may be called only once for each libxl_ctx. 356 * libxl may make calls to register/modify/deregister from within 357 * any libxl function (indeed, it will usually call register from 358 * register_event_hooks). Conversely, the application MUST NOT make 359 * the event occurrence calls (libxl_osevent_occurred_*) into libxl 360 * reentrantly from within libxl (for example, from within the 361 * register/modify functions). 362 * 363 * Lock hierarchy: the register/modify/deregister functions may be 364 * called with locks held. These locks (the "libxl internal locks") 365 * are inside the libxl_ctx. Therefore, if those register functions 366 * acquire any locks of their own ("caller register locks") outside 367 * libxl, to avoid deadlock one of the following must hold for each 368 * such caller register lock: 369 * (a) "acquire libxl internal locks before caller register lock": 370 * No libxl function may be called with the caller register 371 * lock held. 372 * (b) "acquire caller register lock before libxl internal locks": 373 * No libxl function may be called _without_ the caller 374 * register lock held. 375 * Of these we would normally recommend (a). 376 * 377 * The value *hooks is not copied and must outlast the libxl_ctx. 378 */ 379 void libxl_osevent_register_hooks(libxl_ctx *ctx, 380 const libxl_osevent_hooks *hooks, 381 void *user); 382 383 /* It is NOT legal to call _occurred_ reentrantly within any libxl 384 * function. Specifically it is NOT legal to call it from within 385 * a register callback. Conversely, libxl MAY call register/deregister 386 * from within libxl_event_occurred_call_*. 387 */ 388 389 void libxl_osevent_occurred_fd(libxl_ctx *ctx, void *for_libxl, 390 int fd, short events, short revents) 391 LIBXL_EXTERNAL_CALLERS_ONLY; 392 393 /* Implicitly, on entry to this function the timeout has been 394 * deregistered. If _occurred_timeout is called, libxl will not 395 * call timeout_deregister; if it wants to requeue the timeout it 396 * will call timeout_register again. 397 */ 398 void libxl_osevent_occurred_timeout(libxl_ctx *ctx, void *for_libxl) 399 LIBXL_EXTERNAL_CALLERS_ONLY; 400 401 402 /*======================================================================*/ 403 404 /* 405 * Subprocess handling. 406 * 407 * Unfortunately the POSIX interface makes this very awkward. 408 * 409 * There are two possible arrangements for collecting statuses from 410 * wait/waitpid. 411 * 412 * For naive programs: 413 * 414 * libxl will keep a SIGCHLD handler installed whenever it has an 415 * active (unreaped) child. It will reap all children with 416 * wait(); any children it does not recognise will be passed to 417 * the application via an optional callback (and will result in 418 * logged warnings if no callback is provided or the callback 419 * denies responsibility for the child). 420 * 421 * libxl may have children whenever: 422 * 423 * - libxl is performing an operation which can be made 424 * asynchronous; ie one taking a libxl_asyncop_how, even 425 * if NULL is passed indicating that the operation is 426 * synchronous; or 427 * 428 * - events of any kind are being generated, as requested 429 * by libxl_evenable_.... 430 * 431 * A multithreaded application which is naive in this sense may 432 * block SIGCHLD on some of its threads, but there must be at 433 * least one thread that has SIGCHLD unblocked. libxl will not 434 * modify the blocking flag for SIGCHLD (except that it may create 435 * internal service threads with all signals blocked). 436 * 437 * A naive program must only have at any one time only 438 * one libxl context which might have children. 439 * 440 * For programs which run their own children alongside libxl's: 441 * 442 * A program which does this must call libxl_childproc_setmode. 443 * There are three options: 444 * 445 * libxl_sigchld_owner_libxl: 446 * 447 * While any libxl operation which might use child processes 448 * is running, works like libxl_sigchld_owner_libxl_always; 449 * but, deinstalls the handler the rest of the time. 450 * 451 * In this mode, the application, while it uses any libxl 452 * operation which might create or use child processes (see 453 * above): 454 * - Must not have any child processes running. 455 * - Must not install a SIGCHLD handler. 456 * - Must not reap any children. 457 * 458 * This is the default (i.e. if setmode is not called, or 0 is 459 * passed for hooks). 460 * 461 * libxl_sigchld_owner_mainloop: 462 * 463 * The application must install a SIGCHLD handler and reap (at 464 * least) all of libxl's children and pass their exit status to 465 * libxl by calling libxl_childproc_exited. (If the application 466 * has multiple libxl ctx's, it must call libxl_childproc_exited 467 * on each ctx.) 468 * 469 * libxl_sigchld_owner_libxl_always: 470 * 471 * The application expects this libxl ctx to reap all of the 472 * process's children, and provides a callback to be notified of 473 * their exit statuses. The application must have only one 474 * libxl_ctx configured this way. 475 * 476 * libxl_sigchld_owner_libxl_always_selective_reap: 477 * 478 * The application expects to reap all of its own children 479 * synchronously, and does not use SIGCHLD. libxl is to install 480 * a SIGCHLD handler. The application may have multiple 481 * libxl_ctxs configured this way; in which case all of its ctxs 482 * must be so configured. 483 */ 484 485 486 typedef enum { 487 /* libxl owns SIGCHLD whenever it has a child, and reaps 488 * all children, including those not spawned by libxl. */ 489 libxl_sigchld_owner_libxl, 490 491 /* Application promises to discover when SIGCHLD occurs and call 492 * libxl_childproc_exited or libxl_childproc_sigchld_occurred (but 493 * NOT from within a signal handler). libxl will not itself 494 * arrange to (un)block or catch SIGCHLD. */ 495 libxl_sigchld_owner_mainloop, 496 497 /* libxl owns SIGCHLD all the time, and the application is 498 * relying on libxl's event loop for reaping its children too. */ 499 libxl_sigchld_owner_libxl_always, 500 501 /* libxl owns SIGCHLD all the time, but it must only reap its own 502 * children. The application will reap its own children 503 * synchronously with waitpid, without the assistance of SIGCHLD. */ 504 libxl_sigchld_owner_libxl_always_selective_reap, 505 } libxl_sigchld_owner; 506 507 typedef struct { 508 libxl_sigchld_owner chldowner; 509 510 /* All of these are optional: */ 511 512 /* Called by libxl instead of fork. Should behave exactly like 513 * fork, including setting errno etc. May NOT reenter into libxl. 514 * Application may use this to discover pids of libxl's children, 515 * for example. 516 */ 517 pid_t (*fork_replacement)(void *user); 518 519 /* With libxl_sigchld_owner_libxl, called by libxl when it has 520 * reaped a pid. (Not permitted with _owner_mainloop.) 521 * 522 * Should return 0 if the child was recognised by the application 523 * (or if the application does not keep those kind of records), 524 * ERROR_UNKNOWN_CHILD if the application knows that the child is not 525 * the application's; if it returns another error code it is a 526 * disaster as described for libxl_event_register_callbacks. 527 * (libxl will report unexpected children to its error log.) 528 * 529 * If not supplied, the application is assumed not to start 530 * any children of its own. 531 * 532 * This function is NOT called from within the signal handler. 533 * Rather it will be called from inside a libxl's event handling 534 * code and thus only when libxl is running, for example from 535 * within libxl_event_wait. (libxl uses the self-pipe trick 536 * to implement this.) 537 * 538 * childproc_exited_callback may call back into libxl, but it 539 * is best to avoid making long-running libxl calls as that might 540 * stall the calling event loop while the nested operation 541 * completes. 542 */ 543 int (*reaped_callback)(pid_t, int status, void *user); 544 } libxl_childproc_hooks; 545 546 /* hooks may be 0 in which is equivalent to &{ libxl_sigchld_owner_libxl, 0, 0 } 547 * 548 * May not be called when libxl might have any child processes, or the 549 * behaviour is undefined. So it is best to call this at 550 * initialisation. 551 * 552 * The value *hooks is not copied and must outlast the libxl_ctx. 553 */ 554 void libxl_childproc_setmode(libxl_ctx *ctx, const libxl_childproc_hooks *hooks, 555 void *user); 556 557 /* 558 * This function is for an application which owns SIGCHLD and which 559 * reaps all of the process's children, and dispatches the exit status 560 * to the correct place inside the application. 561 * 562 * May be called only by an application which has called setmode with 563 * chldowner == libxl_sigchld_owner_mainloop. If pid was a process started 564 * by this instance of libxl, returns 0 after doing whatever 565 * processing is appropriate. Otherwise silently returns 566 * ERROR_UNKNOWN_CHILD. No other error returns are possible. 567 * 568 * May NOT be called from within a signal handler which might 569 * interrupt any libxl operation. The application will almost 570 * certainly need to use the self-pipe trick (or a working pselect or 571 * ppoll) to implement this. 572 */ 573 int libxl_childproc_reaped(libxl_ctx *ctx, pid_t, int status) 574 LIBXL_EXTERNAL_CALLERS_ONLY; 575 576 /* 577 * This function is for an application which owns SIGCHLD but which 578 * doesn't keep track of all of its own children in a manner suitable 579 * for reaping all of them and then dispatching them. 580 * 581 * Such an the application must notify libxl, by calling this 582 * function, that a SIGCHLD occurred. libxl will then check all its 583 * children, reap any that are ready, and take any action necessary - 584 * but it will not reap anything else. 585 * 586 * May be called only by an application which has called setmode with 587 * chldowner == libxl_sigchld_owner_mainloop. 588 * 589 * May NOT be called from within a signal handler which might 590 * interrupt any libxl operation (just like libxl_childproc_reaped). 591 */ 592 void libxl_childproc_sigchld_occurred(libxl_ctx *ctx) 593 LIBXL_EXTERNAL_CALLERS_ONLY; 594 595 596 /* 597 * An application which initialises a libxl_ctx in a parent process 598 * and then forks a child which does not quickly exec, must 599 * instead libxl_postfork_child_noexec in the child. One call 600 * on any existing (or specially made) ctx is sufficient; after 601 * this all previously existing libxl_ctx's are invalidated and 602 * must not be used - or even freed. It is harmless to call this 603 * postfork function and then exec anyway. 604 * 605 * Until libxl_postfork_child_noexec has returned: 606 * - No other libxl calls may be made. 607 * - If any libxl ctx was configured handle the process's SIGCHLD, 608 * the child may not create further (grand)child processes, nor 609 * manipulate SIGCHLD. 610 * 611 * libxl_postfork_child_noexec may not reclaim all the resources 612 * associated with the libxl ctx. This includes but is not limited 613 * to: ordinary memory; files on disk and in /var/run; file 614 * descriptors; memory mapped into the process from domains being 615 * managed (grant maps); Xen event channels. Use of libxl in 616 * processes which fork long-lived children is not recommended for 617 * this reason. libxl_postfork_child_noexec is provided so that 618 * an application can make further libxl calls in a child which 619 * is going to exec or exit soon. 620 */ 621 void libxl_postfork_child_noexec(libxl_ctx *ctx); 622 623 624 #endif 625 626 /* 627 * Local variables: 628 * mode: C 629 * c-basic-offset: 4 630 * indent-tabs-mode: nil 631 * End: 632 */ 633