summaryrefslogtreecommitdiffstats
path: root/master/debian/branch_fuse.patch
diff options
context:
space:
mode:
authorroot <root@arianrhod.panaceas.james.local>2012-11-16 11:52:02 +0000
committerroot <root@arianrhod.panaceas.james.local>2012-11-16 11:52:02 +0000
commita109bb6d0eb936ac4e2a9f0ee46a269a58ec48ce (patch)
tree9a6b9c35465b23ce5871feec5e9ba0c7d5ac7797 /master/debian/branch_fuse.patch
downloadgrub-1.99-pq-a109bb6d0eb936ac4e2a9f0ee46a269a58ec48ce.tar.gz
grub-1.99-pq-a109bb6d0eb936ac4e2a9f0ee46a269a58ec48ce.tar.bz2
grub-1.99-pq-a109bb6d0eb936ac4e2a9f0ee46a269a58ec48ce.zip
fish
Diffstat (limited to 'master/debian/branch_fuse.patch')
-rw-r--r--master/debian/branch_fuse.patch605
1 files changed, 605 insertions, 0 deletions
diff --git a/master/debian/branch_fuse.patch b/master/debian/branch_fuse.patch
new file mode 100644
index 0000000..1f5a22d
--- /dev/null
+++ b/master/debian/branch_fuse.patch
@@ -0,0 +1,605 @@
+Description: Add grub-mount utility
+Author: Vladimir Serbinenko <phcoder@gmail.com>
+Origin: upstream, http://bzr.sv.gnu.org/r/grub/branches/fuse/
+Forwarded: http://lists.gnu.org/archive/html/grub-devel/2011-01/msg00056.html
+Last-Update: 2011-07-10
+
+--- a/Makefile.util.def
++++ b/Makefile.util.def
+@@ -216,6 +216,21 @@
+ };
+
+ program = {
++ name = grub-mount;
++ mansection = 1;
++ common_nodist = grub_fstest_init.c;
++ common = util/grub-mount.c;
++ common = grub-core/kern/emu/hostfs.c;
++ common = grub-core/disk/host.c;
++
++ ldadd = libgrubmods.a;
++ ldadd = libgrubkern.a;
++ ldadd = grub-core/gnulib/libgnu.a;
++ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) -lfuse';
++ condition = COND_GRUB_MOUNT;
++};
++
++program = {
+ name = grub-mkfont;
+ mansection = 1;
+ common = util/grub-mkfont.c;
+--- a/configure.ac
++++ b/configure.ac
+@@ -856,6 +856,37 @@
+ AC_SUBST([freetype_cflags])
+ AC_SUBST([freetype_libs])
+
++AC_ARG_ENABLE([grub-mount],
++ [AS_HELP_STRING([--enable-grub-mount],
++ [build and install the `grub-mount' utility (default=guessed)])])
++if test x"$enable_grub_mount" = xno ; then
++ grub_mount_excuse="explicitly disabled"
++fi
++
++if test x"$grub_mount_excuse" = x ; then
++ AC_CHECK_LIB([fuse], [fuse_main_real], [],
++ [grub_mount_excuse="need FUSE library"])
++fi
++
++if test x"$grub_mount_excuse" = x ; then
++ # Check for fuse headers.
++ SAVED_CPPFLAGS="$CPPFLAGS"
++ CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26"
++ AC_CHECK_HEADERS([fuse/fuse.h], [],
++ [grub_mount_excuse=["need FUSE headers"]])
++ CPPFLAGS="$SAVED_CPPFLAGS"
++fi
++
++if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then
++ AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled])
++fi
++if test x"$grub_mount_excuse" = x ; then
++enable_grub_mount=yes
++else
++enable_grub_mount=no
++fi
++AC_SUBST([enable_grub_mount])
++
+ AC_ARG_ENABLE([device-mapper],
+ [AS_HELP_STRING([--enable-device-mapper],
+ [enable Linux device-mapper support (default=guessed)])])
+@@ -967,6 +998,7 @@
+ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes])
+ AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
+ AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
++AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes])
+ AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
+ AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x])
+ AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1])
+@@ -1043,5 +1075,10 @@
+ else
+ echo grub-mkfont: No "($grub_mkfont_excuse)"
+ fi
++if [ x"$grub_mount_excuse" = x ]; then
++echo grub-mount: Yes
++else
++echo grub-mount: No "($grub_mount_excuse)"
++fi
+ echo "*******************************************************"
+ ]
+--- /dev/null
++++ b/docs/man/grub-mount.h2m
+@@ -0,0 +1,2 @@
++[NAME]
++grub-mount \- export GRUB filesystem with FUSE
+--- /dev/null
++++ b/util/grub-mount.c
+@@ -0,0 +1,508 @@
++/* grub-mount.c - FUSE driver for filesystems that GRUB understands */
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc.
++ *
++ * GRUB is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GRUB is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
++ */
++#define FUSE_USE_VERSION 26
++#include <config.h>
++#include <grub/types.h>
++#include <grub/emu/misc.h>
++#include <grub/util/misc.h>
++#include <grub/misc.h>
++#include <grub/device.h>
++#include <grub/disk.h>
++#include <grub/file.h>
++#include <grub/fs.h>
++#include <grub/env.h>
++#include <grub/term.h>
++#include <grub/mm.h>
++#include <grub/lib/hexdump.h>
++#include <grub/crypto.h>
++#include <grub/command.h>
++#include <grub/i18n.h>
++#include <fuse/fuse.h>
++
++#include <stdio.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdlib.h>
++
++#include "progname.h"
++#include "argp.h"
++
++static char *root = NULL;
++grub_device_t dev = NULL;
++grub_fs_t fs = NULL;
++static char **images = NULL;
++static char *debug_str = NULL;
++static char **fuse_args = NULL;
++static int fuse_argc = 0;
++static int num_disks = 0;
++
++static grub_err_t
++execute_command (char *name, int n, char **args)
++{
++ grub_command_t cmd;
++
++ cmd = grub_command_find (name);
++ if (! cmd)
++ grub_util_error (_("can\'t find command %s"), name);
++
++ return (cmd->func) (cmd, n, args);
++}
++
++/* Translate GRUB error numbers into OS error numbers. Print any unexpected
++ errors. */
++static int
++translate_error (void)
++{
++ int ret;
++
++ switch (grub_errno)
++ {
++ case GRUB_ERR_NONE:
++ ret = 0;
++ break;
++
++ case GRUB_ERR_OUT_OF_MEMORY:
++ grub_print_error ();
++ ret = -ENOMEM;
++ break;
++
++ case GRUB_ERR_BAD_FILE_TYPE:
++ /* This could also be EISDIR. Take a guess. */
++ ret = -ENOTDIR;
++ break;
++
++ case GRUB_ERR_FILE_NOT_FOUND:
++ ret = -ENOENT;
++ break;
++
++ case GRUB_ERR_FILE_READ_ERROR:
++ case GRUB_ERR_READ_ERROR:
++ case GRUB_ERR_IO:
++ grub_print_error ();
++ ret = -EIO;
++ break;
++
++ case GRUB_ERR_SYMLINK_LOOP:
++ ret = -ELOOP;
++ break;
++
++ default:
++ grub_print_error ();
++ ret = -EINVAL;
++ break;
++ }
++
++ /* Any previous errors were handled. */
++ grub_errno = GRUB_ERR_NONE;
++
++ return ret;
++}
++
++static int
++fuse_getattr (const char *path, struct stat *st)
++{
++ char *filename, *pathname, *path2;
++ const char *pathname_t;
++ struct grub_dirhook_info file_info;
++ int file_exists = 0;
++
++ /* A hook for iterating directories. */
++ auto int find_file (const char *cur_filename,
++ const struct grub_dirhook_info *info);
++ int find_file (const char *cur_filename,
++ const struct grub_dirhook_info *info)
++ {
++ if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
++ : grub_strcmp (cur_filename, filename)) == 0)
++ {
++ file_info = *info;
++ file_exists = 1;
++ return 1;
++ }
++ return 0;
++ }
++
++ if (path[0] == '/' && path[1] == 0)
++ {
++ st->st_dev = 0;
++ st->st_ino = 0;
++ st->st_mode = 0555 | S_IFDIR;
++ st->st_uid = 0;
++ st->st_gid = 0;
++ st->st_rdev = 0;
++ st->st_size = 0;
++ st->st_blksize = 512;
++ st->st_blocks = (st->st_blksize + 511) >> 9;
++ st->st_atime = st->st_mtime = st->st_ctime = 0;
++ return 0;
++ }
++
++ file_exists = 0;
++
++ pathname_t = grub_strchr (path, ')');
++ if (! pathname_t)
++ pathname_t = path;
++ else
++ pathname_t++;
++ pathname = xstrdup (pathname_t);
++
++ /* Remove trailing '/'. */
++ while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
++ pathname[grub_strlen (pathname) - 1] = 0;
++
++ /* Split into path and filename. */
++ filename = grub_strrchr (pathname, '/');
++ if (! filename)
++ {
++ path2 = grub_strdup ("/");
++ filename = pathname;
++ }
++ else
++ {
++ filename++;
++ path2 = grub_strdup (pathname);
++ path2[filename - pathname] = 0;
++ }
++
++ /* It's the whole device. */
++ (fs->dir) (dev, path2, find_file);
++
++ grub_free (path2);
++ if (!file_exists)
++ {
++ grub_errno = GRUB_ERR_NONE;
++ return -ENOENT;
++ }
++ st->st_dev = 0;
++ st->st_ino = 0;
++ st->st_mode = file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG);
++ st->st_uid = 0;
++ st->st_gid = 0;
++ st->st_rdev = 0;
++ if (!file_info.dir)
++ {
++ grub_file_t file;
++ file = grub_file_open (path);
++ if (! file)
++ return translate_error ();
++ st->st_size = file->size;
++ grub_file_close (file);
++ }
++ else
++ st->st_size = 0;
++ st->st_blksize = 512;
++ st->st_blocks = (st->st_size + 511) >> 9;
++ st->st_atime = st->st_mtime = st->st_ctime = file_info.mtimeset
++ ? file_info.mtime : 0;
++ grub_errno = GRUB_ERR_NONE;
++ return 0;
++}
++
++static int
++fuse_opendir (const char *path, struct fuse_file_info *fi)
++{
++ return 0;
++}
++
++/* FIXME */
++static grub_file_t files[65536];
++static int first_fd = 1;
++
++static int
++fuse_open (const char *path, struct fuse_file_info *fi __attribute__ ((unused)))
++{
++ grub_file_t file;
++ file = grub_file_open (path);
++ if (! file)
++ return translate_error ();
++ files[first_fd++] = file;
++ fi->fh = first_fd;
++ files[first_fd++] = file;
++ grub_errno = GRUB_ERR_NONE;
++ return 0;
++}
++
++static int
++fuse_read (const char *path, char *buf, size_t sz, off_t off,
++ struct fuse_file_info *fi)
++{
++ grub_file_t file = files[fi->fh];
++ grub_ssize_t size;
++
++ if (off > file->size)
++ return -EINVAL;
++
++ file->offset = off;
++
++ size = grub_file_read (file, buf, sz);
++ if (size < 0)
++ return translate_error ();
++ else
++ {
++ grub_errno = GRUB_ERR_NONE;
++ return size;
++ }
++}
++
++static int
++fuse_release (const char *path, struct fuse_file_info *fi)
++{
++ grub_file_close (files[fi->fh]);
++ files[fi->fh] = NULL;
++ grub_errno = GRUB_ERR_NONE;
++ return 0;
++}
++
++static int
++fuse_readdir (const char *path, void *buf,
++ fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi)
++{
++ char *pathname;
++
++ auto int call_fill (const char *filename,
++ const struct grub_dirhook_info *info);
++ int call_fill (const char *filename, const struct grub_dirhook_info *info)
++ {
++ fill (buf, filename, NULL, 0);
++ return 0;
++ }
++
++ pathname = xstrdup (path);
++
++ /* Remove trailing '/'. */
++ while (pathname [0] && pathname[1]
++ && pathname[grub_strlen (pathname) - 1] == '/')
++ pathname[grub_strlen (pathname) - 1] = 0;
++
++ (fs->dir) (dev, pathname, call_fill);
++ free (pathname);
++ grub_errno = GRUB_ERR_NONE;
++ return 0;
++}
++
++struct fuse_operations grub_opers = {
++ .getattr = fuse_getattr,
++ .open = fuse_open,
++ .release = fuse_release,
++ .opendir = fuse_opendir,
++ .readdir = fuse_readdir,
++ .read = fuse_read
++};
++
++static grub_err_t
++fuse_init (void)
++{
++ int i;
++
++ for (i = 0; i < num_disks; i++)
++ {
++ char *argv[2];
++ char *host_file;
++ char *loop_name;
++ loop_name = grub_xasprintf ("loop%d", i);
++ if (!loop_name)
++ grub_util_error (grub_errmsg);
++
++ host_file = grub_xasprintf ("(host)%s", images[i]);
++ if (!host_file)
++ grub_util_error (grub_errmsg);
++
++ argv[0] = loop_name;
++ argv[1] = host_file;
++
++ if (execute_command ("loopback", 2, argv))
++ grub_util_error (_("loopback command fails"));
++
++ grub_free (loop_name);
++ grub_free (host_file);
++ }
++
++ grub_lvm_fini ();
++ grub_mdraid09_fini ();
++ grub_mdraid1x_fini ();
++ grub_raid_fini ();
++ grub_raid_init ();
++ grub_mdraid09_init ();
++ grub_mdraid1x_init ();
++ grub_lvm_init ();
++
++ dev = grub_device_open (0);
++ if (! dev)
++ return grub_errno;
++
++ fs = grub_fs_probe (dev);
++ if (! fs)
++ {
++ grub_device_close (dev);
++ return grub_errno;
++ }
++
++ fuse_main (fuse_argc, fuse_args, &grub_opers, NULL);
++
++ for (i = 0; i < num_disks; i++)
++ {
++ char *argv[2];
++ char *loop_name;
++
++ loop_name = grub_xasprintf ("loop%d", i);
++ if (!loop_name)
++ grub_util_error (grub_errmsg);
++
++ argv[0] = "-d";
++ argv[1] = loop_name;
++
++ execute_command ("loopback", 2, argv);
++
++ grub_free (loop_name);
++ }
++
++ return GRUB_ERR_NONE;
++}
++
++static struct argp_option options[] = {
++ {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2},
++ {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2},
++ {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2},
++ {0, 0, 0, 0, 0, 0}
++};
++
++/* Print the version information. */
++static void
++print_version (FILE *stream, struct argp_state *state)
++{
++ fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
++}
++void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
++
++error_t
++argp_parser (int key, char *arg, struct argp_state *state)
++{
++ char *p;
++
++ switch (key)
++ {
++ case 'r':
++ root = arg;
++ return 0;
++
++ case 'd':
++ debug_str = arg;
++ return 0;
++
++ case 'v':
++ verbosity++;
++ return 0;
++
++ case ARGP_KEY_ARG:
++ if (arg[0] != '-')
++ break;
++
++ default:
++ if (!arg)
++ return 0;
++
++ fuse_args = xrealloc (fuse_args, (fuse_argc + 1) * sizeof (fuse_args[0]));
++ fuse_args[fuse_argc] = xstrdup (arg);
++ fuse_argc++;
++ return 0;
++ }
++
++ if (arg[0] != '/')
++ {
++ fprintf (stderr, "%s", _("Must use absolute path.\n"));
++ argp_usage (state);
++ }
++ images = xrealloc (images, (num_disks + 1) * sizeof (images[0]));
++ images[num_disks] = xstrdup (arg);
++ num_disks++;
++
++ return 0;
++}
++
++struct argp argp = {
++ options, argp_parser, N_("IMAGE1 [IMAGE2 ...] MOUNTPOINT"),
++ N_("Debug tool for filesystem driver."),
++ NULL, NULL, NULL
++};
++
++int
++main (int argc, char *argv[])
++{
++ char *default_root, *alloc_root;
++
++ set_program_name (argv[0]);
++
++ grub_util_init_nls ();
++
++ fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0]));
++ fuse_args[fuse_argc] = xstrdup (argv[0]);
++ fuse_argc++;
++ /* Run single-threaded. */
++ fuse_args[fuse_argc] = xstrdup ("-s");
++ fuse_argc++;
++
++ argp_parse (&argp, argc, argv, 0, 0, 0);
++
++ if (num_disks < 2)
++ grub_util_error ("need an image and mountpoint");
++ fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0]));
++ fuse_args[fuse_argc] = images[num_disks - 1];
++ fuse_argc++;
++ num_disks--;
++ fuse_args[fuse_argc] = NULL;
++
++ /* Initialize all modules. */
++ grub_init_all ();
++
++ if (debug_str)
++ grub_env_set ("debug", debug_str);
++
++ default_root = (num_disks == 1) ? "loop0" : "md0";
++ alloc_root = 0;
++ if (root)
++ {
++ if ((*root >= '0') && (*root <= '9'))
++ {
++ alloc_root = xmalloc (strlen (default_root) + strlen (root) + 2);
++
++ sprintf (alloc_root, "%s,%s", default_root, root);
++ root = alloc_root;
++ }
++ }
++ else
++ root = default_root;
++
++ grub_env_set ("root", root);
++
++ if (alloc_root)
++ free (alloc_root);
++
++ /* Do it. */
++ fuse_init ();
++ if (grub_errno)
++ {
++ grub_print_error ();
++ return 1;
++ }
++
++ /* Free resources. */
++ grub_fini_all ();
++
++ return 0;
++}