Re: [Libguestfs] libguestfs powerpc package
by Richard W.M. Jones
[Please keep message on the list]
On Mon, Sep 30, 2013 at 12:58:38AM +0200, Roberto Innocenti wrote:
> [libguestfs on ppc]
You should be able to compile from the latest source on ppc64, since I
spent some time a few weeks ago getting it to work:
http://comments.gmane.org/gmane.linux.redhat.fedora.virtualization/2268
Start with git (not 1.22), read the README file, and let us know on
the mailing list what precise errors you get when you try to compile it.
Note you'll require the latest supermin (from git) first, and qemu
from git, and IIRC there was an endianness bug in hivex too which is
fixed in git. The latest hivex isn't required unless you're doing
Widows guest inspection.
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
10 years, 7 months
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, 8 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 0/4] virt-v2v: Convert RedHat.pm to Linux.pm
by Mike Latimer
In preparation for an upcoming patch which adds support for SUSE guest
conversions, it makes sense to have an intermediate steps that changes the
RedHat.pm converter into a more generic Linux converter. The SUSE changes
will then be limited in scope to only what is required for SUSE support.
This series of patches accomplishes the following:
- Renames RedHat.pm to Linux.pm
- Modifies Linux.pm to be more generic, and ready for additional distribution
support (such as SUSE)
- Adds functionality to _remap_block_devices, to ensure root and resume
devices are updated in both grub legacy and grub2 environments
- Allows for qxl or cirrus settings in LibVirtTarget.pm (based on passing
guestcaps->{display} from the conversion.
I'll submit the SUSE-specific changes after we work through any issues raised
here.
Mike Latimer (4):
Rename RedHat.pm to Linux.pm
Make Linux.pm more generic
Handle block remaps in grub and grub2 files
Support multiple display types through guestcaps
MANIFEST | 2 +-
lib/Sys/VirtConvert/Connection/LibVirtTarget.pm | 14 +-
.../VirtConvert/Converter/{RedHat.pm => Linux.pm} | 225 ++++++++++++++++-----
po/POTFILES.in | 2 +-
4 files changed, 185 insertions(+), 58 deletions(-)
rename lib/Sys/VirtConvert/Converter/{RedHat.pm => Linux.pm} (92%)
--
1.8.1.4
11 years
Request to relicense hash gnulib module to LGPLv2+
by Richard W.M. Jones
libguestfs (an LGPLv2+ library) uses the 'hash' module, which turns
out to be "GPL".
Actually this happened because we started to use it in a separate
GPL'd utility program, but later on included this functionality in the
core library, copying the same code from the utility but not checking
the license of 'hash'.
We'd therefore like to request that 'hash' is relicensed as LGPLv2+.
If this is not possible, we will have to rewrite the code, probably
implementing our own hash table, which would be a shame because hash
works well for our needs.
Notes:
- the code doesn't appear to call exit (it does call abort), and so
seems to be suitable for a library
- hash-pjw which we also use is already licensed as LGPLv2+
- it looks like the original author was Jim Meyering (CC'd)
- the dependencies are all LGPLv2+
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
11 years
[PATCH] virt-v2v: Add use augeas_error to GrubLegacy, plus typo fixup
by Mike Latimer
The following patch adds augeas_error to the Sys::VirtConvert::Util use
statement for GrubLegacy (matching what is used in the Grub2 package).
This is required to prevent an undefined subroutine error for the
augeas_error call in list_kernels().
There are also a few minor typo fixups:
- A message string in _configure_kernel was missing the $ before a variable
- In _install_capability, the expression that filters out 'xen' should
actually filter out '-xen'
- Two typos in comments were irritating me ;)
---
lib/Sys/VirtConvert/Converter/RedHat.pm | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/Sys/VirtConvert/Converter/RedHat.pm b/lib/Sys/VirtConvert/Converter/RedHat.pm
index 612ab2e..f3926e8 100644
--- a/lib/Sys/VirtConvert/Converter/RedHat.pm
+++ b/lib/Sys/VirtConvert/Converter/RedHat.pm
@@ -63,7 +63,7 @@ sub check_efi
# Methods for inspecting and manipulating grub legacy
package Sys::VirtConvert::Converter::RedHat::GrubLegacy;
-use Sys::VirtConvert::Util;
+use Sys::VirtConvert::Util qw(:DEFAULT augeas_error);
use File::Basename;
use Locale::TextDomain 'virt-v2v';
@@ -1055,7 +1055,7 @@ sub _configure_kernel
unless defined($boot_kernel);
} else {
v2vdie __x('Failed to find a {name} package to install',
- name => "kernel_pkg.$kernel_arch");
+ name => "$kernel_pkg.$kernel_arch");
}
}
}
@@ -1512,7 +1512,7 @@ sub _install_capability
_get_replacement_kernel_name($g, $root, $kernel_arch,
$meta);
- # Check if we've got already got an appropriate kernel
+ # Check if we've already got an appropriate kernel
my ($inst) =
_get_installed("$kernel_pkg.$kernel_arch", $g);
@@ -1523,7 +1523,7 @@ sub _install_capability
{
# filter out xen/xenU from release field
if (defined($kernel_release) &&
- $kernel_release =~ /^(\S+?)(xen)?(U)?$/)
+ $kernel_release =~ /^(\S+?)(-xen)?(U)?$/)
{
$kernel_release = $1;
}
@@ -2076,7 +2076,7 @@ sub _get_installed
or die("Unexpected return from rpm command: $installed");
my ($epoch, $version, $release) = ($1, $2, $3);
- # Ensure iepoch is always numeric
+ # Ensure epoch is always numeric
$epoch = 0 if('(none)' eq $epoch);
push(@installed, [$epoch, $version, $release]);
--
1.8.1.4
11 years
[PATCH] sysprep: add feature of removing specified paths
by Wanlong Gao
Signed-off-by: Wanlong Gao <gaowanlong(a)cn.fujitsu.com>
---
po/POTFILES-ml | 1 +
sysprep/Makefile.am | 1 +
sysprep/sysprep_operation_remove_path.ml | 53 ++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+)
create mode 100644 sysprep/sysprep_operation_remove_path.ml
diff --git a/po/POTFILES-ml b/po/POTFILES-ml
index 509e786..0e25e95 100644
--- a/po/POTFILES-ml
+++ b/po/POTFILES-ml
@@ -50,6 +50,7 @@ sysprep/sysprep_operation_pam_data.ml
sysprep/sysprep_operation_password.ml
sysprep/sysprep_operation_puppet_data_log.ml
sysprep/sysprep_operation_random_seed.ml
+sysprep/sysprep_operation_remove_path.ml
sysprep/sysprep_operation_rhn_systemid.ml
sysprep/sysprep_operation_rpm_db.ml
sysprep/sysprep_operation_samba_db_log.ml
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
index c5be5ba..cb95cea 100644
--- a/sysprep/Makefile.am
+++ b/sysprep/Makefile.am
@@ -57,6 +57,7 @@ operations = \
password \
puppet_data_log \
random_seed \
+ remove_path \
rhn_systemid \
rpm_db \
samba_db_log \
diff --git a/sysprep/sysprep_operation_remove_path.ml b/sysprep/sysprep_operation_remove_path.ml
new file mode 100644
index 0000000..d307373
--- /dev/null
+++ b/sysprep/sysprep_operation_remove_path.ml
@@ -0,0 +1,53 @@
+(* virt-sysprep
+ * Copyright (C) 2013 Fujitsu Ltd.
+ *
+ * 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 Common_utils
+open Sysprep_operation
+open Common_gettext.Gettext
+
+module G = Guestfs
+
+let paths= ref []
+let add_paths path= paths := path :: !paths
+
+let path_perform g root =
+ let paths = List.rev !paths in
+ if paths <> [] then (
+ List.iter (fun glob -> Array.iter g#rm_rf (g#glob_expand glob)) paths
+ );
+ []
+
+let op = {
+ defaults with
+ name = "remove-path";
+ enabled_by_default = true;
+ heading = s_"Remove specified paths";
+ pod_description = Some (s_"\
+Remove specified files or directories.
+
+Use the I<--remove-path> option to specify a path to remove.");
+ extra_args = [
+ ("--remove-path", Arg.String add_paths, s_"path" ^ " " ^ s_"Files or directories to be removed on guest"),
+ s_"\
+Remove the specified path C<file> on guest.";
+ ];
+
+ perform_on_filesystems = Some path_perform;
+}
+
+let () = register_operation op
--
1.8.4.474.g128a96c
11 years
virt-resize for shrinking
by Richard W.M. Jones
[Continuing a discussion from IRC so we have a permanent record]
We want to shrink a disk image using virt-resize. Shrinking is harder
and not really documented. It requires some manual calculations too.
Here is the original:
$ virt-df -a 209e6911-fe48-4321-900f-928b3400df88
Filesystem 1K-blocks Used Available Use%
209e6911-fe48-4321-900f-928b3400df88:/dev/sda1
51564664 8000404 40943880 16%
$ virt-filesystems -a 209e6911-fe48-4321-900f-928b3400df88 --all --long
Name Type VFS Label MBR Size Parent
/dev/sda1 filesystem ext4 cloudimg-rootfs - 53678177280 -
/dev/sda1 partition - - 83 53678177280 /dev/sda
/dev/sda device - - - 53687091200
The first question was: Why doesn't the filesystem Size in
virt-filesystems match the 1K-blocks field in virt-df? That's because
the 1K-blocks field in virt-df doesn't include filesystem metadata
overhead (more accurately: it depends on the filesystem and different
fses will report slightly different things for this field). The
virt-filesystems Size field is reporting the entire, true size of the
partition.
My observations are: (1) There's plenty of scope for shrinking. Note
that Use% is just 16%. (2) There's only one filesystem, no swap or
boot partitions, and that makes the calculations easy.
To shrink down to, say, 1/2 of the original size, total device size of
53687091200 / 2 == 26843545600 bytes (25 GB).
As there is always some filesystem overhead, you'll need to shrink the
filesystem by a bit more than 1/2. I would shrink it down to 20 GB
(which is still well over 16% of the original).
Start the guest up in virt-rescue:
virt-rescue -a 209e6911-fe48-4321-900f-928b3400df88
[... boot messages ...]
><rescue> resize2fs /dev/sda1 20G
><rescue> sync
><rescue> exit
Now after that, it should be possible to run virt-resize:
rm -f output.img
truncate -s 25G output.img
virt-resize 209e6911-fe48-4321-900f-928b3400df88 output.img \
--shrink /dev/sda1
Note (1) The shrink path of virt-resize isn't well tested at all, so
you might hit bugs. If you do, run it again with --debug and file a
bugzilla.
Now (you can check with virt-filesystems) you should have 'output.img'
which has one partition that is just under 25GB, but contains a 20GB
filesystem. You can now *expand* the filesystem on /dev/sda1 to
occupy the full space:
virt-rescue -a output.img
><rescue> resize2fs /dev/sda1
><rescue> sync
><rescue> exit
Note (2) The virt-rescue steps could also be done using guestfish (or
the API) which is especially useful if you wish to automate any of this.
Note (3) There's an entirely different way to think about this, which
is also much easier. Make the file sparse (or use qcow2 or LVM thinp),
using virt-sparsify. It'll save MORE disk space ...
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
11 years
[PATCH] docs: guestfs_case_sensitive_path returns error on non-existent path
by Matthew Booth
---
generator/actions.ml | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/generator/actions.ml b/generator/actions.ml
index c73a319..cb6d137 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -7150,13 +7150,32 @@ a problem.
Bug or feature? You decide:
L<http://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
-This function resolves the true case of each element in the
-path and returns the case-sensitive path.
+C<guestfs_case_sensitive_path> attempts to resolve the true case of
+each element in the path. It will return a resolved path if either the
+full path or its parent directory exists. If the parent directory
+exists but the full path does not, the case of the parent directory
+will be correctly resolved, and the remainder appended unmodified. For
+example, if the file C<\"/Windows/System32/netkvm.sys\"> exists:
-Thus C<guestfs_case_sensitive_path> (\"/Windows/System32\")
-might return C<\"/WINDOWS/system32\"> (the exact return value
-would depend on details of how the directories were originally
-created under Windows).
+=over 4
+
+=item C<guestfs_case_sensitive_path> (\"/windows/system32/netkvm.sys\")
+
+\"Windows/System32/netkvm.sys\"
+
+=item C<guestfs_case_sensitive_path> (\"/windows/system32/NoSuchFile\")
+
+\"Windows/System32/NoSuchFile\"
+
+=item C<guestfs_case_sensitive_path> (\"/windows/system33/netkvm.sys\")
+
+I<ERROR>
+
+=back
+
+I<Note>:
+Because of the above behaviour, C<guestfs_case_sensitive_path> cannot
+be used to check for the existence of a file.
I<Note>:
This function does not handle drive names, backslashes etc.
--
1.8.3.1
11 years