Page MenuHomeFreeBSD

Move the ability to search for alternate UFS superblocks from fsck_ffs(8) into ffs_search() to allow use by other parts of the system.
ClosedPublic

Authored by mckusick on Sat, Aug 6, 1:04 AM.

Details

Summary

Historically only fsck_ffs(8), the UFS filesystem checker had code to track down and use alternate superblocks. Since fsdb(8) used much of the fsck_ffs(8) implementation it had some ability to track down alternate superblocks.

This change extracts the code to track down alternate superblocks from fsck_ffs(8) and puts it into a new function ffs_sbsearch() in sys/ufs/ffs/ffs_subr.c. Like ffs_sbget() and ffs_sbput() also found in ffs_subr.c, these functions can be used directly by the kernel subsystems. Additionally they are exported to the UFS library, libufs(8) so that they can be used by user-level programs. The new functions added to libufs(8) are sbfind(3) that is an alternative to sbread(3) and sbsearch(3) that is an alternative to sbget(3).

The utilities that have been changed to search for superblocks are dumpfs(8), fsdb(8), ffsinfo(8), and fsck_ffs(8). Also, the prtblknos(8) tool found in tools/diag/prtblknos searches for superblocks..

The UFS specific mount code uses the superblock search interface when mounting the root filesystem and when the administrator doing a mount(8) command specifies the force flag (-f). The standalone UFS boot code (found in stand/libsa/ufs.c) uses the superblock search code in the hope of being able to get the system up and running so that fsck_ffs(8) can be used to get the filesystem cleaned up.

The following utilities have not been changed to not search for superblocks: clri(8), tunefs(8), snapinfo(8), fstyp(8), quot(8), dump(8), fsirand(8), growfs(8), quotacheck(8), gjournal(8), and glabel(8). When these utilities fail, they do report the cause of the failure. The one exception is the tasting code used to try and figure what a given disk contains. The tasting code will remain silent so as not to put out a slew of messages as it trying to taste every new mass storage device that shows up.

Reviewers are solicited to provide feedback on the above selection of utilities to use or not use the new search facility. The current criterion is to make the utilities that are mainly used for debugging search for superblocks while those used for administrative tasks to not search. The thinking for the administrative commands to not search is that if a filesystem superblock is inconsistent, then fsck_ffs(8) should be used first to clean it up before attempting the administrative task.

Test Plan

Have Peter Holm run his vast set of filesystem tests.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

gbe added a reviewer: manpages.
gbe added a subscriber: gbe.

LGTM for the man page parts.

pauamma added a subscriber: pauamma.

The English in the manual page change LGTM. I can't attest to consistency with the rest.

This revision is now accepted and ready to land.Sat, Aug 6, 10:00 AM

I am not sure about positioning of fstype(8) there. On one hand, it is better to report that the volume is suspicious to have something resembling UFS on it. On the other hand, it might be that the alternative superblock is a ghost and now the different kind of the on-disk structure is present.

In D36053#818705, @kib wrote:

I am not sure about positioning of fstype(8) there. On one hand, it is better to report that the volume is suspicious to have something resembling UFS on it. On the other hand, it might be that the alternative superblock is a ghost and now the different kind of the on-disk structure is present.

I had considered just asking for the superblock, with sbget(), and if that failed trying harder with sbsearch() and if that then succeeded printing out something like 'possibly ufs'. But that seemed a bit out of character with the reading of other filesystem types, so I left it with its historic behavior. What do you think about this alternative approach?

In D36053#818684, @gbe wrote:

LGTM for the man page parts.

Thanks for your (quick) review.

The English in the manual page change LGTM. I can't attest to consistency with the rest.

Thanks for your (quick) review.

tl;dr: Looks good to me.

Too long, but you are reading anyway:

I believe this is correct for the boot loader (I didn't read the other stuff since I'm short on time today).
This will increase the boot loader size a small amount. For EFI we're so far under the limits that it's not going to be an issue.
For a normal x86/BIOS build, this will be fine. We have plenty of space in the ~485k of space that's typically available.
However, for a x86/BIOS build, with the VERIEXEC options turned on this pushes us closer and closer to the edge, though my "spidy" sense on the generated code size says this won't be the straw that breaks that camel's back on the build (though it will make running lua scripts a tiny bit harder).
For all other flavors of loader build, either this routine isn't used (boot2, gptboot, etc), or we're in a similar situation to EFI where the limits are in the hundreds of megabytes and the loader size is still in the hundreds of kilobytes.

stand/libsa/ufs.c
155

Would be nicer if we had a #include file that we could use to pick this up, but that's a bit beyond the basic remit of this change.

534

I'll note for the record that we use 'ufs_open' (indirectly) from ufs_mount which will also want to search for alternative blocks, so this is good.

Thanks Warner. You zero'ed in on the part that I was concerned about which is whether the expanded code would fit.
If you do find that the fit is a problem, it would be trivial to #ifdef to get the old behavior and smaller code where needed.

In D36053#818705, @kib wrote:

I am not sure about positioning of fstype(8) there. On one hand, it is better to report that the volume is suspicious to have something resembling UFS on it. On the other hand, it might be that the alternative superblock is a ghost and now the different kind of the on-disk structure is present.

I had considered just asking for the superblock, with sbget(), and if that failed trying harder with sbsearch() and if that then succeeded printing out something like 'possibly ufs'. But that seemed a bit out of character with the reading of other filesystem types, so I left it with its historic behavior. What do you think about this alternative approach?

After thinking about it more, I tend to agree with the code as is, for fstyp(8). Reason is that typical use if the fstyp is to determine the volume type that can be just mounted, without requiring a recovery. In this regard, not looking at alternative superblock is right.