Annotation of embedaddon/libpdel/config/app_config.3, revision 1.1.1.1

1.1       misho       1: .\" Copyright (c) 2001-2002 Packet Design, LLC.
                      2: .\" All rights reserved.
                      3: .\" 
                      4: .\" Subject to the following obligations and disclaimer of warranty,
                      5: .\" use and redistribution of this software, in source or object code
                      6: .\" forms, with or without modifications are expressly permitted by
                      7: .\" Packet Design; provided, however, that:
                      8: .\" 
                      9: .\"    (i)  Any and all reproductions of the source or object code
                     10: .\"         must include the copyright notice above and the following
                     11: .\"         disclaimer of warranties; and
                     12: .\"    (ii) No rights are granted, in any manner or form, to use
                     13: .\"         Packet Design trademarks, including the mark "PACKET DESIGN"
                     14: .\"         on advertising, endorsements, or otherwise except as such
                     15: .\"         appears in the above copyright notice or in the software.
                     16: .\" 
                     17: .\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
                     18: .\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
                     19: .\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
                     20: .\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
                     21: .\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
                     22: .\" OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
                     23: .\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
                     24: .\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
                     25: .\" RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
                     26: .\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
                     27: .\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
                     28: .\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
                     29: .\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
                     30: .\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
                     31: .\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     32: .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
                     33: .\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
                     34: .\" THE POSSIBILITY OF SUCH DAMAGE.
                     35: .\"
                     36: .\" Author: Archie Cobbs <archie@freebsd.org>
                     37: .\"
                     38: .\" $Id: app_config.3,v 1.12 2004/06/02 17:24:36 archie Exp $
                     39: .\"
                     40: .Dd April 22, 2002
                     41: .Dt APP_CONFIG 3
                     42: .Os
                     43: .Sh NAME
                     44: .Nm app_config
                     45: .Nd application configuration system
                     46: .Sh LIBRARY
                     47: PDEL Library (libpdel, \-lpdel)
                     48: .Sh SYNOPSIS
                     49: .In sys/types.h
                     50: .In pdel/config/app_config.h
                     51: .Ft "struct app_config_ctx *"
                     52: .Fn app_config_init "struct pevent_ctx *ctx" "const struct app_config *info" "void *cookie"
                     53: .Ft int
                     54: .Fn app_config_uninit "struct app_config_ctx **ctxp"
                     55: .Ft "void *"
                     56: .Fn app_config_get_cookie "struct app_config_ctx *ctx"
                     57: .Ft int
                     58: .Fn app_config_load "struct app_config_ctx *ctx" "const char *path" "int allow_writeback"
                     59: .Ft int
                     60: .Fn app_config_reload "struct app_config_ctx *ctx"
                     61: .Ft "void *"
                     62: .Fn app_config_new "struct app_config_ctx *ctx"
                     63: .Ft int
                     64: .Fn app_config_set "struct app_config_ctx *ctx" "const void *config" "u_long delay" "char *ebuf" "int emax"
                     65: .Ft "void *"
                     66: .Fn app_config_get "struct app_config_ctx *ctx" "int pending"
                     67: .Ft "const struct structs_type *"
                     68: .Fn app_config_get_type "struct app_config_ctx *ctx"
                     69: .Ft "void *"
                     70: .Fn app_config_copy "struct app_config_ctx *ctx" "const void *config"
                     71: .Ft void
                     72: .Fn app_config_free "struct app_config_ctx *ctx" "void **configp"
                     73: .Vt extern const struct app_subsystem app_config_alog_subsystem ;
                     74: .Vt extern const struct app_subsystem app_config_curconf_subsystem ;
                     75: .Vt extern const struct app_subsystem app_config_directory_subsystem ;
                     76: .Vt extern const struct app_subsystem app_config_pidfile_subsystem ;
                     77: .Sh DESCRIPTION
                     78: These functions implement an application configuration framework.
                     79: .\"
                     80: .Ss Application model
                     81: .\"
                     82: The
                     83: .Nm app_config
                     84: model assumes that the application's configuration is stored in a single
                     85: .Em "configuration object" ,
                     86: which can be any data structure that is describable by a
                     87: .Xr structs 3
                     88: type.
                     89: The configuration can be stored in an XML file which is automatically updated.
                     90: .Pp
                     91: The application itself consists of one or more
                     92: .Em subsystems .
                     93: A subsystem is an abstract activity that can be started or stopped and
                     94: whose behavior depends on (some part of) the configuration object.
                     95: When the configuration object is changed, those subsystems that
                     96: require it are automatically stopped and then restarted with the new
                     97: configuration.
                     98: .Pp
                     99: The application may provide methods for:
                    100: .Pp
                    101: .Bl -bullet -compact -offset 3n
                    102: .It
                    103: Creating a new, default configuration object
                    104: .It
                    105: Initializing a new configuration object for the current system
                    106: .It
                    107: Checking a configuration object for overall validity
                    108: .It
                    109: Normalizing a configuration object
                    110: .It
                    111: Upgrading a configuration object from an old version
                    112: .El
                    113: .Pp
                    114: Each subsystem may provide methods for:
                    115: .Pp
                    116: .Bl -bullet -compact -offset 3n
                    117: .It
                    118: Starting the subsystem
                    119: .It
                    120: Stopping the subsystem
                    121: .It
                    122: Determining if the subsystem will run
                    123: .It
                    124: Determining if the subsystem needs to be restarted
                    125: .El
                    126: .Pp
                    127: In the steady state, there is a single currently active configuration object.
                    128: Only those subsystems that are supposed to be running are.
                    129: All running subsystems are running with their configurations based on
                    130: (i.e., consistent with) the active configuration object.
                    131: .Pp
                    132: When there needs to be a configuration change, a new configuration object
                    133: is constructed and the
                    134: .Nm app_config
                    135: library is told to apply the new configuration object.
                    136: After a configurable delay (for hysteresis), those subsystems affected
                    137: by the change are stopped, the new configuration object is installed
                    138: in place of the old one, and the stopped subsystems are restarted.
                    139: .Pp
                    140: The
                    141: .Nm app_config
                    142: library guarantees that only "valid" configurations may be applied,
                    143: where the meaning of "valid" is determined by the application.
                    144: .\"
                    145: .Ss Subsystems
                    146: .\"
                    147: A subsystem is defined as anything that can be started and/or stopped.
                    148: A subsystem typically depends on some portion of the configuration
                    149: object such that it must be stopped and restarted when that portion changes.
                    150: .Pp
                    151: A subsystem is defined by a
                    152: .Li "struct app_subsystem" :
                    153: .Pp
                    154: .Bd -literal -compact -offset 3n
                    155: struct app_subsystem {
                    156:     const char          *name;      /* name, null to end list */
                    157:     void                *arg;       /* opaque subsystem argument */
                    158:     app_ss_startup_t    *start;     /* start subsystem */
                    159:     app_ss_shutdown_t   *stop;      /* stop subsystem */
                    160:     app_ss_willrun_t    *willrun;   /* will subsystem run? */
                    161:     app_ss_changed_t    *changed;   /* subsystem config changed? */
                    162:     const char          **deplist;  /* config items dependent on */
                    163: };
                    164: .Ed
                    165: .Pp
                    166: The
                    167: .Fa name
                    168: is currently used only for debugging, but must be
                    169: .Dv NULL
                    170: to terminate the list of subsystems (see below).
                    171: The
                    172: .Fa arg
                    173: is ignored and is for the application's private use.
                    174: The
                    175: .Fa start ,
                    176: .Fa stop ,
                    177: .Fa willrun ,
                    178: and
                    179: .Fa changed
                    180: fields must be pointers to functions having these types:
                    181: .Pp
                    182: .Bd -literal -compact -offset 3n
                    183: typedef int  app_ss_startup_t(struct app_config_ctx *ctx,
                    184:                 const struct app_subsystem *ss, const void *config);
                    185: typedef void app_ss_shutdown_t(struct app_config_ctx *ctx,
                    186:                 const struct app_subsystem *ss, const void *config);
                    187: typedef int  app_ss_willrun_t(struct app_config_ctx *ctx,
                    188:                 const struct app_subsystem *ss, const void *config);
                    189: typedef int  app_ss_changed_t(struct app_config_ctx *ctx,
                    190:                 const struct app_subsystem *ss,
                    191:                 const void *config1, const void *config2);
                    192: .Ed
                    193: .Pp
                    194: .Fn start
                    195: starts the subsystem;
                    196: .Fa config
                    197: points to a copy of the current (i.e., new) configuration object.
                    198: .Fn start
                    199: should return zero if successful, or else -1 with
                    200: .Va errno
                    201: set on failure.
                    202: In the latter case, the
                    203: .Fn stop
                    204: method will not be called.
                    205: .Pp
                    206: .Fn stop
                    207: stops the subsystem;
                    208: .Fa config
                    209: points to a copy of the current configuration object.
                    210: .Pp
                    211: .Fn willrun
                    212: should return non-zero if the subsystem needs to run at all.
                    213: .Fa config
                    214: points to a copy of the current (i.e., new) configuration object.
                    215: .Pp
                    216: .Fn changed
                    217: determines if the subsystem needs to be restarted during a configuration
                    218: change from
                    219: .Fa config1
                    220: to
                    221: .Fa config2 .
                    222: It should return 1 if so, zero otherwise.
                    223: .Pp
                    224: In the above methods, the configuration object argument(s)
                    225: become invalid after the method returns.
                    226: .Pp
                    227: Alternately, or in conjunction with the
                    228: .Fn changed
                    229: method, the
                    230: .Fa deplist
                    231: may point to a
                    232: .Dv NULL
                    233: terminated list of
                    234: .Xr structs 3
                    235: names of fields in the configuration object on which this subsystem depends.
                    236: The subsystem will automatically be restarted if any of the named fields
                    237: differ between
                    238: .Fa config1
                    239: and
                    240: .Fa config2 ,
                    241: as determined by
                    242: .Xr structs_equal 3 .
                    243: .Pp
                    244: All four of the above subsystem methods are optional and may be specified as
                    245: .Dv NULL .
                    246: In the case of
                    247: .Fn startup
                    248: and
                    249: .Fn shutdown ,
                    250: .Dv NULL
                    251: means "do nothing".
                    252: .Fn willrun
                    253: being
                    254: .Dv NULL
                    255: is equivalent to it always returning 1.
                    256: .Fn changed
                    257: being
                    258: .Dv NULL
                    259: is equivalent to it always returning 0.
                    260: .Fa deplist
                    261: being
                    262: .Dv NULL
                    263: is equivalent to an empty list.
                    264: .\"
                    265: .Ss Application
                    266: .\"
                    267: An application itself is described by a
                    268: .Li "struct app_config" :
                    269: .Pp
                    270: .Bd -literal -compact -offset 3n
                    271: struct app_config {
                    272:     u_int                       version;    /* current version # */
                    273:     const struct structs_type   **types;    /* all version types */
                    274:     const struct app_subsystem  **slist;    /* list of subsystems */
                    275:     app_config_init_t           *init;      /* initialize defaults */
                    276:     app_config_getnew_t         *getnew;    /* generate new config */
                    277:     app_config_checker_t        *checker;   /* validate a config */
                    278:     app_config_normalize_t      *normalize; /* normalize a config */
                    279:     app_config_upgrade_t        *upgrade;   /* upgrade a config */
                    280: };
                    281: .Ed
                    282: .Pp
                    283: The list of subsystems supported by the application is pointed to by
                    284: .Fa slist .
                    285: This list must be terminated with an entry whose
                    286: .Fa name
                    287: is
                    288: .Dv NULL .
                    289: .Pp
                    290: Subsystems are always started in the order they are listed in
                    291: .Fa slist ,
                    292: and they are always shutdown in the reverse order.
                    293: .Pp
                    294: The
                    295: .Fa version
                    296: is the configuration object version number (the first version is zero), and
                    297: .Fa types
                    298: points to an array of
                    299: .Fa "version"
                    300: + 1 pointers to
                    301: .Xr structs 3
                    302: types for the configuration object, where
                    303: .Li "types[i]"
                    304: is the
                    305: .Xr structs 3
                    306: type for version
                    307: .Fa i
                    308: of the configuration object.
                    309: .Pp
                    310: The remaining fields are pointers to functions having these types:
                    311: .Pp
                    312: .Bd -literal -compact -offset 3n
                    313: typedef int  app_config_init_t(struct app_config_ctx *ctx,
                    314:                  void *config);
                    315: typedef int  app_config_getnew_t(struct app_config_ctx *ctx,
                    316:                  void *config);
                    317: typedef int  app_config_checker_t(struct app_config_ctx *ctx,
                    318:                  const void *config, char *errbuf, size_t ebufsize);
                    319: typedef void app_config_normalize_t(struct app_config_ctx *ctx,
                    320:                  void *config);
                    321: typedef int  app_config_upgrade_t(struct app_config_ctx *ctx,
                    322:                  const void *old_conf, u_int old_version,
                    323:                 void *new_conf);
                    324: .Ed
                    325: .Pp
                    326: If the default configuration object is not equal to what is provided by
                    327: .Xr structs_init 3 ,
                    328: then
                    329: .Fn init
                    330: may be implemented.
                    331: It should further modify the
                    332: .Fa config
                    333: as appropriate to get the generic default configuration.
                    334: .Fn init
                    335: returns zero on success, or -1 on error with
                    336: .Va errno
                    337: set appropriately.
                    338: .Pp
                    339: .Fn getnew
                    340: is invoked when no existing configuration is found by
                    341: .Fn app_config_load
                    342: (see below).
                    343: The
                    344: .Fa config
                    345: is as returned by
                    346: .Fn init .
                    347: .Fn getnew
                    348: should apply any further initialization required for this particular system.
                    349: .Fn getnew
                    350: returns zero on success, or -1 on error with
                    351: .Va errno
                    352: set appropriately.
                    353: .Pp
                    354: The distinction between
                    355: .Fn init
                    356: and
                    357: .Fn getnew
                    358: is somewhat subtle:
                    359: .Fn init
                    360: simply initializes a new configuration object.
                    361: It may be invoked many times during the normal operation of the application
                    362: as configuration objects are needed.
                    363: .Fn getnew
                    364: is only invoked once, at the beginning of application startup, when there
                    365: is no previously saved configuration found.
                    366: Therefore, the behavior of
                    367: .Fn init
                    368: should not be affected by the "environment", while the behavior of
                    369: .Fn getnew
                    370: often is.
                    371: .Pp
                    372: .Fn checker
                    373: determines whether the
                    374: .Fa config
                    375: is valid, returning 1 if so or 0 if not.
                    376: In the latter case, it may print an error message (including '\\0')
                    377: into the buffer
                    378: .Fa errbuf ,
                    379: which has size
                    380: .Fa ebufsize
                    381: (see
                    382: .Xr snprintf 3) .
                    383: .Pp
                    384: .Fn normalize
                    385: gives the application a chance to normalize an otherwise valid
                    386: configuration object.
                    387: This is useful when the configuration object contains redundant information,
                    388: or information that can be represented in more than one way.
                    389: .Pp
                    390: All configurations that are applied by
                    391: .Nm app_config
                    392: are guaranteed to have been checked and normalized.
                    393: All configurations passed to
                    394: .Fn checker
                    395: are guaranteed to have been passed through
                    396: .Fn normalize
                    397: first.
                    398: .Pp
                    399: Note: the configurations returned by
                    400: .Fn init
                    401: and
                    402: .Fn getnew
                    403: must be valid according to
                    404: .Fa checker .
                    405: .Pp
                    406: .Fn upgrade
                    407: is invoked when an older version of the configuration object is read
                    408: in from an XML file.
                    409: The configuration version number is stored as the "version" attribute
                    410: of the XML document element.
                    411: .Fa old_conf
                    412: is the old object, which has version
                    413: .Fa old_version ,
                    414: and
                    415: .Fa new_conf
                    416: is a newly initialized configuration object of the current version.
                    417: .Fn upgrade
                    418: should copy the configuration information from
                    419: .Fa old_conf
                    420: to
                    421: .Fa new_conf .
                    422: .Pp
                    423: A quick and dirty way to do this when most of the fields are the same
                    424: is to use
                    425: .Xr structs_traverse 3
                    426: to list the fields in the old configuration object,
                    427: .Xr structs_get_string 3
                    428: to get their ASCII values, and
                    429: .Xr structs_set_string 3
                    430: to set the same values in the new configuration object.
                    431: .\"
                    432: .Ss API
                    433: .\"
                    434: .Fn app_config_init
                    435: should be called at application startup time to initialize
                    436: .Nm app_config
                    437: for the application described by
                    438: .Fa info .
                    439: A
                    440: .Xr pevent 3
                    441: context
                    442: .Fa ctx
                    443: must be supplied.
                    444: .Fn app_config_init
                    445: returns an application context, with which all configuration and
                    446: subsystems are associated.
                    447: Multiple independent application contexts may exist at the same time.
                    448: The
                    449: .Fa cookie
                    450: is saved along with the context but is otherwise ignored.
                    451: .Pp
                    452: .Fn app_config_uninit
                    453: should be called at application shutdown time to release resources
                    454: allocated by
                    455: .Nm app_config .
                    456: It may only be called when all subsystems are shutdown (i.e., the
                    457: current configuration object pointer is
                    458: .Dv NULL) .
                    459: This enables
                    460: .Fn app_config_init
                    461: to be called again, if so desired.
                    462: .Pp
                    463: Upon return from
                    464: .Fn app_config_uninit ,
                    465: .Fa "*ctxp"
                    466: will be set to
                    467: .Dv NULL .
                    468: If
                    469: .Fa "*ctxp"
                    470: is already equal to
                    471: .Dv NULL
                    472: when
                    473: .Fn app_config_uninit
                    474: is invoked, nothing happens.
                    475: .Pp
                    476: .Fn app_config_get_cookie
                    477: retrieves the application cookie provided to
                    478: .Fn app_config_init .
                    479: .Pp
                    480: .Fn app_config_load
                    481: reads in an application configuration object from the XML file at
                    482: .Fa path
                    483: and applies it, making it the current configuration.
                    484: If
                    485: .Fa path
                    486: is empty or non-existent, a new configuration object is created
                    487: using the application's
                    488: .Fn getnew
                    489: method.
                    490: .Pp
                    491: If the file contains an old version of the configuration object,
                    492: it is automatically upgraded to the current version.
                    493: If
                    494: .Fa allow_writeback
                    495: is non-zero, then
                    496: .Fa path
                    497: is remembered and the file is updated (i.e., rewritten) every time
                    498: the application configuration object changes.
                    499: Updates are done atomically by creating a temporary file with the
                    500: suffix ".new" and renaming it (see
                    501: .Xr rename 2) .
                    502: .Pp
                    503: In theory, one call to
                    504: .Fn app_config_load
                    505: in an application's
                    506: .Fn main
                    507: routine is all that is required to get things going.
                    508: .Pp
                    509: .Fn app_config_reload
                    510: reloads the configuration file previously specified to
                    511: .Fn app_config_load
                    512: and applies it.
                    513: This would be the typical response to receiving a
                    514: .Dv SIGHUP
                    515: signal.
                    516: .Pp
                    517: .Fn app_config_new
                    518: creates a new configuration object with the application's default values
                    519: as specified by the application's
                    520: .Fn init
                    521: method.
                    522: The returned pointer should be cast to the appropriate type.
                    523: The caller is responsible for eventually freeing the returned
                    524: configuration object by calling
                    525: .Fn app_config_free .
                    526: .Pp
                    527: .Fn app_config_set
                    528: changes the application's current configuration to be a copy of the
                    529: configuration pointed to by
                    530: .Fa config .
                    531: If this configuration is invalid, -1 is returned with
                    532: .Va errno
                    533: set to
                    534: .Er EINVAL ,
                    535: and if
                    536: .Fa ebuf
                    537: is not
                    538: .Dv NULL ,
                    539: the buffer pointed to by
                    540: .Fa ebuf
                    541: and having size
                    542: .Fa emax
                    543: is filled in with a '\\0'-terminated error message.
                    544: .Fn app_config_set
                    545: may also return -1 with
                    546: .Va errno
                    547: set to other values in the case of system errors.
                    548: .Pp
                    549: If
                    550: .Fa config
                    551: is
                    552: .Dv NULL ,
                    553: all running subsystems will be shut down.
                    554: Any configurations passed to
                    555: .Fn app_config_set
                    556: subsequent to passing a
                    557: .Dv NULL
                    558: configuration, but before the shutdown operation has completed, are ignored.
                    559: This guarantees that a
                    560: .Dv NULL
                    561: configuration does actually shutdown the application.
                    562: .Pp
                    563: The new configuration (or shutdown) takes effect after a delay of
                    564: .Fa delay
                    565: milliseconds after
                    566: .Fn app_config_set
                    567: has successfully returned zero.
                    568: The appropriate subsystem
                    569: .Fn stop ,
                    570: and then
                    571: .Fn start
                    572: methods are invoked serially from a new thread.
                    573: .Pp
                    574: .Fn app_config_get
                    575: returns a copy of the current or pending configuration object.
                    576: The returned pointer should be cast to the appropriate type.
                    577: If
                    578: .Fa pending
                    579: is zero, then the configuration object currently in use is copied.
                    580: Otherwise, the configuration object most recently applied via
                    581: .Fn app_config_set
                    582: is copied.
                    583: These will be different when there is a pending, but not yet applied,
                    584: configuration.
                    585: The caller is responsible for eventually freeing the returned
                    586: configuration object by calling
                    587: .Fn app_config_free .
                    588: .Pp
                    589: .Fn app_config_get_type
                    590: returns the
                    591: .Xr structs 3
                    592: for the application configuration object.
                    593: .Pp
                    594: .Fn app_config_copy
                    595: copies a configuration object.
                    596: The returned pointer should be cast to the appropriate type.
                    597: The caller is responsible for eventually freeing the returned
                    598: configuration object by calling
                    599: .Fn app_config_free .
                    600: .Pp
                    601: .Fn app_config_free
                    602: destroys the configuration object pointed to by
                    603: .Fa "*configp" .
                    604: Upon return,
                    605: .Fa "*configp"
                    606: will be set to
                    607: .Dv NULL .
                    608: If
                    609: .Fa "*configp"
                    610: is already
                    611: .Dv NULL
                    612: when
                    613: .Fn app_config_free
                    614: is invoked, nothing happens.
                    615: .\"
                    616: .Ss Pre-defined subsystems
                    617: .\"
                    618: The
                    619: .Nm app_config
                    620: library comes with some predefined subsystem templates.
                    621: .Pp
                    622: .Va app_config_alog_subsystem
                    623: handles configuring error logging for an application.
                    624: To use
                    625: .Va app_config_alog_subsystem ,
                    626: copy the structure and set the
                    627: .Fa arg
                    628: field to point to a
                    629: .Li "struct app_config_alog_info" :
                    630: .Pp
                    631: .Bd -literal -compact -offset 3n
                    632: struct app_config_alog_info {
                    633:     const char  *name;      /* field name */
                    634:     int         channel;    /* alog channel */
                    635: };
                    636: .Ed
                    637: .Pp
                    638: The
                    639: .Fa name
                    640: should be the
                    641: .Xr structs 3
                    642: field name of the field in the configuration object that configures
                    643: logging for the
                    644: .Xr alog 3
                    645: logging channel
                    646: .Fa channel .
                    647: This field should be a
                    648: .Li "struct alog_config" .
                    649: .Pp
                    650: .Va app_config_curconf_subsystem
                    651: is useful when the application needs efficient access to the currently
                    652: active configuration.
                    653: This subsystem assumes that there is a global pointer variable (call it
                    654: .Va curconf )
                    655: which by definition always points to a read-only copy of the currently
                    656: active configuration.
                    657: For example, if the application's configuration object is a
                    658: .Li "struct my_config" ,
                    659: then
                    660: .Va curconf
                    661: would be defined as:
                    662: .Pp
                    663: .Bd -literal -compact -offset 3n
                    664: const struct my_config *const curconf;
                    665: .Ed
                    666: .Pp
                    667: Then the function of
                    668: .Va app_config_curconf_subsystem
                    669: is to automatically keep this variable up to date.
                    670: (The
                    671: .Li "const"
                    672: keywords reflect the application's point of view:
                    673: the first is because the structure is read-only, while the second
                    674: is because the pointer itself is read-only.)
                    675: .Pp
                    676: To use
                    677: .Va app_config_curconf_subsystem ,
                    678: copy the structure and set the
                    679: .Fa arg
                    680: field to point to the application's
                    681: .Va curconf
                    682: pointer variable.
                    683: Typically the
                    684: .Va app_config_curconf_subsystem
                    685: will be first in the list of subsystems, so that
                    686: .Va curconf
                    687: is always updated before any other subsystem starts.
                    688: Then at any time
                    689: .Va "*curconf"
                    690: can be examined for the currently active configuration.
                    691: .Pp
                    692: .Va app_config_directory_subsystem
                    693: handles configuring the current working directory for the process.
                    694: To use
                    695: .Va app_config_directory_subsystem ,
                    696: copy the structure and set the
                    697: .Fa arg
                    698: field to point to a string containing the
                    699: .Xr structs 3
                    700: name of the field in the configuration object that contains the
                    701: directory name.
                    702: If this name is not the empty string, then the current working directory
                    703: will be set according to the value of this field.
                    704: .Pp
                    705: .Va app_config_pidfile_subsystem
                    706: handles "PID files", i.e., exclusive application lock files into which
                    707: the process ID is written.
                    708: These guard against two instances of the same application running at the
                    709: same time.
                    710: To use
                    711: .Va app_config_pidfile_subsystem ,
                    712: copy the structure and set the
                    713: .Fa arg
                    714: field to point to a string containing the
                    715: .Xr structs 3
                    716: name of the field in the configuration object that contains the PID file
                    717: pathname.
                    718: .Sh RETURN VALUES
                    719: All of the
                    720: .Nm app_config
                    721: functions return
                    722: .Dv NULL
                    723: or -1 to indicate an error and set
                    724: .Va errno
                    725: appropriately.
                    726: .Sh SEE ALSO
                    727: .Xr alog 3 ,
                    728: .Xr libpdel 3 ,
                    729: .Xr pevent 3 ,
                    730: .Xr structs 3 ,
                    731: .Xr typed_mem 3
                    732: .Sh HISTORY
                    733: The PDEL library was developed at Packet Design, LLC.
                    734: .Dv "http://www.packetdesign.com/"
                    735: .Sh AUTHORS
                    736: .An Archie Cobbs Aq archie@freebsd.org
                    737: .Sh BUGS
                    738: There should be explicit support for subsystems that require other
                    739: subsystems to be running before they may run.
                    740: As it stands now, such dependencies must be implicitly encoded into the
                    741: .Fn willrun
                    742: and
                    743: .Fn changed
                    744: methods.
                    745: Even so, the dependent subsystem cannot detect if the other subsystem
                    746: fails to start.
                    747: .Pp
                    748: Subsystems should be defined more like objects using dynamically
                    749: allocated structures that can be added and removed from the subsystem
                    750: list at any time, without having to shutdown and restart the whole
                    751: application.
                    752: .Pp
                    753: It should be possible to start and shutdown subsystems individually.

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>