freebsd 10.0 reboot loop with ffs dup alloc

Darren Reed darrenr at freebsd.org
Sat Jun 14 08:21:40 UTC 2014


I've just been through an interesting little scenario where my FreeBSD
box was in a reboot loop due to an error in the FFS log leading to it
replaying data that led to apanic: ffs_valloc: dup alloc

At this point, if I had not of been paying attention, FreeBSD would
have continued to reboot forever as the panic happened when it was
writing out a crash dump - well after fsck had marked the filesystem
clean.

The fix was to reboot into single user mode, not to replay the log,
and let fsck do what it normally does.

Unfortunately when the log is present, using "-y" means that the
log is replayed thus forcing "-y" to not being used and "y" being
manually entered for all of the answers :-/

Something like the patch below should be used where the answer
to the "USE JOURNAL" question is not subject to the "-y" setting.

I suppose another bug here is that the journal ended up with some
sort of corruption or bad data inside of it that led to it recreating
a situation on disk that would later cause a panic.

Cheers,
Darren

*** main.c.orig Sat Jun 14 18:15:52 2014
--- main.c      Sat Jun 14 18:16:50 2014
***************
*** 400,406 ****
         */
        if ((sblock.fs_flags & FS_SUJ) == FS_SUJ) {
                if ((sblock.fs_flags & FS_NEEDSFSCK) != FS_NEEDSFSCK &&
skipclean) {
!                       if (preen || reply("USE JOURNAL")) {
                                if (suj_check(filesys) == 0) {
                                        printf("\n***** FILE SYSTEM
MARKED CLEAN *****\n");
                                        if (chkdoreload(mntp) == 0)
--- 400,415 ----
         */
        if ((sblock.fs_flags & FS_SUJ) == FS_SUJ) {
                if ((sblock.fs_flags & FS_NEEDSFSCK) != FS_NEEDSFSCK &&
skipclean) {
!                       int yf = yflag;
!                       int rep;
!
!                       yflag = 0;
!                       if (!preen)
!                               rep = reply("USE JOURNAL");
!                       else
!                               rep = 0;
!                       yflag = yf;
!                       if (preen || rep) {
                                if (suj_check(filesys) == 0) {
                                        printf("\n***** FILE SYSTEM
MARKED CLEAN *****\n");
                                        if (chkdoreload(mntp) == 0)



More information about the freebsd-hackers mailing list