New API: Replace btrfs-fsck with btrfs-scrub-full

The old btrfs-fsck API used "btrfs check" which appears to be broken
or deprecated.  The real tool you should use is "btrfs scrub".  We
have already implemented that API, but it is very awkward to use from
libguestfs.  In particular there's no existing way to run the scrub
and wait for it to finish.

Fix this by deprecating btrfs-fsck.  Implement a new API
btrfs-scrub-full which runs btrfs scrub in the foreground, waits for
it to finish, and handles errors.  It's much more like fsck tools in
other filesystems.

Thanks: Eric Sandeen
Fixes: https://issues.redhat.com/browse/RHEL-91936
This commit is contained in:
Richard W.M. Jones
2025-05-15 21:18:14 +01:00
committed by rwmjones
parent 1c2b94f095
commit ea3dd97f1d
7 changed files with 78 additions and 15 deletions

View File

@@ -1450,6 +1450,47 @@ do_btrfs_scrub_resume (const char *path)
return 0;
}
/* Takes optional arguments, consult optargs_bitmask. */
int
do_btrfs_scrub_full (const char *path, int readonly)
{
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
size_t i = 0;
CLEANUP_FREE char *path_buf = NULL;
CLEANUP_FREE char *out = NULL, *err = NULL;
int r;
path_buf = sysroot_path (path);
if (path_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "scrub");
ADD_ARG (argv, i, "start");
ADD_ARG (argv, i, "-B"); /* foreground */
/* Optional arguments. */
if ((optargs_bitmask & GUESTFS_BTRFS_SCRUB_FULL_READONLY_BITMASK) &&
readonly)
ADD_ARG (argv, i, "-r");
ADD_ARG (argv, i, path_buf);
ADD_ARG (argv, i, NULL);
r = commandvf (&out, &err,
COMMAND_FLAG_FOLD_STDOUT_ON_STDERR,
argv);
if (r == -1) {
reply_with_error ("%s: %s", path, err);
return -1;
}
return 0;
}
int
do_btrfs_balance_pause (const char *path)
{

View File

@@ -26,6 +26,9 @@ New C<command_out> and C<sh_out> APIs which allow you to capture
output from guest commands that generate more output than the protocol
limit allows.
New C<btrfs_scrub_full> API which runs a full Btrfs scrub,
synchronously. It works more like fsck for other filesystems.
The C<fstrim> API has been modified to work around several issues in
upstream and RHEL 9 kernels related to XFS support (Eric Sandeen, Dave
Chinner).

View File

@@ -7344,20 +7344,6 @@ If C<devices> is an empty list, this does nothing." };
Enable or disable the seeding feature of a device that contains
a btrfs filesystem." };
{ defaults with
name = "btrfs_fsck"; added = (1, 17, 43);
style = RErr, [String (Device, "device")], [OInt64 "superblock"; OBool "repair"];
optional = Some "btrfs";
tests = [
InitPartition, Always, TestRun (
[["mkfs_btrfs"; "/dev/sda1"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
["btrfs_fsck"; "/dev/sda1"; ""; ""]]), []
];
shortdesc = "check a btrfs filesystem";
longdesc = "\
Used to check a btrfs filesystem, C<device> is the device file where the
filesystem is stored." };
{ defaults with
name = "filesystem_available"; added = (1, 19, 5);
style = RBool "fsavail", [String (PlainString, "filesystem")], [];
@@ -9082,6 +9068,21 @@ Show the status of a running or paused balance on a btrfs filesystem." };
longdesc = "\
Show status of running or finished scrub on a btrfs filesystem." };
{ defaults with
name = "btrfs_scrub_full"; added = (1, 55, 12);
style = RErr, [String (Pathname, "path")], [OBool "readonly"];
optional = Some "btrfs"; camel_name = "BTRFSScrubFull";
tests = [
InitPartition, Always, TestRun (
[["mkfs_btrfs"; "/dev/sda1"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
["mount"; "/dev/sda1"; "/"];
["btrfs_scrub_full"; "/"; "false"]]), [];
];
shortdesc = "run a full scrub on a btrfs filesystem";
longdesc = "\
Run a full scrub on a btrfs filesystem and wait for it to finish.
If the filesystem has errors this will return an error." };
{ defaults with
name = "btrfstune_seeding"; added = (1, 29, 29);
style = RErr, [String (Device, "device"); Bool "seeding"], [];

View File

@@ -927,4 +927,19 @@ This call does nothing and returns an error." };
longdesc = "\
This call does nothing and returns an error." };
{ defaults with
name = "btrfs_fsck"; added = (1, 17, 43);
style = RErr, [String (Device, "device")], [OInt64 "superblock"; OBool "repair"];
optional = Some "btrfs";
deprecated_by = Replaced_by "btrfs_scrub_full";
tests = [
InitPartition, Always, TestRun (
[["mkfs_btrfs"; "/dev/sda1"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
["btrfs_fsck"; "/dev/sda1"; ""; ""]]), []
];
shortdesc = "check a btrfs filesystem";
longdesc = "\
Used to check a btrfs filesystem, C<device> is the device file where the
filesystem is stored." };
]

View File

@@ -520,6 +520,7 @@ let proc_nr = [
515, "findfs_partlabel";
516, "command_out";
517, "sh_out";
518, "btrfs_scrub_full";
]
(* End of list. If adding a new entry, add it at the end of the list

View File

@@ -59,6 +59,7 @@ guestfs_gobject_headers= \
include/guestfs-gobject/optargs-btrfs_filesystem_resize.h \
include/guestfs-gobject/optargs-btrfs_fsck.h \
include/guestfs-gobject/optargs-btrfs_image.h \
include/guestfs-gobject/optargs-btrfs_scrub_full.h \
include/guestfs-gobject/optargs-btrfs_subvolume_create.h \
include/guestfs-gobject/optargs-btrfs_subvolume_snapshot.h \
include/guestfs-gobject/optargs-compress_device_out.h \
@@ -153,6 +154,7 @@ guestfs_gobject_sources= \
src/optargs-btrfs_filesystem_resize.c \
src/optargs-btrfs_fsck.c \
src/optargs-btrfs_image.c \
src/optargs-btrfs_scrub_full.c \
src/optargs-btrfs_subvolume_create.c \
src/optargs-btrfs_subvolume_snapshot.c \
src/optargs-compress_device_out.c \

View File

@@ -1 +1 @@
517
518