enable build for ocaml bytecode
by Olaf Hering
This is a first attempt to build libguestfs with just a ocaml bytecode
compiler. The three tools written in ocaml will be build only when an
ocamlopt compiler is available.
Olaf
---
Makefile.am | 5 ++++-
configure.ac | 2 ++
ocaml/Makefile.am | 20 +++++++++++++++++---
resize/Makefile.am | 2 +-
sparsify/Makefile.am | 2 +-
sysprep/Makefile.am | 2 +-
6 files changed, 26 insertions(+), 7 deletions(-)
Index: libguestfs-1.20.1/Makefile.am
===================================================================
--- libguestfs-1.20.1.orig/Makefile.am
+++ libguestfs-1.20.1/Makefile.am
@@ -74,7 +74,10 @@ if HAVE_PERL
SUBDIRS += perl perl/examples
endif
if HAVE_OCAML
-SUBDIRS += ocaml ocaml/examples
+SUBDIRS += ocaml
+endif
+if HAVE_OCAMLOPT
+SUBDIRS += ocaml/examples
endif
if HAVE_PYTHON
SUBDIRS += python python/examples
Index: libguestfs-1.20.1/configure.ac
===================================================================
--- libguestfs-1.20.1.orig/configure.ac
+++ libguestfs-1.20.1/configure.ac
@@ -865,6 +865,8 @@ AS_IF([test "x$enable_ocaml" != "xno"],
])
AM_CONDITIONAL([HAVE_OCAML],
[test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno"])
+AM_CONDITIONAL([HAVE_OCAMLOPT],
+ [test "x$OCAMLOPT" != "xno" && test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno"])
AM_CONDITIONAL([HAVE_OCAMLDOC],
[test "x$OCAMLDOC" != "xno"])
Index: libguestfs-1.20.1/ocaml/Makefile.am
===================================================================
--- libguestfs-1.20.1.orig/ocaml/Makefile.am
+++ libguestfs-1.20.1/ocaml/Makefile.am
@@ -43,10 +43,20 @@ CLEANFILES += t/*.cmi t/*.cmo t/*.cmx t/
if HAVE_OCAML
+DATA_HOOK_FILES = META *.so *.a *.cma \
+ *.cmi $(srcdir)/*.mli
+if HAVE_OCAMLOPT
+DATA_HOOK_FILES += *.cmx *.cmxa
+endif
+
OCAMLCFLAGS = -g -warn-error CDEFLMPSUVYZX
OCAMLOPTFLAGS = $(OCAMLCFLAGS)
-noinst_DATA = mlguestfs.cma mlguestfs.cmxa META
+noinst_DATA = mlguestfs.cma
+if HAVE_OCAMLOPT
+noinst_DATA += mlguestfs.cmxa
+endif
+noinst_DATA += META
# Build the C part into a library, so that automake handles the C
# compilation step for us. Note that we don't directly use this
@@ -101,9 +111,13 @@ TESTS = run-bindtests \
$(patsubst %,%.opt,$(test_progs)))
noinst_DATA += \
- bindtests.bc bindtests.opt \
+ bindtests.bc
+if HAVE_OCAMLOPT
+noinst_DATA += \
+ bindtests.opt \
$(test_progs:%=%.bc) \
$(test_progs:%=%.opt)
+endif
bindtests.bc: bindtests.cmo mlguestfs.cma
mkdir -p t
@@ -217,7 +231,7 @@ install-data-hook:
$(OCAMLFIND) install \
-ldconf ignore -destdir $(DESTDIR)$(OCAMLLIB) \
guestfs \
- META *.so *.a *.cma *.cmx *.cmxa *.cmi $(srcdir)/*.mli
+ $(DATA_HOOK_FILES)
rm $(DESTDIR)$(OCAMLLIB)/guestfs/bindtests.*
rm $(DESTDIR)$(OCAMLLIB)/guestfs/libguestfsocaml.a
Index: libguestfs-1.20.1/resize/Makefile.am
===================================================================
--- libguestfs-1.20.1.orig/resize/Makefile.am
+++ libguestfs-1.20.1/resize/Makefile.am
@@ -40,7 +40,7 @@ SOURCES = \
resize_utils.ml \
resize_utils_tests.ml
-if HAVE_OCAML
+if HAVE_OCAMLOPT
# Note this list must be in dependency order.
OBJECTS = \
Index: libguestfs-1.20.1/sparsify/Makefile.am
===================================================================
--- libguestfs-1.20.1.orig/sparsify/Makefile.am
+++ libguestfs-1.20.1/sparsify/Makefile.am
@@ -36,7 +36,7 @@ SOURCES = \
sparsify_gettext.ml \
sparsify_utils.ml
-if HAVE_OCAML
+if HAVE_OCAMLOPT
# Note this list must be in dependency order.
OBJECTS = \
Index: libguestfs-1.20.1/sysprep/Makefile.am
===================================================================
--- libguestfs-1.20.1.orig/sysprep/Makefile.am
+++ libguestfs-1.20.1/sysprep/Makefile.am
@@ -86,7 +86,7 @@ SOURCES = \
utils.ml \
utils.mli
-if HAVE_OCAML
+if HAVE_OCAMLOPT
# Note this list must be in dependency order.
OBJECTS = \
10 years, 9 months
[PATCH] sysprep: handle distro specific sysv scripts
by Olaf Hering
Currently firstboot would only work on redhat-based images.
Handle redhat-based, suse-based and debian guests, error out in case of an
unknown distro.
Update firstboot.sh:
- make sure scripts exists and can be executed
- add LSB header to avoid insserv warnings later on
- run script only if called with "start"
Update functions, pass only required options.
Signed-off-by: Olaf Hering <olaf(a)aepfle.de>
diff --git a/sysprep/firstboot.ml b/sysprep/firstboot.ml
index 97cd8a9..c5296a1 100644
--- a/sysprep/firstboot.ml
+++ b/sysprep/firstboot.ml
@@ -28,14 +28,35 @@ let firstboot_dir = "/usr/lib/virt-sysprep"
let firstboot_sh = sprintf "\
#!/bin/sh -
+### BEGIN INIT INFO
+# Provides: virt-sysprep
+# Required-Start: $null
+# Should-Start: $all
+# Required-Stop: $null
+# Should-Stop: $all
+# Default-Start: 2 3 5
+# Default-Stop: 0 1 6
+# Short-Description: Start scripts to run once at next boot
+# Description: Start scripts to run once at next boot
+# These scripts run the first time the guest boots,
+# and then are deleted. Output or errors from the scripts
+# are written to ~root/virt-sysprep-firstboot.log.
+### END INIT INFO
+
d=%s/scripts
logfile=~root/virt-sysprep-firstboot.log
-for f in $d/* ; do
- echo '=== Running' $f '===' >>$logfile
- $f >>$logfile 2>&1
- rm $f
-done
+if test \"$1\" = \"start\"
+then
+ for f in $d/* ; do
+ if test -x \"$f\"
+ then
+ echo '=== Running' $f '===' >>$logfile
+ $f >>$logfile 2>&1
+ rm -f $f
+ fi
+ done
+fi
" firstboot_dir
let firstboot_service = sprintf "\
@@ -56,7 +77,7 @@ WantedBy=default.target
let failed fs =
ksprintf (fun msg -> failwith (s_"firstboot: failed: " ^ msg)) fs
-let rec install_service g root =
+let rec install_service g distro =
g#mkdir_p firstboot_dir;
g#mkdir_p (sprintf "%s/scripts" firstboot_dir);
g#write (sprintf "%s/firstboot.sh" firstboot_dir) firstboot_sh;
@@ -64,18 +85,18 @@ let rec install_service g root =
(* systemd, else assume sysvinit *)
if g#is_dir "/etc/systemd" then
- install_systemd_service g root
+ install_systemd_service g
else
- install_sysvinit_service g root
+ install_sysvinit_service g distro
(* Install the systemd firstboot service, if not installed already. *)
-and install_systemd_service g root =
+and install_systemd_service g =
g#write (sprintf "%s/firstboot.service" firstboot_dir) firstboot_service;
g#mkdir_p "/etc/systemd/system/default.target.wants";
g#ln_sf (sprintf "%s/firstboot.service" firstboot_dir)
"/etc/systemd/system/default.target.wants"
-and install_sysvinit_service g root =
+and install_sysvinit_redhat g =
g#mkdir_p "/etc/rc.d/rc2.d";
g#mkdir_p "/etc/rc.d/rc3.d";
g#mkdir_p "/etc/rc.d/rc5.d";
@@ -86,12 +107,51 @@ and install_sysvinit_service g root =
g#ln_sf (sprintf "%s/firstboot.sh" firstboot_dir)
"/etc/rc.d/rc5.d/99virt-sysprep-firstboot"
+(* Make firstboot.sh look like a runlevel script to avoid insserv warnings. *)
+and install_sysvinit_suse g =
+ g#mkdir_p "/etc/init.d/rc2.d";
+ g#mkdir_p "/etc/init.d/rc3.d";
+ g#mkdir_p "/etc/init.d/rc5.d";
+ g#ln_sf (sprintf "%s/firstboot.sh" firstboot_dir)
+ "/etc/init.d/virt-sysprep-firstboot";
+ g#ln_sf "../virt-sysprep-firstboot"
+ "/etc/init.d/rc2.d/S99virt-sysprep-firstboot";
+ g#ln_sf "../virt-sysprep-firstboot"
+ "/etc/init.d/rc3.d/S99virt-sysprep-firstboot";
+ g#ln_sf "../virt-sysprep-firstboot"
+ "/etc/init.d/rc5.d/S99virt-sysprep-firstboot"
+
+and install_sysvinit_debian g =
+ g#mkdir_p "/etc/init.d";
+ g#mkdir_p "/etc/rc2.d";
+ g#mkdir_p "/etc/rc3.d";
+ g#mkdir_p "/etc/rc5.d";
+ g#ln_sf (sprintf "%s/firstboot.sh" firstboot_dir)
+ "/etc/init.d/virt-sysprep-firstboot";
+ g#ln_sf "/etc/init.d/virt-sysprep-firstboot"
+ "/etc/rc2.d/S99virt-sysprep-firstboot";
+ g#ln_sf "/etc/init.d/virt-sysprep-firstboot"
+ "/etc/rc3.d/S99virt-sysprep-firstboot";
+ g#ln_sf "/etc/init.d/virt-sysprep-firstboot"
+ "/etc/rc5.d/S99virt-sysprep-firstboot"
+
+and install_sysvinit_service g distro =
+ match distro with
+ | ("fedora"|"rhel"|"centos"|"scientificlinux"|"redhat-based") ->
+ install_sysvinit_redhat g
+ | ("opensuse"|"sles"|"suse-based") ->
+ install_sysvinit_suse g
+ | "debian" ->
+ install_sysvinit_debian g
+ | _ ->
+ failed "guest type %s is not supported" distro
+
let add_firstboot_script g root id content =
let typ = g#inspect_get_type root in
let distro = g#inspect_get_distro root in
match typ, distro with
| "linux", _ ->
- install_service g root;
+ install_service g distro;
let t = Int64.of_float (Unix.time ()) in
let r = string_random8 () in
let filename = sprintf "%s/scripts/%Ld-%s-%s" firstboot_dir t r id in
--
1.7.12
10 years, 11 months
[PATCH] Use pkg-config for Python
by Hilko Bengen
At least libpython2.7-dev and libpython3.3-dev on current
Debian/unstable ship with pkg-config files. As with the pkg-config
check for Lua, we check for versioned and an unversioned .pc files.
---
configure.ac | 35 ++++++++++++++++++++---------------
python/Makefile.am | 2 +-
2 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac
index c809741..0aa1716 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1106,7 +1106,6 @@ AM_CONDITIONAL([HAVE_PERL],
dnl Check for Python (optional, for Python bindings).
PYTHON_PREFIX=
PYTHON_VERSION=
-PYTHON_INCLUDEDIR=
PYTHON_INSTALLDIR=
AC_ARG_ENABLE([python],
@@ -1117,23 +1116,30 @@ AS_IF([test "x$enable_python" != "xno"],[
AC_CHECK_PROG([PYTHON],[python],[python],[no])
if test "x$PYTHON" != "xno"; then
- AC_MSG_CHECKING([Python prefix])
- PYTHON_PREFIX=`$PYTHON -c "import sys; print (sys.prefix)"`
- AC_MSG_RESULT([$PYTHON_PREFIX])
-
AC_MSG_CHECKING([Python version])
PYTHON_VERSION_MAJOR=`$PYTHON -c "import sys; print (sys.version_info@<:@0@:>@)"`
PYTHON_VERSION_MINOR=`$PYTHON -c "import sys; print (sys.version_info@<:@1@:>@)"`
PYTHON_VERSION="$PYTHON_VERSION_MAJOR.$PYTHON_VERSION_MINOR"
AC_MSG_RESULT([$PYTHON_VERSION])
-
- AC_MSG_CHECKING([for Python include path])
- if test -z "$PYTHON_INCLUDEDIR"; then
- python_path=`$PYTHON -c "import distutils.sysconfig; \
- print (distutils.sysconfig.get_python_inc ());"`
- PYTHON_INCLUDEDIR=$python_path
- fi
- AC_MSG_RESULT([$PYTHON_INCLUDEDIR])
+ # Debian: python-2.7.pc, python-3.2.pc
+ PKG_CHECK_MODULES([PYTHON], [python-"$PYTHON_VERSION"],[
+ AC_SUBST([PYTHON_CFLAGS])
+ AC_SUBST([PYTHON_LIBS])
+ AC_SUBST([PYTHON_VERSION])
+ AC_DEFINE([HAVE_PYTHON],[1],[Python library found at compile time])
+ ],[
+ PKG_CHECK_MODULES([PYTHON], [python],[
+ AC_SUBST([PYTHON_CFLAGS])
+ AC_SUBST([PYTHON_LIBS])
+ AC_SUBST([PYTHON_VERSION])
+ AC_DEFINE([HAVE_PYTHON],[1],[Python library found at compile time])
+ ],[
+ AC_MSG_WARN([python $PYTHON_VERSION not found])
+ ])
+ ])
+ AC_MSG_CHECKING([Python prefix])
+ PYTHON_PREFIX=`$PYTHON -c "import sys; print (sys.prefix)"`
+ AC_MSG_RESULT([$PYTHON_PREFIX])
AC_ARG_WITH([python-installdir],
[AS_HELP_STRING([--with-python-installdir],
@@ -1171,11 +1177,10 @@ AS_IF([test "x$enable_python" != "xno"],[
AC_SUBST(PYTHON_PREFIX)
AC_SUBST(PYTHON_VERSION)
- AC_SUBST(PYTHON_INCLUDEDIR)
AC_SUBST(PYTHON_INSTALLDIR)
])
AM_CONDITIONAL([HAVE_PYTHON],
- [test "x$PYTHON" != "xno" && test "x$PYTHON_INCLUDEDIR" != "x" && test "x$PYTHON_INSTALLDIR" != "x"])
+ [test "x$PYTHON" != "xno" && test "x$PYTHON_LIBS" != "x" ])
dnl Check for Ruby and rake (optional, for Ruby bindings).
AC_ARG_ENABLE([ruby],
diff --git a/python/Makefile.am b/python/Makefile.am
index e514a76..ecc25d5 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -43,7 +43,7 @@ libguestfsmod_la_SOURCES = guestfs-py.c guestfs-py.h guestfs-py-byhand.c
libguestfsmod_la_CPPFLAGS = \
-DGUESTFS_PRIVATE=1 \
- -I$(PYTHON_INCLUDEDIR) \
+ $(PYTHON_CFLAGS) \
-I$(top_srcdir)/src -I$(top_builddir)/src
libguestfsmod_la_CFLAGS = \
--
1.7.10.4
11 years, 5 months
[PATCH] hivex: Add O_BINARY flag to open calls for platforms where this isn't the default (such as Win32)
by Daniel Gillen
Hi
As my cross platform registry editor (FRED available from
https://www.pinguin.lu (sorry for advertising but I couldn't resist
;-))) is evolving, I recently added write support to it.
While under Linux everything worked nice, the Windblows build didn't.
It seems that Windows opens files by default in text mode (O_TEXT) which
is a problem. The attached patch adds the O_BINARY flag to all open
calls which solves the issue and allows libhivex to alter hives in Windows.
I don't think this will harm on any other platform, so no fancy ifdefs
this time :)
ok?
cu
--
Unix _IS_ user friendly - it's just
selective about who its friends are!
11 years, 5 months
[PATCH] Add read support for "big data" blocks to hivex
by Hilko Bengen
---
lib/hivex.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 66 insertions(+), 15 deletions(-)
diff --git a/lib/hivex.c b/lib/hivex.c
index efc27f8..e3c1e05 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -208,6 +208,19 @@ struct ntreg_sk_record {
char sec_desc[1]; /* security info follows */
} __attribute__((__packed__));
+struct ntreg_db_record {
+ int32_t seg_len; /* length (always -ve because used) */
+ char id[2]; /* "db" */
+ uint16_t nr_blocks;
+ uint32_t blocklist_offset;
+ uint32_t unknown1;
+} __attribute__((__packed__));
+
+struct ntreg_db_block {
+ int32_t seg_len;
+ char data[1];
+} __attribute__((__packed__));
+
static uint32_t
header_checksum (const hive_h *h)
{
@@ -1418,22 +1431,60 @@ hivex_value_value (hive_h *h, hive_value_h value,
* instead.
*/
size_t blen = block_len (h, data_offset, NULL);
- if (len > blen - 4 /* subtract 4 for block header */) {
- if (h->msglvl >= 2)
- fprintf (stderr, "hivex_value_value: warning: declared data length "
- "is longer than the block it is in "
- "(data 0x%zx, data len %zu, block len %zu)\n",
- data_offset, len, blen);
- len = blen - 4;
-
- /* Return the smaller length to the caller too. */
- if (len_rtn)
- *len_rtn = len;
+ if (len <= blen - 4 /* subtract 4 for block header */) {
+ char *data = (char *) h->addr + data_offset + 4;
+ memcpy (ret, data, len);
+ return ret;
+ } else {
+ if (!IS_VALID_BLOCK (h, data_offset) || !BLOCK_ID_EQ (h, data_offset, "db")) {
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_value: warning: declared data length "
+ "is longer than the amount of data found in big-data blocks "
+ "(data 0x%zx, data len %zu)\n",
+ data_offset, len);
+ errno = EINVAL;
+ free (ret);
+ return NULL;
+ }
+ struct ntreg_db_record *db =
+ (struct ntreg_db_record *) ((char *) h->addr + data_offset);
+ size_t blocklist_offset = le32toh (db->blocklist_offset);
+ blocklist_offset += 0x1000;
+ size_t nr_blocks = le16toh (db->nr_blocks);
+ if (!IS_VALID_BLOCK (h, blocklist_offset)) {
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_value: warning: blocklist is not a "
+ "valid block "
+ "(db block 0x%zx, blocklist 0x%zx)\n",
+ data_offset, blocklist_offset);
+ errno = EINVAL;
+ free (ret);
+ return NULL;
+ }
+ struct ntreg_value_list *bl =
+ (struct ntreg_value_list *) ((char *) h->addr + blocklist_offset);
+ size_t i, off;
+ for (i=off=0; i < nr_blocks; ++i) {
+ uint32_t subblock_offset = le32toh (bl->offset[i]);
+ subblock_offset += 0x1000;
+ if (!IS_VALID_BLOCK (h, subblock_offset)) {
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_value: warning: big data block is not "
+ "valid (db block 0x%zx, block list 0x%zx, data block 0x%zx)\n",
+ data_offset, blocklist_offset, subblock_offset);
+ }
+ int32_t seg_len = block_len(h, subblock_offset, NULL);
+ struct ntreg_db_block *subblock =
+ (struct ntreg_db_block *) ((char *) h->addr + subblock_offset);
+ int32_t sz = seg_len - 8; /* don't copy the last 4 bytes */
+ if (off + sz > len) {
+ sz = len - off;
+ }
+ memcpy (ret + off, subblock->data, sz);
+ off += sz;
+ }
+ return ret;
}
-
- char *data = (char *) h->addr + data_offset + 4;
- memcpy (ret, data, len);
- return ret;
}
static char *
--
1.8.3.1
11 years, 5 months
[PATCH] Relax size checks for integer types
by Hilko Bengen
I recenetly came across a Windows XP image, where one REG_QWORD value
(HKLM\Software\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Shutdown\0\0\ExecTime)
would be displayed by hivexsh but hivex_value_qword() would return -1.
It turned out that the data length of this value was 16 bytes instead
of 8.
There is no problem in simply interpreting the first 4 (DWORD) or
8 (QWORD) bytes -- if there are enough bytes to be interpreted.
---
lib/hivex.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/hivex.c b/lib/hivex.c
index a2bd43b..efc27f8 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -1624,7 +1624,7 @@ hivex_value_dword (hive_h *h, hive_value_h value)
if (data == NULL)
return -1;
- if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) {
+ if ((t != hive_t_dword && t != hive_t_dword_be) || len < 4) {
free (data);
errno = EINVAL;
return -1;
@@ -1650,7 +1650,7 @@ hivex_value_qword (hive_h *h, hive_value_h value)
if (data == NULL)
return -1;
- if (t != hive_t_qword || len != 8) {
+ if (t != hive_t_qword || len < 8) {
free (data);
errno = EINVAL;
return -1;
--
1.8.3.1
11 years, 5 months
Re: [Libguestfs] libguestfs: error: umount_local: unknown option 1069642336
by Richard W.M. Jones
| 08:49 < oberonc> hi
| 08:49 < oberonc> I have a problem with libguesfs 1.20.6
| 08:50 < oberonc> on fedora 18
| 08:50 < oberonc> with fuse 2.9.2
| 08:50 < oberonc> when I call guestfs_umount_local() I get the following
| error:
| 08:50 < oberonc> libguestfs: error: umount_local: unknown option
| 1069642336 (this can happen if a program is compiled
| against a newer version of libguestfs, then
| dynamically linked to an older version)
I'm going to guess that you're calling the C API directly. The
prototype for guestfs_umount_local is:
extern int guestfs_umount_local (guestfs_h *g, ...);
with the '...' being used for optional arguments. If you don't
have any optional arguments, or to terminate the list of optional
arguments, you need to use '-1'. eg:
guestfs_umount_local (g, -1);
If you miss this out then you'd see an error like the above.
If you're using another binding then please give some more details of
exactly what you're doing.
By the way, guestfs_umount_local isn't exactly safe to use. You're
probably better off calling 'fusermount -u /mountpoint' instead. In
newer versions of libguestfs there is a program called guestunmount
which makes this easy.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
11 years, 5 months