Repository URL to install this package:
|
Version:
1:1.38.2-12.el7 ▾
|
/* 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.
*
* See "MOUNT LOCAL" in guestfs(3).
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <guestfs.h>
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
/* Define a list of filesystem mount options (used on the libguestfs
* side, nothing to do with FUSE). An empty string may be used here
* instead.
*/
#define MOUNT_OPTIONS "acl,user_xattr"
/* Size of the disk (megabytes). */
#define SIZE_MB 512
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 r;
char tempdir[] = "/tmp/mlXXXXXX";
pid_t pid;
char *shell, *p;
if (argc != 2) {
usage ();
exit (EXIT_FAILURE);
}
if (argv[1][0] == '-') {
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);
/* Guestfs handle. */
g = guestfs_create ();
if (g == NULL) {
perror ("could not create libguestfs handle");
exit (EXIT_FAILURE);
}
/* Create the output disk image: raw sparse. */
if (guestfs_disk_create (g, argv[1], "raw", SIZE_MB * 1024 * 1024, -1) == -1)
exit (EXIT_FAILURE);
/* Create the disk image and format it with a partition and a filesystem. */
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_options (g, MOUNT_OPTIONS, "/dev/sda1", "/") == -1)
exit (EXIT_FAILURE);
/* Create a file in the new filesystem. */
if (guestfs_touch (g, "/PUT_FILES_AND_DIRECTORIES_HERE") == -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 %d 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 type 'exit' to\n"
"exit the shell and return to the mount-local program.\n"
"\n",
SIZE_MB);
shell = getenv ("SHELL");
if (!shell)
r = system ("/bin/sh");
else {
/* Set a magic prompt. We only know how to do this for bash. */
p = strrchr (shell, '/');
if (p && strcmp (p+1, "bash") == 0) {
const size_t len = 64 + strlen (shell);
char *buf;
buf = malloc (len);
if (buf == NULL) {
perror ("malloc");
_exit (EXIT_FAILURE);
}
snprintf (buf, len, "PS1='mount-local-shell> ' %s --norc -i", shell);
r = system (buf);
free (buf);
} else
r = system (shell);
}
if (r == -1) {
fprintf (stderr, "error: failed to run sub-shell (%s) "
"(is $SHELL set correctly?)\n",
shell);
//FALLTHROUGH
}
if (chdir ("/") == -1)
perror ("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.
*/
/* We're going to hide libguestfs errors here, but in a real program
* you would probably want to log them somewhere.
*/
guestfs_push_error_handler (g, NULL, NULL);
/* Now run the FUSE thread. */
if (guestfs_mount_local_run (g) == -1)
exit (EXIT_FAILURE);
guestfs_pop_error_handler (g);
waitpid (pid, NULL, 0);
/* Shutdown the handle explicitly so write errors can be detected. */
if (guestfs_shutdown (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);
}