From 07b409ff9a2b4594b01fad3b6c53adbec2d31ad7 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 11 Oct 2012 13:23:24 +0000 Subject: sparsify: Re-use progress bar wrapper code from virt-resize. The code was identical -- just copied with s/resize/sparsify/. Instead of duplicating identical code, cause the Makefile.am to use the code from the ../resize/ directory. Unfortunately because there are two Utils modules (which are different), this means we had to rename those modules to Resize_utils and Sparsify_utils respectively. So this is a rather larger change than intended. However it's just code motion. (cherry picked from commit 91b2238fc8e462c02f697f0c053043a55f43c13d) --- .gitignore | 2 +- po/POTFILES | 1 - po/POTFILES-ml | 7 +- resize/Makefile.am | 12 +-- resize/progress.ml | 2 - resize/resize.ml | 2 +- resize/resize_utils.ml | 172 +++++++++++++++++++++++++++++++++++++++++++ resize/resize_utils_tests.ml | 87 ++++++++++++++++++++++ resize/utils.ml | 172 ------------------------------------------- resize/utils_tests.ml | 87 ---------------------- sparsify/Makefile.am | 13 ++-- sparsify/progress-c.c | 105 -------------------------- sparsify/progress.ml | 54 -------------- sparsify/progress.mli | 19 ----- sparsify/sparsify.ml | 2 +- sparsify/sparsify_utils.ml | 154 ++++++++++++++++++++++++++++++++++++++ sparsify/utils.ml | 154 -------------------------------------- 17 files changed, 430 insertions(+), 615 deletions(-) create mode 100644 resize/resize_utils.ml create mode 100644 resize/resize_utils_tests.ml delete mode 100644 resize/utils.ml delete mode 100644 resize/utils_tests.ml delete mode 100644 sparsify/progress-c.c delete mode 100644 sparsify/progress.ml delete mode 100644 sparsify/progress.mli create mode 100644 sparsify/sparsify_utils.ml delete mode 100644 sparsify/utils.ml diff --git a/.gitignore b/.gitignore index 4ef05fe9..86fa6072 100644 --- a/.gitignore +++ b/.gitignore @@ -313,8 +313,8 @@ Makefile.in /rescue/virt-rescue.1 /resize/.depend /resize/resize_gettext.ml +/resize/resize_utils_tests /resize/stamp-virt-resize.pod -/resize/utils_tests /resize/virt-resize /resize/virt-resize.1 /ruby/bindtests.rb diff --git a/po/POTFILES b/po/POTFILES index 30aff56b..2ad2eb37 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -186,7 +186,6 @@ python/guestfs-py.c rescue/virt-rescue.c resize/progress-c.c ruby/ext/guestfs/_guestfs.c -sparsify/progress-c.c src/actions.c src/appliance.c src/bindtests.c diff --git a/po/POTFILES-ml b/po/POTFILES-ml index 5d5abace..8deeeaa3 100644 --- a/po/POTFILES-ml +++ b/po/POTFILES-ml @@ -1,12 +1,11 @@ resize/progress.ml resize/resize.ml resize/resize_gettext.ml -resize/utils.ml -resize/utils_tests.ml -sparsify/progress.ml +resize/resize_utils.ml +resize/resize_utils_tests.ml sparsify/sparsify.ml sparsify/sparsify_gettext.ml -sparsify/utils.ml +sparsify/sparsify_utils.ml sysprep/main.ml sysprep/sysprep_gettext.ml sysprep/sysprep_operation.ml diff --git a/resize/Makefile.am b/resize/Makefile.am index 8bb093d2..d9123613 100644 --- a/resize/Makefile.am +++ b/resize/Makefile.am @@ -37,8 +37,8 @@ SOURCES = \ progress.ml \ resize.ml \ resize_gettext.ml \ - utils.ml \ - utils_tests.ml + resize_utils.ml \ + resize_utils_tests.ml if HAVE_OCAML @@ -47,7 +47,7 @@ OBJECTS = \ $(top_builddir)/fish/guestfish-progress.o \ progress-c.o \ resize_gettext.cmx \ - utils.cmx \ + resize_utils.cmx \ progress.cmx \ resize.cmx @@ -103,9 +103,9 @@ CLEANFILES += stamp-virt-resize.pod # Tests. -check_SCRIPTS = utils_tests +check_SCRIPTS = resize_utils_tests -utils_tests: resize_gettext.cmx utils.cmx utils_tests.cmx +resize_utils_tests: resize_gettext.cmx resize_utils.cmx resize_utils_tests.cmx $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) \ mlguestfs.cmxa -linkpkg $^ -cclib -lncurses -o $@ @@ -115,7 +115,7 @@ TESTS_ENVIRONMENT = \ MALLOC_PERTURB_=$(random_val) \ $(top_builddir)/run -TESTS = utils_tests +TESTS = resize_utils_tests if ENABLE_APPLIANCE TESTS += test-virt-resize.sh endif diff --git a/resize/progress.ml b/resize/progress.ml index e4fd47e0..993a0b7d 100644 --- a/resize/progress.ml +++ b/resize/progress.ml @@ -18,8 +18,6 @@ open Printf -open Utils - module G = Guestfs type progress_bar diff --git a/resize/resize.ml b/resize/resize.ml index 23c5101b..cec73b3c 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -22,7 +22,7 @@ open Resize_gettext.Gettext module G = Guestfs -open Utils +open Resize_utils (* Minimum surplus before we create an extra partition. *) let min_extra_partition = 10L *^ 1024L *^ 1024L diff --git a/resize/resize_utils.ml b/resize/resize_utils.ml new file mode 100644 index 00000000..d99f489b --- /dev/null +++ b/resize/resize_utils.ml @@ -0,0 +1,172 @@ +(* virt-resize + * Copyright (C) 2010-2012 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. + *) + +open Printf + +open Resize_gettext.Gettext + +module G = Guestfs + +let ( +^ ) = Int64.add +let ( -^ ) = Int64.sub +let ( *^ ) = Int64.mul +let ( /^ ) = Int64.div +let ( &^ ) = Int64.logand +let ( ~^ ) = Int64.lognot + +let int_of_le32 str = + assert (String.length str = 4); + let c0 = Char.code (String.unsafe_get str 0) in + let c1 = Char.code (String.unsafe_get str 1) in + let c2 = Char.code (String.unsafe_get str 2) in + let c3 = Char.code (String.unsafe_get str 3) in + Int64.of_int c0 +^ + (Int64.shift_left (Int64.of_int c1) 8) +^ + (Int64.shift_left (Int64.of_int c2) 16) +^ + (Int64.shift_left (Int64.of_int c3) 24) + +let le32_of_int i = + let c0 = i &^ 0xffL in + let c1 = Int64.shift_right (i &^ 0xff00L) 8 in + let c2 = Int64.shift_right (i &^ 0xff0000L) 16 in + let c3 = Int64.shift_right (i &^ 0xff000000L) 24 in + let s = String.create 4 in + String.unsafe_set s 0 (Char.unsafe_chr (Int64.to_int c0)); + String.unsafe_set s 1 (Char.unsafe_chr (Int64.to_int c1)); + String.unsafe_set s 2 (Char.unsafe_chr (Int64.to_int c2)); + String.unsafe_set s 3 (Char.unsafe_chr (Int64.to_int c3)); + s + +let output_spaces chan n = for i = 0 to n-1 do output_char chan ' ' done + +let wrap ?(chan = stdout) ?(hanging = 0) str = + let rec _wrap col str = + let n = String.length str in + let i = try String.index str ' ' with Not_found -> n in + let col = + if col+i >= 72 then ( + output_char chan '\n'; + output_spaces chan hanging; + i+hanging+1 + ) else col+i+1 in + output_string chan (String.sub str 0 i); + if i < n then ( + output_char chan ' '; + _wrap col (String.sub str (i+1) (n-(i+1))) + ) + in + _wrap 0 str + +let error fs = + let display str = + wrap ~chan:stderr (s_"virt-resize: error: " ^ str); + prerr_newline (); + prerr_newline (); + wrap ~chan:stderr + (s_"If reporting bugs, run virt-resize with the '-d' option and include the complete output."); + prerr_newline (); + exit 1 + in + ksprintf display fs + +(* The reverse of device name translation, see + * BLOCK DEVICE NAMING in guestfs(3). + *) +let canonicalize dev = + if String.length dev >= 8 && + dev.[0] = '/' && dev.[1] = 'd' && dev.[2] = 'e' && dev.[3] = 'v' && + dev.[4] = '/' && (dev.[5] = 'h' || dev.[5] = 'v') && dev.[6] = 'd' then ( + let dev = String.copy dev in + dev.[5] <- 's'; + dev + ) + else + dev + +let feature_available (g : Guestfs.guestfs) names = + try g#available names; true + with G.Error _ -> false + +(* Parse the size field from --resize and --resize-force options. *) +let parse_size = + let const_re = Str.regexp "^\\([.0-9]+\\)\\([bKMG]\\)$" + and plus_const_re = Str.regexp "^\\+\\([.0-9]+\\)\\([bKMG]\\)$" + and minus_const_re = Str.regexp "^-\\([.0-9]+\\)\\([bKMG]\\)$" + and percent_re = Str.regexp "^\\([.0-9]+\\)%$" + and plus_percent_re = Str.regexp "^\\+\\([.0-9]+\\)%$" + and minus_percent_re = Str.regexp "^-\\([.0-9]+\\)%$" + in + fun oldsize field -> + let matches rex = Str.string_match rex field 0 in + let sub i = Str.matched_group i field in + let size_scaled f = function + | "b" -> Int64.of_float f + | "K" -> Int64.of_float (f *. 1024.) + | "M" -> Int64.of_float (f *. 1024. *. 1024.) + | "G" -> Int64.of_float (f *. 1024. *. 1024. *. 1024.) + | _ -> assert false + in + + if matches const_re then ( + size_scaled (float_of_string (sub 1)) (sub 2) + ) + else if matches plus_const_re then ( + let incr = size_scaled (float_of_string (sub 1)) (sub 2) in + oldsize +^ incr + ) + else if matches minus_const_re then ( + let incr = size_scaled (float_of_string (sub 1)) (sub 2) in + oldsize -^ incr + ) + else if matches percent_re then ( + let percent = Int64.of_float (10. *. float_of_string (sub 1)) in + oldsize *^ percent /^ 1000L + ) + else if matches plus_percent_re then ( + let percent = Int64.of_float (10. *. float_of_string (sub 1)) in + oldsize +^ oldsize *^ percent /^ 1000L + ) + else if matches minus_percent_re then ( + let percent = Int64.of_float (10. *. float_of_string (sub 1)) in + oldsize -^ oldsize *^ percent /^ 1000L + ) + else + error "virt-resize: %s: cannot parse size field" field + +let human_size i = + let sign, i = if i < 0L then "-", Int64.neg i else "", i in + + if i < 1024L then + sprintf "%s%Ld" sign i + else ( + let f = Int64.to_float i /. 1024. in + let i = i /^ 1024L in + if i < 1024L then + sprintf "%s%.1fK" sign f + else ( + let f = Int64.to_float i /. 1024. in + let i = i /^ 1024L in + if i < 1024L then + sprintf "%s%.1fM" sign f + else ( + let f = Int64.to_float i /. 1024. in + (*let i = i /^ 1024L in*) + sprintf "%s%.1fG" sign f + ) + ) + ) diff --git a/resize/resize_utils_tests.ml b/resize/resize_utils_tests.ml new file mode 100644 index 00000000..2d4b816e --- /dev/null +++ b/resize/resize_utils_tests.ml @@ -0,0 +1,87 @@ +(* virt-resize + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *) + +(* This file tests the Resize_utils module. *) + +open Resize_utils + +(* Test Resize_utils.int_of_le32 and Resize_utils.le32_of_int. *) +let () = + assert (int_of_le32 "\x80\x60\x40\x20" = 0x20406080L); + assert (le32_of_int 0x20406080L = "\x80\x60\x40\x20") + +(* Test Resize_utils.canonicalize. *) +let () = + assert (canonicalize "/dev/vda" = "/dev/sda"); + assert (canonicalize "/dev/hda3" = "/dev/sda3"); + assert (canonicalize "/dev/sda4" = "/dev/sda4"); + assert (canonicalize "/dev/hdaa" = "/dev/sdaa"); + assert (canonicalize "/dev/sdaa" = "/dev/sdaa"); + assert (canonicalize "/dev/cciss/c0d0p1" = "/dev/cciss/c0d0p1") + +(* Test Resize_utils.parse_size. *) +let () = + (* For absolute sizes, oldsize is ignored. *) + assert (parse_size 100_L "100b" = 100_L); + assert (parse_size 1000_L "100b" = 100_L); + assert (parse_size 10000_L "100b" = 100_L); + assert (parse_size 100_L "100K" = 102400_L); + (* Fractions are always rounded down. *) + assert (parse_size 100_L "1.1K" = 1126_L); + assert (parse_size 100_L "100.1M" = 104962457_L); + assert (parse_size 100_L "123.4G" = 132499741081_L); + + (* oldsize +/- a constant. *) + assert (parse_size 100_L "+1b" = 101_L); + assert (parse_size 100_L "-2b" = 98_L); + assert (parse_size 100_L "+1K" = 1124_L); + assert (parse_size 1024_L "-1K" = 0_L); + assert (parse_size 1126_L "-1.1K" = 0_L); + assert (parse_size 1024_L "+1.1M" = 1154457_L); + assert (parse_size 132499741081_L "-123.3G" = 107374182_L); + + (* oldsize +/- a percentage. *) + assert (parse_size 100_L "+1%" = 101_L); + assert (parse_size 100_L "-1%" = 99_L); + assert (parse_size 100000_L "+1%" = 101000_L); + assert (parse_size 100000_L "-1%" = 99000_L); + assert (parse_size 100000_L "+50%" = 150000_L); + assert (parse_size 100000_L "-50%" = 50000_L); + assert (parse_size 100000_L "+100%" = 200000_L); + assert (parse_size 100000_L "-100%" = 0_L); + assert (parse_size 100000_L "+200%" = 300000_L); + assert (parse_size 100000_L "+300%" = 400000_L); + + (* Implementation rounds numbers so that only a single digit after + * the decimal point is significant. + *) + assert (parse_size 100000_L "+1.1%" = 101100_L); + assert (parse_size 100000_L "+1.12%" = 101100_L) + +(* Test Resize_utils.human_size. *) +let () = + assert (human_size 100_L = "100"); + assert (human_size (-100_L) = "-100"); + assert (human_size 1024_L = "1.0K"); + assert (human_size (-1024_L) = "-1.0K"); + assert (human_size 1126_L = "1.1K"); + assert (human_size (-1126_L) = "-1.1K"); + assert (human_size 1363149_L = "1.3M"); + assert (human_size (-1363149_L) = "-1.3M"); + assert (human_size 3650722201_L = "3.4G"); + assert (human_size (-3650722201_L) = "-3.4G") diff --git a/resize/utils.ml b/resize/utils.ml deleted file mode 100644 index d99f489b..00000000 --- a/resize/utils.ml +++ /dev/null @@ -1,172 +0,0 @@ -(* virt-resize - * Copyright (C) 2010-2012 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. - *) - -open Printf - -open Resize_gettext.Gettext - -module G = Guestfs - -let ( +^ ) = Int64.add -let ( -^ ) = Int64.sub -let ( *^ ) = Int64.mul -let ( /^ ) = Int64.div -let ( &^ ) = Int64.logand -let ( ~^ ) = Int64.lognot - -let int_of_le32 str = - assert (String.length str = 4); - let c0 = Char.code (String.unsafe_get str 0) in - let c1 = Char.code (String.unsafe_get str 1) in - let c2 = Char.code (String.unsafe_get str 2) in - let c3 = Char.code (String.unsafe_get str 3) in - Int64.of_int c0 +^ - (Int64.shift_left (Int64.of_int c1) 8) +^ - (Int64.shift_left (Int64.of_int c2) 16) +^ - (Int64.shift_left (Int64.of_int c3) 24) - -let le32_of_int i = - let c0 = i &^ 0xffL in - let c1 = Int64.shift_right (i &^ 0xff00L) 8 in - let c2 = Int64.shift_right (i &^ 0xff0000L) 16 in - let c3 = Int64.shift_right (i &^ 0xff000000L) 24 in - let s = String.create 4 in - String.unsafe_set s 0 (Char.unsafe_chr (Int64.to_int c0)); - String.unsafe_set s 1 (Char.unsafe_chr (Int64.to_int c1)); - String.unsafe_set s 2 (Char.unsafe_chr (Int64.to_int c2)); - String.unsafe_set s 3 (Char.unsafe_chr (Int64.to_int c3)); - s - -let output_spaces chan n = for i = 0 to n-1 do output_char chan ' ' done - -let wrap ?(chan = stdout) ?(hanging = 0) str = - let rec _wrap col str = - let n = String.length str in - let i = try String.index str ' ' with Not_found -> n in - let col = - if col+i >= 72 then ( - output_char chan '\n'; - output_spaces chan hanging; - i+hanging+1 - ) else col+i+1 in - output_string chan (String.sub str 0 i); - if i < n then ( - output_char chan ' '; - _wrap col (String.sub str (i+1) (n-(i+1))) - ) - in - _wrap 0 str - -let error fs = - let display str = - wrap ~chan:stderr (s_"virt-resize: error: " ^ str); - prerr_newline (); - prerr_newline (); - wrap ~chan:stderr - (s_"If reporting bugs, run virt-resize with the '-d' option and include the complete output."); - prerr_newline (); - exit 1 - in - ksprintf display fs - -(* The reverse of device name translation, see - * BLOCK DEVICE NAMING in guestfs(3). - *) -let canonicalize dev = - if String.length dev >= 8 && - dev.[0] = '/' && dev.[1] = 'd' && dev.[2] = 'e' && dev.[3] = 'v' && - dev.[4] = '/' && (dev.[5] = 'h' || dev.[5] = 'v') && dev.[6] = 'd' then ( - let dev = String.copy dev in - dev.[5] <- 's'; - dev - ) - else - dev - -let feature_available (g : Guestfs.guestfs) names = - try g#available names; true - with G.Error _ -> false - -(* Parse the size field from --resize and --resize-force options. *) -let parse_size = - let const_re = Str.regexp "^\\([.0-9]+\\)\\([bKMG]\\)$" - and plus_const_re = Str.regexp "^\\+\\([.0-9]+\\)\\([bKMG]\\)$" - and minus_const_re = Str.regexp "^-\\([.0-9]+\\)\\([bKMG]\\)$" - and percent_re = Str.regexp "^\\([.0-9]+\\)%$" - and plus_percent_re = Str.regexp "^\\+\\([.0-9]+\\)%$" - and minus_percent_re = Str.regexp "^-\\([.0-9]+\\)%$" - in - fun oldsize field -> - let matches rex = Str.string_match rex field 0 in - let sub i = Str.matched_group i field in - let size_scaled f = function - | "b" -> Int64.of_float f - | "K" -> Int64.of_float (f *. 1024.) - | "M" -> Int64.of_float (f *. 1024. *. 1024.) - | "G" -> Int64.of_float (f *. 1024. *. 1024. *. 1024.) - | _ -> assert false - in - - if matches const_re then ( - size_scaled (float_of_string (sub 1)) (sub 2) - ) - else if matches plus_const_re then ( - let incr = size_scaled (float_of_string (sub 1)) (sub 2) in - oldsize +^ incr - ) - else if matches minus_const_re then ( - let incr = size_scaled (float_of_string (sub 1)) (sub 2) in - oldsize -^ incr - ) - else if matches percent_re then ( - let percent = Int64.of_float (10. *. float_of_string (sub 1)) in - oldsize *^ percent /^ 1000L - ) - else if matches plus_percent_re then ( - let percent = Int64.of_float (10. *. float_of_string (sub 1)) in - oldsize +^ oldsize *^ percent /^ 1000L - ) - else if matches minus_percent_re then ( - let percent = Int64.of_float (10. *. float_of_string (sub 1)) in - oldsize -^ oldsize *^ percent /^ 1000L - ) - else - error "virt-resize: %s: cannot parse size field" field - -let human_size i = - let sign, i = if i < 0L then "-", Int64.neg i else "", i in - - if i < 1024L then - sprintf "%s%Ld" sign i - else ( - let f = Int64.to_float i /. 1024. in - let i = i /^ 1024L in - if i < 1024L then - sprintf "%s%.1fK" sign f - else ( - let f = Int64.to_float i /. 1024. in - let i = i /^ 1024L in - if i < 1024L then - sprintf "%s%.1fM" sign f - else ( - let f = Int64.to_float i /. 1024. in - (*let i = i /^ 1024L in*) - sprintf "%s%.1fG" sign f - ) - ) - ) diff --git a/resize/utils_tests.ml b/resize/utils_tests.ml deleted file mode 100644 index 9356d7b6..00000000 --- a/resize/utils_tests.ml +++ /dev/null @@ -1,87 +0,0 @@ -(* virt-resize - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - -(* This file tests the Utils module. *) - -open Utils - -(* Test Utils.int_of_le32 and Utils.le32_of_int. *) -let () = - assert (int_of_le32 "\x80\x60\x40\x20" = 0x20406080L); - assert (le32_of_int 0x20406080L = "\x80\x60\x40\x20") - -(* Test Utils.canonicalize. *) -let () = - assert (canonicalize "/dev/vda" = "/dev/sda"); - assert (canonicalize "/dev/hda3" = "/dev/sda3"); - assert (canonicalize "/dev/sda4" = "/dev/sda4"); - assert (canonicalize "/dev/hdaa" = "/dev/sdaa"); - assert (canonicalize "/dev/sdaa" = "/dev/sdaa"); - assert (canonicalize "/dev/cciss/c0d0p1" = "/dev/cciss/c0d0p1") - -(* Test Utils.parse_size. *) -let () = - (* For absolute sizes, oldsize is ignored. *) - assert (parse_size 100_L "100b" = 100_L); - assert (parse_size 1000_L "100b" = 100_L); - assert (parse_size 10000_L "100b" = 100_L); - assert (parse_size 100_L "100K" = 102400_L); - (* Fractions are always rounded down. *) - assert (parse_size 100_L "1.1K" = 1126_L); - assert (parse_size 100_L "100.1M" = 104962457_L); - assert (parse_size 100_L "123.4G" = 132499741081_L); - - (* oldsize +/- a constant. *) - assert (parse_size 100_L "+1b" = 101_L); - assert (parse_size 100_L "-2b" = 98_L); - assert (parse_size 100_L "+1K" = 1124_L); - assert (parse_size 1024_L "-1K" = 0_L); - assert (parse_size 1126_L "-1.1K" = 0_L); - assert (parse_size 1024_L "+1.1M" = 1154457_L); - assert (parse_size 132499741081_L "-123.3G" = 107374182_L); - - (* oldsize +/- a percentage. *) - assert (parse_size 100_L "+1%" = 101_L); - assert (parse_size 100_L "-1%" = 99_L); - assert (parse_size 100000_L "+1%" = 101000_L); - assert (parse_size 100000_L "-1%" = 99000_L); - assert (parse_size 100000_L "+50%" = 150000_L); - assert (parse_size 100000_L "-50%" = 50000_L); - assert (parse_size 100000_L "+100%" = 200000_L); - assert (parse_size 100000_L "-100%" = 0_L); - assert (parse_size 100000_L "+200%" = 300000_L); - assert (parse_size 100000_L "+300%" = 400000_L); - - (* Implementation rounds numbers so that only a single digit after - * the decimal point is significant. - *) - assert (parse_size 100000_L "+1.1%" = 101100_L); - assert (parse_size 100000_L "+1.12%" = 101100_L) - -(* Test Utils.human_size. *) -let () = - assert (human_size 100_L = "100"); - assert (human_size (-100_L) = "-100"); - assert (human_size 1024_L = "1.0K"); - assert (human_size (-1024_L) = "-1.0K"); - assert (human_size 1126_L = "1.1K"); - assert (human_size (-1126_L) = "-1.1K"); - assert (human_size 1363149_L = "1.3M"); - assert (human_size (-1363149_L) = "-1.3M"); - assert (human_size 3650722201_L = "3.4G"); - assert (human_size (-3650722201_L) = "-3.4G") diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am index e037adae..d2a4d8e7 100644 --- a/sparsify/Makefile.am +++ b/sparsify/Makefile.am @@ -32,22 +32,19 @@ CLEANFILES = *~ *.cmi *.cmo *.cmx *.cmxa *.o virt-sparsify test.img # Alphabetical order. SOURCES = \ - progress-c.c \ - progress.mli \ - progress.ml \ sparsify.ml \ sparsify_gettext.ml \ - utils.ml + sparsify_utils.ml if HAVE_OCAML # Note this list must be in dependency order. OBJECTS = \ $(top_builddir)/fish/guestfish-progress.o \ - progress-c.o \ + $(top_builddir)/resize/progress-c.o \ sparsify_gettext.cmx \ - utils.cmx \ - progress.cmx \ + sparsify_utils.cmx \ + $(top_builddir)/resize/progress.cmx \ sparsify.cmx bin_SCRIPTS = virt-sparsify @@ -55,7 +52,7 @@ bin_SCRIPTS = virt-sparsify # -I $(top_builddir)/src/.libs is a hack which forces corresponding -L # option to be passed to gcc, so we don't try linking against an # installed copy of libguestfs. -OCAMLPACKAGES = -package unix -I $(top_builddir)/src/.libs -I $(top_builddir)/ocaml +OCAMLPACKAGES = -package unix -I $(top_builddir)/src/.libs -I $(top_builddir)/ocaml -I $(top_builddir)/resize if HAVE_OCAML_PKG_GETTEXT OCAMLPACKAGES += -package gettext-stub endif diff --git a/sparsify/progress-c.c b/sparsify/progress-c.c deleted file mode 100644 index 81137289..00000000 --- a/sparsify/progress-c.c +++ /dev/null @@ -1,105 +0,0 @@ -/* virt-sparsify - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#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_sparsify_progress_bar_init (value machine_readablev) -{ - CAMLparam1 (machine_readablev); - CAMLlocal1 (barv); - struct progress_bar *bar; - int machine_readable = Bool_val (machine_readablev); - unsigned flags = 0; - - /* XXX Have to do this to get nl_langinfo to work properly. However - * we should really only call this from main. - */ - setlocale (LC_ALL, ""); - - if (machine_readable) - flags |= PROGRESS_BAR_MACHINE_READABLE; - bar = progress_bar_init (flags); - 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_sparsify_progress_bar_reset (value barv) -{ - CAMLparam1 (barv); - struct progress_bar *bar = Bar_val (barv); - - progress_bar_reset (bar); - - CAMLreturn (Val_unit); -} - -value -virt_sparsify_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); -} diff --git a/sparsify/progress.ml b/sparsify/progress.ml deleted file mode 100644 index f925a9c6..00000000 --- a/sparsify/progress.ml +++ /dev/null @@ -1,54 +0,0 @@ -(* virt-sparsify - * Copyright (C) 2010-2012 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. - *) - -open Printf - -open Utils - -module G = Guestfs - -type progress_bar -external progress_bar_init : machine_readable:bool -> progress_bar - = "virt_sparsify_progress_bar_init" -external progress_bar_reset : progress_bar -> unit - = "virt_sparsify_progress_bar_reset" -external progress_bar_set : progress_bar -> int64 -> int64 -> unit - = "virt_sparsify_progress_bar_set" - -let set_up_progress_bar ?(machine_readable = false) (g : Guestfs.guestfs) = - (* Initialize the C mini library. *) - let bar = progress_bar_init ~machine_readable in - - (* 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 - in - - (* 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 - ) - in - - ignore (g#set_event_callback enter_callback [G.EVENT_ENTER]); - ignore (g#set_event_callback progress_callback [G.EVENT_PROGRESS]) diff --git a/sparsify/progress.mli b/sparsify/progress.mli deleted file mode 100644 index 677df677..00000000 --- a/sparsify/progress.mli +++ /dev/null @@ -1,19 +0,0 @@ -(* virt-sparsify - * Copyright (C) 2010-2012 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 : ?machine_readable:bool -> Guestfs.guestfs -> unit diff --git a/sparsify/sparsify.ml b/sparsify/sparsify.ml index f7a1d561..ccece63b 100644 --- a/sparsify/sparsify.ml +++ b/sparsify/sparsify.ml @@ -23,7 +23,7 @@ open Sparsify_gettext.Gettext module G = Guestfs -open Utils +open Sparsify_utils let () = Random.self_init () diff --git a/sparsify/sparsify_utils.ml b/sparsify/sparsify_utils.ml new file mode 100644 index 00000000..dd27ba88 --- /dev/null +++ b/sparsify/sparsify_utils.ml @@ -0,0 +1,154 @@ +(* virt-sparsify + * Copyright (C) 2010-2012 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. + *) + +(* XXX This was copied from virt-resize, and probably some of the + functions here are not used in virt-sparsify and could be + deleted. *) + +open Printf + +open Sparsify_gettext.Gettext + +module G = Guestfs + +let (//) = Filename.concat + +let ( +^ ) = Int64.add +let ( -^ ) = Int64.sub +let ( *^ ) = Int64.mul +let ( /^ ) = Int64.div +let ( &^ ) = Int64.logand +let ( ~^ ) = Int64.lognot + +let output_spaces chan n = for i = 0 to n-1 do output_char chan ' ' done + +let wrap ?(chan = stdout) ?(hanging = 0) str = + let rec _wrap col str = + let n = String.length str in + let i = try String.index str ' ' with Not_found -> n in + let col = + if col+i >= 72 then ( + output_char chan '\n'; + output_spaces chan hanging; + i+hanging+1 + ) else col+i+1 in + output_string chan (String.sub str 0 i); + if i < n then ( + output_char chan ' '; + _wrap col (String.sub str (i+1) (n-(i+1))) + ) + in + _wrap 0 str + +let string_prefix str prefix = + let n = String.length prefix in + String.length str >= n && String.sub str 0 n = prefix + +let rec string_find s sub = + let len = String.length s in + let sublen = String.length sub in + let rec loop i = + if i <= len-sublen then ( + let rec loop2 j = + if j < sublen then ( + if s.[i+j] = sub.[j] then loop2 (j+1) + else -1 + ) else + i (* found *) + in + let r = loop2 0 in + if r = -1 then loop (i+1) else r + ) else + -1 (* not found *) + in + loop 0 + +let rec replace_str s s1 s2 = + let len = String.length s in + let sublen = String.length s1 in + let i = string_find s s1 in + if i = -1 then s + else ( + let s' = String.sub s 0 i in + let s'' = String.sub s (i+sublen) (len-i-sublen) in + s' ^ s2 ^ replace_str s'' s1 s2 + ) +let string_random8 = + let chars = "abcdefghijklmnopqrstuvwxyz0123456789" in + fun () -> + String.concat "" ( + List.map ( + fun _ -> + let c = Random.int 36 in + let c = chars.[c] in + String.make 1 c + ) [1;2;3;4;5;6;7;8] + ) + +let error fs = + let display str = + wrap ~chan:stderr ("virt-sparsify: error: " ^ str); + prerr_newline (); + prerr_newline (); + wrap ~chan:stderr + (s_"If reporting bugs, run virt-sparsify with the '-v' and '-x' options and include the complete output."); + prerr_newline (); + exit 1 + in + ksprintf display fs + +(* The reverse of device name translation, see + * BLOCK DEVICE NAMING in guestfs(3). + *) +let canonicalize dev = + if String.length dev >= 8 && + dev.[0] = '/' && dev.[1] = 'd' && dev.[2] = 'e' && dev.[3] = 'v' && + dev.[4] = '/' && (dev.[5] = 'h' || dev.[5] = 'v') && dev.[6] = 'd' then ( + let dev = String.copy dev in + dev.[5] <- 's'; + dev + ) + else + dev + +let feature_available (g : Guestfs.guestfs) names = + try g#available names; true + with G.Error _ -> false + +let human_size i = + let sign, i = if i < 0L then "-", Int64.neg i else "", i in + + if i < 1024L then + sprintf "%s%Ld" sign i + else ( + let f = Int64.to_float i /. 1024. in + let i = i /^ 1024L in + if i < 1024L then + sprintf "%s%.1fK" sign f + else ( + let f = Int64.to_float i /. 1024. in + let i = i /^ 1024L in + if i < 1024L then + sprintf "%s%.1fM" sign f + else ( + let f = Int64.to_float i /. 1024. in + (*let i = i /^ 1024L in*) + sprintf "%s%.1fG" sign f + ) + ) + ) diff --git a/sparsify/utils.ml b/sparsify/utils.ml deleted file mode 100644 index dd27ba88..00000000 --- a/sparsify/utils.ml +++ /dev/null @@ -1,154 +0,0 @@ -(* virt-sparsify - * Copyright (C) 2010-2012 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. - *) - -(* XXX This was copied from virt-resize, and probably some of the - functions here are not used in virt-sparsify and could be - deleted. *) - -open Printf - -open Sparsify_gettext.Gettext - -module G = Guestfs - -let (//) = Filename.concat - -let ( +^ ) = Int64.add -let ( -^ ) = Int64.sub -let ( *^ ) = Int64.mul -let ( /^ ) = Int64.div -let ( &^ ) = Int64.logand -let ( ~^ ) = Int64.lognot - -let output_spaces chan n = for i = 0 to n-1 do output_char chan ' ' done - -let wrap ?(chan = stdout) ?(hanging = 0) str = - let rec _wrap col str = - let n = String.length str in - let i = try String.index str ' ' with Not_found -> n in - let col = - if col+i >= 72 then ( - output_char chan '\n'; - output_spaces chan hanging; - i+hanging+1 - ) else col+i+1 in - output_string chan (String.sub str 0 i); - if i < n then ( - output_char chan ' '; - _wrap col (String.sub str (i+1) (n-(i+1))) - ) - in - _wrap 0 str - -let string_prefix str prefix = - let n = String.length prefix in - String.length str >= n && String.sub str 0 n = prefix - -let rec string_find s sub = - let len = String.length s in - let sublen = String.length sub in - let rec loop i = - if i <= len-sublen then ( - let rec loop2 j = - if j < sublen then ( - if s.[i+j] = sub.[j] then loop2 (j+1) - else -1 - ) else - i (* found *) - in - let r = loop2 0 in - if r = -1 then loop (i+1) else r - ) else - -1 (* not found *) - in - loop 0 - -let rec replace_str s s1 s2 = - let len = String.length s in - let sublen = String.length s1 in - let i = string_find s s1 in - if i = -1 then s - else ( - let s' = String.sub s 0 i in - let s'' = String.sub s (i+sublen) (len-i-sublen) in - s' ^ s2 ^ replace_str s'' s1 s2 - ) -let string_random8 = - let chars = "abcdefghijklmnopqrstuvwxyz0123456789" in - fun () -> - String.concat "" ( - List.map ( - fun _ -> - let c = Random.int 36 in - let c = chars.[c] in - String.make 1 c - ) [1;2;3;4;5;6;7;8] - ) - -let error fs = - let display str = - wrap ~chan:stderr ("virt-sparsify: error: " ^ str); - prerr_newline (); - prerr_newline (); - wrap ~chan:stderr - (s_"If reporting bugs, run virt-sparsify with the '-v' and '-x' options and include the complete output."); - prerr_newline (); - exit 1 - in - ksprintf display fs - -(* The reverse of device name translation, see - * BLOCK DEVICE NAMING in guestfs(3). - *) -let canonicalize dev = - if String.length dev >= 8 && - dev.[0] = '/' && dev.[1] = 'd' && dev.[2] = 'e' && dev.[3] = 'v' && - dev.[4] = '/' && (dev.[5] = 'h' || dev.[5] = 'v') && dev.[6] = 'd' then ( - let dev = String.copy dev in - dev.[5] <- 's'; - dev - ) - else - dev - -let feature_available (g : Guestfs.guestfs) names = - try g#available names; true - with G.Error _ -> false - -let human_size i = - let sign, i = if i < 0L then "-", Int64.neg i else "", i in - - if i < 1024L then - sprintf "%s%Ld" sign i - else ( - let f = Int64.to_float i /. 1024. in - let i = i /^ 1024L in - if i < 1024L then - sprintf "%s%.1fK" sign f - else ( - let f = Int64.to_float i /. 1024. in - let i = i /^ 1024L in - if i < 1024L then - sprintf "%s%.1fM" sign f - else ( - let f = Int64.to_float i /. 1024. in - (*let i = i /^ 1024L in*) - sprintf "%s%.1fG" sign f - ) - ) - ) -- cgit