grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] parttool


From: phcoder
Subject: [PATCH] parttool
Date: Wed, 04 Mar 2009 22:15:30 +0100
User-agent: Thunderbird 2.0.0.19 (X11/20090105)

Hello here is the implementation of parttool with the syntax I proposed earlier and equivalent of parttype, makeactive and hide/unhide
--

Regards
Vladimir 'phcoder' Serbinenko
Index: conf/common.rmk
===================================================================
--- conf/common.rmk     (revision 2017)
+++ conf/common.rmk     (working copy)
@@ -334,7 +340,7 @@
        cmp.mod cat.mod help.mod search.mod                                     
\
        loopback.mod fs_uuid.mod configfile.mod echo.mod        \
        terminfo.mod test.mod blocklist.mod hexdump.mod         \
-       read.mod sleep.mod loadenv.mod crc.mod
+       read.mod sleep.mod loadenv.mod crc.mod parttool.mod pcpart.mod
 
 # For hello.mod.
 hello_mod_SOURCES = hello/hello.c
@@ -346,6 +352,16 @@
 boot_mod_CFLAGS = $(COMMON_CFLAGS)
 boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For parttool.mod.
+parttool_mod_SOURCES = commands/parttool.c
+parttool_mod_CFLAGS = $(COMMON_CFLAGS)
+parttool_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pcpart.mod.
+pcpart_mod_SOURCES = parttool/pcpart.c
+pcpart_mod_CFLAGS = $(COMMON_CFLAGS)
+pcpart_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For handler.mod.
 handler_mod_SOURCES = commands/handler.c
 handler_mod_CFLAGS = $(COMMON_CFLAGS)
Index: conf/i386-coreboot.rmk
===================================================================
--- conf/i386-coreboot.rmk      (revision 2017)
+++ conf/i386-coreboot.rmk      (working copy)
@@ -87,6 +89,7 @@
        \
        disk/raid.c disk/raid5_recover.c disk/raid6_recover.c           \
        disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
+       commands/parttool.c parttool/pcpart.c                           \
        grub_emu_init.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
Index: conf/i386-efi.rmk
===================================================================
--- conf/i386-efi.rmk   (revision 2017)
+++ conf/i386-efi.rmk   (working copy)
@@ -65,6 +66,7 @@
        \
        disk/raid.c disk/raid5_recover.c disk/raid6_recover.c           \
        disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
+       commands/parttool.c parttool/pcpart.c                           \
        grub_emu_init.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
Index: conf/i386-ieee1275.rmk
===================================================================
--- conf/i386-ieee1275.rmk      (revision 2017)
+++ conf/i386-ieee1275.rmk      (working copy)
@@ -87,6 +89,7 @@
        \
        disk/raid.c disk/raid5_recover.c disk/raid6_recover.c           \
        disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
+       commands/parttool.c parttool/pcpart.c                           \
        grub_emu_init.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
Index: conf/i386-pc.rmk
===================================================================
--- conf/i386-pc.rmk    (revision 2017)
+++ conf/i386-pc.rmk    (working copy)
@@ -146,3 +147,4 @@
        \
        disk/raid.c disk/raid5_recover.c disk/raid6_recover.c           \
        disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
+       commands/parttool.c parttool/pcpart.c                           \
        grub_emu_init.c
 
 grub_emu_LDFLAGS = $(LIBCURSES) 
 
Index: conf/powerpc-ieee1275.rmk
===================================================================
--- conf/powerpc-ieee1275.rmk   (revision 2017)
+++ conf/powerpc-ieee1275.rmk   (working copy)
@@ -70,6 +70,7 @@
        \
        disk/raid.c disk/raid5_recover.c disk/raid6_recover.c           \
        disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
+       commands/parttool.c parttool/pcpart.c                           \
        grub_script.tab.c grub_emu_init.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
Index: conf/sparc64-ieee1275.rmk
===================================================================
--- conf/sparc64-ieee1275.rmk   (revision 2017)
+++ conf/sparc64-ieee1275.rmk   (working copy)
@@ -66,6 +67,7 @@
 #      partmap/acorn.c                                                 \
 #      util/console.c util/grub-emu.c util/misc.c                      \
 #      util/hostdisk.c util/getroot.c                                  \
+#      commands/parttool.c parttool/pcpart.c                           \
 #      util/sparc64/ieee1275/misc.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
Index: conf/x86_64-efi.rmk
===================================================================
--- conf/x86_64-efi.rmk (revision 2017)
+++ conf/x86_64-efi.rmk (working copy)
@@ -67,6 +68,7 @@
        \
        disk/raid.c disk/raid5_recover.c disk/raid6_recover.c           \
        disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
+       commands/parttool.c parttool/pcpart.c                           \
        grub_emu_init.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
Index: commands/parttool.c
===================================================================
--- commands/parttool.c (revision 0)
+++ commands/parttool.c (revision 0)
@@ -0,0 +1,248 @@
+/* parttool.c - common dispatcher and parser for partition operations */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  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/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+
+struct grub_parttool *parts = 0;
+static int curhandle = 0;
+static grub_dl_t mymod;
+
+int 
+grub_parttool_register(const char *part_name, 
+                      const grub_parttool_function_t func,
+                      const struct grub_parttool_argdesc *args)
+{
+  struct grub_parttool *cur;
+  int nargs = 0;
+  struct grub_parttool_argdesc *curarg;
+
+#ifndef GRUB_UTIL
+  if (!parts)
+    grub_dl_ref (mymod);
+#endif
+
+  cur = (struct grub_parttool *) grub_malloc (sizeof (struct grub_parttool));
+  cur->next = parts;
+  cur->name = grub_strdup (part_name);
+  cur->handle = curhandle++;
+  for (curarg = args; curarg->name != 0; curarg++)
+    nargs++;
+  cur->nargs = nargs;
+  cur->args = (struct grub_parttool_argdesc *) 
+    grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
+  grub_memcpy (cur->args, args, 
+              (nargs + 1) * sizeof (struct grub_parttool_argdesc));
+  
+  cur->func = func;
+  parts = cur;
+  return cur->handle;
+}
+
+void
+grub_parttool_unregister (int handle)
+{
+  struct grub_parttool *prev = 0, *cur;
+  for (cur = parts; cur; prev=cur, cur = cur->next)
+    if (cur->handle == handle)
+      {
+       grub_free (cur->args);
+       grub_free (cur->name);
+       if (prev)
+         prev->next = cur->next;
+       else
+         parts = cur->next;
+       grub_free (cur);
+      }
+#ifndef GRUB_UTIL
+  if (!parts)
+    grub_dl_unref (mymod);
+#endif
+}
+
+static grub_err_t
+grub_cmd_parttool (struct grub_arg_list *state __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  grub_device_t dev;
+  struct grub_parttool *cur, *ptool;
+  int *parsed;
+  int i, j;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  if (argc < 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
+
+  dev = grub_device_open (args[0]); 
+
+  if (!dev)
+    return grub_errno;
+
+  if (!dev->disk)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
+    }
+
+  if (!dev->disk->partition)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a partition");
+    }
+
+  parsed = (int *)grub_malloc (argc * sizeof (int));
+  grub_memset (parsed, 0, argc * sizeof (int));
+
+  for (i = 1; i < argc; i++)
+    if (!grub_strcmp (args[i], "help"))
+      {
+       int found = 0;
+       for (cur = parts; cur; cur = cur->next)
+         if (!grub_strcmp (dev->disk->partition->partmap->name, cur->name))
+           {
+             struct grub_parttool_argdesc *curarg;
+             found = 1;
+             for (curarg = cur->args; curarg->name; curarg++)
+               {
+                 int spacing = 20;
+               
+                 spacing -= grub_strlen (curarg->name);
+                 grub_printf ("%s", curarg->name);
+
+                 switch (curarg->type)
+                   {
+                   case GRUB_PARTTOOL_ARG_BOOL:
+                     grub_printf ("+/-");
+                     spacing-=3;
+                     break;
+
+                   case GRUB_PARTTOOL_ARG_VAL:               
+                     grub_printf ("=VAL");
+                     spacing-=4;
+                     break;
+
+                   case GRUB_PARTTOOL_ARG_END:
+                     break;
+                   }
+                 while (spacing-- > 0)
+                   grub_printf (" ");
+                 grub_printf ("%s\n", curarg->desc);
+               }
+           }
+       if (!found)
+         grub_printf ("Sorry no parttool is available for %s\n", 
+                      dev->disk->partition->partmap->name);
+       return GRUB_ERR_NONE;
+      }
+
+  for (i = 1; i < argc; i++)
+    if (!parsed[i])
+      {
+       struct grub_parttool_argdesc *curarg;
+       struct grub_parttool_args *pargs;
+       for (cur = parts; cur; cur = cur->next)
+         if (!grub_strcmp (dev->disk->partition->partmap->name, cur->name))
+           {
+             for (curarg = cur->args; curarg->name; curarg++)
+               if (!grub_strncmp (curarg->name, args[i], 
+                                  grub_strlen (curarg->name))
+                   && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL 
+                        && (args[i][grub_strlen (curarg->name)] == '+' 
+                            || args[i][grub_strlen (curarg->name)] == '-'))
+                       || (curarg->type==GRUB_PARTTOOL_ARG_VAL
+                           && args[i][grub_strlen (curarg->name)] == '=')))
+                   
+                 break;
+             if (curarg)
+               break;
+           }
+       if (!cur)
+         return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s",
+                            args[i]);
+       ptool = cur;
+       pargs = (struct grub_parttool_args *) 
+         grub_malloc (ptool->nargs * sizeof (struct grub_parttool_args));
+       grub_memset (pargs, 0, 
+                    ptool->nargs * sizeof (struct grub_parttool_args));
+       for (j = i; j < argc; j++)
+         if (!parsed[j])
+           {
+             for (curarg = ptool->args; curarg->name; curarg++)
+               if (!grub_strncmp (curarg->name, args[i], 
+                                  grub_strlen (curarg->name))
+                   && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL 
+                        && (args[j][grub_strlen (curarg->name)] == '+' 
+                            || args[j][grub_strlen (curarg->name)] == '-'))
+                       || (curarg->type == GRUB_PARTTOOL_ARG_VAL
+                           && args[j][grub_strlen (curarg->name)] == '=')))
+                 {
+                   parsed[j] = 1;
+                   pargs[curarg - ptool->args].set = 1;
+                   switch (curarg->type)
+                     {
+                     case GRUB_PARTTOOL_ARG_BOOL:
+                       pargs[curarg - ptool->args].bool 
+                         = (args[j][grub_strlen (curarg->name)] != '-');
+                       break;
+
+                     case GRUB_PARTTOOL_ARG_VAL:
+                       pargs[curarg - ptool->args].str 
+                         = (args[j]+grub_strlen (curarg->name)+ 1);
+                       break;
+                       
+                     case GRUB_PARTTOOL_ARG_END:
+                       break;
+                     }
+                 }
+           }
+
+       err = ptool->func (dev, pargs);
+       grub_free (pargs);
+       if (err)
+         break;
+      }
+
+  grub_device_close (dev);
+  return err;
+}
+
+GRUB_MOD_INIT(parttool)
+{
+  (void)mod;                   /* To stop warning. */
+  mymod = mod;
+  grub_register_command ("parttool", grub_cmd_parttool, GRUB_COMMAND_FLAG_BOTH,
+                        "parttool PARTITION COMMANDS", 
+                        "perform COMMANDS on partition."
+                        " use parttool PARTITION help for the list "
+                        " of available commands", 0);
+}
+
+GRUB_MOD_FINI(parttool)
+{
+  grub_unregister_command ("parttool");
+}
Index: parttool/pcpart.c
===================================================================
--- parttool/pcpart.c   (revision 0)
+++ parttool/pcpart.c   (revision 0)
@@ -0,0 +1,152 @@
+/* pcpart.c - manipulate fdisk partitions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  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/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/pc_partition.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+
+static int activate_table_handle = -1;
+static int type_table_handle = -1;
+
+static struct grub_parttool_argdesc grub_pcpart_bootargs[] =
+{
+  {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL},
+  {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_boot (const grub_device_t dev, 
+                                   const struct grub_parttool_args *args)
+{
+  int i, index;
+  grub_partition_t part;
+  struct grub_pc_partition_mbr mbr;
+
+  if (dev->disk->partition->offset)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition");
+
+  index = dev->disk->partition->index;
+  part = dev->disk->partition;
+  dev->disk->partition = 0;
+
+  /* Read the MBR.  */
+  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), (char *) &mbr))
+    {
+      dev->disk->partition = part;
+      return grub_errno;
+    }
+
+  if (args[0].set && args[0].bool)
+    {
+      for (i = 0; i < 4; i++)
+       mbr.entries[i].flag = 0x0;
+      mbr.entries[index].flag = 0x80;
+    }
+  else
+    mbr.entries[index].flag = 0x0;
+
+   /* Write the MBR.  */
+  grub_disk_write (dev->disk, 0, 0, sizeof (mbr), (char *) &mbr);
+
+  dev->disk->partition = part;
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_parttool_argdesc grub_pcpart_typeargs[] =
+{
+  {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL},
+  {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL},
+  {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_type (const grub_device_t dev, 
+                                   const struct grub_parttool_args *args)
+{
+  int index;
+  grub_uint8_t type;
+  grub_partition_t part;
+  struct grub_pc_partition_mbr mbr;
+
+  index = dev->disk->partition->index;
+  part = dev->disk->partition;
+  dev->disk->partition = 0;
+
+  /* Read the parttable.  */
+  if (grub_disk_read (dev->disk, part->offset, 0, 
+                     sizeof (mbr), (char *) &mbr))
+    {
+      dev->disk->partition = part;
+      return grub_errno;
+    }
+
+  if (args[0].set)
+    type = grub_strtoul (args[0].str, 0, 0);
+  else
+    type = mbr.entries[index].type;
+
+  if (args[1].set)
+    {
+      if (args[1].bool)
+       type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+      else
+       type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+    }
+
+  if (grub_pc_partition_is_empty (type) 
+      || grub_pc_partition_is_extended (type))
+    {
+      dev->disk->partition = part;
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid type");
+    }
+
+  mbr.entries[index].type = type;
+
+   /* Write the parttable.  */
+  grub_disk_write (dev->disk, part->offset, 0, 
+                  sizeof (mbr), (char *) &mbr);
+
+  dev->disk->partition = part;
+
+  return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT (pcpart)
+{
+  (void)mod;                   /* To stop warning. */
+
+  activate_table_handle = grub_parttool_register("pc_partition_map", 
+                                                grub_pcpart_boot,
+                                                grub_pcpart_bootargs);
+  type_table_handle = grub_parttool_register("pc_partition_map", 
+                                            grub_pcpart_type,
+                                            grub_pcpart_typeargs);
+ 
+}
+GRUB_MOD_FINI(pcpart)
+{
+  grub_parttool_unregister (activate_table_handle);
+  grub_parttool_unregister (type_table_handle);
+}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]