From a109bb6d0eb936ac4e2a9f0ee46a269a58ec48ce Mon Sep 17 00:00:00 2001 From: root Date: Fri, 16 Nov 2012 11:52:02 +0000 Subject: fish --- master/debian/branch_fuse.patch | 605 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 605 insertions(+) create mode 100644 master/debian/branch_fuse.patch (limited to 'master/debian/branch_fuse.patch') 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 +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 . ++ */ ++#define FUSE_USE_VERSION 26 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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; ++} -- cgit v1.2.3