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 }
|