Page MenuHomeFreeBSD

Fix bsdinstall distfetch "Overall Progress" greater or less than 100%.
ClosedPublic

Authored by asiciliano on Jan 21 2022, 3:20 AM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Apr 12, 6:17 PM
Unknown Object (File)
Mar 7 2024, 6:36 PM
Unknown Object (File)
Jan 13 2024, 8:31 AM
Unknown Object (File)
Jan 13 2024, 3:56 AM
Unknown Object (File)
Dec 12 2023, 1:45 PM
Unknown Object (File)
Nov 22 2023, 8:50 PM
Unknown Object (File)
Nov 14 2023, 1:12 PM
Unknown Object (File)
Sep 18 2023, 2:21 PM
Subscribers

Details

Summary

I found the problem in a recent CURRENT 14 installation, anyway it is well known:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=164094
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=169748
https://www.reddit.com/r/freebsd/comments/g7gdc9/is_that_normal_overall_progress_208/

It is just a graphical problem not related to the real fetching process but it may be of concern to some users.

distfetch uses 2 "modes" to compute the main percentage in the mixedgauge: nfiles or total ustat.size, "if (total_bytes > 0)" allows to select the "mode".


PERC > 100%

The problem arises if some file fails to download, to reproduce "if (i==0) continue" to simulate an error for the first fetch (it is my case and the PRs)

	/* Try to stat all the files */
	total_bytes = 0;
	for (i = 0; i < nfiles; i++) {
		if (i == 0)
			continue; // effect: do not increment total_bytes
		if (fetchStatURL(urls[i], &ustat, "") == 0 && ustat.size > 0)
			total_bytes += ustat.size;
	}

env DISTRIBUTIONS="kernel.txz ports.txz tests.txz" BSDINSTALL_DISTDIR="./download" BSDINSTALL_DISTSITE="https://download.freebsd.org/ftp/snapshots/amd64/14.0-CURRENT/" ./distfetch

┌───────────Fetching Distribution─────────────┐
│                                             │  
│ kernel.txz                   [   Done     ] │  
│ ports.txz                    [   Done     ] │  
│ tests.txz                    [    98%     ] │  
│                                             │  
│ Fetching distribution files...              │  
│                                             │  
│  ┌─Overall Progress──────────────────────┐  │  
│  │                 189%                  │  │  
│  └───────────────────────────────────────┘  │  
└─────────────────────────────────────────────┘

To note: Overall Progess 189% (I have screenshots with percentage > 300%).

TO FIX

If an error occurs in the "for loop" of fetchStatURL() total_bytes becomes inconsistent,
total_bytes is less than the real amount so the main percentage is over 100%, progress = (current_bytes*100)/total_bytes.

To fix: switch to nfiles mode if an error occurs :

	/* Try to stat all the files */
	total_bytes = 0;
	for (i = 0; i < nfiles; i++) {
		if (fetchStatURL(urls[i], &ustat, "") == 0 && ustat.size > 0)
			total_bytes += ustat.size;
		else {
			total_bytes = 0;
			break;
		}
	}

PERC < 100%

Similar problem/idea/solution for fetchXGetURL(), if an error occurs show a msgbox, switch to nfiles mode and use a new way/algo too compute the main bar percentage;
here the problem is inverse, distfetch can end with percentage less than 100%. Set a fake file to reproduce the error:

	urls[0] = strdup("FAKE.txz"); // fake file to fail
	current_bytes = 0;
	for (i = 0; i < nfiles; i++) {
		last_progress = progress;
		if (total_bytes == 0)
			progress = (i*100)/nfiles;
	.............
               ┌───────────Fetching Distribution─────────────┐
               │                                             │  
               │ kernel.txz                   [  Failed    ] │  
               │ ports.txz                    [   Done     ] │  
               │ tests.txz                    [    93%     ] │  
               │                                             │  
               │ Fetching distribution files...              │  
               │                                             │  
               │  ┌─Overall Progress──────────────────────┐  │  
               │  │                  52%                  │  │  
               │  └───────────────────────────────────────┘  │  
               └─────────────────────────────────────────────┘  
                                                               
alfonso@bsd:~/coding/distfetch_fix_mainbar/%

Finally a mixedgauge is added at the end of distfetch.c to display at least one gauge in case of total fault.

urls[0] = urls[1] = urls[2] = strdup("FAKE");
fetchXGetURL()
┌───────────Fetching Distribution─────────────┐
│                                             │  
│ kernel.txz                   [  Failed    ] │  
│ ports.txz                    [  Failed    ] │  
│ tests.txz                    [  Failed    ] │  
│                                             │  
│ Fetching distribution completed             │  
│                                             │  
│  ┌─Overall Progress──────────────────────┐  │  
│  │                   0%                  │  │  
│  └───────────────────────────────────────┘  │  
└─────────────────────────────────────────────┘
Test Plan
% git clone https://gitlab.com/alfix/freebsd-lab.git
% cd freebsd-lab/distfetch_fix_mainbar
% make
% env DISTRIBUTIONS="kernel.txz ports.txz tests.txz" BSDINSTALL_DISTDIR="./download" BSDINSTALL_DISTSITE="https://download.freebsd.org/ftp/snapshots/amd64/14.0-CURRENT/" ./distfetch

Error for fetchStatURL(), this is the case of the PRs:

	urls[0]=strdup("FAKE");

	/* Try to stat all the files */
	total_bytes = 0;
	for (i = 0; i < nfiles; i++) {
		if (fetchStatURL(urls[i], &ustat, "") == 0 && ustat.size > 0) {
			total_bytes += ustat.size;
		} else {
			total_bytes = 0;
			break;
		}
	}

	urls[0] = strdup("https://download.freebsd.org/ftp/snapshots/amd64/14.0-CURRENT/kernel.txz");
┌───────────Fetching Distribution─────────────┐
│                                             │  
│ kernel.txz                   [   Done     ] │  
│ ports.txz                    [   Done     ] │  
│ tests.txz                    [   Done     ] │  
│                                             │  
│ Fetching distribution completed             │  
│                                             │  
│  ┌─Overall Progress──────────────────────┐  │  
│  │                 100%                  │  │  
│  └───────────────────────────────────────┘  │  
└─────────────────────────────────────────────┘

Fixed error perc > 100%


urls[1] = strdup("FAKE") instead of ports.txt before fetchXGetURL():
┌───────────Fetching Distribution─────────────┐
│                                             │  
│ kernel.txz                   [   Done     ] │  
│ ports.txz                    [  Failed    ] │  
│ tests.txz                    [   Done     ] │  
│                                             │  
│ Fetching distribution completed             │  
│                                             │  
│  ┌─Overall Progress──────────────────────┐  │  
│  │                 100%                  │  │  
│  └───────────────────────────────────────┘  │  
└─────────────────────────────────────────────┘

Fixed error perc < 100%

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped