Re: [PATCH v2] makedumpfile: Use integer arithmetics for the progress bar

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

 



On Fri, 18 May 2018 08:22:10 +0000
Masaki Tachibana <mas-tachibana@xxxxxxxxxxxxx> wrote:

> Hi Petr and Lianbo,

Hi Masaki-san,

> Sorry for the late reply.

No problem. I know how to wait. ;-)

> I will merge the patch into V1.6.4.

Thank you very much!

> 
> Thanks
> Tachibana
> 
> 
> > -----Original Message-----
> > From: Petr Tesarik [mailto:ptesarik@xxxxxxx]
> > Sent: Tuesday, April 10, 2018 8:39 PM
> > To: lijiang <lijiang@xxxxxxxxxx>
> > Cc: Tachibana Masaki() <mas-tachibana@xxxxxxxxxxxxx>; Nakayama Takuya() <tak-nakayama@xxxxxxxxxxxxx>;
> > kexec-ml <kexec@xxxxxxxxxxxxxxxxxxx>
> > Subject: [PATCH v2] makedumpfile: Use integer arithmetics for the progress bar
> > 
> > Essentially, the estimated remaining time is calculated as:
> > 
> >   elapsed * (100 - progress) / progress
> > 
> > Since the calculation is done with floating point numbers, it had
> > masked a division by zero (if progress is 0), producing a NaN or
> > infinity. The following conversion to int produces INT_MIN with GCC
> > on major platforms, which originally overflowed the eta buffer. This
> > bug was fixed by commit e5f96e79d69a1d295f19130da00ec6514d28a8ae,
> > but conversion of NaN and infinity is undefined behaviour in ISO C,
> > plus the corresponding output is still wrong, e.g.:
> > 
> > Copying data                                      : [  0.0 %] /  eta: -9223372036854775808s
> > 
> > Most importantly, using the FPU for a progress bar is overkill.
> > Since the progress percentage is reported with one decimal digit
> > following the decimal point, it can be stored as an integer tenths
> > of a percent.
> > 
> > Second, the estimated time can be calculated in milliseconds. Up to
> > 49 days can be represented this way even on 32-bit platforms. Note
> > that delta.tv_usec can be ignored in the subtraction, because the
> > resulting eta is printed as seconds, so elapsed microseconds are
> > irrelevant.
> > 
> > Last but not least, the original buffer overflow was probably caused
> > by the wrong assumption that integers < 100 can be interpreted with
> > less than 3 ASCII characters, but that's not true for signed
> > integers. To make eta_to_human_short() a bit safer, use an unsigned
> > integer type.
> > 
> > Signed-off-by: Petr Tesarik <ptesarik@xxxxxxxx>
> > ---
> >  print_info.c | 43 ++++++++++++++++++++-----------------------
> >  1 file changed, 20 insertions(+), 23 deletions(-)
> > 
> > diff --git a/print_info.c b/print_info.c
> > index 09e215a..6bfcd11 100644
> > --- a/print_info.c
> > +++ b/print_info.c
> > @@ -16,8 +16,6 @@
> >  #include "print_info.h"
> >  #include <time.h>
> >  #include <string.h>
> > -#include <stdint.h>
> > -#include <inttypes.h>
> > 
> >  #define PROGRESS_MAXLEN		"50"
> > 
> > @@ -354,21 +352,18 @@ static void calc_delta(struct timeval *tv_start, struct timeval *delta)
> >  }
> > 
> >  /* produce less than 12 bytes on msg */
> > -static int eta_to_human_short (int64_t secs, char* msg, int maxsize)
> > +static int eta_to_human_short (unsigned long secs, char* msg)
> >  {
> >  	strcpy(msg, "eta: ");
> >  	msg += strlen("eta: ");
> >  	if (secs < 100)
> > -		snprintf(msg, maxsize, "%"PRId64"s", secs);
> > +		sprintf(msg, "%lus", secs);
> >  	else if (secs < 100 * 60)
> > -		snprintf(msg, maxsize, "%"PRId64"m""%"PRId64"s",
> > -			secs / 60, secs % 60);
> > +		sprintf(msg, "%lum%lus", secs / 60, secs % 60);
> >  	else if (secs < 48 * 3600)
> > -		snprintf(msg, maxsize, "%"PRId64"h""%"PRId64"m",
> > -			secs / 3600, (secs / 60) % 60);
> > +		sprintf(msg, "%luh%lum", secs / 3600, (secs / 60) % 60);
> >  	else if (secs < 100 * 86400)
> > -		snprintf(msg, maxsize, "%"PRId64"d""%"PRId64"h",
> > -			secs / 86400, (secs / 3600) % 24);
> > +		sprintf(msg, "%lud%luh", secs / 86400, (secs / 3600) % 24);
> >  	else
> >  		sprintf(msg, ">2day");
> >  	return 0;
> > @@ -378,37 +373,39 @@ static int eta_to_human_short (int64_t secs, char* msg, int maxsize)
> >  void
> >  print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start)
> >  {
> > -	float progress;
> > +	unsigned progress;	/* in promilles (tenths of a percent) */
> >  	time_t tm;
> >  	static time_t last_time = 0;
> >  	static unsigned int lapse = 0;
> >  	static const char *spinner = "/|\\-";
> >  	struct timeval delta;
> > -	int64_t eta;
> > -	char eta_msg[32] = " ";
> > +	unsigned long eta;
> > +	char eta_msg[16] = " ";
> > 
> >  	if (current < end) {
> >  		tm = time(NULL);
> >  		if (tm - last_time < 1)
> >  			return;
> >  		last_time = tm;
> > -		progress = (float)current * 100 / end;
> > +		progress = current * 1000 / end;
> >  	} else
> > -		progress = 100;
> > +		progress = 1000;
> > 
> > -	if (start != NULL) {
> > +	if (start != NULL && progress != 0) {
> >  		calc_delta(start, &delta);
> > -		eta = delta.tv_sec + delta.tv_usec / 1e6;
> > -		eta = (100 - progress) * eta / progress;
> > -		eta_to_human_short(eta, eta_msg, sizeof(eta_msg));
> > +		eta = 1000 * delta.tv_sec + delta.tv_usec / 1000;
> > +		eta = eta / progress - delta.tv_sec;
> > +		eta_to_human_short(eta, eta_msg);
> >  	}
> >  	if (flag_ignore_r_char) {
> > -		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c  %16s\n",
> > -			     msg, progress, spinner[lapse % 4], eta_msg);
> > +		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%3u.%u %%] %c  %16s\n",
> > +			     msg, progress / 10, progress % 10,
> > +			     spinner[lapse % 4], eta_msg);
> >  	} else {
> >  		PROGRESS_MSG("\r");
> > -		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c  %16s",
> > -			     msg, progress, spinner[lapse % 4], eta_msg);
> > +		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%3u.%u %%] %c  %16s",
> > +			     msg, progress / 10, progress % 10,
> > +			     spinner[lapse % 4], eta_msg);
> >  	}
> >  	lapse++;
> >  }
> > --
> > 2.13.6
> >   
> 
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@xxxxxxxxxxxxxxxxxxx
> http://lists.infradead.org/mailman/listinfo/kexec


_______________________________________________
kexec mailing list
kexec@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/kexec



[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux