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