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 2017 Nexenta Systems, Inc. All rights reserved.
  14  */
  15 
  16 #include <libintl.h>
  17 #include <sys/uuid.h>
  18 #include <sys/debug.h>
  19 #include <string.h>
  20 #include <inttypes.h>
  21 
  22 #include <libzfs.h>
  23 #include <sys/krrp.h>
  24 #include "libkrrp.h"
  25 #include "libkrrp_impl.h"
  26 
  27 static int
  28 krrp_sess_create_common(libkrrp_handle_t *hdl, uuid_t sess_id,
  29     const char *sess_kstat_id, const char *auth_digest, boolean_t fake_mode,
  30     nvlist_t *params)
  31 {
  32         int rc;
  33         krrp_sess_id_str_t sess_id_str;
  34 
  35         VERIFY(hdl != NULL);
  36         VERIFY(sess_kstat_id != NULL);
  37 
  38         libkrrp_reset(hdl);
  39 
  40         uuid_unparse(sess_id, sess_id_str);
  41 
  42         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
  43 
  44         (void) krrp_param_put(KRRP_PARAM_SESS_KSTAT_ID, params,
  45             (void *)sess_kstat_id);
  46 
  47         if (auth_digest != NULL) {
  48                 (void) krrp_param_put(KRRP_PARAM_AUTH_DATA, params,
  49                     (void *)auth_digest);
  50         }
  51 
  52         if (fake_mode)
  53                 (void) krrp_param_put(KRRP_PARAM_FAKE_MODE, params, NULL);
  54 
  55         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_CREATE, params, NULL);
  56 
  57         return (rc);
  58 }
  59 
  60 int
  61 krrp_sess_create_sender(libkrrp_handle_t *hdl, uuid_t sess_id,
  62     const char *sess_kstat_id, const char *auth_digest, boolean_t fake_mode)
  63 {
  64         nvlist_t *params = NULL;
  65         int rc;
  66 
  67         params = fnvlist_alloc();
  68 
  69         (void) krrp_param_put(KRRP_PARAM_SESS_SENDER, params, NULL);
  70 
  71         rc = krrp_sess_create_common(hdl, sess_id, sess_kstat_id, auth_digest,
  72             fake_mode, params);
  73 
  74         fnvlist_free(params);
  75         return (rc);
  76 }
  77 
  78 int
  79 krrp_sess_create_receiver(libkrrp_handle_t *hdl, uuid_t sess_id,
  80     const char *sess_kstat_id, const char *auth_digest, boolean_t fake_mode)
  81 {
  82         nvlist_t *params = NULL;
  83         int rc;
  84 
  85         params = fnvlist_alloc();
  86 
  87         rc = krrp_sess_create_common(hdl, sess_id, sess_kstat_id, auth_digest,
  88             fake_mode, params);
  89 
  90         fnvlist_free(params);
  91         return (rc);
  92 }
  93 
  94 int
  95 krrp_sess_create_compound(libkrrp_handle_t *hdl, uuid_t sess_id,
  96     const char *sess_kstat_id, boolean_t fake_mode)
  97 {
  98         nvlist_t *params = NULL;
  99         int rc;
 100 
 101         params = fnvlist_alloc();
 102 
 103         (void) krrp_param_put(KRRP_PARAM_SESS_COMPOUND, params, NULL);
 104 
 105         rc = krrp_sess_create_common(hdl, sess_id, sess_kstat_id, NULL,
 106             fake_mode, params);
 107 
 108         fnvlist_free(params);
 109         return (rc);
 110 }
 111 
 112 int
 113 krrp_sess_destroy(libkrrp_handle_t *hdl, uuid_t sess_id)
 114 {
 115         nvlist_t *params = NULL;
 116         int rc;
 117         krrp_sess_id_str_t sess_id_str;
 118 
 119         VERIFY(hdl != NULL);
 120 
 121         libkrrp_reset(hdl);
 122 
 123         uuid_unparse(sess_id, sess_id_str);
 124         params = fnvlist_alloc();
 125         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 126 
 127         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_DESTROY, params, NULL);
 128 
 129         fnvlist_free(params);
 130         return (rc);
 131 }
 132 
 133 int
 134 krrp_sess_set_private_data(libkrrp_handle_t *hdl, uuid_t sess_id,
 135     nvlist_t *private_data)
 136 {
 137         nvlist_t *params = NULL;
 138         int rc;
 139         krrp_sess_id_str_t sess_id_str;
 140 
 141         VERIFY(hdl != NULL);
 142         VERIFY(private_data != NULL);
 143 
 144         libkrrp_reset(hdl);
 145 
 146         uuid_unparse(sess_id, sess_id_str);
 147         params = fnvlist_alloc();
 148         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 149         (void) krrp_param_put(KRRP_PARAM_SESS_PRIVATE_DATA,
 150             params, private_data);
 151 
 152         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_SET_PRIVATE_DATA,
 153             params, NULL);
 154 
 155         fnvlist_free(params);
 156         return (rc);
 157 }
 158 
 159 int
 160 krrp_sess_get_private_data(libkrrp_handle_t *hdl, uuid_t sess_id,
 161     nvlist_t **private_data)
 162 {
 163         nvlist_t *params = NULL, *result = NULL, *tmp = NULL;
 164         int rc;
 165         krrp_sess_id_str_t sess_id_str;
 166 
 167         VERIFY(hdl != NULL);
 168         VERIFY(private_data != NULL && *private_data == NULL);
 169 
 170         libkrrp_reset(hdl);
 171 
 172         uuid_unparse(sess_id, sess_id_str);
 173         params = fnvlist_alloc();
 174         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 175 
 176         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_GET_PRIVATE_DATA,
 177             params, &result);
 178 
 179         if (rc != 0)
 180                 goto fini;
 181 
 182         VERIFY0(krrp_param_get(KRRP_PARAM_SESS_PRIVATE_DATA,
 183             result, &tmp));
 184 
 185         *private_data = fnvlist_dup(tmp);
 186         fnvlist_free(result);
 187 
 188 fini:
 189         fnvlist_free(params);
 190         return (rc);
 191 }
 192 
 193 int
 194 krrp_sess_create_conn(libkrrp_handle_t *hdl, uuid_t sess_id,
 195     const char *address, const uint16_t port, const uint32_t conn_timeout)
 196 {
 197         nvlist_t *params = NULL;
 198         int rc;
 199         krrp_sess_id_str_t sess_id_str;
 200 
 201         VERIFY(hdl != NULL);
 202         VERIFY(address != NULL);
 203 
 204         libkrrp_reset(hdl);
 205 
 206         uuid_unparse(sess_id, sess_id_str);
 207         params = fnvlist_alloc();
 208 
 209         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 210         (void) krrp_param_put(KRRP_PARAM_REMOTE_HOST, params, (void *)address);
 211         (void) krrp_param_put(KRRP_PARAM_PORT, params, (void *)&port);
 212 
 213         if (conn_timeout != 0) {
 214                 (void) krrp_param_put(KRRP_PARAM_CONN_TIMEOUT, params,
 215                     (void *)&conn_timeout);
 216         }
 217 
 218         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_CREATE_CONN, params, NULL);
 219 
 220         fnvlist_free(params);
 221         return (rc);
 222 }
 223 
 224 int
 225 krrp_sess_conn_throttle(libkrrp_handle_t *hdl, uuid_t sess_id,
 226     const uint32_t limit)
 227 {
 228         nvlist_t *params = NULL;
 229         int rc;
 230         krrp_sess_id_str_t sess_id_str;
 231 
 232         VERIFY(hdl != NULL);
 233 
 234         libkrrp_reset(hdl);
 235 
 236         uuid_unparse(sess_id, sess_id_str);
 237         params = fnvlist_alloc();
 238         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 239         (void) krrp_param_put(KRRP_PARAM_THROTTLE, params, (void *)&limit);
 240 
 241         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_CONN_THROTTLE, params,
 242             NULL);
 243 
 244         fnvlist_free(params);
 245         return (rc);
 246 }
 247 
 248 int
 249 krrp_sess_create_pdu_engine(libkrrp_handle_t *hdl, uuid_t sess_id,
 250     const int memory_limit, const int dblk_sz, boolean_t use_preallocation)
 251 {
 252         nvlist_t *params = NULL;
 253         int rc;
 254         krrp_sess_id_str_t sess_id_str;
 255 
 256         VERIFY(hdl != NULL);
 257 
 258         libkrrp_reset(hdl);
 259 
 260         uuid_unparse(sess_id, sess_id_str);
 261         params = fnvlist_alloc();
 262         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 263         (void) krrp_param_put(KRRP_PARAM_MAX_MEMORY, params,
 264             (void *)&memory_limit);
 265         (void) krrp_param_put(KRRP_PARAM_DBLK_DATA_SIZE, params,
 266             (void *)&dblk_sz);
 267 
 268         if (use_preallocation) {
 269                 (void) krrp_param_put(KRRP_PARAM_USE_PREALLOCATION,
 270                     params, NULL);
 271         }
 272 
 273         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_CREATE_PDU_ENGINE, params,
 274             NULL);
 275 
 276         fnvlist_free(params);
 277         return (rc);
 278 }
 279 
 280 static void
 281 krrp_sess_create_stream_common(libkrrp_handle_t *hdl, nvlist_t *params,
 282     uuid_t sess_id, const char *common_snap,
 283     krrp_sess_stream_flags_t krrp_sess_stream_flags, const char *resume_token,
 284     uint32_t keep_snaps)
 285 {
 286         krrp_sess_id_str_t sess_id_str;
 287 
 288         VERIFY(hdl != NULL);
 289 
 290         libkrrp_reset(hdl);
 291 
 292         uuid_unparse(sess_id, sess_id_str);
 293 
 294         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 295 
 296         /* keep_snaps == UINT32_MAX means "not defined" */
 297         if (keep_snaps != UINT32_MAX) {
 298                 (void) krrp_param_put(KRRP_PARAM_STREAM_KEEP_SNAPS,
 299                     params, &keep_snaps);
 300         }
 301 
 302         if (common_snap != NULL) {
 303                 (void) krrp_param_put(KRRP_PARAM_COMMON_SNAPSHOT,
 304                     params, (void *)common_snap);
 305         }
 306 
 307         if (resume_token != NULL) {
 308                 (void) krrp_param_put(KRRP_PARAM_RESUME_TOKEN,
 309                     params, (void *)resume_token);
 310         }
 311 
 312         if (krrp_sess_stream_flags & KRRP_STREAM_ZFS_EMBEDDED) {
 313                 (void) krrp_param_put(KRRP_PARAM_STREAM_EMBEDDED_BLOCKS,
 314                     params, NULL);
 315         }
 316 
 317         if (krrp_sess_stream_flags & KRRP_STREAM_ZFS_COMPRESSED) {
 318                 (void) krrp_param_put(KRRP_PARAM_STREAM_COMPRESSED_BLOCKS,
 319                     params, NULL);
 320         }
 321 
 322         if (krrp_sess_stream_flags & KRRP_STREAM_ZFS_LARGE_BLOCKS) {
 323                 (void) krrp_param_put(KRRP_PARAM_STREAM_LARGE_BLOCKS,
 324                     params, NULL);
 325         }
 326 
 327         if (krrp_sess_stream_flags & KRRP_STREAM_ZFS_CHKSUM) {
 328                 (void) krrp_param_put(KRRP_PARAM_ENABLE_STREAM_CHKSUM,
 329                     params, NULL);
 330         }
 331 }
 332 
 333 int
 334 krrp_sess_create_write_stream(libkrrp_handle_t *hdl, uuid_t sess_id,
 335     const char *dataset, const char *common_snap,
 336     krrp_sess_stream_flags_t krrp_sess_stream_flags, nvlist_t *ignore_props,
 337     nvlist_t *replace_props, const char *resume_token, uint32_t keep_snaps)
 338 {
 339         nvlist_t *replace_props_copy = NULL;
 340         nvlist_t *params = NULL;
 341         int rc;
 342 
 343         libkrrp_reset(hdl);
 344 
 345         if (replace_props != NULL) {
 346                 libzfs_handle_t *libzfs_hdl;
 347                 char errbuf[1024];
 348 
 349                 libzfs_hdl = libzfs_init();
 350                 if (libzfs_hdl == NULL) {
 351                         libkrrp_error_set(&hdl->libkrrp_error,
 352                             LIBKRRP_ERRNO_PROPS, ENOMEM, 0);
 353                         return (-1);
 354                 }
 355 
 356                 replace_props_copy = zfs_valid_proplist(libzfs_hdl,
 357                     ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
 358                     replace_props, B_FALSE, NULL, NULL, "");
 359                 if (replace_props_copy == NULL) {
 360                         libkrrp_error_set(&hdl->libkrrp_error,
 361                             LIBKRRP_ERRNO_PROPS, EINVAL, 0);
 362                         (void) snprintf(errbuf, sizeof (errbuf),
 363                             dgettext(TEXT_DOMAIN, "Failed to validate "
 364                             "ZFS properties: %s"),
 365                             libzfs_error_description(libzfs_hdl));
 366                         libkrrp_set_error_description(hdl, errbuf);
 367                 }
 368 
 369                 libzfs_fini(libzfs_hdl);
 370 
 371                 if (replace_props_copy == NULL)
 372                         return (-1);
 373         }
 374 
 375         params = fnvlist_alloc();
 376 
 377         krrp_sess_create_stream_common(hdl, params, sess_id, common_snap,
 378             krrp_sess_stream_flags, resume_token, keep_snaps);
 379 
 380         (void) krrp_param_put(KRRP_PARAM_DST_DATASET, params,
 381             (void *)dataset);
 382 
 383         if (krrp_sess_stream_flags & KRRP_STREAM_FORCE_RECEIVE)
 384                 (void) krrp_param_put(KRRP_PARAM_FORCE_RECEIVE, params, NULL);
 385 
 386         if (ignore_props != NULL) {
 387                 (void) krrp_param_put(KRRP_PARAM_IGNORE_PROPS_LIST, params,
 388                     ignore_props);
 389         }
 390 
 391         if (replace_props_copy != NULL) {
 392                 (void) krrp_param_put(KRRP_PARAM_REPLACE_PROPS_LIST, params,
 393                     replace_props_copy);
 394                 fnvlist_free(replace_props_copy);
 395         }
 396 
 397         if (krrp_sess_stream_flags & KRRP_STREAM_DISCARD_HEAD) {
 398                 /*
 399                  * Kernel does not yet support this flag
 400                  */
 401                 libkrrp_error_set(&hdl->libkrrp_error,
 402                     LIBKRRP_ERRNO_NOTSUP, 0, 0);
 403                 rc = -1;
 404                 goto out;
 405         }
 406 
 407         if (krrp_sess_stream_flags & KRRP_STREAM_LEAVE_TAIL) {
 408                 (void) krrp_param_put(KRRP_PARAM_STREAM_LEAVE_TAIL,
 409                     params, NULL);
 410         }
 411 
 412         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_CREATE_WRITE_STREAM,
 413             params, NULL);
 414 
 415 out:
 416         fnvlist_free(params);
 417 
 418         return (rc);
 419 }
 420 
 421 int
 422 krrp_sess_create_read_stream(libkrrp_handle_t *hdl, uuid_t sess_id,
 423     const char *dataset, const char *common_snap, const char *src_snap,
 424     uint64_t fake_data_sz, krrp_sess_stream_flags_t krrp_sess_stream_flags,
 425     const char *resume_token, uint32_t keep_snaps,
 426         const char *skip_snaps_mask)
 427 {
 428         nvlist_t *params = NULL;
 429         int rc;
 430 
 431         params = fnvlist_alloc();
 432 
 433         krrp_sess_create_stream_common(hdl, params, sess_id, common_snap,
 434             krrp_sess_stream_flags, resume_token, keep_snaps);
 435 
 436         (void) krrp_param_put(KRRP_PARAM_SRC_DATASET, params, (void *)dataset);
 437 
 438         if (fake_data_sz != 0) {
 439                 (void) krrp_param_put(KRRP_PARAM_FAKE_DATA_SIZE, params,
 440                     &fake_data_sz);
 441         }
 442 
 443         if (src_snap != NULL) {
 444                 (void) krrp_param_put(KRRP_PARAM_SRC_SNAPSHOT, params,
 445                     (void *)src_snap);
 446         }
 447 
 448         if (krrp_sess_stream_flags & KRRP_STREAM_SEND_RECURSIVE)
 449                 (void) krrp_param_put(KRRP_PARAM_SEND_RECURSIVE, params, NULL);
 450 
 451         if (krrp_sess_stream_flags & KRRP_STREAM_SEND_PROPERTIES)
 452                 (void) krrp_param_put(KRRP_PARAM_SEND_PROPERTIES, params, NULL);
 453 
 454         if (krrp_sess_stream_flags & KRRP_STREAM_INCLUDE_ALL_SNAPS) {
 455                 (void) krrp_param_put(KRRP_PARAM_INCLUDE_ALL_SNAPSHOTS,
 456                     params, NULL);
 457         }
 458 
 459         if (skip_snaps_mask != NULL) {
 460                 (void) krrp_param_put(KRRP_PARAM_SKIP_SNAPS_MASK,
 461                     params, (void *)skip_snaps_mask);
 462         }
 463 
 464         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_CREATE_READ_STREAM,
 465             params, NULL);
 466 
 467         fnvlist_free(params);
 468 
 469         return (rc);
 470 }
 471 
 472 int
 473 krrp_sess_run(libkrrp_handle_t *hdl, uuid_t sess_id, boolean_t once)
 474 {
 475         nvlist_t *params = NULL;
 476         int rc;
 477         krrp_sess_id_str_t sess_id_str;
 478 
 479         VERIFY(hdl != NULL);
 480 
 481         libkrrp_reset(hdl);
 482 
 483         uuid_unparse(sess_id, sess_id_str);
 484         params = fnvlist_alloc();
 485 
 486         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 487 
 488         if (once)
 489                 (void) krrp_param_put(KRRP_PARAM_ONLY_ONCE, params, NULL);
 490 
 491         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_RUN, params, NULL);
 492 
 493         fnvlist_free(params);
 494         return (rc);
 495 }
 496 
 497 int
 498 krrp_sess_send_stop(libkrrp_handle_t *hdl, uuid_t sess_id)
 499 {
 500         nvlist_t *params = NULL;
 501         int rc;
 502         krrp_sess_id_str_t sess_id_str;
 503 
 504         VERIFY(hdl != NULL);
 505 
 506         libkrrp_reset(hdl);
 507 
 508         uuid_unparse(sess_id, sess_id_str);
 509         params = fnvlist_alloc();
 510         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 511 
 512         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_SEND_STOP, params, NULL);
 513 
 514         fnvlist_free(params);
 515         return (rc);
 516 }
 517 
 518 int krrp_sess_status(libkrrp_handle_t *hdl, uuid_t sess_id,
 519     libkrrp_sess_status_t *sess_status)
 520 {
 521         nvlist_t *result = NULL;
 522         nvlist_t *params = NULL;
 523         char *res_sess_id_str;
 524         char *res_sess_kstat_id;
 525 
 526         krrp_sess_id_str_t sess_id_str;
 527         int rc = 0;
 528 
 529         VERIFY(hdl != NULL);
 530 
 531         libkrrp_reset(hdl);
 532 
 533         uuid_unparse(sess_id, sess_id_str);
 534         params = fnvlist_alloc();
 535         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 536 
 537         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_STATUS, params, &result);
 538 
 539         if (rc != 0) {
 540                 rc = -1;
 541                 goto fini;
 542         }
 543 
 544         VERIFY0(krrp_param_get(KRRP_PARAM_SESS_ID, result,
 545             &res_sess_id_str));
 546 
 547         if (uuid_parse(res_sess_id_str, sess_status->sess_id) != 0) {
 548                 libkrrp_error_set(&hdl->libkrrp_error,
 549                     LIBKRRP_ERRNO_SESSID, EINVAL, 0);
 550                 rc = -1;
 551                 goto fini;
 552         }
 553 
 554         VERIFY0(krrp_param_get(KRRP_PARAM_SESS_STARTED, result,
 555             &sess_status->sess_started));
 556 
 557         VERIFY0(krrp_param_get(KRRP_PARAM_SESS_RUNNING, result,
 558             &sess_status->sess_running));
 559 
 560         if (krrp_param_exists(KRRP_PARAM_SESS_SENDER, result))
 561                 sess_status->sess_type = LIBKRRP_SESS_TYPE_SENDER;
 562         else if (krrp_param_exists(KRRP_PARAM_SESS_COMPOUND, result))
 563                 sess_status->sess_type = LIBKRRP_SESS_TYPE_COMPOUND;
 564         else
 565                 sess_status->sess_type = LIBKRRP_SESS_TYPE_RECEIVER;
 566 
 567         VERIFY0(krrp_param_get(KRRP_PARAM_SESS_KSTAT_ID, result,
 568             &res_sess_kstat_id));
 569 
 570         (void) strlcpy(sess_status->sess_kstat_id, res_sess_kstat_id,
 571             KRRP_KSTAT_ID_STRING_LENGTH);
 572 
 573         if (krrp_param_exists(KRRP_PARAM_ERROR_CODE, result)) {
 574                 rc = libkrrp_error_from_nvl(result,
 575                     &sess_status->libkrrp_error);
 576                 ASSERT0(rc);
 577         } else {
 578                 sess_status->libkrrp_error.libkrrp_errno = 0;
 579         }
 580 
 581 fini:
 582         fnvlist_free(params);
 583 
 584         if (result != NULL)
 585                 fnvlist_free(result);
 586 
 587         return (rc);
 588 }
 589 
 590 int
 591 krrp_sess_get_conn_info(libkrrp_handle_t *hdl, uuid_t sess_id,
 592     libkrrp_sess_conn_info_t *sess_conn_info)
 593 {
 594         nvlist_t *result = NULL;
 595         nvlist_t *params = NULL;
 596         krrp_sess_id_str_t sess_id_str;
 597         int rc = 0;
 598 
 599         VERIFY(hdl != NULL);
 600         VERIFY(sess_conn_info != NULL);
 601 
 602         libkrrp_reset(hdl);
 603 
 604         uuid_unparse(sess_id, sess_id_str);
 605         params = fnvlist_alloc();
 606         (void) krrp_param_put(KRRP_PARAM_SESS_ID, params, sess_id_str);
 607 
 608         rc = krrp_ioctl_perform(hdl, KRRP_IOCTL_SESS_GET_CONN_INFO, params, &result);
 609         if (rc != 0)
 610                 goto fini;
 611 
 612         VERIFY0(krrp_param_get(KRRP_PARAM_DBLK_DATA_SIZE, result,
 613             &sess_conn_info->blk_sz));
 614 
 615 fini:
 616         fnvlist_free(params);
 617 
 618         fnvlist_free(result);
 619 
 620         return (rc);
 621 }