summaryrefslogtreecommitdiffstats
path: root/zfs/lib/libzpool/spa_boot.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2008-12-03 12:09:06 -0800
committerBrian Behlendorf <[email protected]>2008-12-03 12:09:06 -0800
commitb128c09fbee863d15be744a2ce602b514eddbe3a (patch)
treee7b220dec77fb17703f5b45f164370e30f52e7c2 /zfs/lib/libzpool/spa_boot.c
parentb6097ae55adc8edb7149c4d433fa45a6ea3c45e7 (diff)
Rebase to OpenSolaris b103, in the process we are removing any code which did not originate from the OpenSolaris source. These changes will be reintroduced in topic branches for easier tracking
Diffstat (limited to 'zfs/lib/libzpool/spa_boot.c')
-rw-r--r--zfs/lib/libzpool/spa_boot.c165
1 files changed, 7 insertions, 158 deletions
diff --git a/zfs/lib/libzpool/spa_boot.c b/zfs/lib/libzpool/spa_boot.c
index 1107b0298..49e9e5019 100644
--- a/zfs/lib/libzpool/spa_boot.c
+++ b/zfs/lib/libzpool/spa_boot.c
@@ -24,175 +24,24 @@
* Use is subject to license terms.
*/
-#pragma ident "@(#)spa_boot.c 1.1 08/04/09 SMI"
+#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/spa.h>
#include <sys/sunddi.h>
char *
-spa_get_bootfs()
+spa_get_bootprop(char *propname)
{
- char *zfs_bp;
+ char *value;
if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
- DDI_PROP_DONTPASS, "zfs-bootfs", &zfs_bp) !=
- DDI_SUCCESS)
+ DDI_PROP_DONTPASS, propname, &value) != DDI_SUCCESS)
return (NULL);
- return (zfs_bp);
+ return (value);
}
void
-spa_free_bootfs(char *bootfs)
+spa_free_bootprop(char *value)
{
- ddi_prop_free(bootfs);
-}
-
-/*
- * Calculate how many device pathnames are in devpath_list.
- * The devpath_list could look like this:
- *
- * "/pci@1f,0/ide@d/disk@0,0:a /pci@1f,o/ide@d/disk@2,0:a"
- */
-static int
-spa_count_devpath(char *devpath_list)
-{
- int numpath;
- char *tmp_path, *blank;
-
- numpath = 0;
- tmp_path = devpath_list;
-
- /* skip leading blanks */
- while (*tmp_path == ' ')
- tmp_path++;
-
- while ((blank = strchr(tmp_path, ' ')) != NULL) {
-
- numpath++;
- /* skip contiguous blanks */
- while (*blank == ' ')
- blank++;
- tmp_path = blank;
- }
-
- if (strlen(tmp_path) > 0)
- numpath++;
-
- return (numpath);
-}
-
-/*
- * Only allow booting the device if it has the same vdev information as
- * the most recently updated vdev (highest txg) and is in a valid state.
- *
- * GRUB passes online/active device path names, e.g.
- * "/pci@1f,0/ide@d/disk@0,0:a /pci@1f,o/ide@d/disk@2,0:a"
- * to the kernel. The best vdev should have the same matching online/active
- * list as what GRUB passes in.
- */
-static int
-spa_check_devstate(char *devpath_list, char *dev, nvlist_t *conf)
-{
- nvlist_t *nvtop, **child;
- uint_t label_path, grub_path, c, children;
- char *type;
-
- VERIFY(nvlist_lookup_nvlist(conf, ZPOOL_CONFIG_VDEV_TREE,
- &nvtop) == 0);
- VERIFY(nvlist_lookup_string(nvtop, ZPOOL_CONFIG_TYPE, &type) == 0);
-
- if (strcmp(type, VDEV_TYPE_DISK) == 0)
- return (spa_rootdev_validate(nvtop)? 0 : EINVAL);
-
- ASSERT(strcmp(type, VDEV_TYPE_MIRROR) == 0);
-
- VERIFY(nvlist_lookup_nvlist_array(nvtop, ZPOOL_CONFIG_CHILDREN,
- &child, &children) == 0);
-
- /*
- * Check if the devpath_list is the same as the path list in conf.
- * If these two lists are different, then the booting device is not an
- * up-to-date device that can be booted.
- */
- label_path = 0;
- for (c = 0; c < children; c++) {
- char *physpath;
-
- if (nvlist_lookup_string(child[c], ZPOOL_CONFIG_PHYS_PATH,
- &physpath) != 0)
- return (EINVAL);
-
- if (spa_rootdev_validate(child[c])) {
- if (strstr(devpath_list, physpath) == NULL)
- return (EINVAL);
- label_path++;
- } else {
- char *blank;
-
- if (blank = strchr(dev, ' '))
- *blank = '\0';
- if (strcmp(physpath, dev) == 0)
- return (EINVAL);
- if (blank)
- *blank = ' ';
- }
- }
-
- grub_path = spa_count_devpath(devpath_list);
-
- if (label_path != grub_path)
- return (EINVAL);
-
- return (0);
-}
-
-/*
- * Given a list of vdev physpath names, pick the vdev with the most recent txg,
- * and return the point of the device's physpath in the list and the device's
- * label configuration. The content of the label would be the most recent
- * updated information.
- */
-int
-spa_get_rootconf(char *devpath_list, char **bestdev, nvlist_t **bestconf)
-{
- nvlist_t *conf = NULL;
- char *dev = NULL;
- uint64_t txg = 0;
- char *devpath, *blank;
-
- devpath = devpath_list;
- dev = devpath;
-
- while (devpath[0] == ' ')
- devpath++;
-
- while ((blank = strchr(devpath, ' ')) != NULL) {
- *blank = '\0';
- spa_check_rootconf(devpath, &dev, &conf, &txg);
- *blank = ' ';
-
- while (*blank == ' ')
- blank++;
- devpath = blank;
- }
-
- /* for the only or the last devpath in the devpath_list */
- if (strlen(devpath) > 0)
- spa_check_rootconf(devpath, &dev, &conf, &txg);
-
- if (conf == NULL)
- return (EINVAL);
-
- /*
- * dev/conf is the vdev with the most recent txg.
- * Check if the device is in a bootable state.
- * dev may have a trailing blank since it points to a string
- * in the devpath_list.
- */
- if (spa_check_devstate(devpath_list, dev, conf) != 0)
- return (EINVAL);
-
- *bestdev = dev;
- *bestconf = conf;
- return (0);
+ ddi_prop_free(value);
}