1 /* libguestfs-test-tool
2 * Copyright (C) 2009-2011 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <sys/types.h>
39 #define _(str) dgettext(PACKAGE, (str))
40 //#define N_(str) dgettext(PACKAGE, (str))
48 #define textdomain(Domainname) /* empty */
50 #define bindtextdomain(Domainname, Dirname) /* empty */
53 #define STREQ(a,b) (strcmp((a),(b)) == 0)
54 //#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
55 //#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
56 //#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
57 #define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
58 //#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
59 //#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
60 //#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
61 //#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
64 #define P_tmpdir "/tmp"
67 #define DEFAULT_TIMEOUT 600
69 static int timeout = DEFAULT_TIMEOUT;
70 static char tmpf[] = P_tmpdir "/libguestfs-test-tool-sda-XXXXXX";
73 static void make_files (void);
74 static void set_qemu (const char *path, int use_wrapper);
79 printf (_("libguestfs-test-tool: interactive test tool\n"
80 "Copyright (C) 2009-2011 Red Hat Inc.\n"
82 " libguestfs-test-tool [--options]\n"
84 " --help Display usage\n"
85 " --qemudir dir Specify QEMU source directory\n"
86 " --qemu qemu Specify QEMU binary\n"
88 " -t n Set launch timeout (default: %d seconds)\n"
93 extern char **environ;
96 main (int argc, char *argv[])
98 setlocale (LC_ALL, "");
99 bindtextdomain (PACKAGE, LOCALEBASEDIR);
100 textdomain (PACKAGE);
102 static const char *options = "t:?";
103 static const struct option long_options[] = {
104 { "help", 0, 0, '?' },
106 { "qemudir", 1, 0, 0 },
107 { "timeout", 1, 0, 't' },
113 struct guestfs_version *vers;
117 c = getopt_long (argc, argv, options, long_options, &option_index);
121 case 0: /* options which are long only */
122 if (STREQ (long_options[option_index].name, "qemu"))
123 set_qemu (optarg, 0);
124 else if (STREQ (long_options[option_index].name, "qemudir"))
125 set_qemu (optarg, 1);
128 _("libguestfs-test-tool: unknown long option: %s (%d)\n"),
129 long_options[option_index].name, option_index);
135 if (sscanf (optarg, "%d", &timeout) != 1 || timeout < 0) {
137 _("libguestfs-test-tool: invalid timeout: %s\n"),
149 _("libguestfs-test-tool: unexpected command line option 0x%x\n"),
157 printf ("===== Test starts here =====\n");
159 /* Must set LIBGUESTFS_DEBUG=1 */
160 setenv ("LIBGUESTFS_DEBUG", "1", 1);
162 /* Print out any environment variables which may relate to this test. */
163 for (i = 0; environ[i] != NULL; ++i)
164 if (STREQLEN (environ[i], "LIBGUESTFS_", 11))
165 printf ("%s\n", environ[i]);
166 for (i = 0; environ[i] != NULL; ++i)
167 if (STREQLEN (environ[i], "FEBOOTSTRAP_", 12))
168 printf ("%s\n", environ[i]);
169 printf ("TMPDIR=%s\n", getenv ("TMPDIR") ? : "(not set)");
171 /* Create the handle and configure it. */
172 g = guestfs_create ();
175 _("libguestfs-test-tool: failed to create libguestfs handle\n"));
178 if (guestfs_add_drive_opts (g, tmpf,
179 GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
182 _("libguestfs-test-tool: failed to add drive '%s'\n"),
187 /* Print any version info etc. */
188 vers = guestfs_version (g);
190 fprintf (stderr, _("libguestfs-test-tool: guestfs_version failed\n"));
193 printf ("library version: %"PRIi64".%"PRIi64".%"PRIi64"%s\n",
194 vers->major, vers->minor, vers->release, vers->extra);
195 guestfs_free_version (vers);
197 printf ("guestfs_get_append: %s\n", guestfs_get_append (g) ? : "(null)");
198 p = guestfs_get_attach_method (g);
199 printf ("guestfs_get_attach_method: %s\n", p ? : "(null)");
201 printf ("guestfs_get_autosync: %d\n", guestfs_get_autosync (g));
202 printf ("guestfs_get_direct: %d\n", guestfs_get_direct (g));
203 printf ("guestfs_get_memsize: %d\n", guestfs_get_memsize (g));
204 printf ("guestfs_get_network: %d\n", guestfs_get_network (g));
205 printf ("guestfs_get_path: %s\n", guestfs_get_path (g));
206 printf ("guestfs_get_pgroup: %d\n", guestfs_get_pgroup (g));
207 printf ("guestfs_get_qemu: %s\n", guestfs_get_qemu (g));
208 printf ("guestfs_get_recovery_proc: %d\n", guestfs_get_recovery_proc (g));
209 printf ("guestfs_get_selinux: %d\n", guestfs_get_selinux (g));
210 printf ("guestfs_get_smp: %d\n", guestfs_get_smp (g));
211 printf ("guestfs_get_trace: %d\n", guestfs_get_trace (g));
212 printf ("guestfs_get_verbose: %d\n", guestfs_get_verbose (g));
214 printf ("host_cpu: %s\n", host_cpu);
216 /* Launch the guest handle. */
217 printf ("Launching appliance, timeout set to %d seconds.\n", timeout);
222 if (guestfs_launch (g) == -1) {
224 _("libguestfs-test-tool: failed to launch appliance\n"));
230 printf ("Guest launched OK.\n");
233 /* Create the filesystem and mount everything. */
234 if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1) {
236 _("libguestfs-test-tool: failed to run part-disk\n"));
240 if (guestfs_mkfs (g, "ext2", "/dev/sda1") == -1) {
242 _("libguestfs-test-tool: failed to mkfs.ext2\n"));
246 if (guestfs_mount_options (g, "", "/dev/sda1", "/") == -1) {
248 _("libguestfs-test-tool: failed to mount /dev/sda1 on /\n"));
253 if (guestfs_touch (g, "/hello") == -1) {
255 _("libguestfs-test-tool: failed to touch file\n"));
259 /* Close the handle. */
262 /* Booted and performed some simple operations -- success! */
263 printf ("===== TEST FINISHED OK =====\n");
267 static char qemuwrapper[] = P_tmpdir "/libguestfs-test-tool-wrapper-XXXXXX";
270 cleanup_wrapper (void)
272 unlink (qemuwrapper);
275 /* Handle the --qemu and --qemudir parameters. use_wrapper is true
276 * in the --qemudir (source directory) case, where we have to create
277 * a wrapper shell script.
280 set_qemu (const char *path, int use_wrapper)
282 char buffer[PATH_MAX];
287 if (getenv ("LIBGUESTFS_QEMU")) {
289 _("LIBGUESTFS_QEMU environment variable is already set, so\n"
290 "--qemu/--qemudir options cannot be used.\n"));
295 if (access (path, X_OK) == -1) {
297 _("Binary '%s' does not exist or is not executable\n"),
302 setenv ("LIBGUESTFS_QEMU", path, 1);
306 /* This should be a source directory, so check it. */
307 snprintf (buffer, sizeof buffer, "%s/pc-bios", path);
308 if (stat (buffer, &statbuf) == -1 ||
309 !S_ISDIR (statbuf.st_mode)) {
311 _("%s: does not look like a qemu source directory\n"),
316 /* Make a wrapper script. */
317 fd = mkstemp (qemuwrapper);
319 perror (qemuwrapper);
325 fp = fdopen (fd, "w");
332 /* Select the right qemu binary for the wrapper script. */
334 fprintf (fp, "i386-softmmu/qemu");
336 fprintf (fp, host_cpu "-softmmu/qemu-system-" host_cpu);
339 fprintf (fp, " -L \"$qemudir\"/pc-bios \"$@\"\n");
343 setenv ("LIBGUESTFS_QEMU", qemuwrapper, 1);
344 atexit (cleanup_wrapper);
348 cleanup_tmpfiles (void)
358 /* Allocate the sparse file for /dev/sda. */
365 if (lseek (fd, 100 * 1024 * 1024 - 1, SEEK_SET) == -1) {
372 if (write (fd, "\0", 1) == -1) {
381 atexit (cleanup_tmpfiles); /* Removes tmpf. */