Add progress module to display load progress of files.

* grub-core/lib/progress.c: New file.
	* grub-core/Makefile.core.def (progress): New module.
	* grub-core/kern/file.c (grub_file_open): File name added.
	* (grub_file_read): Progress hook added.
	* grub-core/fs/cbfs.c (grub_cbfs_read): Likewise.
	* grub-core/fs/cpio_common.c (grub_cpio_read): Likewise.
	* grub-core/net/net.c (grub_net_fs_read_real): Likewise.
	* include/grub/file.h (struct grub_file): Add progress module
	* members.
	* include/grub/term.h (struct grub_term_output): Likewise.
	* grub-core/osdep/unix/emuconsole.c (grub_console_term_output):
	Terminal velocity added.
	* grub-core/osdep/windows/emuconsole.c (grub_console_term_output):
	* Likewise.
	* grub-core/term/arc/console.c (grub_console_term_output): Likewise.
	* grub-core/term/efi/console.c (grub_console_term_output): Likewise.
	* grub-core/term/gfxterm.c (grub_video_term): Likewise.
	* grub-core/term/i386/coreboot/cbmemc.c (grub_cbmemc_term_output):
	* Likewise.
	* grub-core/term/i386/pc/console.c (grub_console_term_output):
	* Likewise.
	* grub-core/term/i386/pc/vga_text.c (grub_vga_text_term): Likewise.
	* grub-core/term/ieee1275/console.c (grub_console_term_output):
	* Likewise.
	* grub-core/term/morse.c (grub_audio_term_output): Likewise.
	* grub-core/term/serial.c (grub_serial_term_output): Likewise.
	* grub-core/term/spkmodem.c (grub_spkmodem_term_output): Likewise.
	* grub-core/term/uboot/console.c (uboot_console_term_output):
	* Likewise.
This commit is contained in:
Paulo Flabiano Smorigo 2013-10-22 16:42:20 -02:00 committed by Paulo Flabiano Smorigo
parent 0d711431c7
commit 84a0e9699f
22 changed files with 205 additions and 7 deletions

View file

@ -1,3 +1,31 @@
2013-10-22 Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
Add new progress module that displays the load progress of files.
* grub-core/lib/progress.c: New file.
* grub-core/Makefile.core.def (progress): New module.
* grub-core/kern/file.c (grub_file_open): File name added.
* (grub_file_read): Progress hook added.
* grub-core/fs/cbfs.c (grub_cbfs_read): Likewise.
* grub-core/fs/cpio_common.c (grub_cpio_read): Likewise.
* grub-core/net/net.c (grub_net_fs_read_real): Likewise.
* include/grub/file.h (struct grub_file): Add progress module members.
* include/grub/term.h (struct grub_term_output): Likewise.
* grub-core/osdep/unix/emuconsole.c (grub_console_term_output):
Terminal velocity added.
* grub-core/osdep/windows/emuconsole.c (grub_console_term_output): Likewise.
* grub-core/term/arc/console.c (grub_console_term_output): Likewise.
* grub-core/term/efi/console.c (grub_console_term_output): Likewise.
* grub-core/term/gfxterm.c (grub_video_term): Likewise.
* grub-core/term/i386/coreboot/cbmemc.c (grub_cbmemc_term_output): Likewise.
* grub-core/term/i386/pc/console.c (grub_console_term_output): Likewise.
* grub-core/term/i386/pc/vga_text.c (grub_vga_text_term): Likewise.
* grub-core/term/ieee1275/console.c (grub_console_term_output): Likewise.
* grub-core/term/morse.c (grub_audio_term_output): Likewise.
* grub-core/term/serial.c (grub_serial_term_output): Likewise.
* grub-core/term/spkmodem.c (grub_spkmodem_term_output): Likewise.
* grub-core/term/uboot/console.c (uboot_console_term_output): Likewise.
2013-10-22 Vladimir Serbinenko <phcoder@gmail.com> 2013-10-22 Vladimir Serbinenko <phcoder@gmail.com>
Verify signatures of signatures unless --skip-sig is specified. Verify signatures of signatures unless --skip-sig is specified.

View file

@ -2135,3 +2135,8 @@ module = {
name = tr; name = tr;
common = commands/tr.c; common = commands/tr.c;
}; };
module = {
name = progress;
common = lib/progress.c;
};

View file

@ -243,10 +243,17 @@ static grub_ssize_t
grub_cbfs_read (grub_file_t file, char *buf, grub_size_t len) grub_cbfs_read (grub_file_t file, char *buf, grub_size_t len)
{ {
struct grub_archelp_data *data; struct grub_archelp_data *data;
grub_ssize_t ret;
data = file->data; data = file->data;
return (grub_disk_read (data->disk, 0, data->dofs + file->offset, data->disk->read_hook = file->read_hook;
data->disk->read_hook_data = file->read_hook_data;
ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset,
len, buf)) ? -1 : (grub_ssize_t) len; len, buf)) ? -1 : (grub_ssize_t) len;
data->disk->read_hook = 0;
return ret;
} }
static grub_err_t static grub_err_t

View file

@ -200,10 +200,17 @@ static grub_ssize_t
grub_cpio_read (grub_file_t file, char *buf, grub_size_t len) grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
{ {
struct grub_archelp_data *data; struct grub_archelp_data *data;
grub_ssize_t ret;
data = file->data; data = file->data;
return (grub_disk_read (data->disk, 0, data->dofs + file->offset, data->disk->read_hook = file->read_hook;
data->disk->read_hook_data = file->read_hook_data;
ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset,
len, buf)) ? -1 : (grub_ssize_t) len; len, buf)) ? -1 : (grub_ssize_t) len;
data->disk->read_hook = 0;
return ret;
} }
static grub_err_t static grub_err_t

View file

@ -87,6 +87,9 @@ grub_file_open (const char *name)
if (! file) if (! file)
goto fail; goto fail;
file->name = grub_strdup (name);
grub_errno = GRUB_ERR_NONE;
file->device = device; file->device = device;
if (device->disk && file_name[0] != '/') if (device->disk && file_name[0] != '/')
@ -131,10 +134,14 @@ grub_file_open (const char *name)
return 0; return 0;
} }
grub_disk_read_hook_t grub_file_progress_hook;
grub_ssize_t grub_ssize_t
grub_file_read (grub_file_t file, void *buf, grub_size_t len) grub_file_read (grub_file_t file, void *buf, grub_size_t len)
{ {
grub_ssize_t res; grub_ssize_t res;
grub_disk_read_hook_t read_hook;
void *read_hook_data;
if (file->offset > file->size) if (file->offset > file->size)
{ {
@ -155,7 +162,17 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
if (len == 0) if (len == 0)
return 0; return 0;
read_hook = file->read_hook;
read_hook_data = file->read_hook_data;
if (!file->read_hook)
{
file->read_hook = grub_file_progress_hook;
file->read_hook_data = file;
file->progress_offset = file->offset;
}
res = (file->fs->read) (file, buf, len); res = (file->fs->read) (file, buf, len);
file->read_hook = read_hook;
file->read_hook_data = read_hook_data;
if (res > 0) if (res > 0)
file->offset += res; file->offset += res;

100
grub-core/lib/progress.c Normal file
View file

@ -0,0 +1,100 @@
/* progress.c - show loading progress */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/time.h>
#include <grub/term.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/normal.h>
GRUB_MOD_LICENSE ("GPLv3+");
#define UPDATE_INTERVAL 800
static void
grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
unsigned offset __attribute__ ((unused)),
unsigned length, void *data)
{
grub_uint64_t now = grub_get_time_ms ();
static grub_uint64_t last_progress_update_time;
grub_file_t file = data;
file->progress_offset += length;
if (((now - last_progress_update_time > UPDATE_INTERVAL) &&
(file->progress_offset - file->offset > 0)) ||
(file->progress_offset == file->size))
{
char buffer[80];
struct grub_term_output *term;
char *partial_file_name = grub_strrchr (file->name, '/') + 1;
grub_uint64_t current_speed = grub_divmod64 ((file->progress_offset -
file->last_progress_offset)
* 100ULL * 1000ULL,
now - file->last_progress_time, 0);
file->estimated_speed = (file->estimated_speed + current_speed) >> 1;
grub_snprintf (buffer, sizeof (buffer), " [ %.20s %s %llu%% ",
partial_file_name,
grub_get_human_size (file->progress_offset,
GRUB_HUMAN_SIZE_NORMAL),
(100 * file->progress_offset) / file->size);
char *ptr = buffer + grub_strlen (buffer);
grub_snprintf (ptr, sizeof (buffer) - (ptr - buffer), "%s ]",
grub_get_human_size (file->estimated_speed,
GRUB_HUMAN_SIZE_SPEED));
grub_uint16_t len = grub_strlen (buffer);
FOR_ACTIVE_TERM_OUTPUTS (term)
{
if (term->progress_update_counter++ > term->progress_update_divisor ||
(file->progress_offset == file->size &&
term->progress_update_divisor != (unsigned) GRUB_PROGRESS_NO_UPDATE))
{
struct grub_term_coordinate old_pos = grub_term_getxy (term);
struct grub_term_coordinate new_pos = old_pos;
new_pos.x = grub_term_width (term) - len - 1;
grub_term_gotoxy (term, new_pos);
grub_puts_terminal (buffer, term);
grub_term_gotoxy (term, old_pos);
term->progress_update_counter = 0;
}
}
file->last_progress_offset = file->progress_offset;
file->last_progress_time = now;
last_progress_update_time = now;
}
}
GRUB_MOD_INIT(progress)
{
grub_file_progress_hook = grub_file_progress_hook_real;
}
GRUB_MOD_FINI(progress)
{
grub_file_progress_hook = 0;
}

View file

@ -1536,6 +1536,8 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
len -= amount; len -= amount;
total += amount; total += amount;
file->device->net->offset += amount; file->device->net->offset += amount;
if (grub_file_progress_hook)
grub_file_progress_hook (0, 0, amount, file);
if (buf) if (buf)
{ {
grub_memcpy (ptr, nb->data, amount); grub_memcpy (ptr, nb->data, amount);

View file

@ -149,6 +149,7 @@ static struct grub_term_output grub_console_term_output =
.setcolorstate = grub_terminfo_setcolorstate, .setcolorstate = grub_terminfo_setcolorstate,
.setcursor = grub_terminfo_setcursor, .setcursor = grub_terminfo_setcursor,
.data = &grub_console_terminfo_output, .data = &grub_console_terminfo_output,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
void void

View file

@ -283,7 +283,8 @@ static struct grub_term_output grub_console_term_output =
.cls = grub_console_cls, .cls = grub_console_cls,
.setcolorstate = grub_console_setcolorstate, .setcolorstate = grub_console_setcolorstate,
.setcursor = grub_console_setcursor, .setcursor = grub_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
void void

View file

@ -188,6 +188,7 @@ static struct grub_term_output grub_console_term_output =
.setcursor = grub_terminfo_setcursor, .setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII, .flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_console_terminfo_output, .data = &grub_console_terminfo_output,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
void void

View file

@ -276,7 +276,8 @@ static struct grub_term_output grub_console_term_output =
.cls = grub_console_cls, .cls = grub_console_cls,
.setcolorstate = grub_console_setcolorstate, .setcolorstate = grub_console_setcolorstate,
.setcursor = grub_console_setcursor, .setcursor = grub_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
void void

View file

@ -1108,6 +1108,7 @@ static struct grub_term_output grub_video_term =
.refresh = grub_gfxterm_refresh, .refresh = grub_gfxterm_refresh,
.fullscreen = grub_gfxterm_fullscreen, .fullscreen = grub_gfxterm_fullscreen,
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
.progress_update_divisor = GRUB_PROGRESS_SLOW,
.next = 0 .next = 0
}; };

View file

@ -68,6 +68,7 @@ static struct grub_term_output grub_cbmemc_term_output =
.setcursor = grub_terminfo_setcursor, .setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII, .flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_cbmemc_terminfo_output, .data = &grub_cbmemc_terminfo_output,
.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE
}; };
static int static int

View file

@ -292,6 +292,7 @@ static struct grub_term_output grub_console_term_output =
.setcolorstate = grub_console_setcolorstate, .setcolorstate = grub_console_setcolorstate,
.setcursor = grub_console_setcursor, .setcursor = grub_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_CP437, .flags = GRUB_TERM_CODE_TYPE_CP437,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
void void

View file

@ -267,6 +267,7 @@ static struct grub_term_output grub_vga_text_term =
.setcolorstate = grub_vga_text_setcolorstate, .setcolorstate = grub_vga_text_setcolorstate,
.setcursor = grub_vga_text_setcursor, .setcursor = grub_vga_text_setcursor,
.flags = GRUB_TERM_CODE_TYPE_CP437, .flags = GRUB_TERM_CODE_TYPE_CP437,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
/* FIXME: this is was too spaghetti. */ /* FIXME: this is was too spaghetti. */

View file

@ -236,6 +236,7 @@ static struct grub_term_output grub_console_term_output =
.setcursor = grub_console_setcursor, .setcursor = grub_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII, .flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_console_terminfo_output, .data = &grub_console_terminfo_output,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
void void

View file

@ -118,7 +118,8 @@ static struct grub_term_output grub_audio_term_output =
.cls = (void *) dummy, .cls = (void *) dummy,
.setcolorstate = (void *) dummy, .setcolorstate = (void *) dummy,
.setcursor = (void *) dummy, .setcursor = (void *) dummy,
.flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB .flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB,
.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE
}; };
GRUB_MOD_INIT (morse) GRUB_MOD_INIT (morse)

View file

@ -123,6 +123,7 @@ static struct grub_term_output grub_serial_term_output =
.setcursor = grub_terminfo_setcursor, .setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII, .flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_serial_terminfo_output, .data = &grub_serial_terminfo_output,
.progress_update_divisor = GRUB_PROGRESS_SLOW
}; };

View file

@ -126,6 +126,7 @@ static struct grub_term_output grub_spkmodem_term_output =
.setcursor = grub_terminfo_setcursor, .setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII, .flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_spkmodem_terminfo_output, .data = &grub_spkmodem_terminfo_output,
.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE
}; };
GRUB_MOD_INIT (spkmodem) GRUB_MOD_INIT (spkmodem)

View file

@ -95,6 +95,7 @@ static struct grub_term_output uboot_console_term_output = {
.setcursor = uboot_console_setcursor, .setcursor = uboot_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII, .flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &uboot_console_terminfo_output, .data = &uboot_console_terminfo_output,
.progress_update_divisor = GRUB_PROGRESS_FAST
}; };
void void

View file

@ -28,6 +28,9 @@
/* File description. */ /* File description. */
struct grub_file struct grub_file
{ {
/* File name. */
char *name;
/* The underlying device. */ /* The underlying device. */
grub_device_t device; grub_device_t device;
@ -36,6 +39,12 @@ struct grub_file
/* The current offset. */ /* The current offset. */
grub_off_t offset; grub_off_t offset;
grub_off_t progress_offset;
/* Progress info. */
grub_uint64_t last_progress_time;
grub_off_t last_progress_offset;
grub_uint64_t estimated_speed;
/* The file size. */ /* The file size. */
grub_off_t size; grub_off_t size;
@ -54,6 +63,8 @@ struct grub_file
}; };
typedef struct grub_file *grub_file_t; typedef struct grub_file *grub_file_t;
extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
/* Filters with lower ID are executed first. */ /* Filters with lower ID are executed first. */
typedef enum grub_file_filter_id typedef enum grub_file_filter_id
{ {

View file

@ -59,6 +59,10 @@
#define GRUB_TERM_TAB '\t' #define GRUB_TERM_TAB '\t'
#define GRUB_TERM_BACKSPACE '\b' #define GRUB_TERM_BACKSPACE '\b'
#define GRUB_PROGRESS_NO_UPDATE -1
#define GRUB_PROGRESS_FAST 0
#define GRUB_PROGRESS_SLOW 2
#ifndef ASM_FILE #ifndef ASM_FILE
#include <grub/err.h> #include <grub/err.h>
@ -215,6 +219,10 @@ struct grub_term_output
/* The feature flags defined above. */ /* The feature flags defined above. */
grub_uint32_t flags; grub_uint32_t flags;
/* Progress data. */
grub_uint32_t progress_update_divisor;
grub_uint32_t progress_update_counter;
void *data; void *data;
}; };
typedef struct grub_term_output *grub_term_output_t; typedef struct grub_term_output *grub_term_output_t;