]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Attempts at ZFS options
authorVladimir Serbinenko <phcoder@gmail.com>
Sun, 3 Nov 2013 15:40:32 +0000 (16:40 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sun, 3 Nov 2013 15:40:32 +0000 (16:40 +0100)
grub-core/fs/zfs/zfs.c
grub-core/fs/zfs/zfsinfo.c
include/grub/zfs/zfs.h
util/grub-fstest.c

index d0a4d9cc71e8c53659f7f2c163d58c90ec3689ee..9bfaebb4ceb9734a2853f90ea92402986fb88106 100644 (file)
@@ -2604,7 +2604,8 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
       grub_memmove (&(buf->dn), &(data->dnode_buf)[idx], DNODE_SIZE);
       buf->endian = data->dnode_endian;
       if (type && buf->dn.dn_type != type) 
-       return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); 
+       return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type: %x, %x",
+                         buf->dn.dn_type, type); 
       return GRUB_ERR_NONE;
     }
 
@@ -2635,7 +2636,8 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
   grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE);
   buf->endian = endian;
   if (type && buf->dn.dn_type != type) 
-    return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); 
+    return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type: %x, %x",
+                     buf->dn.dn_type, type); 
 
   return GRUB_ERR_NONE;
 }
@@ -3771,6 +3773,66 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
   return GRUB_ERR_NONE;
 }
 
+#if 1
+
+static int print_hook (const void *name,
+                      grub_size_t namelen __attribute__ ((unused)),
+                      const void *val_in __attribute__ ((unused)),
+                      grub_size_t nelem __attribute__ ((unused)),
+                      grub_size_t elemsize __attribute__ ((unused)),
+                      void *data __attribute__ ((unused)))
+{
+  grub_printf ("<%s %u %u, %s>\n", (char *)name,
+              (unsigned) elemsize, (unsigned) nelem,
+              (char *) val_in);
+  return 0;
+}
+
+#endif
+
+grub_err_t
+grub_zfs_get_property (grub_device_t dev,
+                      const char *fsfilename, const char *propname,
+                      grub_uint64_t *property)
+{
+  struct grub_zfs_data *data;
+  grub_err_t err;
+  int isfs;
+  dnode_end_t props_dn;
+  grub_uint64_t propsobj;
+
+  data = zfs_mount (dev);
+  if (! data)
+    return grub_errno;
+
+  err = dnode_get_fullpath (fsfilename, &(data->subvol),
+                           &(data->dnode), &isfs, data);
+
+  propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_props_zapobj, data->dnode.endian);
+
+  if (!err)
+    err = dnode_get (&(data->mos), propsobj, DMU_OT_DSL_PROPS,
+                    &props_dn, data);
+
+#if 0
+  if (!err)
+    err = zap_lookup (&props_dn, propname,
+                     property, data, 0);
+#else
+  (void) propname;
+  (void) property;
+#endif
+
+  zap_iterate (&props_dn, 1,
+              print_hook,
+              NULL, data);
+
+  zfs_unmount (data);
+
+  return err;
+}
+
+
 static grub_ssize_t
 grub_zfs_read (grub_file_t file, char *buf, grub_size_t len)
 {
index c96bf2183c09e0df909537513b7cb22b7030bc1f..f8b915ebff9fd35a9857851c32424f1447e1e8ab 100644 (file)
@@ -419,14 +419,72 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc,
   return GRUB_ERR_NONE;
 }
 
+static grub_err_t
+grub_cmd_zfs_property (grub_command_t cmd __attribute__ ((unused)), int argc,
+                      char **args)
+{
+  grub_device_t device = 0;
+  char *device_name;
+  const char *file_name;
+  char *fs_name = NULL;
+  const char *name, *ptr;
+  grub_uint64_t property;
+  grub_err_t err;
+
+  if (argc < 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
+
+  name = args[0];
+  device_name = grub_file_get_device_name (name);
+  if (grub_errno)
+    return grub_errno;
+
+  /* Get the file part of NAME.  */  
+  file_name = (name[0] == '(') ? grub_strchr (name, ')') : NULL;
+  if (file_name)
+    file_name++;
+  else
+    file_name = name;
+
+  device = grub_device_open (device_name);
+  grub_free (device_name);
+  if (! device)
+    return grub_errno;
+
+  ptr = grub_strchr (file_name, '@');
+  if (ptr)
+    {
+      fs_name = grub_strndup (file_name, ptr - file_name);
+      if (!fs_name)
+       {
+         grub_device_close (device);
+         return grub_errno;
+       }
+    }
+
+  err = grub_zfs_get_property (device, fs_name ? : file_name, args[1],
+                              &property);
+  grub_free (fs_name);
+  grub_device_close (device);
+  if (err)
+    return err;
+
+  grub_printf ("0x%llx\n", (unsigned long long) property);
+
+  return GRUB_ERR_NONE;
+}
+
 
-static grub_command_t cmd_info, cmd_bootfs;
+static grub_command_t cmd_info, cmd_bootfs, cmd_property;
 
 GRUB_MOD_INIT (zfsinfo)
 {
   cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo,
                                    N_("DEVICE"),
                                    N_("Print ZFS info about DEVICE."));
+  cmd_property = grub_register_command ("zfsproperty", grub_cmd_zfs_property,
+                                       N_("SUBVOLUME PROPNAME"),
+                                       N_("Print ZFS property value."));
   cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs,
                                      N_("FILESYSTEM [VARIABLE]"),
                                      N_("Print ZFS-BOOTFSOBJ or store it into VARIABLE"));
@@ -436,4 +494,5 @@ GRUB_MOD_FINI (zfsinfo)
 {
   grub_unregister_command (cmd_info);
   grub_unregister_command (cmd_bootfs);
+  grub_unregister_command (cmd_property);
 }
index 4ee513887ed6a329cd94124881b81486184434de..e059db690739e249e7f12e4d3f19f33a66a31ddc 100644 (file)
@@ -153,6 +153,10 @@ extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_k
                                                         grub_uint64_t salt,
                                                         grub_uint64_t algo);
 
+grub_err_t
+grub_zfs_get_property (grub_device_t dev,
+                      const char *fsfilename, const char *propname,
+                      grub_uint64_t *property);
 
 
 #endif /* ! GRUB_ZFS_HEADER */
index 802733963a73000c7983b1de79315957a972ea1a..cd39e6edd00b7d07ca1a85ace0771d0a3f1bbb21 100644 (file)
@@ -417,9 +417,11 @@ fstest (int n)
     {
     case CMD_LS:
       execute_command ("ls", n, args);
+      grub_print_error ();
       break;
     case CMD_ZFSINFO:
-      execute_command ("zfsinfo", n, args);
+      execute_command ("zfsproperty", n, args);
+      grub_print_error ();
       break;
     case CMD_CP:
       cmd_cp (args[0], args[1]);