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>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/fm/fmd/common/fmd_api.c
          +++ new/usr/src/cmd/fm/fmd/common/fmd_api.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  24   25   */
  25   26  
  26   27  #include <sys/types.h>
  27   28  #include <sys/fm/protocol.h>
  28   29  #include <fm/topo_hc.h>
  29   30  #include <uuid/uuid.h>
  30   31  
  31   32  #include <unistd.h>
  32   33  #include <signal.h>
  33   34  #include <limits.h>
↓ open down ↓ 717 lines elided ↑ open up ↑
 751  752  {
 752  753          fmd_module_t *mp = fmd_api_module_lock(hdl);
 753  754  
 754  755          if (fmd_module_topo_rele(mp, thp) != 0)
 755  756                  fmd_api_error(mp, EFMD_MOD_TOPO, "failed to release invalid "
 756  757                      "topo handle: %p\n", (void *)thp);
 757  758  
 758  759          fmd_module_unlock(mp);
 759  760  }
 760  761  
      762 +/*
      763 + * Visit a libtopo node trying to find a disk with the specified devid.
      764 + * If we find it, copy it's FRU and resource fields.
      765 + */
      766 +static int
      767 +fmd_hdl_topo_walk_cb(topo_hdl_t *thp, tnode_t *tn, void *arg)
      768 +{
      769 +
      770 +        fmd_hdl_topo_node_info_t *node = (fmd_hdl_topo_node_info_t *)arg;
      771 +        char *cur_devid;
      772 +        nvlist_t *fru;
      773 +        nvlist_t *resource;
      774 +        int err = 0;
      775 +        _NOTE(ARGUNUSED(thp));
      776 +
      777 +        if (strcmp(topo_node_name(tn), "disk") != 0)
      778 +                return (TOPO_WALK_NEXT);
      779 +
      780 +        if (topo_prop_get_string(tn, "io", "devid", &cur_devid, &err) != 0)
      781 +                return (TOPO_WALK_NEXT);
      782 +
      783 +        if (strcmp(cur_devid, node->device) == 0) {
      784 +                if (topo_node_fru(tn, &fru, NULL, &err) == 0 && err == 0 &&
      785 +                    topo_node_resource(tn, &resource, &err) == 0 && err == 0) {
      786 +                        node->fru = fnvlist_dup(fru);
      787 +                        node->resource = fnvlist_dup(resource);
      788 +                        return (TOPO_WALK_TERMINATE);
      789 +                }
      790 +        }
      791 +
      792 +        return (TOPO_WALK_NEXT);
      793 +}
      794 +
      795 +/*
      796 + * Extract FRU and resource values from a libtopo node with the matching devid
      797 + */
      798 +fmd_hdl_topo_node_info_t *
      799 +fmd_hdl_topo_node_get_by_devid(fmd_hdl_t *hdl, char *device)
      800 +{
      801 +
      802 +        int err = 0;
      803 +        topo_hdl_t *thp;
      804 +        topo_walk_t *twp;
      805 +
      806 +        fmd_hdl_topo_node_info_t *node = (fmd_hdl_topo_node_info_t *)
      807 +            fmd_hdl_zalloc(hdl, sizeof (fmd_hdl_topo_node_info_t), FMD_SLEEP);
      808 +
      809 +        thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION);
      810 +
      811 +        node->device = device;
      812 +
      813 +        if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, fmd_hdl_topo_walk_cb,
      814 +            node, &err)) == NULL) {
      815 +                fmd_hdl_error(hdl, "failed to get topology: %s",
      816 +                    topo_strerror(err));
      817 +                fmd_hdl_topo_rele(hdl, thp);
      818 +                return (NULL);
      819 +        }
      820 +
      821 +        (void) topo_walk_step(twp, TOPO_WALK_CHILD);
      822 +        topo_walk_fini(twp);
      823 +        fmd_hdl_topo_rele(hdl, thp);
      824 +
      825 +        if (node->fru == NULL || node->resource == NULL) {
      826 +                fmd_hdl_debug(hdl, "Could not find device with matching FRU");
      827 +                fmd_hdl_free(hdl, node, sizeof (fmd_hdl_topo_node_info_t));
      828 +                return (NULL);
      829 +        } else {
      830 +                fmd_hdl_debug(hdl, "Found FRU for device %s", device);
      831 +                return (node);
      832 +        }
      833 +}
      834 +
 761  835  static void *
 762  836  fmd_hdl_alloc_locked(fmd_module_t *mp, size_t size, int flags)
 763  837  {
 764  838          void *data;
 765  839  
 766  840          if (mp->mod_stats->ms_memlimit.fmds_value.ui64 -
 767  841              mp->mod_stats->ms_memtotal.fmds_value.ui64 < size) {
 768  842                  fmd_api_error(mp, EFMD_HDL_NOMEM, "%s's allocation of %lu "
 769  843                      "bytes exceeds module memory limit (%llu)\n",
 770  844                      mp->mod_name, (ulong_t)size, (u_longlong_t)
↓ open down ↓ 1961 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX