Print this page
grub patch


 167             }
 168 
 169           /* TRANSLATORS: it's the element carying the number %d, not
 170              total element number. This is used in enumeration
 171              "Element number 1", "Element number 2", ... */
 172           grub_printf_ (N_("Mirror element number %d:\n"), i);
 173           print_vdev_info (child, tab + 1);
 174 
 175           grub_free (child);
 176         }
 177       return GRUB_ERR_NONE;
 178     }
 179 
 180   print_tabs (tab);
 181   grub_printf_ (N_("Unknown virtual device type: %s\n"), type);
 182 
 183   return GRUB_ERR_NONE;
 184 }
 185 
 186 static grub_err_t
 187 get_bootpath (char *nvlist, char **bootpath, char **devid)
 188 {
 189   char *type = 0;

 190 
 191   type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE);
 192 
 193   if (!type)
 194     return grub_errno;
 195 
 196   if (grub_strcmp (type, VDEV_TYPE_DISK) == 0)
 197     {

 198       *bootpath = grub_zfs_nvlist_lookup_string (nvlist,
 199                                                  ZPOOL_CONFIG_PHYS_PATH);
 200       *devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID);
 201       if (!*bootpath || !*devid)
 202         {
 203           grub_free (*bootpath);
 204           grub_free (*devid);
 205           *bootpath = 0;
 206           *devid = 0;
 207         }
 208       return GRUB_ERR_NONE;
 209     }
 210 
 211   if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0)
 212     {
 213       int nelm, i;
 214 
 215       nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm
 216         (nvlist, ZPOOL_CONFIG_CHILDREN);
 217 
 218       for (i = 0; i < nelm; i++)
 219         {
 220           char *child;
 221 
 222           child = grub_zfs_nvlist_lookup_nvlist_array (nvlist,
 223                                                        ZPOOL_CONFIG_CHILDREN,
 224                                                        i);
 225 
 226           get_bootpath (child, bootpath, devid);
 227 
 228           grub_free (child);
 229 
 230           if (*bootpath && *devid)
 231             return GRUB_ERR_NONE;
 232         }
 233     }
 234 
 235   return GRUB_ERR_NONE;
 236 }
 237 
 238 static const char *poolstates[] = {
 239   /* TRANSLATORS: Here we speak about ZFS pools it's semi-marketing,
 240      semi-technical term by Sun/Oracle and should be translated in sync with
 241      other ZFS-related software and documentation.  */
 242   [POOL_STATE_ACTIVE] = N_("Pool state: active"),
 243   [POOL_STATE_EXPORTED] = N_("Pool state: exported"),
 244   [POOL_STATE_DESTROYED] = N_("Pool state: destroyed"),
 245   [POOL_STATE_SPARE] = N_("Pool state: reserved for hot spare"),
 246   [POOL_STATE_L2CACHE] = N_("Pool state: level 2 ARC device"),


 323 
 324   grub_free (nv);
 325   grub_free (nvlist);
 326 
 327   return GRUB_ERR_NONE;
 328 }
 329 
 330 static grub_err_t
 331 grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc,
 332                      char **args)
 333 {
 334   grub_device_t dev;
 335   char *devname;
 336   grub_err_t err;
 337   char *nvlist = 0;
 338   char *nv = 0;
 339   char *bootpath = 0, *devid = 0;
 340   char *fsname;
 341   char *bootfs;
 342   char *poolname;
 343   grub_uint64_t mdnobj;



 344 
 345   if (argc < 1)
 346     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
 347 
 348   devname = grub_file_get_device_name (args[0]);

 349   if (grub_errno)
 350     return grub_errno;
 351 
 352   dev = grub_device_open (devname);
 353   grub_free (devname);
 354   if (!dev)
 355     return grub_errno;
 356 
 357   err = grub_zfs_fetch_nvlist (dev, &nvlist);
 358 
 359   fsname = grub_strchr (args[0], ')');
 360   if (fsname)
 361     fsname++;
 362   else
 363     fsname = args[0];
 364 
 365   if (!err)



 366     err = grub_zfs_getmdnobj (dev, fsname, &mdnobj);



 367 
 368   grub_device_close (dev);
 369 
 370   if (err)
 371     return err;
 372 
 373   poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME);
 374   if (!poolname)
 375     {
 376       if (!grub_errno)
 377         grub_error (GRUB_ERR_BAD_FS, "No poolname found");
 378       return grub_errno;
 379     }
 380 
 381   nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE);

 382 
 383   if (nv)
 384     get_bootpath (nv, &bootpath, &devid);
 385 
 386   grub_free (nv);
 387   grub_free (nvlist);
 388 
 389   bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s%s%s",
 390                            poolname, (unsigned long long) mdnobj,
 391                            bootpath ? ",bootpath=\"" : "",
 392                            bootpath ? : "",
 393                            bootpath ? "\"" : "",
 394                            devid ? ",diskdevid=\"" : "",
 395                            devid ? : "",
 396                            devid ? "\"" : "");
 397   if (!bootfs)
 398     return grub_errno;
 399   if (argc >= 2)
 400     grub_env_set (args[1], bootfs);
 401   else
 402     grub_printf ("%s\n", bootfs);
 403 





 404   grub_free (bootfs);
 405   grub_free (poolname);
 406   grub_free (bootpath);
 407   grub_free (devid);
 408 
 409   return GRUB_ERR_NONE;
 410 }
 411 
 412 
 413 static grub_command_t cmd_info, cmd_bootfs;
 414 
 415 GRUB_MOD_INIT (zfsinfo)
 416 {
 417   cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo,
 418                                     N_("DEVICE"),
 419                                     N_("Print ZFS info about DEVICE."));
 420   cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs,
 421                                       N_("FILESYSTEM [VARIABLE]"),
 422                                       N_("Print ZFS-BOOTFSOBJ or store it into VARIABLE"));
 423 }


 167             }
 168 
 169           /* TRANSLATORS: it's the element carying the number %d, not
 170              total element number. This is used in enumeration
 171              "Element number 1", "Element number 2", ... */
 172           grub_printf_ (N_("Mirror element number %d:\n"), i);
 173           print_vdev_info (child, tab + 1);
 174 
 175           grub_free (child);
 176         }
 177       return GRUB_ERR_NONE;
 178     }
 179 
 180   print_tabs (tab);
 181   grub_printf_ (N_("Unknown virtual device type: %s\n"), type);
 182 
 183   return GRUB_ERR_NONE;
 184 }
 185 
 186 static grub_err_t
 187 get_bootpath (char *nvlist, char **bootpath, char **devid, grub_uint64_t inguid)
 188 {
 189   char *type = 0;
 190   grub_uint64_t diskguid = 0;
 191 
 192   type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE);
 193 
 194   if (!type)
 195     return grub_errno;
 196 
 197   if (grub_strcmp (type, VDEV_TYPE_DISK) == 0)
 198     {
 199       grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &diskguid);
 200       *bootpath = grub_zfs_nvlist_lookup_string (nvlist,
 201                                                  ZPOOL_CONFIG_PHYS_PATH);
 202       *devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID);
 203       if (!*bootpath || !*devid || (diskguid != inguid))
 204         {
 205           grub_free (*bootpath);
 206           grub_free (*devid);
 207           *bootpath = 0;
 208           *devid = 0;
 209         }
 210       return GRUB_ERR_NONE;
 211     }
 212 
 213   if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0)
 214     {
 215       int nelm, i;
 216 
 217       nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm
 218         (nvlist, ZPOOL_CONFIG_CHILDREN);
 219 
 220       for (i = 0; i < nelm; i++)
 221         {
 222           char *child;
 223 
 224           child = grub_zfs_nvlist_lookup_nvlist_array (nvlist,
 225                                                        ZPOOL_CONFIG_CHILDREN,
 226                                                        i);
 227 
 228           get_bootpath (child, bootpath, devid, inguid);
 229 
 230           grub_free (child);
 231 
 232           if (*bootpath && *devid)
 233             return GRUB_ERR_NONE;
 234         }
 235     }
 236 
 237   return GRUB_ERR_NONE;
 238 }
 239 
 240 static const char *poolstates[] = {
 241   /* TRANSLATORS: Here we speak about ZFS pools it's semi-marketing,
 242      semi-technical term by Sun/Oracle and should be translated in sync with
 243      other ZFS-related software and documentation.  */
 244   [POOL_STATE_ACTIVE] = N_("Pool state: active"),
 245   [POOL_STATE_EXPORTED] = N_("Pool state: exported"),
 246   [POOL_STATE_DESTROYED] = N_("Pool state: destroyed"),
 247   [POOL_STATE_SPARE] = N_("Pool state: reserved for hot spare"),
 248   [POOL_STATE_L2CACHE] = N_("Pool state: level 2 ARC device"),


 325 
 326   grub_free (nv);
 327   grub_free (nvlist);
 328 
 329   return GRUB_ERR_NONE;
 330 }
 331 
 332 static grub_err_t
 333 grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc,
 334                      char **args)
 335 {
 336   grub_device_t dev;
 337   char *devname;
 338   grub_err_t err;
 339   char *nvlist = 0;
 340   char *nv = 0;
 341   char *bootpath = 0, *devid = 0;
 342   char *fsname;
 343   char *bootfs;
 344   char *poolname;
 345   char def_path[512];
 346   struct grub_zfs_data * data;
 347   grub_uint64_t mdnobj, guid;
 348   int def = 0;
 349 
 350   if (argc <  1) 
 351     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
 352 
 353   devname = grub_file_get_device_name (args[0]);
 354 
 355   if (grub_errno)
 356     return grub_errno;
 357 
 358   dev = grub_device_open (devname);
 359   grub_free (devname);
 360   if (!dev)
 361     return grub_errno;
 362 
 363   err = grub_zfs_fetch_nvlist (dev, &nvlist);
 364 
 365   fsname = grub_strchr (args[0], ')');
 366   if (fsname)
 367     fsname++;
 368   else
 369     fsname = args[0];
 370 
 371   if (grub_strcmp(fsname, "default") == 0)
 372     ++def;
 373 
 374   if (! def) {
 375     err = grub_zfs_getmdnobj (dev, fsname, &mdnobj);
 376   } else {
 377     err = get_default_bootfs_obj(dev, def_path, &mdnobj);
 378   }
 379 
 380   grub_device_close (dev);
 381 
 382   if (err)
 383     return err;
 384 
 385   poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME);
 386   if (!poolname)
 387     {
 388       if (!grub_errno)
 389         grub_error (GRUB_ERR_BAD_FS, "No poolname found");
 390       return grub_errno;
 391     }
 392 
 393   nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE);
 394   grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &guid);
 395 
 396   if (nv && guid)
 397     get_bootpath (nv, &bootpath, &devid, guid);
 398 
 399   grub_free (nv);
 400   grub_free (nvlist);
 401 
 402   bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s%s%s",
 403                            poolname, (unsigned long long) mdnobj,
 404                            bootpath ? ",bootpath=\"" : "",
 405                            bootpath ? : "",
 406                            bootpath ? "\"" : "",
 407                            devid ? ",diskdevid=\"" : "",
 408                            devid ? : "",
 409                            devid ? "\"" : "");
 410   if (!bootfs)
 411     return grub_errno;
 412   if (argc >= 2)
 413     grub_env_set (args[1], bootfs);
 414   else
 415     grub_printf ("%s\n", bootfs);
 416 
 417   if ((def) && (argc >= 3))
 418     grub_env_set(args[2], def_path);
 419   else if (def)
 420     grub_printf("%s\n", def_path);
 421 
 422   grub_free (bootfs);
 423   grub_free (poolname);
 424   grub_free (bootpath);
 425   grub_free (devid);
 426 
 427   return GRUB_ERR_NONE;
 428 }
 429 
 430 
 431 static grub_command_t cmd_info, cmd_bootfs;
 432 
 433 GRUB_MOD_INIT (zfsinfo)
 434 {
 435   cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo,
 436                                     N_("DEVICE"),
 437                                     N_("Print ZFS info about DEVICE."));
 438   cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs,
 439                                       N_("FILESYSTEM [VARIABLE]"),
 440                                       N_("Print ZFS-BOOTFSOBJ or store it into VARIABLE"));
 441 }