1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 #include <sys/ddi.h>
  17 #include <sys/sunddi.h>
  18 #include <sys/sunldi.h>
  19 #include <sys/cmn_err.h>
  20 #include <sys/varargs.h>
  21 #include <sys/debug.h>
  22 
  23 #include "krrp_params.h"
  24 #include "krrp_error.h"
  25 
  26 static struct {
  27         krrp_errno_t    krrp_errno;
  28         const char              *krrp_errno_str;
  29 } krrp_errs[] = {
  30         {KRRP_ERRNO_OK, "KRRP_ERRNO_OK"},
  31         {KRRP_ERRNO_UNKNOWN, "KRRP_ERRNO_UNKNOWN"},
  32 #define KRRP_ERRNO_EXPAND(enum_name) \
  33         {KRRP_ERRNO_##enum_name, "KRRP_ERRNO_"#enum_name},
  34         KRRP_ERRNO_MAP(KRRP_ERRNO_EXPAND)
  35 #undef KRRP_ERRNO_EXPAND
  36 };
  37 
  38 static size_t krrp_errs_sz = sizeof (krrp_errs) / sizeof (krrp_errs[0]);
  39 
  40 #ifdef _KERNEL
  41 
  42 void
  43 krrp_error_set(krrp_error_t *error, krrp_errno_t krrp_errno,
  44     int unix_errno)
  45 {
  46         error->krrp_errno = krrp_errno;
  47         error->unix_errno = unix_errno;
  48 }
  49 
  50 void
  51 krrp_error_set_flag(krrp_error_t *error, krrp_error_flag_t flag)
  52 {
  53         error->flags |= flag;
  54 }
  55 
  56 void
  57 krrp_error_to_nvl(krrp_error_t *error, nvlist_t **result_nvl)
  58 {
  59         nvlist_t *nvl;
  60 
  61         nvl = (*result_nvl == NULL) ? fnvlist_alloc() : *result_nvl;
  62 
  63         VERIFY3U(krrp_param_put(KRRP_PARAM_ERROR_CODE,
  64             nvl, (void *) &error->krrp_errno), ==, 0);
  65         VERIFY3U(krrp_param_put(KRRP_PARAM_ERROR_EXCODE,
  66             nvl, (void *) &error->unix_errno), ==, 0);
  67         VERIFY3U(krrp_param_put(KRRP_PARAM_ERROR_FLAGS,
  68             nvl, (void *) &error->flags), ==, 0);
  69 
  70         *result_nvl = nvl;
  71 }
  72 
  73 int
  74 krrp_error_from_nvl(krrp_error_t *res_error, nvlist_t *error_nvl)
  75 {
  76         int rc;
  77         krrp_error_t error;
  78 
  79         rc = krrp_param_get(KRRP_PARAM_ERROR_CODE,
  80             error_nvl, (void *) &error.krrp_errno);
  81         if (rc != 0)
  82                 return (rc);
  83 
  84         rc = krrp_param_get(KRRP_PARAM_ERROR_EXCODE,
  85             error_nvl, (void *) &error.unix_errno);
  86         if (rc != 0)
  87                 return (rc);
  88 
  89         rc = krrp_param_get(KRRP_PARAM_ERROR_FLAGS,
  90             error_nvl, (void *) &error.flags);
  91         if (rc != 0)
  92                 return (rc);
  93 
  94         bcopy(&error, res_error, sizeof (krrp_error_t));
  95 
  96         return (0);
  97 }
  98 
  99 #endif /* _KERNEL */
 100 
 101 const char *
 102 krrp_error_errno_to_str(krrp_errno_t krrp_errno)
 103 {
 104         size_t i;
 105 
 106         for (i = 0; i < krrp_errs_sz; i++) {
 107                 if (krrp_errs[i].krrp_errno == krrp_errno)
 108                         return (krrp_errs[i].krrp_errno_str);
 109         }
 110 
 111         return (krrp_error_errno_to_str(KRRP_ERRNO_UNKNOWN));
 112 }