1 /*
   2  * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
   3  */
   4 
   5 #include <strings.h>
   6 #include <sys/debug.h>
   7 #include <umem.h>
   8 
   9 #include <sys/krrp.h>
  10 #include "libkrrp.h"
  11 #include "libkrrp_impl.h"
  12 
  13 int
  14 krrp_set_srv_config(libkrrp_handle_t *hdl, const char *address,
  15     const uint16_t port)
  16 {
  17         nvlist_t *params = NULL;
  18         krrp_cfg_type_t cfg_type = KRRP_SVC_CFG_TYPE_SERVER;
  19         int rc;
  20 
  21         params = fnvlist_alloc();
  22 
  23         VERIFY(hdl != NULL);
  24 
  25         if ((address != NULL) && (strlen(address))) {
  26                 (void) krrp_param_put(KRRP_PARAM_LISTENING_ADDRESS, params,
  27                     (void *)address);
  28         }
  29 
  30         (void) krrp_param_put(KRRP_PARAM_CFG_TYPE, params, (void *)&cfg_type);
  31         (void) krrp_param_put(KRRP_PARAM_PORT, params,
  32             (void *)&port);
  33 
  34         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SVC_SET_CONFIG, params, NULL);
  35 
  36         fnvlist_free(params);
  37         return (rc);
  38 }
  39 
  40 int
  41 krrp_get_srv_config(libkrrp_handle_t *hdl, libkrrp_srv_config_t *cfg)
  42 {
  43         nvlist_t *result = NULL;
  44         nvlist_t *params = NULL;
  45         char *address = NULL;
  46         int rc;
  47         krrp_cfg_type_t cfg_type = KRRP_SVC_CFG_TYPE_SERVER;
  48 
  49         VERIFY(hdl != NULL);
  50 
  51         params = fnvlist_alloc();
  52 
  53         (void) krrp_param_put(KRRP_PARAM_CFG_TYPE, params, (void *)&cfg_type);
  54 
  55         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SVC_GET_CONFIG, params,
  56             &result);
  57 
  58         if (rc != 0) {
  59                 rc = -1;
  60                 goto fini;
  61         }
  62 
  63         VERIFY3U(krrp_param_get(KRRP_PARAM_PORT, result,
  64             (void *)&cfg->port), ==, 0);
  65 
  66         rc = krrp_param_get(KRRP_PARAM_LISTENING_ADDRESS, result,
  67             (void *)&address);
  68 
  69         VERIFY(rc == 0 || rc == ENOENT);
  70 
  71         if (rc == 0) {
  72                 rc = strlcpy(cfg->address, address, sizeof (cfg->address));
  73                 VERIFY(rc < sizeof (cfg->address));
  74         } else {
  75                 cfg->address[0] = '\0';
  76         }
  77 
  78         rc = 0;
  79 
  80 fini:
  81         fnvlist_free(params);
  82 
  83         if (result != NULL)
  84                 fnvlist_free(result);
  85 
  86         return (rc);
  87 }
  88 
  89 int
  90 krrp_svc_enable(libkrrp_handle_t *hdl)
  91 {
  92         VERIFY(hdl != NULL);
  93         return (krrp_ioctl_perform(hdl, KRRP_IOCTL_SVC_ENABLE, NULL, NULL));
  94 }
  95 
  96 int
  97 krrp_svc_disable(libkrrp_handle_t *hdl)
  98 {
  99         VERIFY(hdl != NULL);
 100         return (krrp_ioctl_perform(hdl, KRRP_IOCTL_SVC_DISABLE, NULL, NULL));
 101 }
 102 
 103 int
 104 krrp_svc_state(libkrrp_handle_t *hdl, libkrrp_svc_state_t *state)
 105 {
 106         int rc;
 107         nvlist_t *result_nvl = NULL;
 108 
 109         VERIFY(hdl != NULL);
 110 
 111         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SVC_STATE, NULL, &result_nvl);
 112 
 113         if (rc != 0)
 114                 return (-1);
 115 
 116         VERIFY3U(krrp_param_get(KRRP_PARAM_SVC_ENABLED, result_nvl,
 117             (void *)&state->enabled), ==, 0);
 118 
 119         VERIFY3U(krrp_param_get(KRRP_PARAM_SRV_RUNNING, result_nvl,
 120             (void *)&state->running), ==, 0);
 121 
 122         fnvlist_free(result_nvl);
 123         return (rc);
 124 }
 125 
 126 int
 127 krrp_sess_list(libkrrp_handle_t *hdl, libkrrp_sess_list_t **res_sess_list)
 128 {
 129         int rc;
 130         nvlist_t *result = NULL;
 131         uint_t i;
 132         krrp_param_array_t sessions;
 133         nvlist_t *session;
 134         char *sess_id_str;
 135         char *sess_kstat_id;
 136         libkrrp_sess_list_t *sess_list = NULL;
 137         libkrrp_sess_list_t *entry = NULL;
 138         libkrrp_sess_list_t *prev = NULL;
 139 
 140         VERIFY(hdl != NULL);
 141 
 142         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_LIST, NULL, &result);
 143         if (rc != 0)
 144                 return (-1);
 145 
 146         if (result == NULL) {
 147                 *res_sess_list = NULL;
 148                 return (0);
 149         }
 150 
 151         VERIFY3U(krrp_param_get(KRRP_PARAM_SESSIONS, result,
 152             (void *)&sessions), ==, 0);
 153 
 154         for (i = 0; i < sessions.nelem; i++) {
 155                 session = sessions.array[i];
 156                 VERIFY3U(krrp_param_get(KRRP_PARAM_SESS_ID, session,
 157                     (void *)&sess_id_str), ==, 0);
 158 
 159                 entry = umem_zalloc(sizeof (libkrrp_sess_list_t), UMEM_DEFAULT);
 160 
 161                 if (entry == NULL) {
 162                         libkrrp_error_set(&hdl->libkrrp_error,
 163                             LIBKRRP_ERRNO_NOMEM, errno, 0);
 164                         rc = -1;
 165                         goto fini;
 166                 }
 167 
 168                 if (uuid_parse(sess_id_str, entry->sess_id) != 0) {
 169                         libkrrp_error_set(&hdl->libkrrp_error,
 170                             LIBKRRP_ERRNO_SESSID, EINVAL, 0);
 171                         rc = -1;
 172                         goto fini;
 173                 }
 174 
 175                 VERIFY3U(krrp_param_get(KRRP_PARAM_SESS_KSTAT_ID, session,
 176                     (void *)&sess_kstat_id), ==, 0);
 177 
 178                 entry->sess_kstat_id = umem_alloc(KRRP_KSTAT_ID_STRING_LENGTH,
 179                     UMEM_DEFAULT);
 180 
 181                 if (entry->sess_kstat_id == NULL) {
 182                         libkrrp_error_set(&hdl->libkrrp_error,
 183                             LIBKRRP_ERRNO_NOMEM, errno, 0);
 184                         rc = -1;
 185                         goto fini;
 186                 }
 187 
 188                 (void) strlcpy(entry->sess_kstat_id, sess_kstat_id,
 189                     KRRP_KSTAT_ID_STRING_LENGTH);
 190 
 191                 VERIFY3U(krrp_param_get(KRRP_PARAM_SESS_STARTED, session,
 192                     (void *)&entry->sess_started), ==, 0);
 193 
 194                 VERIFY3U(krrp_param_get(KRRP_PARAM_SESS_RUNNING, session,
 195                     (void *)&entry->sess_running), ==, 0);
 196 
 197                 if (prev == NULL)
 198                         sess_list = entry;
 199                 else
 200                         prev->sl_next = entry;
 201 
 202                 prev = entry;
 203         }
 204 
 205         *res_sess_list = sess_list;
 206 
 207 fini:
 208         fnvlist_free(result);
 209 
 210         if (rc != 0 && sess_list != NULL)
 211                 krrp_sess_list_free(sess_list);
 212 
 213         return (rc);
 214 }
 215 
 216 void
 217 krrp_sess_list_free(libkrrp_sess_list_t *sess_list)
 218 {
 219         libkrrp_sess_list_t *next;
 220 
 221         while (sess_list != NULL) {
 222                 next = sess_list->sl_next;
 223 
 224                 if (sess_list->sess_kstat_id != NULL) {
 225                         umem_free(sess_list->sess_kstat_id,
 226                             KRRP_KSTAT_ID_STRING_LENGTH);
 227                 }
 228 
 229                 umem_free(sess_list, sizeof (libkrrp_sess_list_t));
 230                 sess_list = next;
 231         }
 232 }