[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bugfix, hostfs
From: |
Tomas Ebenlendr |
Subject: |
Re: bugfix, hostfs |
Date: |
Fri, 13 Aug 2004 00:21:19 +0200 |
User-agent: |
Mutt/1.5.6i |
At the end of the mail are new versions of patches. Hope, there are few
(or no) GCS-errors.
> > > > + if ((signed) device->disk->id != -2) {
> > >
> > > What is -2?
> >
> > Oh, sorry. Just a magic constant. Probably there should be better
> > identification (e.g. magic device->disk->data (e.g. device->disk ==
> > device->disk->data)). This identification is used in hostfs_mount()
>
> Probably the id is a problem on Open Firmware potentially, since Marco
> used phandlers for disk ids and phandlers can be anything in theory.
>
> I bet that I made a mistake in the design of struct grub_disk. I thought
> it would be easy to find an identifier because the size of an id is
> 4-byte. But this assumption breaks on Open Firmware. So perhaps we
> should add one more id for the type of a disk, so that we can write
> this kind of code:
>
> (include/grub/disk.h)
> enum grub_disk_class_id
> {
> GRUB_DISK_CLASS_IEEE1275_ID,
> GRUB_DISK_CLASS_PCBIOS_ID,
> GRUB_DISK_CLASS_HOST_ID,
> };
>
> (disk/powerpc/ieee1275/ofdisk.c)
> disk->class_id = GRUB_DISK_CLASS_IEEE1275_ID;
> disk->id = phandler;
>
> Then you can use this:
>
> disk->class_id = GRUB_DISK_CLASS_HOST_ID;
> disk->id = 0;
>
> This requires some changes in the cache manager, but not difficult. What
> do you think?
Hmm, leaving this change for anybody who understand disks in grub.
Instead of it I use disk->name :-) .
> > > > + grub_strncpy(pathbuf,path,/*FIXME*/2048 - 1);
> > >
> > > Why do you use pathbuf? Can't you just use path directly? If that
> > > is not possible use MAX_PATH_LEN here when it is defined and
> > > dynamic memory allocation otherwise (when there is no limit).
> >
> > I concatenate path of directory and its entries to stat them. I will
> > use the MAX_PATH_LEN. I only forgot that I forgot the name of this
> > constant. (Uh).
>
> You should not use MAX_PATH_LEN if not defined, otherwise you code won't
> work well on GNU/Hurd. The right way is to allocate memory dynamically
> for PATHBUF:
I don't use MAX_PATH_LEN even if defined now: Less #ifdef means less
bugs.
I will commit both following patches if you agree. I tested both on
i386,pc,linux-2.4.
PS.: I'm changing conf/powerpc-ieee1275.rmk and I didn't test
compilability of my code on ppc. But it should be OS-dependent, but
not architecture dependent.
##########################################################################
Changelog:
2004-08-08 Tomas Ebenlendr <address@hidden>
* kern/dl.c (grub_dl_load_file): Fixed bug: When
grub_dl_load_core fails, mod shouldn't be derefered.
Index: kern/dl.c
===================================================================
RCS file: /cvsroot/grub/grub2/kern/dl.c,v
retrieving revision 1.7
diff -p -u -r1.7 dl.c
--- kern/dl.c 4 Apr 2004 13:46:01 -0000 1.7
+++ kern/dl.c 12 Aug 2004 21:37:53 -0000
@@ -548,7 +548,8 @@ grub_dl_load_file (const char *filename)
goto failed;
mod = grub_dl_load_core (core, size);
- mod->ref_count = 0;
+ if (mod)
+ mod->ref_count = 0;
failed:
grub_file_close (file);
##########################################################################
Changelog:
2004-08-08 Tomas Ebenlendr <address@hidden>
Added support for accessing files via host filesystem to
grub-emu.
* conf/i386-pc.rmk (grub_emu_SOURCES): Added util/hostdisk.c
and fs/hostfs.c
* fs/hostfs.c: New file. Connects grub fs interface and libc file
interface.
* include/grub/fakedisk.h: New file, prototypes for inicialization
and destruction of fakedisk device.
* util/fakedisk.c: New file, implements device "host" (i.e., tells
that device "host" is fake-disk with filesystem hostfs).
* util/grub-emu.c (main): Added inicialzation and destruction
of hostfs and fakedisk.
diff -rupN -x CVS grub2_x/conf/i386-pc.rmk grub2_wodiff/conf/i386-pc.rmk
--- grub2_x/conf/i386-pc.rmk 2004-08-08 19:32:20.000000000 +0200
+++ grub2_wodiff/conf/i386-pc.rmk 2004-08-10 14:13:32.000000000 +0200
@@ -69,7 +69,8 @@ grub_emu_SOURCES = kern/main.c kern/devi
kern/misc.c kern/loader.c kern/rescue.c kern/term.c \
disk/i386/pc/partition.c kern/env.c commands/ls.c \
commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c
\
- util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c
\
+ util/i386/pc/biosdisk.c util/fakedisk.c \
+ fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hostfs.c \
normal/cmdline.c normal/command.c normal/main.c normal/menu.c
normal/arg.c \
util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c
grub_emu_LDFLAGS = -lncurses
diff -rupN -x CVS grub2_x/conf/powerpc-ieee1275.rmk
grub2_wodiff/conf/powerpc-ieee1275.rmk
--- grub2_x/conf/powerpc-ieee1275.rmk 2004-08-08 19:32:20.000000000 +0200
+++ grub2_wodiff/conf/powerpc-ieee1275.rmk 2004-08-12 23:59:07.000000000
+0200
@@ -25,7 +25,8 @@ grub_emu_SOURCES = kern/main.c kern/devi
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/loader.c kern/rescue.c kern/term.c \
disk/powerpc/ieee1275/partition.c
\
- util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c \
+ util/i386/pc/biosdisk.c util/fakedisk.c \
+ fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hostfs.c \
normal/cmdline.c normal/command.c normal/main.c normal/menu.c \
normal/arg.c \
util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c \
diff -rupN -x CVS grub2_x/fs/hostfs.c grub2_wodiff/fs/hostfs.c
--- grub2_x/fs/hostfs.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2_wodiff/fs/hostfs.c 2004-08-13 00:06:36.000000000 +0200
@@ -0,0 +1,203 @@
+/* hostfs.c - host filesystem for grub-emu */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fakedisk.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+#ifndef GRUB_UTIL
+# error Cannot live without underlying OS.
+#endif
+
+
+/* FIXME grub consider the fs in utf-8 => use only ascii (0-127) chars. */
+
+static grub_err_t
+host_mount (grub_device_t device)
+{
+ if (! GRUB_IS_HOST_FAKEDISK(device->disk))
+ return grub_error (GRUB_ERR_BAD_FS, "not a host filesystem");
+ return 0;
+}
+
+/* Maybe not a exact mapping, but at least sufficient. */
+static grub_err_t
+errno2err (void)
+{
+ grub_err_t r;
+ switch (errno)
+ {
+ case EMFILE:
+ case ENFILE:
+ case ENOMEM: r = GRUB_ERR_OUT_OF_MEMORY; break;
+ case ENOTDIR:
+ case ENOENT: r = GRUB_ERR_FILE_NOT_FOUND; break;
+ case ELOOP: r = GRUB_ERR_SYMLINK_LOOP; break;
+ case EIO: r = GRUB_ERR_FILE_READ_ERROR; break;
+ default: r = GRUB_ERR_BAD_ARGUMENT; break;
+ }
+ return grub_error (r, strerror (errno));
+}
+
+/* Open a file named NAME and initialize FILE. */
+/* File->data will contain retyped filedescriptor. */
+static grub_err_t
+grub_host_open (struct grub_file *file, const char *name)
+{
+ struct stat statbuf;
+
+ if (host_mount (file->device))
+ return grub_errno;
+
+ file->data = (void *) open(name, O_RDONLY);
+ if (file->data == (void *) -1)
+ return errno2err();
+ fstat((int) file->data, &statbuf);
+ file->size = statbuf.st_size;
+ file->offset = 0;
+
+ return 0;
+}
+
+static grub_err_t
+grub_host_close (grub_file_t file)
+{
+ close ((int) file->data);
+ file->data = (void *) -1;
+ return 0;
+}
+
+/* Read LEN bytes data from FILE into BUF. */
+static grub_ssize_t
+grub_host_read (grub_file_t file, char *buf, grub_ssize_t len)
+{
+ int rv;
+
+ /* Maybe loop to get as most as possible should be here, may be not. */
+ rv = read ((int) file->data, buf, len);
+ if (rv == -1)
+ return errno2err();
+ return rv;
+}
+
+
+static grub_err_t
+grub_host_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename, int dir))
+{
+ DIR *dir;
+ struct dirent *dent;
+ struct stat stent;
+ char *pathbuf, *p;
+ unsigned pathlen;
+ unsigned maxname = 32;
+
+ if (host_mount (device))
+ return grub_errno;
+
+ pathlen = grub_strlen (path) + 1;
+ pathbuf = grub_malloc (pathlen + maxname);
+ if (pathbuf == 0)
+ goto mem_fail;
+
+ grub_strcpy (pathbuf, path);
+ pathbuf [pathlen - 1] = '/';
+ pathbuf [pathlen] = 0;
+
+ dir = opendir (pathbuf);
+ if (dir == 0)
+ goto errno_fail;
+
+ while ((dent = readdir (dir)) != 0)
+ {
+ if (grub_strlen (dent->d_name) >= maxname)
+ {
+ maxname = grub_strlen (dent->d_name);
+ p = grub_realloc (pathbuf, pathlen + maxname);
+ if (p == 0)
+ goto mem_fail;
+ pathbuf = p;
+ }
+ grub_strcpy (pathbuf + pathlen, dent->d_name);
+ lstat (pathbuf, &stent);
+ hook (dent->d_name, (stent.st_mode & S_IFMT) == S_IFDIR);
+ }
+
+ grub_free (pathbuf);
+ return 0;
+
+mem_fail:
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "Not enough memory.");
+ goto fail;
+
+errno_fail:
+ errno2err ();
+
+fail:
+ grub_free (pathbuf);
+ return grub_errno;
+}
+
+static grub_err_t
+grub_host_label (grub_device_t device, char **label)
+{
+ if (host_mount (device))
+ return grub_errno;
+ *label = 0;
+ return 0;
+}
+
+
+static struct grub_fs grub_host_fs =
+ {
+ .name = "host",
+ .dir = grub_host_dir,
+ .open = grub_host_open,
+ .read = grub_host_read,
+ .close = grub_host_close,
+ .label = grub_host_label,
+ .next = 0
+ };
+
+void
+grub_hostfs_init (void)
+{
+ grub_fs_register (&grub_host_fs);
+}
+
+void
+grub_hostfs_fini (void)
+{
+ grub_fs_unregister (&grub_host_fs);
+}
+
diff -rupN -x CVS grub2_x/include/grub/fakedisk.h
grub2_wodiff/include/grub/fakedisk.h
--- grub2_x/include/grub/fakedisk.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2_wodiff/include/grub/fakedisk.h 2004-08-13 00:08:40.000000000
+0200
@@ -0,0 +1,32 @@
+/* fakedisk.h - fake disk device */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2004 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_FAKEDISK_HEADER
+#define GRUB_FAKEDISK_HEADER 1
+
+void grub_util_fakedisk_init (void);
+void grub_util_fakedisk_fini (void);
+
+#define GRUB_FAKEDISK_HOST_STRING "host"
+
+/* For hostfs to detect, that this is hostdisk. */
+#define GRUB_IS_HOST_FAKEDISK(x) (grub_strcmp((x)->name,
GRUB_FAKEDISK_HOST_STRING) == 0)
+
+#endif /* ! GRUB_FAKEDISK_HEADER */
diff -rupN -x CVS grub2_x/include/grub/fs.h grub2_wodiff/include/grub/fs.h
--- grub2_x/include/grub/fs.h 2004-08-08 14:18:18.000000000 +0200
+++ grub2_wodiff/include/grub/fs.h 2004-08-08 19:33:28.000000000 +0200
@@ -74,6 +74,8 @@ void grub_ufs_init (void);
void grub_ufs_fini (void);
void grub_minix_init (void);
void grub_minix_fini (void);
+void grub_hostfs_init (void);
+void grub_hostfs_fini (void);
#endif /* GRUB_UTIL */
#endif /* ! GRUB_FS_HEADER */
diff -rupN -x CVS grub2_x/util/fakedisk.c grub2_wodiff/util/fakedisk.c
--- grub2_x/util/fakedisk.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2_wodiff/util/fakedisk.c 2004-08-13 00:08:05.000000000 +0200
@@ -0,0 +1,96 @@
+/* fakedisk.c - fake disk device */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2004 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/disk.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/util/misc.h>
+#include <grub/misc.h>
+
+#include <grub/fakedisk.h>
+
+static int
+grub_util_fakedisk_iterate (int (*hook) (const char *name))
+{
+ if (hook (GRUB_FAKEDISK_HOST_STRING))
+ return 1;
+ else
+ return 0;
+}
+
+static grub_err_t
+grub_util_fakedisk_open (const char *name, grub_disk_t disk)
+{
+ if (grub_strcmp (name,GRUB_FAKEDISK_HOST_STRING) != 0)
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown disk %s", name);
+ disk->has_partitions = 0;
+ /* Id is irrelevant. */
+ disk->id = -1;
+ /* This shoud be much greater than zero. Some fs claims that disk is
+ * totaly bad while fs-probe if total_sectors to low. */
+ disk->total_sectors = 1234;
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_util_fakedisk_read (grub_disk_t disk __attribute__ ((unused)),
+ unsigned long sector __attribute__ ((unused)),
+ unsigned long size __attribute__ ((unused)),
+ char *buf __attribute__ ((unused)))
+{
+ /* BAD_FS is here for filesystem probe to work. */
+ grub_error (GRUB_ERR_BAD_FS, "cannot read from fakedisk %s", disk->name);
+ return grub_errno;
+}
+
+
+static grub_err_t
+grub_util_fakedisk_write (grub_disk_t disk __attribute__ ((unused)),
+ unsigned long sector __attribute__ ((unused)),
+ unsigned long size __attribute__ ((unused)),
+ const char *buf __attribute__ ((unused)))
+{
+ grub_error (GRUB_ERR_BAD_FS, "cannot write to fakedisk %s", disk->name);
+ return grub_errno;
+}
+
+
+static struct grub_disk_dev grub_util_fakedisk_dev =
+ {
+ .name = "fakedisk",
+ .iterate = grub_util_fakedisk_iterate,
+ .open = grub_util_fakedisk_open,
+ .close = 0,
+ .read = grub_util_fakedisk_read,
+ .write = grub_util_fakedisk_write,
+ .next = 0
+ };
+
+void
+grub_util_fakedisk_init (void)
+{
+ grub_disk_dev_register (&grub_util_fakedisk_dev);
+}
+
+void
+grub_util_fakedisk_fini (void)
+{
+ grub_disk_dev_unregister (&grub_util_fakedisk_dev);
+}
diff -rupN -x CVS grub2_x/util/grub-emu.c grub2_wodiff/util/grub-emu.c
--- grub2_x/util/grub-emu.c 2004-08-08 14:18:18.000000000 +0200
+++ grub2_wodiff/util/grub-emu.c 2004-08-10 14:12:15.000000000 +0200
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2004 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
@@ -35,6 +35,8 @@
#include <grub/util/getroot.h>
#include <grub/env.h>
+#include <grub/fakedisk.h>
+
#ifdef __NetBSD__
/* NetBSD uses /boot for its boot block. */
# define DEFAULT_DIRECTORY "/grub"
@@ -154,7 +156,9 @@ main (int argc, char *argv[])
/* XXX: This is a bit unportable. */
grub_util_biosdisk_init (args.dev_map);
+ grub_util_fakedisk_init ();
+ grub_hostfs_init ();
/* Initialize the default modules. */
grub_fat_init ();
grub_ext2_init ();
@@ -172,6 +176,7 @@ main (int argc, char *argv[])
/* Start GRUB! */
grub_main ();
+ grub_util_fakedisk_fini ();
grub_util_biosdisk_fini ();
grub_normal_fini ();
grub_ufs_fini ();
@@ -182,6 +187,7 @@ main (int argc, char *argv[])
grub_cmp_fini ();
grub_cat_fini ();
grub_terminal_fini ();
+ grub_hostfs_fini ();
return 0;
}
##########################################################################
--
Tomas 'ebi' Ebenlendr
http://get.to/ebik
PF 2004.61477452692
- bugfix, hostfs, Tomas Ebenlendr, 2004/08/08
- Re: bugfix, hostfs, Marco Gerards, 2004/08/08
- Re: bugfix, hostfs, Tomas Ebenlendr, 2004/08/08
- Re: bugfix, hostfs, Marco Gerards, 2004/08/08
- Re: bugfix, hostfs, Yoshinori K. Okuji, 2004/08/08
- Re: bugfix, hostfs,
Tomas Ebenlendr <=
- Re: bugfix, hostfs, Marco Gerards, 2004/08/13
- Re: bugfix, hostfs, Tomas Ebenlendr, 2004/08/14
- Re: bugfix, hostfs, Marco Gerards, 2004/08/14
- Re: bugfix, hostfs, Tomas Ebenlendr, 2004/08/14
- Re: bugfix, hostfs, Yoshinori K. Okuji, 2004/08/21