All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch] search for partition using GPT GUID
@ 2010-02-12 18:21 George Buranov
  2010-02-18  7:13 ` gburanov
  0 siblings, 1 reply; 12+ messages in thread
From: George Buranov @ 2010-02-12 18:21 UTC (permalink / raw)
  To: The development of GNU GRUB


[-- Attachment #1.1: Type: text/plain, Size: 525 bytes --]

Hello everybody.

I have just implemented support for GPT GUID search and I am really
interested in providing this patch for integration.Who is in chief here, we
can discuss details =)

Patch is included. The syntax is now the following

# Entry 1 - Chainload another bootloader
menuentry "Chainload LILO"
{
    search --no-floppy --gpt-guid --set a97fa026-fa15-8244-b272-5bff98b1c522
    chainloader /boot/elilo.efi
}

As I said before, search over GPT GUIDs is much safer then in FS UUID (see
topic below)

Regards,
Georgy

[-- Attachment #1.2: Type: text/html, Size: 608 bytes --]

[-- Attachment #2: gpt_guid.diff --]
[-- Type: application/octet-stream, Size: 10268 bytes --]

=== modified file 'ChangeLog'
--- ChangeLog	2010-02-10 19:27:12 +0000
+++ ChangeLog	2010-02-12 14:14:46 +0000
@@ -1,3 +1,8 @@
+2010-02-12  Georgy Buranov <gburanov@gmail.com>
+
+	* disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix bug obtaining device name of the whole disk
+	* fs/iso9660.c (grub_iso9660_iterate_dir): Remove file versions from ISO9660&Joliet file names
+
 2010-02-10  Vladimir Serbinenko  <phcoder@gmail.com>
 
 	Pass SIMPLE framebuffer size in bytes and not 64K blocks.

=== modified file 'commands/search.c'
--- commands/search.c	2010-01-20 08:12:47 +0000
+++ commands/search.c	2010-02-12 18:10:03 +0000
@@ -23,6 +23,9 @@
 #include <grub/err.h>
 #include <grub/dl.h>
 #include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/gpt_partition.h>
+#include <grub/partition.h>
 #include <grub/file.h>
 #include <grub/env.h>
 #include <grub/command.h>
@@ -62,6 +65,58 @@
 	  }
 	grub_free (buf);
       }
+#elif defined (DO_SEARCH_GPT_GUID)
+      {
+	/* type is SEARCH_GPT_GUID. Obtaining device by GPT GUID */
+	grub_device_t dev = grub_device_open (name);
+	if (dev)
+	{
+	  const char * dest_partmap  = 0;
+
+	  auto int identify_partmap (grub_disk_t /*disk*/, const grub_partition_t p);
+	  int identify_partmap (grub_disk_t disk __attribute__((unused)), const grub_partition_t p)
+	  {
+	    dest_partmap = p->partmap->name;
+	    return 1;
+	  }
+	
+	  dest_partmap = 0;
+	  grub_partition_iterate (dev->disk, identify_partmap);	
+	  if (grub_strcmp (dest_partmap, "part_gpt") == 0)
+	  {
+	    auto void identify_gpt_partition(grub_gpt_partentry_t partition);
+	  
+	    void identify_gpt_partition(grub_gpt_partentry_t partition)
+	    {
+	      int i = 0;
+	      char guid[37];
+	      char* pguid = (char*)guid;
+	      grub_memset(pguid, 0, 37);
+	    
+	      for (; i < 16; ++i)
+	      {
+		if (i == 4 || i == 6 || i == 8 || i == 10)
+		{
+		  grub_snprintf(pguid, 37 - i, "-");
+		  ++pguid;
+		}
+		grub_snprintf(pguid, 37 - i, "%02x", partition->guid[i]);
+		pguid += 2;	       
+	      }
+	      // For debug
+	      grub_printf("Compare %s and %s\n", guid, key);	    
+	      if (grub_strcmp(guid, key) == 0)
+	      {
+		found = 1;
+	      }
+	      return;
+	    }
+	  
+	    // this is gpt disk.
+	   gpt_partition_map_gpt_iterate(dev->disk, identify_gpt_partition);
+	  }
+	}
+      }
 #else
       {
 	/* SEARCH_FS_UUID or SEARCH_LABEL */
@@ -152,6 +207,8 @@
 GRUB_MOD_INIT(search_file)
 #elif defined (DO_SEARCH_FS_UUID)
 GRUB_MOD_INIT(search_fs_uuid)
+#elif defined (DO_SEARCH_GPT_GUID)
+GRUB_MOD_INIT(search_gpt_guid)
 #else
 GRUB_MOD_INIT(search_fs_label)
 #endif
@@ -166,6 +223,8 @@
 GRUB_MOD_FINI(search_file)
 #elif defined (DO_SEARCH_FS_UUID)
 GRUB_MOD_FINI(search_fs_uuid)
+#elif defined (DO_SEARCH_GPT_GUID)
+GRUB_MOD_FINI(search_gpt_guid)
 #else
 GRUB_MOD_FINI(search_fs_label)
 #endif

=== modified file 'commands/search_wrap.c'
--- commands/search_wrap.c	2009-12-25 22:06:52 +0000
+++ commands/search_wrap.c	2010-02-12 17:06:50 +0000
@@ -34,6 +34,8 @@
      0, 0},
     {"fs-uuid",		'u', 0, N_("Search devices by a filesystem UUID."),
      0, 0},
+    {"gpt-guid",	'g', 0, N_("Search devices by GPT GUID."),
+     0, 0},
     {"set",		's', GRUB_ARG_OPTION_OPTIONAL,
      N_("Set a variable to the first device found."), "VAR", ARG_TYPE_STRING},
     {"no-floppy",	'n', 0, N_("Do not probe any floppy drive."), 0, 0},
@@ -45,6 +47,7 @@
     SEARCH_FILE,
     SEARCH_LABEL,
     SEARCH_FS_UUID,
+    SEARCH_GPT_GUID,
     SEARCH_SET,
     SEARCH_NO_FLOPPY,
  };
@@ -67,6 +70,8 @@
     grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set);
   else if (state[SEARCH_FILE].set)
     grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set);
+  else if (state[SEARCH_GPT_GUID].set)
+    grub_search_gpt_guid (args[0], var, state[SEARCH_NO_FLOPPY].set);   
   else
     return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
 
@@ -80,9 +85,9 @@
   cmd =
     grub_register_extcmd ("search", grub_cmd_search,
 			  GRUB_COMMAND_FLAG_BOTH,
-			  N_("search [-f|-l|-u|-s|-n] NAME"),
+			  N_("search [-f|-l|-u|-g|-s|-n] NAME"),
 			  N_("Search devices by file, filesystem label"
-			     " or filesystem UUID."
+			     " ,filesystem UUID or GPT GUID."
 			     " If --set is specified, the first device found is"
 			     " set to a variable. If no variable name is"
 			     " specified, \"root\" is used."),

=== modified file 'conf/any-emu.rmk'
--- conf/any-emu.rmk	2010-02-03 00:24:07 +0000
+++ conf/any-emu.rmk	2010-02-12 16:46:14 +0000
@@ -10,6 +10,7 @@
 	commands/handler.c commands/ls.c commands/test.c 		\
 	commands/search_wrap.c commands/search_file.c			\
 	commands/search_label.c commands/search_uuid.c			\
+	commands/search_guid.c						\
 	commands/blocklist.c commands/hexdump.c				\
 	lib/hexdump.c commands/halt.c commands/reboot.c			\
 	lib/envblk.c commands/loadenv.c					\

=== modified file 'conf/common.rmk'
--- conf/common.rmk	2010-02-06 14:37:23 +0000
+++ conf/common.rmk	2010-02-12 17:05:18 +0000
@@ -519,7 +519,7 @@
 search_mod_CFLAGS = $(COMMON_CFLAGS)
 search_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-pkglib_MODULES += search_fs_file.mod search_fs_uuid.mod search_label.mod
+pkglib_MODULES += search_fs_file.mod search_fs_uuid.mod search_label.mod search_gpt_guid.mod
 
 # For search.mod.
 search_fs_file_mod_SOURCES = commands/search_file.c
@@ -536,6 +536,11 @@
 search_fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
 search_fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For search.mod.
+search_gpt_guid_mod_SOURCES = commands/search_guid.c
+search_gpt_guid_mod_CFLAGS = $(COMMON_CFLAGS)
+search_gpt_guid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For test.mod.
 test_mod_SOURCES = commands/test.c
 test_mod_CFLAGS = $(COMMON_CFLAGS)

=== modified file 'disk/efi/efidisk.c'
--- disk/efi/efidisk.c	2010-01-20 08:12:47 +0000
+++ disk/efi/efidisk.c	2010-02-12 14:05:23 +0000
@@ -825,7 +825,7 @@
 	  if (! disk)
 	    return 1;
 
-	  if (disk->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+	  if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
 	    {
 	      struct grub_efidisk_data *d;
 

=== modified file 'fs/iso9660.c'
--- fs/iso9660.c	2010-01-27 03:11:20 +0000
+++ fs/iso9660.c	2010-02-12 14:13:01 +0000
@@ -615,9 +615,6 @@
 	if (!filename)
 	  {
 	    name[dirent.namelen] = '\0';
-	    filename = grub_strrchr (name, ';');
-	    if (filename)
-	      *filename = '\0';
 
 	    if (dirent.namelen == 1 && name[0] == 0)
 	      filename = ".";
@@ -640,6 +637,14 @@
 
             filename_alloc = 1;
           }
+	  
+	 if (!dir->data->rockridge)
+	 {
+	   // On simple ISO 9660 disks and on joliet, we need to remove file version, if any
+	    char* lastSymbol = grub_strrchr (filename, ';');
+	    if (lastSymbol)
+	      *lastSymbol = '\0';
+	 }	  
 
 	if (hook (filename, type, node))
 	  {

=== modified file 'include/grub/gpt_partition.h'
--- include/grub/gpt_partition.h	2009-04-19 20:38:46 +0000
+++ include/grub/gpt_partition.h	2010-02-12 17:21:00 +0000
@@ -20,6 +20,9 @@
 #define GRUB_GPT_PARTITION_HEADER	1
 
 #include <grub/types.h>
+#include <grub/err.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
 
 struct grub_gpt_part_type
 {
@@ -67,5 +70,9 @@
   grub_uint64_t attrib;
   char name[72];
 } __attribute__ ((packed));
+typedef struct grub_gpt_partentry *grub_gpt_partentry_t;
+
+grub_err_t
+gpt_partition_map_gpt_iterate(grub_disk_t disk, void (*hook) (grub_gpt_partentry_t entry));
 
 #endif /* ! GRUB_GPT_PARTITION_HEADER */

=== modified file 'include/grub/search.h'
--- include/grub/search.h	2009-11-23 20:15:44 +0000
+++ include/grub/search.h	2010-02-12 17:05:39 +0000
@@ -22,5 +22,6 @@
 void grub_search_fs_file (const char *key, const char *var, int no_floppy);
 void grub_search_fs_uuid (const char *key, const char *var, int no_floppy);
 void grub_search_label (const char *key, const char *var, int no_floppy);
+void grub_search_gpt_guid (const char *key, const char *var, int no_floppy);
 
 #endif

=== modified file 'partmap/gpt.c'
--- partmap/gpt.c	2010-01-20 08:12:47 +0000
+++ partmap/gpt.c	2010-02-12 17:30:09 +0000
@@ -34,12 +34,15 @@
 
 static struct grub_partition_map grub_gpt_partition_map;
 
-\f
-
-static grub_err_t
-gpt_partition_map_iterate (grub_disk_t disk,
-			   int (*hook) (grub_disk_t disk,
-					const grub_partition_t partition))
+/*
+* Both gpt_partition_map_gpt_iterate and gpt_partition_map_iterate are using this func internally
+* to obtain grub_gpt_partentry_t and grub_partition_t of every partition
+*/
+static
+grub_err_t
+gpt_partition_map_iterate_internal(grub_disk_t disk, 
+			  int (*hook) (grub_disk_t disk, const grub_partition_t partition,
+				       grub_gpt_partentry_t entry))
 {
   struct grub_partition part;
   struct grub_gpt_header gpt;
@@ -98,7 +101,7 @@
 			(unsigned long long) part.start,
 			(unsigned long long) part.len);
 
-	  if (hook (disk, &part))
+	  if (hook (disk, &part, &entry))
 	    return 1;
 	}
 
@@ -110,7 +113,39 @@
 	}
     }
 
-  return 0;
+  return 0;  
+}
+
+grub_err_t
+gpt_partition_map_gpt_iterate(grub_disk_t disk, void (*hook) (grub_gpt_partentry_t entry))
+{
+  auto int hook_func(grub_disk_t hook_disk, const grub_partition_t partition, grub_gpt_partentry_t entry);
+  
+  int hook_func(grub_disk_t hook_disk, const grub_partition_t partition, grub_gpt_partentry_t entry)
+  {
+    if (hook_disk->partition->index == partition->index)
+    {
+      hook(entry);
+    }
+    return 0;
+  }
+  
+  return gpt_partition_map_iterate_internal(disk, hook_func);
+}
+
+static grub_err_t
+gpt_partition_map_iterate (grub_disk_t disk,
+			   int (*hook) (grub_disk_t disk,
+					const grub_partition_t partition))
+{
+  auto int hook_func(grub_disk_t hook_disk, const grub_partition_t partition, grub_gpt_partentry_t entry);
+  int hook_func(grub_disk_t hook_disk, const grub_partition_t partition, grub_gpt_partentry_t entry)
+  {
+    if (entry->guid)
+      return hook(hook_disk, partition);    
+  }
+  
+  return gpt_partition_map_iterate_internal(disk, hook_func);
 }
 
 

=== modified file 'po/POTFILES'
--- po/POTFILES	2010-01-21 08:04:49 +0000
+++ po/POTFILES	2010-02-12 16:48:29 +0000
@@ -40,6 +40,7 @@
 commands/search_file.c
 commands/search_label.c
 commands/search_uuid.c
+commands/search_guid.c
 commands/sleep.c
 commands/test.c
 commands/true.c


^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: [patch] search for partition using GPT GUID
@ 2010-03-11 14:43 KESHAV P.R.
  2010-03-11 20:04 ` Isaac Dupree
  0 siblings, 1 reply; 12+ messages in thread
From: KESHAV P.R. @ 2010-03-11 14:43 UTC (permalink / raw)
  To: grub-devel

GPT GUID is one of the best FILESYSTEM-INDEPENDENT way of uniquely
identifying a partition.

Most people who use GPT are thos who have need for many primary
partitions. I use GPT in my internal 320 GB HDD (12 partitions) and
500 GB USB 2.0 external (11 partitions).

My guess of the workflow of grub2's search command :-

1) Read the partition table both the disks.
2) Find the starting/ending sectors of First Partition.
3) Detect its filesystem
4) Check for its UUID/GUID (length/uniqueness depends on the FS.
5) If the UUID matches, set it as the root part (set root=*)
6) If the UUID is different repeat steps 2,3,4 and 5 for 2nd partition
(and so on).

The time taken for this operation depends on the number of partitions
and the filesystem in each part. If one uses a 4 TB drive with 40
partitions of 100 GB (approx) each. GRUB2 has to read all the
partitions, its filesystems in order till a UUID match is found. This
will take a long time and will take more time depending on the not of
disks connected.

But if GPT GUID is used, only the partition table needs to be accessed
and each partition entry is checked for its "Partition Unique GUID"
till a match is found. This is way faster since no filesystem is
accessed and that accessing time is saved (especially for more no. of
partitions). Maybe even the GPT Disk GUID can be used to reference a
GPT disk (instead of confusion over whether it is (hd1) or (hd2) and
so on.

Also I have no-FS partitions like BIOS-Boot incase of grub2, ie lets
say I dd copy some bootloader to an unknown (my own random) GUID
partition (like the way grub2 core.img is embedded in GPT-BIOS mode)
in one of the external HDD, and I connect 2 external HDDs, how will I
know which one is /dev/sdb and which one is /dev/sdc. SInce that part
has no FS, the only way to uniquely reference that partition is using
it "Unique GPT GUID". Also FS like FAT do not have UUIDs which can be
regarded as unique. The main reason GPT table is good is because it
provided FS-independent way to reference a part thus removing
abiguity. Hope this test case is sufficient. Thank you.

PS : Please change the behavior of "help" command in grub2 shell as it
is not possible to see all possible commands (it scrolls past screen
and I see commands starting from s-alphabet only)



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: [patch] search for partition using GPT GUID
@ 2010-03-12 11:44 KESHAV P.R.
  0 siblings, 0 replies; 12+ messages in thread
From: KESHAV P.R. @ 2010-03-12 11:44 UTC (permalink / raw)
  To: grub-devel

My mail is actually a reply to the request for a use case from grub2
developers for for the gpt_guid.diff patch ( patch -
http://lists.gnu.org/archive/html/grub-devel/2010-02/msg00094.html and
question - http://lists.gnu.org/archive/html/grub-devel/2010-02/msg00175.html
). This is a very nice feature and should definitely be integrated
into grub2 trunk.

If FS-UUIDs are sufficient then why does Microsoft use the Unique GUID
of a GPT partition in its Boot Configuration Data (equivalent to
grub.cfg, for Windows Boot Manager) instead of the part's NTFS
filesystem UUID for booting Windows (for example)?



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: [patch] search for partition using GPT GUID
@ 2010-03-12 11:52 KESHAV P.R.
  0 siblings, 0 replies; 12+ messages in thread
From: KESHAV P.R. @ 2010-03-12 11:52 UTC (permalink / raw)
  To: grub-devel

My mail is actually a reply to the request for a use case from grub2
developers for for the gpt_guid.diff patch ( patch -
http://lists.gnu.org/archive/html/grub-devel/2010-02/msg00094.html and
question - http://lists.gnu.org/archive/html/grub-devel/2010-02/msg00175.html
). This is a very nice feature and should definitely be integrated
into grub2 trunk.

If FS-UUIDs are sufficient then why does Microsoft use the Unique GUID
of a GPT partition in its Boot Configuration Data (equivalent to
grub.cfg, for Windows Boot Manager) instead of the part's NTFS
filesystem UUID for booting Windows (for example)?



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2010-04-02 20:01 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-12 18:21 [patch] search for partition using GPT GUID George Buranov
2010-02-18  7:13 ` gburanov
2010-02-20 11:05   ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-02-21 12:32     ` Michal Suchanek
2010-02-21 13:27       ` Colin Watson
2010-02-25  6:59     ` gburanov
2010-04-02 20:01       ` Vladimir 'φ-coder/phcoder' Serbinenko
  -- strict thread matches above, loose matches on Subject: below --
2010-03-11 14:43 KESHAV P.R.
2010-03-11 20:04 ` Isaac Dupree
2010-03-11 20:07   ` Seth Goldberg
2010-03-12 11:44 KESHAV P.R.
2010-03-12 11:52 KESHAV P.R.

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.