Re: btrfs-progs reports nonsense scrub status

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/05/2020 12:52, Graham Cobb wrote:
> On 10/05/2020 02:14, Chris Murphy wrote:
>> I don't know how the kernel and user space communicate scrub progress.
>> I don't see anything in sysfs.
> 
> I did some work on btrfs-scrub a while ago to fix a bug in the way
> last_physical was being saved between cancel and restore.
> 
> If I remember correctly, the way this works is that the scrub process
> receives stats about the scrub progress directly from the kernel on a
> socket it creates in /var/lib/btrfs, then writes updated stats into a
> file in /var/lib/btrfs/scrub.status.<UUID> to share with scrub status
> and keep a record. At the end of the scrub, the final stats are provided
> by the kernel into a buffer provided in the ioctl which are also then
> used to update the scrub.status file.

Unfortunately my memory is rubbish! I have just looked at the code to
remind myself.

The scrub process gets stats from the kernel using a
BTRFS_IOC_SCRUB_PROGRESS ioctl (one for each device).

It uses this to update the status file and also sends the stats to any
listeners on the socket.

btrfs scrub status reads the data from the socket if it exists (i.e. the
scrub process is still running), otherwise it reads it from the data
file (for a scrub which has finished or been cancelled).

It might be worth you making a small logging change to progress_one_dev
to watch the value of last_physical exactly as received from the kernel
during the scrub. I have attached a small patch.
diff --git a/cmds/scrub.c b/cmds/scrub.c
index 9fe59822..48d76852 100644
--- a/cmds/scrub.c
+++ b/cmds/scrub.c
@@ -902,6 +902,8 @@ static void *progress_one_dev(void *ctx)
 	struct scrub_progress *sp = ctx;
 
 	sp->ret = ioctl(sp->fd, BTRFS_IOC_SCRUB_PROGRESS, &sp->scrub_args);
+	fprintf(stderr, "NOTE: device %lld last_physical=%lld\n", sp->scrub_args.devid, sp->scrub_args.progress.last_physical);
+
 	sp->ioctl_errno = errno;
 
 	return NULL;
@@ -1784,7 +1786,8 @@ static int cmd_scrub_status(const struct cmd_struct *cmd, int argc, char **argv)
 			err = 1;
 			goto out;
 		}
-	}
+		fputs("NOTE: Reading progress from status file \n", stderr);
+	} else { fputs("NOTE: Reading progress from socket \n", stderr); }
 
 	if (fdres >= 0) {
 		past_scrubs = scrub_read_file(fdres, 1);

[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux