[Libguestfs] [PATCH nbdkit 2/2] tar: Rewrite the tar plugin (again), this time in C.

Richard W.M. Jones rjones at redhat.com
Sun Jun 28 13:02:51 UTC 2020


---
 plugins/tar/{tar.pl => nbdkit-tar-plugin.pod} | 145 ++-------
 configure.ac                                  |   2 -
 plugins/tar/Makefile.am                       |  41 +--
 tests/Makefile.am                             |  14 +-
 plugins/tar/tar.c                             | 286 ++++++++++++++++++
 tests/test-dump-plugin.sh                     |   2 +-
 tests/test-help-plugin.sh                     |   2 +-
 tests/test-tar-info.sh                        |  67 ++++
 tests/test-tar.sh                             |  22 +-
 tests/test-version-plugin.sh                  |   2 +-
 wrapper.c                                     |   2 +-
 .gitignore                                    |   1 -
 README                                        |   4 +-
 13 files changed, 427 insertions(+), 163 deletions(-)

diff --git a/plugins/tar/tar.pl b/plugins/tar/nbdkit-tar-plugin.pod
similarity index 52%
rename from plugins/tar/tar.pl
rename to plugins/tar/nbdkit-tar-plugin.pod
index 9b05b83d..589e114b 100644
--- a/plugins/tar/tar.pl
+++ b/plugins/tar/nbdkit-tar-plugin.pod
@@ -1,21 +1,16 @@
-#!@sbindir@/nbdkit perl
-# -*- perl -*-
-
-=pod
-
 =head1 NAME
 
 nbdkit-tar-plugin - read and write files inside tar files without unpacking
 
 =head1 SYNOPSIS
 
- nbdkit tar tar=FILENAME.tar file=PATH_INSIDE_TAR
+ nbdkit tar [tar=]FILENAME.tar file=PATH_INSIDE_TAR
 
 =head1 EXAMPLES
 
 =head2 Serve a single file inside a tarball
 
- nbdkit tar tar=file.tar file=some/disk.img
+ nbdkit tar file.tar file=some/disk.img
  guestfish --format=raw -a nbd://localhost
 
 =head2 Opening a disk image inside an OVA file
@@ -28,7 +23,7 @@ could access one file in an OVA like this:
  rhel.ovf
  rhel-disk1.vmdk
  rhel.mf
- $ nbdkit -r tar tar=rhel.ova file=rhel-disk1.vmdk
+ $ nbdkit -r tar rhel.ova file=rhel-disk1.vmdk
  $ guestfish --ro --format=vmdk -a nbd://localhost
 
 In this case the tarball is opened readonly (I<-r> option).  The
@@ -55,6 +50,27 @@ modified.  Without I<-r> writes will modify the tar file.
 
 The disk image cannot be resized.
 
+=head1 PARAMETERS
+
+=over 4
+
+=item [B<tar=>]FILENAME.tar
+
+The path of the tarball.  This parameter is required.
+
+C<tar=> is a magic config key and may be omitted in most cases.
+See L<nbdkit(1)/Magic parameters>.
+
+=item B<file=>PATH_INSIDE_TAR
+
+The path of the file inside the tarball to serve.  This parameter is
+required.  It must exactly match the name stored in the tarball, so
+use S<C<tar tf filename.tar>>
+
+=back
+
+=head1 NOTE
+
 =head2 Alternatives to the tar plugin
 
 The tar plugin ought to be a filter so that you can extract files from
@@ -94,11 +110,9 @@ C<nbdkit-tar-plugin> first appeared in nbdkit 1.2.
 
 =head1 SEE ALSO
 
-L<https://github.com/libguestfs/nbdkit/blob/master/plugins/tar/tar.pl>,
 L<nbdkit(1)>,
 L<nbdkit-offset-filter(1)>,
 L<nbdkit-plugin(3)>,
-L<nbdkit-perl-plugin(3)>,
 L<nbdkit-xz-filter(1)>,
 L<tar(1)>.
 
@@ -111,114 +125,3 @@ Based on the virt-v2v OVA importer written by Tomáš Golembiovský.
 =head1 COPYRIGHT
 
 Copyright (C) 2017-2020 Red Hat Inc.
-
-=cut
-
-use strict;
-
-use Cwd qw(abs_path);
-use IO::File;
-
-my $tar;                        # Tar file.
-my $file;                       # File within the tar file.
-my $offset;                     # Offset within tar file.
-my $size;                       # Size of disk image within tar file.
-
-sub config
-{
-    my $k = shift;
-    my $v = shift;
-
-    if ($k eq "tar") {
-        $tar = abs_path ($v);
-    }
-    elsif ($k eq "file") {
-        $file = $v;
-    }
-    else {
-        die "unknown parameter $k";
-    }
-}
-
-# Check all the config parameters were set.
-sub config_complete
-{
-    die "tar or file parameter was not set\n"
-        unless defined $tar && defined $file;
-
-    die "$tar: file not found\n"
-        unless -f $tar;
-}
-
-# Find the extent of the file within the tar file.
-sub get_ready
-{
-    open (my $pipe, "-|", "tar", "--no-auto-compress", "-tRvf", $tar, $file)
-        or die "$tar: could not open or parse tar file, see errors above";
-    while (<$pipe>) {
-        if (/^block\s(\d+):\s\S+\s\S+\s(\d+)/) {
-            # Add one for the tar header, and multiply by the block size.
-            $offset = ($1 + 1) * 512;
-            $size = $2;
-            Nbdkit::debug ("tar: file: $file offset: $offset size: $size")
-        }
-    }
-    close ($pipe);
-
-    die "offset or size could not be parsed.  Probably the tar file is not a tar file or the file does not exist in the tar file.  See any errors above.\n"
-        unless defined $offset && defined $size;
-}
-
-# Accept a connection from a client, create and return the handle
-# which is passed back to other calls.
-sub open
-{
-    my $readonly = shift;
-    my $mode = "<";
-    $mode = "+<" unless $readonly;
-    my $fh = IO::File->new;
-    $fh->open ($tar, $mode) or die "$tar: open: $!";
-    $fh->binmode;
-    my $h = { fh => $fh, readonly => $readonly };
-    return $h;
-}
-
-# Close the connection.
-sub close
-{
-    my $h = shift;
-    my $fh = $h->{fh};
-    $fh->close;
-}
-
-# Return the size.
-sub get_size
-{
-    my $h = shift;
-    return $size;
-}
-
-# Read.
-sub pread
-{
-    my $h = shift;
-    my $fh = $h->{fh};
-    my $count = shift;
-    my $offs = shift;
-    $fh->seek ($offset + $offs, 0) or die "seek: $!";
-    my $r;
-    $fh->read ($r, $count) or die "read: $!";
-    return $r;
-}
-
-# Write.
-sub pwrite
-{
-    my $h = shift;
-    my $fh = $h->{fh};
-    my $buf = shift;
-    my $count = length ($buf);
-    my $offs = shift;
-    $fh->seek ($offset + $offs, 0) or die "seek: $!";
-    print $fh ($buf);
-}
diff --git a/configure.ac b/configure.ac
index af7e6e3b..237ecd75 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1221,8 +1221,6 @@ feature "nbd .................................... " \
         test "x$HAVE_LIBNBD_TRUE" = "x"
 feature "ssh .................................... " \
         test "x$HAVE_SSH_TRUE" = "x"
-feature "tar .................................... " \
-        test "x$HAVE_PERL_TRUE" = "x"
 feature "torrent ................................ " \
         test "x$HAVE_TORRENT_TRUE" = "x"
 feature "vddk ................................... " \
diff --git a/plugins/tar/Makefile.am b/plugins/tar/Makefile.am
index 09a6caa9..14d57e04 100644
--- a/plugins/tar/Makefile.am
+++ b/plugins/tar/Makefile.am
@@ -1,5 +1,5 @@
 # nbdkit
-# Copyright (C) 2013-2020 Red Hat Inc.
+# Copyright (C) 2018-2020 Red Hat Inc.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
@@ -31,34 +31,37 @@
 
 include $(top_srcdir)/common-rules.mk
 
-source = tar.pl
+EXTRA_DIST = nbdkit-tar-plugin.pod
 
-EXTRA_DIST = \
-	$(source) \
-	$(NULL)
-
-if HAVE_PERL
+plugin_LTLIBRARIES = nbdkit-tar-plugin.la
 
-plugin_SCRIPTS = nbdkit-tar-plugin
-CLEANFILES += nbdkit-tar-plugin
+nbdkit_tar_plugin_la_SOURCES = \
+	tar.c \
+	$(top_srcdir)/include/nbdkit-plugin.h \
+	$(NULL)
 
-# We have to do the rewriting here to avoid stupid exec_prefix.
-nbdkit-tar-plugin: $(source)
-	rm -f $@ $@-t
-	sed 's,\@sbindir\@,${sbindir},g' < $< > $@-t
-	mv $@-t $@
-	chmod 0555 $@
+nbdkit_tar_plugin_la_CPPFLAGS = \
+	-I$(top_srcdir)/common/utils \
+	-I$(top_srcdir)/include \
+	-I. \
+	$(NULL)
+nbdkit_tar_plugin_la_CFLAGS = $(WARNINGS_CFLAGS)
+nbdkit_tar_plugin_la_LDFLAGS = \
+	-module -avoid-version -shared $(SHARED_LDFLAGS) \
+	-Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \
+	$(NULL)
+nbdkit_tar_plugin_la_LIBADD = \
+	$(top_builddir)/common/utils/libutils.la \
+	$(NULL)
 
 if HAVE_POD
 
 man_MANS = nbdkit-tar-plugin.1
 CLEANFILES += $(man_MANS)
 
-nbdkit-tar-plugin.1: $(source)
-	$(PODWRAPPER) --section=1 --name nbdkit-tar-plugin --man $@ \
+nbdkit-tar-plugin.1: nbdkit-tar-plugin.pod
+	$(PODWRAPPER) --section=1 --man $@ \
 	    --html $(top_builddir)/html/$@.html \
 	    $<
 
 endif HAVE_POD
-
-endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 16043f49..9ab6a7af 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -828,11 +828,15 @@ test_streaming_SOURCES = test-streaming.c
 test_streaming_CFLAGS = $(WARNINGS_CFLAGS) $(LIBNBD_CFLAGS)
 test_streaming_LDADD = $(LIBNBD_LIBS)
 
-# tar plugin test (written in perl).
-if HAVE_PERL
-TESTS += test-tar.sh
-endif HAVE_PERL
-EXTRA_DIST += test-tar.sh
+# tar plugin test.
+TESTS += \
+	test-tar.sh \
+	test-tar-info.sh \
+	$(NULL)
+EXTRA_DIST += \
+	test-tar.sh \
+	test-tar-info.sh \
+	$(NULL)
 
 # tmpdisk plugin test.
 LIBGUESTFS_TESTS += test-tmpdisk
diff --git a/plugins/tar/tar.c b/plugins/tar/tar.c
new file mode 100644
index 00000000..fe298035
--- /dev/null
+++ b/plugins/tar/tar.c
@@ -0,0 +1,286 @@
+/* nbdkit
+ * Copyright (C) 2018-2020 Red Hat Inc.
+ *
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <nbdkit-plugin.h>
+
+#include "cleanup.h"
+#include "utils.h"
+
+static char *tarfile;           /* The tar file (tar= parameter). */
+static const char *file;        /* File within tar (file=). */
+static uint64_t offset, size;   /* Offset and size within tarball. */
+
+static void
+tar_unload (void)
+{
+  free (tarfile);
+}
+
+static int
+tar_config (const char *key, const char *value)
+{
+  if (strcmp (key, "tar") == 0) {
+    if (tarfile) {
+      nbdkit_error ("only one tar parameter can be given");
+      return -1;
+    }
+    tarfile = nbdkit_realpath (value);
+    if (tarfile == NULL)
+      return -1;
+  }
+  else if (strcmp (key, "file") == 0) {
+    if (file) {
+      nbdkit_error ("only one file parameter can be given");
+      return -1;
+    }
+    file = value;
+  }
+  else {
+    nbdkit_error ("unknown parameter '%s'", key);
+    return -1;
+  }
+
+  return 0;
+}
+
+static int
+tar_config_complete (void)
+{
+  if (tarfile == NULL || file == NULL) {
+    nbdkit_error ("you must supply the tar=<TARFILE> and file=<FILENAME> "
+                  "parameters");
+    return -1;
+  }
+
+  return 0;
+}
+
+#define tar_config_help \
+  "[tar=]<TARBALL>     (required) The name of the tar file.\n" \
+  "file=<FILENAME>                The path inside the tar file to server."
+
+static int
+tar_get_ready (void)
+{
+  FILE *fp;
+  CLEANUP_FREE char *cmd = NULL;
+  size_t len = 0;
+  bool scanned_ok;
+  char s[256];
+
+  /* Construct the tar command to examine the tar file. */
+  fp = open_memstream (&cmd, &len);
+  if (fp == NULL) {
+    nbdkit_error ("open_memstream: %m");
+    return -1;
+  }
+  fprintf (fp, "LANG=C tar --no-auto-compress -tRvf ");
+  shell_quote (tarfile, fp);
+  fputc (' ', fp);
+  shell_quote (file, fp);
+  if (fclose (fp) == EOF) {
+    nbdkit_error ("memstream failed: %m");
+    return -1;
+  }
+
+  /* Run the command and read the first line of the output. */
+  nbdkit_debug ("%s", cmd);
+  fp = popen (cmd, "r");
+  if (fp == NULL) {
+    nbdkit_error ("tar: %m");
+    return -1;
+  }
+  scanned_ok = fscanf (fp, "block %" SCNu64 ": %*s %*s %" SCNu64,
+                       &offset, &size) == 2;
+  /* We have to now read and discard the rest of the output until EOF. */
+  while (fread (s, sizeof s, 1, fp) > 0)
+    ;
+  if (pclose (fp) != 0) {
+    nbdkit_error ("tar subcommand failed, "
+                  "check that the file really exists in the tarball");
+    return -1;
+  }
+
+  if (!scanned_ok) {
+    nbdkit_error ("unexpected output from the tar subcommand");
+    return -1;
+  }
+
+  /* Adjust the offset: Add 1 for the tar header, then multiply by the
+   * block size.
+   */
+  offset = (offset+1) * 512;
+
+  nbdkit_debug ("tar: offset %" PRIu64 ", size %" PRIu64, offset, size);
+
+  /* Check it looks sensible.  XXX We ought to check it doesn't exceed
+   * the size of the tar file.
+   */
+  if (offset >= INT64_MAX || size >= INT64_MAX) {
+    nbdkit_error ("internal error: calculated offset and size are wrong");
+    return -1;
+  }
+
+  return 0;
+}
+
+struct handle {
+  int fd;
+};
+
+static void *
+tar_open (int readonly)
+{
+  struct handle *h;
+
+  assert (offset > 0);     /* Cannot be zero because of tar header. */
+
+  h = calloc (1, sizeof *h);
+  if (h == NULL) {
+    nbdkit_error ("calloc: %m");
+    return NULL;
+  }
+  h->fd = open (tarfile, (readonly ? O_RDONLY : O_RDWR) | O_CLOEXEC);
+  if (h->fd == -1) {
+    nbdkit_error ("%s: %m", tarfile);
+    free (h);
+    return NULL;
+  }
+
+  return h;
+}
+
+#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
+
+/* Get the file size. */
+static int64_t
+tar_get_size (void *handle)
+{
+  return size;
+}
+
+/* Serves the same data over multiple connections. */
+static int
+tar_can_multi_conn (void *handle)
+{
+  return 1;
+}
+
+static int
+tar_can_cache (void *handle)
+{
+  /* Let nbdkit call pread to populate the file system cache. */
+  return NBDKIT_CACHE_EMULATE;
+}
+
+/* Read data from the file. */
+static int
+tar_pread (void *handle, void *buf, uint32_t count, uint64_t offs)
+{
+  struct handle *h = handle;
+
+  offs += offset;
+
+  while (count > 0) {
+    ssize_t r = pread (h->fd, buf, count, offs);
+    if (r == -1) {
+      nbdkit_error ("pread: %m");
+      return -1;
+    }
+    if (r == 0) {
+      nbdkit_error ("pread: unexpected end of file");
+      return -1;
+    }
+    buf += r;
+    count -= r;
+    offs += r;
+  }
+
+  return 0;
+}
+
+/* Write data to the file. */
+static int
+tar_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offs)
+{
+  struct handle *h = handle;
+
+  offs += offset;
+
+  while (count > 0) {
+    ssize_t r = pwrite (h->fd, buf, count, offs);
+    if (r == -1) {
+      nbdkit_error ("pwrite: %m");
+      return -1;
+    }
+    buf += r;
+    count -= r;
+    offs += r;
+  }
+
+  return 0;
+}
+
+static struct nbdkit_plugin plugin = {
+  .name              = "tar",
+  .longname          = "nbdkit tar plugin",
+  .version           = PACKAGE_VERSION,
+  .unload            = tar_unload,
+  .config            = tar_config,
+  .config_complete   = tar_config_complete,
+  .config_help       = tar_config_help,
+  .magic_config_key  = "tar",
+  .get_ready         = tar_get_ready,
+  .open              = tar_open,
+  .get_size          = tar_get_size,
+  .can_multi_conn    = tar_can_multi_conn,
+  .can_cache         = tar_can_cache,
+  .pread             = tar_pread,
+  .pwrite            = tar_pwrite,
+  .errno_is_preserved = 1,
+};
+
+NBDKIT_REGISTER_PLUGIN(plugin)
diff --git a/tests/test-dump-plugin.sh b/tests/test-dump-plugin.sh
index 0b4c1ce1..6eb25a65 100755
--- a/tests/test-dump-plugin.sh
+++ b/tests/test-dump-plugin.sh
@@ -46,7 +46,7 @@ do_test ()
         python-valgrind | ruby-valgrind | tcl-valgrind)
             echo "$0: skipping $1$vg because this language doesn't support valgrind"
             ;;
-        example4* | tar*)
+        example4*)
             # These tests are written in Perl so we have to check that
             # the Perl plugin was compiled.
             if nbdkit perl --version; then run_test $1; fi
diff --git a/tests/test-help-plugin.sh b/tests/test-help-plugin.sh
index 7dc26ece..f0dfa7df 100755
--- a/tests/test-help-plugin.sh
+++ b/tests/test-help-plugin.sh
@@ -46,7 +46,7 @@ do_test ()
         python-valgrind | ruby-valgrind | tcl-valgrind)
             echo "$0: skipping $1$vg because this language doesn't support valgrind"
             ;;
-        example4* | tar*)
+        example4*)
             # These tests are written in Perl so we have to check that
             # the Perl plugin was compiled.
             if nbdkit perl --version; then run_test $1; fi
diff --git a/tests/test-tar-info.sh b/tests/test-tar-info.sh
new file mode 100755
index 00000000..efaa8ec8
--- /dev/null
+++ b/tests/test-tar-info.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+# nbdkit
+# Copyright (C) 2017-2020 Red Hat Inc.
+#
+# 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.
+
+# Test that qemu-img info works on a qcow2 file in a tar file.
+
+source ./functions.sh
+set -e
+set -x
+
+requires test -f disk
+requires guestfish --version
+requires tar --version
+requires qemu-img --version
+requires qemu-img info --output=json /dev/null
+requires jq --version
+requires stat --version
+
+disk=tar-info-disk.qcow2
+out=tar-info.out
+tar=tar-info.tar
+files="$disk $out $tar"
+rm -f $files
+cleanup_fn rm -f $files
+
+# Create a tar file containing a known qcow2 file.
+qemu-img convert -f raw disk -O qcow2 $disk
+tar cf $tar $disk
+
+# Run nbdkit.
+nbdkit -U - tar $tar file=$disk --run 'qemu-img info --output=json $nbd' > $out
+cat $out
+
+# Check various fields in the input.
+# Virtual size must be the same as the size of the original raw disk.
+test "$( jq -r -c '.["virtual-size"]' $out )" -eq "$( stat -c %s disk )"
+
+# Format must be qcow2.
+test "$( jq -r -c '.["format"]' $out )" = "qcow2"
diff --git a/tests/test-tar.sh b/tests/test-tar.sh
index c6d726c4..3164b826 100755
--- a/tests/test-tar.sh
+++ b/tests/test-tar.sh
@@ -38,23 +38,27 @@ requires test -f disk
 requires guestfish --version
 requires tar --version
 
-# The tar plugin requires some Perl modules, this checks if they are
-# installed.
-requires perl -MCwd -e 1
-requires perl -MIO::File -e 1
-
 sock=`mktemp -u`
 files="tar.pid tar.tar $sock"
 rm -f $files
 cleanup_fn rm -f $files
 
-# Create a tar file containing the disk image.
-tar cf tar.tar disk
+# Create a tar file containing the disk image plus some other random
+# files that hopefully will be ignored.
+tar cf tar.tar test-tar.sh Makefile disk Makefile.am
+tar tvvf tar.tar
 
 # Run nbdkit.
 start_nbdkit -P tar.pid -U $sock tar tar=tar.tar file=disk
 
-# Now see if we can open the disk from the tar file.
-guestfish -x --ro --format=raw -a "nbd://?socket=$sock" -m /dev/sda1 <<EOF
+# Now see if we can open, read and write the disk from the tar file.
+guestfish -x --format=raw -a "nbd://?socket=$sock" -m /dev/sda1 <<EOF
   cat /hello.txt
+
+  # Write a new file.
+  write /test.txt "hello"
+  cat /test.txt
 EOF
+
+# Check that the tar file isn't corrupt.
+tar tvvf tar.tar
diff --git a/tests/test-version-plugin.sh b/tests/test-version-plugin.sh
index 7d2ab072..c397afc2 100755
--- a/tests/test-version-plugin.sh
+++ b/tests/test-version-plugin.sh
@@ -46,7 +46,7 @@ do_test ()
         python-valgrind | ruby-valgrind | tcl-valgrind)
             echo "$0: skipping $1$vg because this language doesn't support valgrind"
             ;;
-        example4* | tar*)
+        example4*)
             # These tests are written in Perl so we have to check that
             # the Perl plugin was compiled.
             if nbdkit perl --version; then run_test $1; fi
diff --git a/wrapper.c b/wrapper.c
index b1e2ce2f..c27afae0 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -85,7 +85,7 @@ static size_t len;
 static bool
 is_perl_plugin (const char *name)
 {
-  return strcmp (name, "example4") == 0 || strcmp (name, "tar") == 0;
+  return strcmp (name, "example4") == 0;
 }
 
 static void
diff --git a/.gitignore b/.gitignore
index f02d19dc..48a5302e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -79,7 +79,6 @@ plugins/*/*.3
 /plugins/ocaml/nbdkit-ocamlexample-plugin.so
 /plugins/rust/Cargo.lock
 /plugins/rust/target
-/plugins/tar/nbdkit-tar-plugin
 /plugins/tmpdisk/default-command.c
 /podwrapper.pl
 /server/local/nbdkit.pc
diff --git a/README b/README
index 4f584828..7733761e 100644
--- a/README
+++ b/README
@@ -124,13 +124,13 @@ For the bittorrent plugin:
 
  - libtorrent-rasterbar (https://www.libtorrent.org)
 
-For the Perl, example4 and tar plugins:
+For the Perl and example4 plugins:
 
  - perl interpreter
 
  - perl development libraries
 
- - perl modules ExtUtils::Embed, IO::File and Cwd
+ - perl modules ExtUtils::Embed
 
 For the Python plugin:
 
-- 
2.25.0




More information about the Libguestfs mailing list