Print this page
    
1845 allow disable of UNMAP via stmfadm(1M).
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libstmf/common/stmf.c
          +++ new/usr/src/lib/libstmf/common/stmf.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
  24   24  
  25   25  #include <stdlib.h>
  26   26  #include <stdio.h>
  27   27  #include <wchar.h>
  28   28  #include <strings.h>
  29   29  #include <sys/types.h>
  30   30  #include <sys/stat.h>
  31   31  #include <fcntl.h>
  32   32  #include <unistd.h>
  33   33  #include <libintl.h>
  34   34  #include <errno.h>
  35   35  #include <string.h>
  36   36  #include <assert.h>
  37   37  #include <libnvpair.h>
  38   38  #include <pthread.h>
  39   39  #include <syslog.h>
  40   40  #include <libstmf.h>
  41   41  #include <netinet/in.h>
  42   42  #include <inttypes.h>
  43   43  #include <store.h>
  44   44  #include <locale.h>
  45   45  #include <math.h>
  46   46  #include <libstmf_impl.h>
  47   47  #include <sys/stmf_ioctl.h>
  48   48  #include <sys/stmf_sbd_ioctl.h>
  49   49  #include <sys/pppt_ioctl.h>
  50   50  #include <macros.h>
  51   51  
  52   52  #define STMF_PATH    "/devices/pseudo/stmf@0:admin"
  53   53  #define SBD_PATH    "/devices/pseudo/stmf_sbd@0:admin"
  54   54  #define PPPT_PATH    "/devices/pseudo/pppt@0:pppt"
  55   55  
  56   56  #define EUI "eui."
  57   57  #define WWN "wwn."
  58   58  #define IQN "iqn."
  59   59  #define LU_ASCII_GUID_SIZE 32
  60   60  #define LU_GUID_SIZE 16
  61   61  #define OUI_ASCII_SIZE 6
  62   62  #define HOST_ID_ASCII_SIZE 8
  63   63  #define OUI_SIZE 3
  64   64  #define HOST_ID_SIZE 4
  65   65  #define IDENT_LENGTH_BYTE 3
  66   66  
  67   67  /* various initial allocation values */
  68   68  #define ALLOC_LU                8192
  69   69  #define ALLOC_TARGET_PORT       2048
  70   70  #define ALLOC_PROVIDER          64
  71   71  #define ALLOC_GROUP             2048
  72   72  #define ALLOC_SESSION           2048
  73   73  #define ALLOC_VE                256
  74   74  #define ALLOC_PP_DATA_SIZE      128*1024
  75   75  #define ALLOC_GRP_MEMBER        256
  76   76  
  77   77  #define MAX_ISCSI_NAME  223
  78   78  #define MAX_SERIAL_SIZE 252 + 1
  79   79  #define MAX_LU_ALIAS_SIZE 256
  80   80  #define MAX_SBD_PROPS   MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE
  81   81  
  82   82  #define OPEN_STMF 0
  83   83  #define OPEN_EXCL_STMF O_EXCL
  84   84  
  85   85  #define OPEN_SBD 0
  86   86  #define OPEN_EXCL_SBD O_EXCL
  87   87  
  88   88  #define OPEN_PPPT 0
  89   89  #define OPEN_EXCL_PPPT O_EXCL
  90   90  
  91   91  #define LOGICAL_UNIT_TYPE 0
  92   92  #define TARGET_TYPE 1
  93   93  #define STMF_SERVICE_TYPE 2
  94   94  
  95   95  #define HOST_GROUP   1
  96   96  #define TARGET_GROUP 2
  97   97  
  98   98  /* set default persistence here */
  99   99  #define STMF_DEFAULT_PERSIST    STMF_PERSIST_SMF
 100  100  
 101  101  #define MAX_PROVIDER_RETRY 30
 102  102  
 103  103  static int openStmf(int, int *fd);
 104  104  static int openSbd(int, int *fd);
 105  105  static int openPppt(int, int *fd);
 106  106  static int groupIoctl(int fd, int cmd, stmfGroupName *);
 107  107  static int loadStore(int fd);
 108  108  static int initializeConfig();
 109  109  static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
 110  110  static int guidCompare(const void *, const void *);
 111  111  static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
 112  112  static int loadHostGroups(int fd, stmfGroupList *);
 113  113  static int loadTargetGroups(int fd, stmfGroupList *);
 114  114  static int getStmfState(stmf_state_desc_t *);
 115  115  static int setStmfState(int fd, stmf_state_desc_t *, int);
 116  116  static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *);
 117  117  static int createDiskResource(luResourceImpl *);
 118  118  static int createDiskLu(diskResource *, stmfGuid *);
 119  119  static int deleteDiskLu(stmfGuid *luGuid);
 120  120  static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *);
 121  121  static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl);
 122  122  static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *);
 123  123  static int removeGuidFromDiskStore(stmfGuid *);
 124  124  static int addGuidToDiskStore(stmfGuid *, char *);
 125  125  static int persistDiskGuid(stmfGuid *, char *, boolean_t);
 126  126  static int setDiskProp(luResourceImpl *, uint32_t, const char *);
 127  127  static int getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen);
 128  128  static int checkHexUpper(char *);
 129  129  static int strToShift(const char *);
 130  130  static int niceStrToNum(const char *, uint64_t *);
 131  131  static void diskError(uint32_t, int *);
 132  132  static int importDiskLu(char *fname, stmfGuid *);
 133  133  static int modifyDiskLu(diskResource *, stmfGuid *, const char *);
 134  134  static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *);
 135  135  static int validateModifyDiskProp(uint32_t);
 136  136  static uint8_t iGetPersistMethod();
 137  137  static int groupListIoctl(stmfGroupList **, int);
 138  138  static int iLoadGroupFromPs(stmfGroupList **, int);
 139  139  static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
 140  140  static int getProviderData(char *, nvlist_t **, int, uint64_t *);
 141  141  static int setDiskStandby(stmfGuid *luGuid);
 142  142  static int setDiskGlobalProp(uint32_t, const char *);
 143  143  static int viewEntryCompare(const void *, const void *);
 144  144  static void deleteNonActiveLus();
 145  145  static int loadStmfProp(int fd);
 146  146  
 147  147  static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER;
 148  148  static int iPersistType = 0;
 149  149  /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */
 150  150  static boolean_t iLibSetPersist = B_FALSE;
 151  151  
 152  152  /*
 153  153   * Open for stmf module
 154  154   *
 155  155   * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
 156  156   * fd - pointer to integer. On success, contains the stmf file descriptor
 157  157   */
 158  158  static int
 159  159  openStmf(int flag, int *fd)
 160  160  {
 161  161          int ret = STMF_STATUS_ERROR;
 162  162  
 163  163          if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
 164  164                  ret = STMF_STATUS_SUCCESS;
 165  165          } else {
 166  166                  if (errno == EBUSY) {
 167  167                          ret = STMF_ERROR_BUSY;
 168  168                  } else if (errno == EACCES) {
 169  169                          ret = STMF_ERROR_PERM;
 170  170                  } else {
 171  171                          ret = STMF_STATUS_ERROR;
 172  172                  }
 173  173                  syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
 174  174                      STMF_PATH, errno);
 175  175          }
 176  176  
 177  177          return (ret);
 178  178  }
 179  179  
 180  180  /*
 181  181   * Open for sbd module
 182  182   *
 183  183   * flag - open flag (OPEN_SBD, OPEN_EXCL_SBD)
 184  184   * fd - pointer to integer. On success, contains the stmf file descriptor
 185  185   */
 186  186  static int
 187  187  openSbd(int flag, int *fd)
 188  188  {
 189  189          int ret = STMF_STATUS_ERROR;
 190  190  
 191  191          if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
 192  192                  ret = STMF_STATUS_SUCCESS;
 193  193          } else {
 194  194                  if (errno == EBUSY) {
 195  195                          ret = STMF_ERROR_BUSY;
 196  196                  } else if (errno == EACCES) {
 197  197                          ret = STMF_ERROR_PERM;
 198  198                  } else {
 199  199                          ret = STMF_STATUS_ERROR;
 200  200                  }
 201  201                  syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)",
 202  202                      SBD_PATH, errno);
 203  203          }
 204  204  
 205  205          return (ret);
 206  206  }
 207  207  
 208  208  /*
 209  209   * Open for pppt module
 210  210   *
 211  211   * flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT)
 212  212   * fd - pointer to integer. On success, contains the stmf file descriptor
 213  213   */
 214  214  static int
 215  215  openPppt(int flag, int *fd)
 216  216  {
 217  217          int ret = STMF_STATUS_ERROR;
 218  218  
 219  219          if ((*fd = open(PPPT_PATH, O_RDONLY | flag)) != -1) {
 220  220                  ret = STMF_STATUS_SUCCESS;
 221  221          } else {
 222  222                  if (errno == EBUSY) {
 223  223                          ret = STMF_ERROR_BUSY;
 224  224                  } else if (errno == EACCES) {
 225  225                          ret = STMF_ERROR_PERM;
 226  226                  } else {
 227  227                          ret = STMF_STATUS_ERROR;
 228  228                  }
 229  229                  syslog(LOG_DEBUG, "openPppt:open failure:%s:errno(%d)",
 230  230                      PPPT_PATH, errno);
 231  231          }
 232  232  
 233  233          return (ret);
 234  234  }
 235  235  
 236  236  /*
 237  237   * initializeConfig
 238  238   *
 239  239   * This routine should be called before any ioctl requiring initialization
 240  240   * which is basically everything except stmfGetState(), setStmfState() and
 241  241   * stmfLoadConfig().
 242  242   */
 243  243  static int
 244  244  initializeConfig()
 245  245  {
 246  246          int ret;
 247  247          stmfState state;
 248  248  
 249  249  
 250  250          ret = stmfGetState(&state);
 251  251          if (ret != STMF_STATUS_SUCCESS) {
 252  252                  return (ret);
 253  253          }
 254  254  
 255  255          /* if we've already initialized or in the process, return success */
 256  256          if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
 257  257              state.configState == STMF_CONFIG_STATE_INIT) {
 258  258                  return (STMF_STATUS_SUCCESS);
 259  259          }
 260  260  
 261  261          ret = stmfLoadConfig();
 262  262          if (ret != STMF_STATUS_SUCCESS) {
 263  263                  syslog(LOG_DEBUG,
 264  264                      "initializeConfig:stmfLoadConfig:error(%d)", ret);
 265  265                  return (ret);
 266  266          }
 267  267  
 268  268          ret = stmfGetState(&state);
 269  269          if (ret != STMF_STATUS_SUCCESS) {
 270  270                  syslog(LOG_DEBUG,
 271  271                      "initializeConfig:stmfGetState:error(%d)", ret);
 272  272                  return (ret);
 273  273          }
 274  274  
 275  275          if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
 276  276                  syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
 277  277                      state.configState);
 278  278                  ret = STMF_STATUS_ERROR;
 279  279          }
 280  280  
 281  281          return (ret);
 282  282  }
 283  283  
 284  284  
 285  285  /*
 286  286   * groupIoctl
 287  287   *
 288  288   * Purpose: issue ioctl for create/delete on group
 289  289   *
 290  290   * cmd - valid STMF ioctl group cmd
 291  291   * groupName - groupName to create or delete
 292  292   */
 293  293  static int
 294  294  groupIoctl(int fd, int cmd, stmfGroupName *groupName)
 295  295  {
 296  296          int ret = STMF_STATUS_SUCCESS;
 297  297          int ioctlRet;
 298  298          stmf_iocdata_t stmfIoctl;
 299  299          stmf_group_name_t iGroupName;
 300  300  
 301  301          bzero(&iGroupName, sizeof (iGroupName));
 302  302  
 303  303          bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
 304  304  
 305  305          iGroupName.name_size = strlen((char *)groupName);
 306  306  
 307  307          bzero(&stmfIoctl, sizeof (stmfIoctl));
 308  308          /*
 309  309           * Issue ioctl to create the host group
 310  310           */
 311  311          stmfIoctl.stmf_version = STMF_VERSION_1;
 312  312          stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
 313  313          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
 314  314          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
 315  315          if (ioctlRet != 0) {
 316  316                  switch (errno) {
 317  317                          case EPERM:
 318  318                          case EACCES:
 319  319                                  ret = STMF_ERROR_PERM;
 320  320                                  break;
 321  321                          default:
 322  322                                  switch (stmfIoctl.stmf_error) {
 323  323                                          case STMF_IOCERR_TG_EXISTS:
 324  324                                          case STMF_IOCERR_HG_EXISTS:
 325  325                                                  ret = STMF_ERROR_EXISTS;
 326  326                                                  break;
 327  327                                          case STMF_IOCERR_TG_IN_USE:
 328  328                                          case STMF_IOCERR_HG_IN_USE:
 329  329                                                  ret = STMF_ERROR_GROUP_IN_USE;
 330  330                                                  break;
 331  331                                          case STMF_IOCERR_INVALID_HG:
 332  332                                          case STMF_IOCERR_INVALID_TG:
 333  333                                                  ret = STMF_ERROR_NOT_FOUND;
 334  334                                                  break;
 335  335                                          default:
 336  336                                                  syslog(LOG_DEBUG,
 337  337                                                      "groupIoctl:error(%d)",
 338  338                                                      stmfIoctl.stmf_error);
 339  339                                                  ret = STMF_STATUS_ERROR;
 340  340                                                  break;
 341  341                                  }
 342  342                                  break;
 343  343                  }
 344  344          }
 345  345  done:
 346  346          return (ret);
 347  347  }
 348  348  
 349  349  /*
 350  350   * groupMemberIoctl
 351  351   *
 352  352   * Purpose: issue ioctl for add/remove member on group
 353  353   *
 354  354   * cmd - valid STMF ioctl group member cmd
 355  355   * groupName - groupName to add to or remove from
 356  356   * devid - group member to add or remove
 357  357   */
 358  358  static int
 359  359  groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
 360  360  {
 361  361          int ret = STMF_STATUS_SUCCESS;
 362  362          int ioctlRet;
 363  363          stmf_iocdata_t stmfIoctl;
 364  364          stmf_group_op_data_t stmfGroupData;
 365  365  
 366  366          bzero(&stmfGroupData, sizeof (stmfGroupData));
 367  367  
 368  368          bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
 369  369  
 370  370          stmfGroupData.group.name_size = strlen((char *)groupName);
 371  371          stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
 372  372          bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
 373  373              devid->identLength);
 374  374  
 375  375          bzero(&stmfIoctl, sizeof (stmfIoctl));
 376  376          /*
 377  377           * Issue ioctl to add to the host group
 378  378           */
 379  379          stmfIoctl.stmf_version = STMF_VERSION_1;
 380  380          stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
 381  381          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
 382  382          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
 383  383          if (ioctlRet != 0) {
 384  384                  switch (errno) {
 385  385                          case EBUSY:
 386  386                                  switch (stmfIoctl.stmf_error) {
 387  387                                          case STMF_IOCERR_TG_NEED_TG_OFFLINE:
 388  388                                                  ret = STMF_ERROR_TG_ONLINE;
 389  389                                                  break;
 390  390                                          default:
 391  391                                                  ret = STMF_ERROR_BUSY;
 392  392                                                  break;
 393  393                                  }
 394  394                                  break;
 395  395                          case EPERM:
 396  396                          case EACCES:
 397  397                                  ret = STMF_ERROR_PERM;
 398  398                                  break;
 399  399                          default:
 400  400                                  switch (stmfIoctl.stmf_error) {
 401  401                                          case STMF_IOCERR_TG_ENTRY_EXISTS:
 402  402                                          case STMF_IOCERR_HG_ENTRY_EXISTS:
 403  403                                                  ret = STMF_ERROR_EXISTS;
 404  404                                                  break;
 405  405                                          case STMF_IOCERR_INVALID_TG_ENTRY:
 406  406                                          case STMF_IOCERR_INVALID_HG_ENTRY:
 407  407                                                  ret =
 408  408                                                      STMF_ERROR_MEMBER_NOT_FOUND;
 409  409                                                  break;
 410  410                                          case STMF_IOCERR_INVALID_TG:
 411  411                                          case STMF_IOCERR_INVALID_HG:
 412  412                                                  ret =
 413  413                                                      STMF_ERROR_GROUP_NOT_FOUND;
 414  414                                                  break;
 415  415                                          default:
 416  416                                                  syslog(LOG_DEBUG,
 417  417                                                      "groupMemberIoctl:error"
 418  418                                                      "(%d)",
 419  419                                                      stmfIoctl.stmf_error);
 420  420                                                  ret = STMF_STATUS_ERROR;
 421  421                                                  break;
 422  422                                  }
 423  423                                  break;
 424  424                  }
 425  425          }
 426  426  done:
 427  427          return (ret);
 428  428  }
 429  429  
 430  430  /*
 431  431   * qsort function
 432  432   * sort on veIndex
 433  433   */
 434  434  static int
 435  435  viewEntryCompare(const void *p1, const void *p2)
 436  436  {
 437  437  
 438  438          stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
 439  439          if (v1->veIndex > v2->veIndex)
 440  440                  return (1);
 441  441          if (v1->veIndex < v2->veIndex)
 442  442                  return (-1);
 443  443          return (0);
 444  444  }
 445  445  
 446  446  /*
 447  447   * guidCompare
 448  448   *
 449  449   * qsort function
 450  450   * sort on guid
 451  451   */
 452  452  static int
 453  453  guidCompare(const void *p1, const void *p2)
 454  454  {
 455  455  
 456  456          stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
 457  457          int i;
 458  458  
 459  459          for (i = 0; i < sizeof (stmfGuid); i++) {
 460  460                  if (g1->guid[i] > g2->guid[i])
 461  461                          return (1);
 462  462                  if (g1->guid[i] < g2->guid[i])
 463  463                          return (-1);
 464  464          }
 465  465  
 466  466          return (0);
 467  467  }
 468  468  
 469  469  /*
 470  470   * stmfAddToHostGroup
 471  471   *
 472  472   * Purpose: Adds an initiator to an existing host group
 473  473   *
 474  474   * hostGroupName - name of an existing host group
 475  475   * hostName - name of initiator to add
 476  476   */
 477  477  int
 478  478  stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
 479  479  {
 480  480          int ret;
 481  481          int fd;
 482  482  
 483  483          if (hostGroupName == NULL ||
 484  484              (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
 485  485              == sizeof (stmfGroupName)) || hostName == NULL) {
 486  486                  return (STMF_ERROR_INVALID_ARG);
 487  487          }
 488  488  
 489  489          /* call init */
 490  490          ret = initializeConfig();
 491  491          if (ret != STMF_STATUS_SUCCESS) {
 492  492                  return (ret);
 493  493          }
 494  494  
 495  495          /*
 496  496           * Open control node for stmf
 497  497           */
 498  498          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
 499  499                  return (ret);
 500  500  
 501  501          if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
 502  502              hostName)) != STMF_STATUS_SUCCESS) {
 503  503                  goto done;
 504  504          }
 505  505  
 506  506          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
 507  507                  goto done;
 508  508          }
 509  509  
 510  510          ret = psAddHostGroupMember((char *)hostGroupName,
 511  511              (char *)hostName->ident);
 512  512          switch (ret) {
 513  513                  case STMF_PS_SUCCESS:
 514  514                          ret = STMF_STATUS_SUCCESS;
 515  515                          break;
 516  516                  case STMF_PS_ERROR_EXISTS:
 517  517                          ret = STMF_ERROR_EXISTS;
 518  518                          break;
 519  519                  case STMF_PS_ERROR_GROUP_NOT_FOUND:
 520  520                          ret = STMF_ERROR_GROUP_NOT_FOUND;
 521  521                          break;
 522  522                  case STMF_PS_ERROR_BUSY:
 523  523                          ret = STMF_ERROR_BUSY;
 524  524                          break;
 525  525                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
 526  526                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
 527  527                          break;
 528  528                  case STMF_PS_ERROR_VERSION_MISMATCH:
 529  529                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
 530  530                          break;
 531  531                  default:
 532  532                          syslog(LOG_DEBUG,
 533  533                              "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
 534  534                              ret);
 535  535                          ret = STMF_STATUS_ERROR;
 536  536                          break;
 537  537          }
 538  538  
 539  539  done:
 540  540          (void) close(fd);
 541  541          return (ret);
 542  542  }
 543  543  
 544  544  /*
 545  545   * stmfAddToTargetGroup
 546  546   *
 547  547   * Purpose: Adds a local port to an existing target group
 548  548   *
 549  549   * targetGroupName - name of an existing target group
 550  550   * targetName - name of target to add
 551  551   */
 552  552  int
 553  553  stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
 554  554  {
 555  555          int ret;
 556  556          int fd;
 557  557  
 558  558          if (targetGroupName == NULL ||
 559  559              (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
 560  560              == sizeof (stmfGroupName)) || targetName == NULL) {
 561  561                  return (STMF_ERROR_INVALID_ARG);
 562  562          }
 563  563  
 564  564          /* call init */
 565  565          ret = initializeConfig();
 566  566          if (ret != STMF_STATUS_SUCCESS) {
 567  567                  return (ret);
 568  568          }
 569  569  
 570  570          /*
 571  571           * Open control node for stmf
 572  572           */
 573  573          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
 574  574                  return (ret);
 575  575  
 576  576          if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
 577  577              targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
 578  578                  goto done;
 579  579          }
 580  580  
 581  581          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
 582  582                  goto done;
 583  583          }
 584  584  
 585  585          ret = psAddTargetGroupMember((char *)targetGroupName,
 586  586              (char *)targetName->ident);
 587  587          switch (ret) {
 588  588                  case STMF_PS_SUCCESS:
 589  589                          ret = STMF_STATUS_SUCCESS;
 590  590                          break;
 591  591                  case STMF_PS_ERROR_EXISTS:
 592  592                          ret = STMF_ERROR_EXISTS;
 593  593                          break;
 594  594                  case STMF_PS_ERROR_GROUP_NOT_FOUND:
 595  595                          ret = STMF_ERROR_GROUP_NOT_FOUND;
 596  596                          break;
 597  597                  case STMF_PS_ERROR_BUSY:
 598  598                          ret = STMF_ERROR_BUSY;
 599  599                          break;
 600  600                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
 601  601                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
 602  602                          break;
 603  603                  case STMF_PS_ERROR_VERSION_MISMATCH:
 604  604                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
 605  605                          break;
 606  606                  default:
 607  607                          syslog(LOG_DEBUG,
 608  608                              "stmfAddToTargetGroup:psAddTargetGroupMember:"
 609  609                              "error(%d)", ret);
 610  610                          ret = STMF_STATUS_ERROR;
 611  611                          break;
 612  612          }
 613  613  
 614  614  done:
 615  615          (void) close(fd);
 616  616          return (ret);
 617  617  }
 618  618  
 619  619  /*
 620  620   * addViewEntryIoctl
 621  621   *
 622  622   * Purpose: Issues ioctl to add a view entry
 623  623   *
 624  624   * lu - Logical Unit identifier to which the view entry is added
 625  625   * viewEntry - view entry to add
 626  626   * init - When set to B_TRUE, we are in the init state, i.e. don't call open
 627  627   */
 628  628  static int
 629  629  addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
 630  630  {
 631  631          int ret = STMF_STATUS_SUCCESS;
 632  632          int ioctlRet;
 633  633          stmf_iocdata_t stmfIoctl;
 634  634          stmf_view_op_entry_t ioctlViewEntry;
 635  635  
 636  636          bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
 637  637          /*
 638  638           * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
 639  639           * false on input
 640  640           */
 641  641          ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
 642  642          ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
 643  643          ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
 644  644  
 645  645          if (viewEntry->allHosts == B_FALSE) {
 646  646                  bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
 647  647                      sizeof (stmfGroupName));
 648  648                  ioctlViewEntry.ve_host_group.name_size =
 649  649                      strlen((char *)viewEntry->hostGroup);
 650  650          }
 651  651          if (viewEntry->allTargets == B_FALSE) {
 652  652                  bcopy(viewEntry->targetGroup,
 653  653                      &ioctlViewEntry.ve_target_group.name,
 654  654                      sizeof (stmfGroupName));
 655  655                  ioctlViewEntry.ve_target_group.name_size =
 656  656                      strlen((char *)viewEntry->targetGroup);
 657  657          }
 658  658          if (viewEntry->luNbrValid) {
 659  659                  bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
 660  660                      sizeof (ioctlViewEntry.ve_lu_nbr));
 661  661          }
 662  662          bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
 663  663  
 664  664          bzero(&stmfIoctl, sizeof (stmfIoctl));
 665  665          /*
 666  666           * Issue ioctl to add to the view entry
 667  667           */
 668  668          stmfIoctl.stmf_version = STMF_VERSION_1;
 669  669          stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
 670  670          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
 671  671          stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
 672  672          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
 673  673          ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
 674  674          if (ioctlRet != 0) {
 675  675                  switch (errno) {
 676  676                          case EBUSY:
 677  677                                  ret = STMF_ERROR_BUSY;
 678  678                                  break;
 679  679                          case EPERM:
 680  680                                  ret = STMF_ERROR_PERM;
 681  681                                  break;
 682  682                          case EACCES:
 683  683                                  switch (stmfIoctl.stmf_error) {
 684  684                                          case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
 685  685                                                  ret = STMF_ERROR_CONFIG_NONE;
 686  686                                                  break;
 687  687                                          default:
 688  688                                                  ret = STMF_ERROR_PERM;
 689  689                                                  break;
 690  690                                  }
 691  691                                  break;
 692  692                          default:
 693  693                                  switch (stmfIoctl.stmf_error) {
 694  694                                          case STMF_IOCERR_LU_NUMBER_IN_USE:
 695  695                                                  ret = STMF_ERROR_LUN_IN_USE;
 696  696                                                  break;
 697  697                                          case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
 698  698                                                  ret = STMF_ERROR_VE_CONFLICT;
 699  699                                                  break;
 700  700                                          case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
 701  701                                                  ret = STMF_ERROR_CONFIG_NONE;
 702  702                                                  break;
 703  703                                          case STMF_IOCERR_INVALID_HG:
 704  704                                                  ret = STMF_ERROR_INVALID_HG;
 705  705                                                  break;
 706  706                                          case STMF_IOCERR_INVALID_TG:
 707  707                                                  ret = STMF_ERROR_INVALID_TG;
 708  708                                                  break;
 709  709                                          default:
 710  710                                                  syslog(LOG_DEBUG,
 711  711                                                      "addViewEntryIoctl"
 712  712                                                      ":error(%d)",
 713  713                                                      stmfIoctl.stmf_error);
 714  714                                                  ret = STMF_STATUS_ERROR;
 715  715                                                  break;
 716  716                                  }
 717  717                                  break;
 718  718                  }
 719  719                  goto done;
 720  720          }
 721  721  
 722  722          /* copy lu nbr back to caller's view entry on success */
 723  723          viewEntry->veIndex = ioctlViewEntry.ve_ndx;
 724  724          if (ioctlViewEntry.ve_lu_number_valid) {
 725  725                  bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
 726  726                      sizeof (ioctlViewEntry.ve_lu_nbr));
 727  727          }
 728  728          viewEntry->luNbrValid = B_TRUE;
 729  729  
 730  730  done:
 731  731          return (ret);
 732  732  }
 733  733  
 734  734  /*
 735  735   * stmfAddViewEntry
 736  736   *
 737  737   * Purpose: Adds a view entry to a logical unit
 738  738   *
 739  739   * lu - guid of the logical unit to which the view entry is added
 740  740   * viewEntry - view entry structure to add
 741  741   */
 742  742  int
 743  743  stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
 744  744  {
 745  745          int ret;
 746  746          int fd;
 747  747          stmfViewEntry iViewEntry;
 748  748  
 749  749          if (lu == NULL || viewEntry == NULL) {
 750  750                  return (STMF_ERROR_INVALID_ARG);
 751  751          }
 752  752  
 753  753          /* initialize and set internal view entry */
 754  754          bzero(&iViewEntry, sizeof (iViewEntry));
 755  755  
 756  756          if (!viewEntry->allHosts) {
 757  757                  bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
 758  758                      sizeof (iViewEntry.hostGroup));
 759  759          } else {
 760  760                  iViewEntry.allHosts = B_TRUE;
 761  761          }
 762  762  
 763  763          if (!viewEntry->allTargets) {
 764  764                  bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
 765  765                      sizeof (iViewEntry.targetGroup));
 766  766          } else {
 767  767                  iViewEntry.allTargets = B_TRUE;
 768  768          }
 769  769  
 770  770          if (viewEntry->luNbrValid) {
 771  771                  iViewEntry.luNbrValid = B_TRUE;
 772  772                  bcopy(viewEntry->luNbr, iViewEntry.luNbr,
 773  773                      sizeof (iViewEntry.luNbr));
 774  774          }
 775  775  
 776  776          /*
 777  777           * set users return view entry index valid flag to false
 778  778           * in case of failure
 779  779           */
 780  780          viewEntry->veIndexValid = B_FALSE;
 781  781  
 782  782          /* Check to ensure service exists */
 783  783          if (psCheckService() != STMF_STATUS_SUCCESS) {
 784  784                  return (STMF_ERROR_SERVICE_NOT_FOUND);
 785  785          }
 786  786  
 787  787          /* call init */
 788  788          ret = initializeConfig();
 789  789          if (ret != STMF_STATUS_SUCCESS) {
 790  790                  return (ret);
 791  791          }
 792  792  
 793  793          /*
 794  794           * Open control node for stmf
 795  795           */
 796  796          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
 797  797                  return (ret);
 798  798  
 799  799          /*
 800  800           * First add the view entry to the driver
 801  801           */
 802  802          ret = addViewEntryIoctl(fd, lu, &iViewEntry);
 803  803          if (ret != STMF_STATUS_SUCCESS) {
 804  804                  goto done;
 805  805          }
 806  806  
 807  807          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
 808  808                  goto done;
 809  809          }
 810  810  
 811  811          /*
 812  812           * If the add to driver was successful, add it to the persistent
 813  813           * store.
 814  814           */
 815  815          ret = psAddViewEntry(lu, &iViewEntry);
 816  816          switch (ret) {
 817  817                  case STMF_PS_SUCCESS:
 818  818                          ret = STMF_STATUS_SUCCESS;
 819  819                          break;
 820  820                  case STMF_PS_ERROR_NOT_FOUND:
 821  821                          ret = STMF_ERROR_NOT_FOUND;
 822  822                          break;
 823  823                  case STMF_PS_ERROR_BUSY:
 824  824                          ret = STMF_ERROR_BUSY;
 825  825                          break;
 826  826                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
 827  827                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
 828  828                          break;
 829  829                  case STMF_PS_ERROR_VERSION_MISMATCH:
 830  830                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
 831  831                          break;
 832  832                  default:
 833  833                          syslog(LOG_DEBUG,
 834  834                              "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
 835  835                          ret = STMF_STATUS_ERROR;
 836  836                          break;
 837  837          }
 838  838  
 839  839  done:
 840  840          (void) close(fd);
 841  841  
 842  842          if (ret == STMF_STATUS_SUCCESS) {
 843  843                  /* set caller's view entry on success */
 844  844                  viewEntry->veIndexValid = iViewEntry.veIndexValid;
 845  845                  viewEntry->veIndex = iViewEntry.veIndex;
 846  846                  viewEntry->luNbrValid = B_TRUE;
 847  847                  bcopy(iViewEntry.luNbr, viewEntry->luNbr,
 848  848                      sizeof (iViewEntry.luNbr));
 849  849          }
 850  850          return (ret);
 851  851  }
 852  852  
 853  853  /*
 854  854   * stmfClearProviderData
 855  855   *
 856  856   * Purpose: delete all provider data for specified provider
 857  857   *
 858  858   * providerName - name of provider for which data should be deleted
 859  859   */
 860  860  int
 861  861  stmfClearProviderData(char *providerName, int providerType)
 862  862  {
 863  863          int ret;
 864  864          int fd;
 865  865          int ioctlRet;
 866  866          int savedErrno;
 867  867          stmf_iocdata_t stmfIoctl;
 868  868          stmf_ppioctl_data_t ppi;
 869  869  
 870  870          /* call init */
 871  871          ret = initializeConfig();
 872  872          if (ret != STMF_STATUS_SUCCESS) {
 873  873                  return (ret);
 874  874          }
 875  875  
 876  876          if (providerName == NULL) {
 877  877                  return (STMF_ERROR_INVALID_ARG);
 878  878          }
 879  879  
 880  880          if (providerType != STMF_LU_PROVIDER_TYPE &&
 881  881              providerType != STMF_PORT_PROVIDER_TYPE) {
 882  882                  return (STMF_ERROR_INVALID_ARG);
 883  883          }
 884  884  
 885  885          /*
 886  886           * Open control node for stmf
 887  887           */
 888  888          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
 889  889                  return (ret);
 890  890  
 891  891          bzero(&ppi, sizeof (ppi));
 892  892  
 893  893          (void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
 894  894  
 895  895          switch (providerType) {
 896  896                  case STMF_LU_PROVIDER_TYPE:
 897  897                          ppi.ppi_lu_provider = 1;
 898  898                          break;
 899  899                  case STMF_PORT_PROVIDER_TYPE:
 900  900                          ppi.ppi_port_provider = 1;
 901  901                          break;
 902  902                  default:
 903  903                          ret = STMF_ERROR_INVALID_ARG;
 904  904                          goto done;
 905  905          }
 906  906  
 907  907          bzero(&stmfIoctl, sizeof (stmfIoctl));
 908  908  
 909  909          stmfIoctl.stmf_version = STMF_VERSION_1;
 910  910          stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
 911  911          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
 912  912  
 913  913          ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
 914  914          if (ioctlRet != 0) {
 915  915                  savedErrno = errno;
 916  916                  switch (savedErrno) {
 917  917                          case EBUSY:
 918  918                                  ret = STMF_ERROR_BUSY;
 919  919                                  break;
 920  920                          case EPERM:
 921  921                          case EACCES:
 922  922                                  ret = STMF_ERROR_PERM;
 923  923                                  break;
 924  924                          default:
 925  925                                  syslog(LOG_DEBUG,
 926  926                                      "stmfClearProviderData:ioctl error(%d)",
 927  927                                      ioctlRet);
 928  928                                  ret = STMF_STATUS_ERROR;
 929  929                                  break;
 930  930                  }
 931  931                  if (savedErrno != ENOENT) {
 932  932                          goto done;
 933  933                  }
 934  934          }
 935  935  
 936  936          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
 937  937                  goto done;
 938  938          }
 939  939  
 940  940          ret = psClearProviderData(providerName, providerType);
 941  941          switch (ret) {
 942  942                  case STMF_PS_SUCCESS:
 943  943                          ret = STMF_STATUS_SUCCESS;
 944  944                          break;
 945  945                  case STMF_PS_ERROR_NOT_FOUND:
 946  946                          ret = STMF_ERROR_NOT_FOUND;
 947  947                          break;
 948  948                  case STMF_PS_ERROR_BUSY:
 949  949                          ret = STMF_ERROR_BUSY;
 950  950                          break;
 951  951                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
 952  952                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
 953  953                          break;
 954  954                  case STMF_PS_ERROR_VERSION_MISMATCH:
 955  955                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
 956  956                          break;
 957  957                  default:
 958  958                          syslog(LOG_DEBUG,
 959  959                              "stmfClearProviderData:psClearProviderData"
 960  960                              ":error(%d)", ret);
 961  961                          ret = STMF_STATUS_ERROR;
 962  962                          break;
 963  963          }
 964  964  
 965  965  done:
 966  966          (void) close(fd);
 967  967          return (ret);
 968  968  }
 969  969  
 970  970  /*
 971  971   * stmfCreateHostGroup
 972  972   *
 973  973   * Purpose: Create a new initiator group
 974  974   *
 975  975   * hostGroupName - name of host group to create
 976  976   */
 977  977  int
 978  978  stmfCreateHostGroup(stmfGroupName *hostGroupName)
 979  979  {
 980  980          int ret;
 981  981          int fd;
 982  982  
 983  983          if (hostGroupName == NULL ||
 984  984              (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
 985  985              == sizeof (stmfGroupName))) {
 986  986                  return (STMF_ERROR_INVALID_ARG);
 987  987          }
 988  988  
 989  989          /* Check to ensure service exists */
 990  990          if (psCheckService() != STMF_STATUS_SUCCESS) {
 991  991                  return (STMF_ERROR_SERVICE_NOT_FOUND);
 992  992          }
 993  993  
 994  994          /* call init */
 995  995          ret = initializeConfig();
 996  996          if (ret != STMF_STATUS_SUCCESS) {
 997  997                  return (ret);
 998  998          }
 999  999  
1000 1000          /*
1001 1001           * Open control node for stmf
1002 1002           */
1003 1003          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
1004 1004                  return (ret);
1005 1005  
1006 1006          if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
1007 1007              hostGroupName)) != STMF_STATUS_SUCCESS) {
1008 1008                  goto done;
1009 1009          }
1010 1010  
1011 1011          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
1012 1012                  goto done;
1013 1013          }
1014 1014  
1015 1015          ret = psCreateHostGroup((char *)hostGroupName);
1016 1016          switch (ret) {
1017 1017                  case STMF_PS_SUCCESS:
1018 1018                          ret = STMF_STATUS_SUCCESS;
1019 1019                          break;
1020 1020                  case STMF_PS_ERROR_EXISTS:
1021 1021                          ret = STMF_ERROR_EXISTS;
1022 1022                          break;
1023 1023                  case STMF_PS_ERROR_BUSY:
1024 1024                          ret = STMF_ERROR_BUSY;
1025 1025                          break;
1026 1026                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1027 1027                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
1028 1028                          break;
1029 1029                  case STMF_PS_ERROR_VERSION_MISMATCH:
1030 1030                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
1031 1031                          break;
1032 1032                  default:
1033 1033                          syslog(LOG_DEBUG,
1034 1034                              "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
1035 1035                              ret);
1036 1036                          ret = STMF_STATUS_ERROR;
1037 1037                          break;
1038 1038          }
1039 1039  
1040 1040  done:
1041 1041          (void) close(fd);
1042 1042          return (ret);
1043 1043  }
1044 1044  
1045 1045  /*
1046 1046   * stmfCreateLu
1047 1047   *
1048 1048   * Purpose: Create a logical unit
1049 1049   *
1050 1050   * hdl - handle to logical unit resource created via stmfCreateLuResource
1051 1051   *
1052 1052   * luGuid - If non-NULL, on success, contains the guid of the created logical
1053 1053   *          unit
1054 1054   */
1055 1055  int
1056 1056  stmfCreateLu(luResource hdl, stmfGuid *luGuid)
1057 1057  {
1058 1058          int ret = STMF_STATUS_SUCCESS;
1059 1059          luResourceImpl *luPropsHdl = hdl;
1060 1060  
1061 1061          if (hdl == NULL) {
1062 1062                  return (STMF_ERROR_INVALID_ARG);
1063 1063          }
1064 1064  
1065 1065          if (luPropsHdl->type == STMF_DISK) {
1066 1066                  ret = createDiskLu((diskResource *)luPropsHdl->resource,
1067 1067                      luGuid);
1068 1068          } else {
1069 1069                  return (STMF_ERROR_INVALID_ARG);
1070 1070          }
1071 1071  
1072 1072          return (ret);
1073 1073  }
1074 1074  
1075 1075  /*
1076 1076   * stmfCreateLuResource
1077 1077   *
1078 1078   * Purpose: Create resource handle for a logical unit
1079 1079   *
1080 1080   * dType - Type of logical unit resource to create
1081 1081   *         Can be: STMF_DISK
1082 1082   *
1083 1083   * hdl - pointer to luResource
1084 1084   */
1085 1085  int
1086 1086  stmfCreateLuResource(uint16_t dType, luResource *hdl)
1087 1087  {
1088 1088          int ret = STMF_STATUS_SUCCESS;
1089 1089  
1090 1090          if (dType != STMF_DISK || hdl == NULL) {
1091 1091                  return (STMF_ERROR_INVALID_ARG);
1092 1092          }
1093 1093  
1094 1094          *hdl = calloc(1, sizeof (luResourceImpl));
1095 1095          if (*hdl == NULL) {
1096 1096                  return (STMF_ERROR_NOMEM);
1097 1097          }
1098 1098  
1099 1099          ret = createDiskResource((luResourceImpl *)*hdl);
1100 1100          if (ret != STMF_STATUS_SUCCESS) {
1101 1101                  free(*hdl);
1102 1102                  return (ret);
1103 1103          }
1104 1104  
1105 1105          return (STMF_STATUS_SUCCESS);
1106 1106  }
1107 1107  
1108 1108  /*
1109 1109   * Creates a disk logical unit
1110 1110   *
1111 1111   * disk - pointer to diskResource structure that represents the properties
1112 1112   *        for the disk logical unit to be created.
1113 1113   */
1114 1114  static int
1115 1115  createDiskLu(diskResource *disk, stmfGuid *createdGuid)
1116 1116  {
1117 1117          int ret = STMF_STATUS_SUCCESS;
1118 1118          int dataFileNameLen = 0;
1119 1119          int metaFileNameLen = 0;
1120 1120          int serialNumLen = 0;
1121 1121          int luAliasLen = 0;
1122 1122          int luMgmtUrlLen = 0;
1123 1123          int sluBufSize = 0;
1124 1124          int bufOffset = 0;
1125 1125          int fd = 0;
1126 1126          int ioctlRet;
1127 1127          int savedErrno;
1128 1128          stmfGuid guid;
1129 1129          stmf_iocdata_t sbdIoctl = {0};
1130 1130  
1131 1131          sbd_create_and_reg_lu_t *sbdLu = NULL;
1132 1132  
1133 1133          /*
1134 1134           * Open control node for sbd
1135 1135           */
1136 1136          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1137 1137                  return (ret);
1138 1138  
1139 1139          /* data file name must be specified */
1140 1140          if (disk->luDataFileNameValid) {
1141 1141                  dataFileNameLen = strlen(disk->luDataFileName);
1142 1142          } else {
1143 1143                  (void) close(fd);
1144 1144                  return (STMF_ERROR_MISSING_PROP_VAL);
1145 1145          }
1146 1146  
1147 1147          sluBufSize += dataFileNameLen + 1;
1148 1148  
1149 1149          if (disk->luMetaFileNameValid) {
1150 1150                  metaFileNameLen = strlen(disk->luMetaFileName);
1151 1151                  sluBufSize += metaFileNameLen + 1;
1152 1152          }
1153 1153  
1154 1154          serialNumLen = strlen(disk->serialNum);
1155 1155          sluBufSize += serialNumLen;
1156 1156  
1157 1157          if (disk->luAliasValid) {
1158 1158                  luAliasLen = strlen(disk->luAlias);
1159 1159                  sluBufSize += luAliasLen + 1;
1160 1160          }
1161 1161  
1162 1162          if (disk->luMgmtUrlValid) {
1163 1163                  luMgmtUrlLen = strlen(disk->luMgmtUrl);
1164 1164                  sluBufSize += luMgmtUrlLen + 1;
1165 1165          }
1166 1166  
1167 1167          /*
1168 1168           * 8 is the size of the buffer set aside for
1169 1169           * concatenation of variable length fields
1170 1170           */
1171 1171          sbdLu = (sbd_create_and_reg_lu_t *)calloc(1,
1172 1172              sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8);
1173 1173          if (sbdLu == NULL) {
1174 1174                  return (STMF_ERROR_NOMEM);
1175 1175          }
1176 1176  
1177 1177          sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) +
1178 1178              sluBufSize - 8;
1179 1179  
1180 1180          if (metaFileNameLen) {
1181 1181                  sbdLu->slu_meta_fname_valid = 1;
1182 1182                  sbdLu->slu_meta_fname_off = bufOffset;
1183 1183                  bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]),
1184 1184                      metaFileNameLen + 1);
1185 1185                  bufOffset += metaFileNameLen + 1;
1186 1186          }
1187 1187  
1188 1188          bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]),
1189 1189              dataFileNameLen + 1);
1190 1190          sbdLu->slu_data_fname_off = bufOffset;
1191 1191          bufOffset += dataFileNameLen + 1;
1192 1192  
1193 1193          /* currently, serial # is not passed null terminated to the driver */
1194 1194          if (disk->serialNumValid) {
1195 1195                  sbdLu->slu_serial_valid = 1;
1196 1196                  sbdLu->slu_serial_off = bufOffset;
1197 1197                  sbdLu->slu_serial_size = serialNumLen;
1198 1198                  bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]),
1199 1199                      serialNumLen);
1200 1200                  bufOffset += serialNumLen;
1201 1201          }
1202 1202  
1203 1203          if (disk->luAliasValid) {
1204 1204                  sbdLu->slu_alias_valid = 1;
1205 1205                  sbdLu->slu_alias_off = bufOffset;
1206 1206                  bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]),
1207 1207                      luAliasLen + 1);
1208 1208                  bufOffset += luAliasLen + 1;
1209 1209          }
1210 1210  
1211 1211          if (disk->luMgmtUrlValid) {
1212 1212                  sbdLu->slu_mgmt_url_valid = 1;
1213 1213                  sbdLu->slu_mgmt_url_off = bufOffset;
1214 1214                  bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]),
1215 1215                      luMgmtUrlLen + 1);
1216 1216                  bufOffset += luMgmtUrlLen + 1;
1217 1217          }
1218 1218  
1219 1219          if (disk->luSizeValid) {
1220 1220                  sbdLu->slu_lu_size_valid = 1;
1221 1221                  sbdLu->slu_lu_size = disk->luSize;
1222 1222          }
1223 1223  
1224 1224          if (disk->luGuidValid) {
1225 1225                  sbdLu->slu_guid_valid = 1;
1226 1226                  bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid));
1227 1227          }
1228 1228  
1229 1229          if (disk->vidValid) {
1230 1230                  sbdLu->slu_vid_valid = 1;
1231 1231                  bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid));
1232 1232          }
1233 1233  
1234 1234          if (disk->pidValid) {
1235 1235                  sbdLu->slu_pid_valid = 1;
1236 1236                  bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid));
1237 1237          }
1238 1238  
1239 1239          if (disk->revValid) {
1240 1240                  sbdLu->slu_rev_valid = 1;
1241 1241                  bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev));
1242 1242          }
1243 1243  
1244 1244          if (disk->companyIdValid) {
1245 1245                  sbdLu->slu_company_id_valid = 1;
1246 1246                  sbdLu->slu_company_id = disk->companyId;
1247 1247          }
1248 1248  
1249 1249          if (disk->hostIdValid) {
1250 1250                  sbdLu->slu_host_id_valid = 1;
1251 1251                  sbdLu->slu_host_id = disk->hostId;
1252 1252          }
1253 1253  
1254 1254          if (disk->blkSizeValid) {
  
    | 
      ↓ open down ↓ | 
    1254 lines elided | 
    
      ↑ open up ↑ | 
  
1255 1255                  sbdLu->slu_blksize_valid = 1;
1256 1256                  sbdLu->slu_blksize = disk->blkSize;
1257 1257          }
1258 1258  
1259 1259          if (disk->writeProtectEnableValid) {
1260 1260                  if (disk->writeProtectEnable) {
1261 1261                          sbdLu->slu_write_protected = 1;
1262 1262                  }
1263 1263          }
1264 1264  
     1265 +        if (disk->unmapValid) {
     1266 +                sbdLu->slu_unmap_valid = 1;
     1267 +                if (disk->unmap) {
     1268 +                        sbdLu->slu_unmap = 1;
     1269 +                }
     1270 +        }
     1271 +
1265 1272          if (disk->writebackCacheDisableValid) {
1266 1273                  sbdLu->slu_writeback_cache_disable_valid = 1;
1267 1274                  if (disk->writebackCacheDisable) {
1268 1275                          sbdLu->slu_writeback_cache_disable = 1;
1269 1276                  }
1270 1277          }
1271 1278  
1272 1279          sbdIoctl.stmf_version = STMF_VERSION_1;
1273 1280          sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size;
1274 1281          sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1275 1282          sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size;
1276 1283          sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
1277 1284  
1278 1285          ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl);
1279 1286          if (ioctlRet != 0) {
1280 1287                  savedErrno = errno;
1281 1288                  switch (savedErrno) {
1282 1289                          case EBUSY:
1283 1290                                  ret = STMF_ERROR_BUSY;
1284 1291                                  break;
1285 1292                          case EPERM:
1286 1293                          case EACCES:
1287 1294                                  ret = STMF_ERROR_PERM;
1288 1295                                  break;
1289 1296                          default:
1290 1297                                  diskError(sbdIoctl.stmf_error, &ret);
1291 1298                                  if (ret == STMF_STATUS_ERROR) {
1292 1299                                          syslog(LOG_DEBUG,
1293 1300                                          "createDiskLu:ioctl "
1294 1301                                          "error(%d) (%d) (%d)", ioctlRet,
1295 1302                                              sbdIoctl.stmf_error, savedErrno);
1296 1303                                  }
1297 1304                                  break;
1298 1305                  }
1299 1306          }
1300 1307  
1301 1308          if (ret != STMF_STATUS_SUCCESS) {
1302 1309                  goto done;
1303 1310          }
1304 1311  
1305 1312          /*
1306 1313           * on success, copy the resulting guid into the caller's guid if not
1307 1314           * NULL
1308 1315           */
1309 1316          if (createdGuid) {
1310 1317                  bcopy(sbdLu->slu_guid, createdGuid->guid,
1311 1318                      sizeof (sbdLu->slu_guid));
1312 1319          }
1313 1320  
1314 1321          bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid));
1315 1322          if (disk->luMetaFileNameValid) {
1316 1323                  ret = addGuidToDiskStore(&guid, disk->luMetaFileName);
1317 1324          } else {
1318 1325                  ret = addGuidToDiskStore(&guid, disk->luDataFileName);
1319 1326          }
1320 1327  done:
1321 1328          free(sbdLu);
1322 1329          (void) close(fd);
1323 1330          return (ret);
1324 1331  }
1325 1332  
1326 1333  
1327 1334  /*
1328 1335   * stmfImportLu
1329 1336   *
1330 1337   * Purpose: Import a previously created logical unit
1331 1338   *
1332 1339   * dType - Type of logical unit
1333 1340   *         Can be: STMF_DISK
1334 1341   *
1335 1342   * luGuid - If non-NULL, on success, contains the guid of the imported logical
1336 1343   *          unit
1337 1344   *
1338 1345   * fname - A file name where the metadata resides
1339 1346   *
1340 1347   */
1341 1348  int
1342 1349  stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid)
1343 1350  {
1344 1351          int ret = STMF_STATUS_SUCCESS;
1345 1352  
1346 1353          if (dType == STMF_DISK) {
1347 1354                  ret = importDiskLu(fname, luGuid);
1348 1355          } else {
1349 1356                  return (STMF_ERROR_INVALID_ARG);
1350 1357          }
1351 1358  
1352 1359          return (ret);
1353 1360  }
1354 1361  
1355 1362  /*
1356 1363   * importDiskLu
1357 1364   *
1358 1365   * filename - filename to import
1359 1366   * createdGuid - if not NULL, on success contains the imported guid
1360 1367   *
1361 1368   */
1362 1369  static int
1363 1370  importDiskLu(char *fname, stmfGuid *createdGuid)
1364 1371  {
1365 1372          int ret = STMF_STATUS_SUCCESS;
1366 1373          int fd = 0;
1367 1374          int ioctlRet;
1368 1375          int savedErrno;
1369 1376          int metaFileNameLen;
1370 1377          stmfGuid iGuid;
1371 1378          int iluBufSize = 0;
1372 1379          sbd_import_lu_t *sbdLu = NULL;
1373 1380          stmf_iocdata_t sbdIoctl = {0};
1374 1381  
1375 1382          if (fname == NULL) {
1376 1383                  return (STMF_ERROR_INVALID_ARG);
1377 1384          }
1378 1385  
1379 1386          /*
1380 1387           * Open control node for sbd
1381 1388           */
1382 1389          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1383 1390                  return (ret);
1384 1391  
1385 1392          metaFileNameLen = strlen(fname);
1386 1393          iluBufSize += metaFileNameLen + 1;
1387 1394  
1388 1395          /*
1389 1396           * 8 is the size of the buffer set aside for
1390 1397           * concatenation of variable length fields
1391 1398           */
1392 1399          sbdLu = (sbd_import_lu_t *)calloc(1,
1393 1400              sizeof (sbd_import_lu_t) + iluBufSize - 8);
1394 1401          if (sbdLu == NULL) {
1395 1402                  (void) close(fd);
1396 1403                  return (STMF_ERROR_NOMEM);
1397 1404          }
1398 1405  
1399 1406          /*
1400 1407           * Accept either a data file or meta data file.
1401 1408           * sbd will do the right thing here either way.
1402 1409           * i.e. if it's a data file, it assumes that the
1403 1410           * meta data is shared with the data.
1404 1411           */
1405 1412          (void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen);
1406 1413  
1407 1414          sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8;
1408 1415  
1409 1416          sbdIoctl.stmf_version = STMF_VERSION_1;
1410 1417          sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size;
1411 1418          sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1412 1419          sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size;
1413 1420          sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
1414 1421  
1415 1422          ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl);
1416 1423          if (ioctlRet != 0) {
1417 1424  
1418 1425                  if (createdGuid && sbdIoctl.stmf_error ==
1419 1426                      SBD_RET_FILE_ALREADY_REGISTERED) {
1420 1427                          bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
1421 1428                              sizeof (sbdLu->ilu_ret_guid));
1422 1429                  }
1423 1430  
1424 1431                  savedErrno = errno;
1425 1432                  switch (savedErrno) {
1426 1433                          case EBUSY:
1427 1434                                  ret = STMF_ERROR_BUSY;
1428 1435                                  break;
1429 1436                          case EPERM:
1430 1437                          case EACCES:
1431 1438                                  ret = STMF_ERROR_PERM;
1432 1439                                  break;
1433 1440                          default:
1434 1441                                  diskError(sbdIoctl.stmf_error, &ret);
1435 1442                                  if (ret == STMF_STATUS_ERROR) {
1436 1443                                          syslog(LOG_DEBUG,
1437 1444                                          "importDiskLu:ioctl "
1438 1445                                          "error(%d) (%d) (%d)", ioctlRet,
1439 1446                                              sbdIoctl.stmf_error, savedErrno);
1440 1447                                  }
1441 1448                                  break;
1442 1449                  }
1443 1450          }
1444 1451  
1445 1452  
1446 1453          if (ret != STMF_STATUS_SUCCESS) {
1447 1454                  goto done;
1448 1455          }
1449 1456  
1450 1457          /*
1451 1458           * on success, copy the resulting guid into the caller's guid if not
1452 1459           * NULL and add it to the persistent store for sbd
1453 1460           */
1454 1461          if (createdGuid) {
1455 1462                  bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
1456 1463                      sizeof (sbdLu->ilu_ret_guid));
1457 1464                  ret = addGuidToDiskStore(createdGuid, fname);
1458 1465          } else {
1459 1466                  bcopy(sbdLu->ilu_ret_guid, iGuid.guid,
1460 1467                      sizeof (sbdLu->ilu_ret_guid));
1461 1468                  ret = addGuidToDiskStore(&iGuid, fname);
1462 1469          }
1463 1470  done:
1464 1471          free(sbdLu);
1465 1472          (void) close(fd);
1466 1473          return (ret);
1467 1474  }
1468 1475  
1469 1476  /*
1470 1477   * diskError
1471 1478   *
1472 1479   * Purpose: Translate sbd driver error
1473 1480   */
1474 1481  static void
1475 1482  diskError(uint32_t stmfError, int *ret)
1476 1483  {
1477 1484          switch (stmfError) {
1478 1485                  case SBD_RET_META_CREATION_FAILED:
1479 1486                  case SBD_RET_ZFS_META_CREATE_FAILED:
1480 1487                          *ret = STMF_ERROR_META_CREATION;
1481 1488                          break;
1482 1489                  case SBD_RET_INVALID_BLKSIZE:
1483 1490                          *ret = STMF_ERROR_INVALID_BLKSIZE;
1484 1491                          break;
1485 1492                  case SBD_RET_FILE_ALREADY_REGISTERED:
1486 1493                          *ret = STMF_ERROR_FILE_IN_USE;
1487 1494                          break;
1488 1495                  case SBD_RET_GUID_ALREADY_REGISTERED:
1489 1496                          *ret = STMF_ERROR_GUID_IN_USE;
1490 1497                          break;
1491 1498                  case SBD_RET_META_PATH_NOT_ABSOLUTE:
1492 1499                  case SBD_RET_META_FILE_LOOKUP_FAILED:
1493 1500                  case SBD_RET_META_FILE_OPEN_FAILED:
1494 1501                  case SBD_RET_META_FILE_GETATTR_FAILED:
1495 1502                  case SBD_RET_NO_META:
1496 1503                          *ret = STMF_ERROR_META_FILE_NAME;
1497 1504                          break;
1498 1505                  case SBD_RET_DATA_PATH_NOT_ABSOLUTE:
1499 1506                  case SBD_RET_DATA_FILE_LOOKUP_FAILED:
1500 1507                  case SBD_RET_DATA_FILE_OPEN_FAILED:
1501 1508                  case SBD_RET_DATA_FILE_GETATTR_FAILED:
1502 1509                          *ret = STMF_ERROR_DATA_FILE_NAME;
1503 1510                          break;
1504 1511                  case SBD_RET_FILE_SIZE_ERROR:
1505 1512                          *ret = STMF_ERROR_FILE_SIZE_INVALID;
  
    | 
      ↓ open down ↓ | 
    231 lines elided | 
    
      ↑ open up ↑ | 
  
1506 1513                          break;
1507 1514                  case SBD_RET_SIZE_OUT_OF_RANGE:
1508 1515                          *ret = STMF_ERROR_SIZE_OUT_OF_RANGE;
1509 1516                          break;
1510 1517                  case SBD_RET_LU_BUSY:
1511 1518                          *ret = STMF_ERROR_LU_BUSY;
1512 1519                          break;
1513 1520                  case SBD_RET_WRITE_CACHE_SET_FAILED:
1514 1521                          *ret = STMF_ERROR_WRITE_CACHE_SET;
1515 1522                          break;
     1523 +                case SBD_RET_UNMAP_SET_FAILED:
     1524 +                        *ret = STMF_ERROR_UNMAP_SET;
     1525 +                        break;
1516 1526                  case SBD_RET_ACCESS_STATE_FAILED:
1517 1527                          *ret = STMF_ERROR_ACCESS_STATE_SET;
1518 1528                          break;
1519 1529                  default:
1520 1530                          *ret = STMF_STATUS_ERROR;
1521 1531                          break;
1522 1532          }
1523 1533  }
1524 1534  
1525 1535  /*
1526 1536   * Creates a logical unit resource of type STMF_DISK.
1527 1537   *
1528 1538   * No defaults should be set here as all defaults are derived from the
1529 1539   * driver's default settings.
1530 1540   */
1531 1541  static int
1532 1542  createDiskResource(luResourceImpl *hdl)
1533 1543  {
1534 1544          hdl->type = STMF_DISK;
1535 1545  
1536 1546          hdl->resource = calloc(1, sizeof (diskResource));
1537 1547          if (hdl->resource == NULL) {
1538 1548                  return (STMF_ERROR_NOMEM);
1539 1549          }
1540 1550  
1541 1551          return (STMF_STATUS_SUCCESS);
1542 1552  }
1543 1553  
1544 1554  /*
1545 1555   * stmfDeleteLu
1546 1556   *
1547 1557   * Purpose: Delete a logical unit
1548 1558   *
1549 1559   * hdl - handle to logical unit resource created via stmfCreateLuResource
1550 1560   *
1551 1561   * luGuid - If non-NULL, on success, contains the guid of the created logical
1552 1562   *          unit
1553 1563   */
1554 1564  int
1555 1565  stmfDeleteLu(stmfGuid *luGuid)
1556 1566  {
1557 1567          int ret = STMF_STATUS_SUCCESS;
1558 1568          stmfLogicalUnitProperties luProps;
1559 1569  
1560 1570          if (luGuid == NULL) {
1561 1571                  return (STMF_ERROR_INVALID_ARG);
1562 1572          }
1563 1573  
1564 1574          /* Check logical unit provider name to call correct dtype function */
1565 1575          if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1566 1576              != STMF_STATUS_SUCCESS) {
1567 1577                  return (ret);
1568 1578          } else {
1569 1579                  if (strcmp(luProps.providerName, "sbd") == 0) {
1570 1580                          ret = deleteDiskLu(luGuid);
1571 1581                  } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1572 1582                          return (STMF_ERROR_NOT_FOUND);
1573 1583                  } else {
1574 1584                          return (STMF_ERROR_INVALID_ARG);
1575 1585                  }
1576 1586          }
1577 1587  
1578 1588          return (ret);
1579 1589  }
1580 1590  
1581 1591  static int
1582 1592  deleteDiskLu(stmfGuid *luGuid)
1583 1593  {
1584 1594          int ret = STMF_STATUS_SUCCESS;
1585 1595          int fd;
1586 1596          int savedErrno;
1587 1597          int ioctlRet;
1588 1598          sbd_delete_lu_t deleteLu = {0};
1589 1599  
1590 1600          stmf_iocdata_t sbdIoctl = {0};
1591 1601  
1592 1602          /*
1593 1603           * Open control node for sbd
1594 1604           */
1595 1605          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1596 1606                  return (ret);
1597 1607  
1598 1608          ret = removeGuidFromDiskStore(luGuid);
1599 1609          if (ret != STMF_STATUS_SUCCESS) {
1600 1610                  goto done;
1601 1611          }
1602 1612  
1603 1613          bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid));
1604 1614          deleteLu.dlu_by_guid = 1;
1605 1615  
1606 1616          sbdIoctl.stmf_version = STMF_VERSION_1;
1607 1617          sbdIoctl.stmf_ibuf_size = sizeof (deleteLu);
1608 1618          sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu;
1609 1619          ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl);
1610 1620          if (ioctlRet != 0) {
1611 1621                  savedErrno = errno;
1612 1622                  switch (savedErrno) {
1613 1623                          case EBUSY:
1614 1624                                  ret = STMF_ERROR_BUSY;
1615 1625                                  break;
1616 1626                          case EPERM:
1617 1627                          case EACCES:
1618 1628                                  ret = STMF_ERROR_PERM;
1619 1629                                  break;
1620 1630                          case ENOENT:
1621 1631                                  ret = STMF_ERROR_NOT_FOUND;
1622 1632                                  break;
1623 1633                          default:
1624 1634                                  syslog(LOG_DEBUG,
1625 1635                                      "deleteDiskLu:ioctl error(%d) (%d) (%d)",
1626 1636                                      ioctlRet, sbdIoctl.stmf_error, savedErrno);
1627 1637                                  ret = STMF_STATUS_ERROR;
1628 1638                                  break;
1629 1639                  }
1630 1640          }
1631 1641  
1632 1642  done:
1633 1643          (void) close(fd);
1634 1644          return (ret);
1635 1645  }
1636 1646  
1637 1647  /*
1638 1648   * stmfLuStandby
1639 1649   *
1640 1650   * Purpose: Sets access state to standby
1641 1651   *
1642 1652   * luGuid - guid of registered logical unit
1643 1653   *
1644 1654   */
1645 1655  int
1646 1656  stmfLuStandby(stmfGuid *luGuid)
1647 1657  {
1648 1658          int ret = STMF_STATUS_SUCCESS;
1649 1659          stmfLogicalUnitProperties luProps;
1650 1660  
1651 1661          if (luGuid == NULL) {
1652 1662                  return (STMF_ERROR_INVALID_ARG);
1653 1663          }
1654 1664  
1655 1665          /* Check logical unit provider name to call correct dtype function */
1656 1666          if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1657 1667              != STMF_STATUS_SUCCESS) {
1658 1668                  return (ret);
1659 1669          } else {
1660 1670                  if (strcmp(luProps.providerName, "sbd") == 0) {
1661 1671                          ret = setDiskStandby(luGuid);
1662 1672                  } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1663 1673                          return (STMF_ERROR_NOT_FOUND);
1664 1674                  } else {
1665 1675                          return (STMF_ERROR_INVALID_ARG);
1666 1676                  }
1667 1677          }
1668 1678  
1669 1679          return (ret);
1670 1680  }
1671 1681  
1672 1682  static int
1673 1683  setDiskStandby(stmfGuid *luGuid)
1674 1684  {
1675 1685          int ret = STMF_STATUS_SUCCESS;
1676 1686          stmf_iocdata_t sbdIoctl = {0};
1677 1687          sbd_set_lu_standby_t sbdLu = {0};
1678 1688          int ioctlRet;
1679 1689          int savedErrno;
1680 1690          int fd = 0;
1681 1691  
1682 1692          /*
1683 1693           * Open control node for sbd
1684 1694           */
1685 1695          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1686 1696                  return (ret);
1687 1697  
1688 1698          bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid));
1689 1699  
1690 1700          sbdIoctl.stmf_version = STMF_VERSION_1;
1691 1701          sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t);
1692 1702          sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu;
1693 1703  
1694 1704          ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl);
1695 1705          if (ioctlRet != 0) {
1696 1706                  savedErrno = errno;
1697 1707                  switch (savedErrno) {
1698 1708                          case EBUSY:
1699 1709                                  ret = STMF_ERROR_BUSY;
1700 1710                                  break;
1701 1711                          case EPERM:
1702 1712                          case EACCES:
1703 1713                                  ret = STMF_ERROR_PERM;
1704 1714                                  break;
1705 1715                          default:
1706 1716                                  diskError(sbdIoctl.stmf_error, &ret);
1707 1717                                  if (ret == STMF_STATUS_ERROR) {
1708 1718                                          syslog(LOG_DEBUG,
1709 1719                                          "setDiskStandby:ioctl "
1710 1720                                          "error(%d) (%d) (%d)", ioctlRet,
1711 1721                                              sbdIoctl.stmf_error, savedErrno);
1712 1722                                  }
1713 1723                                  break;
1714 1724                  }
1715 1725          }
1716 1726          (void) close(fd);
1717 1727          return (ret);
1718 1728  }
1719 1729  
1720 1730  /*
1721 1731   * stmfModifyLu
1722 1732   *
1723 1733   * Purpose: Modify properties of a logical unit
1724 1734   *
1725 1735   * luGuid - guid of registered logical unit
1726 1736   * prop - property to modify
1727 1737   * propVal - property value to set
1728 1738   *
1729 1739   */
1730 1740  int
1731 1741  stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal)
1732 1742  {
1733 1743          int ret = STMF_STATUS_SUCCESS;
1734 1744          stmfLogicalUnitProperties luProps;
1735 1745  
1736 1746          if (luGuid == NULL) {
1737 1747                  return (STMF_ERROR_INVALID_ARG);
1738 1748          }
1739 1749  
1740 1750          /* Check logical unit provider name to call correct dtype function */
1741 1751          if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1742 1752              != STMF_STATUS_SUCCESS) {
1743 1753                  return (ret);
1744 1754          } else {
1745 1755                  if (strcmp(luProps.providerName, "sbd") == 0) {
1746 1756                          ret = modifyDiskLuProp(luGuid, NULL, prop, propVal);
1747 1757                  } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1748 1758                          return (STMF_ERROR_NOT_FOUND);
1749 1759                  } else {
1750 1760                          return (STMF_ERROR_INVALID_ARG);
1751 1761                  }
1752 1762          }
1753 1763  
1754 1764          return (ret);
1755 1765  }
1756 1766  
1757 1767  /*
1758 1768   * stmfModifyLuByFname
1759 1769   *
1760 1770   * Purpose: Modify a device by filename. Device does not need to be registered.
1761 1771   *
1762 1772   * dType - type of device to modify
1763 1773   *         STMF_DISK
1764 1774   *
1765 1775   * fname - filename or meta filename
1766 1776   * prop - valid property identifier
1767 1777   * propVal - property value
1768 1778   *
1769 1779   */
1770 1780  int
1771 1781  stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop,
1772 1782      const char *propVal)
1773 1783  {
1774 1784          int ret = STMF_STATUS_SUCCESS;
1775 1785          if (fname == NULL) {
1776 1786                  return (STMF_ERROR_INVALID_ARG);
1777 1787          }
1778 1788  
1779 1789          if (dType == STMF_DISK) {
1780 1790                  ret = modifyDiskLuProp(NULL, fname, prop, propVal);
1781 1791          } else {
1782 1792                  return (STMF_ERROR_INVALID_ARG);
1783 1793          }
1784 1794  
1785 1795          return (ret);
1786 1796  }
1787 1797  
1788 1798  static int
1789 1799  modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop,
1790 1800      const char *propVal)
1791 1801  {
1792 1802          int ret = STMF_STATUS_SUCCESS;
1793 1803          luResource hdl = NULL;
1794 1804          luResourceImpl *luPropsHdl;
1795 1805  
1796 1806          ret = stmfCreateLuResource(STMF_DISK, &hdl);
1797 1807          if (ret != STMF_STATUS_SUCCESS) {
1798 1808                  return (ret);
1799 1809          }
1800 1810          ret = validateModifyDiskProp(prop);
1801 1811          if (ret != STMF_STATUS_SUCCESS) {
1802 1812                  (void) stmfFreeLuResource(hdl);
1803 1813                  return (STMF_ERROR_INVALID_PROP);
1804 1814          }
1805 1815          ret = stmfSetLuProp(hdl, prop, propVal);
1806 1816          if (ret != STMF_STATUS_SUCCESS) {
1807 1817                  (void) stmfFreeLuResource(hdl);
1808 1818                  return (ret);
1809 1819          }
1810 1820          luPropsHdl = hdl;
1811 1821          ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname);
1812 1822          (void) stmfFreeLuResource(hdl);
1813 1823          return (ret);
1814 1824  }
  
    | 
      ↓ open down ↓ | 
    289 lines elided | 
    
      ↑ open up ↑ | 
  
1815 1825  
1816 1826  static int
1817 1827  validateModifyDiskProp(uint32_t prop)
1818 1828  {
1819 1829          switch (prop) {
1820 1830                  case STMF_LU_PROP_ALIAS:
1821 1831                  case STMF_LU_PROP_SIZE:
1822 1832                  case STMF_LU_PROP_MGMT_URL:
1823 1833                  case STMF_LU_PROP_WRITE_PROTECT:
1824 1834                  case STMF_LU_PROP_WRITE_CACHE_DISABLE:
     1835 +                case STMF_LU_PROP_UNMAP:
1825 1836                          return (STMF_STATUS_SUCCESS);
1826 1837                          break;
1827 1838                  default:
1828 1839                          return (STMF_STATUS_ERROR);
1829 1840                          break;
1830 1841          }
1831 1842  }
1832 1843  
1833 1844  static int
1834 1845  modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
1835 1846  {
1836 1847          int ret = STMF_STATUS_SUCCESS;
1837 1848          int luAliasLen = 0;
1838 1849          int luMgmtUrlLen = 0;
1839 1850          int mluBufSize = 0;
1840 1851          int bufOffset = 0;
1841 1852          int fd = 0;
1842 1853          int ioctlRet;
1843 1854          int savedErrno;
1844 1855          int fnameSize = 0;
1845 1856          stmf_iocdata_t sbdIoctl = {0};
1846 1857  
1847 1858          sbd_modify_lu_t *sbdLu = NULL;
1848 1859  
1849 1860          if (luGuid == NULL && fname == NULL) {
1850 1861                  return (STMF_ERROR_INVALID_ARG);
1851 1862          }
1852 1863  
1853 1864          if (fname) {
1854 1865                  fnameSize = strlen(fname) + 1;
1855 1866                  mluBufSize += fnameSize;
1856 1867          }
1857 1868  
1858 1869          /*
1859 1870           * Open control node for sbd
1860 1871           */
1861 1872          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1862 1873                  return (ret);
1863 1874  
1864 1875          if (disk->luAliasValid) {
1865 1876                  luAliasLen = strlen(disk->luAlias);
1866 1877                  mluBufSize += luAliasLen + 1;
1867 1878          }
1868 1879  
1869 1880          if (disk->luMgmtUrlValid) {
1870 1881                  luMgmtUrlLen = strlen(disk->luMgmtUrl);
1871 1882                  mluBufSize += luMgmtUrlLen + 1;
1872 1883          }
1873 1884  
1874 1885          /*
1875 1886           * 8 is the size of the buffer set aside for
1876 1887           * concatenation of variable length fields
1877 1888           */
1878 1889          sbdLu = (sbd_modify_lu_t *)calloc(1,
1879 1890              sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize);
1880 1891          if (sbdLu == NULL) {
1881 1892                  (void) close(fd);
1882 1893                  return (STMF_ERROR_NOMEM);
1883 1894          }
1884 1895  
1885 1896          sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) +
1886 1897              mluBufSize - 8 + fnameSize;
1887 1898  
1888 1899          if (disk->luAliasValid) {
1889 1900                  sbdLu->mlu_alias_valid = 1;
1890 1901                  sbdLu->mlu_alias_off = bufOffset;
1891 1902                  bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]),
1892 1903                      luAliasLen + 1);
1893 1904                  bufOffset += luAliasLen + 1;
1894 1905          }
1895 1906  
1896 1907          if (disk->luMgmtUrlValid) {
1897 1908                  sbdLu->mlu_mgmt_url_valid = 1;
1898 1909                  sbdLu->mlu_mgmt_url_off = bufOffset;
  
    | 
      ↓ open down ↓ | 
    64 lines elided | 
    
      ↑ open up ↑ | 
  
1899 1910                  bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]),
1900 1911                      luMgmtUrlLen + 1);
1901 1912                  bufOffset += luMgmtUrlLen + 1;
1902 1913          }
1903 1914  
1904 1915          if (disk->luSizeValid) {
1905 1916                  sbdLu->mlu_lu_size_valid = 1;
1906 1917                  sbdLu->mlu_lu_size = disk->luSize;
1907 1918          }
1908 1919  
     1920 +        if (disk->unmapValid) {
     1921 +                sbdLu->mlu_unmap_valid = 1;
     1922 +                if (disk->unmap)
     1923 +                        sbdLu->mlu_unmap = 1;
     1924 +        }
     1925 +
1909 1926          if (disk->writeProtectEnableValid) {
1910 1927                  sbdLu->mlu_write_protected_valid = 1;
1911 1928                  if (disk->writeProtectEnable) {
1912 1929                          sbdLu->mlu_write_protected = 1;
1913 1930                  }
1914 1931          }
1915 1932  
1916 1933          if (disk->writebackCacheDisableValid) {
1917 1934                  sbdLu->mlu_writeback_cache_disable_valid = 1;
1918 1935                  if (disk->writebackCacheDisable) {
1919 1936                          sbdLu->mlu_writeback_cache_disable = 1;
1920 1937                  }
1921 1938          }
1922 1939  
1923 1940          if (luGuid) {
1924 1941                  bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid));
1925 1942                  sbdLu->mlu_by_guid = 1;
1926 1943          } else {
1927 1944                  sbdLu->mlu_fname_off = bufOffset;
1928 1945                  bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1);
1929 1946                  sbdLu->mlu_by_fname = 1;
1930 1947          }
1931 1948  
1932 1949          sbdIoctl.stmf_version = STMF_VERSION_1;
1933 1950          sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size;
1934 1951          sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1935 1952  
1936 1953          ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl);
1937 1954          if (ioctlRet != 0) {
1938 1955                  savedErrno = errno;
1939 1956                  switch (savedErrno) {
1940 1957                          case EBUSY:
1941 1958                                  ret = STMF_ERROR_BUSY;
1942 1959                                  break;
1943 1960                          case EPERM:
1944 1961                          case EACCES:
1945 1962                                  ret = STMF_ERROR_PERM;
1946 1963                                  break;
1947 1964                          default:
1948 1965                                  diskError(sbdIoctl.stmf_error, &ret);
1949 1966                                  if (ret == STMF_STATUS_ERROR) {
1950 1967                                          syslog(LOG_DEBUG,
1951 1968                                          "modifyDiskLu:ioctl "
1952 1969                                          "error(%d) (%d) (%d)", ioctlRet,
1953 1970                                              sbdIoctl.stmf_error, savedErrno);
1954 1971                                  }
1955 1972                                  break;
1956 1973                  }
1957 1974          }
1958 1975  
1959 1976          if (ret != STMF_STATUS_SUCCESS) {
1960 1977                  goto done;
1961 1978          }
1962 1979  
1963 1980  done:
1964 1981          free(sbdLu);
1965 1982          (void) close(fd);
1966 1983          return (ret);
1967 1984  }
1968 1985  
1969 1986  /*
1970 1987   * removeGuidFromDiskStore
1971 1988   *
1972 1989   * Purpose: delete a logical unit from the sbd provider data
1973 1990   */
1974 1991  static int
1975 1992  removeGuidFromDiskStore(stmfGuid *guid)
1976 1993  {
1977 1994          return (persistDiskGuid(guid, NULL, B_FALSE));
1978 1995  }
1979 1996  
1980 1997  
1981 1998  /*
1982 1999   * addGuidToDiskStore
1983 2000   *
1984 2001   * Purpose: add a logical unit to the sbd provider data
1985 2002   */
1986 2003  static int
1987 2004  addGuidToDiskStore(stmfGuid *guid, char *filename)
1988 2005  {
1989 2006          return (persistDiskGuid(guid, filename, B_TRUE));
1990 2007  }
1991 2008  
1992 2009  
1993 2010  /*
1994 2011   * persistDiskGuid
1995 2012   *
1996 2013   * Purpose: Persist or unpersist a guid for the sbd provider data
1997 2014   *
1998 2015   */
1999 2016  static int
2000 2017  persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist)
2001 2018  {
2002 2019          char        guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0};
2003 2020          nvlist_t    *nvl = NULL;
2004 2021  
2005 2022          uint64_t    setToken;
2006 2023          boolean_t   retryGetProviderData = B_FALSE;
2007 2024          boolean_t   newData = B_FALSE;
2008 2025          int         ret = STMF_STATUS_SUCCESS;
2009 2026          int         retryCnt = 0;
2010 2027          int         stmfRet;
2011 2028  
2012 2029          /* if we're persisting a guid, there must be a filename */
2013 2030          if (persist && !filename) {
2014 2031                  return (1);
2015 2032          }
2016 2033  
2017 2034          /* guid is stored in lowercase ascii hex */
2018 2035          (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
2019 2036              "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
2020 2037              "%02x%02x%02x%02x%02x%02x",
2021 2038              guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3],
2022 2039              guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7],
2023 2040              guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11],
2024 2041              guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]);
2025 2042  
2026 2043  
2027 2044          do {
2028 2045                  retryGetProviderData = B_FALSE;
2029 2046                  stmfRet = stmfGetProviderDataProt("sbd", &nvl,
2030 2047                      STMF_LU_PROVIDER_TYPE, &setToken);
2031 2048                  if (stmfRet != STMF_STATUS_SUCCESS) {
2032 2049                          if (persist && stmfRet == STMF_ERROR_NOT_FOUND) {
2033 2050                                  ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
2034 2051                                  if (ret != 0) {
2035 2052                                          syslog(LOG_DEBUG,
2036 2053                                              "unpersistGuid:nvlist_alloc(%d)",
2037 2054                                              ret);
2038 2055                                          ret = STMF_STATUS_ERROR;
2039 2056                                          goto done;
2040 2057                                  }
2041 2058                                  newData = B_TRUE;
2042 2059                          } else {
2043 2060                                  /*
2044 2061                                   * if we're persisting the data, it's
2045 2062                                   * an error. Otherwise, just return
2046 2063                                   */
2047 2064                                  if (persist) {
2048 2065                                          ret = stmfRet;
2049 2066                                  }
2050 2067                                  goto done;
2051 2068                          }
2052 2069                  }
2053 2070                  if (persist) {
2054 2071                          ret = nvlist_add_string(nvl, guidAsciiBuf, filename);
2055 2072                  } else {
2056 2073                          ret = nvlist_remove(nvl, guidAsciiBuf,
2057 2074                              DATA_TYPE_STRING);
2058 2075                          if (ret == ENOENT) {
2059 2076                                  ret = 0;
2060 2077                          }
2061 2078                  }
2062 2079                  if (ret == 0) {
2063 2080                          if (newData) {
2064 2081                                  stmfRet = stmfSetProviderDataProt("sbd", nvl,
2065 2082                                      STMF_LU_PROVIDER_TYPE, NULL);
2066 2083                          } else {
2067 2084                                  stmfRet = stmfSetProviderDataProt("sbd", nvl,
2068 2085                                      STMF_LU_PROVIDER_TYPE, &setToken);
2069 2086                          }
2070 2087                          if (stmfRet != STMF_STATUS_SUCCESS) {
2071 2088                                  if (stmfRet == STMF_ERROR_BUSY) {
2072 2089                                          /* get/set failed, try again */
2073 2090                                          retryGetProviderData = B_TRUE;
2074 2091                                          if (retryCnt++ > MAX_PROVIDER_RETRY) {
2075 2092                                                  ret = stmfRet;
2076 2093                                                  break;
2077 2094                                          }
2078 2095                                          continue;
2079 2096                                  } else if (stmfRet ==
2080 2097                                      STMF_ERROR_PROV_DATA_STALE) {
2081 2098                                          /* update failed, try again */
2082 2099                                          nvlist_free(nvl);
2083 2100                                          nvl = NULL;
2084 2101                                          retryGetProviderData = B_TRUE;
2085 2102                                          if (retryCnt++ > MAX_PROVIDER_RETRY) {
2086 2103                                                  ret = stmfRet;
2087 2104                                                  break;
2088 2105                                          }
2089 2106                                          continue;
2090 2107                                  } else {
2091 2108                                          syslog(LOG_DEBUG,
2092 2109                                              "unpersistGuid:error(%x)", stmfRet);
2093 2110                                          ret = stmfRet;
2094 2111                                  }
2095 2112                                  break;
2096 2113                          }
2097 2114                  } else {
2098 2115                          syslog(LOG_DEBUG,
2099 2116                              "unpersistGuid:error nvlist_add/remove(%d)",
2100 2117                              ret);
2101 2118                          ret = STMF_STATUS_ERROR;
2102 2119                  }
2103 2120          } while (retryGetProviderData);
2104 2121  
2105 2122  done:
2106 2123          nvlist_free(nvl);
2107 2124          return (ret);
2108 2125  }
2109 2126  
2110 2127  
2111 2128  /*
2112 2129   * stmfGetLuProp
2113 2130   *
2114 2131   * Purpose: Get current value for a resource property
2115 2132   *
2116 2133   * hdl - luResource from a previous call to stmfCreateLuResource
2117 2134   *
2118 2135   * resourceProp - a valid resource property type
2119 2136   *
2120 2137   * propVal - void pointer to a pointer of the value to be retrieved
2121 2138   */
2122 2139  int
2123 2140  stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen)
2124 2141  {
2125 2142          int ret = STMF_STATUS_SUCCESS;
2126 2143          luResourceImpl *luPropsHdl = hdl;
2127 2144          if (hdl == NULL || propLen == NULL || propVal == NULL) {
2128 2145                  return (STMF_ERROR_INVALID_ARG);
2129 2146          }
2130 2147  
2131 2148          if (luPropsHdl->type == STMF_DISK) {
2132 2149                  ret = getDiskProp(luPropsHdl, prop, propVal, propLen);
2133 2150          } else {
2134 2151                  return (STMF_ERROR_INVALID_ARG);
2135 2152          }
2136 2153  
2137 2154          return (ret);
2138 2155  }
2139 2156  
2140 2157  /*
2141 2158   * stmfGetLuResource
2142 2159   *
2143 2160   * Purpose: Get a logical unit resource handle for a given logical unit.
2144 2161   *
2145 2162   * hdl - pointer to luResource
2146 2163   */
2147 2164  int
2148 2165  stmfGetLuResource(stmfGuid *luGuid, luResource *hdl)
2149 2166  {
2150 2167          int ret = STMF_STATUS_SUCCESS;
2151 2168          stmfLogicalUnitProperties luProps;
2152 2169  
2153 2170          if (hdl == NULL) {
2154 2171                  return (STMF_ERROR_INVALID_ARG);
2155 2172          }
2156 2173  
2157 2174          /* Check logical unit provider name to call correct dtype function */
2158 2175          if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
2159 2176              != STMF_STATUS_SUCCESS) {
2160 2177                  return (ret);
2161 2178          } else {
2162 2179                  if (strcmp(luProps.providerName, "sbd") == 0) {
2163 2180                          ret = getDiskAllProps(luGuid, hdl);
2164 2181                  } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
2165 2182                          return (STMF_ERROR_NOT_FOUND);
2166 2183                  } else {
2167 2184                          return (STMF_ERROR_INVALID_ARG);
2168 2185                  }
2169 2186          }
2170 2187  
2171 2188          return (ret);
2172 2189  }
2173 2190  
2174 2191  /*
2175 2192   * getDiskAllProps
2176 2193   *
2177 2194   * Purpose: load all disk properties from sbd driver
2178 2195   *
2179 2196   * luGuid - guid of disk device for which properties are to be retrieved
2180 2197   * hdl - allocated luResource into which properties are to be copied
2181 2198   *
2182 2199   */
2183 2200  static int
2184 2201  getDiskAllProps(stmfGuid *luGuid, luResource *hdl)
2185 2202  {
2186 2203          int ret = STMF_STATUS_SUCCESS;
2187 2204          int fd;
2188 2205          sbd_lu_props_t *sbdProps;
2189 2206          int ioctlRet;
2190 2207          int savedErrno;
2191 2208          int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
2192 2209          stmf_iocdata_t sbdIoctl = {0};
2193 2210  
2194 2211          /*
2195 2212           * Open control node for sbd
2196 2213           */
2197 2214          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
2198 2215                  return (ret);
2199 2216  
2200 2217  
2201 2218          *hdl = calloc(1, sizeof (luResourceImpl));
2202 2219          if (*hdl == NULL) {
2203 2220                  (void) close(fd);
2204 2221                  return (STMF_ERROR_NOMEM);
2205 2222          }
2206 2223  
2207 2224          sbdProps = calloc(1, sbdPropsSize);
2208 2225          if (sbdProps == NULL) {
2209 2226                  free(*hdl);
2210 2227                  (void) close(fd);
2211 2228                  return (STMF_ERROR_NOMEM);
2212 2229          }
2213 2230  
2214 2231          ret = createDiskResource((luResourceImpl *)*hdl);
2215 2232          if (ret != STMF_STATUS_SUCCESS) {
2216 2233                  free(*hdl);
2217 2234                  free(sbdProps);
2218 2235                  (void) close(fd);
2219 2236                  return (ret);
2220 2237          }
2221 2238  
2222 2239          sbdProps->slp_input_guid = 1;
2223 2240          bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid));
2224 2241  
2225 2242          sbdIoctl.stmf_version = STMF_VERSION_1;
2226 2243          sbdIoctl.stmf_ibuf_size = sbdPropsSize;
2227 2244          sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps;
2228 2245          sbdIoctl.stmf_obuf_size = sbdPropsSize;
2229 2246          sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
2230 2247          ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl);
2231 2248          if (ioctlRet != 0) {
2232 2249                  savedErrno = errno;
2233 2250                  switch (savedErrno) {
2234 2251                          case EBUSY:
2235 2252                                  ret = STMF_ERROR_BUSY;
2236 2253                                  break;
2237 2254                          case EPERM:
2238 2255                          case EACCES:
2239 2256                                  ret = STMF_ERROR_PERM;
2240 2257                                  break;
2241 2258                          case ENOENT:
2242 2259                                  ret = STMF_ERROR_NOT_FOUND;
2243 2260                                  break;
2244 2261                          default:
2245 2262                                  syslog(LOG_DEBUG,
2246 2263                                      "getDiskAllProps:ioctl error(%d) (%d) (%d)",
2247 2264                                      ioctlRet, sbdIoctl.stmf_error, savedErrno);
2248 2265                                  ret = STMF_STATUS_ERROR;
2249 2266                                  break;
2250 2267                  }
2251 2268          }
2252 2269  
2253 2270          if (ret == STMF_STATUS_SUCCESS) {
2254 2271                  ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps);
2255 2272          }
2256 2273  
2257 2274          free(sbdProps);
2258 2275          (void) close(fd);
2259 2276          return (ret);
2260 2277  }
2261 2278  
2262 2279  /*
2263 2280   * loadDiskPropsFromDriver
2264 2281   *
2265 2282   * Purpose: Retrieve all disk type properties from sbd driver
2266 2283   *
2267 2284   * hdl - Allocated luResourceImpl
2268 2285   * sbdProps - sbd_lu_props_t structure returned from sbd driver
2269 2286   *
2270 2287   */
2271 2288  static int
2272 2289  loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
2273 2290  {
2274 2291          int ret = STMF_STATUS_SUCCESS;
2275 2292          diskResource *diskLu = hdl->resource;
2276 2293          /* copy guid */
2277 2294          diskLu->luGuidValid = B_TRUE;
2278 2295          bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid));
2279 2296  
2280 2297          if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) {
2281 2298                  diskLu->luMetaFileNameValid = B_TRUE;
2282 2299                  if (strlcpy(diskLu->luMetaFileName,
2283 2300                      (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]),
2284 2301                      sizeof (diskLu->luMetaFileName)) >=
2285 2302                      sizeof (diskLu->luMetaFileName)) {
2286 2303                          return (STMF_STATUS_ERROR);
2287 2304                  }
2288 2305          }
2289 2306  
2290 2307          if (sbdProps->slp_data_fname_valid) {
2291 2308                  diskLu->luDataFileNameValid = B_TRUE;
2292 2309                  if (strlcpy(diskLu->luDataFileName,
2293 2310                      (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]),
2294 2311                      sizeof (diskLu->luDataFileName)) >=
2295 2312                      sizeof (diskLu->luDataFileName)) {
2296 2313                          return (STMF_STATUS_ERROR);
2297 2314                  }
2298 2315          }
2299 2316  
2300 2317          if (sbdProps->slp_serial_valid) {
2301 2318                  diskLu->serialNumValid = B_TRUE;
2302 2319                  bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]),
2303 2320                      diskLu->serialNum, sbdProps->slp_serial_size);
2304 2321          }
2305 2322  
2306 2323          if (sbdProps->slp_mgmt_url_valid) {
2307 2324                  diskLu->luMgmtUrlValid = B_TRUE;
2308 2325                  if (strlcpy(diskLu->luMgmtUrl,
2309 2326                      (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]),
2310 2327                      sizeof (diskLu->luMgmtUrl)) >=
2311 2328                      sizeof (diskLu->luMgmtUrl)) {
2312 2329                          return (STMF_STATUS_ERROR);
2313 2330                  }
2314 2331          }
2315 2332  
2316 2333          if (sbdProps->slp_alias_valid) {
2317 2334                  diskLu->luAliasValid = B_TRUE;
2318 2335                  if (strlcpy(diskLu->luAlias,
2319 2336                      (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]),
2320 2337                      sizeof (diskLu->luAlias)) >=
2321 2338                      sizeof (diskLu->luAlias)) {
2322 2339                          return (STMF_STATUS_ERROR);
2323 2340                  }
2324 2341          } else { /* set alias to data filename if not set */
2325 2342                  if (sbdProps->slp_data_fname_valid) {
2326 2343                          diskLu->luAliasValid = B_TRUE;
2327 2344                          if (strlcpy(diskLu->luAlias,
2328 2345                              (char *)&(sbdProps->slp_buf[
2329 2346                              sbdProps->slp_data_fname_off]),
2330 2347                              sizeof (diskLu->luAlias)) >=
2331 2348                              sizeof (diskLu->luAlias)) {
2332 2349                                  return (STMF_STATUS_ERROR);
2333 2350                          }
2334 2351                  }
2335 2352          }
  
    | 
      ↓ open down ↓ | 
    417 lines elided | 
    
      ↑ open up ↑ | 
  
2336 2353  
2337 2354          diskLu->vidValid = B_TRUE;
2338 2355          bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid));
2339 2356  
2340 2357          diskLu->pidValid = B_TRUE;
2341 2358          bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid));
2342 2359  
2343 2360          diskLu->revValid = B_TRUE;
2344 2361          bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev));
2345 2362  
     2363 +        diskLu->unmapValid = B_TRUE;
     2364 +        if (sbdProps->slp_unmap_cur)
     2365 +                diskLu->unmap = B_TRUE;
     2366 +
2346 2367          diskLu->writeProtectEnableValid = B_TRUE;
2347 2368          if (sbdProps->slp_write_protected) {
2348 2369                  diskLu->writeProtectEnable = B_TRUE;
2349 2370          }
2350 2371  
2351 2372          diskLu->writebackCacheDisableValid = B_TRUE;
2352 2373          if (sbdProps->slp_writeback_cache_disable_cur) {
2353 2374                  diskLu->writebackCacheDisable = B_TRUE;
2354 2375          }
2355 2376  
2356 2377          diskLu->blkSizeValid = B_TRUE;
2357 2378          diskLu->blkSize = sbdProps->slp_blksize;
2358 2379  
2359 2380          diskLu->luSizeValid = B_TRUE;
2360 2381          diskLu->luSize = sbdProps->slp_lu_size;
2361 2382  
2362 2383          diskLu->accessState = sbdProps->slp_access_state;
2363 2384  
2364 2385          return (ret);
2365 2386  }
2366 2387  
2367 2388  /*
2368 2389   * stmfGetGlobalLuProp
2369 2390   *
2370 2391   * Purpose: get a global property for a device type
2371 2392   *
2372 2393   */
2373 2394  int
2374 2395  stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal,
2375 2396      size_t *propLen)
2376 2397  {
2377 2398          int ret = STMF_STATUS_SUCCESS;
2378 2399          if (dType != STMF_DISK || propVal == NULL) {
2379 2400                  return (STMF_ERROR_INVALID_ARG);
2380 2401          }
2381 2402  
2382 2403          ret = getDiskGlobalProp(prop, propVal, propLen);
2383 2404  
2384 2405          return (ret);
2385 2406  }
2386 2407  
2387 2408  /*
2388 2409   * getDiskGlobalProp
2389 2410   *
2390 2411   * Purpose: get global property from sbd driver
2391 2412   *
2392 2413   */
2393 2414  static int
2394 2415  getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen)
2395 2416  {
2396 2417          int ret = STMF_STATUS_SUCCESS;
2397 2418          int fd;
2398 2419          sbd_global_props_t *sbdProps;
2399 2420          void *sbd_realloc;
2400 2421          int retryCnt = 0;
2401 2422          boolean_t retry;
2402 2423          int ioctlRet;
2403 2424          int savedErrno;
2404 2425          int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
2405 2426          stmf_iocdata_t sbdIoctl = {0};
2406 2427          size_t reqLen;
2407 2428  
2408 2429          switch (prop) {
2409 2430                  case STMF_LU_PROP_MGMT_URL:
2410 2431                          break;
2411 2432                  default:
2412 2433                          return (STMF_ERROR_INVALID_PROP);
2413 2434          }
2414 2435  
2415 2436          /*
2416 2437           * Open control node for sbd
2417 2438           */
2418 2439          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
2419 2440                  return (ret);
2420 2441  
2421 2442          sbdProps = calloc(1, sbdPropsSize);
2422 2443          if (sbdProps == NULL) {
2423 2444                  (void) close(fd);
2424 2445                  return (STMF_ERROR_NOMEM);
2425 2446          }
2426 2447  
2427 2448          do {
2428 2449                  retry = B_FALSE;
2429 2450                  sbdIoctl.stmf_version = STMF_VERSION_1;
2430 2451                  sbdIoctl.stmf_obuf_size = sbdPropsSize;
2431 2452                  sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
2432 2453                  ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl);
2433 2454                  if (ioctlRet != 0) {
2434 2455                          savedErrno = errno;
2435 2456                          switch (savedErrno) {
2436 2457                                  case EBUSY:
2437 2458                                          ret = STMF_ERROR_BUSY;
2438 2459                                          break;
2439 2460                                  case EPERM:
2440 2461                                  case EACCES:
2441 2462                                          ret = STMF_ERROR_PERM;
2442 2463                                          break;
2443 2464                                  case ENOMEM:
2444 2465                                          if (sbdIoctl.stmf_error ==
2445 2466                                              SBD_RET_INSUFFICIENT_BUF_SPACE &&
2446 2467                                              retryCnt++ < 3) {
2447 2468                                                  sbdPropsSize =
2448 2469                                                      sizeof (*sbdProps) +
2449 2470                                                      sbdProps->
2450 2471                                                      mlu_buf_size_needed;
2451 2472  
2452 2473                                                  sbd_realloc = sbdProps;
2453 2474                                                  sbdProps = realloc(sbdProps,
2454 2475                                                      sbdPropsSize);
2455 2476                                                  if (sbdProps == NULL) {
2456 2477                                                          free(sbd_realloc);
2457 2478                                                          ret = STMF_ERROR_NOMEM;
2458 2479                                                          break;
2459 2480                                                  }
2460 2481                                                  retry = B_TRUE;
2461 2482                                          } else {
2462 2483                                                  ret = STMF_ERROR_NOMEM;
2463 2484                                          }
2464 2485                                          break;
2465 2486                                  default:
2466 2487                                          syslog(LOG_DEBUG,
2467 2488                                              "getDiskGlobalProp:ioctl error(%d)"
2468 2489                                              "(%d)(%d)", ioctlRet,
2469 2490                                              sbdIoctl.stmf_error, savedErrno);
2470 2491                                          ret = STMF_STATUS_ERROR;
2471 2492                                          break;
2472 2493                          }
2473 2494  
2474 2495                  }
2475 2496          } while (retry);
2476 2497  
2477 2498          if (ret != STMF_STATUS_SUCCESS) {
2478 2499                  goto done;
2479 2500          }
2480 2501  
2481 2502          switch (prop) {
2482 2503                  case STMF_LU_PROP_MGMT_URL:
2483 2504                          if (sbdProps->mlu_mgmt_url_valid == 0) {
2484 2505                                  ret = STMF_ERROR_NO_PROP;
2485 2506                                  goto done;
2486 2507                          }
2487 2508                          if ((reqLen = strlcpy(propVal, (char *)&(
2488 2509                              sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]),
2489 2510                              *propLen)) >= *propLen) {
2490 2511                                  *propLen = reqLen + 1;
2491 2512                                  ret = STMF_ERROR_INVALID_ARG;
2492 2513                                  goto done;
2493 2514                          }
2494 2515                          break;
2495 2516          }
2496 2517  
2497 2518  done:
2498 2519          free(sbdProps);
2499 2520          (void) close(fd);
2500 2521          return (ret);
2501 2522  }
2502 2523  
2503 2524  /*
2504 2525   * stmfSetGlobalLuProp
2505 2526   *
2506 2527   * Purpose: set a global property for a device type
2507 2528   *
2508 2529   */
2509 2530  int
2510 2531  stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal)
2511 2532  {
2512 2533          int ret = STMF_STATUS_SUCCESS;
2513 2534          if (dType != STMF_DISK || propVal == NULL) {
2514 2535                  return (STMF_ERROR_INVALID_ARG);
2515 2536          }
2516 2537  
2517 2538          ret = setDiskGlobalProp(prop, propVal);
2518 2539  
2519 2540          return (ret);
2520 2541  }
2521 2542  
2522 2543  /*
2523 2544   * setDiskGlobalProp
2524 2545   *
2525 2546   * Purpose: set properties for resource of type disk
2526 2547   *
2527 2548   * resourceProp - valid resource identifier
2528 2549   * propVal - valid resource value
2529 2550   */
2530 2551  static int
2531 2552  setDiskGlobalProp(uint32_t resourceProp, const char *propVal)
2532 2553  {
2533 2554          int ret = STMF_STATUS_SUCCESS;
2534 2555          sbd_global_props_t *sbdGlobalProps = NULL;
2535 2556          int sbdGlobalPropsSize = 0;
2536 2557          int propLen;
2537 2558          int mluBufSize = 0;
2538 2559          int fd;
2539 2560          int savedErrno;
2540 2561          int ioctlRet;
2541 2562          stmf_iocdata_t sbdIoctl = {0};
2542 2563  
2543 2564          switch (resourceProp) {
2544 2565                  case STMF_LU_PROP_MGMT_URL:
2545 2566                          break;
2546 2567                  default:
2547 2568                          return (STMF_ERROR_INVALID_PROP);
2548 2569                          break;
2549 2570          }
2550 2571  
2551 2572          /*
2552 2573           * Open control node for sbd
2553 2574           */
2554 2575          if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
2555 2576                  return (ret);
2556 2577  
2557 2578          propLen = strlen(propVal);
2558 2579          mluBufSize += propLen + 1;
2559 2580          sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 +
2560 2581              max(8, mluBufSize);
2561 2582          /*
2562 2583           * 8 is the size of the buffer set aside for
2563 2584           * concatenation of variable length fields
2564 2585           */
2565 2586          sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize);
2566 2587          if (sbdGlobalProps == NULL) {
2567 2588                  (void) close(fd);
2568 2589                  return (STMF_ERROR_NOMEM);
2569 2590          }
2570 2591  
2571 2592          sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize;
2572 2593  
2573 2594          switch (resourceProp) {
2574 2595                  case STMF_LU_PROP_MGMT_URL:
2575 2596                          sbdGlobalProps->mlu_mgmt_url_valid = 1;
2576 2597                          bcopy(propVal, &(sbdGlobalProps->mlu_buf),
2577 2598                              propLen + 1);
2578 2599                          break;
2579 2600                  default:
2580 2601                          ret = STMF_ERROR_NO_PROP;
2581 2602                          goto done;
2582 2603          }
2583 2604  
2584 2605          sbdIoctl.stmf_version = STMF_VERSION_1;
2585 2606          sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size;
2586 2607          sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps;
2587 2608  
2588 2609          ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl);
2589 2610          if (ioctlRet != 0) {
2590 2611                  savedErrno = errno;
2591 2612                  switch (savedErrno) {
2592 2613                          case EBUSY:
2593 2614                                  ret = STMF_ERROR_BUSY;
2594 2615                                  break;
2595 2616                          case EPERM:
2596 2617                          case EACCES:
2597 2618                                  ret = STMF_ERROR_PERM;
2598 2619                                  break;
2599 2620                          default:
2600 2621                                  diskError(sbdIoctl.stmf_error, &ret);
2601 2622                                  if (ret == STMF_STATUS_ERROR) {
2602 2623                                          syslog(LOG_DEBUG,
2603 2624                                          "modifyDiskLu:ioctl "
2604 2625                                          "error(%d) (%d) (%d)", ioctlRet,
2605 2626                                              sbdIoctl.stmf_error, savedErrno);
2606 2627                                  }
2607 2628                                  break;
2608 2629                  }
2609 2630          }
2610 2631  
2611 2632  done:
2612 2633          free(sbdGlobalProps);
2613 2634          (void) close(fd);
2614 2635          return (ret);
2615 2636  }
2616 2637  
2617 2638  
2618 2639  /*
2619 2640   * stmfSetLuProp
2620 2641   *
2621 2642   * Purpose: set a property on an luResource
2622 2643   *
2623 2644   * hdl - allocated luResource
2624 2645   * prop - property identifier
2625 2646   * propVal - property value to be set
2626 2647   */
2627 2648  int
2628 2649  stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal)
2629 2650  {
2630 2651          int ret = STMF_STATUS_SUCCESS;
2631 2652          luResourceImpl *luPropsHdl = hdl;
2632 2653          if (hdl == NULL) {
2633 2654                  return (STMF_ERROR_INVALID_ARG);
2634 2655          }
2635 2656  
2636 2657          if (luPropsHdl->type == STMF_DISK) {
2637 2658                  ret = setDiskProp(luPropsHdl, prop, propVal);
2638 2659          } else {
2639 2660                  return (STMF_ERROR_INVALID_ARG);
2640 2661          }
2641 2662  
2642 2663          return (ret);
2643 2664  }
2644 2665  
2645 2666  /*
2646 2667   * getDiskProp
2647 2668   *
2648 2669   * Purpose: retrieve a given property from a logical unit resource of type disk
2649 2670   *
2650 2671   * hdl - allocated luResourceImpl
2651 2672   * prop - property identifier
2652 2673   * propVal - pointer to character to contain the retrieved property value
2653 2674   * propLen - On input this is the length of propVal. On failure, it contains the
2654 2675   *           number of bytes required for propVal
2655 2676   */
2656 2677  static int
2657 2678  getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
2658 2679  {
2659 2680          int ret = STMF_STATUS_SUCCESS;
2660 2681          diskResource *diskLu = hdl->resource;
2661 2682          char accessState[20];
2662 2683          size_t reqLen;
2663 2684  
2664 2685          if (prop == STMF_LU_PROP_ACCESS_STATE) {
2665 2686                  if (diskLu->accessState == SBD_LU_ACTIVE) {
2666 2687                          (void) strlcpy(accessState, STMF_ACCESS_ACTIVE,
2667 2688                              sizeof (accessState));
2668 2689                  } else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) {
2669 2690                          (void) strlcpy(accessState,
2670 2691                              STMF_ACCESS_STANDBY_TO_ACTIVE,
2671 2692                              sizeof (accessState));
2672 2693                  } else if (diskLu->accessState == SBD_LU_STANDBY) {
2673 2694                          (void) strlcpy(accessState, STMF_ACCESS_STANDBY,
2674 2695                              sizeof (accessState));
2675 2696                  } else if (diskLu->accessState ==
2676 2697                      SBD_LU_TRANSITION_TO_STANDBY) {
2677 2698                          (void) strlcpy(accessState,
2678 2699                              STMF_ACCESS_ACTIVE_TO_STANDBY,
2679 2700                              sizeof (accessState));
2680 2701                  }
2681 2702                  if ((reqLen = strlcpy(propVal, accessState,
2682 2703                      *propLen)) >= *propLen) {
2683 2704                          *propLen = reqLen + 1;
2684 2705                          return (STMF_ERROR_INVALID_ARG);
2685 2706                  }
2686 2707                  return (0);
2687 2708          }
2688 2709  
2689 2710          if (diskLu->accessState != SBD_LU_ACTIVE) {
2690 2711                  return (STMF_ERROR_NO_PROP_STANDBY);
2691 2712          }
2692 2713  
2693 2714          switch (prop) {
2694 2715                  case STMF_LU_PROP_BLOCK_SIZE:
2695 2716                          if (diskLu->blkSizeValid == B_FALSE) {
2696 2717                                  return (STMF_ERROR_NO_PROP);
2697 2718                          }
2698 2719                          reqLen = snprintf(propVal, *propLen, "%llu",
2699 2720                              (u_longlong_t)diskLu->blkSize);
2700 2721                          if (reqLen >= *propLen) {
2701 2722                                  *propLen = reqLen + 1;
2702 2723                                  return (STMF_ERROR_INVALID_ARG);
2703 2724                          }
2704 2725                          break;
2705 2726                  case STMF_LU_PROP_FILENAME:
2706 2727                          if (diskLu->luDataFileNameValid == B_FALSE) {
2707 2728                                  return (STMF_ERROR_NO_PROP);
2708 2729                          }
2709 2730                          if ((reqLen = strlcpy(propVal, diskLu->luDataFileName,
2710 2731                              *propLen)) >= *propLen) {
2711 2732                                  *propLen = reqLen + 1;
2712 2733                                  return (STMF_ERROR_INVALID_ARG);
2713 2734                          }
2714 2735                          break;
2715 2736                  case STMF_LU_PROP_META_FILENAME:
2716 2737                          if (diskLu->luMetaFileNameValid == B_FALSE) {
2717 2738                                  return (STMF_ERROR_NO_PROP);
2718 2739                          }
2719 2740                          if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName,
2720 2741                              *propLen)) >= *propLen) {
2721 2742                                  *propLen = reqLen + 1;
2722 2743                                  return (STMF_ERROR_INVALID_ARG);
2723 2744                          }
2724 2745                          break;
2725 2746                  case STMF_LU_PROP_MGMT_URL:
2726 2747                          if (diskLu->luMgmtUrlValid == B_FALSE) {
2727 2748                                  return (STMF_ERROR_NO_PROP);
2728 2749                          }
2729 2750                          if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl,
2730 2751                              *propLen)) >= *propLen) {
2731 2752                                  *propLen = reqLen + 1;
2732 2753                                  return (STMF_ERROR_INVALID_ARG);
2733 2754                          }
2734 2755                          break;
2735 2756                  case STMF_LU_PROP_GUID:
2736 2757                          if (diskLu->luGuidValid == B_FALSE) {
2737 2758                                  return (STMF_ERROR_NO_PROP);
2738 2759                          }
2739 2760                          reqLen = snprintf(propVal, *propLen,
2740 2761                              "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
2741 2762                              "%02X%02X%02X%02X",
2742 2763                              diskLu->luGuid[0], diskLu->luGuid[1],
2743 2764                              diskLu->luGuid[2], diskLu->luGuid[3],
2744 2765                              diskLu->luGuid[4], diskLu->luGuid[5],
2745 2766                              diskLu->luGuid[6], diskLu->luGuid[7],
2746 2767                              diskLu->luGuid[8], diskLu->luGuid[9],
2747 2768                              diskLu->luGuid[10], diskLu->luGuid[11],
2748 2769                              diskLu->luGuid[12], diskLu->luGuid[13],
2749 2770                              diskLu->luGuid[14], diskLu->luGuid[15]);
2750 2771                          if (reqLen >= *propLen) {
2751 2772                                  *propLen = reqLen + 1;
2752 2773                                  return (STMF_ERROR_INVALID_ARG);
2753 2774                          }
2754 2775                          break;
2755 2776                  case STMF_LU_PROP_SERIAL_NUM:
2756 2777                          if (diskLu->serialNumValid == B_FALSE) {
2757 2778                                  return (STMF_ERROR_NO_PROP);
2758 2779                          }
2759 2780                          if ((reqLen = strlcpy(propVal, diskLu->serialNum,
2760 2781                              *propLen)) >= *propLen) {
2761 2782                                  *propLen = reqLen + 1;
2762 2783                                  return (STMF_ERROR_INVALID_ARG);
2763 2784                          }
2764 2785                          break;
2765 2786                  case STMF_LU_PROP_SIZE:
2766 2787                          if (diskLu->luSizeValid == B_FALSE) {
2767 2788                                  return (STMF_ERROR_NO_PROP);
2768 2789                          }
2769 2790                          (void) snprintf(propVal, *propLen, "%llu",
2770 2791                              (u_longlong_t)diskLu->luSize);
2771 2792                          break;
2772 2793                  case STMF_LU_PROP_ALIAS:
2773 2794                          if (diskLu->luAliasValid == B_FALSE) {
2774 2795                                  return (STMF_ERROR_NO_PROP);
2775 2796                          }
2776 2797                          if ((reqLen = strlcpy(propVal, diskLu->luAlias,
2777 2798                              *propLen)) >= *propLen) {
2778 2799                                  *propLen = reqLen + 1;
2779 2800                                  return (STMF_ERROR_INVALID_ARG);
2780 2801                          }
2781 2802                          break;
2782 2803                  case STMF_LU_PROP_VID:
2783 2804                          if (diskLu->vidValid == B_FALSE) {
2784 2805                                  return (STMF_ERROR_NO_PROP);
2785 2806                          }
2786 2807                          if (*propLen <= sizeof (diskLu->vid)) {
2787 2808                                  return (STMF_ERROR_INVALID_ARG);
2788 2809                          }
2789 2810                          bcopy(diskLu->vid, propVal, sizeof (diskLu->vid));
2790 2811                          propVal[sizeof (diskLu->vid)] = 0;
2791 2812                          break;
2792 2813                  case STMF_LU_PROP_PID:
2793 2814                          if (diskLu->pidValid == B_FALSE) {
2794 2815                                  return (STMF_ERROR_NO_PROP);
2795 2816                          }
2796 2817                          if (*propLen <= sizeof (diskLu->pid)) {
2797 2818                                  return (STMF_ERROR_INVALID_ARG);
2798 2819                          }
2799 2820                          bcopy(diskLu->pid, propVal, sizeof (diskLu->pid));
2800 2821                          propVal[sizeof (diskLu->pid)] = 0;
2801 2822                          break;
2802 2823                  case STMF_LU_PROP_WRITE_PROTECT:
2803 2824                          if (diskLu->writeProtectEnableValid == B_FALSE) {
2804 2825                                  return (STMF_ERROR_NO_PROP);
2805 2826                          }
2806 2827                          if (diskLu->writeProtectEnable) {
2807 2828                                  if ((reqLen = strlcpy(propVal, "true",
2808 2829                                      *propLen)) >= *propLen) {
2809 2830                                          *propLen = reqLen + 1;
  
    | 
      ↓ open down ↓ | 
    454 lines elided | 
    
      ↑ open up ↑ | 
  
2810 2831                                          return (STMF_ERROR_INVALID_ARG);
2811 2832                                  }
2812 2833                          } else {
2813 2834                                  if ((reqLen = strlcpy(propVal, "false",
2814 2835                                      *propLen)) >= *propLen) {
2815 2836                                          *propLen = reqLen + 1;
2816 2837                                          return (STMF_ERROR_INVALID_ARG);
2817 2838                                  }
2818 2839                          }
2819 2840                          break;
     2841 +                case STMF_LU_PROP_UNMAP:
     2842 +                        if (!diskLu->unmapValid)
     2843 +                                return (STMF_ERROR_NO_PROP);
     2844 +                        if (diskLu->unmap) {
     2845 +                                if ((reqLen = strlcpy(propVal, "true",
     2846 +                                    *propLen)) >= *propLen) {
     2847 +                                        *propLen = reqLen + 1;
     2848 +                                        return (STMF_ERROR_INVALID_ARG);
     2849 +                                }
     2850 +                        } else {
     2851 +                                if ((reqLen = strlcpy(propVal, "false",
     2852 +                                    *propLen)) >= *propLen) {
     2853 +                                        *propLen = reqLen + 1;
     2854 +                                        return (STMF_ERROR_INVALID_ARG);
     2855 +                                }
     2856 +                        }
     2857 +                        break;
2820 2858                  case STMF_LU_PROP_WRITE_CACHE_DISABLE:
2821 2859                          if (diskLu->writebackCacheDisableValid == B_FALSE) {
2822 2860                                  return (STMF_ERROR_NO_PROP);
2823 2861                          }
2824 2862                          if (diskLu->writebackCacheDisable) {
2825 2863                                  if ((reqLen = strlcpy(propVal, "true",
2826 2864                                      *propLen)) >= *propLen) {
2827 2865                                          *propLen = reqLen + 1;
2828 2866                                          return (STMF_ERROR_INVALID_ARG);
2829 2867                                  }
2830 2868                          } else {
2831 2869                                  if ((reqLen = strlcpy(propVal, "false",
2832 2870                                      *propLen)) >= *propLen) {
2833 2871                                          *propLen = reqLen + 1;
2834 2872                                          return (STMF_ERROR_INVALID_ARG);
2835 2873                                  }
2836 2874                          }
2837 2875                          break;
2838 2876                  default:
2839 2877                          ret = STMF_ERROR_INVALID_PROP;
2840 2878                          break;
2841 2879          }
2842 2880  
2843 2881          return (ret);
2844 2882  }
2845 2883  
2846 2884  /*
2847 2885   * setDiskProp
2848 2886   *
2849 2887   * Purpose: set properties for resource of type disk
2850 2888   *
2851 2889   * hdl - allocated luResourceImpl
2852 2890   * resourceProp - valid resource identifier
2853 2891   * propVal - valid resource value
2854 2892   */
2855 2893  static int
2856 2894  setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
2857 2895  {
2858 2896          int ret = STMF_STATUS_SUCCESS;
2859 2897          int i;
2860 2898          diskResource *diskLu = hdl->resource;
2861 2899          unsigned long long numericProp = 0;
2862 2900          char guidProp[LU_ASCII_GUID_SIZE + 1];
2863 2901          char ouiProp[OUI_ASCII_SIZE + 1];
2864 2902          char hostIdProp[HOST_ID_ASCII_SIZE + 1];
2865 2903          unsigned int oui[OUI_SIZE];
2866 2904          unsigned int hostId[HOST_ID_SIZE];
2867 2905          unsigned int guid[LU_GUID_SIZE];
2868 2906          int propSize;
2869 2907  
2870 2908  
2871 2909          if (propVal == NULL) {
2872 2910                  return (STMF_ERROR_INVALID_ARG);
2873 2911          }
2874 2912  
2875 2913          switch (resourceProp) {
2876 2914                  case STMF_LU_PROP_ALIAS:
2877 2915                          if (strlcpy(diskLu->luAlias, propVal,
2878 2916                              sizeof (diskLu->luAlias)) >=
2879 2917                              sizeof (diskLu->luAlias)) {
2880 2918                                  return (STMF_ERROR_INVALID_PROPSIZE);
2881 2919                          }
2882 2920                          diskLu->luAliasValid = B_TRUE;
2883 2921                          break;
2884 2922                  case STMF_LU_PROP_BLOCK_SIZE: {
2885 2923                          const char *tmp = propVal;
2886 2924                          while (*tmp) {
2887 2925                                  if (!isdigit(*tmp++)) {
2888 2926                                          return (STMF_ERROR_INVALID_ARG);
2889 2927                                  }
2890 2928                          }
2891 2929                          (void) sscanf(propVal, "%llu", &numericProp);
2892 2930                          if (numericProp > UINT16_MAX) {
2893 2931                                  return (STMF_ERROR_INVALID_PROPSIZE);
2894 2932                          }
2895 2933                          diskLu->blkSize = numericProp;
2896 2934                          diskLu->blkSizeValid = B_TRUE;
2897 2935                          break;
2898 2936                  }
2899 2937                  case STMF_LU_PROP_COMPANY_ID:
2900 2938                          if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >=
2901 2939                              sizeof (ouiProp)) {
2902 2940                                  return (STMF_ERROR_INVALID_ARG);
2903 2941                          }
2904 2942                          if (checkHexUpper(ouiProp) != 0) {
2905 2943                                  return (STMF_ERROR_INVALID_ARG);
2906 2944                          }
2907 2945                          (void) sscanf(ouiProp, "%2X%2X%2X",
2908 2946                              &oui[0], &oui[1], &oui[2]);
2909 2947  
2910 2948                          diskLu->companyId = 0;
2911 2949                          diskLu->companyId += oui[0] << 16;
2912 2950                          diskLu->companyId += oui[1] << 8;
2913 2951                          diskLu->companyId += oui[2];
2914 2952                          if (diskLu->companyId == 0) {
2915 2953                                  return (STMF_ERROR_INVALID_ARG);
2916 2954                          }
2917 2955                          diskLu->companyIdValid = B_TRUE;
2918 2956                          break;
2919 2957                  case STMF_LU_PROP_HOST_ID:
2920 2958                          if ((strlcpy(hostIdProp, propVal,
2921 2959                              sizeof (hostIdProp))) >= sizeof (hostIdProp)) {
2922 2960                                  return (STMF_ERROR_INVALID_ARG);
2923 2961                          }
2924 2962                          if (checkHexUpper(hostIdProp) != 0) {
2925 2963                                  return (STMF_ERROR_INVALID_ARG);
2926 2964                          }
2927 2965                          (void) sscanf(hostIdProp, "%2X%2X%2X%2X",
2928 2966                              &hostId[0], &hostId[1], &hostId[2], &hostId[3]);
2929 2967  
2930 2968                          diskLu->hostId = 0;
2931 2969                          diskLu->hostId += hostId[0] << 24;
2932 2970                          diskLu->hostId += hostId[1] << 16;
2933 2971                          diskLu->hostId += hostId[2] << 8;
2934 2972                          diskLu->hostId += hostId[3];
2935 2973                          if (diskLu->hostId == 0) {
2936 2974                                  return (STMF_ERROR_INVALID_ARG);
2937 2975                          }
2938 2976                          diskLu->hostIdValid = B_TRUE;
2939 2977                          break;
2940 2978                  case STMF_LU_PROP_GUID:
2941 2979                          if (strlen(propVal) != LU_ASCII_GUID_SIZE) {
2942 2980                                  return (STMF_ERROR_INVALID_PROPSIZE);
2943 2981                          }
2944 2982  
2945 2983                          if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >=
2946 2984                              sizeof (guidProp)) {
2947 2985                                  return (STMF_ERROR_INVALID_ARG);
2948 2986                          }
2949 2987  
2950 2988                          if (checkHexUpper(guidProp) != 0) {
2951 2989                                  return (STMF_ERROR_INVALID_ARG);
2952 2990                          }
2953 2991  
2954 2992                          (void) sscanf(guidProp,
2955 2993                              "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
2956 2994                              &guid[0], &guid[1], &guid[2], &guid[3], &guid[4],
2957 2995                              &guid[5], &guid[6], &guid[7], &guid[8], &guid[9],
2958 2996                              &guid[10], &guid[11], &guid[12], &guid[13],
2959 2997                              &guid[14], &guid[15]);
2960 2998                          for (i = 0; i < sizeof (diskLu->luGuid); i++) {
2961 2999                                  diskLu->luGuid[i] = guid[i];
2962 3000                          }
2963 3001                          diskLu->luGuidValid = B_TRUE;
2964 3002                          break;
2965 3003                  case STMF_LU_PROP_FILENAME:
2966 3004                          if ((strlcpy(diskLu->luDataFileName, propVal,
2967 3005                              sizeof (diskLu->luDataFileName))) >=
2968 3006                              sizeof (diskLu->luDataFileName)) {
2969 3007                                  return (STMF_ERROR_INVALID_PROPSIZE);
2970 3008                          }
2971 3009                          diskLu->luDataFileNameValid = B_TRUE;
2972 3010                          break;
2973 3011                  case STMF_LU_PROP_META_FILENAME:
2974 3012                          if ((strlcpy(diskLu->luMetaFileName, propVal,
2975 3013                              sizeof (diskLu->luMetaFileName))) >=
2976 3014                              sizeof (diskLu->luMetaFileName)) {
2977 3015                                  return (STMF_ERROR_INVALID_PROPSIZE);
2978 3016                          }
2979 3017                          diskLu->luMetaFileNameValid = B_TRUE;
2980 3018                          break;
2981 3019                  case STMF_LU_PROP_MGMT_URL:
2982 3020                          if ((strlcpy(diskLu->luMgmtUrl, propVal,
2983 3021                              sizeof (diskLu->luMgmtUrl))) >=
2984 3022                              sizeof (diskLu->luMgmtUrl)) {
2985 3023                                  return (STMF_ERROR_INVALID_PROPSIZE);
2986 3024                          }
2987 3025                          diskLu->luMgmtUrlValid = B_TRUE;
2988 3026                          break;
2989 3027                  case STMF_LU_PROP_PID:
2990 3028                          if ((propSize = strlen(propVal)) >
2991 3029                              sizeof (diskLu->pid)) {
2992 3030                                  return (STMF_ERROR_INVALID_PROPSIZE);
2993 3031                          }
2994 3032                          (void) strncpy(diskLu->pid, propVal, propSize);
2995 3033                          diskLu->pidValid = B_TRUE;
2996 3034                          break;
2997 3035                  case STMF_LU_PROP_SERIAL_NUM:
2998 3036                          if ((propSize = strlen(propVal)) >
2999 3037                              (sizeof (diskLu->serialNum) - 1)) {
3000 3038                                  return (STMF_ERROR_INVALID_PROPSIZE);
3001 3039                          }
3002 3040                          (void) strncpy(diskLu->serialNum, propVal, propSize);
3003 3041                          diskLu->serialNumValid = B_TRUE;
3004 3042                          break;
3005 3043                  case STMF_LU_PROP_SIZE:
3006 3044                          if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) {
3007 3045                                  return (STMF_ERROR_INVALID_ARG);
3008 3046                          }
3009 3047                          diskLu->luSizeValid = B_TRUE;
3010 3048                          break;
3011 3049                  case STMF_LU_PROP_VID:
3012 3050                          if ((propSize = strlen(propVal)) >
3013 3051                              sizeof (diskLu->vid)) {
3014 3052                                  return (STMF_ERROR_INVALID_PROPSIZE);
3015 3053                          }
3016 3054                          (void) strncpy(diskLu->vid, propVal, propSize);
3017 3055                          diskLu->vidValid = B_TRUE;
3018 3056                          break;
3019 3057                  case STMF_LU_PROP_WRITE_PROTECT:
3020 3058                          if (strcasecmp(propVal, "TRUE") == 0) {
3021 3059                                  diskLu->writeProtectEnable = B_TRUE;
3022 3060                          } else if (strcasecmp(propVal, "FALSE") == 0) {
3023 3061                                  diskLu->writeProtectEnable = B_FALSE;
3024 3062                          } else {
3025 3063                                  return (STMF_ERROR_INVALID_ARG);
3026 3064                          }
3027 3065                          diskLu->writeProtectEnableValid = B_TRUE;
3028 3066                          break;
  
    | 
      ↓ open down ↓ | 
    199 lines elided | 
    
      ↑ open up ↑ | 
  
3029 3067                  case STMF_LU_PROP_WRITE_CACHE_DISABLE:
3030 3068                          if (strcasecmp(propVal, "TRUE") == 0) {
3031 3069                                  diskLu->writebackCacheDisable = B_TRUE;
3032 3070                          } else if (strcasecmp(propVal, "FALSE") == 0) {
3033 3071                                  diskLu->writebackCacheDisable = B_FALSE;
3034 3072                          } else {
3035 3073                                  return (STMF_ERROR_INVALID_ARG);
3036 3074                          }
3037 3075                          diskLu->writebackCacheDisableValid = B_TRUE;
3038 3076                          break;
     3077 +                case STMF_LU_PROP_UNMAP:
     3078 +                        if (strcasecmp(propVal, "TRUE") == 0) {
     3079 +                                diskLu->unmap = B_TRUE;
     3080 +                        } else if (strcasecmp(propVal, "FALSE") == 0) {
     3081 +                                diskLu->unmap = B_FALSE;
     3082 +                        } else {
     3083 +                                return (STMF_ERROR_INVALID_ARG);
     3084 +                        }
     3085 +                        diskLu->unmapValid = B_TRUE;
     3086 +                        break;
3039 3087                  case STMF_LU_PROP_ACCESS_STATE:
3040 3088                          ret = STMF_ERROR_INVALID_PROP;
3041 3089                          break;
3042 3090                  default:
3043 3091                          ret = STMF_ERROR_INVALID_PROP;
3044 3092                          break;
3045 3093          }
3046 3094          return (ret);
3047 3095  }
3048 3096  
3049 3097  static int
3050 3098  checkHexUpper(char *buf)
3051 3099  {
3052 3100          int i;
3053 3101  
3054 3102          for (i = 0; i < strlen(buf); i++) {
3055 3103                  if (isxdigit(buf[i])) {
3056 3104                          buf[i] = toupper(buf[i]);
3057 3105                          continue;
3058 3106                  }
3059 3107                  return (-1);
3060 3108          }
3061 3109  
3062 3110          return (0);
3063 3111  }
3064 3112  
3065 3113  /*
3066 3114   * Given a numeric suffix, convert the value into a number of bits that the
3067 3115   * resulting value must be shifted.
3068 3116   * Code lifted from libzfs_util.c
3069 3117   */
3070 3118  static int
3071 3119  strToShift(const char *buf)
3072 3120  {
3073 3121          const char *ends = "BKMGTPE";
3074 3122          int i;
3075 3123  
3076 3124          if (buf[0] == '\0')
3077 3125                  return (0);
3078 3126  
3079 3127          for (i = 0; i < strlen(ends); i++) {
3080 3128                  if (toupper(buf[0]) == ends[i])
3081 3129                          return (10*i);
3082 3130          }
3083 3131  
3084 3132          return (-1);
3085 3133  }
3086 3134  
3087 3135  int
3088 3136  stmfFreeLuResource(luResource hdl)
3089 3137  {
3090 3138          int ret = STMF_STATUS_SUCCESS;
3091 3139          if (hdl == NULL) {
3092 3140                  return (STMF_ERROR_INVALID_ARG);
3093 3141          }
3094 3142  
3095 3143          luResourceImpl *hdlImpl = hdl;
3096 3144          free(hdlImpl->resource);
3097 3145          free(hdlImpl);
3098 3146          return (ret);
3099 3147  }
3100 3148  
3101 3149  /*
3102 3150   * Convert a string of the form '100G' into a real number. Used when setting
3103 3151   * the size of a logical unit.
3104 3152   * Code lifted from libzfs_util.c
3105 3153   */
3106 3154  static int
3107 3155  niceStrToNum(const char *value, uint64_t *num)
3108 3156  {
3109 3157          char *end;
3110 3158          int shift;
3111 3159  
3112 3160          *num = 0;
3113 3161  
3114 3162          /* Check to see if this looks like a number.  */
3115 3163          if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
3116 3164                  return (-1);
3117 3165          }
3118 3166  
3119 3167          /* Rely on stroull() to process the numeric portion.  */
3120 3168          errno = 0;
3121 3169          *num = strtoull(value, &end, 10);
3122 3170  
3123 3171          /*
3124 3172           * Check for ERANGE, which indicates that the value is too large to fit
3125 3173           * in a 64-bit value.
3126 3174           */
3127 3175          if (errno == ERANGE) {
3128 3176                  return (-1);
3129 3177          }
3130 3178  
3131 3179          /*
3132 3180           * If we have a decimal value, then do the computation with floating
3133 3181           * point arithmetic.  Otherwise, use standard arithmetic.
3134 3182           */
3135 3183          if (*end == '.') {
3136 3184                  double fval = strtod(value, &end);
3137 3185  
3138 3186                  if ((shift = strToShift(end)) == -1) {
3139 3187                          return (-1);
3140 3188                  }
3141 3189  
3142 3190                  fval *= pow(2, shift);
3143 3191  
3144 3192                  if (fval > UINT64_MAX) {
3145 3193                          return (-1);
3146 3194                  }
3147 3195  
3148 3196                  *num = (uint64_t)fval;
3149 3197          } else {
3150 3198                  if ((shift = strToShift(end)) == -1) {
3151 3199                          return (-1);
3152 3200                  }
3153 3201  
3154 3202                  /* Check for overflow */
3155 3203                  if (shift >= 64 || (*num << shift) >> shift != *num) {
3156 3204                          return (-1);
3157 3205                  }
3158 3206  
3159 3207                  *num <<= shift;
3160 3208          }
3161 3209  
3162 3210          return (0);
3163 3211  }
3164 3212  
3165 3213  /*
3166 3214   * stmfCreateTargetGroup
3167 3215   *
3168 3216   * Purpose: Create a local port group
3169 3217   *
3170 3218   * targetGroupName - name of local port group to create
3171 3219   */
3172 3220  int
3173 3221  stmfCreateTargetGroup(stmfGroupName *targetGroupName)
3174 3222  {
3175 3223          int ret;
3176 3224          int fd;
3177 3225  
3178 3226          if (targetGroupName == NULL ||
3179 3227              (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
3180 3228              == sizeof (stmfGroupName))) {
3181 3229                  return (STMF_ERROR_INVALID_ARG);
3182 3230          }
3183 3231  
3184 3232          /* Check to ensure service exists */
3185 3233          if (psCheckService() != STMF_STATUS_SUCCESS) {
3186 3234                  return (STMF_ERROR_SERVICE_NOT_FOUND);
3187 3235          }
3188 3236  
3189 3237          /* call init */
3190 3238          ret = initializeConfig();
3191 3239          if (ret != STMF_STATUS_SUCCESS) {
3192 3240                  return (ret);
3193 3241          }
3194 3242  
3195 3243          /*
3196 3244           * Open control node for stmf
3197 3245           */
3198 3246          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3199 3247                  return (ret);
3200 3248  
3201 3249          /*
3202 3250           * Add the group to the driver
3203 3251           */
3204 3252          if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
3205 3253              targetGroupName)) != STMF_STATUS_SUCCESS) {
3206 3254                  goto done;
3207 3255          }
3208 3256  
3209 3257          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
3210 3258                  goto done;
3211 3259          }
3212 3260  
3213 3261          /*
3214 3262           * If the add to the driver was successful, add it to the persistent
3215 3263           * store.
3216 3264           */
3217 3265          ret = psCreateTargetGroup((char *)targetGroupName);
3218 3266          switch (ret) {
3219 3267                  case STMF_PS_SUCCESS:
3220 3268                          ret = STMF_STATUS_SUCCESS;
3221 3269                          break;
3222 3270                  case STMF_PS_ERROR_EXISTS:
3223 3271                          ret = STMF_ERROR_EXISTS;
3224 3272                          break;
3225 3273                  case STMF_PS_ERROR_BUSY:
3226 3274                          ret = STMF_ERROR_BUSY;
3227 3275                          break;
3228 3276                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3229 3277                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
3230 3278                          break;
3231 3279                  case STMF_PS_ERROR_VERSION_MISMATCH:
3232 3280                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
3233 3281                          break;
3234 3282                  default:
3235 3283                          syslog(LOG_DEBUG,
3236 3284                              "stmfCreateTargetGroup:psCreateTargetGroup"
3237 3285                              ":error(%d)", ret);
3238 3286                          ret = STMF_STATUS_ERROR;
3239 3287                          break;
3240 3288          }
3241 3289  
3242 3290  done:
3243 3291          (void) close(fd);
3244 3292          return (ret);
3245 3293  }
3246 3294  
3247 3295  /*
3248 3296   * stmfDeleteHostGroup
3249 3297   *
3250 3298   * Purpose: Delete an initiator or local port group
3251 3299   *
3252 3300   * hostGroupName - group to delete
3253 3301   */
3254 3302  int
3255 3303  stmfDeleteHostGroup(stmfGroupName *hostGroupName)
3256 3304  {
3257 3305          int ret;
3258 3306          int fd;
3259 3307  
3260 3308          if (hostGroupName == NULL) {
3261 3309                  return (STMF_ERROR_INVALID_ARG);
3262 3310          }
3263 3311  
3264 3312          /* Check to ensure service exists */
3265 3313          if (psCheckService() != STMF_STATUS_SUCCESS) {
3266 3314                  return (STMF_ERROR_SERVICE_NOT_FOUND);
3267 3315          }
3268 3316  
3269 3317          /* call init */
3270 3318          ret = initializeConfig();
3271 3319          if (ret != STMF_STATUS_SUCCESS) {
3272 3320                  return (ret);
3273 3321          }
3274 3322  
3275 3323          /*
3276 3324           * Open control node for stmf
3277 3325           */
3278 3326          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3279 3327                  return (ret);
3280 3328  
3281 3329          /*
3282 3330           * Remove the group from the driver
3283 3331           */
3284 3332          if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
3285 3333              hostGroupName)) != STMF_STATUS_SUCCESS) {
3286 3334                  goto done;
3287 3335          }
3288 3336  
3289 3337          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
3290 3338                  goto done;
3291 3339          }
3292 3340  
3293 3341          /*
3294 3342           * If the remove from the driver was successful, remove it from the
3295 3343           * persistent store.
3296 3344           */
3297 3345          ret = psDeleteHostGroup((char *)hostGroupName);
3298 3346          switch (ret) {
3299 3347                  case STMF_PS_SUCCESS:
3300 3348                          ret = STMF_STATUS_SUCCESS;
3301 3349                          break;
3302 3350                  case STMF_PS_ERROR_NOT_FOUND:
3303 3351                          ret = STMF_ERROR_NOT_FOUND;
3304 3352                          break;
3305 3353                  case STMF_PS_ERROR_BUSY:
3306 3354                          ret = STMF_ERROR_BUSY;
3307 3355                          break;
3308 3356                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3309 3357                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
3310 3358                          break;
3311 3359                  case STMF_PS_ERROR_VERSION_MISMATCH:
3312 3360                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
3313 3361                          break;
3314 3362                  default:
3315 3363                          syslog(LOG_DEBUG,
3316 3364                              "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
3317 3365                              ret);
3318 3366                          ret = STMF_STATUS_ERROR;
3319 3367                          break;
3320 3368          }
3321 3369  
3322 3370  done:
3323 3371          (void) close(fd);
3324 3372          return (ret);
3325 3373  }
3326 3374  
3327 3375  /*
3328 3376   * stmfDeleteTargetGroup
3329 3377   *
3330 3378   * Purpose: Delete an initiator or local port group
3331 3379   *
3332 3380   * targetGroupName - group to delete
3333 3381   */
3334 3382  int
3335 3383  stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
3336 3384  {
3337 3385          int ret = STMF_STATUS_SUCCESS;
3338 3386          int fd;
3339 3387  
3340 3388          if (targetGroupName == NULL) {
3341 3389                  return (STMF_ERROR_INVALID_ARG);
3342 3390          }
3343 3391  
3344 3392          /* Check to ensure service exists */
3345 3393          if (psCheckService() != STMF_STATUS_SUCCESS) {
3346 3394                  return (STMF_ERROR_SERVICE_NOT_FOUND);
3347 3395          }
3348 3396  
3349 3397          /* call init */
3350 3398          ret = initializeConfig();
3351 3399          if (ret != STMF_STATUS_SUCCESS) {
3352 3400                  return (ret);
3353 3401          }
3354 3402  
3355 3403          /*
3356 3404           * Open control node for stmf
3357 3405           */
3358 3406          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3359 3407                  return (ret);
3360 3408  
3361 3409          /*
3362 3410           * Remove the group from the driver
3363 3411           */
3364 3412          if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
3365 3413              targetGroupName)) != STMF_STATUS_SUCCESS) {
3366 3414                  goto done;
3367 3415          }
3368 3416  
3369 3417          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
3370 3418                  goto done;
3371 3419          }
3372 3420  
3373 3421          /*
3374 3422           * If the remove from the driver was successful, remove it from the
3375 3423           * persistent store.
3376 3424           */
3377 3425          ret = psDeleteTargetGroup((char *)targetGroupName);
3378 3426          switch (ret) {
3379 3427                  case STMF_PS_SUCCESS:
3380 3428                          ret = STMF_STATUS_SUCCESS;
3381 3429                          break;
3382 3430                  case STMF_PS_ERROR_NOT_FOUND:
3383 3431                          ret = STMF_ERROR_NOT_FOUND;
3384 3432                          break;
3385 3433                  case STMF_PS_ERROR_BUSY:
3386 3434                          ret = STMF_ERROR_BUSY;
3387 3435                          break;
3388 3436                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3389 3437                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
3390 3438                          break;
3391 3439                  case STMF_PS_ERROR_VERSION_MISMATCH:
3392 3440                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
3393 3441                          break;
3394 3442                  default:
3395 3443                          syslog(LOG_DEBUG,
3396 3444                              "stmfDeleteTargetGroup:psDeleteTargetGroup"
3397 3445                              ":error(%d)", ret);
3398 3446                          ret = STMF_STATUS_ERROR;
3399 3447                          break;
3400 3448          }
3401 3449  
3402 3450  done:
3403 3451          (void) close(fd);
3404 3452          return (ret);
3405 3453  }
3406 3454  
3407 3455  /*
3408 3456   * stmfDevidFromIscsiName
3409 3457   *
3410 3458   * Purpose: convert an iSCSI name to an stmf devid
3411 3459   *
3412 3460   * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
3413 3461   * devid - on success, contains the converted iscsi name
3414 3462   */
3415 3463  int
3416 3464  stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
3417 3465  {
3418 3466          if (devid == NULL || iscsiName == NULL)
3419 3467                  return (STMF_ERROR_INVALID_ARG);
3420 3468  
3421 3469          bzero(devid, sizeof (stmfDevid));
3422 3470  
3423 3471          /* Validate size of target */
3424 3472          if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
3425 3473              devid->identLength < strlen(EUI) ||
3426 3474              devid->identLength < strlen(IQN)) {
3427 3475                  return (STMF_ERROR_INVALID_ARG);
3428 3476          }
3429 3477  
3430 3478          if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
3431 3479              strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
3432 3480                  return (STMF_ERROR_INVALID_ARG);
3433 3481          }
3434 3482  
3435 3483          /* copy UTF-8 bytes to ident */
3436 3484          bcopy(iscsiName, devid->ident, devid->identLength);
3437 3485  
3438 3486          return (STMF_STATUS_SUCCESS);
3439 3487  }
3440 3488  
3441 3489  /*
3442 3490   * stmfDevidFromWwn
3443 3491   *
3444 3492   * Purpose: convert a WWN to an stmf devid
3445 3493   *
3446 3494   * wwn - 8-byte wwn identifier
3447 3495   * devid - on success, contains the converted wwn
3448 3496   */
3449 3497  int
3450 3498  stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
3451 3499  {
3452 3500          if (wwn == NULL || devid == NULL)
3453 3501                  return (STMF_ERROR_INVALID_ARG);
3454 3502  
3455 3503          bzero(devid, sizeof (stmfDevid));
3456 3504  
3457 3505          /* Copy eui prefix */
3458 3506          (void) bcopy(WWN, devid->ident, strlen(WWN));
3459 3507  
3460 3508          /* Convert to ASCII uppercase hexadecimal string */
3461 3509          (void) snprintf((char *)&devid->ident[strlen(WWN)],
3462 3510              sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
3463 3511              wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
3464 3512  
3465 3513          devid->identLength = strlen((char *)devid->ident);
3466 3514  
3467 3515          return (STMF_STATUS_SUCCESS);
3468 3516  }
3469 3517  
3470 3518  /*
3471 3519   * stmfFreeMemory
3472 3520   *
3473 3521   * Purpose: Free memory allocated by this library
3474 3522   *
3475 3523   * memory - previously allocated pointer of memory managed by library
3476 3524   */
3477 3525  void
3478 3526  stmfFreeMemory(void *memory)
3479 3527  {
3480 3528          free(memory);
3481 3529  }
3482 3530  
3483 3531  /*
3484 3532   * get host group, target group list from stmf
3485 3533   *
3486 3534   * groupType - HOST_GROUP, TARGET_GROUP
3487 3535   */
3488 3536  static int
3489 3537  groupListIoctl(stmfGroupList **groupList, int groupType)
3490 3538  {
3491 3539          int ret;
3492 3540          int fd;
3493 3541          int ioctlRet;
3494 3542          int i;
3495 3543          int cmd;
3496 3544          stmf_iocdata_t stmfIoctl;
3497 3545          /* framework group list */
3498 3546          stmf_group_name_t *iGroupList = NULL;
3499 3547          uint32_t groupListSize;
3500 3548  
3501 3549          if (groupList == NULL) {
3502 3550                  return (STMF_ERROR_INVALID_ARG);
3503 3551          }
3504 3552  
3505 3553          if (groupType == HOST_GROUP) {
3506 3554                  cmd = STMF_IOCTL_GET_HG_LIST;
3507 3555          } else if (groupType == TARGET_GROUP) {
3508 3556                  cmd = STMF_IOCTL_GET_TG_LIST;
3509 3557          } else {
3510 3558                  return (STMF_ERROR_INVALID_ARG);
3511 3559          }
3512 3560  
3513 3561          /* call init */
3514 3562          ret = initializeConfig();
3515 3563          if (ret != STMF_STATUS_SUCCESS) {
3516 3564                  return (ret);
3517 3565          }
3518 3566  
3519 3567          /*
3520 3568           * Open control node for stmf
3521 3569           */
3522 3570          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3523 3571                  return (ret);
3524 3572  
3525 3573          /*
3526 3574           * Allocate ioctl input buffer
3527 3575           */
3528 3576          groupListSize = ALLOC_GROUP;
3529 3577          groupListSize = groupListSize * (sizeof (stmf_group_name_t));
3530 3578          iGroupList = (stmf_group_name_t *)calloc(1, groupListSize);
3531 3579          if (iGroupList == NULL) {
3532 3580                  ret = STMF_ERROR_NOMEM;
3533 3581                  goto done;
3534 3582          }
3535 3583  
3536 3584          bzero(&stmfIoctl, sizeof (stmfIoctl));
3537 3585          /*
3538 3586           * Issue ioctl to get the group list
3539 3587           */
3540 3588          stmfIoctl.stmf_version = STMF_VERSION_1;
3541 3589          stmfIoctl.stmf_obuf_size = groupListSize;
3542 3590          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
3543 3591          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3544 3592          if (ioctlRet != 0) {
3545 3593                  switch (errno) {
3546 3594                          case EBUSY:
3547 3595                                  ret = STMF_ERROR_BUSY;
3548 3596                                  break;
3549 3597                          case EPERM:
3550 3598                          case EACCES:
3551 3599                                  ret = STMF_ERROR_PERM;
3552 3600                                  break;
3553 3601                          default:
3554 3602                                  syslog(LOG_DEBUG,
3555 3603                                      "groupListIoctl:ioctl errno(%d)",
3556 3604                                      errno);
3557 3605                                  ret = STMF_STATUS_ERROR;
3558 3606                                  break;
3559 3607                  }
3560 3608                  goto done;
3561 3609          }
3562 3610          /*
3563 3611           * Check whether input buffer was large enough
3564 3612           */
3565 3613          if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) {
3566 3614                  groupListSize = stmfIoctl.stmf_obuf_max_nentries *
3567 3615                      sizeof (stmf_group_name_t);
3568 3616                  iGroupList = realloc(iGroupList, groupListSize);
3569 3617                  if (iGroupList == NULL) {
3570 3618                          ret = STMF_ERROR_NOMEM;
3571 3619                          goto done;
3572 3620                  }
3573 3621                  stmfIoctl.stmf_obuf_size = groupListSize;
3574 3622                  stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
3575 3623                  ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3576 3624                  if (ioctlRet != 0) {
3577 3625                          switch (errno) {
3578 3626                                  case EBUSY:
3579 3627                                          ret = STMF_ERROR_BUSY;
3580 3628                                          break;
3581 3629                                  case EPERM:
3582 3630                                  case EACCES:
3583 3631                                          ret = STMF_ERROR_PERM;
3584 3632                                          break;
3585 3633                                  default:
3586 3634                                          syslog(LOG_DEBUG,
3587 3635                                              "groupListIoctl:ioctl errno(%d)",
3588 3636                                              errno);
3589 3637                                          ret = STMF_STATUS_ERROR;
3590 3638                                          break;
3591 3639                          }
3592 3640                          goto done;
3593 3641                  }
3594 3642          }
3595 3643  
3596 3644          /* allocate and copy to caller's buffer */
3597 3645          *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
3598 3646              sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries);
3599 3647          if (*groupList == NULL) {
3600 3648                  ret = STMF_ERROR_NOMEM;
3601 3649                  goto done;
3602 3650          }
3603 3651          (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
3604 3652          for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
3605 3653                  bcopy(iGroupList[i].name, (*groupList)->name[i],
3606 3654                      sizeof (stmfGroupName));
3607 3655          }
3608 3656  
3609 3657  done:
3610 3658          free(iGroupList);
3611 3659          (void) close(fd);
3612 3660          return (ret);
3613 3661  }
3614 3662  
3615 3663  /*
3616 3664   * get host group members, target group members from stmf
3617 3665   *
3618 3666   * groupProps - allocated on success
3619 3667   *
3620 3668   * groupType - HOST_GROUP, TARGET_GROUP
3621 3669   */
3622 3670  static int
3623 3671  groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
3624 3672      int groupType)
3625 3673  {
3626 3674          int ret;
3627 3675          int fd;
3628 3676          int ioctlRet;
3629 3677          int i;
3630 3678          int cmd;
3631 3679          stmf_iocdata_t stmfIoctl;
3632 3680          /* framework group list */
3633 3681          stmf_group_name_t iGroupName;
3634 3682          stmf_ge_ident_t *iGroupMembers;
3635 3683          uint32_t groupListSize;
3636 3684  
3637 3685          if (groupName == NULL) {
3638 3686                  return (STMF_ERROR_INVALID_ARG);
3639 3687          }
3640 3688  
3641 3689          if (groupType == HOST_GROUP) {
3642 3690                  cmd = STMF_IOCTL_GET_HG_ENTRIES;
3643 3691          } else if (groupType == TARGET_GROUP) {
3644 3692                  cmd = STMF_IOCTL_GET_TG_ENTRIES;
3645 3693          } else {
3646 3694                  return (STMF_ERROR_INVALID_ARG);
3647 3695          }
3648 3696  
3649 3697          /* call init */
3650 3698          ret = initializeConfig();
3651 3699          if (ret != STMF_STATUS_SUCCESS) {
3652 3700                  return (ret);
3653 3701          }
3654 3702  
3655 3703          /*
3656 3704           * Open control node for stmf
3657 3705           */
3658 3706          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3659 3707                  return (ret);
3660 3708  
3661 3709          bzero(&iGroupName, sizeof (iGroupName));
3662 3710  
3663 3711          bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
3664 3712  
3665 3713          iGroupName.name_size = strlen((char *)groupName);
3666 3714  
3667 3715          /*
3668 3716           * Allocate ioctl input buffer
3669 3717           */
3670 3718          groupListSize = ALLOC_GRP_MEMBER;
3671 3719          groupListSize = groupListSize * (sizeof (stmf_ge_ident_t));
3672 3720          iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize);
3673 3721          if (iGroupMembers == NULL) {
3674 3722                  ret = STMF_ERROR_NOMEM;
3675 3723                  goto done;
3676 3724          }
3677 3725  
3678 3726          bzero(&stmfIoctl, sizeof (stmfIoctl));
3679 3727          /*
3680 3728           * Issue ioctl to get the group list
3681 3729           */
3682 3730          stmfIoctl.stmf_version = STMF_VERSION_1;
3683 3731          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3684 3732          stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
3685 3733          stmfIoctl.stmf_obuf_size = groupListSize;
3686 3734          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
3687 3735          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3688 3736          if (ioctlRet != 0) {
3689 3737                  switch (errno) {
3690 3738                          case EBUSY:
3691 3739                                  ret = STMF_ERROR_BUSY;
3692 3740                                  break;
3693 3741                          case EPERM:
3694 3742                          case EACCES:
3695 3743                                  ret = STMF_ERROR_PERM;
3696 3744                                  break;
3697 3745                          default:
3698 3746                                  syslog(LOG_DEBUG,
3699 3747                                      "groupListIoctl:ioctl errno(%d)",
3700 3748                                      errno);
3701 3749                                  ret = STMF_STATUS_ERROR;
3702 3750                                  break;
3703 3751                  }
3704 3752                  goto done;
3705 3753          }
3706 3754          /*
3707 3755           * Check whether input buffer was large enough
3708 3756           */
3709 3757          if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) {
3710 3758                  groupListSize = stmfIoctl.stmf_obuf_max_nentries *
3711 3759                      sizeof (stmf_ge_ident_t);
3712 3760                  iGroupMembers = realloc(iGroupMembers, groupListSize);
3713 3761                  if (iGroupMembers == NULL) {
3714 3762                          ret = STMF_ERROR_NOMEM;
3715 3763                          goto done;
3716 3764                  }
3717 3765                  stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3718 3766                  stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
3719 3767                  stmfIoctl.stmf_obuf_size = groupListSize;
3720 3768                  stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
3721 3769                  ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3722 3770                  if (ioctlRet != 0) {
3723 3771                          switch (errno) {
3724 3772                                  case EBUSY:
3725 3773                                          ret = STMF_ERROR_BUSY;
3726 3774                                          break;
3727 3775                                  case EPERM:
3728 3776                                  case EACCES:
3729 3777                                          ret = STMF_ERROR_PERM;
3730 3778                                          break;
3731 3779                                  default:
3732 3780                                          syslog(LOG_DEBUG,
3733 3781                                              "groupListIoctl:ioctl errno(%d)",
3734 3782                                              errno);
3735 3783                                          ret = STMF_STATUS_ERROR;
3736 3784                                          break;
3737 3785                          }
3738 3786                          goto done;
3739 3787                  }
3740 3788          }
3741 3789  
3742 3790          /* allocate and copy to caller's buffer */
3743 3791          *groupProps = (stmfGroupProperties *)calloc(1,
3744 3792              sizeof (stmfGroupProperties) +
3745 3793              sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries);
3746 3794          if (*groupProps == NULL) {
3747 3795                  ret = STMF_ERROR_NOMEM;
3748 3796                  goto done;
3749 3797          }
3750 3798          (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
3751 3799          for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
3752 3800                  (*groupProps)->name[i].identLength =
3753 3801                      iGroupMembers[i].ident_size;
3754 3802                  bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident,
3755 3803                      iGroupMembers[i].ident_size);
3756 3804          }
3757 3805  
3758 3806  done:
3759 3807          free(iGroupMembers);
3760 3808          (void) close(fd);
3761 3809          return (ret);
3762 3810  }
3763 3811  
3764 3812  /*
3765 3813   * Purpose: access persistent config data for host groups and target groups
3766 3814   */
3767 3815  static int
3768 3816  iLoadGroupFromPs(stmfGroupList **groupList, int type)
3769 3817  {
3770 3818          int ret;
3771 3819  
3772 3820          if (groupList == NULL) {
3773 3821                  return (STMF_ERROR_INVALID_ARG);
3774 3822          }
3775 3823  
3776 3824          if (type == HOST_GROUP) {
3777 3825                  ret = psGetHostGroupList(groupList);
3778 3826          } else if (type == TARGET_GROUP) {
3779 3827                  ret = psGetTargetGroupList(groupList);
3780 3828          } else {
3781 3829                  return (STMF_ERROR_INVALID_ARG);
3782 3830          }
3783 3831          switch (ret) {
3784 3832                  case STMF_PS_SUCCESS:
3785 3833                          ret = STMF_STATUS_SUCCESS;
3786 3834                          break;
3787 3835                  case STMF_PS_ERROR_NOT_FOUND:
3788 3836                          ret = STMF_ERROR_NOT_FOUND;
3789 3837                          break;
3790 3838                  case STMF_PS_ERROR_BUSY:
3791 3839                          ret = STMF_ERROR_BUSY;
3792 3840                          break;
3793 3841                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3794 3842                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
3795 3843                          break;
3796 3844                  case STMF_PS_ERROR_VERSION_MISMATCH:
3797 3845                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
3798 3846                          break;
3799 3847                  default:
3800 3848                          syslog(LOG_DEBUG,
3801 3849                              "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
3802 3850                              ret);
3803 3851                          ret = STMF_STATUS_ERROR;
3804 3852                          break;
3805 3853          }
3806 3854  
3807 3855          return (ret);
3808 3856  }
3809 3857  
3810 3858  /*
3811 3859   * stmfGetHostGroupList
3812 3860   *
3813 3861   * Purpose: Retrieves the list of initiator group oids
3814 3862   *
3815 3863   * hostGroupList - pointer to pointer to hostGroupList structure
3816 3864   *                 on success, this contains the host group list.
3817 3865   */
3818 3866  int
3819 3867  stmfGetHostGroupList(stmfGroupList **hostGroupList)
3820 3868  {
3821 3869          int ret = STMF_STATUS_ERROR;
3822 3870  
3823 3871          if (hostGroupList == NULL) {
3824 3872                  return (STMF_ERROR_INVALID_ARG);
3825 3873          }
3826 3874  
3827 3875          ret = groupListIoctl(hostGroupList, HOST_GROUP);
3828 3876          return (ret);
3829 3877  }
3830 3878  
3831 3879  
3832 3880  /*
3833 3881   * Purpose: access persistent config data for host groups and target groups
3834 3882   */
3835 3883  static int
3836 3884  iLoadGroupMembersFromPs(stmfGroupName *groupName,
3837 3885      stmfGroupProperties **groupProp, int type)
3838 3886  {
3839 3887          int ret;
3840 3888  
3841 3889          if (groupName == NULL) {
3842 3890                  return (STMF_ERROR_INVALID_ARG);
3843 3891          }
3844 3892  
3845 3893          if (type == HOST_GROUP) {
3846 3894                  ret = psGetHostGroupMemberList((char *)groupName, groupProp);
3847 3895          } else if (type == TARGET_GROUP) {
3848 3896                  ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
3849 3897          } else {
3850 3898                  return (STMF_ERROR_INVALID_ARG);
3851 3899          }
3852 3900          switch (ret) {
3853 3901                  case STMF_PS_SUCCESS:
3854 3902                          ret = STMF_STATUS_SUCCESS;
3855 3903                          break;
3856 3904                  case STMF_PS_ERROR_NOT_FOUND:
3857 3905                          ret = STMF_ERROR_NOT_FOUND;
3858 3906                          break;
3859 3907                  case STMF_PS_ERROR_BUSY:
3860 3908                          ret = STMF_ERROR_BUSY;
3861 3909                          break;
3862 3910                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3863 3911                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
3864 3912                          break;
3865 3913                  case STMF_PS_ERROR_VERSION_MISMATCH:
3866 3914                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
3867 3915                          break;
3868 3916                  default:
3869 3917                          syslog(LOG_DEBUG,
3870 3918                              "iLoadGroupMembersFromPs:psGetHostGroupList:"
3871 3919                              "error(%d)", ret);
3872 3920                          ret = STMF_STATUS_ERROR;
3873 3921                          break;
3874 3922          }
3875 3923  
3876 3924          return (ret);
3877 3925  }
3878 3926  
3879 3927  /*
3880 3928   * stmfGetHostGroupMembers
3881 3929   *
3882 3930   * Purpose: Retrieves the group properties for a host group
3883 3931   *
3884 3932   * groupName - name of group for which to retrieve host group members.
3885 3933   * groupProp - pointer to pointer to stmfGroupProperties structure
3886 3934   *             on success, this contains the list of group members.
3887 3935   */
3888 3936  int
3889 3937  stmfGetHostGroupMembers(stmfGroupName *groupName,
3890 3938      stmfGroupProperties **groupProp)
3891 3939  {
3892 3940          int ret;
3893 3941  
3894 3942          if (groupName == NULL || groupProp == NULL) {
3895 3943                  return (STMF_ERROR_INVALID_ARG);
3896 3944          }
3897 3945  
3898 3946          ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP);
3899 3947  
3900 3948          return (ret);
3901 3949  }
3902 3950  
3903 3951  /*
3904 3952   * stmfGetProviderData
3905 3953   *
3906 3954   * Purpose: Get provider data list
3907 3955   *
3908 3956   * providerName - name of provider for which to retrieve the data
3909 3957   * nvl - pointer to nvlist_t pointer which will contain the nvlist data
3910 3958   *       retrieved.
3911 3959   * providerType - type of provider for which to retrieve data.
3912 3960   *                  STMF_LU_PROVIDER_TYPE
3913 3961   *                  STMF_PORT_PROVIDER_TYPE
3914 3962   */
3915 3963  int
3916 3964  stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
3917 3965  {
3918 3966          return (stmfGetProviderDataProt(providerName, nvl, providerType,
3919 3967              NULL));
3920 3968  }
3921 3969  
3922 3970  /*
3923 3971   * stmfGetProviderDataProt
3924 3972   *
3925 3973   * Purpose: Get provider data list with token
3926 3974   *
3927 3975   * providerName - name of provider for which to retrieve the data
3928 3976   * nvl - pointer to nvlist_t pointer which will contain the nvlist data
3929 3977   *       retrieved.
3930 3978   * providerType - type of provider for which to retrieve data.
3931 3979   *                  STMF_LU_PROVIDER_TYPE
3932 3980   *                  STMF_PORT_PROVIDER_TYPE
3933 3981   * setToken - Returns the stale data token
3934 3982   */
3935 3983  int
3936 3984  stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
3937 3985      uint64_t *setToken)
3938 3986  {
3939 3987          int ret;
3940 3988  
3941 3989          if (providerName == NULL || nvl == NULL) {
3942 3990                  return (STMF_ERROR_INVALID_ARG);
3943 3991          }
3944 3992          if (providerType != STMF_LU_PROVIDER_TYPE &&
3945 3993              providerType != STMF_PORT_PROVIDER_TYPE) {
3946 3994                  return (STMF_ERROR_INVALID_ARG);
3947 3995          }
3948 3996          /* call init */
3949 3997          ret = initializeConfig();
3950 3998          if (ret != STMF_STATUS_SUCCESS) {
3951 3999                  return (ret);
3952 4000          }
3953 4001          return (getProviderData(providerName, nvl, providerType, setToken));
3954 4002  }
3955 4003  
3956 4004  /*
3957 4005   * stmfGetProviderDataList
3958 4006   *
3959 4007   * Purpose: Get the list of providers currently persisting data
3960 4008   *
3961 4009   * providerList - pointer to pointer to an stmfProviderList structure allocated
3962 4010   *                by the caller. Will contain the list of providers on success.
3963 4011   */
3964 4012  int
3965 4013  stmfGetProviderDataList(stmfProviderList **providerList)
3966 4014  {
3967 4015          int ret;
3968 4016  
3969 4017          ret = psGetProviderDataList(providerList);
3970 4018          switch (ret) {
3971 4019                  case STMF_PS_SUCCESS:
3972 4020                          ret = STMF_STATUS_SUCCESS;
3973 4021                          break;
3974 4022                  case STMF_PS_ERROR_BUSY:
3975 4023                          ret = STMF_ERROR_BUSY;
3976 4024                          break;
3977 4025                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3978 4026                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
3979 4027                          break;
3980 4028                  case STMF_PS_ERROR_VERSION_MISMATCH:
3981 4029                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
3982 4030                          break;
3983 4031                  default:
3984 4032                          syslog(LOG_DEBUG,
3985 4033                              "stmfGetProviderDataList:psGetProviderDataList"
3986 4034                              ":error(%d)", ret);
3987 4035                          ret = STMF_STATUS_ERROR;
3988 4036                          break;
3989 4037          }
3990 4038  
3991 4039          return (ret);
3992 4040  }
3993 4041  
3994 4042  
3995 4043  /*
3996 4044   * stmfGetSessionList
3997 4045   *
3998 4046   * Purpose: Retrieves the session list for a target (devid)
3999 4047   *
4000 4048   * devid - devid of target for which to retrieve session information.
4001 4049   * sessionList - pointer to pointer to stmfSessionList structure
4002 4050   *             on success, this contains the list of initiator sessions.
4003 4051   */
4004 4052  int
4005 4053  stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
4006 4054  {
4007 4055          int ret = STMF_STATUS_SUCCESS;
4008 4056          int fd;
4009 4057          int ioctlRet;
4010 4058          int cmd = STMF_IOCTL_SESSION_LIST;
4011 4059          int i;
4012 4060          stmf_iocdata_t stmfIoctl;
4013 4061          slist_scsi_session_t *fSessionList, *fSessionListP = NULL;
4014 4062          uint8_t ident[260];
4015 4063          uint32_t fSessionListSize;
4016 4064  
4017 4065          if (sessionList == NULL || devid == NULL) {
4018 4066                  ret = STMF_ERROR_INVALID_ARG;
4019 4067          }
4020 4068  
4021 4069          /* call init */
4022 4070          ret = initializeConfig();
4023 4071          if (ret != STMF_STATUS_SUCCESS) {
4024 4072                  return (ret);
4025 4073          }
4026 4074  
4027 4075          /*
4028 4076           * Open control node for stmf
4029 4077           */
4030 4078          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4031 4079                  return (ret);
4032 4080  
4033 4081          /*
4034 4082           * Allocate ioctl input buffer
4035 4083           */
4036 4084          fSessionListSize = ALLOC_SESSION;
4037 4085          fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
4038 4086          fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
4039 4087          fSessionListP = fSessionList;
4040 4088          if (fSessionList == NULL) {
4041 4089                  ret = STMF_ERROR_NOMEM;
4042 4090                  goto done;
4043 4091          }
4044 4092  
4045 4093          ident[IDENT_LENGTH_BYTE] = devid->identLength;
4046 4094          bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
4047 4095              devid->identLength);
4048 4096  
4049 4097          bzero(&stmfIoctl, sizeof (stmfIoctl));
4050 4098          /*
4051 4099           * Issue ioctl to get the session list
4052 4100           */
4053 4101          stmfIoctl.stmf_version = STMF_VERSION_1;
4054 4102          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
4055 4103          stmfIoctl.stmf_ibuf_size = sizeof (ident);
4056 4104          stmfIoctl.stmf_obuf_size = fSessionListSize;
4057 4105          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
4058 4106          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4059 4107          if (ioctlRet != 0) {
4060 4108                  switch (errno) {
4061 4109                          case EBUSY:
4062 4110                                  ret = STMF_ERROR_BUSY;
4063 4111                                  break;
4064 4112                          case EPERM:
4065 4113                          case EACCES:
4066 4114                                  ret = STMF_ERROR_PERM;
4067 4115                                  break;
4068 4116                          default:
4069 4117                                  syslog(LOG_DEBUG,
4070 4118                                      "stmfGetSessionList:ioctl errno(%d)",
4071 4119                                      errno);
4072 4120                                  ret = STMF_STATUS_ERROR;
4073 4121                                  break;
4074 4122                  }
4075 4123                  goto done;
4076 4124          }
4077 4125          /*
4078 4126           * Check whether input buffer was large enough
4079 4127           */
4080 4128          if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) {
4081 4129                  fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
4082 4130                      sizeof (slist_scsi_session_t);
4083 4131                  fSessionList = realloc(fSessionList, fSessionListSize);
4084 4132                  if (fSessionList == NULL) {
4085 4133                          ret = STMF_ERROR_NOMEM;
4086 4134                          goto done;
4087 4135                  }
4088 4136                  fSessionListP = fSessionList;
4089 4137                  stmfIoctl.stmf_obuf_size = fSessionListSize;
4090 4138                  stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
4091 4139                  ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4092 4140                  if (ioctlRet != 0) {
4093 4141                          switch (errno) {
4094 4142                                  case EBUSY:
4095 4143                                          ret = STMF_ERROR_BUSY;
4096 4144                                          break;
4097 4145                                  case EPERM:
4098 4146                                  case EACCES:
4099 4147                                          ret = STMF_ERROR_PERM;
4100 4148                                          break;
4101 4149                                  default:
4102 4150                                          syslog(LOG_DEBUG,
4103 4151                                              "stmfGetSessionList:ioctl "
4104 4152                                              "errno(%d)", errno);
4105 4153                                          ret = STMF_STATUS_ERROR;
4106 4154                                          break;
4107 4155                          }
4108 4156                          goto done;
4109 4157                  }
4110 4158          }
4111 4159  
4112 4160          /*
4113 4161           * allocate caller's buffer with the final size
4114 4162           */
4115 4163          *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
4116 4164              stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
4117 4165          if (*sessionList == NULL) {
4118 4166                  ret = STMF_ERROR_NOMEM;
4119 4167                  free(sessionList);
4120 4168                  goto done;
4121 4169          }
4122 4170  
4123 4171          (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
4124 4172  
4125 4173          /*
4126 4174           * copy session info to caller's buffer
4127 4175           */
4128 4176          for (i = 0; i < (*sessionList)->cnt; i++) {
4129 4177                  (*sessionList)->session[i].initiator.identLength =
4130 4178                      fSessionList->initiator[IDENT_LENGTH_BYTE];
4131 4179                  bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
4132 4180                      (*sessionList)->session[i].initiator.ident,
4133 4181                      STMF_IDENT_LENGTH);
4134 4182                  bcopy(&(fSessionList->alias),
4135 4183                      &((*sessionList)->session[i].alias),
4136 4184                      sizeof ((*sessionList)->session[i].alias));
4137 4185                  bcopy(&(fSessionList++->creation_time),
4138 4186                      &((*sessionList)->session[i].creationTime),
4139 4187                      sizeof (time_t));
4140 4188          }
4141 4189  done:
4142 4190          (void) close(fd);
4143 4191          free(fSessionListP);
4144 4192          return (ret);
4145 4193  }
4146 4194  
4147 4195  /*
4148 4196   * stmfGetTargetGroupList
4149 4197   *
4150 4198   * Purpose: Retrieves the list of target groups
4151 4199   *
4152 4200   * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
4153 4201   *                   success, it contains the list of target groups.
4154 4202   */
4155 4203  int
4156 4204  stmfGetTargetGroupList(stmfGroupList **targetGroupList)
4157 4205  {
4158 4206          int ret;
4159 4207  
4160 4208          if (targetGroupList == NULL) {
4161 4209                  return (STMF_ERROR_INVALID_ARG);
4162 4210          }
4163 4211  
4164 4212          ret = groupListIoctl(targetGroupList, TARGET_GROUP);
4165 4213          return (ret);
4166 4214  }
4167 4215  
4168 4216  /*
4169 4217   * stmfGetTargetGroupMembers
4170 4218   *
4171 4219   * Purpose: Retrieves the group members for a target group
4172 4220   *
4173 4221   * groupName - name of target group for which to retrieve members.
4174 4222   * groupProp - pointer to pointer to stmfGroupProperties structure
4175 4223   *             on success, this contains the list of group members.
4176 4224   */
4177 4225  int
4178 4226  stmfGetTargetGroupMembers(stmfGroupName *groupName,
4179 4227      stmfGroupProperties **groupProp)
4180 4228  {
4181 4229          int ret;
4182 4230  
4183 4231          if (groupName == NULL || groupProp == NULL) {
4184 4232                  return (STMF_ERROR_INVALID_ARG);
4185 4233          }
4186 4234  
4187 4235          ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP);
4188 4236  
4189 4237          return (ret);
4190 4238  }
4191 4239  
4192 4240  /*
4193 4241   * stmfGetTargetList
4194 4242   *
4195 4243   * Purpose: Retrieves the list of target ports
4196 4244   *
4197 4245   * targetList - pointer to a pointer to an stmfDevidList structure.
4198 4246   *                  On success, it contains the list of local ports (target).
4199 4247   */
4200 4248  int
4201 4249  stmfGetTargetList(stmfDevidList **targetList)
4202 4250  {
4203 4251          int ret;
4204 4252          int fd;
4205 4253          int ioctlRet;
4206 4254          int i;
4207 4255          stmf_iocdata_t stmfIoctl;
4208 4256          /* framework target port list */
4209 4257          slist_target_port_t *fTargetList, *fTargetListP = NULL;
4210 4258          uint32_t fTargetListSize;
4211 4259  
4212 4260          if (targetList == NULL) {
4213 4261                  return (STMF_ERROR_INVALID_ARG);
4214 4262          }
4215 4263  
4216 4264          /* call init */
4217 4265          ret = initializeConfig();
4218 4266          if (ret != STMF_STATUS_SUCCESS) {
4219 4267                  return (ret);
4220 4268          }
4221 4269  
4222 4270          /*
4223 4271           * Open control node for stmf
4224 4272           */
4225 4273          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4226 4274                  return (ret);
4227 4275  
4228 4276          /*
4229 4277           * Allocate ioctl input buffer
4230 4278           */
4231 4279          fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t);
4232 4280          fTargetListP = fTargetList =
4233 4281              (slist_target_port_t *)calloc(1, fTargetListSize);
4234 4282          if (fTargetList == NULL) {
4235 4283                  ret = STMF_ERROR_NOMEM;
4236 4284                  goto done;
4237 4285          }
4238 4286  
4239 4287          bzero(&stmfIoctl, sizeof (stmfIoctl));
4240 4288          /*
4241 4289           * Issue ioctl to retrieve target list
4242 4290           */
4243 4291          stmfIoctl.stmf_version = STMF_VERSION_1;
4244 4292          stmfIoctl.stmf_obuf_size = fTargetListSize;
4245 4293          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
4246 4294          ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
4247 4295          if (ioctlRet != 0) {
4248 4296                  switch (errno) {
4249 4297                          case EBUSY:
4250 4298                                  ret = STMF_ERROR_BUSY;
4251 4299                                  break;
4252 4300                          case EPERM:
4253 4301                          case EACCES:
4254 4302                                  ret = STMF_ERROR_PERM;
4255 4303                                  break;
4256 4304                          default:
4257 4305                                  syslog(LOG_DEBUG,
4258 4306                                      "stmfGetTargetList:ioctl errno(%d)", errno);
4259 4307                                  ret = STMF_STATUS_ERROR;
4260 4308                                  break;
4261 4309                  }
4262 4310                  goto done;
4263 4311          }
4264 4312          /*
4265 4313           * Check whether input buffer was large enough
4266 4314           */
4267 4315          if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) {
4268 4316                  fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
4269 4317                      sizeof (slist_target_port_t);
4270 4318                  fTargetListP = fTargetList =
4271 4319                      realloc(fTargetList, fTargetListSize);
4272 4320                  if (fTargetList == NULL) {
4273 4321                          ret = STMF_ERROR_NOMEM;
4274 4322                          goto done;
4275 4323                  }
4276 4324                  stmfIoctl.stmf_obuf_size = fTargetListSize;
4277 4325                  stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
4278 4326                  ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
4279 4327                      &stmfIoctl);
4280 4328                  if (ioctlRet != 0) {
4281 4329                          switch (errno) {
4282 4330                                  case EBUSY:
4283 4331                                          ret = STMF_ERROR_BUSY;
4284 4332                                          break;
4285 4333                                  case EPERM:
4286 4334                                  case EACCES:
4287 4335                                          ret = STMF_ERROR_PERM;
4288 4336                                          break;
4289 4337                                  default:
4290 4338                                          syslog(LOG_DEBUG,
4291 4339                                              "stmfGetTargetList:ioctl errno(%d)",
4292 4340                                              errno);
4293 4341                                          ret = STMF_STATUS_ERROR;
4294 4342                                          break;
4295 4343                          }
4296 4344                          goto done;
4297 4345                  }
4298 4346          }
4299 4347  
4300 4348          *targetList = (stmfDevidList *)calloc(1,
4301 4349              stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
4302 4350              sizeof (stmfDevidList));
4303 4351          if (*targetList == NULL) {
4304 4352                  ret = STMF_ERROR_NOMEM;
4305 4353                  goto done;
4306 4354          }
4307 4355  
4308 4356          (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
4309 4357          for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
4310 4358                  (*targetList)->devid[i].identLength =
4311 4359                      fTargetList->target[IDENT_LENGTH_BYTE];
4312 4360                  bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
4313 4361                      &(*targetList)->devid[i].ident,
4314 4362                      fTargetList->target[IDENT_LENGTH_BYTE]);
4315 4363          }
4316 4364  
4317 4365  done:
4318 4366          (void) close(fd);
4319 4367          free(fTargetListP);
4320 4368          return (ret);
4321 4369  }
4322 4370  
4323 4371  /*
4324 4372   * stmfGetTargetProperties
4325 4373   *
4326 4374   * Purpose:  Retrieves the properties for a logical unit
4327 4375   *
4328 4376   * devid - devid of the target for which to retrieve properties
4329 4377   * targetProps - pointer to an stmfTargetProperties structure.
4330 4378   *              On success, it contains the target properties for
4331 4379   *              the specified devid.
4332 4380   */
4333 4381  int
4334 4382  stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
4335 4383  {
4336 4384          int ret = STMF_STATUS_SUCCESS;
4337 4385          int fd;
4338 4386          int ioctlRet;
4339 4387          stmf_iocdata_t stmfIoctl;
4340 4388          sioc_target_port_props_t targetProperties;
4341 4389          scsi_devid_desc_t *scsiDevid;
4342 4390  
4343 4391          if (devid == NULL || targetProps == NULL) {
4344 4392                  return (STMF_ERROR_INVALID_ARG);
4345 4393          }
4346 4394  
4347 4395          /* call init */
4348 4396          ret = initializeConfig();
4349 4397          if (ret != STMF_STATUS_SUCCESS) {
4350 4398                  return (ret);
4351 4399          }
4352 4400  
4353 4401          /*
4354 4402           * Open control node for stmf
4355 4403           */
4356 4404          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4357 4405                  return (ret);
4358 4406  
4359 4407          targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
4360 4408          bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
4361 4409              devid->identLength);
4362 4410  
4363 4411          bzero(&stmfIoctl, sizeof (stmfIoctl));
4364 4412          /*
4365 4413           * Issue ioctl to add to the host group
4366 4414           */
4367 4415          stmfIoctl.stmf_version = STMF_VERSION_1;
4368 4416          stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
4369 4417          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
4370 4418          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
4371 4419          stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
4372 4420          ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
4373 4421              &stmfIoctl);
4374 4422          if (ioctlRet != 0) {
4375 4423                  switch (errno) {
4376 4424                          case EBUSY:
4377 4425                                  ret = STMF_ERROR_BUSY;
4378 4426                                  break;
4379 4427                          case EPERM:
4380 4428                          case EACCES:
4381 4429                                  ret = STMF_ERROR_PERM;
4382 4430                                  break;
4383 4431                          case ENOENT:
4384 4432                                  ret = STMF_ERROR_NOT_FOUND;
4385 4433                                  break;
4386 4434                          default:
4387 4435                                  syslog(LOG_DEBUG,
4388 4436                                      "stmfGetTargetProperties:ioctl errno(%d)",
4389 4437                                      errno);
4390 4438                                  ret = STMF_STATUS_ERROR;
4391 4439                                  break;
4392 4440                  }
4393 4441                  goto done;
4394 4442          }
4395 4443  
4396 4444          bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
4397 4445              sizeof (targetProperties.tgt_provider_name));
4398 4446          if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
4399 4447                  targetProps->status = STMF_TARGET_PORT_ONLINE;
4400 4448          } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
4401 4449                  targetProps->status = STMF_TARGET_PORT_OFFLINE;
4402 4450          } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
4403 4451                  targetProps->status = STMF_TARGET_PORT_ONLINING;
4404 4452          } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
4405 4453                  targetProps->status = STMF_TARGET_PORT_OFFLINING;
4406 4454          }
4407 4455          bcopy(targetProperties.tgt_alias, targetProps->alias,
4408 4456              sizeof (targetProps->alias));
4409 4457  
4410 4458          scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id;
4411 4459          targetProps->protocol = scsiDevid->protocol_id;
4412 4460  
4413 4461  done:
4414 4462          (void) close(fd);
4415 4463          return (ret);
4416 4464  }
4417 4465  
4418 4466  /*
4419 4467   * stmfGetLogicalUnitList
4420 4468   *
4421 4469   * Purpose: Retrieves list of logical unit Object IDs
4422 4470   *
4423 4471   * luList - pointer to a pointer to a stmfGuidList structure. On success,
4424 4472   *          it contains the list of logical unit guids.
4425 4473   *
4426 4474   */
4427 4475  int
4428 4476  stmfGetLogicalUnitList(stmfGuidList **luList)
4429 4477  {
4430 4478          int ret;
4431 4479          int fd;
4432 4480          int ioctlRet;
4433 4481          int cmd = STMF_IOCTL_LU_LIST;
4434 4482          int i;
4435 4483          stmf_iocdata_t stmfIoctl;
4436 4484          slist_lu_t *fLuList;
4437 4485          uint32_t fLuListSize;
4438 4486          uint32_t listCnt;
4439 4487  
4440 4488          if (luList == NULL) {
4441 4489                  return (STMF_ERROR_INVALID_ARG);
4442 4490          }
4443 4491  
4444 4492          /* call init */
4445 4493          ret = initializeConfig();
4446 4494          if (ret != STMF_STATUS_SUCCESS) {
4447 4495                  return (ret);
4448 4496          }
4449 4497  
4450 4498          /*
4451 4499           * Open control node for stmf
4452 4500           */
4453 4501          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4454 4502                  return (ret);
4455 4503  
4456 4504          /*
4457 4505           * Allocate ioctl input buffer
4458 4506           */
4459 4507          fLuListSize = ALLOC_LU;
4460 4508          fLuListSize = fLuListSize * (sizeof (slist_lu_t));
4461 4509          fLuList = (slist_lu_t *)calloc(1, fLuListSize);
4462 4510          if (fLuList == NULL) {
4463 4511                  ret = STMF_ERROR_NOMEM;
4464 4512                  goto done;
4465 4513          }
4466 4514  
4467 4515          bzero(&stmfIoctl, sizeof (stmfIoctl));
4468 4516          /*
4469 4517           * Issue ioctl to get the LU list
4470 4518           */
4471 4519          stmfIoctl.stmf_version = STMF_VERSION_1;
4472 4520          stmfIoctl.stmf_obuf_size = fLuListSize;
4473 4521          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
4474 4522          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4475 4523          if (ioctlRet != 0) {
4476 4524                  switch (errno) {
4477 4525                          case EBUSY:
4478 4526                                  ret = STMF_ERROR_BUSY;
4479 4527                                  break;
4480 4528                          case EPERM:
4481 4529                          case EACCES:
4482 4530                                  ret = STMF_ERROR_PERM;
4483 4531                                  break;
4484 4532                          default:
4485 4533                                  syslog(LOG_DEBUG,
4486 4534                                      "stmfGetLogicalUnitList:ioctl errno(%d)",
4487 4535                                      errno);
4488 4536                                  ret = STMF_STATUS_ERROR;
4489 4537                                  break;
4490 4538                  }
4491 4539                  goto done;
4492 4540          }
4493 4541          /*
4494 4542           * Check whether input buffer was large enough
4495 4543           */
4496 4544          if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) {
4497 4545                  fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
4498 4546                      sizeof (slist_lu_t);
4499 4547                  free(fLuList);
4500 4548                  fLuList = (slist_lu_t *)calloc(1, fLuListSize);
4501 4549                  if (fLuList == NULL) {
4502 4550                          ret = STMF_ERROR_NOMEM;
4503 4551                          goto done;
4504 4552                  }
4505 4553                  stmfIoctl.stmf_obuf_size = fLuListSize;
4506 4554                  stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
4507 4555                  ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4508 4556                  if (ioctlRet != 0) {
4509 4557                          switch (errno) {
4510 4558                                  case EBUSY:
4511 4559                                          ret = STMF_ERROR_BUSY;
4512 4560                                          break;
4513 4561                                  case EPERM:
4514 4562                                  case EACCES:
4515 4563                                          ret = STMF_ERROR_PERM;
4516 4564                                          break;
4517 4565                                  default:
4518 4566                                          syslog(LOG_DEBUG,
4519 4567                                              "stmfGetLogicalUnitList:"
4520 4568                                              "ioctl errno(%d)", errno);
4521 4569                                          ret = STMF_STATUS_ERROR;
4522 4570                                          break;
4523 4571                          }
4524 4572                          goto done;
4525 4573                  }
4526 4574          }
4527 4575  
4528 4576          if (ret != STMF_STATUS_SUCCESS) {
4529 4577                  goto done;
4530 4578          }
4531 4579  
4532 4580          listCnt = stmfIoctl.stmf_obuf_nentries;
4533 4581  
4534 4582          /*
4535 4583           * allocate caller's buffer with the final size
4536 4584           */
4537 4585          *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
4538 4586              listCnt * sizeof (stmfGuid));
4539 4587          if (*luList == NULL) {
4540 4588                  ret = STMF_ERROR_NOMEM;
4541 4589                  goto done;
4542 4590          }
4543 4591  
4544 4592          (*luList)->cnt = listCnt;
4545 4593  
4546 4594          /* copy to caller's buffer */
4547 4595          for (i = 0; i < listCnt; i++) {
4548 4596                  bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid,
4549 4597                      sizeof (stmfGuid));
4550 4598          }
4551 4599  
4552 4600          /*
4553 4601           * sort the list. This gives a consistent view across gets
4554 4602           */
4555 4603          qsort((void *)&((*luList)->guid[0]), (*luList)->cnt,
4556 4604              sizeof (stmfGuid), guidCompare);
4557 4605  
4558 4606  done:
4559 4607          (void) close(fd);
4560 4608          /*
4561 4609           * free internal buffers
4562 4610           */
4563 4611          free(fLuList);
4564 4612          return (ret);
4565 4613  }
4566 4614  
4567 4615  /*
4568 4616   * stmfGetLogicalUnitProperties
4569 4617   *
4570 4618   * Purpose:  Retrieves the properties for a logical unit
4571 4619   *
4572 4620   * lu - guid of the logical unit for which to retrieve properties
4573 4621   * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
4574 4622   *               it contains the logical unit properties for the specified guid.
4575 4623   */
4576 4624  int
4577 4625  stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
4578 4626  {
4579 4627          int ret = STMF_STATUS_SUCCESS;
4580 4628          int stmfRet;
4581 4629          int fd;
4582 4630          int ioctlRet;
4583 4631          int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
4584 4632          stmfViewEntryList *viewEntryList = NULL;
4585 4633          stmf_iocdata_t stmfIoctl;
4586 4634          sioc_lu_props_t fLuProps;
4587 4635  
4588 4636          if (lu == NULL || luProps == NULL) {
4589 4637                  return (STMF_ERROR_INVALID_ARG);
4590 4638          }
4591 4639  
4592 4640          bzero(luProps, sizeof (stmfLogicalUnitProperties));
4593 4641  
4594 4642          /* call init */
4595 4643          ret = initializeConfig();
4596 4644          if (ret != STMF_STATUS_SUCCESS) {
4597 4645                  return (ret);
4598 4646          }
4599 4647  
4600 4648          /*
4601 4649           * Open control node for stmf
4602 4650           */
4603 4651          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4604 4652                  return (ret);
4605 4653  
4606 4654          bzero(&stmfIoctl, sizeof (stmfIoctl));
4607 4655          /*
4608 4656           * Issue ioctl to add to the host group
4609 4657           */
4610 4658          stmfIoctl.stmf_version = STMF_VERSION_1;
4611 4659          stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
4612 4660          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
4613 4661          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
4614 4662          stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
4615 4663          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4616 4664          if (ioctlRet != 0) {
4617 4665                  switch (errno) {
4618 4666                          case EBUSY:
4619 4667                                  ret = STMF_ERROR_BUSY;
4620 4668                                  break;
4621 4669                          case EPERM:
4622 4670                          case EACCES:
4623 4671                                  ret = STMF_ERROR_PERM;
4624 4672                                  break;
4625 4673                          case ENOENT:
4626 4674                                  stmfRet = stmfGetViewEntryList(lu,
4627 4675                                      &viewEntryList);
4628 4676                                  if (stmfRet == STMF_STATUS_SUCCESS) {
4629 4677                                          luProps->status =
4630 4678                                              STMF_LOGICAL_UNIT_UNREGISTERED;
4631 4679                                          if (viewEntryList->cnt > 0) {
4632 4680                                                  ret = STMF_STATUS_SUCCESS;
4633 4681                                          } else {
4634 4682                                                  ret = STMF_ERROR_NOT_FOUND;
4635 4683                                          }
4636 4684                                  } else {
4637 4685                                          ret = STMF_ERROR_NOT_FOUND;
4638 4686                                  }
4639 4687                                  stmfFreeMemory(viewEntryList);
4640 4688                                  break;
4641 4689                          default:
4642 4690                                  syslog(LOG_DEBUG,
4643 4691                                      "stmfGetLogicalUnit:ioctl errno(%d)",
4644 4692                                      errno);
4645 4693                                  ret = STMF_STATUS_ERROR;
4646 4694                                  break;
4647 4695                  }
4648 4696                  goto done;
4649 4697          }
4650 4698  
4651 4699          bcopy(fLuProps.lu_provider_name, luProps->providerName,
4652 4700              sizeof (fLuProps.lu_provider_name));
4653 4701          if (fLuProps.lu_state == STMF_STATE_ONLINE) {
4654 4702                  luProps->status = STMF_LOGICAL_UNIT_ONLINE;
4655 4703          } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
4656 4704                  luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
4657 4705          } else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
4658 4706                  luProps->status = STMF_LOGICAL_UNIT_ONLINING;
4659 4707          } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
4660 4708                  luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
4661 4709          }
4662 4710          bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
4663 4711  done:
4664 4712          (void) close(fd);
4665 4713          return (ret);
4666 4714  }
4667 4715  
4668 4716  /*
4669 4717   * stmfGetState
4670 4718   *
4671 4719   * Purpose: retrieve the current state of the stmf module
4672 4720   *
4673 4721   * state - pointer to stmfState structure allocated by the caller
4674 4722   *         On success, contains the state of stmf
4675 4723   */
4676 4724  int
4677 4725  stmfGetState(stmfState *state)
4678 4726  {
4679 4727          int ret;
4680 4728          stmf_state_desc_t iState;
4681 4729  
4682 4730          if (state == NULL) {
4683 4731                  return (STMF_ERROR_INVALID_ARG);
4684 4732          }
4685 4733  
4686 4734          ret = getStmfState(&iState);
4687 4735          if (ret != STMF_STATUS_SUCCESS) {
4688 4736                  return (ret);
4689 4737          }
4690 4738          switch (iState.state) {
4691 4739                  case STMF_STATE_ONLINE:
4692 4740                          state->operationalState =
4693 4741                              STMF_SERVICE_STATE_ONLINE;
4694 4742                          break;
4695 4743                  case STMF_STATE_OFFLINE:
4696 4744                          state->operationalState =
4697 4745                              STMF_SERVICE_STATE_OFFLINE;
4698 4746                          break;
4699 4747                  case STMF_STATE_ONLINING:
4700 4748                          state->operationalState =
4701 4749                              STMF_SERVICE_STATE_ONLINING;
4702 4750                          break;
4703 4751                  case STMF_STATE_OFFLINING:
4704 4752                          state->operationalState =
4705 4753                              STMF_SERVICE_STATE_OFFLINING;
4706 4754                          break;
4707 4755                  default:
4708 4756                          state->operationalState =
4709 4757                              STMF_SERVICE_STATE_UNKNOWN;
4710 4758                          break;
4711 4759          }
4712 4760          switch (iState.config_state) {
4713 4761                  case STMF_CONFIG_NONE:
4714 4762                          state->configState = STMF_CONFIG_STATE_NONE;
4715 4763                          break;
4716 4764                  case STMF_CONFIG_INIT:
4717 4765                          state->configState = STMF_CONFIG_STATE_INIT;
4718 4766                          break;
4719 4767                  case STMF_CONFIG_INIT_DONE:
4720 4768                          state->configState =
4721 4769                              STMF_CONFIG_STATE_INIT_DONE;
4722 4770                          break;
4723 4771                  default:
4724 4772                          state->configState =
4725 4773                              STMF_CONFIG_STATE_UNKNOWN;
4726 4774                          break;
4727 4775          }
4728 4776          return (STMF_STATUS_SUCCESS);
4729 4777  }
4730 4778  
4731 4779  /*
4732 4780   * stmfGetViewEntryList
4733 4781   *
4734 4782   * Purpose: Retrieves the list of view entries for the specified
4735 4783   *          logical unit.
4736 4784   *
4737 4785   * lu - the guid of the logical unit for which to retrieve the view entry list
4738 4786   * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
4739 4787   *                 success, contains the list of view entries.
4740 4788   */
4741 4789  int
4742 4790  stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
4743 4791  {
4744 4792          int ret;
4745 4793          int fd;
4746 4794          int ioctlRet;
4747 4795          int cmd = STMF_IOCTL_LU_VE_LIST;
4748 4796          int i;
4749 4797          stmf_iocdata_t stmfIoctl;
4750 4798          stmf_view_op_entry_t *fVeList;
4751 4799          uint32_t fVeListSize;
4752 4800          uint32_t listCnt;
4753 4801  
4754 4802          if (lu == NULL || viewEntryList == NULL) {
4755 4803                  return (STMF_ERROR_INVALID_ARG);
4756 4804          }
4757 4805  
4758 4806          /* call init */
4759 4807          ret = initializeConfig();
4760 4808          if (ret != STMF_STATUS_SUCCESS) {
4761 4809                  return (ret);
4762 4810          }
4763 4811  
4764 4812          /*
4765 4813           * Open control node for stmf
4766 4814           */
4767 4815          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4768 4816                  return (ret);
4769 4817  
4770 4818          /*
4771 4819           * Allocate ioctl input buffer
4772 4820           */
4773 4821          fVeListSize = ALLOC_VE;
4774 4822          fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t));
4775 4823          fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
4776 4824          if (fVeList == NULL) {
4777 4825                  ret = STMF_ERROR_NOMEM;
4778 4826                  goto done;
4779 4827          }
4780 4828  
4781 4829          bzero(&stmfIoctl, sizeof (stmfIoctl));
4782 4830          /*
4783 4831           * Issue ioctl to get the LU list
4784 4832           */
4785 4833          stmfIoctl.stmf_version = STMF_VERSION_1;
4786 4834          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
4787 4835          stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
4788 4836          stmfIoctl.stmf_obuf_size = fVeListSize;
4789 4837          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
4790 4838          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4791 4839          if (ioctlRet != 0) {
4792 4840                  switch (errno) {
4793 4841                          case EBUSY:
4794 4842                                  ret = STMF_ERROR_BUSY;
4795 4843                                  break;
4796 4844                          case EPERM:
4797 4845                          case EACCES:
4798 4846                                  ret = STMF_ERROR_PERM;
4799 4847                                  break;
4800 4848                          default:
4801 4849                                  syslog(LOG_DEBUG,
4802 4850                                      "stmfGetViewEntryList:ioctl errno(%d)",
4803 4851                                      errno);
4804 4852                                  ret = STMF_STATUS_ERROR;
4805 4853                                  break;
4806 4854                  }
4807 4855                  goto done;
4808 4856          }
4809 4857          /*
4810 4858           * Check whether input buffer was large enough
4811 4859           */
4812 4860          if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) {
4813 4861                  bzero(&stmfIoctl, sizeof (stmfIoctl));
4814 4862                  fVeListSize = stmfIoctl.stmf_obuf_max_nentries *
4815 4863                      sizeof (stmf_view_op_entry_t);
4816 4864                  free(fVeList);
4817 4865                  fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
4818 4866                  if (fVeList == NULL) {
4819 4867                          return (STMF_ERROR_NOMEM);
4820 4868                  }
4821 4869                  stmfIoctl.stmf_obuf_size = fVeListSize;
4822 4870                  stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
4823 4871                  ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4824 4872                  if (ioctlRet != 0) {
4825 4873                          switch (errno) {
4826 4874                                  case EBUSY:
4827 4875                                          ret = STMF_ERROR_BUSY;
4828 4876                                          break;
4829 4877                                  case EPERM:
4830 4878                                  case EACCES:
4831 4879                                          ret = STMF_ERROR_PERM;
4832 4880                                          break;
4833 4881                                  default:
4834 4882                                          syslog(LOG_DEBUG,
4835 4883                                              "stmfGetLogicalUnitList:"
4836 4884                                              "ioctl errno(%d)", errno);
4837 4885                                          ret = STMF_STATUS_ERROR;
4838 4886                                          break;
4839 4887                          }
4840 4888                          goto done;
4841 4889                  }
4842 4890          }
4843 4891  
4844 4892          if (ret != STMF_STATUS_SUCCESS) {
4845 4893                  goto done;
4846 4894          }
4847 4895  
4848 4896          listCnt = stmfIoctl.stmf_obuf_nentries;
4849 4897  
4850 4898          /*
4851 4899           * allocate caller's buffer with the final size
4852 4900           */
4853 4901          *viewEntryList = (stmfViewEntryList *)calloc(1,
4854 4902              sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry));
4855 4903          if (*viewEntryList == NULL) {
4856 4904                  ret = STMF_ERROR_NOMEM;
4857 4905                  goto done;
4858 4906          }
4859 4907  
4860 4908          (*viewEntryList)->cnt = listCnt;
4861 4909  
4862 4910          /* copy to caller's buffer */
4863 4911          for (i = 0; i < listCnt; i++) {
4864 4912                  (*viewEntryList)->ve[i].veIndexValid = B_TRUE;
4865 4913                  (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx;
4866 4914                  if (fVeList[i].ve_all_hosts == 1) {
4867 4915                          (*viewEntryList)->ve[i].allHosts = B_TRUE;
4868 4916                  } else {
4869 4917                          bcopy(fVeList[i].ve_host_group.name,
4870 4918                              (*viewEntryList)->ve[i].hostGroup,
4871 4919                              fVeList[i].ve_host_group.name_size);
4872 4920                  }
4873 4921                  if (fVeList[i].ve_all_targets == 1) {
4874 4922                          (*viewEntryList)->ve[i].allTargets = B_TRUE;
4875 4923                  } else {
4876 4924                          bcopy(fVeList[i].ve_target_group.name,
4877 4925                              (*viewEntryList)->ve[i].targetGroup,
4878 4926                              fVeList[i].ve_target_group.name_size);
4879 4927                  }
4880 4928                  bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr,
4881 4929                      sizeof ((*viewEntryList)->ve[i].luNbr));
4882 4930                  (*viewEntryList)->ve[i].luNbrValid = B_TRUE;
4883 4931          }
4884 4932  
4885 4933          /*
4886 4934           * sort the list. This gives a consistent view across gets
4887 4935           */
4888 4936          qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
4889 4937              sizeof (stmfViewEntry), viewEntryCompare);
4890 4938  
4891 4939  done:
4892 4940          (void) close(fd);
4893 4941          /*
4894 4942           * free internal buffers
4895 4943           */
4896 4944          free(fVeList);
4897 4945          return (ret);
4898 4946  }
4899 4947  
4900 4948  
4901 4949  /*
4902 4950   * loadHostGroups
4903 4951   *
4904 4952   * Purpose - issues the ioctl to load the host groups into stmf
4905 4953   *
4906 4954   * fd - file descriptor for the control node of stmf.
4907 4955   * groupList - populated host group list
4908 4956   */
4909 4957  static int
4910 4958  loadHostGroups(int fd, stmfGroupList *groupList)
4911 4959  {
4912 4960          int i, j;
4913 4961          int ret = STMF_STATUS_SUCCESS;
4914 4962          stmfGroupProperties *groupProps = NULL;
4915 4963  
4916 4964          for (i = 0; i < groupList->cnt; i++) {
4917 4965                  if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
4918 4966                      &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
4919 4967                          goto out;
4920 4968                  }
4921 4969                  ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
4922 4970                      &groupProps, HOST_GROUP);
4923 4971                  for (j = 0; j < groupProps->cnt; j++) {
4924 4972                          if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
4925 4973                              &(groupList->name[i]), &(groupProps->name[j])))
4926 4974                              != STMF_STATUS_SUCCESS) {
4927 4975                                  goto out;
4928 4976                          }
4929 4977                  }
4930 4978          }
4931 4979  
4932 4980  
4933 4981  out:
4934 4982          stmfFreeMemory(groupProps);
4935 4983          return (ret);
4936 4984  }
4937 4985  
4938 4986  /*
4939 4987   * loadTargetGroups
4940 4988   *
4941 4989   * Purpose - issues the ioctl to load the target groups into stmf
4942 4990   *
4943 4991   * fd - file descriptor for the control node of stmf.
4944 4992   * groupList - populated target group list.
4945 4993   */
4946 4994  static int
4947 4995  loadTargetGroups(int fd, stmfGroupList *groupList)
4948 4996  {
4949 4997          int i, j;
4950 4998          int ret = STMF_STATUS_SUCCESS;
4951 4999          stmfGroupProperties *groupProps = NULL;
4952 5000  
4953 5001          for (i = 0; i < groupList->cnt; i++) {
4954 5002                  if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
4955 5003                      &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
4956 5004                          goto out;
4957 5005                  }
4958 5006                  ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
4959 5007                      &groupProps, TARGET_GROUP);
4960 5008                  for (j = 0; j < groupProps->cnt; j++) {
4961 5009                          if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
4962 5010                              &(groupList->name[i]), &(groupProps->name[j])))
4963 5011                              != STMF_STATUS_SUCCESS) {
4964 5012                                  goto out;
4965 5013                          }
4966 5014                  }
4967 5015          }
4968 5016  
4969 5017  
4970 5018  out:
4971 5019          stmfFreeMemory(groupProps);
4972 5020          return (ret);
4973 5021  }
4974 5022  
4975 5023  
4976 5024  /*
4977 5025   * loadStore
4978 5026   *
4979 5027   * Purpose: Load the configuration data from the store
4980 5028   *
4981 5029   * First load the host groups and target groups, then the view entries
4982 5030   * and finally the provider data
4983 5031   *
4984 5032   * fd - file descriptor of control node for stmf.
4985 5033   */
4986 5034  static int
4987 5035  loadStore(int fd)
4988 5036  {
4989 5037          int ret;
4990 5038          int i, j;
4991 5039          stmfGroupList *groupList = NULL;
4992 5040          stmfGuidList *guidList = NULL;
4993 5041          stmfViewEntryList *viewEntryList = NULL;
4994 5042          stmfProviderList *providerList = NULL;
4995 5043          int providerType;
4996 5044          nvlist_t *nvl = NULL;
4997 5045  
4998 5046  
4999 5047  
5000 5048          /* load host groups */
5001 5049          ret = iLoadGroupFromPs(&groupList, HOST_GROUP);
5002 5050          if (ret != STMF_STATUS_SUCCESS) {
5003 5051                  return (ret);
5004 5052          }
5005 5053          ret = loadHostGroups(fd, groupList);
5006 5054          if (ret != STMF_STATUS_SUCCESS) {
5007 5055                  goto out;
5008 5056          }
5009 5057  
5010 5058          stmfFreeMemory(groupList);
5011 5059          groupList = NULL;
5012 5060  
5013 5061          /* load target groups */
5014 5062          ret = iLoadGroupFromPs(&groupList, TARGET_GROUP);
5015 5063          if (ret != STMF_STATUS_SUCCESS) {
5016 5064                  goto out;
5017 5065          }
5018 5066          ret = loadTargetGroups(fd, groupList);
5019 5067          if (ret != STMF_STATUS_SUCCESS) {
5020 5068                  goto out;
5021 5069          }
5022 5070  
5023 5071          stmfFreeMemory(groupList);
5024 5072          groupList = NULL;
5025 5073  
5026 5074          /* Get the guid list */
5027 5075          ret = psGetLogicalUnitList(&guidList);
5028 5076          switch (ret) {
5029 5077                  case STMF_PS_SUCCESS:
5030 5078                          ret = STMF_STATUS_SUCCESS;
5031 5079                          break;
5032 5080                  case STMF_PS_ERROR_NOT_FOUND:
5033 5081                          ret = STMF_ERROR_NOT_FOUND;
5034 5082                          break;
5035 5083                  case STMF_PS_ERROR_BUSY:
5036 5084                          ret = STMF_ERROR_BUSY;
5037 5085                          break;
5038 5086                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5039 5087                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
5040 5088                          break;
5041 5089                  case STMF_PS_ERROR_VERSION_MISMATCH:
5042 5090                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
5043 5091                          break;
5044 5092                  default:
5045 5093                          ret = STMF_STATUS_ERROR;
5046 5094                          break;
5047 5095          }
5048 5096  
5049 5097          if (ret != STMF_STATUS_SUCCESS) {
5050 5098                  goto out;
5051 5099          }
5052 5100  
5053 5101          /*
5054 5102           * We have the guid list, now get the corresponding
5055 5103           * view entries for each guid
5056 5104           */
5057 5105          for (i = 0; i < guidList->cnt; i++) {
5058 5106                  ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
5059 5107                  switch (ret) {
5060 5108                          case STMF_PS_SUCCESS:
5061 5109                                  ret = STMF_STATUS_SUCCESS;
5062 5110                                  break;
5063 5111                          case STMF_PS_ERROR_NOT_FOUND:
5064 5112                                  ret = STMF_ERROR_NOT_FOUND;
5065 5113                                  break;
5066 5114                          case STMF_PS_ERROR_BUSY:
5067 5115                                  ret = STMF_ERROR_BUSY;
5068 5116                                  break;
5069 5117                          case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5070 5118                                  ret = STMF_ERROR_SERVICE_NOT_FOUND;
5071 5119                                  break;
5072 5120                          case STMF_PS_ERROR_VERSION_MISMATCH:
5073 5121                                  ret = STMF_ERROR_SERVICE_DATA_VERSION;
5074 5122                                  break;
5075 5123                          default:
5076 5124                                  ret = STMF_STATUS_ERROR;
5077 5125                                  break;
5078 5126                  }
5079 5127                  if (ret != STMF_STATUS_SUCCESS) {
5080 5128                          goto out;
5081 5129                  }
5082 5130                  for (j = 0; j < viewEntryList->cnt; j++) {
5083 5131                          ret = addViewEntryIoctl(fd, &guidList->guid[i],
5084 5132                              &viewEntryList->ve[j]);
5085 5133                          if (ret != STMF_STATUS_SUCCESS) {
5086 5134                                  goto out;
5087 5135                          }
5088 5136                  }
5089 5137          }
5090 5138  
5091 5139          /* get the list of providers that have data */
5092 5140          ret = psGetProviderDataList(&providerList);
5093 5141          switch (ret) {
5094 5142                  case STMF_PS_SUCCESS:
5095 5143                          ret = STMF_STATUS_SUCCESS;
5096 5144                          break;
5097 5145                  case STMF_PS_ERROR_NOT_FOUND:
5098 5146                          ret = STMF_ERROR_NOT_FOUND;
5099 5147                          break;
5100 5148                  case STMF_PS_ERROR_BUSY:
5101 5149                          ret = STMF_ERROR_BUSY;
5102 5150                          break;
5103 5151                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5104 5152                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
5105 5153                          break;
5106 5154                  case STMF_PS_ERROR_VERSION_MISMATCH:
5107 5155                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
5108 5156                          break;
5109 5157                  default:
5110 5158                          ret = STMF_STATUS_ERROR;
5111 5159                          break;
5112 5160          }
5113 5161          if (ret != STMF_STATUS_SUCCESS) {
5114 5162                  goto out;
5115 5163          }
5116 5164  
5117 5165          for (i = 0; i < providerList->cnt; i++) {
5118 5166                  providerType = providerList->provider[i].providerType;
5119 5167                  ret = psGetProviderData(providerList->provider[i].name,
5120 5168                      &nvl, providerType, NULL);
5121 5169                  switch (ret) {
5122 5170                          case STMF_PS_SUCCESS:
5123 5171                                  ret = STMF_STATUS_SUCCESS;
5124 5172                                  break;
5125 5173                          case STMF_PS_ERROR_NOT_FOUND:
5126 5174                                  ret = STMF_ERROR_NOT_FOUND;
5127 5175                                  break;
5128 5176                          case STMF_PS_ERROR_BUSY:
5129 5177                                  ret = STMF_ERROR_BUSY;
5130 5178                                  break;
5131 5179                          case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5132 5180                                  ret = STMF_ERROR_SERVICE_NOT_FOUND;
5133 5181                                  break;
5134 5182                          case STMF_PS_ERROR_VERSION_MISMATCH:
5135 5183                                  ret = STMF_ERROR_SERVICE_DATA_VERSION;
5136 5184                                  break;
5137 5185                          default:
5138 5186                                  ret = STMF_STATUS_ERROR;
5139 5187                                  break;
5140 5188                  }
5141 5189                  if (ret != STMF_STATUS_SUCCESS) {
5142 5190                          goto out;
5143 5191                  }
5144 5192  
5145 5193                  /* call setProviderData */
5146 5194                  ret = setProviderData(fd, providerList->provider[i].name, nvl,
5147 5195                      providerType, NULL);
5148 5196                  switch (ret) {
5149 5197                          case STMF_PS_SUCCESS:
5150 5198                                  ret = STMF_STATUS_SUCCESS;
5151 5199                                  break;
5152 5200                          case STMF_PS_ERROR_NOT_FOUND:
5153 5201                                  ret = STMF_ERROR_NOT_FOUND;
5154 5202                                  break;
5155 5203                          case STMF_PS_ERROR_BUSY:
5156 5204                                  ret = STMF_ERROR_BUSY;
5157 5205                                  break;
5158 5206                          case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5159 5207                                  ret = STMF_ERROR_SERVICE_NOT_FOUND;
5160 5208                                  break;
5161 5209                          case STMF_PS_ERROR_VERSION_MISMATCH:
5162 5210                                  ret = STMF_ERROR_SERVICE_DATA_VERSION;
5163 5211                                  break;
5164 5212                          default:
5165 5213                                  ret = STMF_STATUS_ERROR;
5166 5214                                  break;
5167 5215                  }
5168 5216                  if (ret != STMF_STATUS_SUCCESS) {
5169 5217                          goto out;
5170 5218                  }
5171 5219  
5172 5220                  nvlist_free(nvl);
5173 5221                  nvl = NULL;
5174 5222          }
5175 5223  out:
5176 5224          if (groupList != NULL) {
5177 5225                  free(groupList);
5178 5226          }
5179 5227          if (guidList != NULL) {
5180 5228                  free(guidList);
5181 5229          }
5182 5230          if (viewEntryList != NULL) {
5183 5231                  free(viewEntryList);
5184 5232          }
5185 5233          if (nvl != NULL) {
5186 5234                  nvlist_free(nvl);
5187 5235          }
5188 5236          return (ret);
5189 5237  }
5190 5238  
5191 5239  /*
5192 5240   * stmfGetAluaState
5193 5241   *
5194 5242   * Purpose - Get the alua state
5195 5243   *
5196 5244   */
5197 5245  int
5198 5246  stmfGetAluaState(boolean_t *enabled, uint32_t *node)
5199 5247  {
5200 5248          int ret = STMF_STATUS_SUCCESS;
5201 5249          int fd;
5202 5250          stmf_iocdata_t stmfIoctl = {0};
5203 5251          stmf_alua_state_desc_t alua_state = {0};
5204 5252          int ioctlRet;
5205 5253  
5206 5254          if (enabled == NULL || node == NULL) {
5207 5255                  return (STMF_ERROR_INVALID_ARG);
5208 5256          }
5209 5257  
5210 5258          /*
5211 5259           * Open control node for stmf
5212 5260           */
5213 5261          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5214 5262                  return (ret);
5215 5263  
5216 5264          /*
5217 5265           * Issue ioctl to get the stmf state
5218 5266           */
5219 5267          stmfIoctl.stmf_version = STMF_VERSION_1;
5220 5268          stmfIoctl.stmf_obuf_size = sizeof (alua_state);
5221 5269          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state;
5222 5270          ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl);
5223 5271  
5224 5272          (void) close(fd);
5225 5273  
5226 5274          if (ioctlRet != 0) {
5227 5275                  switch (errno) {
5228 5276                          case EBUSY:
5229 5277                                  ret = STMF_ERROR_BUSY;
5230 5278                                  break;
5231 5279                          case EPERM:
5232 5280                          case EACCES:
5233 5281                                  ret = STMF_ERROR_PERM;
5234 5282                                  break;
5235 5283                          default:
5236 5284                                  syslog(LOG_DEBUG,
5237 5285                                      "getStmfState:ioctl errno(%d)", errno);
5238 5286                                  ret = STMF_STATUS_ERROR;
5239 5287                                  break;
5240 5288                  }
5241 5289          } else {
5242 5290                  if (alua_state.alua_state == 1) {
5243 5291                          *enabled = B_TRUE;
5244 5292                  } else {
5245 5293                          *enabled = B_FALSE;
5246 5294                  }
5247 5295                  *node = alua_state.alua_node;
5248 5296          }
5249 5297  
5250 5298          return (ret);
5251 5299  }
5252 5300  
5253 5301  /*
5254 5302   * stmfSetAluaState
5255 5303   *
5256 5304   * Purpose - set the alua state to enabled/disabled
5257 5305   *
5258 5306   */
5259 5307  int
5260 5308  stmfSetAluaState(boolean_t enabled, uint32_t node)
5261 5309  {
5262 5310          int ret = STMF_STATUS_SUCCESS;
5263 5311          int fd;
5264 5312          stmf_iocdata_t stmfIoctl = {0};
5265 5313          stmf_alua_state_desc_t alua_state = {0};
5266 5314          int ioctlRet;
5267 5315  
5268 5316          if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) {
5269 5317                  return (STMF_ERROR_INVALID_ARG);
5270 5318          }
5271 5319  
5272 5320          if (enabled) {
5273 5321                  alua_state.alua_state = 1;
5274 5322          }
5275 5323  
5276 5324          alua_state.alua_node = node;
5277 5325  
5278 5326          /*
5279 5327           * Open control node for stmf
5280 5328           */
5281 5329          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5282 5330                  return (ret);
5283 5331  
5284 5332          /*
5285 5333           * Issue ioctl to get the stmf state
5286 5334           */
5287 5335          stmfIoctl.stmf_version = STMF_VERSION_1;
5288 5336          stmfIoctl.stmf_ibuf_size = sizeof (alua_state);
5289 5337          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state;
5290 5338          ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl);
5291 5339  
5292 5340          (void) close(fd);
5293 5341  
5294 5342          if (ioctlRet != 0) {
5295 5343                  switch (errno) {
5296 5344                          case EBUSY:
5297 5345                                  ret = STMF_ERROR_BUSY;
5298 5346                                  break;
5299 5347                          case EPERM:
5300 5348                          case EACCES:
5301 5349                                  ret = STMF_ERROR_PERM;
5302 5350                                  break;
5303 5351                          default:
5304 5352                                  syslog(LOG_DEBUG,
5305 5353                                      "getStmfState:ioctl errno(%d)", errno);
5306 5354                                  ret = STMF_STATUS_ERROR;
5307 5355                                  break;
5308 5356                  }
5309 5357          }
5310 5358          if (!enabled && ret == STMF_STATUS_SUCCESS) {
5311 5359                  deleteNonActiveLus();
5312 5360          }
5313 5361  
5314 5362          return (ret);
5315 5363  }
5316 5364  
5317 5365  static void
5318 5366  deleteNonActiveLus()
5319 5367  {
5320 5368          int stmfRet;
5321 5369          int i;
5322 5370          stmfGuidList *luList;
5323 5371          luResource hdl = NULL;
5324 5372          char propVal[10];
5325 5373          size_t propValSize = sizeof (propVal);
5326 5374  
5327 5375          stmfRet = stmfGetLogicalUnitList(&luList);
5328 5376          if (stmfRet != STMF_STATUS_SUCCESS) {
5329 5377                  return;
5330 5378          }
5331 5379  
5332 5380          for (i = 0; i < luList->cnt; i++) {
5333 5381                  stmfRet = stmfGetLuResource(&luList->guid[i], &hdl);
5334 5382                  if (stmfRet != STMF_STATUS_SUCCESS) {
5335 5383                          goto err;
5336 5384                  }
5337 5385                  stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal,
5338 5386                      &propValSize);
5339 5387                  if (stmfRet != STMF_STATUS_SUCCESS) {
5340 5388                          goto err;
5341 5389                  }
5342 5390                  if (propVal[0] == '0') {
5343 5391                          (void) stmfFreeLuResource(hdl);
5344 5392                          hdl = NULL;
5345 5393                          continue;
5346 5394                  }
5347 5395                  (void) stmfDeleteLu(&luList->guid[i]);
5348 5396                  (void) stmfFreeLuResource(hdl);
5349 5397                  hdl = NULL;
5350 5398          }
5351 5399  
5352 5400  err:
5353 5401          stmfFreeMemory(luList);
5354 5402          (void) stmfFreeLuResource(hdl);
5355 5403  }
5356 5404  
5357 5405  /*
5358 5406   * stmfLoadConfig
5359 5407   *
5360 5408   * Purpose - load the configuration data from smf into stmf
5361 5409   *
5362 5410   */
5363 5411  int
5364 5412  stmfLoadConfig(void)
5365 5413  {
5366 5414          int ret = STMF_STATUS_SUCCESS;
5367 5415          int fd;
5368 5416          stmf_state_desc_t stmfStateSet;
5369 5417          stmfState state;
5370 5418  
5371 5419          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5372 5420                  stmfStateSet.state = STMF_STATE_OFFLINE;
5373 5421  
5374 5422                  if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
5375 5423                      != STMF_STATUS_SUCCESS) {
5376 5424                          return (ret);
5377 5425                  }
5378 5426                  /*
5379 5427                   * Configuration not stored persistently; nothing to
5380 5428                   * initialize so do not set to STMF_CONFIG_INIT.
5381 5429                   */
5382 5430                  stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
5383 5431                  goto done;
5384 5432          }
5385 5433  
5386 5434          /* Check to ensure service exists */
5387 5435          if (psCheckService() != STMF_STATUS_SUCCESS) {
5388 5436                  return (STMF_ERROR_SERVICE_NOT_FOUND);
5389 5437          }
5390 5438  
5391 5439          ret = stmfGetState(&state);
5392 5440          if (ret == STMF_STATUS_SUCCESS) {
5393 5441                  if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
5394 5442                          return (STMF_ERROR_SERVICE_ONLINE);
5395 5443                  }
5396 5444          } else {
5397 5445                  return (STMF_STATUS_ERROR);
5398 5446          }
5399 5447  
5400 5448  
5401 5449          stmfStateSet.state = STMF_STATE_OFFLINE;
5402 5450          stmfStateSet.config_state = STMF_CONFIG_INIT;
5403 5451  
5404 5452          /*
5405 5453           * Open control node for stmf
5406 5454           */
5407 5455          if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5408 5456                  return (ret);
5409 5457  
5410 5458          ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
5411 5459          if (ret != STMF_STATUS_SUCCESS) {
5412 5460                  goto done;
5413 5461          }
5414 5462  
5415 5463          /* Load the persistent configuration data */
5416 5464          ret = loadStore(fd);
5417 5465          if (ret != 0) {
5418 5466                  goto done;
5419 5467          }
5420 5468  
5421 5469          stmfStateSet.state = STMF_STATE_OFFLINE;
5422 5470          stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
5423 5471  
5424 5472  done:
5425 5473          if (ret == STMF_STATUS_SUCCESS) {
5426 5474                  ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
5427 5475          }
5428 5476          (void) close(fd);
5429 5477          return (ret);
5430 5478  }
5431 5479  
5432 5480  
5433 5481  /*
5434 5482   * getStmfState
5435 5483   *
5436 5484   * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
5437 5485   *             information of the stmf service on success.
5438 5486   */
5439 5487  static int
5440 5488  getStmfState(stmf_state_desc_t *stmfState)
5441 5489  {
5442 5490          int ret = STMF_STATUS_SUCCESS;
5443 5491          int fd;
5444 5492          int ioctlRet;
5445 5493          stmf_iocdata_t stmfIoctl;
5446 5494  
5447 5495          /*
5448 5496           * Open control node for stmf
5449 5497           */
5450 5498          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5451 5499                  return (ret);
5452 5500  
5453 5501          bzero(&stmfIoctl, sizeof (stmfIoctl));
5454 5502          /*
5455 5503           * Issue ioctl to get the stmf state
5456 5504           */
5457 5505          stmfIoctl.stmf_version = STMF_VERSION_1;
5458 5506          stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
5459 5507          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
5460 5508          stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
5461 5509          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
5462 5510          ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
5463 5511  
5464 5512          (void) close(fd);
5465 5513  
5466 5514          if (ioctlRet != 0) {
5467 5515                  switch (errno) {
5468 5516                          case EBUSY:
5469 5517                                  ret = STMF_ERROR_BUSY;
5470 5518                                  break;
5471 5519                          case EPERM:
5472 5520                          case EACCES:
5473 5521                                  ret = STMF_ERROR_PERM;
5474 5522                                  break;
5475 5523                          default:
5476 5524                                  syslog(LOG_DEBUG,
5477 5525                                      "getStmfState:ioctl errno(%d)", errno);
5478 5526                                  ret = STMF_STATUS_ERROR;
5479 5527                                  break;
5480 5528                  }
5481 5529          }
5482 5530          return (ret);
5483 5531  }
5484 5532  
5485 5533  
5486 5534  /*
5487 5535   * setStmfState
5488 5536   *
5489 5537   * stmfState - pointer to caller set state structure
5490 5538   * objectType - one of:
5491 5539   *              LOGICAL_UNIT_TYPE
5492 5540   *              TARGET_TYPE
5493 5541   *              STMF_SERVICE_TYPE
5494 5542   */
5495 5543  static int
5496 5544  setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
5497 5545  {
5498 5546          int ret = STMF_STATUS_SUCCESS;
5499 5547          int ioctlRet;
5500 5548          int cmd;
5501 5549          stmf_iocdata_t stmfIoctl;
5502 5550  
5503 5551          switch (objectType) {
5504 5552                  case LOGICAL_UNIT_TYPE:
5505 5553                          cmd = STMF_IOCTL_SET_LU_STATE;
5506 5554                          break;
5507 5555                  case TARGET_TYPE:
5508 5556                          cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
5509 5557                          break;
5510 5558                  case STMF_SERVICE_TYPE:
5511 5559                          cmd = STMF_IOCTL_SET_STMF_STATE;
5512 5560                          break;
5513 5561                  default:
5514 5562                          ret = STMF_STATUS_ERROR;
5515 5563                          goto done;
5516 5564          }
5517 5565  
5518 5566          bzero(&stmfIoctl, sizeof (stmfIoctl));
5519 5567          /*
5520 5568           * Issue ioctl to set the stmf state
5521 5569           */
5522 5570          stmfIoctl.stmf_version = STMF_VERSION_1;
5523 5571          stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
5524 5572          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
5525 5573          ioctlRet = ioctl(fd, cmd, &stmfIoctl);
5526 5574          if (ioctlRet != 0) {
5527 5575                  switch (errno) {
5528 5576                          case EBUSY:
5529 5577                                  ret = STMF_ERROR_BUSY;
5530 5578                                  break;
5531 5579                          case EPERM:
5532 5580                          case EACCES:
5533 5581                                  ret = STMF_ERROR_PERM;
5534 5582                                  break;
5535 5583                          case ENOENT:
5536 5584                                  ret = STMF_ERROR_NOT_FOUND;
5537 5585                                  break;
5538 5586                          default:
5539 5587                                  syslog(LOG_DEBUG,
5540 5588                                      "setStmfState:ioctl errno(%d)", errno);
5541 5589                                  ret = STMF_STATUS_ERROR;
5542 5590                                  break;
5543 5591                  }
5544 5592          }
5545 5593  done:
5546 5594          return (ret);
5547 5595  }
5548 5596  int
5549 5597  stmfSetStmfProp(uint8_t propType, char *propVal)
5550 5598  {
5551 5599          int ret = STMF_STATUS_SUCCESS;
5552 5600          switch (propType) {
5553 5601                  case STMF_DEFAULT_LU_STATE:
5554 5602                          break;
5555 5603                  case STMF_DEFAULT_TARGET_PORT_STATE:
5556 5604                          break;
5557 5605                  default:
5558 5606                          return (STMF_ERROR_INVALID_ARG);
5559 5607          }
5560 5608          ret = psSetStmfProp(propType, propVal);
5561 5609          switch (ret) {
5562 5610                  case STMF_PS_SUCCESS:
5563 5611                          ret = STMF_STATUS_SUCCESS;
5564 5612                          break;
5565 5613                  case STMF_PS_ERROR_BUSY:
5566 5614                          ret = STMF_ERROR_BUSY;
5567 5615                          break;
5568 5616                  default:
5569 5617                          syslog(LOG_DEBUG,
5570 5618                              "stmfSetStmfProp:psSetStmfProp:error(%d)",
5571 5619                              ret);
5572 5620                          ret = STMF_STATUS_ERROR;
5573 5621                          break;
5574 5622          }
5575 5623          return (ret);
5576 5624  }
5577 5625  
5578 5626  
5579 5627  int
5580 5628  stmfGetStmfProp(uint8_t propType, char *propVal, size_t *propLen)
5581 5629  {
5582 5630          int ret = STMF_STATUS_SUCCESS;
5583 5631          char prop[MAXNAMELEN] = {0};
5584 5632          size_t reqLen;
5585 5633  
5586 5634          if (propVal == NULL || propLen == NULL) {
5587 5635                  return (STMF_ERROR_INVALID_ARG);
5588 5636          }
5589 5637          switch (propType) {
5590 5638                  case STMF_DEFAULT_LU_STATE:
5591 5639                          break;
5592 5640                  case STMF_DEFAULT_TARGET_PORT_STATE:
5593 5641                          break;
5594 5642                  default:
5595 5643                          return (STMF_ERROR_INVALID_ARG);
5596 5644          }
5597 5645          ret = psGetStmfProp(propType, prop);
5598 5646          if ((reqLen = strlcpy(propVal, prop, *propLen)) >= *propLen) {
5599 5647                  *propLen = reqLen + 1;
5600 5648                  return (STMF_ERROR_INVALID_ARG);
5601 5649          }
5602 5650  
5603 5651          switch (ret) {
5604 5652                  case STMF_PS_SUCCESS:
5605 5653                          ret = STMF_STATUS_SUCCESS;
5606 5654                          break;
5607 5655                  case STMF_PS_ERROR_BUSY:
5608 5656                          ret = STMF_ERROR_BUSY;
5609 5657                          break;
5610 5658                  case STMF_PS_ERROR_NOT_FOUND:
5611 5659                          ret = STMF_ERROR_NOT_FOUND;
5612 5660                          break;
5613 5661                  default:
5614 5662                          syslog(LOG_DEBUG,
5615 5663                              "stmfGetStmfProp:psGetStmfProp:error(%d)",
5616 5664                              ret);
5617 5665                          ret = STMF_STATUS_ERROR;
5618 5666                          break;
5619 5667          }
5620 5668          return (ret);
5621 5669  }
5622 5670  
5623 5671  static int
5624 5672  setStmfProp(stmf_set_props_t *stmf_set_props)
5625 5673  {
5626 5674          char propVal[MAXNAMELEN] = {0};
5627 5675          int ret;
5628 5676          if ((ret = psGetStmfProp(STMF_DEFAULT_LU_STATE, propVal)) ==
5629 5677              STMF_PS_SUCCESS) {
5630 5678                  if (strncmp(propVal, "offline", strlen(propVal)) == 0) {
5631 5679                          stmf_set_props->default_lu_state_value =
5632 5680                              STMF_STATE_OFFLINE;
5633 5681                  } else {
5634 5682                          stmf_set_props->default_lu_state_value =
5635 5683                              STMF_STATE_ONLINE;
5636 5684                  }
5637 5685          } else {
5638 5686                  syslog(LOG_DEBUG,
5639 5687                      "DefaultLuState:psSetStmfProp:error(%d)", ret);
5640 5688                  goto done;
5641 5689          }
5642 5690  
5643 5691          if ((ret = psGetStmfProp(STMF_DEFAULT_TARGET_PORT_STATE, propVal)) ==
5644 5692              STMF_PS_SUCCESS) {
5645 5693                  if (strncmp(propVal, "offline", strlen(propVal)) == 0) {
5646 5694                          stmf_set_props->default_target_state_value =
5647 5695                              STMF_STATE_OFFLINE;
5648 5696                  } else {
5649 5697                          stmf_set_props->default_target_state_value =
5650 5698                              STMF_STATE_ONLINE;
5651 5699                  }
5652 5700          } else {
5653 5701                  syslog(LOG_DEBUG,
5654 5702                      "DefaultTargetPortState:psSetStmfProp:error(%d)", ret);
5655 5703                  goto done;
5656 5704          }
5657 5705  done:
5658 5706          switch (ret) {
5659 5707                  case STMF_PS_SUCCESS:
5660 5708                          ret = STMF_STATUS_SUCCESS;
5661 5709                          break;
5662 5710                  case STMF_PS_ERROR_NOT_FOUND:
5663 5711                          ret = STMF_ERROR_NOT_FOUND;
5664 5712                          break;
5665 5713                  case STMF_PS_ERROR_BUSY:
5666 5714                          ret = STMF_ERROR_BUSY;
5667 5715                          break;
5668 5716                  default:
5669 5717                          ret = STMF_STATUS_ERROR;
5670 5718                          break;
5671 5719          }
5672 5720          return (ret);
5673 5721  }
5674 5722  
5675 5723  static int
5676 5724  loadStmfProp(int fd)
5677 5725  {
5678 5726          int ret = STMF_STATUS_SUCCESS;
5679 5727          int ioctlRet;
5680 5728          stmf_iocdata_t stmfIoctl = {0};
5681 5729          stmf_set_props_t *stmf_set_props = NULL;
5682 5730  
5683 5731          stmf_set_props = (stmf_set_props_t *)
5684 5732              calloc(1, (sizeof (stmf_set_props_t)));
5685 5733          if (stmf_set_props == NULL) {
5686 5734                  ret = STMF_ERROR_NOMEM;
5687 5735                  goto done;
5688 5736          }
5689 5737  
5690 5738          /* Loading the default property values from smf */
5691 5739  
5692 5740          if ((ret = setStmfProp(stmf_set_props)) != STMF_STATUS_SUCCESS)
5693 5741                  goto done;
5694 5742  
5695 5743          stmfIoctl.stmf_version = STMF_VERSION_1;
5696 5744          stmfIoctl.stmf_ibuf_size = sizeof (stmf_set_props_t);
5697 5745          stmfIoctl.stmf_ibuf =
5698 5746              (uint64_t)(unsigned long)stmf_set_props;
5699 5747  
5700 5748          ioctlRet = ioctl(fd, STMF_IOCTL_SET_STMF_PROPS,
5701 5749              &stmfIoctl);
5702 5750  
5703 5751          if (ioctlRet != 0) {
5704 5752                  switch (errno) {
5705 5753                          case EBUSY:
5706 5754                                  ret = STMF_ERROR_BUSY;
5707 5755                                  break;
5708 5756                          case EPERM:
5709 5757                          case EACCES:
5710 5758                                  ret = STMF_ERROR_PERM;
5711 5759                                  break;
5712 5760                          case ENOENT:
5713 5761                                  ret = STMF_ERROR_NOT_FOUND;
5714 5762                                  break;
5715 5763                          default:
5716 5764                                  syslog(LOG_DEBUG,
5717 5765                                      "setDefaultStmfState:"
5718 5766                                      "ioctl errno(%d)", errno);
5719 5767                                  ret = STMF_STATUS_ERROR;
5720 5768                                  break;
5721 5769                  }
5722 5770          }
5723 5771  done:
5724 5772          if (stmf_set_props != NULL) {
5725 5773                  free(stmf_set_props);
5726 5774          }
5727 5775          return (ret);
5728 5776  }
5729 5777  
5730 5778  int
5731 5779  stmfLoadStmfProps(void)
5732 5780  {
5733 5781          int ret = STMF_STATUS_SUCCESS;
5734 5782          int fd;
5735 5783          /* open control node for stmf */
5736 5784          if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
5737 5785              != STMF_STATUS_SUCCESS) {
5738 5786                  goto done;
5739 5787          }
5740 5788          ret = loadStmfProp(fd);
5741 5789  
5742 5790          (void) close(fd);
5743 5791  done:
5744 5792          if (ret != STMF_STATUS_SUCCESS) {
5745 5793                  syslog(LOG_DEBUG,
5746 5794                      "stmfLoadStmfProps:Failed");
5747 5795          }
5748 5796          return (ret);
5749 5797  }
5750 5798  
5751 5799  /*
5752 5800   * stmfOnline
5753 5801   *
5754 5802   * Purpose: Online stmf service
5755 5803   *
5756 5804   */
5757 5805  int
5758 5806  stmfOnline(void)
5759 5807  {
5760 5808          int ret;
5761 5809          int fd;
5762 5810          stmfState state;
5763 5811          stmf_state_desc_t iState;
5764 5812  
5765 5813          ret = stmfGetState(&state);
5766 5814          if (ret == STMF_STATUS_SUCCESS) {
5767 5815                  if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
5768 5816                          return (STMF_ERROR_SERVICE_ONLINE);
5769 5817                  }
5770 5818          } else {
5771 5819                  return (STMF_STATUS_ERROR);
5772 5820          }
5773 5821          iState.state = STMF_STATE_ONLINE;
5774 5822          iState.config_state = STMF_CONFIG_NONE;
5775 5823          /*
5776 5824           * Open control node for stmf
5777 5825           * to make call to setStmfState()
5778 5826           */
5779 5827          if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5780 5828                  return (ret);
5781 5829          ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
5782 5830          (void) close(fd);
5783 5831          return (ret);
5784 5832  }
5785 5833  
5786 5834  /*
5787 5835   * stmfOffline
5788 5836   *
5789 5837   * Purpose: Offline stmf service
5790 5838   *
5791 5839   */
5792 5840  int
5793 5841  stmfOffline(void)
5794 5842  {
5795 5843          int ret;
5796 5844          int fd;
5797 5845          stmfState state;
5798 5846          stmf_state_desc_t iState;
5799 5847  
5800 5848          ret = stmfGetState(&state);
5801 5849          if (ret == STMF_STATUS_SUCCESS) {
5802 5850                  if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
5803 5851                          return (STMF_ERROR_SERVICE_OFFLINE);
5804 5852                  }
5805 5853          } else {
5806 5854                  return (STMF_STATUS_ERROR);
5807 5855          }
5808 5856          iState.state = STMF_STATE_OFFLINE;
5809 5857          iState.config_state = STMF_CONFIG_NONE;
5810 5858  
5811 5859          /*
5812 5860           * Open control node for stmf
5813 5861           * to make call to setStmfState()
5814 5862           */
5815 5863          if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5816 5864                  return (ret);
5817 5865          ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
5818 5866          (void) close(fd);
5819 5867          return (ret);
5820 5868  }
5821 5869  
5822 5870  
5823 5871  /*
5824 5872   * stmfOfflineTarget
5825 5873   *
5826 5874   * Purpose: Change state of target to offline
5827 5875   *
5828 5876   * devid - devid of the target to offline
5829 5877   */
5830 5878  int
5831 5879  stmfOfflineTarget(stmfDevid *devid)
5832 5880  {
5833 5881          stmf_state_desc_t targetState;
5834 5882          int ret = STMF_STATUS_SUCCESS;
5835 5883          int fd;
5836 5884  
5837 5885          if (devid == NULL) {
5838 5886                  return (STMF_ERROR_INVALID_ARG);
5839 5887          }
5840 5888          bzero(&targetState, sizeof (targetState));
5841 5889  
5842 5890          targetState.state = STMF_STATE_OFFLINE;
5843 5891          targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
5844 5892          bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
5845 5893              devid->identLength);
5846 5894          /*
5847 5895           * Open control node for stmf
5848 5896           * to make call to setStmfState()
5849 5897           */
5850 5898          if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5851 5899                  return (ret);
5852 5900          ret = setStmfState(fd, &targetState, TARGET_TYPE);
5853 5901          (void) close(fd);
5854 5902          return (ret);
5855 5903  }
5856 5904  
5857 5905  /*
5858 5906   * stmfOfflineLogicalUnit
5859 5907   *
5860 5908   * Purpose: Change state of logical unit to offline
5861 5909   *
5862 5910   * lu - guid of the logical unit to offline
5863 5911   */
5864 5912  int
5865 5913  stmfOfflineLogicalUnit(stmfGuid *lu)
5866 5914  {
5867 5915          stmf_state_desc_t luState;
5868 5916          int ret = STMF_STATUS_SUCCESS;
5869 5917          int fd;
5870 5918  
5871 5919          if (lu == NULL) {
5872 5920                  return (STMF_ERROR_INVALID_ARG);
5873 5921          }
5874 5922  
5875 5923          bzero(&luState, sizeof (luState));
5876 5924  
5877 5925          luState.state = STMF_STATE_OFFLINE;
5878 5926          bcopy(lu, &luState.ident, sizeof (stmfGuid));
5879 5927          /*
5880 5928           * Open control node for stmf
5881 5929           * to make call to setStmfState()
5882 5930           */
5883 5931          if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5884 5932                  return (ret);
5885 5933          ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
5886 5934          (void) close(fd);
5887 5935          return (ret);
5888 5936  }
5889 5937  
5890 5938  /*
5891 5939   * stmfOnlineTarget
5892 5940   *
5893 5941   * Purpose: Change state of target to online
5894 5942   *
5895 5943   * devid - devid of the target to online
5896 5944   */
5897 5945  int
5898 5946  stmfOnlineTarget(stmfDevid *devid)
5899 5947  {
5900 5948          stmf_state_desc_t targetState;
5901 5949          int ret = STMF_STATUS_SUCCESS;
5902 5950          int fd;
5903 5951  
5904 5952          if (devid == NULL) {
5905 5953                  return (STMF_ERROR_INVALID_ARG);
5906 5954          }
5907 5955          bzero(&targetState, sizeof (targetState));
5908 5956  
5909 5957          targetState.state = STMF_STATE_ONLINE;
5910 5958          targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
5911 5959          bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
5912 5960              devid->identLength);
5913 5961          /*
5914 5962           * Open control node for stmf
5915 5963           * to make call to setStmfState()
5916 5964           */
5917 5965          if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5918 5966                  return (ret);
5919 5967          ret = setStmfState(fd, &targetState, TARGET_TYPE);
5920 5968          (void) close(fd);
5921 5969          return (ret);
5922 5970  }
5923 5971  
5924 5972  /*
5925 5973   * stmfOnlineLogicalUnit
5926 5974   *
5927 5975   * Purpose: Change state of logical unit to online
5928 5976   *
5929 5977   * lu - guid of the logical unit to online
5930 5978   */
5931 5979  int
5932 5980  stmfOnlineLogicalUnit(stmfGuid *lu)
5933 5981  {
5934 5982          stmf_state_desc_t luState;
5935 5983          int ret = STMF_STATUS_SUCCESS;
5936 5984          int fd;
5937 5985  
5938 5986          if (lu == NULL) {
5939 5987                  return (STMF_ERROR_INVALID_ARG);
5940 5988          }
5941 5989  
5942 5990          bzero(&luState, sizeof (luState));
5943 5991  
5944 5992          luState.state = STMF_STATE_ONLINE;
5945 5993          bcopy(lu, &luState.ident, sizeof (stmfGuid));
5946 5994          /*
5947 5995           * Open control node for stmf
5948 5996           * to make call to setStmfState()
5949 5997           */
5950 5998          if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5951 5999                  return (ret);
5952 6000          ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
5953 6001          (void) close(fd);
5954 6002          return (ret);
5955 6003  }
5956 6004  
5957 6005  /*
5958 6006   * stmfRemoveFromHostGroup
5959 6007   *
5960 6008   * Purpose: Removes an initiator from an initiator group
5961 6009   *
5962 6010   * hostGroupName - name of an initiator group
5963 6011   * hostName - name of host group member to remove
5964 6012   */
5965 6013  int
5966 6014  stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
5967 6015  {
5968 6016          int ret;
5969 6017          int fd;
5970 6018  
5971 6019          if (hostGroupName == NULL ||
5972 6020              (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
5973 6021              == sizeof (stmfGroupName)) || hostName == NULL) {
5974 6022                  return (STMF_ERROR_INVALID_ARG);
5975 6023          }
5976 6024  
5977 6025          /* call init */
5978 6026          ret = initializeConfig();
5979 6027          if (ret != STMF_STATUS_SUCCESS) {
5980 6028                  return (ret);
5981 6029          }
5982 6030  
5983 6031          /*
5984 6032           * Open control node for stmf
5985 6033           */
5986 6034          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5987 6035                  return (ret);
5988 6036  
5989 6037          if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
5990 6038              hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
5991 6039                  goto done;
5992 6040          }
5993 6041  
5994 6042          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5995 6043                  goto done;
5996 6044          }
5997 6045  
5998 6046          ret = psRemoveHostGroupMember((char *)hostGroupName,
5999 6047              (char *)hostName->ident);
6000 6048          switch (ret) {
6001 6049                  case STMF_PS_SUCCESS:
6002 6050                          ret = STMF_STATUS_SUCCESS;
6003 6051                          break;
6004 6052                  case STMF_PS_ERROR_MEMBER_NOT_FOUND:
6005 6053                          ret = STMF_ERROR_MEMBER_NOT_FOUND;
6006 6054                          break;
6007 6055                  case STMF_PS_ERROR_GROUP_NOT_FOUND:
6008 6056                          ret = STMF_ERROR_GROUP_NOT_FOUND;
6009 6057                          break;
6010 6058                  case STMF_PS_ERROR_BUSY:
6011 6059                          ret = STMF_ERROR_BUSY;
6012 6060                          break;
6013 6061                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6014 6062                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
6015 6063                          break;
6016 6064                  case STMF_PS_ERROR_VERSION_MISMATCH:
6017 6065                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
6018 6066                          break;
6019 6067                  default:
6020 6068                          syslog(LOG_DEBUG,
6021 6069                              "stmfRemoveFromHostGroup"
6022 6070                              "psRemoveHostGroupMember:error(%d)", ret);
6023 6071                          ret = STMF_STATUS_ERROR;
6024 6072                          break;
6025 6073          }
6026 6074  
6027 6075  done:
6028 6076          (void) close(fd);
6029 6077          return (ret);
6030 6078  }
6031 6079  
6032 6080  /*
6033 6081   * stmfRemoveFromTargetGroup
6034 6082   *
6035 6083   * Purpose: Removes a local port from a local port group
6036 6084   *
6037 6085   * targetGroupName - name of a target group
6038 6086   * targetName - name of target to remove
6039 6087   */
6040 6088  int
6041 6089  stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
6042 6090  {
6043 6091          int ret;
6044 6092          int fd;
6045 6093  
6046 6094          if (targetGroupName == NULL ||
6047 6095              (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
6048 6096              == sizeof (stmfGroupName)) || targetName == NULL) {
6049 6097                  return (STMF_ERROR_INVALID_ARG);
6050 6098          }
6051 6099  
6052 6100          /* call init */
6053 6101          ret = initializeConfig();
6054 6102          if (ret != STMF_STATUS_SUCCESS) {
6055 6103                  return (ret);
6056 6104          }
6057 6105  
6058 6106          /*
6059 6107           * Open control node for stmf
6060 6108           */
6061 6109          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6062 6110                  return (ret);
6063 6111  
6064 6112          if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
6065 6113              targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
6066 6114                  goto done;
6067 6115          }
6068 6116  
6069 6117          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
6070 6118                  goto done;
6071 6119          }
6072 6120  
6073 6121          ret = psRemoveTargetGroupMember((char *)targetGroupName,
6074 6122              (char *)targetName->ident);
6075 6123          switch (ret) {
6076 6124                  case STMF_PS_SUCCESS:
6077 6125                          ret = STMF_STATUS_SUCCESS;
6078 6126                          break;
6079 6127                  case STMF_PS_ERROR_MEMBER_NOT_FOUND:
6080 6128                          ret = STMF_ERROR_MEMBER_NOT_FOUND;
6081 6129                          break;
6082 6130                  case STMF_PS_ERROR_GROUP_NOT_FOUND:
6083 6131                          ret = STMF_ERROR_GROUP_NOT_FOUND;
6084 6132                          break;
6085 6133                  case STMF_PS_ERROR_BUSY:
6086 6134                          ret = STMF_ERROR_BUSY;
6087 6135                          break;
6088 6136                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6089 6137                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
6090 6138                          break;
6091 6139                  case STMF_PS_ERROR_VERSION_MISMATCH:
6092 6140                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
6093 6141                          break;
6094 6142                  default:
6095 6143                          syslog(LOG_DEBUG,
6096 6144                              "stmfRemoveFromTargetGroup"
6097 6145                              "psRemoveTargetGroupMember:error(%d)", ret);
6098 6146                          ret = STMF_STATUS_ERROR;
6099 6147                          break;
6100 6148          }
6101 6149  
6102 6150  done:
6103 6151          (void) close(fd);
6104 6152          return (ret);
6105 6153  }
6106 6154  
6107 6155  /*
6108 6156   * stmfRemoveViewEntry
6109 6157   *
6110 6158   * Purpose: Removes a view entry from a logical unit
6111 6159   *
6112 6160   * lu - guid of lu for which view entry is being removed
6113 6161   * viewEntryIndex - index of view entry to remove
6114 6162   *
6115 6163   */
6116 6164  int
6117 6165  stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
6118 6166  {
6119 6167          int ret = STMF_STATUS_SUCCESS;
6120 6168          int fd;
6121 6169          int ioctlRet;
6122 6170          stmf_iocdata_t stmfIoctl;
6123 6171          stmf_view_op_entry_t ioctlViewEntry;
6124 6172  
6125 6173          if (lu == NULL) {
6126 6174                  return (STMF_ERROR_INVALID_ARG);
6127 6175          }
6128 6176  
6129 6177          /* call init */
6130 6178          ret = initializeConfig();
6131 6179          if (ret != STMF_STATUS_SUCCESS) {
6132 6180                  return (ret);
6133 6181          }
6134 6182  
6135 6183          /*
6136 6184           * Open control node for stmf
6137 6185           */
6138 6186          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6139 6187                  return (ret);
6140 6188  
6141 6189          bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
6142 6190          ioctlViewEntry.ve_ndx_valid = B_TRUE;
6143 6191          ioctlViewEntry.ve_ndx = viewEntryIndex;
6144 6192          bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
6145 6193  
6146 6194          bzero(&stmfIoctl, sizeof (stmfIoctl));
6147 6195          /*
6148 6196           * Issue ioctl to add to the view entry
6149 6197           */
6150 6198          stmfIoctl.stmf_version = STMF_VERSION_1;
6151 6199          stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
6152 6200          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6153 6201          ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
6154 6202          if (ioctlRet != 0) {
6155 6203                  switch (errno) {
6156 6204                          case EBUSY:
6157 6205                                  ret = STMF_ERROR_BUSY;
6158 6206                                  break;
6159 6207                          case EPERM:
6160 6208                                  ret = STMF_ERROR_PERM;
6161 6209                                  break;
6162 6210                          case EACCES:
6163 6211                                  switch (stmfIoctl.stmf_error) {
6164 6212                                          case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6165 6213                                                  ret = STMF_ERROR_CONFIG_NONE;
6166 6214                                                  break;
6167 6215                                          default:
6168 6216                                                  ret = STMF_ERROR_PERM;
6169 6217                                                  break;
6170 6218                                  }
6171 6219                                  break;
6172 6220                          case ENODEV:
6173 6221                          case ENOENT:
6174 6222                                  ret = STMF_ERROR_NOT_FOUND;
6175 6223                                  break;
6176 6224                          default:
6177 6225                                  syslog(LOG_DEBUG,
6178 6226                                      "stmfRemoveViewEntry:ioctl errno(%d)",
6179 6227                                      errno);
6180 6228                                  ret = STMF_STATUS_ERROR;
6181 6229                                  break;
6182 6230                  }
6183 6231                  goto done;
6184 6232          }
6185 6233  
6186 6234          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
6187 6235                  goto done;
6188 6236          }
6189 6237  
6190 6238          ret = psRemoveViewEntry(lu, viewEntryIndex);
6191 6239          switch (ret) {
6192 6240                  case STMF_PS_SUCCESS:
6193 6241                          ret = STMF_STATUS_SUCCESS;
6194 6242                          break;
6195 6243                  case STMF_PS_ERROR_NOT_FOUND:
6196 6244                          ret = STMF_ERROR_NOT_FOUND;
6197 6245                          break;
6198 6246                  case STMF_PS_ERROR_BUSY:
6199 6247                          ret = STMF_ERROR_BUSY;
6200 6248                          break;
6201 6249                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6202 6250                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
6203 6251                          break;
6204 6252                  case STMF_PS_ERROR_VERSION_MISMATCH:
6205 6253                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
6206 6254                          break;
6207 6255                  default:
6208 6256                          syslog(LOG_DEBUG,
6209 6257                              "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
6210 6258                              ret);
6211 6259                          ret = STMF_STATUS_ERROR;
6212 6260                          break;
6213 6261          }
6214 6262  
6215 6263  done:
6216 6264          (void) close(fd);
6217 6265          return (ret);
6218 6266  }
6219 6267  
6220 6268  /*
6221 6269   * stmfSetProviderData
6222 6270   *
6223 6271   * Purpose: set the provider data
6224 6272   *
6225 6273   * providerName - unique name of provider
6226 6274   * nvl - nvlist to set
6227 6275   * providerType - type of provider for which to set data
6228 6276   *              STMF_LU_PROVIDER_TYPE
6229 6277   *              STMF_PORT_PROVIDER_TYPE
6230 6278   */
6231 6279  int
6232 6280  stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
6233 6281  {
6234 6282          return (stmfSetProviderDataProt(providerName, nvl, providerType,
6235 6283              NULL));
6236 6284  }
6237 6285  
6238 6286  /*
6239 6287   * stmfSetProviderDataProt
6240 6288   *
6241 6289   * Purpose: set the provider data
6242 6290   *
6243 6291   * providerName - unique name of provider
6244 6292   * nvl - nvlist to set
6245 6293   * providerType - type of provider for which to set data
6246 6294   *              STMF_LU_PROVIDER_TYPE
6247 6295   *              STMF_PORT_PROVIDER_TYPE
6248 6296   * setToken - Stale data token returned in the stmfGetProviderDataProt()
6249 6297   *            call or NULL.
6250 6298   */
6251 6299  int
6252 6300  stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
6253 6301      uint64_t *setToken)
6254 6302  {
6255 6303          int ret;
6256 6304          int fd;
6257 6305  
6258 6306          if (providerName == NULL || nvl == NULL) {
6259 6307                  return (STMF_ERROR_INVALID_ARG);
6260 6308          }
6261 6309  
6262 6310          if (providerType != STMF_LU_PROVIDER_TYPE &&
6263 6311              providerType != STMF_PORT_PROVIDER_TYPE) {
6264 6312                  return (STMF_ERROR_INVALID_ARG);
6265 6313          }
6266 6314  
6267 6315          /* call init */
6268 6316          ret = initializeConfig();
6269 6317          if (ret != STMF_STATUS_SUCCESS) {
6270 6318                  return (ret);
6271 6319          }
6272 6320  
6273 6321          /*
6274 6322           * Open control node for stmf
6275 6323           */
6276 6324          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6277 6325                  return (ret);
6278 6326  
6279 6327          ret = setProviderData(fd, providerName, nvl, providerType, setToken);
6280 6328  
6281 6329          (void) close(fd);
6282 6330  
6283 6331          if (ret != STMF_STATUS_SUCCESS) {
6284 6332                  goto done;
6285 6333          }
6286 6334  
6287 6335          if (iGetPersistMethod() == STMF_PERSIST_NONE) {
6288 6336                  goto done;
6289 6337          }
6290 6338  
6291 6339          /* setting driver provider data successful. Now persist it */
6292 6340          ret = psSetProviderData(providerName, nvl, providerType, NULL);
6293 6341          switch (ret) {
6294 6342                  case STMF_PS_SUCCESS:
6295 6343                          ret = STMF_STATUS_SUCCESS;
6296 6344                          break;
6297 6345                  case STMF_PS_ERROR_EXISTS:
6298 6346                          ret = STMF_ERROR_EXISTS;
6299 6347                          break;
6300 6348                  case STMF_PS_ERROR_BUSY:
6301 6349                          ret = STMF_ERROR_BUSY;
6302 6350                          break;
6303 6351                  case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6304 6352                          ret = STMF_ERROR_SERVICE_NOT_FOUND;
6305 6353                          break;
6306 6354                  case STMF_PS_ERROR_VERSION_MISMATCH:
6307 6355                          ret = STMF_ERROR_SERVICE_DATA_VERSION;
6308 6356                          break;
6309 6357                  case STMF_PS_ERROR_PROV_DATA_STALE:
6310 6358                          ret = STMF_ERROR_PROV_DATA_STALE;
6311 6359                          break;
6312 6360                  default:
6313 6361                          syslog(LOG_DEBUG,
6314 6362                              "stmfSetProviderData"
6315 6363                              "psSetProviderData:error(%d)", ret);
6316 6364                          ret = STMF_STATUS_ERROR;
6317 6365                          break;
6318 6366          }
6319 6367  
6320 6368  done:
6321 6369          return (ret);
6322 6370  }
6323 6371  
6324 6372  /*
6325 6373   * getProviderData
6326 6374   *
6327 6375   * Purpose: set the provider data from stmf
6328 6376   *
6329 6377   * providerName - unique name of provider
6330 6378   * nvl - nvlist to load/retrieve
6331 6379   * providerType - logical unit or port provider
6332 6380   * setToken - returned stale data token
6333 6381   */
6334 6382  int
6335 6383  getProviderData(char *providerName, nvlist_t **nvl, int providerType,
6336 6384      uint64_t *setToken)
6337 6385  {
6338 6386          int ret = STMF_STATUS_SUCCESS;
6339 6387          int fd;
6340 6388          int ioctlRet;
6341 6389          size_t nvlistSize = ALLOC_PP_DATA_SIZE;
6342 6390          int retryCnt = 0;
6343 6391          int retryCntMax = MAX_PROVIDER_RETRY;
6344 6392          stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL;
6345 6393          boolean_t retry = B_TRUE;
6346 6394          stmf_iocdata_t stmfIoctl;
6347 6395  
6348 6396          if (providerName == NULL) {
6349 6397                  return (STMF_ERROR_INVALID_ARG);
6350 6398          }
6351 6399  
6352 6400          /*
6353 6401           * Open control node for stmf
6354 6402           */
6355 6403          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6356 6404                  return (ret);
6357 6405  
6358 6406          /* set provider name and provider type */
6359 6407          if (strlcpy(ppi.ppi_name, providerName,
6360 6408              sizeof (ppi.ppi_name)) >=
6361 6409              sizeof (ppi.ppi_name)) {
6362 6410                  ret = STMF_ERROR_INVALID_ARG;
6363 6411                  goto done;
6364 6412          }
6365 6413          switch (providerType) {
6366 6414                  case STMF_LU_PROVIDER_TYPE:
6367 6415                          ppi.ppi_lu_provider = 1;
6368 6416                          break;
6369 6417                  case STMF_PORT_PROVIDER_TYPE:
6370 6418                          ppi.ppi_port_provider = 1;
6371 6419                          break;
6372 6420                  default:
6373 6421                          ret = STMF_ERROR_INVALID_ARG;
6374 6422                          goto done;
6375 6423          }
6376 6424  
6377 6425          do {
6378 6426                  /* allocate memory for ioctl */
6379 6427                  ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize +
6380 6428                      sizeof (stmf_ppioctl_data_t));
6381 6429                  if (ppi_out == NULL) {
6382 6430                          ret = STMF_ERROR_NOMEM;
6383 6431                          goto done;
6384 6432  
6385 6433                  }
6386 6434  
6387 6435                  /* set the size of the ioctl data to allocated buffer */
6388 6436                  ppi.ppi_data_size = nvlistSize;
6389 6437  
6390 6438                  bzero(&stmfIoctl, sizeof (stmfIoctl));
6391 6439  
6392 6440                  stmfIoctl.stmf_version = STMF_VERSION_1;
6393 6441                  stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
6394 6442                  stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
6395 6443                  stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) +
6396 6444                      nvlistSize;
6397 6445                  stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out;
6398 6446                  ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl);
6399 6447                  if (ioctlRet != 0) {
6400 6448                          switch (errno) {
6401 6449                                  case EBUSY:
6402 6450                                          ret = STMF_ERROR_BUSY;
6403 6451                                          break;
6404 6452                                  case EPERM:
6405 6453                                  case EACCES:
6406 6454                                          ret = STMF_ERROR_PERM;
6407 6455                                          break;
6408 6456                                  case EINVAL:
6409 6457                                          if (stmfIoctl.stmf_error ==
6410 6458                                              STMF_IOCERR_INSUFFICIENT_BUF) {
6411 6459                                                  nvlistSize =
6412 6460                                                      ppi_out->ppi_data_size;
6413 6461                                                  free(ppi_out);
6414 6462                                                  ppi_out = NULL;
6415 6463                                                  if (retryCnt++ > retryCntMax) {
6416 6464                                                          retry = B_FALSE;
6417 6465                                                          ret = STMF_ERROR_BUSY;
6418 6466                                                  } else {
6419 6467                                                          ret =
6420 6468                                                              STMF_STATUS_SUCCESS;
6421 6469                                                  }
6422 6470                                          } else {
6423 6471                                                  syslog(LOG_DEBUG,
6424 6472                                                      "getProviderData:ioctl"
6425 6473                                                      "unable to retrieve "
6426 6474                                                      "nvlist");
6427 6475                                                  ret = STMF_STATUS_ERROR;
6428 6476                                          }
6429 6477                                          break;
6430 6478                                  case ENOENT:
6431 6479                                          ret = STMF_ERROR_NOT_FOUND;
6432 6480                                          break;
6433 6481                                  default:
6434 6482                                          syslog(LOG_DEBUG,
6435 6483                                              "getProviderData:ioctl errno(%d)",
6436 6484                                              errno);
6437 6485                                          ret = STMF_STATUS_ERROR;
6438 6486                                          break;
6439 6487                          }
6440 6488                          if (ret != STMF_STATUS_SUCCESS)
6441 6489                                  goto done;
6442 6490                  }
6443 6491          } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF);
6444 6492  
6445 6493          if ((ret = nvlist_unpack((char *)ppi_out->ppi_data,
6446 6494              ppi_out->ppi_data_size, nvl, 0)) != 0) {
6447 6495                  ret = STMF_STATUS_ERROR;
6448 6496                  goto done;
6449 6497          }
6450 6498  
6451 6499          /* caller has asked for new token */
6452 6500          if (setToken) {
6453 6501                  *setToken = ppi_out->ppi_token;
6454 6502          }
6455 6503  done:
6456 6504          free(ppi_out);
6457 6505          (void) close(fd);
6458 6506          return (ret);
6459 6507  }
6460 6508  
6461 6509  /*
6462 6510   * setProviderData
6463 6511   *
6464 6512   * Purpose: set the provider data in stmf
6465 6513   *
6466 6514   * providerName - unique name of provider
6467 6515   * nvl - nvlist to set
6468 6516   * providerType - logical unit or port provider
6469 6517   * setToken - stale data token to check if not NULL
6470 6518   */
6471 6519  static int
6472 6520  setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType,
6473 6521      uint64_t *setToken)
6474 6522  {
6475 6523          int ret = STMF_STATUS_SUCCESS;
6476 6524          int ioctlRet;
6477 6525          size_t nvlistEncodedSize;
6478 6526          stmf_ppioctl_data_t *ppi = NULL;
6479 6527          uint64_t outToken;
6480 6528          char *allocatedNvBuffer;
6481 6529          stmf_iocdata_t stmfIoctl;
6482 6530  
6483 6531          if (providerName == NULL) {
6484 6532                  return (STMF_ERROR_INVALID_ARG);
6485 6533          }
6486 6534  
6487 6535          /* get size of encoded nvlist */
6488 6536          if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
6489 6537                  return (STMF_STATUS_ERROR);
6490 6538          }
6491 6539  
6492 6540          /* allocate memory for ioctl */
6493 6541          ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
6494 6542              sizeof (stmf_ppioctl_data_t));
6495 6543          if (ppi == NULL) {
6496 6544                  return (STMF_ERROR_NOMEM);
6497 6545          }
6498 6546  
6499 6547          if (setToken) {
6500 6548                  ppi->ppi_token_valid = 1;
6501 6549                  ppi->ppi_token = *setToken;
6502 6550          }
6503 6551  
6504 6552          allocatedNvBuffer = (char *)&ppi->ppi_data;
6505 6553          if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
6506 6554              NV_ENCODE_XDR, 0) != 0) {
6507 6555                  return (STMF_STATUS_ERROR);
6508 6556          }
6509 6557  
6510 6558          /* set provider name and provider type */
6511 6559          (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
6512 6560          switch (providerType) {
6513 6561                  case STMF_LU_PROVIDER_TYPE:
6514 6562                          ppi->ppi_lu_provider = 1;
6515 6563                          break;
6516 6564                  case STMF_PORT_PROVIDER_TYPE:
6517 6565                          ppi->ppi_port_provider = 1;
6518 6566                          break;
6519 6567                  default:
6520 6568                          return (STMF_ERROR_INVALID_ARG);
6521 6569          }
6522 6570  
6523 6571          /* set the size of the ioctl data to packed data size */
6524 6572          ppi->ppi_data_size = nvlistEncodedSize;
6525 6573  
6526 6574          bzero(&stmfIoctl, sizeof (stmfIoctl));
6527 6575  
6528 6576          stmfIoctl.stmf_version = STMF_VERSION_1;
6529 6577          /*
6530 6578           * Subtracting 8 from the size as that is the size of the last member
6531 6579           * of the structure where the packed data resides
6532 6580           */
6533 6581          stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
6534 6582              sizeof (stmf_ppioctl_data_t) - 8;
6535 6583          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
6536 6584          stmfIoctl.stmf_obuf_size = sizeof (uint64_t);
6537 6585          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken;
6538 6586          ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
6539 6587          if (ioctlRet != 0) {
6540 6588                  switch (errno) {
6541 6589                          case EBUSY:
6542 6590                                  ret = STMF_ERROR_BUSY;
6543 6591                                  break;
6544 6592                          case EPERM:
6545 6593                          case EACCES:
6546 6594                                  ret = STMF_ERROR_PERM;
6547 6595                                  break;
6548 6596                          case EINVAL:
6549 6597                                  if (stmfIoctl.stmf_error ==
6550 6598                                      STMF_IOCERR_PPD_UPDATED) {
6551 6599                                          ret = STMF_ERROR_PROV_DATA_STALE;
6552 6600                                  } else {
6553 6601                                          ret = STMF_STATUS_ERROR;
6554 6602                                  }
6555 6603                                  break;
6556 6604                          default:
6557 6605                                  syslog(LOG_DEBUG,
6558 6606                                      "setProviderData:ioctl errno(%d)", errno);
6559 6607                                  ret = STMF_STATUS_ERROR;
6560 6608                                  break;
6561 6609                  }
6562 6610                  if (ret != STMF_STATUS_SUCCESS)
6563 6611                          goto done;
6564 6612          }
6565 6613  
6566 6614          /* caller has asked for new token */
6567 6615          if (setToken) {
6568 6616                  *setToken = outToken;
6569 6617          }
6570 6618  done:
6571 6619          free(ppi);
6572 6620          return (ret);
6573 6621  }
6574 6622  
6575 6623  /*
6576 6624   * set the persistence method in the library only or library and service
6577 6625   */
6578 6626  int
6579 6627  stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet)
6580 6628  {
6581 6629          int ret = STMF_STATUS_SUCCESS;
6582 6630          int oldPersist;
6583 6631  
6584 6632          (void) pthread_mutex_lock(&persistenceTypeLock);
6585 6633          oldPersist = iPersistType;
6586 6634          if (persistType == STMF_PERSIST_NONE ||
6587 6635              persistType == STMF_PERSIST_SMF) {
6588 6636                  iLibSetPersist = B_TRUE;
6589 6637                  iPersistType = persistType;
6590 6638          } else {
6591 6639                  (void) pthread_mutex_unlock(&persistenceTypeLock);
6592 6640                  return (STMF_ERROR_INVALID_ARG);
6593 6641          }
6594 6642          /* Is this for this library open or in SMF */
6595 6643          if (serviceSet == B_TRUE) {
6596 6644                  ret = psSetServicePersist(persistType);
6597 6645                  if (ret != STMF_PS_SUCCESS) {
6598 6646                          ret = STMF_ERROR_PERSIST_TYPE;
6599 6647                          /* Set to old value */
6600 6648                          iPersistType = oldPersist;
6601 6649                  }
6602 6650          }
6603 6651          (void) pthread_mutex_unlock(&persistenceTypeLock);
6604 6652  
6605 6653          return (ret);
6606 6654  }
6607 6655  
6608 6656  /*
6609 6657   * Only returns internal state for persist. If unset, goes to ps. If that
6610 6658   * fails, returns default setting
6611 6659   */
6612 6660  static uint8_t
6613 6661  iGetPersistMethod()
6614 6662  {
6615 6663  
6616 6664          uint8_t persistType = 0;
6617 6665  
6618 6666          (void) pthread_mutex_lock(&persistenceTypeLock);
6619 6667          if (iLibSetPersist) {
6620 6668                  persistType = iPersistType;
6621 6669          } else {
6622 6670                  int ret;
6623 6671                  ret = psGetServicePersist(&persistType);
6624 6672                  if (ret != STMF_PS_SUCCESS) {
6625 6673                          /* set to default */
6626 6674                          persistType = STMF_DEFAULT_PERSIST;
6627 6675                  }
6628 6676          }
6629 6677          (void) pthread_mutex_unlock(&persistenceTypeLock);
6630 6678          return (persistType);
6631 6679  }
6632 6680  
6633 6681  /*
6634 6682   * Returns either library state or persistent config state depending on
6635 6683   * serviceState
6636 6684   */
6637 6685  int
6638 6686  stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState)
6639 6687  {
6640 6688          int ret = STMF_STATUS_SUCCESS;
6641 6689  
6642 6690          if (persistType == NULL) {
6643 6691                  return (STMF_ERROR_INVALID_ARG);
6644 6692          }
6645 6693          if (serviceState) {
6646 6694                  ret = psGetServicePersist(persistType);
6647 6695                  if (ret != STMF_PS_SUCCESS) {
6648 6696                          ret = STMF_ERROR_PERSIST_TYPE;
6649 6697                  }
6650 6698          } else {
6651 6699                  (void) pthread_mutex_lock(&persistenceTypeLock);
6652 6700                  if (iLibSetPersist) {
6653 6701                          *persistType = iPersistType;
6654 6702                  } else {
6655 6703                          *persistType = STMF_DEFAULT_PERSIST;
6656 6704                  }
6657 6705                  (void) pthread_mutex_unlock(&persistenceTypeLock);
6658 6706          }
6659 6707  
6660 6708          return (ret);
6661 6709  }
6662 6710  
6663 6711  /*
6664 6712   * stmfPostProxyMsg
6665 6713   *
6666 6714   * Purpose: Post a message to the proxy port provider
6667 6715   *
6668 6716   * buf - buffer containing message to post
6669 6717   * buflen - buffer length
6670 6718   */
6671 6719  int
6672 6720  stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen)
6673 6721  {
6674 6722          int ret = STMF_STATUS_SUCCESS;
6675 6723          int ioctlRet;
6676 6724          pppt_iocdata_t ppptIoctl = {0};
6677 6725  
6678 6726          if (buf == NULL) {
6679 6727                  return (STMF_ERROR_INVALID_ARG);
6680 6728          }
6681 6729  
6682 6730          /*
6683 6731           * Issue ioctl to post the message
6684 6732           */
6685 6733          ppptIoctl.pppt_version = PPPT_VERSION_1;
6686 6734          ppptIoctl.pppt_buf_size = buflen;
6687 6735          ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf;
6688 6736          ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl);
6689 6737          if (ioctlRet != 0) {
6690 6738                  switch (errno) {
6691 6739                          case EPERM:
6692 6740                          case EACCES:
6693 6741                                  ret = STMF_ERROR_PERM;
6694 6742                                  break;
6695 6743                          default:
6696 6744                                  ret = STMF_ERROR_POST_MSG_FAILED;
6697 6745                                  break;
6698 6746                  }
6699 6747          }
6700 6748  
6701 6749          return (ret);
6702 6750  }
6703 6751  
6704 6752  /*
6705 6753   * stmfInitProxyDoor
6706 6754   *
6707 6755   * Purpose: Install door in proxy
6708 6756   *
6709 6757   * hdl - pointer to returned handle
6710 6758   * fd - door from door_create()
6711 6759   */
6712 6760  int
6713 6761  stmfInitProxyDoor(int *hdl, int door)
6714 6762  {
6715 6763          int ret = STMF_STATUS_SUCCESS;
6716 6764          int ioctlRet;
6717 6765          int fd;
6718 6766          pppt_iocdata_t ppptIoctl = {0};
6719 6767  
6720 6768          if (hdl == NULL) {
6721 6769                  return (STMF_ERROR_INVALID_ARG);
6722 6770          }
6723 6771  
6724 6772          /*
6725 6773           * Open control node for pppt
6726 6774           */
6727 6775          if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) {
6728 6776                  return (ret);
6729 6777          }
6730 6778  
6731 6779          /*
6732 6780           * Issue ioctl to install the door
6733 6781           */
6734 6782          ppptIoctl.pppt_version = PPPT_VERSION_1;
6735 6783          ppptIoctl.pppt_door_fd = (uint32_t)door;
6736 6784          ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl);
6737 6785          if (ioctlRet != 0) {
6738 6786                  switch (errno) {
6739 6787                          case EPERM:
6740 6788                          case EACCES:
6741 6789                                  ret = STMF_ERROR_PERM;
6742 6790                                  break;
6743 6791                          case EINVAL:
6744 6792                                  ret = STMF_ERROR_INVALID_ARG;
6745 6793                                  break;
6746 6794                          case EBUSY:
6747 6795                                  ret = STMF_ERROR_DOOR_INSTALLED;
6748 6796                                  break;
6749 6797                          default:
6750 6798                                  ret = STMF_STATUS_ERROR;
6751 6799                                  break;
6752 6800                  }
6753 6801          }
6754 6802  
6755 6803          /* return driver fd to caller */
6756 6804          *hdl = fd;
6757 6805          return (ret);
6758 6806  }
6759 6807  
6760 6808  void
6761 6809  stmfDestroyProxyDoor(int hdl)
6762 6810  {
6763 6811          (void) close(hdl);
6764 6812  }
6765 6813  
6766 6814  /*
6767 6815   * validateLunNumIoctl
6768 6816   *
6769 6817   * Purpose: Issues ioctl to check and get available lun# in view entry
6770 6818   *
6771 6819   * viewEntry - view entry to use
6772 6820   */
6773 6821  static int
6774 6822  validateLunNumIoctl(int fd, stmfViewEntry *viewEntry)
6775 6823  {
6776 6824          int ret = STMF_STATUS_SUCCESS;
6777 6825          int ioctlRet;
6778 6826          stmf_iocdata_t stmfIoctl;
6779 6827          stmf_view_op_entry_t ioctlViewEntry;
6780 6828  
6781 6829          bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
6782 6830          /*
6783 6831           * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
6784 6832           * false on input
6785 6833           */
6786 6834          ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
6787 6835          ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
6788 6836          ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
6789 6837  
6790 6838          if (viewEntry->allHosts == B_FALSE) {
6791 6839                  bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
6792 6840                      sizeof (stmfGroupName));
6793 6841                  ioctlViewEntry.ve_host_group.name_size =
6794 6842                      strlen((char *)viewEntry->hostGroup);
6795 6843          }
6796 6844          if (viewEntry->allTargets == B_FALSE) {
6797 6845                  bcopy(viewEntry->targetGroup,
6798 6846                      &ioctlViewEntry.ve_target_group.name,
6799 6847                      sizeof (stmfGroupName));
6800 6848                  ioctlViewEntry.ve_target_group.name_size =
6801 6849                      strlen((char *)viewEntry->targetGroup);
6802 6850          }
6803 6851          /* Validating the lun number */
6804 6852          if (viewEntry->luNbrValid) {
6805 6853                  bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
6806 6854                      sizeof (ioctlViewEntry.ve_lu_nbr));
6807 6855          }
6808 6856  
6809 6857          bzero(&stmfIoctl, sizeof (stmfIoctl));
6810 6858          /*
6811 6859           * Issue ioctl to validate lun# in the view entry
6812 6860           */
6813 6861          stmfIoctl.stmf_version = STMF_VERSION_1;
6814 6862          stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
6815 6863          stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6816 6864          stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
6817 6865          stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6818 6866          ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl);
6819 6867  
6820 6868          /* save available lun number */
6821 6869          if (!viewEntry->luNbrValid) {
6822 6870                  bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
6823 6871                      sizeof (ioctlViewEntry.ve_lu_nbr));
6824 6872          }
6825 6873          if (ioctlRet != 0) {
6826 6874                  switch (errno) {
6827 6875                          case EBUSY:
6828 6876                                  ret = STMF_ERROR_BUSY;
6829 6877                                  break;
6830 6878                          case EPERM:
6831 6879                                  ret = STMF_ERROR_PERM;
6832 6880                                  break;
6833 6881                          case EACCES:
6834 6882                                  switch (stmfIoctl.stmf_error) {
6835 6883                                          case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6836 6884                                                  ret = STMF_ERROR_CONFIG_NONE;
6837 6885                                                  break;
6838 6886                                          default:
6839 6887                                                  ret = STMF_ERROR_PERM;
6840 6888                                                  break;
6841 6889                                  }
6842 6890                                  break;
6843 6891                          default:
6844 6892                                  switch (stmfIoctl.stmf_error) {
6845 6893                                          case STMF_IOCERR_LU_NUMBER_IN_USE:
6846 6894                                                  ret = STMF_ERROR_LUN_IN_USE;
6847 6895                                                  break;
6848 6896                                          case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
6849 6897                                                  ret = STMF_ERROR_VE_CONFLICT;
6850 6898                                                  break;
6851 6899                                          case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6852 6900                                                  ret = STMF_ERROR_CONFIG_NONE;
6853 6901                                                  break;
6854 6902                                          case STMF_IOCERR_INVALID_HG:
6855 6903                                                  ret = STMF_ERROR_INVALID_HG;
6856 6904                                                  break;
6857 6905                                          case STMF_IOCERR_INVALID_TG:
6858 6906                                                  ret = STMF_ERROR_INVALID_TG;
6859 6907                                                  break;
6860 6908                                          default:
6861 6909                                                  syslog(LOG_DEBUG,
6862 6910                                                      "addViewEntryIoctl"
6863 6911                                                      ":error(%d)",
6864 6912                                                      stmfIoctl.stmf_error);
6865 6913                                                  ret = STMF_STATUS_ERROR;
6866 6914                                                  break;
6867 6915                                  }
6868 6916                                  break;
6869 6917                  }
6870 6918          }
6871 6919          return (ret);
6872 6920  }
6873 6921  
6874 6922  /*
6875 6923   * stmfValidateView
6876 6924   *
6877 6925   * Purpose: Validate or get lun # base on TG, HG of view entry
6878 6926   *
6879 6927   * viewEntry - view entry structure to use
6880 6928   */
6881 6929  int
6882 6930  stmfValidateView(stmfViewEntry *viewEntry)
6883 6931  {
6884 6932          int ret;
6885 6933          int fd;
6886 6934          stmfViewEntry iViewEntry;
6887 6935  
6888 6936          if (viewEntry == NULL) {
6889 6937                  return (STMF_ERROR_INVALID_ARG);
6890 6938          }
6891 6939  
6892 6940          /* initialize and set internal view entry */
6893 6941          bzero(&iViewEntry, sizeof (iViewEntry));
6894 6942  
6895 6943          if (!viewEntry->allHosts) {
6896 6944                  bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
6897 6945                      sizeof (iViewEntry.hostGroup));
6898 6946          } else {
6899 6947                  iViewEntry.allHosts = B_TRUE;
6900 6948          }
6901 6949  
6902 6950          if (!viewEntry->allTargets) {
6903 6951                  bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
6904 6952                      sizeof (iViewEntry.targetGroup));
6905 6953          } else {
6906 6954                  iViewEntry.allTargets = B_TRUE;
6907 6955          }
6908 6956  
6909 6957          if (viewEntry->luNbrValid) {
6910 6958                  iViewEntry.luNbrValid = B_TRUE;
6911 6959                  bcopy(viewEntry->luNbr, iViewEntry.luNbr,
6912 6960                      sizeof (iViewEntry.luNbr));
6913 6961          }
6914 6962  
6915 6963          /*
6916 6964           * set users return view entry index valid flag to false
6917 6965           * in case of failure
6918 6966           */
6919 6967          viewEntry->veIndexValid = B_FALSE;
6920 6968  
6921 6969          /* Check to ensure service exists */
6922 6970          if (psCheckService() != STMF_STATUS_SUCCESS) {
6923 6971                  return (STMF_ERROR_SERVICE_NOT_FOUND);
6924 6972          }
6925 6973  
6926 6974          /* call init */
6927 6975          ret = initializeConfig();
6928 6976          if (ret != STMF_STATUS_SUCCESS) {
6929 6977                  return (ret);
6930 6978          }
6931 6979  
6932 6980          /*
6933 6981           * Open control node for stmf
6934 6982           */
6935 6983          if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6936 6984                  return (ret);
6937 6985  
6938 6986          /*
6939 6987           * Validate lun# in the view entry from the driver
6940 6988           */
6941 6989          ret = validateLunNumIoctl(fd, &iViewEntry);
6942 6990          (void) close(fd);
6943 6991  
6944 6992          /* save available lun number */
6945 6993          if (!viewEntry->luNbrValid) {
6946 6994                  bcopy(iViewEntry.luNbr, viewEntry->luNbr,
6947 6995                      sizeof (iViewEntry.luNbr));
6948 6996          }
6949 6997  
6950 6998          return (ret);
6951 6999  }
  
    | 
      ↓ open down ↓ | 
    3903 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX