* Loopback device
@ 2005-01-21 0:12 Marco Gerards
2005-01-21 12:38 ` P
2005-01-21 13:32 ` Yoshinori K. Okuji
0 siblings, 2 replies; 13+ messages in thread
From: Marco Gerards @ 2005-01-21 0:12 UTC (permalink / raw)
To: grub-devel
Hi,
Here is a patch to add loopback support to GRUB. Although a lot of
people told me they would find it useful, I just wrote it out of
boredom without thinking about its use, just to figure out how hard it
would be.
I could commit it if anyone really wants it. Can I commit it?
Thanks,
Marco
2005-01-21 Marco Gerards <metgerards@student.han.nl>
Add the loopback device, a device via which files can be accessed
as devices.
* conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/loopback.c'.
(pkgdata_MODULES): Add loopback.mod.
(loopback_SOURCES): New variable.
(loopback_CFLAGS): Likewise.
* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
`disk/loopback.c'.
(pkgdata_MODULES): Add loopback.mod.
(loopback_SOURCES): New variable.
(loopback_CFLAGS): Likewise.
* disk/loopback.c: new file.
* include/grub/normal.h (grub_loop_init): New prototype.
(grub_loop_fini): New prototype.
(util/grub-emu.c): Initialize and de-initialize loopback support.
Index: conf/i386-pc.rmk
===================================================================
RCS file: /cvsroot/grub/grub2/conf/i386-pc.rmk,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 i386-pc.rmk
--- conf/i386-pc.rmk 4 Dec 2004 18:45:45 -0000 1.23
+++ conf/i386-pc.rmk 21 Jan 2005 00:09:34 -0000
@@ -73,7 +73,7 @@ grub_emu_SOURCES = kern/main.c kern/devi
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 fs/hfs.c fs/jfs.c fs/iso9660.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
+ util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c disk/loopback.c
grub_emu_LDFLAGS = -lncurses
# For genmoddep.
@@ -83,7 +83,7 @@ genmoddep_SOURCES = util/genmoddep.c
pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \
boot.mod cmp.mod cat.mod terminal.mod fshelp.mod chain.mod multiboot.mod \
- amiga.mod apple.mod pc.mod
+ amiga.mod apple.mod pc.mod loopback.mod
# For _chain.mod.
_chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -190,3 +190,7 @@ apple_mod_CFLAGS = $(COMMON_CFLAGS)
# For pc.mod
pc_mod_SOURCES = partmap/pc.c
pc_mod_CFLAGS = $(COMMON_CFLAGS)
+
+# For loopback.mod
+loopback_SOURCES = disk/loopback.c
+loopback_CFLAGS = $(COMMON_CFLAGS)
Index: conf/powerpc-ieee1275.rmk
===================================================================
RCS file: /cvsroot/grub/grub2/conf/powerpc-ieee1275.rmk,v
retrieving revision 1.19
diff -u -p -u -p -r1.19 powerpc-ieee1275.rmk
--- conf/powerpc-ieee1275.rmk 4 Jan 2005 14:01:45 -0000 1.19
+++ conf/powerpc-ieee1275.rmk 21 Jan 2005 00:09:34 -0000
@@ -41,7 +41,7 @@ grub_emu_SOURCES = kern/main.c kern/devi
normal/cmdline.c normal/command.c normal/main.c normal/menu.c \
normal/arg.c kern/partition.c \
util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c \
- kern/env.c commands/ls.c \
+ kern/env.c disk/loopback.c commands/ls.c \
commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c
grub_emu_LDFLAGS = -lncurses
@@ -64,7 +64,8 @@ genmoddep_SOURCES = util/genmoddep.c
# Modules.
pkgdata_MODULES = _linux.mod linux.mod fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod font.mod \
- boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod pc.mod
+ boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
+ pc.mod loopback.mod
# For fshelp.mod.
fshelp_mod_SOURCES = fs/fshelp.c
@@ -151,3 +152,7 @@ apple_mod_CFLAGS = $(COMMON_CFLAGS)
# For pc.mod
pc_mod_SOURCES = partmap/pc.c
pc_mod_CFLAGS = $(COMMON_CFLAGS)
+
+# For loopback.mod
+loopback_SOURCES = disk/loopback.c
+loopback_CFLAGS = $(COMMON_CFLAGS)
Index: disk/loopback.c
===================================================================
RCS file: disk/loopback.c
diff -N disk/loopback.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ disk/loopback.c 21 Jan 2005 00:09:34 -0000
@@ -0,0 +1,262 @@
+/* loopback.c - command to add loopback devices. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005 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/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+
+struct grub_loopback
+{
+ char *devname;
+ char *filename;
+ struct grub_loopback *next;
+};
+
+static struct grub_loopback *loopback_list;
+
+static const struct grub_arg_option options[] =
+ {
+ {"delete", 'd', 0, "Delete the loopback device entry", 0, 0},
+ {0, 0, 0, 0, 0, 0}
+ };
+
+/* Delete the loopback device NAME. */
+static grub_err_t
+delete_loopback (const char *name)
+{
+ struct grub_loopback *dev;
+ struct grub_loopback **prev;
+
+ /* Search for the device. */
+ for (dev = loopback_list, prev = &loopback_list;
+ dev; prev = &dev->next, dev = dev->next)
+ if (!grub_strcmp (dev->devname, name))
+ break;
+ if (!dev)
+ return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found");
+
+ /* Remove the device from the list. */
+ *prev = dev->next;
+
+ grub_free (dev->devname);
+ grub_free (dev->filename);
+ grub_free (dev);
+
+ return 0;
+}
+
+
+/* The command to add and remove loopback devices. */
+static grub_err_t
+grub_cmd_loopback (struct grub_arg_list *state,
+ int argc, char **args)
+{
+ grub_file_t file;
+ struct grub_loopback *newdev;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+ /* Check if `-d' was used. */
+ if (state[0].set)
+ return delete_loopback (args[0]);
+
+ if (argc < 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+ file = grub_file_open (args[1]);
+ if (! file)
+ return grub_errno;
+
+ /* Close the file, the only reason for opening it is validation. */
+ grub_file_close (file);
+
+ /* First try to replace the old device. */
+ for (newdev = loopback_list; newdev; newdev = newdev->next)
+ if (!grub_strcmp (newdev->devname, args[0]))
+ break;
+ if (newdev)
+ {
+ char *newname = grub_strdup (args[1]);
+ if (!newname)
+ return grub_errno;
+
+ grub_free (newdev->filename);
+ newdev->filename = newname;
+ return 0;
+ }
+
+ /* Unable to replace it, make a new entry. */
+ newdev = grub_malloc (sizeof (struct grub_loopback));
+ if (!newdev)
+ return grub_errno;
+
+ newdev->devname = grub_strdup (args[0]);
+ if (!newdev->devname)
+ {
+ grub_free (newdev);
+ return grub_errno;
+ }
+
+ newdev->filename = grub_strdup (args[1]);
+ if (!newdev->devname)
+ {
+ grub_free (newdev->devname);
+ grub_free (newdev);
+ return grub_errno;
+ }
+
+ /* Add the new entry to the list. */
+ newdev->next = loopback_list;
+ loopback_list = newdev;
+
+ return 0;
+}
+
+\f
+static int
+grub_loopback_iterate (int (*hook) (const char *name))
+{
+ struct grub_loopback *d;
+ for (d = loopback_list; d; d = d->next)
+ {
+ if (hook (d->devname))
+ return 1;
+ }
+ return 0;
+}
+
+static grub_err_t
+grub_loopback_open (const char *name, grub_disk_t disk)
+{
+ grub_file_t file;
+ struct grub_loopback *dev;
+
+ for (dev = loopback_list; dev; dev = dev->next)
+ if (!grub_strcmp (dev->devname, name))
+ break;
+
+ if (! dev)
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
+
+ file = grub_file_open (dev->filename);
+ if (! file)
+ return grub_errno;
+
+ /* Use the filesize for the disk size, round up to a complete sector. */
+ disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1)
+ / GRUB_DISK_SECTOR_SIZE);
+ disk->id = (int) dev;
+ /* XXX: Assume no partitions for now. */
+ disk->has_partitions = 0;
+ disk->data = file;
+
+ return 0;
+}
+
+static void
+grub_loopback_close (grub_disk_t disk)
+{
+ grub_file_t file = (grub_file_t) disk->data;
+
+ grub_file_close (file);
+}
+
+static grub_err_t
+grub_loopback_read (grub_disk_t disk, unsigned long sector,
+ unsigned long size, char *buf)
+{
+ grub_file_t file = (grub_file_t) disk->data;
+ long pos;
+
+ grub_file_seek (file, sector * GRUB_DISK_SECTOR_SIZE);
+
+ grub_file_read (file, buf, size * GRUB_DISK_SECTOR_SIZE);
+ if (grub_errno)
+ return grub_errno;
+
+ /* In case there is more data read than there is available, in case
+ of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
+ the rest with zeros. */
+ pos = sector * GRUB_DISK_SECTOR_SIZE + size * GRUB_DISK_SECTOR_SIZE;
+ if (pos > file->size)
+ {
+ unsigned long amount = pos - file->size;
+ grub_memset (buf + pos - amount, amount, 0);
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_loopback_write (grub_disk_t disk __attribute ((unused)),
+ unsigned long sector __attribute ((unused)),
+ unsigned long size __attribute ((unused)),
+ const char *buf __attribute ((unused)))
+{
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_loopback_dev =
+ {
+ .name = "loopback",
+ .id = GRUB_DISK_DEVICE_OFDISK_ID,
+ .iterate = grub_loopback_iterate,
+ .open = grub_loopback_open,
+ .close = grub_loopback_close,
+ .read = grub_loopback_read,
+ .write = grub_loopback_write,
+ .next = 0
+ };
+
+
+\f
+#ifdef GRUB_UTIL
+void
+grub_loop_init (void)
+{
+ grub_register_command ("loopback", grub_cmd_loopback, GRUB_COMMAND_FLAG_BOTH,
+ "loopback [OPTIONS] DEVICENAME FILE", "Makes a device of a file", options);
+ grub_disk_dev_register (&grub_loopback_dev);
+
+}
+
+void
+grub_loop_fini (void)
+{
+ grub_unregister_command ("loopback");
+}
+#else /* ! GRUB_UTIL */
+GRUB_MOD_INIT
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("loopback", grub_cmd_loopback, GRUB_COMMAND_FLAG_BOTH,
+ "loopback [OPTIONS] DEVICENAME FILE", "Makes a device of a file", options);
+}
+
+GRUB_MOD_FINI
+{
+ grub_unregister_command ("loopback");
+}
+#endif /* ! GRUB_UTIL */
Index: include/grub/normal.h
===================================================================
RCS file: /cvsroot/grub/grub2/include/grub/normal.h,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 normal.h
--- include/grub/normal.h 17 Sep 2004 09:36:52 -0000 1.9
+++ include/grub/normal.h 21 Jan 2005 00:09:34 -0000
@@ -158,6 +158,8 @@ void grub_cmp_init (void);
void grub_cmp_fini (void);
void grub_terminal_init (void);
void grub_terminal_fini (void);
+void grub_loop_init (void);
+void grub_loop_fini (void);
#endif
#endif /* ! GRUB_NORMAL_HEADER */
Index: util/grub-emu.c
===================================================================
RCS file: /cvsroot/grub/grub2/util/grub-emu.c,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 grub-emu.c
--- util/grub-emu.c 20 Jan 2005 17:25:39 -0000 1.11
+++ util/grub-emu.c 21 Jan 2005 00:09:34 -0000
@@ -176,13 +176,14 @@ main (int argc, char *argv[])
grub_cmp_init ();
grub_cat_init ();
grub_terminal_init ();
-
+ grub_loop_init ();
/* XXX: Should normal mode be started by default? */
grub_normal_init ();
/* Start GRUB! */
grub_main ();
+ grub_loop_fini ();
grub_util_biosdisk_fini ();
grub_normal_fini ();
grub_ufs_fini ();
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: Loopback device
2005-01-21 0:12 Loopback device Marco Gerards
@ 2005-01-21 12:38 ` P
2005-01-21 12:58 ` Marco Gerards
2005-01-21 13:32 ` Yoshinori K. Okuji
1 sibling, 1 reply; 13+ messages in thread
From: P @ 2005-01-21 12:38 UTC (permalink / raw)
To: The development of GRUB 2
Marco Gerards wrote:
> Hi,
>
> Here is a patch to add loopback support to GRUB. Although a lot of
> people told me they would find it useful, I just wrote it out of
> boredom without thinking about its use, just to figure out how hard it
> would be.
>
> I could commit it if anyone really wants it. Can I commit it?
Thanks, that's handy.
Note I'm not sure it's completely necessary though
as I have been using grub on a file for
ages by just doing `losetup /dev/loop0 disk.img`
before running grub.
--
Pádraig Brady - http://www.pixelbeat.org
--
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Loopback device
2005-01-21 12:38 ` P
@ 2005-01-21 12:58 ` Marco Gerards
0 siblings, 0 replies; 13+ messages in thread
From: Marco Gerards @ 2005-01-21 12:58 UTC (permalink / raw)
To: The development of GRUB 2
P@draigBrady.com writes:
> Marco Gerards wrote:
>> Hi,
>> Here is a patch to add loopback support to GRUB. Although a lot of
>> people told me they would find it useful, I just wrote it out of
>> boredom without thinking about its use, just to figure out how hard it
>> would be.
>> I could commit it if anyone really wants it. Can I commit it?
>
> Thanks, that's handy.
>
> Note I'm not sure it's completely necessary though
> as I have been using grub on a file for
> ages by just doing `losetup /dev/loop0 disk.img`
> before running grub.
This patch is more for when you are booting.
So when you booted GRUB from your harddrive you can use the commands:
loopback loop (hd0,4)/home/marco/image/floppy.ext2
linux (loop)/vmlinuz root=/dev/hda5
boot
To load a kernel from a floppy image on your harddrive. Same for
iso9660, etc.
I have no idea if your example would work. I never used such
things. :)
--
Marco
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Loopback device
2005-01-21 0:12 Loopback device Marco Gerards
2005-01-21 12:38 ` P
@ 2005-01-21 13:32 ` Yoshinori K. Okuji
2005-01-21 14:01 ` P
` (3 more replies)
1 sibling, 4 replies; 13+ messages in thread
From: Yoshinori K. Okuji @ 2005-01-21 13:32 UTC (permalink / raw)
To: The development of GRUB 2
On Friday 21 January 2005 01:12, Marco Gerards wrote:
> Here is a patch to add loopback support to GRUB. Although a lot of
> people told me they would find it useful, I just wrote it out of
> boredom without thinking about its use, just to figure out how hard
> it would be.
That's great. That is the very thing I wanted to have.
BTW, I think it is better to make it possible to choose a device type
(i.e. if it has a partition table or not). I'm always annoyed with that
Linux cannot deal with a hard disk image.
Okuji
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: Loopback device
2005-01-21 13:32 ` Yoshinori K. Okuji
@ 2005-01-21 14:01 ` P
2005-01-21 14:07 ` Marco Gerards
` (2 subsequent siblings)
3 siblings, 0 replies; 13+ messages in thread
From: P @ 2005-01-21 14:01 UTC (permalink / raw)
To: The development of GRUB 2
Yoshinori K. Okuji wrote:
> On Friday 21 January 2005 01:12, Marco Gerards wrote:
>
>>Here is a patch to add loopback support to GRUB. Although a lot of
>>people told me they would find it useful, I just wrote it out of
>>boredom without thinking about its use, just to figure out how hard
>>it would be.
>
>
> That's great. That is the very thing I wanted to have.
>
> BTW, I think it is better to make it possible to choose a device type
> (i.e. if it has a partition table or not). I'm always annoyed with that
> Linux cannot deal with a hard disk image.
Yes that's annoying. Have a look at:
ftp://ftp.hq.nasa.gov/pub/ig/ccd/enhanced_loopback/
I get around the problem with this script:
#!/bin/sh
FILE=$1
PART=$2
DEST=$3
UNITS=`fdisk -lu $FILE 2>/dev/null | grep $FILE$PART | tr -s ' ' | cut
-f2 -d' '`
OFFSET=`expr 512 '*' $UNITS`
mount -o loop,offset=$OFFSET $FILE $DEST
--
Pádraig Brady - http://www.pixelbeat.org
--
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: Loopback device
2005-01-21 13:32 ` Yoshinori K. Okuji
2005-01-21 14:01 ` P
@ 2005-01-21 14:07 ` Marco Gerards
2005-01-21 14:34 ` Yoshinori K. Okuji
2005-01-21 14:50 ` Vincent Pelletier
2005-01-21 14:46 ` Vincent Pelletier
2005-01-21 19:36 ` Marco Gerards
3 siblings, 2 replies; 13+ messages in thread
From: Marco Gerards @ 2005-01-21 14:07 UTC (permalink / raw)
To: The development of GRUB 2
"Yoshinori K. Okuji" <okuji@enbug.org> writes:
> On Friday 21 January 2005 01:12, Marco Gerards wrote:
>> Here is a patch to add loopback support to GRUB. Although a lot of
>> people told me they would find it useful, I just wrote it out of
>> boredom without thinking about its use, just to figure out how hard
>> it would be.
>
> That's great. That is the very thing I wanted to have.
>
> BTW, I think it is better to make it possible to choose a device type
> (i.e. if it has a partition table or not). I'm always annoyed with that
> Linux cannot deal with a hard disk image.
I could add an argument for that. Such thing is not hard. But I
don't have a harddisk image around to test this.
Can someone suggest a good image (bochs or so) that has multiple
partitions and filesystems so I can test this? I prefer ext2.
Thanks,
Marco
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Loopback device
2005-01-21 14:07 ` Marco Gerards
@ 2005-01-21 14:34 ` Yoshinori K. Okuji
2005-01-21 14:50 ` Vincent Pelletier
1 sibling, 0 replies; 13+ messages in thread
From: Yoshinori K. Okuji @ 2005-01-21 14:34 UTC (permalink / raw)
To: The development of GRUB 2
On Friday 21 January 2005 15:07, Marco Gerards wrote:
> Can someone suggest a good image (bochs or so) that has multiple
> partitions and filesystems so I can test this? I prefer ext2.
You can make it yourself very easily. Try parted.
Okuji
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Loopback device
2005-01-21 14:07 ` Marco Gerards
2005-01-21 14:34 ` Yoshinori K. Okuji
@ 2005-01-21 14:50 ` Vincent Pelletier
1 sibling, 0 replies; 13+ messages in thread
From: Vincent Pelletier @ 2005-01-21 14:50 UTC (permalink / raw)
To: The development of GRUB 2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Marco Gerards wrote:
| I could add an argument for that. Such thing is not hard. But I
| don't have a harddisk image around to test this.
|
| Can someone suggest a good image (bochs or so) that has multiple
| partitions and filesystems so I can test this? I prefer ext2.
That could be easily be generated :
$ dd if=/dev/zero of=your_image bs=512 count=...
$ /sbin/parted your_image
mklabel ("help mklabel" to see the available types of partition table
available)
mkpartfs
I used that a lot to test grub support for SPT & SUN partition tables.
Vincent Pelletier
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFB8Ra0FEQoKRQyjtURAqK1AJ9bMNXbRZGSsKuCUbUwqudtY6TDWgCgtlcg
4tKcWdW+dFcy85Rd9vtu9jM=
=o8fC
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Loopback device
2005-01-21 13:32 ` Yoshinori K. Okuji
2005-01-21 14:01 ` P
2005-01-21 14:07 ` Marco Gerards
@ 2005-01-21 14:46 ` Vincent Pelletier
2005-01-21 19:36 ` Marco Gerards
3 siblings, 0 replies; 13+ messages in thread
From: Vincent Pelletier @ 2005-01-21 14:46 UTC (permalink / raw)
To: The development of GRUB 2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Yoshinori K. Okuji wrote:
| I'm always annoyed with that
| Linux cannot deal with a hard disk image.
Same here.
Maybe should we try to write something ?
Vincent Pelletier
PS: thanks Okuji & Marco for the savanah access :).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFB8RXdFEQoKRQyjtURAtqJAJ9fpUIKbQCwRgXzRnHIc4VHo7azJwCff5uG
u9ePasK7WVWBM15Fhlr7mBI=
=F/r5
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Loopback device
2005-01-21 13:32 ` Yoshinori K. Okuji
` (2 preceding siblings ...)
2005-01-21 14:46 ` Vincent Pelletier
@ 2005-01-21 19:36 ` Marco Gerards
2005-01-21 20:46 ` Yoshinori K. Okuji
3 siblings, 1 reply; 13+ messages in thread
From: Marco Gerards @ 2005-01-21 19:36 UTC (permalink / raw)
To: The development of GRUB 2
"Yoshinori K. Okuji" <okuji@enbug.org> writes:
> On Friday 21 January 2005 01:12, Marco Gerards wrote:
>> Here is a patch to add loopback support to GRUB. Although a lot of
>> people told me they would find it useful, I just wrote it out of
>> boredom without thinking about its use, just to figure out how hard
>> it would be.
>
> That's great. That is the very thing I wanted to have.
>
> BTW, I think it is better to make it possible to choose a device type
> (i.e. if it has a partition table or not). I'm always annoyed with that
> Linux cannot deal with a hard disk image.
I did that and the new patch is included with this email.
Unfortunately it does not work well, but I believe that is a
filesystem problem. Can I commit this patch? I will put the
filesystem problem on the wiki so it is documented to have a look at
it later.
When the PPC port is mostly finished I plan to have a look at the bugs
in GRUB and do some testing. I think there are some regressions in
the filesystems, there are a few known bugs and perhaps I can write
some testing tools to make it easier to test filesystems.
Thanks,
Marco
2005-01-21 Marco Gerards <metgerards@student.han.nl>
Add the loopback device, a device via which files can be accessed
as devices.
* conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/loopback.c'.
(pkgdata_MODULES): Add loopback.mod.
(loopback_SOURCES): New variable.
(loopback_CFLAGS): Likewise.
* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
`disk/loopback.c'.
(pkgdata_MODULES): Add loopback.mod.
(loopback_SOURCES): New variable.
(loopback_CFLAGS): Likewise.
* disk/loopback.c: new file.
* include/grub/normal.h (grub_loop_init): New prototype.
(grub_loop_fini): New prototype.
(util/grub-emu.c): Initialize and de-initialize loopback support.
* include/grub/disk.h (grub_disk_dev_id): Add
`GRUB_DISK_DEVICE_LOOPBACK_ID'.
Index: conf/i386-pc.rmk
===================================================================
RCS file: /cvsroot/grub/grub2/conf/i386-pc.rmk,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 i386-pc.rmk
--- conf/i386-pc.rmk 4 Dec 2004 18:45:45 -0000 1.23
+++ conf/i386-pc.rmk 21 Jan 2005 18:59:54 -0000
@@ -73,7 +73,7 @@ grub_emu_SOURCES = kern/main.c kern/devi
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 fs/hfs.c fs/jfs.c fs/iso9660.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
+ util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c disk/loopback.c
grub_emu_LDFLAGS = -lncurses
# For genmoddep.
@@ -83,7 +83,7 @@ genmoddep_SOURCES = util/genmoddep.c
pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \
boot.mod cmp.mod cat.mod terminal.mod fshelp.mod chain.mod multiboot.mod \
- amiga.mod apple.mod pc.mod
+ amiga.mod apple.mod pc.mod loopback.mod
# For _chain.mod.
_chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -190,3 +190,7 @@ apple_mod_CFLAGS = $(COMMON_CFLAGS)
# For pc.mod
pc_mod_SOURCES = partmap/pc.c
pc_mod_CFLAGS = $(COMMON_CFLAGS)
+
+# For loopback.mod
+loopback_SOURCES = disk/loopback.c
+loopback_CFLAGS = $(COMMON_CFLAGS)
Index: conf/powerpc-ieee1275.rmk
===================================================================
RCS file: /cvsroot/grub/grub2/conf/powerpc-ieee1275.rmk,v
retrieving revision 1.19
diff -u -p -u -p -r1.19 powerpc-ieee1275.rmk
--- conf/powerpc-ieee1275.rmk 4 Jan 2005 14:01:45 -0000 1.19
+++ conf/powerpc-ieee1275.rmk 21 Jan 2005 18:59:55 -0000
@@ -41,7 +41,7 @@ grub_emu_SOURCES = kern/main.c kern/devi
normal/cmdline.c normal/command.c normal/main.c normal/menu.c \
normal/arg.c kern/partition.c \
util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c \
- kern/env.c commands/ls.c \
+ kern/env.c disk/loopback.c commands/ls.c \
commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c
grub_emu_LDFLAGS = -lncurses
@@ -64,7 +64,8 @@ genmoddep_SOURCES = util/genmoddep.c
# Modules.
pkgdata_MODULES = _linux.mod linux.mod fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod font.mod \
- boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod pc.mod
+ boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
+ pc.mod loopback.mod
# For fshelp.mod.
fshelp_mod_SOURCES = fs/fshelp.c
@@ -151,3 +152,7 @@ apple_mod_CFLAGS = $(COMMON_CFLAGS)
# For pc.mod
pc_mod_SOURCES = partmap/pc.c
pc_mod_CFLAGS = $(COMMON_CFLAGS)
+
+# For loopback.mod
+loopback_SOURCES = disk/loopback.c
+loopback_CFLAGS = $(COMMON_CFLAGS)
Index: disk/loopback.c
===================================================================
RCS file: disk/loopback.c
diff -N disk/loopback.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ disk/loopback.c 21 Jan 2005 18:59:55 -0000
@@ -0,0 +1,272 @@
+/* loopback.c - command to add loopback devices. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005 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/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+
+struct grub_loopback
+{
+ char *devname;
+ char *filename;
+ int has_partitions;
+ struct grub_loopback *next;
+};
+
+static struct grub_loopback *loopback_list;
+
+static const struct grub_arg_option options[] =
+ {
+ {"delete", 'd', 0, "Delete the loopback device entry", 0, 0},
+ {"partitions", 'p', 0, "Set that the drive has partitions to"
+ " simulate a harddrive", 0, 0},
+ {0, 0, 0, 0, 0, 0}
+ };
+
+/* Delete the loopback device NAME. */
+static grub_err_t
+delete_loopback (const char *name)
+{
+ struct grub_loopback *dev;
+ struct grub_loopback **prev;
+
+ /* Search for the device. */
+ for (dev = loopback_list, prev = &loopback_list;
+ dev; prev = &dev->next, dev = dev->next)
+ if (!grub_strcmp (dev->devname, name))
+ break;
+ if (!dev)
+ return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found");
+
+ /* Remove the device from the list. */
+ *prev = dev->next;
+
+ grub_free (dev->devname);
+ grub_free (dev->filename);
+ grub_free (dev);
+
+ return 0;
+}
+
+
+/* The command to add and remove loopback devices. */
+static grub_err_t
+grub_cmd_loopback (struct grub_arg_list *state,
+ int argc, char **args)
+{
+ grub_file_t file;
+ struct grub_loopback *newdev;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+ /* Check if `-d' was used. */
+ if (state[0].set)
+ return delete_loopback (args[0]);
+
+ if (argc < 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+ file = grub_file_open (args[1]);
+ if (! file)
+ return grub_errno;
+
+ /* Close the file, the only reason for opening it is validation. */
+ grub_file_close (file);
+
+ /* First try to replace the old device. */
+ for (newdev = loopback_list; newdev; newdev = newdev->next)
+ if (!grub_strcmp (newdev->devname, args[0]))
+ break;
+ if (newdev)
+ {
+ char *newname = grub_strdup (args[1]);
+ if (!newname)
+ return grub_errno;
+
+ grub_free (newdev->filename);
+ newdev->filename = newname;
+
+ /* Set has_partitions when `--partitions' was used. */
+ newdev->has_partitions = state[1].set;
+
+ return 0;
+ }
+
+ /* Unable to replace it, make a new entry. */
+ newdev = grub_malloc (sizeof (struct grub_loopback));
+ if (!newdev)
+ return grub_errno;
+
+ newdev->devname = grub_strdup (args[0]);
+ if (!newdev->devname)
+ {
+ grub_free (newdev);
+ return grub_errno;
+ }
+
+ newdev->filename = grub_strdup (args[1]);
+ if (!newdev->devname)
+ {
+ grub_free (newdev->devname);
+ grub_free (newdev);
+ return grub_errno;
+ }
+
+ /* Set has_partitions when `--partitions' was used. */
+ newdev->has_partitions = state[1].set;
+
+ /* Add the new entry to the list. */
+ newdev->next = loopback_list;
+ loopback_list = newdev;
+
+ return 0;
+}
+
+\f
+static int
+grub_loopback_iterate (int (*hook) (const char *name))
+{
+ struct grub_loopback *d;
+ for (d = loopback_list; d; d = d->next)
+ {
+ if (hook (d->devname))
+ return 1;
+ }
+ return 0;
+}
+
+static grub_err_t
+grub_loopback_open (const char *name, grub_disk_t disk)
+{
+ grub_file_t file;
+ struct grub_loopback *dev;
+
+ for (dev = loopback_list; dev; dev = dev->next)
+ if (!grub_strcmp (dev->devname, name))
+ break;
+
+ if (! dev)
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
+
+ file = grub_file_open (dev->filename);
+ if (! file)
+ return grub_errno;
+
+ /* Use the filesize for the disk size, round up to a complete sector. */
+ disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1)
+ / GRUB_DISK_SECTOR_SIZE);
+ disk->id = (int) dev;
+
+ disk->has_partitions = dev->has_partitions;
+ disk->data = file;
+
+ return 0;
+}
+
+static void
+grub_loopback_close (grub_disk_t disk)
+{
+ grub_file_t file = (grub_file_t) disk->data;
+
+ grub_file_close (file);
+}
+
+static grub_err_t
+grub_loopback_read (grub_disk_t disk, unsigned long sector,
+ unsigned long size, char *buf)
+{
+ grub_file_t file = (grub_file_t) disk->data;
+ long pos;
+
+ grub_file_seek (file, sector * GRUB_DISK_SECTOR_SIZE);
+
+ grub_file_read (file, buf, size * GRUB_DISK_SECTOR_SIZE);
+ if (grub_errno)
+ return grub_errno;
+
+ /* In case there is more data read than there is available, in case
+ of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
+ the rest with zeros. */
+ pos = sector * GRUB_DISK_SECTOR_SIZE + size * GRUB_DISK_SECTOR_SIZE;
+ if (pos > file->size)
+ {
+ unsigned long amount = pos - file->size;
+ grub_memset (buf + pos - amount, amount, 0);
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_loopback_write (grub_disk_t disk __attribute ((unused)),
+ unsigned long sector __attribute ((unused)),
+ unsigned long size __attribute ((unused)),
+ const char *buf __attribute ((unused)))
+{
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_loopback_dev =
+ {
+ .name = "loopback",
+ .id = GRUB_DISK_DEVICE_LOOPBACK_ID,
+ .iterate = grub_loopback_iterate,
+ .open = grub_loopback_open,
+ .close = grub_loopback_close,
+ .read = grub_loopback_read,
+ .write = grub_loopback_write,
+ .next = 0
+ };
+
+
+\f
+#ifdef GRUB_UTIL
+void
+grub_loop_init (void)
+{
+ grub_register_command ("loopback", grub_cmd_loopback, GRUB_COMMAND_FLAG_BOTH,
+ "loopback [OPTIONS] DEVICENAME FILE", "Makes a device of a file", options);
+ grub_disk_dev_register (&grub_loopback_dev);
+
+}
+
+void
+grub_loop_fini (void)
+{
+ grub_unregister_command ("loopback");
+}
+#else /* ! GRUB_UTIL */
+GRUB_MOD_INIT
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("loopback", grub_cmd_loopback, GRUB_COMMAND_FLAG_BOTH,
+ "loopback [OPTIONS] DEVICENAME FILE", "Makes a device of a file", options);
+}
+
+GRUB_MOD_FINI
+{
+ grub_unregister_command ("loopback");
+}
+#endif /* ! GRUB_UTIL */
Index: include/grub/disk.h
===================================================================
RCS file: /cvsroot/grub/grub2/include/grub/disk.h,v
retrieving revision 1.5
diff -u -p -u -p -r1.5 disk.h
--- include/grub/disk.h 21 Aug 2004 13:54:22 -0000 1.5
+++ include/grub/disk.h 21 Jan 2005 18:59:56 -0000
@@ -31,6 +31,7 @@ enum grub_disk_dev_id
{
GRUB_DISK_DEVICE_BIOSDISK_ID,
GRUB_DISK_DEVICE_OFDISK_ID,
+ GRUB_DISK_DEVICE_LOOPBACK_ID
};
struct grub_disk;
Index: include/grub/normal.h
===================================================================
RCS file: /cvsroot/grub/grub2/include/grub/normal.h,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 normal.h
--- include/grub/normal.h 17 Sep 2004 09:36:52 -0000 1.9
+++ include/grub/normal.h 21 Jan 2005 18:59:56 -0000
@@ -158,6 +158,8 @@ void grub_cmp_init (void);
void grub_cmp_fini (void);
void grub_terminal_init (void);
void grub_terminal_fini (void);
+void grub_loop_init (void);
+void grub_loop_fini (void);
#endif
#endif /* ! GRUB_NORMAL_HEADER */
Index: util/grub-emu.c
===================================================================
RCS file: /cvsroot/grub/grub2/util/grub-emu.c,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 grub-emu.c
--- util/grub-emu.c 20 Jan 2005 17:25:39 -0000 1.11
+++ util/grub-emu.c 21 Jan 2005 18:59:56 -0000
@@ -176,13 +176,15 @@ main (int argc, char *argv[])
grub_cmp_init ();
grub_cat_init ();
grub_terminal_init ();
-
+ grub_loop_init ();
+
/* XXX: Should normal mode be started by default? */
grub_normal_init ();
-
+
/* Start GRUB! */
grub_main ();
+ grub_loop_fini ();
grub_util_biosdisk_fini ();
grub_normal_fini ();
grub_ufs_fini ();
^ permalink raw reply [flat|nested] 13+ messages in thread
* Loopback device
@ 2001-11-05 17:53 guenther.sohler
0 siblings, 0 replies; 13+ messages in thread
From: guenther.sohler @ 2001-11-05 17:53 UTC (permalink / raw)
To: linux-sound
Does there a loop back device exist for the AWE32,
where you can send in midi data and it plays it ????
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2005-01-21 22:00 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-21 0:12 Loopback device Marco Gerards
2005-01-21 12:38 ` P
2005-01-21 12:58 ` Marco Gerards
2005-01-21 13:32 ` Yoshinori K. Okuji
2005-01-21 14:01 ` P
2005-01-21 14:07 ` Marco Gerards
2005-01-21 14:34 ` Yoshinori K. Okuji
2005-01-21 14:50 ` Vincent Pelletier
2005-01-21 14:46 ` Vincent Pelletier
2005-01-21 19:36 ` Marco Gerards
2005-01-21 20:46 ` Yoshinori K. Okuji
2005-01-21 21:37 ` Marco Gerards
-- strict thread matches above, loose matches on Subject: below --
2001-11-05 17:53 guenther.sohler
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.