Print this page
4095 minor cleanup up libshare


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 




  27 /* helper functions for using libscf with sharemgr */
  28 
  29 #include <libscf.h>
  30 #include <libxml/parser.h>
  31 #include <libxml/tree.h>
  32 #include "libshare.h"
  33 #include "libshare_impl.h"
  34 #include "scfutil.h"
  35 #include <string.h>
  36 #include <ctype.h>
  37 #include <errno.h>
  38 #include <uuid/uuid.h>
  39 #include <sys/param.h>
  40 #include <signal.h>
  41 #include <sys/time.h>
  42 #include <libintl.h>
  43 
  44 ssize_t scf_max_name_len;
  45 extern struct sa_proto_plugin *sap_proto_list;
  46 extern sa_handle_impl_t get_handle_for_root(xmlNodePtr);
  47 static void set_transaction_tstamp(sa_handle_impl_t);
  48 /*
  49  * The SMF facility uses some properties that must exist. We want to
  50  * skip over these when processing protocol options.
  51  */
  52 static char *skip_props[] = {
  53         "modify_authorization",
  54         "action_authorization",
  55         "value_authorization",
  56         NULL
  57 };
  58 
  59 /*
  60  * sa_scf_fini(handle)
  61  *
  62  * Must be called when done. Called with the handle allocated in
  63  * sa_scf_init(), it cleans up the state and frees any SCF resources
  64  * still in use. Called by sa_fini().
  65  */
  66 
  67 void


  80                 if (handle->pg != NULL)
  81                         scf_pg_destroy(handle->pg);
  82                 if (handle->handle != NULL) {
  83                         handle->scf_state = SCH_STATE_UNINIT;
  84                         if (unbind)
  85                                 (void) scf_handle_unbind(handle->handle);
  86                         scf_handle_destroy(handle->handle);
  87                 }
  88                 free(handle);
  89         }
  90 }
  91 
  92 /*
  93  * sa_scf_init()
  94  *
  95  * Must be called before using any of the SCF functions. Called by
  96  * sa_init() during the API setup.
  97  */
  98 
  99 scfutilhandle_t *
 100 sa_scf_init(sa_handle_impl_t ihandle)
 101 {
 102         scfutilhandle_t *handle;
 103 
 104         scf_max_name_len = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH);
 105         if (scf_max_name_len <= 0)
 106                 scf_max_name_len = SA_MAX_NAME_LEN + 1;
 107 
 108         handle = calloc(1, sizeof (scfutilhandle_t));
 109         if (handle == NULL)
 110                 return (handle);
 111 
 112         ihandle->scfhandle = handle;
 113         handle->scf_state = SCH_STATE_INITIALIZING;
 114         handle->handle = scf_handle_create(SCF_VERSION);
 115         if (handle->handle == NULL) {
 116                 free(handle);
 117                 handle = NULL;
 118                 (void) printf("libshare could not access SMF repository: %s\n",
 119                     scf_strerror(scf_error()));
 120                 return (handle);


 124 
 125         handle->scope = scf_scope_create(handle->handle);
 126         handle->service = scf_service_create(handle->handle);
 127         handle->pg = scf_pg_create(handle->handle);
 128 
 129         /* Make sure we have sufficient SMF running */
 130         handle->instance = scf_instance_create(handle->handle);
 131         if (handle->scope == NULL || handle->service == NULL ||
 132             handle->pg == NULL || handle->instance == NULL)
 133                 goto err;
 134         if (scf_handle_get_scope(handle->handle,
 135             SCF_SCOPE_LOCAL, handle->scope) != 0)
 136                 goto err;
 137         if (scf_scope_get_service(handle->scope,
 138             SA_GROUP_SVC_NAME, handle->service) != 0)
 139                 goto err;
 140 
 141         handle->scf_state = SCH_STATE_INIT;
 142         if (sa_get_instance(handle, "default") != SA_OK) {
 143                 sa_group_t defgrp;
 144                 defgrp = sa_create_group((sa_handle_t)ihandle, "default", NULL);
 145                 /* Only NFS enabled for "default" group. */
 146                 if (defgrp != NULL)
 147                         (void) sa_create_optionset(defgrp, "nfs");
 148         }
 149 
 150         return (handle);
 151 
 152         /* Error handling/unwinding */
 153 err:
 154         (void) sa_scf_fini(handle);
 155         (void) printf("libshare SMF initialization problem: %s\n",
 156             scf_strerror(scf_error()));
 157         return (NULL);
 158 }
 159 
 160 /*
 161  * get_scf_limit(name)
 162  *
 163  * Since we use  scf_limit a lot and do the same  check and return the
 164  * same  value  if  it  fails,   implement  as  a  function  for  code


1332                                 ret = SA_SYSTEM_ERR;
1333                         }
1334                 }
1335         }
1336         if (ret == SA_SYSTEM_ERR &&
1337             scf_error() == SCF_ERROR_PERMISSION_DENIED) {
1338                 ret = SA_NO_PERMISSION;
1339         }
1340         return (ret);
1341 }
1342 
1343 
1344 /*
1345  * sa_end_transaction(scfhandle, sahandle)
1346  *
1347  * Commit the changes that were added to the transaction in the
1348  * handle. Do all necessary cleanup.
1349  */
1350 
1351 int
1352 sa_end_transaction(scfutilhandle_t *handle, sa_handle_impl_t sahandle)
1353 {
1354         int ret = SA_OK;
1355 
1356         if (handle == NULL || handle->trans == NULL || sahandle == NULL) {
1357                 ret = SA_SYSTEM_ERR;
1358         } else {
1359                 if (scf_transaction_commit(handle->trans) < 0)
1360                         ret = SA_SYSTEM_ERR;
1361                 scf_transaction_destroy_children(handle->trans);
1362                 scf_transaction_destroy(handle->trans);
1363                 if (ret == SA_OK)
1364                         set_transaction_tstamp(sahandle);
1365                 handle->trans = NULL;
1366         }
1367         return (ret);
1368 }
1369 
1370 /*
1371  * sa_abort_transaction(handle)
1372  *


1375  */
1376 
1377 void
1378 sa_abort_transaction(scfutilhandle_t *handle)
1379 {
1380         if (handle->trans != NULL) {
1381                 scf_transaction_reset_all(handle->trans);
1382                 scf_transaction_destroy_children(handle->trans);
1383                 scf_transaction_destroy(handle->trans);
1384                 handle->trans = NULL;
1385         }
1386 }
1387 
1388 /*
1389  * set_transaction_tstamp(sahandle)
1390  *
1391  * After a successful transaction commit, update the timestamp of the
1392  * last transaction. This lets us detect changes from other processes.
1393  */
1394 static void
1395 set_transaction_tstamp(sa_handle_impl_t sahandle)
1396 {
1397         char tstring[32];
1398         struct timeval tv;
1399         scfutilhandle_t *scfhandle;
1400 
1401         if (sahandle == NULL || sahandle->scfhandle == NULL)
1402                 return;
1403 
1404         scfhandle = sahandle->scfhandle;
1405 
1406         if (sa_get_instance(scfhandle, "default") != SA_OK)
1407                 return;
1408 
1409         if (gettimeofday(&tv, NULL) != 0)
1410                 return;
1411 
1412         if (sa_start_transaction(scfhandle, "*state") != SA_OK)
1413                 return;
1414 
1415         sahandle->tstrans = TSTAMP((*(timestruc_t *)&tv));


1759                         }
1760                         if (ret == SA_OK) {
1761                                 /*
1762                                  * If there are resource names, bundle them up
1763                                  * and save appropriately.
1764                                  */
1765                                 ret = sa_set_resource_property(handle, share);
1766                         }
1767 
1768                         if (ret == SA_OK) {
1769                                 description = sa_get_share_description(share);
1770                                 if (description != NULL) {
1771                                         ret = sa_set_property(handle,
1772                                             "description",
1773                                             description);
1774                                         sa_free_share_description(description);
1775                                 }
1776                         }
1777                         /* Make sure we cleanup the transaction */
1778                         if (ret == SA_OK) {
1779                                 sa_handle_impl_t sahandle;
1780                                 sahandle = (sa_handle_impl_t)
1781                                     sa_find_group_handle(group);
1782                                 if (sahandle != NULL)
1783                                         ret = sa_end_transaction(handle,
1784                                             sahandle);
1785                                 else
1786                                         ret = SA_SYSTEM_ERR;
1787                         } else {
1788                                 sa_abort_transaction(handle);
1789                         }
1790 
1791                         (void) sigprocmask(SIG_SETMASK, &old, NULL);
1792 
1793                         free(sharename);
1794                 }
1795         }
1796         if (ret == SA_SYSTEM_ERR) {
1797                 int err = scf_error();
1798                 if (err == SCF_ERROR_PERMISSION_DENIED)
1799                         ret = SA_NO_PERMISSION;
1800         }
1801         if (propstring != NULL)




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright (c) 2013 RackTop Systems.
  29  */
  30 
  31 /* helper functions for using libscf with sharemgr */
  32 
  33 #include <libscf.h>
  34 #include <libxml/parser.h>
  35 #include <libxml/tree.h>
  36 #include "libshare.h"
  37 #include "libshare_impl.h"
  38 #include "scfutil.h"
  39 #include <string.h>
  40 #include <ctype.h>
  41 #include <errno.h>
  42 #include <uuid/uuid.h>
  43 #include <sys/param.h>
  44 #include <signal.h>
  45 #include <sys/time.h>
  46 #include <libintl.h>
  47 
  48 ssize_t scf_max_name_len;
  49 extern struct sa_proto_plugin *sap_proto_list;
  50 extern sa_handle_t get_handle_for_root(xmlNodePtr);
  51 static void set_transaction_tstamp(sa_handle_t);
  52 /*
  53  * The SMF facility uses some properties that must exist. We want to
  54  * skip over these when processing protocol options.
  55  */
  56 static char *skip_props[] = {
  57         "modify_authorization",
  58         "action_authorization",
  59         "value_authorization",
  60         NULL
  61 };
  62 
  63 /*
  64  * sa_scf_fini(handle)
  65  *
  66  * Must be called when done. Called with the handle allocated in
  67  * sa_scf_init(), it cleans up the state and frees any SCF resources
  68  * still in use. Called by sa_fini().
  69  */
  70 
  71 void


  84                 if (handle->pg != NULL)
  85                         scf_pg_destroy(handle->pg);
  86                 if (handle->handle != NULL) {
  87                         handle->scf_state = SCH_STATE_UNINIT;
  88                         if (unbind)
  89                                 (void) scf_handle_unbind(handle->handle);
  90                         scf_handle_destroy(handle->handle);
  91                 }
  92                 free(handle);
  93         }
  94 }
  95 
  96 /*
  97  * sa_scf_init()
  98  *
  99  * Must be called before using any of the SCF functions. Called by
 100  * sa_init() during the API setup.
 101  */
 102 
 103 scfutilhandle_t *
 104 sa_scf_init(sa_handle_t ihandle)
 105 {
 106         scfutilhandle_t *handle;
 107 
 108         scf_max_name_len = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH);
 109         if (scf_max_name_len <= 0)
 110                 scf_max_name_len = SA_MAX_NAME_LEN + 1;
 111 
 112         handle = calloc(1, sizeof (scfutilhandle_t));
 113         if (handle == NULL)
 114                 return (handle);
 115 
 116         ihandle->scfhandle = handle;
 117         handle->scf_state = SCH_STATE_INITIALIZING;
 118         handle->handle = scf_handle_create(SCF_VERSION);
 119         if (handle->handle == NULL) {
 120                 free(handle);
 121                 handle = NULL;
 122                 (void) printf("libshare could not access SMF repository: %s\n",
 123                     scf_strerror(scf_error()));
 124                 return (handle);


 128 
 129         handle->scope = scf_scope_create(handle->handle);
 130         handle->service = scf_service_create(handle->handle);
 131         handle->pg = scf_pg_create(handle->handle);
 132 
 133         /* Make sure we have sufficient SMF running */
 134         handle->instance = scf_instance_create(handle->handle);
 135         if (handle->scope == NULL || handle->service == NULL ||
 136             handle->pg == NULL || handle->instance == NULL)
 137                 goto err;
 138         if (scf_handle_get_scope(handle->handle,
 139             SCF_SCOPE_LOCAL, handle->scope) != 0)
 140                 goto err;
 141         if (scf_scope_get_service(handle->scope,
 142             SA_GROUP_SVC_NAME, handle->service) != 0)
 143                 goto err;
 144 
 145         handle->scf_state = SCH_STATE_INIT;
 146         if (sa_get_instance(handle, "default") != SA_OK) {
 147                 sa_group_t defgrp;
 148                 defgrp = sa_create_group(ihandle, "default", NULL);
 149                 /* Only NFS enabled for "default" group. */
 150                 if (defgrp != NULL)
 151                         (void) sa_create_optionset(defgrp, "nfs");
 152         }
 153 
 154         return (handle);
 155 
 156         /* Error handling/unwinding */
 157 err:
 158         (void) sa_scf_fini(handle);
 159         (void) printf("libshare SMF initialization problem: %s\n",
 160             scf_strerror(scf_error()));
 161         return (NULL);
 162 }
 163 
 164 /*
 165  * get_scf_limit(name)
 166  *
 167  * Since we use  scf_limit a lot and do the same  check and return the
 168  * same  value  if  it  fails,   implement  as  a  function  for  code


1336                                 ret = SA_SYSTEM_ERR;
1337                         }
1338                 }
1339         }
1340         if (ret == SA_SYSTEM_ERR &&
1341             scf_error() == SCF_ERROR_PERMISSION_DENIED) {
1342                 ret = SA_NO_PERMISSION;
1343         }
1344         return (ret);
1345 }
1346 
1347 
1348 /*
1349  * sa_end_transaction(scfhandle, sahandle)
1350  *
1351  * Commit the changes that were added to the transaction in the
1352  * handle. Do all necessary cleanup.
1353  */
1354 
1355 int
1356 sa_end_transaction(scfutilhandle_t *handle, sa_handle_t sahandle)
1357 {
1358         int ret = SA_OK;
1359 
1360         if (handle == NULL || handle->trans == NULL || sahandle == NULL) {
1361                 ret = SA_SYSTEM_ERR;
1362         } else {
1363                 if (scf_transaction_commit(handle->trans) < 0)
1364                         ret = SA_SYSTEM_ERR;
1365                 scf_transaction_destroy_children(handle->trans);
1366                 scf_transaction_destroy(handle->trans);
1367                 if (ret == SA_OK)
1368                         set_transaction_tstamp(sahandle);
1369                 handle->trans = NULL;
1370         }
1371         return (ret);
1372 }
1373 
1374 /*
1375  * sa_abort_transaction(handle)
1376  *


1379  */
1380 
1381 void
1382 sa_abort_transaction(scfutilhandle_t *handle)
1383 {
1384         if (handle->trans != NULL) {
1385                 scf_transaction_reset_all(handle->trans);
1386                 scf_transaction_destroy_children(handle->trans);
1387                 scf_transaction_destroy(handle->trans);
1388                 handle->trans = NULL;
1389         }
1390 }
1391 
1392 /*
1393  * set_transaction_tstamp(sahandle)
1394  *
1395  * After a successful transaction commit, update the timestamp of the
1396  * last transaction. This lets us detect changes from other processes.
1397  */
1398 static void
1399 set_transaction_tstamp(sa_handle_t sahandle)
1400 {
1401         char tstring[32];
1402         struct timeval tv;
1403         scfutilhandle_t *scfhandle;
1404 
1405         if (sahandle == NULL || sahandle->scfhandle == NULL)
1406                 return;
1407 
1408         scfhandle = sahandle->scfhandle;
1409 
1410         if (sa_get_instance(scfhandle, "default") != SA_OK)
1411                 return;
1412 
1413         if (gettimeofday(&tv, NULL) != 0)
1414                 return;
1415 
1416         if (sa_start_transaction(scfhandle, "*state") != SA_OK)
1417                 return;
1418 
1419         sahandle->tstrans = TSTAMP((*(timestruc_t *)&tv));


1763                         }
1764                         if (ret == SA_OK) {
1765                                 /*
1766                                  * If there are resource names, bundle them up
1767                                  * and save appropriately.
1768                                  */
1769                                 ret = sa_set_resource_property(handle, share);
1770                         }
1771 
1772                         if (ret == SA_OK) {
1773                                 description = sa_get_share_description(share);
1774                                 if (description != NULL) {
1775                                         ret = sa_set_property(handle,
1776                                             "description",
1777                                             description);
1778                                         sa_free_share_description(description);
1779                                 }
1780                         }
1781                         /* Make sure we cleanup the transaction */
1782                         if (ret == SA_OK) {
1783                                 sa_handle_t sahandle;
1784                                 sahandle = sa_find_group_handle(group);

1785                                 if (sahandle != NULL)
1786                                         ret = sa_end_transaction(handle,
1787                                             sahandle);
1788                                 else
1789                                         ret = SA_SYSTEM_ERR;
1790                         } else {
1791                                 sa_abort_transaction(handle);
1792                         }
1793 
1794                         (void) sigprocmask(SIG_SETMASK, &old, NULL);
1795 
1796                         free(sharename);
1797                 }
1798         }
1799         if (ret == SA_SYSTEM_ERR) {
1800                 int err = scf_error();
1801                 if (err == SCF_ERROR_PERMISSION_DENIED)
1802                         ret = SA_NO_PERMISSION;
1803         }
1804         if (propstring != NULL)