#1037346 cyrus-imapd: all emails disappeared after upgrading from bullseye to bookworm (similar to #1007965)

Package:
cyrus-imapd
Source:
cyrus-imapd
Description:
Cyrus mail system - IMAP support
Submitter:
Kai Lindenberg
Date:
2024-07-18 08:09:03 UTC
Severity:
normal
#1037346#5
Date:
2023-06-11 19:48:57 UTC
From:
To:
Dear Maintainer,

today I upgraded our famliy+friends email server system from bullseye to
bookworm including the cyrus-imapd upgrade to v3.6.1-4.

Unfortunately, all mails of all users disappeared and new inboxes were
autocreated when users logged in:
-----------------------------

The emails were still in the non-uuid directory of the cyrus spool dir. I did
not figure out how this happened, but I solved it by

1. extracting a list of all sub-mailboxes of all users from the filesystem
structure,
2. re-creating the same sub-mailboxes with the cm command of cyradm,
3. and hard-linking all directory content to the new uuid dirs (with the help
of mbpath)

The issue is now solved for me, but I can provide additional system
information and logs if needed.

(same report goes to https://github.com/cyrusimap/cyrus-imapd/issues/4035)

#1037346#10
Date:
2023-06-13 11:43:34 UTC
From:
To:
Dear Kai,
Thank you very much for this report and a possible solution. Exactly the
same happened to me on upgrade to bookworm. Can you please elaborate how
you did this in detail? I really would be in trouble if I lose the emails.
I know this is a big ask but I would really appreciate your help.
Best regards
Michael

PS. I may have a delay answering, I am down under.

#1037346#15
Date:
2023-06-14 19:39:30 UTC
From:
To:
Dear Maintainer,

a new upstream bug was filed on github https://github.com/cyrusimap/cyrus-imapd/issues/4532.

Best
-Kai

#1037346#20
Date:
2023-06-14 20:34:24 UTC
From:
To:
Dear Michael,
(see below), I added the comments for this post. The script was created
iteratively while figuring out how the recovering might work. I worked on the
live system and relied on my backup. I did not spent any time to make the
script fail-safe or even readable, sorry. (Be sure to backup the spool
directory......)

===============================

#!/bin/bash
# the cyrus spool dir
SPOOLDIR=/var/spool/cyrus/mail/
# first argument is relative spool dir of user e.g.: $ scriptname k/user/kai
# extract user and reformat for cm command of cyadmin
# k/user/kai -> user.kai
USER=$(echo $1|cut -d/ -f 2,3|tr "/" ".")
# find all mailboxes of user and reformat for cm
MBXLIST=$(find $SPOOLDIR$1 -type d|cut -d/ -f 1-8 --complement|tr "/ " "._")
# generate a script for cyradm to create new mailboxes
for MBX in $MBXLIST; do
echo cm $USER.$MBX
done > creatembx.cyradm
echo starting shell to examine the situation
echo creatembx.cyradm created to feed cyradm \(please review\)
echo continue with exit
# start a shell to check cyradmin script and general situation
# you need to feed the cyradmin script to cyadmin with
# $ cat creatembx.cyradm | cyradm --user cyrus localhost
bash
# generate a script to hard-link to the new location
for MBX in $MBXLIST; do
# get path of created mailbox
NEWPATH=$(/usr/lib/cyrus/bin/mbpath $USER.$MBX)
# get original path of mailbox
OLDPATH=$SPOOLDIR$1/${MBX//\./\/}
# link it
echo ln -f ${OLDPATH//_/\\ }/\* $NEWPATH
done | tee linkmbx.bash
echo linkmbx.bash created, please review before executing
echo manual work:
echo 1. might be too many argument, review output
echo 2. main inbox not linked, create inbox_recovered

======================================

(be sure you understand each step of the script and be sure that it fits to
your configuration.)

You need to apply this script for all users on your systems (~20 users on my
system). Then you should see all sub-mailboxes filled with mails.

I treated the INBOX differently because the server was already receiving new
mail and out them into the INBOX. To avoid any interferences I created a
mailbox inbox_recovered for each user with cyradm:

$ cyradm --user cyrus localhost
xxx.xxx> cm user.kai.inbox_recovered
ctrl-d

and hard-linked the mails with

$ cd `mbpath user.kai.inbox_recovered`
$ ln -f /var/spool/cyrus/mail/k/user/kai/* .

(these are the commands from by bash history)

some final thoughts:
- I did all the operations as the user cyrus
- I used hard-linking to avoid copying 10s of Gigs of mails....
- it fails with unusual characters because of not escaping them
- new mailbox use underscore instead of blank (did not want to escape too)

Total time for my system: 6 hours with analysis, learnings, and recovering

Feel free to ask, if anything was too unclear, of if you want to know why I
did sth this way (sometime there might be a reason, sometimes I did not know
better)

Good luck
Kai

#1037346#25
Date:
2023-06-23 02:16:14 UTC
From:
To:
Kai,

Thanks so much for your work here, I've been panicking about my email.

This script is a HUGE help. I noticed one thing though, in the linking,
it doesn't really handle nested folders, so I get a ton of:

ln: /var/spool/cyrus/mail/p/user/phil/lists/linuxdriver: hard link not
allowed for directory

And one small thing, it might be useful for others if the 'echo's before
the first bash gave the command to run to feed the file to cyradm, so
you don't have to go back to the script to find it.

Thanks!

#1037346#30
Date:
2023-06-23 02:37:24 UTC
From:
To:
I've fixed up the script a bit and thrown it into a public repo, so
others can easily access it and hack on it as well:

https://github.com/jaymzh/recover-cyrus/blob/main/recover_cyrus_user.sh

Credit given at the top of the script.

#1037346#35
Date:
2023-07-01 22:24:51 UTC
From:
To:
Kai,

I noticed that no emails in nested folders were recovered. Is that expected?

#1037346#40
Date:
2023-07-02 01:32:15 UTC
From:
To:
Aha, I figured out the issue.

Your script does:

   ln -f ${OLDPATH//_/\\ }/\* $NEWPATH

But the substitution there is incorrect - the folders with `_` in them,
actually have that in their file path.

#1037346#45
Date:
2023-07-02 01:52:42 UTC
From:
To:
OK I've updated my copy of the script to properly handle both
underscores and spaces:

https://github.com/jaymzh/recover-cyrus/blob/main/recover_cyrus_user.sh

Hope that helps others!

#1037346#50
Date:
2023-07-18 18:24:13 UTC
From:
To:
Dear Maintainers

The documentation

https://www.cyrusimap.org/3.6/imap/download/upgrade.html#versions-to-upgrade-from

tells me that we should have upgraded from Cyrus 3.2.6 to 3.2.10 before going to
3.6.x. Bullseye stable didn't take us that way, and perhaps neither did Bullseye-backports.

Perhaps a check should be made, and stop Cyrus 3.2 from being upgraded?

Best wishes,

#1037346#55
Date:
2023-07-19 02:38:48 UTC
From:
To:
Hi,

the patch needed to update to 3.6 is included in version
3.2.6-2+deb11u2. So the doc should be updated to explain that "we should
have upgraded from Cyrus 3.2.6-2 to 3.2.6-2+deb11u2 before going to 3.6.x"

Regards,
Yadd

#1037346#60
Date:
2023-08-05 19:55:30 UTC
From:
To:
Hello Yadd,

Thanks for all your work on Cyrus-imapd in Debian!

Ellie writes: "From the amount of failures reported by people who have
let apt upgrade Cyrus for them, I guess there's a step missing in
whatever apt does". Is there something missing so far you know?
https://cyrus.topicbox.com/groups/info/Ta01e6935b46972c7-Mbb5e079f8d91464da502f947/upgrade-cyrus-on-debian-11-to-12

Is it a good idea to upgrade first to the backported version in Debian
11, and then later to Debian 12?  (In this way, I can concentrate on
Cyrus first.)

I have many mailboxes on my server, some of them are over 20 years old,
and some of them contain much data.

With regards,
Paul van der Vlis

#1037346#65
Date:
2023-08-06 15:46:00 UTC
From:
To:
Unfortunately my #calendars and #adresses mailboxes have also been hit.
They now have Inboxes and all entries are gone. Any experience on how
to recover these?

Thanks,
jOACHIM

#1037346#70
Date:
2023-08-07 17:09:40 UTC
From:
To:
The recovery script worked quite nicely. Thanks, I could not have done
it without. However my addressbook is not working yet. It has been
recovered, the links have been created:

mail:~# /usr/lib/cyrus/bin/mbpath 'user.jzobel.#addressbooks.Default'
/var/spool/cyrus/mail/uuid/n/c/ncp127mdldzs1jn8augq24jo
mail:~# ls -lrt /var/spool/cyrus/mail/uuid/n/c/ncp127mdldzs1jn8augq24jo
| head
total 1220
-rw------- 2 cyrus mail    518 Aug  9  2015 2.
-rw------- 2 cyrus mail    536 Aug 16  2015 293.
-rw------- 2 cyrus mail    609 Aug 16  2015 295.
...

But nothing is delivered to my client (evolution).

Sincerely,
Joachim

#1037346#75
Date:
2023-08-08 10:24:55 UTC
From:
To:
The recovery of the DAV mailboxes needs an additional call to
/usr/lib/cyrus/bin/dav_reconstruct. After that, my addressbooks and
calendars started working again. Client caching may however be a
problem, I used cadaver for testing.

Sincerely,
Joachim

#1037346#80
Date:
2023-08-25 12:13:21 UTC
From:
To:
Hi,

we had the same problem. After upgrade was created only mailboxes, which
had uniqueid in database. We can check it in dump:
/usr/lib/cyrus/bin/cvt_cyrusdb /var/lib/cyrus/mailboxes.db twoskip
/tmp/aaa.txt flat;
folder without uniqueid doesn't have "I" in dump /tmp/aaa.txt.

It can be repaired _before_ upgrade with:
/usr/lib/cyrus/bin/reconstruct -I
...
pokus.cz!test: update uniqueid from header (null) => 7f54216e52e02e7c
...

I hope, that this repaired mailboxes.db can be upgraded without problem
and will check it in few days.

I copy mailboxes.db without "reconstruct -I" to test bookworm system and
run "/usr/lib/cyrus/bin/ctl_cyrusdb -r". After that:
/usr/lib/cyrus/bin/ctl_mboxlist -d | wc -l
458
I run  "reconstruct -I" on test source system and copy to test bookworm
system, and run "/usr/lib/cyrus/bin/ctl_cyrusdb -r". After that:
/usr/lib/cyrus/bin/ctl_mboxlist -d | wc -l
2280



And there is typo in postinst in cyrus-common package (you must test
zero size and compare version in variable $2, not $1):
===
case "$1" in
     configure)
         # Refuse to update if previous version is lower than
3.2.6-2+deb11u2~
         if [ -z "$1" ] || $(dpkg --compare-versions $1 lt
'3.2.6-2+deb11u2~'); then
             echo "You must update cyrus-imapd to at least version
3.2.6-2+deb11u2~" >&2
             echo "before updating it to version 3.6.x and run it, else
your mailboxes" >&2
             echo "may be corrupted" >&2
             exit 1
         fi
===

Regards,
Petr Jurasek


On Sat, 5 Aug 2023 21:55:30 +0200 Paul van der Vlis <paul@vandervlis.nl>
wrote:
 > Hello Yadd,
 >
 > Thanks for all your work on Cyrus-imapd in Debian!
 >
 > On Wed, 19 Jul 2023 06:38:48 +0400 Yadd <yadd@debian.org> wrote:
 > > the patch needed to update to 3.6 is included in version
 > > 3.2.6-2+deb11u2. So the doc should be updated to explain that "we
should
 > > have upgraded from Cyrus 3.2.6-2 to 3.2.6-2+deb11u2 before going to
3.6.x"
 >
 > I have heard about problems, even when upgrading from 3.2.6-2+deb11u2.
 >
 > Ellie writes: "From the amount of failures reported by people who have
 > let apt upgrade Cyrus for them, I guess there's a step missing in
 > whatever apt does". Is there something missing so far you know?
 >
https://cyrus.topicbox.com/groups/info/Ta01e6935b46972c7-Mbb5e079f8d91464da502f947/upgrade-cyrus-on-debian-11-to-12
 >
 > Is it a good idea to upgrade first to the backported version in Debian
 > 11, and then later to Debian 12? (In this way, I can concentrate on
 > Cyrus first.)
 >
 > I have many mailboxes on my server, some of them are over 20 years old,
 > and some of them contain much data.
 >
 > With regards,
 > Paul van der Vlis
 >
 > --
 > Paul van der Vlis Linux systeembeheer Groningen
 > https://vandervlis.nl/
 >
 >

#1037346#85
Date:
2023-08-26 03:13:54 UTC
From:
To:
Hi,

thanks for the fix. Did you get this issue when upgrading from
3.2.6-2+deb11u2 or upgrading from 3.2.6-2 ?

#1037346#90
Date:
2023-08-28 07:18:46 UTC
From:
To:
Hi,

Dne 26. 08. 23 v 5:13 Yadd napsal(a):

it was upgrade from buster, 3.0.8-6+deb10u6. Now I know, that it's not
unsupported, but with this typo it was possible. But I tested this
upgrade on few instances without problem. This was first situation and I
think, that this mailbox database inconsistency was the reason.

Regards,
Petr Jurasek

#1037346#95
Date:
2023-08-30 15:55:50 UTC
From:
To:
Hi,

Confirming this issue also arises when coming from 3.2.6-2+deb11u2.
After conducting an update from a fully updated Bullseye to Bookworm, no
more mails were in any user's account, and new mailboxes were created
for users when logging in.

All accounts are many years old. As I had awareness of potential upgrade
issues, I even tried to run reconstruct -G -V max before conducting the
upgrade, which though did not help to prevent the desaster.

Suggestion:
Bullseye (oldstable) should be updated to a Cyrus version 3.2.10+, as
this is the only confirmed way as per Cyrus' upgrade documentation to
avoid these issues when moving to v3.6.1 as contained in Bookworm.
https://www.cyrusimap.org/3.6/imap/download/upgrade.html#versions-to-upgrade-from

I currently have no awareness of what else an admin could do to prevent
this from happening when updating directly from 3.2.6-2+deb11u2
(Standard Bullseye). The most promising hints I've read in other threads
is to run the reconstruct with additional parameters (reconstruct -f -G
-I -V max), whereas I would suggest anyone not to test this without a 
very solid backup.

For others for whom it's too late and who are here for solutions, here
is what I did to recover after the desaster:

1) su'ed to user cyrus
2) Downloaded rescue script by @larsimmisch from here and saved to local
folder:
https://gist.github.com/larsimmisch/f0c02977ffc9a9c72781716eaa3d7334
3) In the same folder:
git clone https://github.com/larsimmisch/python_cyrus python_cyrus
4) python3 ./cyrreconstruct.py -a <cyrus admin user> <mailbox username>

Step 4 will only work if the mailbox has already been created again
(what happens automatically - as an empty one - when a user logs in). If
the mailbox isn't present yet, use cyradm and
cm user.<username>
to create it before running the cyrreconstruct.py script.

Special thanks to @larsimmisch for saving my life, and to the package
maintainers for acting swiftly for preventing others from this nightmare.

Best,
Bastian

#1037346#100
Date:
2023-09-08 08:35:54 UTC
From:
To:
Hi,

after a few tests I can reproduce error on test environment.

mailboxes.db are broken only if I make connections to cyrus during
upgrade. I think, that some postinst restarts cyrus without all needed
packages upgraded or some other coincidence.

But repair is simple - copy mailboxes.db from backup and restart cyrus
:-). This will run "ctl_cyrusdb -r" and repair mailboxes.db.

Folders, that was badly created during upgrade, will be still empty and
you must run recover on them. All mails will be flagged as unseen. If
you use "delete_mode: delayed", users will have "delayed deleted" mails
in folders.

If you can repair mailboxes.db on different server (without physical
mailboxes in /var/lib/cyrus),  cyrus will include only folders, that
have uid included in mailboxes.db. Folders without uid you can see:
/usr/lib/cyrus/bin/cvt_cyrusdb /var/lib/cyrus/mailboxes.db twoskip
/tmp/aaa.txt flat; cat /tmp/aaa.txt | egrep -a -v '( I |\%\(I)'
But you can add uid before upgrade with:
/usr/lib/cyrus/bin/reconstruct -I
and this mailboxes.db will include all folders if you run it on test
machine without physical mailboxes in /var/lib/cyrus.

Prevention is block imap/pop3 in firewall during upgrade.

Regards,
Petr Jurasek

Dne 26. 08. 23 v 5:13 Yadd napsal(a):

#1037346#105
Date:
2024-02-06 10:34:50 UTC
From:
To:
Some additional information:
 - You can roll-back to package 3.2 after the upgrade to 3.6, the
   mailboxes will re-appear again
 - You might encounter some junk mailboxes from the failed conversion
   attempt, the remedy is to convert mailboxes.db to text, remove the
   offending lines, and convert it back to its original format.
 - The proper may to migrate to 3.6 without hassle is:
   - Stop cyrus-imapd service
   - Download and compile 3.4, run ./imap/ctl_cyrusdb -r once (make a
     copy of /var/lib/cyrus/mailboxes.db beforehand, of course)
 - Then proceed with the update

It seems that the debian package, despite claiming that it has the
necessary patches to make the upgrade possible, doesn't.

#1037346#110
Date:
2024-02-08 22:54:03 UTC
From:
To:
Op 06-02-2024 om 11:34 schreef Jens Georg:
I still have to do the upgrade on a few machines..

Did you do this on Debian 11 or Debian 12?

What did you download exactly?  Maybe this?
https://github.com/cyrusimap/cyrus-imapd/tree/cyrus-imapd-3.4.6

After downloading and go to the right directory something like:
systemctl stop cyrus-imap
./configure
make
sudo make install

Did you use any Debian patches?

sudo cp -a /var/lib/cyrus/mailboxes.db /path/to/backup/

./imap/ctl_cyrusdb -r

How did you remove this version?

Then install the new Debian packages?

Bye,
Paul

#1037346#115
Date:
2024-02-12 20:25:25 UTC
From:
To:
Hi,

I had the same problem (mails were not displayed in the mail client any
more after upgrading from Bullseye to Bookworm).

What worked in the end for me was this:

- restored /var/lib/cyrus/ and /var/spool/cyrus/ from backup, to the old
state from before the Debian upgrade.
- built Cyrus 3.4.6, and installed and started it temporarily. The mails
were now visible in the mail client again.
- upgraded to the normal Cyrus version from Bookworm. The mails were
still visible in the mail client.

And since I had already kept the server running for some hours with the
broken mail archive, I then also restored the getmail6 status files
(/var/lib/getmail) to the state from before the Debian upgrade. This
caused getmail to re-fetch the mails that were missing.

I don't know how to detect whether the mail archive was really migrated
successfully; but since Cyrus 3.6.1 is now running and Thunderbird can
connect and sees all mails, I suppose the migration was successful?


Regarding the build of Cyrus 3.4.6, in the end I built it using the
existing Debian packaging data, and using the "debocker" tool to build
inside a clean Docker container.

Unfortunately debocker will always run the "lintian" tool to check the
package, which failed for me with error "E: cyrus-common:
depends-on-obsolete-package Depends: lsb-base". I didn't know how to fix
this error or how to correctly disable the lintian step; so I edited the
debocker files to disable this check. Very ugly, but it worked.

So from my notes, these must have been the steps that I did for building
the Cyrus 3.4.6 Debian package:
- installed "debocker" and "devscripts" packages: `sudo apt install
debocker devscripts`
- downloaded the Debian cyrus-imapd packaging info: `debcheckout
cyrus-imapd`
- downloaded the original source package: `wget
https://github.com/cyrusimap/cyrus-imapd/releases/download/cyrus-imapd-3.4.6/cyrus-imapd-3.4.6.tar.gz`
- renamed the source package so it would be found in the next steps: `mv
cyrus-imapd-3.4.6.tar.gz cyrus-imapd_3.4.6.orig.tar.gz`
- `cd cyrus-imapd/`
- started new Git branch at the state of Cyrus 3.4.3-4: `git checkout -b
cyrus-3.4.6 debian/3.4.3-4`
- added changelog entry: `dch -v '3.4.6-1.1' "use new upstream version
3.4.6"`
	- the warning about missing DEBEMAIL can be ignored
- committed change: `git commit debian/changelog -m 'update changelog'`

- modified the "debocker" template files to disable the lintian step:
`sudo nano /usr/share/debocker/bundle-files/steps/05-build` and then
commented out the line for "lintian --pedantic --display-info *.changes"

- created build bundle: `debocker bundle --image debian:bookworm -f "-b
-us -uc"`
- did the actual build: `sudo debocker build-bundle
../cyrus-imapd_3.4.6-1.1_bundle.tar`
	- whether the "sudo" is necessary depends on your local Docker setup
	- the build took a while (half an hour or more?); and then there was a
message like "LOG Build successful", and there were lots of Cyrus
packages in the current directory.

I then copied cyrus-clients_3.4.6-1.1_amd64.deb,
cyrus-common_3.4.6-1.1_amd64.deb and cyrus-imapd_3.4.6-1.1_amd64.deb to
the server and installed them.

Remember to undo the change to the debocker file
(/usr/share/debocker/bundle-files/steps/05-build) after the build.

Kind regards,
Oliver

#1037346#120
Date:
2024-07-18 07:46:30 UTC
From:
To:
Hello,

I also got hit by this bug - old mailboxes were still in the place, but
new empty mailboxes started to appear in uuid folders. And mailboxes.db
got corrupted/erased.

The easy way is to add to /etc/imapd.conf

mailbox_legacy_dirs: yes

BEFORE starting the upgrade. See:
https://www.cyrusimap.org/3.6/imap/download/upgrade.html#storage-changes

So the easy way would be to add this information to NEWS.Debian.gz

More complicated (but more secure) way, would be to add this option
automatically if upgrading from version < 3.6.0