Since you're soliciting patches... here's one I sent in a while ago. 
Didn't see it appear in CVS, so I thought I'd repost it.

I've been running it locally with great success.  Works fine, and it's
fairly trivial.


On 03/25/2010 05:28 AM, Bron Gondwana wrote:
> Gosh, it's getting awfully close to my self imposed deadline of April
> isn't it - though I think I'll be pulling an Ubuntu and saying "I
> meant the end of April, honest".  Sysadmin stuff got in the way for
> rather longer than I intended.
>
> Due to making changes all over the place, I currently have a giant change
> entry on the future branch with all the changes on it.  I'll try to factor
> them out into individual line items later, keeping it reviewable.  I'm not
> going to try to make every intermediate stage work - let alone even
> compile - because it's too much makework for no benefit.
>
> That said, here's where things are! (long, but hopefully interesting to
> at least some other people... if nothing else a handy memory jogger for
> me if I get side-tracked at all)
>
> Rewritten (greatly simplified) API for getting file names:
> ==========================================================
>
> char *fname = mailbox_meta_fname(&mailbox, META_INDEX);
> char *newfname = mailbox_meta_newfname(&mailbox, META_INDEX);
>
> (uses a separate static buffer so you can just do this and then
> your rename logic!)
>
> char *fname = mailbox_message_fname(&mailbox, uid);
>
> So that simplifies HEAPS of code and hides all the "is it meta"
> behind one interface.
>
> Mboxlist functions return a struct
> ==================================
>
> struct mboxlist_entry mbentry;
> r = mboxlist_lookup(name, &mbentry, &tid);
>
> mbentry.mbtype, mbentry.partition, mbentry.acl
>
> Simplifies parameter passing to functions considerably
>
> Locking
> =======
>
> Here's the big one!  I'll write a separate section on this in more
> detail, but here are the basic contracts:
>
> New file: cyrus.lock - empty file.
>
> exclusive lock on cyrus.lock:
>   * free reign with all files.  Delete what you like, rewrite
>     what you like
>   * no other locks required
>
> shared lock on cyrus.lock: 
>   * MUST NOT replace cyrus.index or cyrus.cache files (change inode)
>   * MUST NOT change any files at all without cyrus.index lock
>   * MAY rewrite cyrus.squat.
>
> exclusive lock on cyrus.index:
>   * MUST have a shared lock on cyrus.lock
>   * MAY rewrite flags/modseq on any index record
>   * MAY append new index records
>   * MAY append to cyrus.cache
>   * MUST NOT rewrite older parts of cyrus.cache
>   * MAY rewrite cyrus.header (write .NEW, rename)
>   * MAY rewrite user.seen file
>
> shared lock on cyrus.index:
>   * optional - gives consistent reads.  Otherwise modseqs higher than
>     last read header may be found, seen may be out of sync.  I have a
>     simple concurrency test case that can see unintended data by being
>     clever.
>
> All this infrastructure is in place in the future branch now, though
> untested so far.  APIs are:
>
> mailbox_open_shared(name, auth_state, &mailbox);
> mailbox_open_exclusive(name, auth_state, &mailbox);
>
> mailbox_lock_index(&mailbox);
> mailbox_unlock_index(&mailbox);
>
> mailbox_close(&mailbox);
>
> CRCs and automatic bookkeeping
> ==============================
>
> (remember the discussion on recno replacing msgno because expunged records
>  remain in cyrus.index rather than cyrus.expunge, so need to be skipped?
>  It's necessary for the above, because cyr_expire will get an exclusive lock
>  on the mailbox for the duration of its index rewrite!)
>
> Move "deleted / flagged / answered" meta count management into mailbox.c:
>
> mailbox_rewrite_index_record(&mailbox, recno, &record);
>  * reads the OLD record again, updates counts, updates CRC32 values including
>    XOR_CRC which is the XOR of all record CRCs.
>  * updates "exists" if it's an expunge.
>  * updates modseq value.  Calls:
>
> mailbox_index_dirty(&mailbox)
>  * anything doing a write to ANYTHING does this.  It sets a flag,
>    increments the highestmodseq and grabs a timestamp.  All changes
>    use these values.
>
> mailbox_header_write(&mailbox);
>  * rewrites the header file.  Also updates the mailbox->header_file_crc
>    value which will be saved when we call:
>
> mailbox_write_index_header(&mailbox);
>  * MUST be called after making any change to ensure all checksums and
>    XOR_CRC are correctlly stored - along with the bumped highestmodseq
>    and correct record counts.
>
> Oh, we missed:
>
> mailbox_append_index_records(&mailbox, &records, num);
>
> Stores "num" records to the index file.  It's a pointer to an array of
> "struct index_record" structs.
>
> I'm still reworking everything to use these rather than doing the
> bookkeeping by hand!
>
> index.c - use a mailbox object
> ==============================
>
> All the globals go away!  There's just a global mailbox struct, which
> will have a lock_fd in shared mode, meaning that all the offsets into
> the cyrus.index and cyrus.cache mmaps are ALWAYS VALID.
>
> Along with compulsary CONDSTORE - vast swathes of code complexity are
> being removed :)  You don't need to track times when you have modseq
> to determine if flags should be sent again.  You don't have to keep
> statting files, just re-read the header and then scan for updates.
>
> It WILL be necessary to keep a global array mapping from msgno to recno
> so non-UID commands can be efficient.  This can be rewritten whenever
> highestmodseq is detected to have changed :)
>
> I'm just starting on this - hence there are lots of global references to
> remove.
>
> Also - no more UID(msgno) and CACHE_OFFSET(msgno) and all that jazz.  We
> read a record with mailbox_read_index_record() and then use it.  In native
> form, in an easily accessible struct.  Joy.  No more 
> htonl((bit32 *)base_offset+SOME_CONSTANT) nonsense everywhere!  Contain it,
> wrap it, ensure accesses to it go via consistency checking, checksum
> updating and header counter maintaining paths!
>
>
> So - that's the status of the future branch!  It also has most of the
> interesting patches from the fastmail branch cherry-picked forwards to 
> sit on top of CVS trunk.  
>
> Feel free to poke around, make suggestions, send patches, etc.  Some of
> the less popular (i.e. I don't use them) utilities could probably do with
> some TLC or maybe merging into uber-tools if they don't do much.  While I
> haven't drifted too far incompatible just yet, it's getting that way!
>
> Speaking of which: cyrus.expunge.  It's pretty much all stripped now.  I'll
> be writing something simple in to mailbox_upgrade_index which detects its
> presence and does a sorted merge of the two files into the new cyrus.index,
> complete with system_flags & FLAG_EXPUNGED.  There's also FLAG_UNLINKED
> which will allow us to have immediate expunge of the actual on-disk-file
> (with the associated inabilithy to unexpunge of course!) if sites want that.
>
>
> Thanks for reading!
>
> Bron.
>   

--- cyrus-imapd-2.3.15/lib/imapoptions.orig     2009-06-29 11:21:06.000000000 
-0600
+++ cyrus-imapd-2.3.15/lib/imapoptions  2009-12-14 14:40:56.000000000 -0700
@@ -854,6 +854,10 @@ are listed with ``<none>''.
    strip the default realm from the userid (this does not affect the stripping
    of realms specified by the afspts_localrealms option) */
 
+{ "qosmarking", "cs0", ENUM("cs0", "cs1", "cs2", "cs3", "cs4", "cs5", "cs6", 
"cs7", "af11", "af12", "af13", "af21", "af22", "af23", "af31", "af32", "af33", 
"af41", "af42", "af43", "ef") }
+/* This specifies the Class Selector or Differentiated Services Code Point
+   designation on IP headers (in the ToS field). */
+
 { "quota_db", "quotalegacy", STRINGLIST("flat", "berkeley", "berkeley-hash", 
"skiplist", "sql", "quotalegacy")}
 /* The cyrusdb backend to use for quotas. */
 
--- cyrus-imapd-2.3.15/lib/libconfig.c.orig     2009-08-20 09:26:15.000000000 
-0600
+++ cyrus-imapd-2.3.15/lib/libconfig.c  2009-12-14 00:37:20.000000000 -0700
@@ -82,6 +82,7 @@ enum enum_value config_virtdomains;       
 enum enum_value config_mupdate_config; /* IMAP_ENUM_MUPDATE_CONFIG_STANDARD */
 int config_maxword;
 int config_maxquoted;
+int config_qosmarking;
 
 /* declared in each binary that uses libconfig */
 extern const int config_need_data;
@@ -210,11 +211,21 @@ static void config_ispartition(const cha
     if (!strncmp("partition-", key, 10)) *found = 1;
 }
 
+static const unsigned char qos[] = {
+/* cs0..cs7 */         0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0,
+/* af11..af13 */       0x28, 0x30, 0x38,
+/* af21..af23 */       0x48, 0x50, 0x58,
+/* af31..af33 */       0x68, 0x70, 0x78,
+/* af41..af43 */       0x88, 0x90, 0x98,
+/* ef */               0xb8
+};
+
 void config_read(const char *alt_config)
 {
     enum imapopt opt = IMAPOPT_ZERO;
     char buf[4096];
     char *p;
+    int ival;
 
     /* xxx this is leaked, this may be able to be better in 2.2 (cyrus_done) */
     if(alt_config) config_filename = xstrdup(alt_config);
@@ -328,6 +339,9 @@ void config_read(const char *alt_config)
     /* set some limits */
     config_maxquoted = config_getint(IMAPOPT_MAXQUOTED);
     config_maxword = config_getint(IMAPOPT_MAXWORD);
+
+    ival = config_getenum(IMAPOPT_QOSMARKING);
+    config_qosmarking = qos[ival];
 }
 
 #define GROWSIZE 4096
--- cyrus-imapd-2.3.15/lib/libconfig.h.orig     2008-09-23 11:34:38.000000000 
-0600
+++ cyrus-imapd-2.3.15/lib/libconfig.h  2009-12-14 00:19:40.000000000 -0700
@@ -80,6 +80,7 @@ extern enum enum_value config_virtdomain
 extern enum enum_value config_mupdate_config;
 extern int config_maxquoted;
 extern int config_maxword;
+extern int config_qosmarking;
 
 /* config requirement flags */
 #define CONFIG_NEED_PARTITION_DATA (1<<0)
--- cyrus-imapd-2.3.15/master/master.c.orig     2009-03-30 22:11:23.000000000 
-0600
+++ cyrus-imapd-2.3.15/master/master.c  2009-12-14 15:18:24.000000000 -0700
@@ -439,6 +439,15 @@ void service_create(struct service *s)
        }
 #endif
 
+       /* set IP ToS if supported */
+#if defined(SOL_IP) && defined(IP_TOS)
+       r = setsockopt(s->socket, SOL_IP, IP_TOS,
+                      (void *) &config_qosmarking, sizeof(config_qosmarking));
+       if (r < 0) {
+           syslog(LOG_WARNING, "unable to setsocketopt(IP_TOS): %m");
+       }
+#endif
+
        oldumask = umask((mode_t) 0); /* for linux */
        r = bind(s->socket, res->ai_addr, res->ai_addrlen);
        umask(oldumask);

Reply via email to