You need to read the instructions at the top, and download the following appliance too: http://libguestfs.org/download/binaries/appliance/appliance-1.18.9.tar.xz So far I've filed the following bugs: https://bugzilla.redhat.com/show_bug.cgi?id=875741 https://bugzilla.redhat.com/show_bug.cgi?id=877110 https://bugzilla.redhat.com/show_bug.cgi?id=877312 https://bugzilla.redhat.com/show_bug.cgi?id=877429 https://bugzilla.redhat.com/show_bug.cgi?id=877430 Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into Xen guests. http://et.redhat.com/~rjones/virt-p2v
/* gcc -Wall test-parallel.c -o test-parallel -lvirt -lpthread */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <errno.h> #include <error.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <pthread.h> #include <libvirt/libvirt.h> #include <libvirt/virterror.h> #define TMPDIR "/tmp" /* You have to download these from * http://libguestfs.org/download/binaries/appliance/appliance-1.18.9.tar.xz * and unpack in TMPDIR. */ #define KERNEL TMPDIR "/appliance/kernel" #define INITRD TMPDIR "/appliance/initrd" #define APPLIANCE TMPDIR "/appliance/root" #define NR_THREADS 8 #define DEBUG 1 #define NOT_ROOT 1 #define LIBVIRT_URI "qemu:///session" #define UNIX_PATH_MAX 108 #define ROOT_DEV "sda" struct thread_state { pthread_t thread; /* Thread handle. */ size_t thread_num; /* Thread number. */ int exit_status; /* Thread exit status. */ }; static struct thread_state threads[NR_THREADS]; static void *start_thread (void *) __attribute__((noreturn)); static volatile sig_atomic_t quit = 0; static void catch_sigint (int signal) { static char cleaning_up[] = "\ngot signal, cleaning up ...\n"; if (quit == 0) { quit = 1; write (2, cleaning_up, sizeof cleaning_up); } } int main (int argc, char *argv[]) { struct sigaction sa; int r; size_t i, errors = 0; void *status; #if NOT_ROOT if (geteuid () == 0) { fprintf (stderr, "don't run this as root!\n"); exit (EXIT_FAILURE); } #endif srandom (time (NULL)); virInitialize (); memset (&sa, 0, sizeof sa); sa.sa_handler = catch_sigint; sa.sa_flags = SA_RESTART; sigaction (SIGINT, &sa, NULL); sigaction (SIGQUIT, &sa, NULL); for (i = 0; i < NR_THREADS; ++i) { threads[i].thread_num = i; /* Start the thread. */ r = pthread_create (&threads[i].thread, NULL, start_thread, &threads[i]); if (r != 0) error (EXIT_FAILURE, r, "pthread_create"); } /* Wait for the threads to exit. */ for (i = 0; i < NR_THREADS; ++i) { r = pthread_join (threads[i].thread, &status); if (r != 0) error (EXIT_FAILURE, r, "pthread_join"); if (*(int *)status != 0) { fprintf (stderr, "%zu: thread returned an error\n", i); errors++; } } exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } /* Run the test in a single thread. */ static void * start_thread (void *statevp) { struct thread_state *state = statevp; size_t i = 0; int r, fd, fd2; struct sockaddr_un addr; struct sockaddr addr2; char snapshot[256]; char sock[256]; char cmd[256]; char xml[2048]; virConnectPtr conn; virDomainPtr dom; char flag[4]; socklen_t addr_size; snprintf (snapshot, sizeof snapshot, TMPDIR "/snapshot%zu.qcow2", state->thread_num); snprintf (sock, sizeof sock, TMPDIR "/sock%zu", state->thread_num); /* Create the virtio socket. */ unlink (sock); fd = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); if (fd == -1) { perror ("socket"); goto error; } addr.sun_family = AF_UNIX; strncpy (addr.sun_path, sock, UNIX_PATH_MAX); addr.sun_path[UNIX_PATH_MAX-1] = '\0'; if (bind (fd, (struct sockaddr *) &addr, sizeof addr) == -1) { perror ("bind"); goto error; } if (listen (fd, 1) == -1) { perror ("listen"); goto error; } while (!quit) { i++; /* Create a snapshot of the appliance disk. */ snprintf (cmd, sizeof cmd, "rm -f %s; " "qemu-img create -f qcow2 -b %s -o backing_fmt=raw %s" " >/dev/null 2>&1", snapshot, APPLIANCE, snapshot); if (system (cmd) != 0) { fprintf (stderr, "command failed: %s\n", cmd); goto error; } snprintf (xml, sizeof xml, "<?xml version=\"1.0\"?>\n" "<domain type=\"kvm\"\n" " xmlns:qemu=\"http://libvirt.org/schemas/domain/qemu/1.0\">\n" " <name>test_%zu_%zu</name>\n" " <memory unit=\"MiB\">500</memory>\n" " <currentMemory unit=\"MiB\">500</currentMemory>\n" " <vcpu>1</vcpu>\n" " <clock offset=\"utc\"/>\n" " <os>\n" " <type>hvm</type>\n" " <kernel>%s</kernel>\n" " <initrd>%s</initrd>\n" " <cmdline>panic=1 console=ttyS0 udevtimeout=600 no_timer_check acpi=off printk.time=1 cgroup_disable=memory root=/dev/" ROOT_DEV " selinux=0 TERM=xterm-256color</cmdline>\n" " </os>\n" " <on_reboot>destroy</on_reboot>\n" " <devices>\n" " <controller type=\"scsi\" index=\"0\" model=\"virtio-scsi\"/>\n" " <disk type=\"file\" device=\"disk\">\n" " <source file=\"%s\"/>\n" " <target dev=\"" ROOT_DEV "\" bus=\"scsi\"/>\n" " <driver name=\"qemu\" type=\"qcow2\" cache=\"unsafe\"/>\n" " <address type=\"drive\" controller=\"0\" bus=\"0\" target=\"0\" unit=\"0\"/>\n" " <shareable/>\n" " </disk>\n" " <channel type=\"unix\">\n" " <source mode=\"connect\" path=\"%s\"/>\n" " <target type=\"virtio\" name=\"org.libguestfs.channel.0\"/>\n" " </channel>\n" " </devices>\n" " <qemu:commandline>\n" " <qemu:env name=\"TMPDIR\" value=\"" TMPDIR "\"/>\n" " </qemu:commandline>\n" "</domain>", state->thread_num, i, KERNEL, INITRD, snapshot, sock); /* Create the libvirt transient domain. */ #if DEBUG printf ("%zu: opening libvirt\n", state->thread_num); #endif conn = virConnectOpen (LIBVIRT_URI); if (!conn) goto error; #if DEBUG printf ("%zu: starting domain\n", state->thread_num); #endif dom = virDomainCreateXML (conn, xml, VIR_DOMAIN_START_AUTODESTROY); if (!dom) goto error; /* Wait for the launch flag to be received, which indicates that * the daemon is running. */ again: #if DEBUG printf ("%zu: waiting for connection back from daemon\n", state->thread_num); #endif addr_size = sizeof addr2; fd2 = accept4 (fd, (struct sockaddr *) &addr2, &addr_size, SOCK_CLOEXEC); if (fd2 == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) goto again; perror ("accept4"); goto error; } r = read (fd2, flag, 4); if (r == -1) { perror ("read"); goto error; } if (r != 4) { fprintf (stderr, "could not read launch flag: probably the transient domain failed to launch\n"); goto error; } close (fd2); /* Destroy the domain. */ #if DEBUG printf ("%zu: destroying domain\n", state->thread_num); #endif if (virDomainDestroyFlags (dom, VIR_DOMAIN_DESTROY_GRACEFUL) == -1) goto error; virDomainFree (dom); virConnectClose (conn); } close (fd); /* Test finished successfully. */ fprintf (stderr, "%zu: thread exiting successfully\n", state->thread_num); state->exit_status = 0; pthread_exit (&state->exit_status); /* Test failed. */ error: fprintf (stderr, "%zu: thread exiting on error\n", state->thread_num); state->exit_status = 1; pthread_exit (&state->exit_status); }
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list