MFC r276079, r276087:

Add a divisor parameter to twiddle() so that callers can request that
  output only happen on every Nth call.

  Add a new loader(8) variable, twiddle_divisor, allowing control over the
  output frequency of the "twiddle" IO progress indicator.
This commit is contained in:
ian 2015-02-11 22:55:24 +00:00
parent ba124c2ef3
commit f8178723e9
13 changed files with 81 additions and 29 deletions

View File

@ -286,7 +286,7 @@ cd9660_open(const char *path, struct open_file *f)
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
vd = buf;
for (bno = 16;; bno++) {
twiddle();
twiddle(1);
rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
ISO_DEFAULT_BLOCK_SIZE, buf, &read);
if (rc)
@ -319,7 +319,7 @@ cd9660_open(const char *path, struct open_file *f)
while (off < dsize) {
if ((off % ISO_DEFAULT_BLOCK_SIZE) == 0) {
twiddle();
twiddle(1);
rc = f->f_dev->dv_strategy
(f->f_devdata, F_READ,
cdb2devb(bno + boff),
@ -379,7 +379,7 @@ cd9660_open(const char *path, struct open_file *f)
/* Check for Rock Ridge since we didn't in the loop above. */
bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length);
twiddle();
twiddle(1);
rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
ISO_DEFAULT_BLOCK_SIZE, buf, &read);
if (rc)
@ -436,7 +436,7 @@ buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
if (fp->f_buf == (char *)0)
fp->f_buf = malloc(ISO_DEFAULT_BLOCK_SIZE);
twiddle();
twiddle(16);
rc = f->f_dev->dv_strategy(f->f_devdata, F_READ,
cdb2devb(blkno), ISO_DEFAULT_BLOCK_SIZE, fp->f_buf, &read);
if (rc)

View File

@ -353,7 +353,7 @@ ext2fs_open(const char *upath, struct open_file *f)
/* allocate space and read super block */
fs = (struct ext2fs *)malloc(sizeof(*fs));
fp->f_fs = fs;
twiddle();
twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
EXT2_SBLOCK, EXT2_SBSIZE, (char *)fs, &buf_size);
if (error)
@ -395,7 +395,7 @@ ext2fs_open(const char *upath, struct open_file *f)
len = blkgrps * fs->fs_bsize;
fp->f_bg = malloc(len);
twiddle();
twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
EXT2_SBLOCK + EXT2_SBSIZE / DEV_BSIZE, len,
(char *)fp->f_bg, &buf_size);
@ -507,7 +507,7 @@ ext2fs_open(const char *upath, struct open_file *f)
if (error)
goto out;
twiddle();
twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata,
F_READ, fsb_to_db(fs, disk_block),
fs->fs_bsize, buf, &buf_size);
@ -568,7 +568,7 @@ read_inode(ino_t inumber, struct open_file *f)
* Read inode and save it.
*/
buf = malloc(fs->fs_bsize);
twiddle();
twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
ino_to_db(fs, fp->f_bg, inumber), fs->fs_bsize, buf, &rsize);
if (error)
@ -665,7 +665,7 @@ block_map(struct open_file *f, daddr_t file_block, daddr_t *disk_block_p)
if (fp->f_blk[level] == (char *)0)
fp->f_blk[level] =
malloc(fs->fs_bsize);
twiddle();
twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsb_to_db(fp->f_fs, ind_block_num), fs->fs_bsize,
fp->f_blk[level], &fp->f_blksize[level]);
@ -723,7 +723,7 @@ buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
bzero(fp->f_buf, block_size);
fp->f_buf_size = block_size;
} else {
twiddle();
twiddle(4);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsb_to_db(fs, disk_block), block_size,
fp->f_buf, &fp->f_buf_size);

View File

@ -921,7 +921,7 @@ nandfs_bmap_lookup(struct nandfs *fs, struct nandfs_node *node,
return (0);
}
twiddle();
twiddle(1);
NANDFS_DEBUG("calling get_map with %jx\n", ind_block_num);
map = nandfs_get_map(fs, node, ind_block_num, phys);
if (map == NULL)

View File

@ -662,7 +662,7 @@ nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
(int)fp->off);
#endif
while ((int)size > 0) {
twiddle();
twiddle(16);
cc = nfs_readdata(fp, fp->off, (void *)addr, size);
/* XXX maybe should retry on certain errors */
if (cc == -1) {
@ -1311,7 +1311,7 @@ nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
(int)fp->off);
#endif
while ((int)size > 0) {
twiddle();
twiddle(16);
cc = nfs_readdata(fp, fp->off, (void *)addr, size);
/* XXX maybe should retry on certain errors */
if (cc == -1) {

View File

@ -77,7 +77,7 @@ read(int fd, void *dest, size_t bcount)
return (-1);
}
if (f->f_flags & F_RAW) {
twiddle();
twiddle(4);
errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
btodb(f->f_offset), bcount, dest, &resid);
if (errno)

View File

@ -241,7 +241,8 @@ extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3);
extern int snprintf(char *buf, size_t size, const char *cfmt, ...) __printflike(3, 4);
extern void vsprintf(char *buf, const char *cfmt, __va_list);
extern void twiddle(void);
extern void twiddle(u_int callerdiv);
extern void twiddle_divisor(u_int globaldiv);
extern void ngets(char *, int);
#define gets(x) ngets((x), 0)

View File

@ -447,14 +447,12 @@ tftp_read(struct open_file *f, void *addr, size_t size,
size_t *resid /* out */)
{
struct tftp_handle *tftpfile;
static int tc = 0;
tftpfile = (struct tftp_handle *) f->f_fsdata;
while (size > 0) {
int needblock, count;
if (!(tc++ % 16))
twiddle();
twiddle(32);
needblock = tftpfile->off / tftpfile->tftp_blksize + 1;

View File

@ -42,11 +42,28 @@ __FBSDID("$FreeBSD$");
/* Extra functions from NetBSD standalone printf.c */
static u_int globaldiv;
void
twiddle()
twiddle(u_int callerdiv)
{
static int pos;
static u_int callercnt, globalcnt, pos;
callercnt++;
if (callerdiv > 1 && (callercnt % callerdiv) != 0)
return;
globalcnt++;
if (globaldiv > 1 && (globalcnt % globaldiv) != 0)
return;
putchar("|/-\\"[pos++ & 3]);
putchar('\b');
}
void
twiddle_divisor(u_int gdiv)
{
globaldiv = gdiv;
}

View File

@ -155,7 +155,7 @@ read_inode(inumber, f)
* Read inode and save it.
*/
buf = malloc(fs->fs_bsize);
twiddle();
twiddle(1);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize,
buf, &rsize);
@ -265,7 +265,7 @@ block_map(f, file_block, disk_block_p)
if (fp->f_blk[level] == (char *)0)
fp->f_blk[level] =
malloc(fs->fs_bsize);
twiddle();
twiddle(1);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fp->f_fs, ind_block_num),
fs->fs_bsize,
@ -346,7 +346,7 @@ buf_write_file(f, buf_p, size_p)
if (fp->f_buf == (char *)0)
fp->f_buf = malloc(fs->fs_bsize);
twiddle();
twiddle(4);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fs, disk_block),
block_size, fp->f_buf, &fp->f_buf_size);
@ -365,7 +365,7 @@ buf_write_file(f, buf_p, size_p)
* Write the block out to storage.
*/
twiddle();
twiddle(4);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
fsbtodb(fs, disk_block),
block_size, fp->f_buf, &fp->f_buf_size);
@ -406,7 +406,7 @@ buf_read_file(f, buf_p, size_p)
bzero(fp->f_buf, block_size);
fp->f_buf_size = block_size;
} else {
twiddle();
twiddle(4);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fs, disk_block),
block_size, fp->f_buf, &fp->f_buf_size);
@ -515,7 +515,7 @@ ufs_open(upath, f)
/* allocate space and read super block */
fs = malloc(SBLOCKSIZE);
fp->f_fs = fs;
twiddle();
twiddle(1);
/*
* Try reading the superblock in each of its possible locations.
*/
@ -649,7 +649,7 @@ ufs_open(upath, f)
if (rc)
goto out;
twiddle();
twiddle(1);
rc = (f->f_dev->dv_strategy)(f->f_devdata,
F_READ, fsbtodb(fs, disk_block),
fs->fs_bsize, buf, &buf_size);

View File

@ -80,7 +80,7 @@ write(fd, dest, bcount)
return (-1);
}
if (f->f_flags & F_RAW) {
twiddle();
twiddle(4);
errno = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
btodb(f->f_offset), bcount, dest, &resid);
if (errno)

View File

@ -39,6 +39,7 @@ static int cons_set(struct env_var *ev, int flags, const void *value);
static int cons_find(const char *name);
static int cons_check(const char *string);
static void cons_change(const char *string);
static int twiddle_set(struct env_var *ev, int flags, const void *value);
/*
* Detect possible console(s) to use. If preferred console(s) have been
@ -52,6 +53,9 @@ cons_probe(void)
int active;
char *prefconsole;
/* We want a callback to install the new value when this var changes. */
env_setenv("twiddle_divisor", EV_VOLATILE, "1", twiddle_set, env_nounset);
/* Do all console probes */
for (cons = 0; consoles[cons] != NULL; cons++) {
consoles[cons]->c_flags = 0;
@ -232,3 +236,28 @@ cons_change(const char *string)
free(dup);
}
/*
* Change the twiddle divisor.
*
* The user can set the twiddle_divisor variable to directly control how fast
* the progress twiddle spins, useful for folks with slow serial consoles. The
* code to monitor changes to the variable and propagate them to the twiddle
* routines has to live somewhere. Twiddling is console-related so it's here.
*/
static int
twiddle_set(struct env_var *ev, int flags, const void *value)
{
u_long tdiv;
char * eptr;
tdiv = strtoul(value, &eptr, 0);
if (*(const char *)value == 0 || *eptr != 0) {
printf("invalid twiddle_divisor '%s'\n", (const char *)value);
return (CMD_ERROR);
}
twiddle_divisor((u_int)tdiv);
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
return(CMD_OK);
}

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 1, 2013
.Dd December 22, 2014
.Dt LOADER 8
.Os
.Sh NAME
@ -670,6 +670,12 @@ Overrides the compile-time set value of
.Dv TCBHASHSIZE
or the preset default of 512.
Must be a power of 2.
.It Va twiddle_divisor
Throttles the output of the `twiddle' I/O progress indicator displayed
while loading the kernel and modules.
This is useful on slow serial consoles where the time spent waiting for
these characters to be written can add up to many seconds.
The default is 1 (full speed); a value of 2 spins half as fast, and so on.
.It Va vm.kmem_size
Sets the size of kernel memory (bytes).
This overrides the value determined when the kernel was compiled.

View File

@ -75,6 +75,7 @@ module_path="/boot/modules" # Set the module search path
# the block size is set to 512. If the value
# is out of range ( < 8 || > 9008 ) an error is
# returned.
#twiddle_divisor="1" # >1 means slow down the progress indicator.
##############################################################