Print this page
NEX-2846 Enable Automatic/Intelligent Hot Sparing capability
Reviewed by: Jeffry Molanus <jeffry.molanus@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
*** 19,28 ****
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/fm/protocol.h>
#include <fm/topo_hc.h>
*** 756,765 ****
--- 757,839 ----
"topo handle: %p\n", (void *)thp);
fmd_module_unlock(mp);
}
+ /*
+ * Visit a libtopo node trying to find a disk with the specified devid.
+ * If we find it, copy it's FRU and resource fields.
+ */
+ static int
+ fmd_hdl_topo_walk_cb(topo_hdl_t *thp, tnode_t *tn, void *arg)
+ {
+
+ fmd_hdl_topo_node_info_t *node = (fmd_hdl_topo_node_info_t *)arg;
+ char *cur_devid;
+ nvlist_t *fru;
+ nvlist_t *resource;
+ int err = 0;
+ _NOTE(ARGUNUSED(thp));
+
+ if (strcmp(topo_node_name(tn), "disk") != 0)
+ return (TOPO_WALK_NEXT);
+
+ if (topo_prop_get_string(tn, "io", "devid", &cur_devid, &err) != 0)
+ return (TOPO_WALK_NEXT);
+
+ if (strcmp(cur_devid, node->device) == 0) {
+ if (topo_node_fru(tn, &fru, NULL, &err) == 0 && err == 0 &&
+ topo_node_resource(tn, &resource, &err) == 0 && err == 0) {
+ node->fru = fnvlist_dup(fru);
+ node->resource = fnvlist_dup(resource);
+ return (TOPO_WALK_TERMINATE);
+ }
+ }
+
+ return (TOPO_WALK_NEXT);
+ }
+
+ /*
+ * Extract FRU and resource values from a libtopo node with the matching devid
+ */
+ fmd_hdl_topo_node_info_t *
+ fmd_hdl_topo_node_get_by_devid(fmd_hdl_t *hdl, char *device)
+ {
+
+ int err = 0;
+ topo_hdl_t *thp;
+ topo_walk_t *twp;
+
+ fmd_hdl_topo_node_info_t *node = (fmd_hdl_topo_node_info_t *)
+ fmd_hdl_zalloc(hdl, sizeof (fmd_hdl_topo_node_info_t), FMD_SLEEP);
+
+ thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION);
+
+ node->device = device;
+
+ if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, fmd_hdl_topo_walk_cb,
+ node, &err)) == NULL) {
+ fmd_hdl_error(hdl, "failed to get topology: %s",
+ topo_strerror(err));
+ fmd_hdl_topo_rele(hdl, thp);
+ return (NULL);
+ }
+
+ (void) topo_walk_step(twp, TOPO_WALK_CHILD);
+ topo_walk_fini(twp);
+ fmd_hdl_topo_rele(hdl, thp);
+
+ if (node->fru == NULL || node->resource == NULL) {
+ fmd_hdl_debug(hdl, "Could not find device with matching FRU");
+ fmd_hdl_free(hdl, node, sizeof (fmd_hdl_topo_node_info_t));
+ return (NULL);
+ } else {
+ fmd_hdl_debug(hdl, "Found FRU for device %s", device);
+ return (node);
+ }
+ }
+
static void *
fmd_hdl_alloc_locked(fmd_module_t *mp, size_t size, int flags)
{
void *data;