summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-05-13 22:53:01 +0100
committerRichard W.M. Jones <rjones@redhat.com>2012-05-13 22:53:01 +0100
commit46b6766156ace142443b36e20e55074c544ae6cc (patch)
treea2f0918a8f10b690147388963cf33722e6f602d1 /examples
parent7201a48d18d03bf3b16141bcff8c56e842d3b1c1 (diff)
downloadlibguestfs-46b6766156ace142443b36e20e55074c544ae6cc.tar.gz
libguestfs-46b6766156ace142443b36e20e55074c544ae6cc.tar.xz
libguestfs-46b6766156ace142443b36e20e55074c544ae6cc.zip
examples: Add an example of using the mount-local API from C.
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile.am15
-rw-r--r--examples/mount_local.c156
2 files changed, 171 insertions, 0 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index b6d9a865..81f22747 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -37,6 +37,9 @@ endif
if HAVE_HIVEX
noinst_PROGRAMS += virt-dhcp-address
endif
+if HAVE_FUSE
+noinst_PROGRAMS += mount_local
+endif
if HAVE_LIBVIRT
copy_over_SOURCES = copy_over.c
@@ -75,6 +78,18 @@ inspect_vm_CFLAGS = \
inspect_vm_LDADD = \
$(top_builddir)/src/libguestfs.la
+if HAVE_FUSE
+mount_local_SOURCES = mount_local.c
+mount_local_CFLAGS = \
+ -DGUESTFS_WARN_DEPRECATED=1 \
+ -I$(top_srcdir)/src -I$(top_builddir)/src \
+ $(FUSE_CFLAGS) \
+ $(WARN_CFLAGS) $(WERROR_CFLAGS)
+mount_local_LDADD = \
+ $(FUSE_LIBS) -lulockmgr \
+ $(top_builddir)/src/libguestfs.la
+endif
+
if HAVE_HIVEX
virt_dhcp_address_SOURCES = virt-dhcp-address.c
virt_dhcp_address_CFLAGS = \
diff --git a/examples/mount_local.c b/examples/mount_local.c
new file mode 100644
index 00000000..526e426f
--- /dev/null
+++ b/examples/mount_local.c
@@ -0,0 +1,156 @@
+/* Demonstrate the use of the 'mount-local' API.
+ *
+ * Run this program as (eg) mount_local /tmp/test.img. Note that
+ * '/tmp/test.img' is created or overwritten. Follow the instructions
+ * on screen.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+
+#include <guestfs.h>
+
+static void
+usage (void)
+{
+ fprintf (stderr,
+ "Usage: mount_local disk.img\n"
+ "\n"
+ "NOTE: disk.img will be created or overwritten.\n"
+ "\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+ guestfs_h *g;
+ int fd;
+ char tempdir[] = "/tmp/mlXXXXXX";
+ pid_t pid;
+ char *shell;
+
+ if (argc != 2) {
+ usage ();
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("\n"
+ "This is the 'mount-local' demonstration program. Follow the\n"
+ "instructions on screen.\n"
+ "\n"
+ "Creating and formatting the disk image, please wait a moment ...\n");
+ fflush (stdout);
+
+ /* Create the output disk image: 512 MB raw sparse. */
+ fd = open (argv[1], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
+ if (fd == -1) {
+ perror (argv[1]);
+ exit (EXIT_FAILURE);
+ }
+ if (ftruncate (fd, 512 * 1024 * 1024) == -1) {
+ perror ("truncate");
+ close (fd);
+ exit (EXIT_FAILURE);
+ }
+ if (close (fd) == -1) {
+ perror ("close");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Open the disk image and format it with a partition and a filesystem. */
+ g = guestfs_create ();
+ if (g == NULL) {
+ perror ("could not create libguestfs handle");
+ exit (EXIT_FAILURE);
+ }
+
+ if (guestfs_add_drive_opts (g, argv[1],
+ GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
+ -1) == -1)
+ exit (EXIT_FAILURE);
+
+ if (guestfs_launch (g) == -1)
+ exit (EXIT_FAILURE);
+
+ if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1)
+ exit (EXIT_FAILURE);
+
+ if (guestfs_mkfs (g, "ext2", "/dev/sda1") == -1)
+ exit (EXIT_FAILURE);
+
+ /* Mount the empty filesystem. */
+ if (guestfs_mount (g, "/dev/sda1", "/") == -1)
+ exit (EXIT_FAILURE);
+
+ /* Create a temporary mount directory. */
+ if (mkdtemp (tempdir) == NULL) {
+ perror ("mkdtemp");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Mount the filesystem. */
+ if (guestfs_mount_local (g, tempdir, -1) == -1)
+ exit (EXIT_FAILURE);
+
+ /* Fork the shell for the user. */
+ pid = fork ();
+ if (pid == -1) {
+ perror ("fork");
+ exit (EXIT_FAILURE);
+ }
+
+ if (pid == 0) { /* Child. */
+ if (chdir (tempdir) == -1) {
+ perror (tempdir);
+ _exit (EXIT_FAILURE);
+ }
+
+ printf ("\n"
+ "The _current directory_ is a FUSE filesystem backed by the disk\n"
+ "image which is managed by libguestfs. Any files or directories\n"
+ "you copy into here (up to 512 MB) will be saved into the disk\n"
+ "image. You can also delete files, create certain special files\n"
+ "and so on.\n"
+ "\n"
+ "When you have finished adding files, hit ^D or exit to exit the\n"
+ "shell and return to the mount-local program.\n"
+ "\n");
+
+ shell = getenv ("SHELL");
+ system (shell ? : "/bin/sh");
+
+ chdir ("/");
+ guestfs_umount_local (g, GUESTFS_UMOUNT_LOCAL_RETRY, 1, -1);
+ _exit (EXIT_SUCCESS);
+ }
+
+ /* Note that we are *not* waiting for the child yet. We want to
+ * run the FUSE code in parallel with the subshell.
+ */
+ if (guestfs_mount_local_run (g) == -1)
+ exit (EXIT_FAILURE);
+
+ waitpid (pid, NULL, 0);
+
+ /* Unmount and close. */
+ if (guestfs_umount (g, "/") == -1)
+ exit (EXIT_FAILURE);
+
+ guestfs_close (g);
+
+ printf ("\n"
+ "Any files or directories that you copied in have been saved into\n"
+ "the disk image called '%s'.\n"
+ "\n"
+ "Try opening the disk image with guestfish to see those files:\n"
+ "\n"
+ " guestfish -a %s -m /dev/sda1\n"
+ "\n",
+ argv[1], argv[1]);
+
+ exit (EXIT_SUCCESS);
+}