retry: Don't call into closed plugin
[nbdkit/ericb.git] / tests / test-error.c
blob12976bf4d760cbaa80d7411a564711f4e8fb221c
1 /* nbdkit
2 * Copyright (C) 2018 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <inttypes.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <time.h>
43 #include <guestfs.h>
45 #include "test.h"
47 int
48 main (int argc, char *argv[])
50 guestfs_h *g;
51 int r;
52 FILE *fp;
53 char *data;
54 #if 0
55 int error;
56 #endif
57 char tmpdir[] = "/tmp/errorXXXXXX";
58 char error_file[] = "/tmp/errorXXXXXX/trigger";
59 char error_file_param[] = "error-file=/tmp/errorXXXXXX/trigger";
61 /* Create temporary directory to store the trigger file. */
62 if (mkdtemp (tmpdir) == NULL) {
63 perror ("mkdtemp");
64 exit (EXIT_FAILURE);
67 memcpy (error_file, tmpdir, strlen (tmpdir));
68 memcpy (&error_file_param[11], tmpdir, strlen (tmpdir));
70 if (test_start_nbdkit ("--filter", "error",
71 "memory", "1M",
72 "error=EIO",
73 "error-rate=100%",
74 error_file_param,
75 NULL) == -1)
76 exit (EXIT_FAILURE);
78 g = guestfs_create ();
79 if (g == NULL) {
80 perror ("guestfs_create");
81 exit (EXIT_FAILURE);
84 r = guestfs_add_drive_opts (g, "",
85 GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
86 GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "nbd",
87 GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
88 -1);
89 if (r == -1)
90 exit (EXIT_FAILURE);
92 if (guestfs_launch (g) == -1)
93 exit (EXIT_FAILURE);
95 /* Format the disk with a filesystem. No errors are being injected
96 * yet so we expect this to work.
98 if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1)
99 exit (EXIT_FAILURE);
101 if (guestfs_mkfs (g, "ext2", "/dev/sda1") == -1)
102 exit (EXIT_FAILURE);
104 if (guestfs_mount (g, "/dev/sda1", "/") == -1)
105 exit (EXIT_FAILURE);
107 #define filename "/hello.txt"
108 #define content "hello, people of the world"
110 if (guestfs_write (g, filename, content, strlen (content)) == -1)
111 exit (EXIT_FAILURE);
113 /* Try as hard as we can to sync data and kill the libguestfs cache. */
114 if (guestfs_sync (g) == -1)
115 exit (EXIT_FAILURE);
116 if (guestfs_drop_caches (g, 3) == -1)
117 exit (EXIT_FAILURE);
118 sleep (1);
120 /* Now start injecting EIO errors. */
121 fp = fopen (error_file, "w");
122 if (fp == NULL) {
123 perror (error_file);
124 exit (EXIT_FAILURE);
126 fclose (fp);
128 data = guestfs_cat (g, filename);
129 if (data != NULL) {
130 fprintf (stderr,
131 "%s: error: "
132 "expecting Input/output error, but read data!\n",
133 program_name);
134 exit (EXIT_FAILURE);
137 #if 0
138 /* Apparently libguestfs doesn't preserve the errno here yet XXX */
139 error = guestfs_last_errno (g);
140 if (error != EIO) {
141 fprintf (stderr, "%s: error: expecting errno = EIO, but got %d\n",
142 program_name, error);
143 exit (EXIT_FAILURE);
145 #endif
147 /* Stop injecting errors, hope that the filesystem recovers. */
148 unlink (error_file);
150 /* But we'll probably have to remount the filesystem because ext2
151 * will get itself into a "state".
153 if (guestfs_umount (g, "/") == -1)
154 exit (EXIT_FAILURE);
155 if (guestfs_mount (g, "/dev/sda1", "/") == -1)
156 exit (EXIT_FAILURE);
158 data = guestfs_cat (g, filename);
159 if (data == NULL)
160 exit (EXIT_FAILURE);
161 if (strcmp (data, content) != 0) {
162 fprintf (stderr, "%s: error: read unexpected data\n", program_name);
163 exit (EXIT_FAILURE);
166 guestfs_close (g);
168 rmdir (tmpdir);
170 exit (EXIT_SUCCESS);