1 #ifndef HAVE_MASTER_H
2 #define HAVE_MASTER_H
3 
4 #include <config.h>
5 #include <sys/resource.h> /* for rlim_t */
6 
7 #include "libconfig.h" /* for config_dir and IMAPOPT_SYNC_MACHINEID */
8 #include "strarray.h"
9 
10 struct service {
11     char *name;                 /* name of service */
12     char *listen;               /* port/socket to listen to */
13     char *proto;                /* protocol to accept */
14     strarray_t *exec;           /* command (with args) to execute */
15     int babysit;                /* babysit this service? */
16 
17     /* multiple address family support */
18     int associate;              /* are we primary or additional instance? */
19     int family;                 /* address family */
20     const char *familyname;     /* address family name */
21 
22     /* communication info */
23     int socket;                 /* client/child communication channel */
24     int stat[2];                /* master/child communication channel */
25 
26     /* limits */
27     int desired_workers;        /* num child processes to have ready */
28     int max_workers;            /* max num child processes to spawn */
29     rlim_t maxfds;              /* max num file descriptors to use */
30     unsigned int maxforkrate;   /* max rate to spawn children */
31 
32     /* stats */
33     int ready_workers;          /* num child processes ready for service */
34     int nforks;                 /* num child processes spawned */
35     int nactive;                /* num children servicing clients */
36     int nconnections;           /* num connections made to children */
37     double forkrate;            /* rate at which we're spawning children */
38     int nreadyfails;            /* number of failures in READY state */
39     time_t lastreadyfail;       /* timestamp of last failure in READY state */
40 
41     /* fork rate computation */
42     struct timeval last_interval_start;
43     unsigned int interval_forks;
44 };
45 
46 extern struct service *Services;
47 extern int nservices;
48 
49 /*
50  * Description of multiple address family support from
51  * Hajimu UMEMOTO <ume@mahoroba.org>:
52  *
53  * In service_create(), master tries to listen each address family which
54  * getaddrinfo() returns.  With existing implementation of getaddrinfo(),
55  * when a protocol is not specified exactly by proto= in cyrus.conf and a
56  * platform supports an IPv4 and an IPv6, getaddrinfo() returns two
57  * struct addrinfo chain which contain INADDR_ANY (0.0.0.0; IPv4) and
58  * IN6ADDR_ANY (::; IPv6), then master will listen an IPv4 and an IPv6.
59  *
60  * As a result, one SERVICE entry in cyrus.conf may correspond to two
61  * Service memory blocks; one is for an IPv6 and the other is for an
62  * IPv4.  The associate field was introduced to intend to distinguish
63  * whether the entry is primary or not.  The associate field of primary
64  * block is 0, 2nd is 1, 3rd is 2, ...
65  * The blocks share same memory area of name, listen and proto.
66  *
67  *    +----------------+
68  *    | Service[i]     |
69  *    |   associate: 0 |
70  *    |   name         | --------------> name
71  *    |   listen       | ----- /- -----> listen
72  *    |   proto        | ---- /- / ----> proto
73  *    +----------------+     /  / /
74  *    | Service[j]     |    /  / /
75  *    |   associate: 1 |   /  / /
76  *    |   name         |--/  / /
77  *    |   listen       |----/ /
78  *    |   proto        |-----/
79  *    +----------------+
80  *
81  * This field is intended to avoid duplicate free by doing free only when
82  * associate is zero.
83  *
84  */
85 
86 #endif /* HAVE_MASTER_H */
87