resize: Use guestfish progress bar mini-library.

There are two benefits:

 - the progress bars look better
 - there is a reasonably accurate estimate of how long each operation
   will take
This commit is contained in:
Richard W.M. Jones
2011-08-26 19:21:23 +01:00
parent 9420eaf44e
commit 2faef37957
6 changed files with 165 additions and 27 deletions

View File

@@ -134,6 +134,7 @@ regressions/test-launch-race.pl
regressions/test-lvm-mapping.pl
regressions/test-noexec-stack.pl
rescue/virt-rescue.c
resize/progress_c.c
ruby/ext/guestfs/_guestfs.c
src/actions.c
src/appliance.c

View File

@@ -1,6 +1,7 @@
progress.cmo: utils.cmo ../ocaml/guestfs.cmi
progress.cmx: utils.cmx ../ocaml/guestfs.cmx
resize.cmo: utils.cmo progress.cmo ../ocaml/guestfs.cmi
progress.cmi: ../ocaml/guestfs.cmi
progress.cmo: utils.cmo ../ocaml/guestfs.cmi progress.cmi
progress.cmx: utils.cmx ../ocaml/guestfs.cmx progress.cmi
resize.cmo: utils.cmo progress.cmi ../ocaml/guestfs.cmi
resize.cmx: utils.cmx progress.cmx ../ocaml/guestfs.cmx
utils.cmo: ../ocaml/guestfs.cmi
utils.cmx: ../ocaml/guestfs.cmx

View File

@@ -29,12 +29,16 @@ if HAVE_OCAML_PCRE
# Alphabetical order.
SOURCES = \
progress_c.c \
progress.mli \
progress.ml \
resize.ml \
utils.ml
# Note this list must be in dependency order.
OBJECTS = \
../fish/guestfish-progress.o \
progress_c.o \
utils.cmx \
progress.cmx \
resize.cmx
@@ -50,7 +54,8 @@ OCAMLCFLAGS = -g -warn-error CDEFLMPSUVYZX $(OCAMLPACKAGES)
OCAMLOPTFLAGS = $(OCAMLCFLAGS)
virt-resize: $(OBJECTS)
$(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) mlguestfs.cmxa -linkpkg $^ -o $@
$(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) \
mlguestfs.cmxa -linkpkg $^ -cclib -lncurses -o $@
.mli.cmi:
$(OCAMLFIND) ocamlc $(OCAMLCFLAGS) -c $< -o $@
@@ -59,6 +64,14 @@ virt-resize: $(OBJECTS)
.ml.cmx:
$(OCAMLFIND) ocamlopt $(OCAMLCFLAGS) -c $< -o $@
# automake will decide we don't need C support in this file. Really
# we do, so we have to provide it ourselves.
DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(shell $(OCAMLC) -where) -I../fish
.c.o:
$(CC) $(CFLAGS) $(PROF_CFLAGS) $(DEFAULT_INCLUDES) -c $< -o $@
# Manual pages and HTML files for the website.
man_MANS = virt-resize.1

View File

@@ -22,28 +22,31 @@ open Utils
module G = Guestfs
type progress_bar
external progress_bar_init : unit -> progress_bar
= "virt_resize_progress_bar_init"
external progress_bar_reset : progress_bar -> unit
= "virt_resize_progress_bar_reset"
external progress_bar_set : progress_bar -> int64 -> int64 -> unit
= "virt_resize_progress_bar_set"
(* Initialize the C mini library. *)
let bar = progress_bar_init ()
(* Reset the progress bar before every libguestfs function. *)
let enter_callback g event evh buf array =
if event = G.EVENT_ENTER then
progress_bar_reset bar
(* A progress event: move the progress bar. *)
let progress_callback g event evh buf array =
if event = G.EVENT_PROGRESS && Array.length array >= 4 then (
let position = array.(2)
and total = array.(3) in
progress_bar_set bar position total
)
let set_up_progress_bar (g : Guestfs.guestfs) =
let progress_callback g event evh buf array =
if event = G.EVENT_PROGRESS && Array.length array >= 4 then (
(*let proc_nr = array.(0)
and serial = array.(1)*)
let position = array.(2)
and total = array.(3) in
let ratio =
if total <> 0L then Int64.to_float position /. Int64.to_float total
else 0. in
let ratio =
if ratio < 0. then 0. else if ratio > 1. then 1. else ratio in
let dots = int_of_float (ratio *. 72.) in
print_string "[";
for i = 0 to dots-1 do print_char '#' done;
for i = dots to 71 do print_char '-' done;
print_string "]\r";
if ratio = 1. then print_string "\n";
flush stdout
)
in
ignore (g#set_event_callback enter_callback [G.EVENT_ENTER]);
ignore (g#set_event_callback progress_callback [G.EVENT_PROGRESS])

19
resize/progress.mli Normal file
View File

@@ -0,0 +1,19 @@
(* virt-resize
* Copyright (C) 2010-2011 Red Hat Inc.
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
val set_up_progress_bar : Guestfs.guestfs -> unit

101
resize/progress_c.c Normal file
View File

@@ -0,0 +1,101 @@
/* virt-resize - interface to progress bar mini library
* Copyright (C) 2011 Red Hat Inc.
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <locale.h>
#include <caml/alloc.h>
#include <caml/custom.h>
#include <caml/fail.h>
#include <caml/memory.h>
#include <caml/mlvalues.h>
#include "progress.h"
#define Bar_val(v) (*((struct progress_bar **)Data_custom_val(v)))
static void
progress_bar_finalize (value barv)
{
struct progress_bar *bar = Bar_val (barv);
if (bar)
progress_bar_free (bar);
}
static struct custom_operations progress_bar_custom_operations = {
(char *) "progress_bar_custom_operations",
progress_bar_finalize,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default
};
value
virt_resize_progress_bar_init (value unitv)
{
CAMLparam1 (unitv);
CAMLlocal1 (barv);
struct progress_bar *bar;
/* XXX Have to do this to get nl_langinfo to work properly. However
* we should really only call this from main.
*/
setlocale (LC_ALL, "");
bar = progress_bar_init (0);
if (bar == NULL)
caml_raise_out_of_memory ();
barv = caml_alloc_custom (&progress_bar_custom_operations,
sizeof (struct progress_bar *), 0, 1);
Bar_val (barv) = bar;
CAMLreturn (barv);
}
value
virt_resize_progress_bar_reset (value barv)
{
CAMLparam1 (barv);
struct progress_bar *bar = Bar_val (barv);
progress_bar_reset (bar);
CAMLreturn (Val_unit);
}
value
virt_resize_progress_bar_set (value barv,
value positionv, value totalv)
{
CAMLparam3 (barv, positionv, totalv);
struct progress_bar *bar = Bar_val (barv);
uint64_t position = Int64_val (positionv);
uint64_t total = Int64_val (totalv);
progress_bar_set (bar, position, total);
CAMLreturn (Val_unit);
}