Richard W.M. Jones
2018-Jun-07 15:48 UTC
[Libguestfs] [PATCH nbdkit 0/4] plugins: Add new "ext2" plugin, for accessing ext2, ext3 or ext4 filesystems.
There is a small test provided. I tested this a lot more locally and it seems pretty robust. Rich.
Richard W.M. Jones
2018-Jun-07 15:48 UTC
[Libguestfs] [PATCH nbdkit 1/4] plugins: guestfs: This plugin is only safe when serializing connections.
If two connections are both made at the same time then they would both open a guestfs handle, possible for write, on the same set of disks. With older qemu this would result in disk corruption, with newer qemu you'd get just a locking failure. --- plugins/guestfs/guestfs-plugin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/guestfs/guestfs-plugin.c b/plugins/guestfs/guestfs-plugin.c index 66788d8..1572940 100644 --- a/plugins/guestfs/guestfs-plugin.c +++ b/plugins/guestfs/guestfs-plugin.c @@ -492,7 +492,7 @@ plugin_guestfs_close (void *handle) free (h); } -#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS +#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS /* Get the file size. */ static int64_t -- 2.16.2
Richard W.M. Jones
2018-Jun-07 15:48 UTC
[Libguestfs] [PATCH nbdkit 2/4] tests: Move creation of ‘disk’ earlier.
Just refactoring. --- tests/Makefile.am | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 0cc2618..1830cd3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -232,6 +232,18 @@ test_oldstyle_LDADD = libtest.la $(LIBGUESTFS_LIBS) endif HAVE_LIBGUESTFS +# common disk image shared with several tests +if HAVE_GUESTFISH +check_DATA += disk +MAINTAINERCLEANFILES += disk + +disk: + rm -f $@ test1.img + guestfish -N fs -m /dev/sda1 write /hello.txt "hello,world" + mv test1.img disk + +endif HAVE_GUESTFISH + # file plugin test. LIBGUESTFS_TESTS += test-file @@ -241,26 +253,19 @@ test_file_LDADD = libtest.la $(LIBGUESTFS_LIBS) # gzip plugin test. if HAVE_ZLIB -if HAVE_GUESTFISH LIBGUESTFS_TESTS += test-gzip -check_DATA += disk disk.gz -MAINTAINERCLEANFILES += disk disk.gz +check_DATA += disk.gz +MAINTAINERCLEANFILES += disk.gz test_gzip_SOURCES = test-gzip.c test.h test_gzip_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS) test_gzip_LDADD = libtest.la $(LIBGUESTFS_LIBS) -disk: - rm -f $@ test1.img - guestfish -N fs -m /dev/sda1 write /hello.txt "hello,world" - mv test1.img disk - disk.gz: disk rm -f $@ gzip -9 -c disk > $@ -endif HAVE_GUESTFISH endif HAVE_ZLIB # memory plugin test. @@ -316,7 +321,6 @@ test_streaming_LDADD = libtest.la $(LIBGUESTFS_LIBS) # xz plugin test. if HAVE_LIBLZMA -if HAVE_GUESTFISH LIBGUESTFS_TESTS += test-xz check_DATA += disk.xz @@ -330,7 +334,6 @@ disk.xz: disk rm -f $@ xz --best --block-size=16777216 -c disk > $@ -endif HAVE_GUESTFISH endif HAVE_LIBLZMA #---------------------------------------------------------------------- -- 2.16.2
Richard W.M. Jones
2018-Jun-07 15:48 UTC
[Libguestfs] [PATCH nbdkit 3/4] plugins: Add new "ext2" plugin, for accessing ext2, ext3 or ext4 filesystems.
--- README | 6 + configure.ac | 24 +++ docs/nbdkit.pod | 1 + plugins/Makefile.am | 1 + plugins/ext2/Makefile.am | 68 +++++++ plugins/ext2/ext2.c | 359 ++++++++++++++++++++++++++++++++++++ plugins/ext2/nbdkit-ext2-plugin.pod | 130 +++++++++++++ 7 files changed, 589 insertions(+) diff --git a/README b/README index baa29fc..e58df8b 100644 --- a/README +++ b/README @@ -65,6 +65,12 @@ For the libguestfs plugin, and to run the test suite: - guestfish (from libguestfs) +For the ext2 plugin: + + - ext2fs + + - com_err + For the VDDK plugin: - VDDK (see plugins/vddk/README.VDDK) diff --git a/configure.ac b/configure.ac index 4bd9aac..c86c6ce 100644 --- a/configure.ac +++ b/configure.ac @@ -426,6 +426,29 @@ dnl Check for guestfish (only needed for some of the tests). AC_CHECK_PROG([GUESTFISH], [guestfish], [guestfish], [no]) AM_CONDITIONAL([HAVE_GUESTFISH], [test "x$GUESTFISH" != "xno"]) +dnl Check for ext2fs and com_err, for the ext2 plugin. +AC_ARG_WITH([ext2],[ + AS_HELP_STRING([--without-ext2], + [disable ext2 plugin @<:@default=check@:>@])], + [], + [with_ext2=check]) +AS_IF([test "$with_ext2" != "no"], [ + PKG_CHECK_MODULES([EXT2FS], [ext2fs], [ + AC_SUBST([EXT2FS_CFLAGS]) + AC_SUBST([EXT2FS_LIBS]) + AC_DEFINE([HAVE_EXT2FS],[1],[ext2fs found at compile time.]) + ], + [AC_MSG_WARN([ext2fs not found, ext2 plugin will be disabled])]) + PKG_CHECK_MODULES([COM_ERR], [com_err], [ + AC_SUBST([COM_ERR_CFLAGS]) + AC_SUBST([COM_ERR_LIBS]) + AC_DEFINE([HAVE_COM_ERR],[1],[com_err found at compile time.]) + ], + [AC_MSG_WARN([com_err not found, ext2 plugin will be disabled])]) +]) +AM_CONDITIONAL([HAVE_EXT2], + [test "x$EXT2FS_LIBS" != "x" && test "x$COM_ERR_LIBS" != "x"]) + dnl See plugins/vddk/README.VDDK. AC_CHECK_SIZEOF([size_t]) AS_IF([test "x$ac_cv_sizeof_size_t" = "x4"],[bits=32],[bits=64]) @@ -511,6 +534,7 @@ AC_CONFIG_FILES([Makefile plugins/example2/Makefile plugins/example3/Makefile plugins/example4/Makefile + plugins/ext2/Makefile plugins/file/Makefile plugins/guestfs/Makefile plugins/gzip/Makefile diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod index a515353..6ba981b 100644 --- a/docs/nbdkit.pod +++ b/docs/nbdkit.pod @@ -909,6 +909,7 @@ L<nbdkit-example1-plugin(1)>, L<nbdkit-example2-plugin(1)>, L<nbdkit-example3-plugin(1)>, L<nbdkit-example4-plugin(1)>, +L<nbdkit-ext2-plugin(1)>, L<nbdkit-file-plugin(1)>, L<nbdkit-guestfs-plugin(1)>, L<nbdkit-gzip-plugin(1)>, diff --git a/plugins/Makefile.am b/plugins/Makefile.am index ba67feb..328bc01 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -36,6 +36,7 @@ SUBDIRS = \ example2 \ example3 \ example4 \ + ext2 \ file \ guestfs \ gzip \ diff --git a/plugins/ext2/Makefile.am b/plugins/ext2/Makefile.am new file mode 100644 index 0000000..525013f --- /dev/null +++ b/plugins/ext2/Makefile.am @@ -0,0 +1,68 @@ +# nbdkit +# Copyright (C) 2017-2018 Red Hat Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +EXTRA_DIST = nbdkit-ext2-plugin.pod + +CLEANFILES = *~ + +plugindir = $(libdir)/nbdkit/plugins + +if HAVE_EXT2 + +plugin_LTLIBRARIES = nbdkit-ext2-plugin.la + +nbdkit_ext2_plugin_la_SOURCES = \ + ext2.c \ + $(top_srcdir)/include/nbdkit-plugin.h + +nbdkit_ext2_plugin_la_CPPFLAGS = \ + -I$(top_srcdir)/include +nbdkit_ext2_plugin_la_CFLAGS = \ + $(WARNINGS_CFLAGS) \ + $(EXT2FS_CFLAGS) $(COM_ERR_CFLAGS) +nbdkit_ext2_plugin_la_LIBADD = \ + $(EXT2FS_LIBS) $(COM_ERR_LIBS) +nbdkit_ext2_plugin_la_LDFLAGS = \ + -module -avoid-version -shared + +if HAVE_POD2MAN + +man_MANS = nbdkit-ext2-plugin.1 +CLEANFILES += $(man_MANS) + +nbdkit-ext2-plugin.1: nbdkit-ext2-plugin.pod + $(POD2MAN) $(POD2MAN_ARGS) --section=1 --name=`basename $@ .1` $< $@.t && \ + if grep 'POD ERROR' $@.t; then rm $@.t; exit 1; fi && \ + mv $@.t $@ + +endif +endif diff --git a/plugins/ext2/ext2.c b/plugins/ext2/ext2.c new file mode 100644 index 0000000..1e8f6dd --- /dev/null +++ b/plugins/ext2/ext2.c @@ -0,0 +1,359 @@ +/* nbdkit + * Copyright (C) 2017-2018 Red Hat Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <inttypes.h> + +/* Inlining is broken in the ext2fs header file. Disable it by + * defining the following: + */ +#define NO_INLINE_FUNCS +#include <ext2fs.h> + +#define NBDKIT_API_VERSION 2 + +#include <nbdkit-plugin.h> + +/* Disk image and filename parameters. */ +static char *disk; +static char *file; + +static void +ext2_load (void) +{ + initialize_ext2_error_table (); +} + +static void +ext2_unload (void) +{ + free (disk); + free (file); +} + +static int +ext2_config (const char *key, const char *value) +{ + if (strcmp (key, "disk") == 0) { + if (disk != NULL) { + nbdkit_error ("disk parameter specified more than once"); + return -1; + } + disk = nbdkit_absolute_path (value); + if (disk == NULL) + return -1; + } + else if (strcmp (key, "file") == 0) { + if (file != NULL) { + nbdkit_error ("file parameter specified more than once"); + return -1; + } + file = strdup (value); + if (file == NULL) { + nbdkit_error ("strdup: %m"); + return -1; + } + } + else { + nbdkit_error ("unknown parameter '%s'", key); + return -1; + } + + return 0; +} + +static int +ext2_config_complete (void) +{ + if (disk == NULL || file == NULL) { + nbdkit_error ("you must supply disk=<DISK> and file=<FILE> parameters " + "after the plugin name on the command line"); + return -1; + } + + if (file[0] != '/') { + nbdkit_error ("the file parameter must refer to an absolute path"); + return -1; + } + + return 0; +} + +#define ext2_config_help \ + "disk=<FILENAME> (required) Raw ext2, ext3 or ext4 filesystem.\n" \ + "file=<FILENAME> (required) File to serve inside the disk image." + +/* The per-connection handle. */ +struct handle { + int readonly; + ext2_filsys fs; /* Filesystem handle. */ + ext2_ino_t ino; /* Inode of open file. */ + ext2_file_t file; /* File handle. */ +}; + +/* Create the per-connection handle. */ +static void * +ext2_open (int readonly) +{ + struct handle *h; + errcode_t err; + int fs_flags; + int file_flags; + struct ext2_inode inode; + + h = malloc (sizeof *h); + if (h == NULL) { + nbdkit_error ("malloc: %m"); + return NULL; + } + + h->readonly = readonly; + + fs_flags = 0; +#ifdef EXT2_FLAG_64BITS + fs_flags |= EXT2_FLAG_64BITS; +#endif + if (!readonly) + fs_flags |= EXT2_FLAG_RW; + + err = ext2fs_open (disk, fs_flags, 0, 0, unix_io_manager, &h->fs); + if (err != 0) { + nbdkit_error ("%s: open: %s", disk, error_message (err)); + goto err0; + } + + if (strcmp (file, "/") == 0) + /* probably gonna fail, but we'll catch it later */ + h->ino = EXT2_ROOT_INO; + else { + err = ext2fs_namei (h->fs, EXT2_ROOT_INO, EXT2_ROOT_INO, + &file[1], &h->ino); + if (err != 0) { + nbdkit_error ("%s: %s: namei: %s", disk, file, error_message (err)); + goto err1; + } + } + + /* Check the file is a regular file. + * XXX This won't follow symlinks, we'd have to do that manually. + */ + err = ext2fs_read_inode (h->fs, h->ino, &inode); + if (err != 0) { + nbdkit_error ("%s: %s: inode: %s", disk, file, error_message (err)); + goto err1; + } + if (!LINUX_S_ISREG (inode.i_mode)) { + nbdkit_error ("%s: %s: must be a regular file in the disk image", + disk, file); + goto err1; + } + + file_flags = 0; + if (!readonly) + file_flags |= EXT2_FILE_WRITE; + err = ext2fs_file_open2 (h->fs, h->ino, NULL, file_flags, &h->file); + if (err != 0) { + nbdkit_error ("%s: %s: open: %s", disk, file, error_message (err)); + goto err1; + } + + return h; + + err1: + ext2fs_close (h->fs); + err0: + free (h); + return NULL; +} + +/* Free up the per-connection handle. */ +static void +ext2_close (void *handle) +{ + struct handle *h = handle; + + ext2fs_file_close (h->file); + ext2fs_close (h->fs); + free (h); +} + +static int +ext2_can_fua (void *handle) +{ + return NBDKIT_FUA_NATIVE; +} + +/* It might be possible to relax this, but it's complicated. + * + * It's desirable for ‘nbdkit -r’ to behave the same way as + * ‘mount -o ro’. But we don't know the state of the readonly flag + * until ext2_open is called (because the NBD client can also request + * a readonly connection). So we could not set the "ro" flag if we + * opened the filesystem any earlier (eg in ext2_config). + * + * So out of necessity we have one ext2_filsys handle per connection, + * but if we allowed parallel work on those handles then we would get + * data corruption, so we need to serialize connections. + */ +#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS + +/* Get the disk size. */ +static int64_t +ext2_get_size (void *handle) +{ + struct handle *h = handle; + errcode_t err; + uint64_t size; + + err = ext2fs_file_get_lsize (h->file, (__u64 *) &size); + if (err != 0) { + nbdkit_error ("%s: %s: lsize: %s", disk, file, error_message (err)); + return -1; + } + return (int64_t) size; +} + +/* Read data. */ +static int +ext2_pread (void *handle, void *buf, uint32_t count, uint64_t offset, + uint32_t flags) +{ + struct handle *h = handle; + errcode_t err; + unsigned int got; + + while (count > 0) { + /* Although this function weirdly can return the new offset, + * examination of the code shows that it never returns anything + * different from what we set, so NULL out that parameter. + */ + err = ext2fs_file_llseek (h->file, offset, EXT2_SEEK_SET, NULL); + if (err != 0) { + nbdkit_error ("%s: %s: llseek: %s", disk, file, error_message (err)); + return -1; + } + + err = ext2fs_file_read (h->file, buf, (unsigned int) count, &got); + if (err != 0) { + nbdkit_error ("%s: %s: read: %s", disk, file, error_message (err)); + return -1; + } + + buf += got; + count -= got; + offset += got; + } + + return 0; +} + +/* Write data to the file. */ +static int +ext2_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, + uint32_t flags) +{ + struct handle *h = handle; + errcode_t err; + unsigned int written; + + while (count > 0) { + err = ext2fs_file_llseek (h->file, offset, EXT2_SEEK_SET, NULL); + if (err != 0) { + nbdkit_error ("%s: %s: llseek: %s", disk, file, error_message (err)); + return -1; + } + + err = ext2fs_file_write (h->file, buf, (unsigned int) count, &written); + if (err != 0) { + nbdkit_error ("%s: %s: write: %s", disk, file, error_message (err)); + return -1; + } + + buf += written; + count -= written; + offset += written; + } + + if ((flags & NBDKIT_FLAG_FUA) != 0) { + err = ext2fs_file_flush (h->file); + if (err != 0) { + nbdkit_error ("%s: %s: flush: %s", disk, file, error_message (err)); + return -1; + } + } + + return 0; +} + +static int +ext2_flush (void *handle, uint32_t flags) +{ + struct handle *h = handle; + errcode_t err; + + err = ext2fs_file_flush (h->file); + if (err != 0) { + nbdkit_error ("%s: %s: flush: %s", disk, file, error_message (err)); + return -1; + } + + return 0; +} + +/* XXX It seems as if we should be able to support trim and zero, if + * we could work out how those are implemented in the ext2fs API which + * is very obscure. + */ + +static struct nbdkit_plugin plugin = { + .name = "ext2", + .version = PACKAGE_VERSION, + .load = ext2_load, + .unload = ext2_unload, + .config = ext2_config, + .config_complete = ext2_config_complete, + .config_help = ext2_config_help, + .open = ext2_open, + .close = ext2_close, + .can_fua = ext2_can_fua, + .get_size = ext2_get_size, + .pread = ext2_pread, + .pwrite = ext2_pwrite, + .flush = ext2_flush, + .errno_is_preserved = 1, +}; + +NBDKIT_REGISTER_PLUGIN(plugin) diff --git a/plugins/ext2/nbdkit-ext2-plugin.pod b/plugins/ext2/nbdkit-ext2-plugin.pod new file mode 100644 index 0000000..29c76aa --- /dev/null +++ b/plugins/ext2/nbdkit-ext2-plugin.pod @@ -0,0 +1,130 @@ +=encoding utf8 + +=head1 NAME + +nbdkit-ext2-plugin - Read and write files inside ext2, ext3 or ext4 filesystems + +=head1 SYNOPSIS + + nbdkit ext2 disk=fs.img file=/disks/disk.raw + + nbdkit --filter=partition ext2 \ + disk=disk.img file=/disks/disk.raw \ + partition=1 + +=head1 DESCRIPTION + +C<nbdkit-ext2-plugin> is an nbdkit plugin which can read and +write files inside ext2, ext3 or ext4 filesystem images. + +Suppose you have an ext2/3/4 filesystem image called F<fs.img> +which contains inside itself a file called F<disk.raw> +inside a directory on the filesystem called F</disks>, then +you could serve that file over NBD using: + + nbdkit ext2 disk=fs.img file=/disks/disk.raw + +Commonly disk images are partitioned. In that case you must +use L<nbdkit-partition-filter(1)> to select the partition: + + nbdkit --filter=partition ext2 disk=.. file=.. partition=1 + +This plugin can both read and write to the file inside the filesystem. +Use the I<-r> flag to force a readonly connection, but note this does +I<not> guarantee that no writes are made to the filesystem. In +particular we may have to replay the ext3 journal in order to open a +filesystem even read-only. + +The plugin does I<not> support multiple parallel connections, because +there is a risk of corrupting the filesystem (as if the filesystem was +mounted by multiple machines). If a second connection is made to +nbdkit, it will block until the first connection closes. + +The plugin is implemented using the ext2fs library which is provided +in most Linux distros, and also available as part of the e2fsprogs +project. + +L<nbdkit-guestfs-plugin(1)> is a more generic plugin which can read +files from all kinds of different filesystem types, even if they are +partitioned or use logical volumes. It uses libguestfs instead of +e2fsprogs. + +=head1 PARAMETERS + +=over 4 + +=item B<disk=FILENAME> + +The ext2, ext3 or ext4 filesystem, a file on the host. + +You could also use a device name here if the filesystem is located on +a device. Be careful that the filesystem is not being accessed in +parallel by another program and is not mounted, as that will almost +certainly result in disk corruption in the filesystem. + +The plugin expects a raw filesystem. If the file/device is +partitioned, use L<nbdkit-partition-filter(1)>. + +=item B<file=PATH> + +The full path of the file within the filesystem that will be exposed +over NBD. The path must be absolute (starts with C</>). + +=back + +=head1 SEE ALSO + +L<nbdkit(1)>, +L<nbdkit-plugin(3)>, +L<nbdkit-partition-filter(1)>, +L<nbdkit-guestfs-plugin(1)>, +L<http://e2fsprogs.sourceforge.net/>, +L<fuse2fs(1)>. + +=head1 AUTHORS + +Richard W.M. Jones + +=head1 COPYRIGHT + +Copyright (C) 2018 Red Hat Inc. + +=head1 LICENSE + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +=over 4 + +=item * + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +=item * + +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +=item * + +Neither the name of Red Hat nor the names of its contributors may be +used to endorse or promote products derived from this software without +specific prior written permission. + +=back + +THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. -- 2.16.2
Richard W.M. Jones
2018-Jun-07 15:48 UTC
[Libguestfs] [PATCH nbdkit 4/4] tests: Add test of the ext2 plugin.
--- .gitignore | 2 ++ tests/Makefile.am | 26 ++++++++++++++++ tests/test-ext2.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/.gitignore b/.gitignore index 3b7365f..f41de87 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ Makefile.in /tests/disk /tests/disk.gz /tests/disk.xz +/tests/ext2.img /tests/file-data /tests/offset-data /tests/partition-disk @@ -57,6 +58,7 @@ Makefile.in /tests/test-connect /tests/test-delay /tests/test-exit-with-parent +/tests/test-ext2 /tests/test-file /tests/test-gzip /tests/test-memory diff --git a/tests/Makefile.am b/tests/Makefile.am index 1830cd3..850240b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -244,6 +244,32 @@ disk: endif HAVE_GUESTFISH +# ext2 plugin test. +if HAVE_EXT2 +if HAVE_GUESTFISH + +LIBGUESTFS_TESTS += test-ext2 +check_DATA += ext2.img +MAINTAINERCLEANFILES += ext2.img + +ext2.img: disk + rm -f $@ $@-t + guestfish \ + sparse $@-t 2G : \ + run : \ + mkfs ext4 /dev/sda : \ + mount /dev/sda / : \ + mkdir /disks : \ + upload $< /disks/disk.img + mv $@-t $@ + +test_ext2_SOURCES = test-ext2.c test.h +test_ext2_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS) +test_ext2_LDADD = libtest.la $(LIBGUESTFS_LIBS) + +endif HAVE_GUESTFISH +endif HAVE_EXT2 + # file plugin test. LIBGUESTFS_TESTS += test-file diff --git a/tests/test-ext2.c b/tests/test-ext2.c new file mode 100644 index 0000000..b222533 --- /dev/null +++ b/tests/test-ext2.c @@ -0,0 +1,92 @@ +/* nbdkit + * Copyright (C) 2013-2018 Red Hat Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <inttypes.h> +#include <string.h> +#include <unistd.h> + +#include <guestfs.h> + +#include "test.h" + +int +main (int argc, char *argv[]) +{ + guestfs_h *g; + int r; + char *data; + + if (test_start_nbdkit ("ext2", "-r", "disk=ext2.img", "file=/disks/disk.img", + NULL) == -1) + exit (EXIT_FAILURE); + + g = guestfs_create (); + if (g == NULL) { + perror ("guestfs_create"); + exit (EXIT_FAILURE); + } + + r = guestfs_add_drive_opts (g, "", + GUESTFS_ADD_DRIVE_OPTS_READONLY, 1, + GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", + GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "nbd", + GUESTFS_ADD_DRIVE_OPTS_SERVER, server, + -1); + if (r == -1) + exit (EXIT_FAILURE); + + if (guestfs_launch (g) == -1) + exit (EXIT_FAILURE); + + /* disk.img contains one partition and a test file called "hello.txt" */ + if (guestfs_mount_ro (g, "/dev/sda1", "/") == -1) + exit (EXIT_FAILURE); + + data = guestfs_cat (g, "/hello.txt"); + if (!data) + exit (EXIT_FAILURE); + + if (strcmp (data, "hello,world") != 0) { + fprintf (stderr, "%s FAILED: unexpected content of /hello.txt file (actual: %s, expected: \"hello,world\")\n", + program_name, data); + exit (EXIT_FAILURE); + } + + guestfs_close (g); + exit (EXIT_SUCCESS); +} -- 2.16.2