Print this page
NEX-3288 fmd segfaults in zfs-diagnosis.so`zfs_fm_close
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-3011 zfs-diagnosis: Memory leak in zpool_find_load_time()
Reviewed by: Dan Fields <dan.fields@nexenta.com>
OS-70 remove zio timer code
re #12393 rb3935 Kerberos and smbd disagree about who is our AD server (fix elf runtime attributes check)
re #11612 rb3907 Failing vdev of a mirrored pool should not take zfs operations out of action for extended periods of time.


   3  *
   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 2015 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  25  */



  26 
  27 #include <assert.h>
  28 #include <stddef.h>
  29 #include <strings.h>
  30 #include <libuutil.h>
  31 #include <libzfs.h>
  32 #include <fm/fmd_api.h>
  33 #include <fm/libtopo.h>
  34 #include <sys/types.h>
  35 #include <sys/time.h>
  36 #include <sys/fs/zfs.h>
  37 #include <sys/fm/protocol.h>
  38 #include <sys/fm/fs/zfs.h>
  39 
  40 /*
  41  * Our serd engines are named 'zfs_<pool_guid>_<vdev_guid>_{checksum,io}'.  This
  42  * #define reserves enough space for two 64-bit hex values plus the length of
  43  * the longest string.
  44  */
  45 #define MAX_SERDLEN     (16 * 2 + sizeof ("zfs___checksum"))


 915         }
 916 }
 917 
 918 /*
 919  * The timeout is fired when we diagnosed an I/O error, and it was not due to
 920  * device removal (which would cause the timeout to be cancelled).
 921  */
 922 /* ARGSUSED */
 923 static void
 924 zfs_fm_timeout(fmd_hdl_t *hdl, id_t id, void *data)
 925 {
 926         zfs_case_t *zcp = data;
 927 
 928         if (id == zcp->zc_remove_timer)
 929                 zfs_case_solve(hdl, zcp, "fault.fs.zfs.vdev.io", B_FALSE);
 930 }
 931 
 932 static void
 933 zfs_fm_close(fmd_hdl_t *hdl, fmd_case_t *cs)
 934 {
 935         zfs_case_t *zcp = fmd_case_getspecific(hdl, cs);
 936 



 937         if (zcp->zc_data.zc_serd_checksum[0] != '\0')
 938                 fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_checksum);
 939         if (zcp->zc_data.zc_serd_io[0] != '\0')
 940                 fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_io);
 941         if (zcp->zc_data.zc_has_remove_timer)
 942                 fmd_timer_remove(hdl, zcp->zc_remove_timer);
 943         uu_list_remove(zfs_cases, zcp);
 944         fmd_hdl_free(hdl, zcp, sizeof (zfs_case_t));
 945 }
 946 
 947 /*
 948  * We use the fmd gc entry point to look for old cases that no longer apply.
 949  * This allows us to keep our set of case data small in a long running system.
 950  */
 951 static void
 952 zfs_fm_gc(fmd_hdl_t *hdl)
 953 {
 954         zfs_purge_cases(hdl);
 955 }
 956 
 957 static const fmd_hdl_ops_t fmd_ops = {
 958         zfs_fm_recv,    /* fmdo_recv */
 959         zfs_fm_timeout, /* fmdo_timeout */
 960         zfs_fm_close,   /* fmdo_close */
 961         NULL,           /* fmdo_stats */
 962         zfs_fm_gc,      /* fmdo_gc */
 963 };
 964 
 965 static const fmd_prop_t fmd_props[] = {
 966         { "checksum_N", FMD_TYPE_UINT32, "10" },
 967         { "checksum_T", FMD_TYPE_TIME, "10min" },
 968         { "io_N", FMD_TYPE_UINT32, "10" },
 969         { "io_T", FMD_TYPE_TIME, "10min" },
 970         { "remove_timeout", FMD_TYPE_TIME, "15sec" },
 971         { NULL, 0, NULL }
 972 };
 973 
 974 static const fmd_hdl_info_t fmd_info = {
 975         "ZFS Diagnosis Engine", "1.0", &fmd_ops, fmd_props
 976 };
 977 
 978 void
 979 _fmd_init(fmd_hdl_t *hdl)
 980 {
 981         fmd_case_t *cp;
 982         libzfs_handle_t *zhdl;
 983 
 984         if ((zhdl = libzfs_init()) == NULL)
 985                 return;
 986 
 987         if ((zfs_case_pool = uu_list_pool_create("zfs_case_pool",
 988             sizeof (zfs_case_t), offsetof(zfs_case_t, zc_node),
 989             NULL, 0)) == NULL) {
 990                 libzfs_fini(zhdl);
 991                 return;
 992         }
 993 
 994         if ((zfs_cases = uu_list_create(zfs_case_pool, NULL, 0)) == NULL) {
 995                 uu_list_pool_destroy(zfs_case_pool);




   3  *
   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) 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 #include <assert.h>
  30 #include <stddef.h>
  31 #include <strings.h>
  32 #include <libuutil.h>
  33 #include <libzfs.h>
  34 #include <fm/fmd_api.h>
  35 #include <fm/libtopo.h>
  36 #include <sys/types.h>
  37 #include <sys/time.h>
  38 #include <sys/fs/zfs.h>
  39 #include <sys/fm/protocol.h>
  40 #include <sys/fm/fs/zfs.h>
  41 
  42 /*
  43  * Our serd engines are named 'zfs_<pool_guid>_<vdev_guid>_{checksum,io}'.  This
  44  * #define reserves enough space for two 64-bit hex values plus the length of
  45  * the longest string.
  46  */
  47 #define MAX_SERDLEN     (16 * 2 + sizeof ("zfs___checksum"))


 917         }
 918 }
 919 
 920 /*
 921  * The timeout is fired when we diagnosed an I/O error, and it was not due to
 922  * device removal (which would cause the timeout to be cancelled).
 923  */
 924 /* ARGSUSED */
 925 static void
 926 zfs_fm_timeout(fmd_hdl_t *hdl, id_t id, void *data)
 927 {
 928         zfs_case_t *zcp = data;
 929 
 930         if (id == zcp->zc_remove_timer)
 931                 zfs_case_solve(hdl, zcp, "fault.fs.zfs.vdev.io", B_FALSE);
 932 }
 933 
 934 static void
 935 zfs_fm_close(fmd_hdl_t *hdl, fmd_case_t *cs)
 936 {
 937         zfs_case_t *zcp;
 938 
 939         if ((zcp = fmd_case_getspecific(hdl, cs)) == NULL)
 940                 return;
 941 
 942         if (zcp->zc_data.zc_serd_checksum[0] != '\0')
 943                 fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_checksum);
 944         if (zcp->zc_data.zc_serd_io[0] != '\0')
 945                 fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_io);
 946         if (zcp->zc_data.zc_has_remove_timer)
 947                 fmd_timer_remove(hdl, zcp->zc_remove_timer);
 948         uu_list_remove(zfs_cases, zcp);
 949         fmd_hdl_free(hdl, zcp, sizeof (zfs_case_t));
 950 }
 951 
 952 /*
 953  * We use the fmd gc entry point to look for old cases that no longer apply.
 954  * This allows us to keep our set of case data small in a long running system.
 955  */
 956 static void
 957 zfs_fm_gc(fmd_hdl_t *hdl)
 958 {
 959         zfs_purge_cases(hdl);
 960 }
 961 
 962 static const fmd_hdl_ops_t fmd_ops = {
 963         zfs_fm_recv,    /* fmdo_recv */
 964         zfs_fm_timeout, /* fmdo_timeout */
 965         zfs_fm_close,   /* fmdo_close */
 966         NULL,           /* fmdo_stats */
 967         zfs_fm_gc,      /* fmdo_gc */
 968 };
 969 
 970 static const fmd_prop_t fmd_props[] = {
 971         { "checksum_N", FMD_TYPE_UINT32, "10" },
 972         { "checksum_T", FMD_TYPE_TIME, "10min" },
 973         { "io_N", FMD_TYPE_UINT32, "10" },
 974         { "io_T", FMD_TYPE_TIME, "10min" },
 975         { "remove_timeout", FMD_TYPE_TIME, "15sec" },
 976         { NULL, 0, NULL }
 977 };
 978 
 979 static const fmd_hdl_info_t fmd_info = {
 980         "ZFS Diagnosis Engine", "1.1", &fmd_ops, fmd_props
 981 };
 982 
 983 void
 984 _fmd_init(fmd_hdl_t *hdl)
 985 {
 986         fmd_case_t *cp;
 987         libzfs_handle_t *zhdl;
 988 
 989         if ((zhdl = libzfs_init()) == NULL)
 990                 return;
 991 
 992         if ((zfs_case_pool = uu_list_pool_create("zfs_case_pool",
 993             sizeof (zfs_case_t), offsetof(zfs_case_t, zc_node),
 994             NULL, 0)) == NULL) {
 995                 libzfs_fini(zhdl);
 996                 return;
 997         }
 998 
 999         if ((zfs_cases = uu_list_create(zfs_case_pool, NULL, 0)) == NULL) {
1000                 uu_list_pool_destroy(zfs_case_pool);