Hi,
as I did not find anything regarding this in the archive, maybe this is interesting for you. I am currently working for a project that aims to build a linux mailsystem that should scale up to 1.5M users. As this needs more IO than one single PC can provide, we cluster several boxes, adding one-by-one as performance suggests. User information wil be served via OpenLDAP, providing hints for the final destination of a mail within the cluster. SMTP relays will be postfixes transporting mails via LMTP to Cyrus-IMAP backends. IMAP proxies will be perditions handling IMAP connections through to the Cyrus-IMAP backends. Both services will ask the LDAP for the appro- priate backend servers to speak to. The projects goal was also secure some sort of availability. As the SMTP relays and the IMAP proxies will hold only temporary data, they won't need additional work, opposite to the Cyrus IMAP backends that contain the mail storage of all users. With respect to this, the Cyrus IMAP mail storages will be small back-to-back failover clusters running kimberlite software. That means that every two Cyrus IMAP servers will backup each other. You may have a look at http://oss.missioncriticallinux.com/projects/kimberlite/ for details. To achieve this, we will set up Cyrus IMAP software structures on each node like this: /<clusterid1>/etc/cyrus.conf /<clusterid1>/etc/imapd.conf /<clusterid1>/var/imap/... /<clusterid1>/var/spool/imap/... /<clusterid2>/etc/cyrus.conf /<clusterid2>/etc/imapd.conf /<clusterid2>/var/imap/... /<clusterid2>/var/spool/imap/... By this, we will be able to maintain two complete separate Cyrus IMAP services which will also bind to different IP addresses. These services will normally run on their respective nodes <clusterid1,2> but on failure the remaining node will "swap" in the service of the sister node. Unfortunately, Cyrus IMAP will support the concept above only when a) com- piling in the path of cyrus.conf and b) supplying /<clusterid1>/bin/cyrus/... /<clusterid2>/bin/cyrus/... as well. This is both not very upgrade friendly as wastes space. I therefore wrote a patch that enables us to start /usr/cyrus/bin/master the same way one can start /usr/cyrus/bin/imapd,lmtpd,...: with "-C" we will be able to provide the cyrus.conf on the command line. I supply the patch, maybe you regard this as a good idea in general and incorporate it in future versions of Cyrus IMAP. Regards, Birger
diff -u cyrus-imapd-2.0.16.orig/master/master.c cyrus-imapd-2.0.16/master/master.c --- cyrus-imapd-2.0.16.orig/master/master.c Mon Jul 16 20:23:11 2001 +++ cyrus-imapd-2.0.16/master/master.c Thu Oct 25 17:21:04 2001 @@ -101,6 +101,7 @@ static int verbose = 0; static int listen_queue_backlog = 32; +char config_filename[255] = "/etc/cyrus.conf"; struct service *Services = NULL; int allocservices = 0; @@ -1002,8 +1003,11 @@ p = getenv("CYRUS_VERBOSE"); if (p) verbose = atoi(p) + 1; - while ((opt = getopt(argc, argv, "l:D")) != EOF) { + while ((opt = getopt(argc, argv, "C:l:D")) != EOF) { switch (opt) { + case 'C': /* user defined cyrus.conf */ + strncpy(config_filename, optarg, sizeof(config_filename)); + break; case 'l': /* user defined listen queue backlog */ listen_queue_backlog = atoi(optarg); break; diff -u cyrus-imapd-2.0.16.orig/master/masterconf.c cyrus-imapd-2.0.16/master/masterconf.c --- cyrus-imapd-2.0.16.orig/master/masterconf.c Wed Mar 14 23:39:35 2001 +++ cyrus-imapd-2.0.16/master/masterconf.c Thu Oct 25 17:25:45 2001 @@ -59,7 +59,7 @@ extern int errno; -#define CONFIG_FILENAME "/etc/cyrus.conf" +extern char config_filename[255]; struct configlist { char *key; @@ -102,7 +102,7 @@ } if (*p != '"') { sprintf(k, "configuration file %s: missing \" on line %d", - CONFIG_FILENAME, e->lineno); + config_filename, e->lineno); fatal(k, EX_CONFIG); } } else { @@ -198,9 +198,9 @@ int lineno = 0; char buf[4096]; - infile = fopen(CONFIG_FILENAME, "r"); + infile = fopen(config_filename, "r"); if (!infile) { - sprintf(buf, "can't open configuration file %s: %s", CONFIG_FILENAME, + sprintf(buf, "can't open configuration file %s: %s", config_filename, strerror(errno)); fatal(buf, EX_CONFIG); }