4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/fm/protocol.h>
  28 #include <fm/topo_hc.h>
  29 #include <uuid/uuid.h>
  30 
  31 #include <unistd.h>
  32 #include <signal.h>
  33 #include <limits.h>
  34 #include <syslog.h>
  35 #include <alloca.h>
  36 #include <stddef.h>
  37 #include <door.h>
  38 
  39 #include <fmd_module.h>
  40 #include <fmd_api.h>
  41 #include <fmd_string.h>
  42 #include <fmd_subr.h>
  43 #include <fmd_error.h>
 
 
 741 
 742         thp = fmd_module_topo_hold(mp);
 743         ASSERT(thp != NULL);
 744 
 745         fmd_module_unlock(mp);
 746         return (thp);
 747 }
 748 
 749 void
 750 fmd_hdl_topo_rele(fmd_hdl_t *hdl, topo_hdl_t *thp)
 751 {
 752         fmd_module_t *mp = fmd_api_module_lock(hdl);
 753 
 754         if (fmd_module_topo_rele(mp, thp) != 0)
 755                 fmd_api_error(mp, EFMD_MOD_TOPO, "failed to release invalid "
 756                     "topo handle: %p\n", (void *)thp);
 757 
 758         fmd_module_unlock(mp);
 759 }
 760 
 761 static void *
 762 fmd_hdl_alloc_locked(fmd_module_t *mp, size_t size, int flags)
 763 {
 764         void *data;
 765 
 766         if (mp->mod_stats->ms_memlimit.fmds_value.ui64 -
 767             mp->mod_stats->ms_memtotal.fmds_value.ui64 < size) {
 768                 fmd_api_error(mp, EFMD_HDL_NOMEM, "%s's allocation of %lu "
 769                     "bytes exceeds module memory limit (%llu)\n",
 770                     mp->mod_name, (ulong_t)size, (u_longlong_t)
 771                     mp->mod_stats->ms_memtotal.fmds_value.ui64);
 772         }
 773 
 774         if ((data = fmd_alloc(size, flags)) != NULL)
 775                 mp->mod_stats->ms_memtotal.fmds_value.ui64 += size;
 776 
 777         return (data);
 778 }
 779 
 780 void *
 
 | 
 
 
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/fm/protocol.h>
  29 #include <fm/topo_hc.h>
  30 #include <uuid/uuid.h>
  31 
  32 #include <unistd.h>
  33 #include <signal.h>
  34 #include <limits.h>
  35 #include <syslog.h>
  36 #include <alloca.h>
  37 #include <stddef.h>
  38 #include <door.h>
  39 
  40 #include <fmd_module.h>
  41 #include <fmd_api.h>
  42 #include <fmd_string.h>
  43 #include <fmd_subr.h>
  44 #include <fmd_error.h>
 
 
 742 
 743         thp = fmd_module_topo_hold(mp);
 744         ASSERT(thp != NULL);
 745 
 746         fmd_module_unlock(mp);
 747         return (thp);
 748 }
 749 
 750 void
 751 fmd_hdl_topo_rele(fmd_hdl_t *hdl, topo_hdl_t *thp)
 752 {
 753         fmd_module_t *mp = fmd_api_module_lock(hdl);
 754 
 755         if (fmd_module_topo_rele(mp, thp) != 0)
 756                 fmd_api_error(mp, EFMD_MOD_TOPO, "failed to release invalid "
 757                     "topo handle: %p\n", (void *)thp);
 758 
 759         fmd_module_unlock(mp);
 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 
 835 static void *
 836 fmd_hdl_alloc_locked(fmd_module_t *mp, size_t size, int flags)
 837 {
 838         void *data;
 839 
 840         if (mp->mod_stats->ms_memlimit.fmds_value.ui64 -
 841             mp->mod_stats->ms_memtotal.fmds_value.ui64 < size) {
 842                 fmd_api_error(mp, EFMD_HDL_NOMEM, "%s's allocation of %lu "
 843                     "bytes exceeds module memory limit (%llu)\n",
 844                     mp->mod_name, (ulong_t)size, (u_longlong_t)
 845                     mp->mod_stats->ms_memtotal.fmds_value.ui64);
 846         }
 847 
 848         if ((data = fmd_alloc(size, flags)) != NULL)
 849                 mp->mod_stats->ms_memtotal.fmds_value.ui64 += size;
 850 
 851         return (data);
 852 }
 853 
 854 void *
 
 |