12654012fSReza Sabdar /* 22654012fSReza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 32654012fSReza Sabdar * Use is subject to license terms. 433f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved. 5*f093add7SJan Kryl * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 62654012fSReza Sabdar */ 72654012fSReza Sabdar 82654012fSReza Sabdar /* 92654012fSReza Sabdar * BSD 3 Clause License 102654012fSReza Sabdar * 112654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 122654012fSReza Sabdar * 132654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 142654012fSReza Sabdar * modification, are permitted provided that the following conditions 152654012fSReza Sabdar * are met: 162654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 172654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 182654012fSReza Sabdar * 192654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 202654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 212654012fSReza Sabdar * the documentation and/or other materials provided with the 222654012fSReza Sabdar * distribution. 232654012fSReza Sabdar * 242654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 252654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 262654012fSReza Sabdar * products derived from this software without specific prior written 272654012fSReza Sabdar * permission. 282654012fSReza Sabdar * 292654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 302654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 312654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 322654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 332654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 342654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 352654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 362654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 372654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 382654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 392654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 402654012fSReza Sabdar */ 412654012fSReza Sabdar 422654012fSReza Sabdar /* 432654012fSReza Sabdar * NDMP configuration management 442654012fSReza Sabdar */ 452654012fSReza Sabdar #include <stdio.h> 462654012fSReza Sabdar #include <stdlib.h> 472654012fSReza Sabdar #include <synch.h> 482654012fSReza Sabdar #include <libintl.h> 492654012fSReza Sabdar #include <strings.h> 502654012fSReza Sabdar #include <libndmp.h> 512654012fSReza Sabdar 522654012fSReza Sabdar /* NDMP properties configuration */ 532654012fSReza Sabdar #define NDMP_GROUP_FMRI_PREFIX "system/ndmpd" 542654012fSReza Sabdar #define NDMP_INST "svc:/system/ndmpd:default" 552654012fSReza Sabdar #define NDMP_PROP_LEN 600 562654012fSReza Sabdar static char *ndmp_pg[] = { 572654012fSReza Sabdar "ndmpd", 582654012fSReza Sabdar "read" 592654012fSReza Sabdar }; 602654012fSReza Sabdar #define NPG (sizeof (ndmp_pg) / sizeof (ndmp_pg[0])) 612654012fSReza Sabdar 622654012fSReza Sabdar /* Handle Init states */ 632654012fSReza Sabdar #define NDMP_SCH_STATE_UNINIT 0 642654012fSReza Sabdar #define NDMP_SCH_STATE_INITIALIZING 1 652654012fSReza Sabdar #define NDMP_SCH_STATE_INIT 2 662654012fSReza Sabdar 672654012fSReza Sabdar /* NDMP scf handle structure */ 682654012fSReza Sabdar typedef struct ndmp_scfhandle { 692654012fSReza Sabdar scf_handle_t *scf_handle; 702654012fSReza Sabdar int scf_state; 712654012fSReza Sabdar scf_service_t *scf_service; 722654012fSReza Sabdar scf_scope_t *scf_scope; 732654012fSReza Sabdar scf_transaction_t *scf_trans; 742654012fSReza Sabdar scf_propertygroup_t *scf_pg; 752654012fSReza Sabdar } ndmp_scfhandle_t; 762654012fSReza Sabdar 77*f093add7SJan Kryl static int ndmp_config_saveenv(ndmp_scfhandle_t *, boolean_t); 788b87c155SJan Kryl static ndmp_scfhandle_t *ndmp_smf_scf_init(const char *); 792654012fSReza Sabdar static void ndmp_smf_scf_fini(ndmp_scfhandle_t *); 802654012fSReza Sabdar static int ndmp_smf_start_transaction(ndmp_scfhandle_t *); 81*f093add7SJan Kryl static int ndmp_smf_end_transaction(ndmp_scfhandle_t *, boolean_t); 828b87c155SJan Kryl static int ndmp_smf_set_property(ndmp_scfhandle_t *, const char *, 838b87c155SJan Kryl const char *); 848b87c155SJan Kryl static int ndmp_smf_get_property(ndmp_scfhandle_t *, const char *, char *, 858b87c155SJan Kryl size_t); 868b87c155SJan Kryl static int ndmp_smf_create_service_pgroup(ndmp_scfhandle_t *, const char *); 878b87c155SJan Kryl static int ndmp_smf_delete_property(ndmp_scfhandle_t *, const char *); 888b87c155SJan Kryl static int ndmp_smf_get_pg_name(ndmp_scfhandle_t *, const char *, char **); 892654012fSReza Sabdar 902654012fSReza Sabdar /* 912654012fSReza Sabdar * This routine send a refresh signal to ndmpd service which cause ndmpd 922654012fSReza Sabdar * property table to be refeshed with current ndmpd properties value from SMF. 932654012fSReza Sabdar */ 942654012fSReza Sabdar int 952654012fSReza Sabdar ndmp_service_refresh(void) 962654012fSReza Sabdar { 97*f093add7SJan Kryl int rc = smf_refresh_instance(NDMP_INST); 982654012fSReza Sabdar 99*f093add7SJan Kryl if (rc != 0) 1002654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 101*f093add7SJan Kryl return (rc); 1022654012fSReza Sabdar } 1032654012fSReza Sabdar 1042654012fSReza Sabdar /* 1052654012fSReza Sabdar * Returns value of the specified variable/property. The return value is a 1062654012fSReza Sabdar * string pointer to the locally allocated memory if the config param is 1072654012fSReza Sabdar * defined otherwise it would be NULL. 1082654012fSReza Sabdar */ 1092654012fSReza Sabdar int 1108b87c155SJan Kryl ndmp_get_prop(const char *prop, char **value) 1112654012fSReza Sabdar { 112*f093add7SJan Kryl ndmp_scfhandle_t *handle; 113*f093add7SJan Kryl char *lval; 1142654012fSReza Sabdar char *pgname; 1152654012fSReza Sabdar 116*f093add7SJan Kryl *value = NULL; 1172654012fSReza Sabdar if ((handle = ndmp_smf_scf_init(NDMP_GROUP_FMRI_PREFIX)) == NULL) { 1182654012fSReza Sabdar return (-1); 1192654012fSReza Sabdar } 1202654012fSReza Sabdar if (ndmp_smf_get_pg_name(handle, prop, &pgname)) { 121*f093add7SJan Kryl ndmp_smf_scf_fini(handle); 1222654012fSReza Sabdar ndmp_errno = ENDMP_SMF_PROP_GRP; 1232654012fSReza Sabdar return (-1); 1242654012fSReza Sabdar } 1252654012fSReza Sabdar if (ndmp_smf_create_service_pgroup(handle, pgname)) { 1262654012fSReza Sabdar ndmp_smf_scf_fini(handle); 127*f093add7SJan Kryl return (-1); 128*f093add7SJan Kryl } 129*f093add7SJan Kryl if ((lval = malloc(NDMP_PROP_LEN)) == NULL) { 130*f093add7SJan Kryl ndmp_smf_scf_fini(handle); 131*f093add7SJan Kryl ndmp_errno = ENDMP_MEM_ALLOC; 1322654012fSReza Sabdar return (-1); 1332654012fSReza Sabdar } 1342654012fSReza Sabdar if (ndmp_smf_get_property(handle, prop, lval, NDMP_PROP_LEN) != 0) { 1352654012fSReza Sabdar ndmp_smf_scf_fini(handle); 1362654012fSReza Sabdar free(lval); 1372654012fSReza Sabdar ndmp_errno = ENDMP_SMF_PROP; 1382654012fSReza Sabdar return (-1); 1392654012fSReza Sabdar } 1402654012fSReza Sabdar *value = lval; 1412654012fSReza Sabdar ndmp_smf_scf_fini(handle); 1422654012fSReza Sabdar return (0); 1432654012fSReza Sabdar } 1442654012fSReza Sabdar 1452654012fSReza Sabdar int 1468b87c155SJan Kryl ndmp_set_prop(const char *env, const char *env_val) 1472654012fSReza Sabdar { 148*f093add7SJan Kryl ndmp_scfhandle_t *handle; 1492654012fSReza Sabdar char *pgname; 150*f093add7SJan Kryl int rc; 1512654012fSReza Sabdar 1522654012fSReza Sabdar if ((handle = ndmp_smf_scf_init(NDMP_GROUP_FMRI_PREFIX)) == NULL) 1532654012fSReza Sabdar return (-1); 1542654012fSReza Sabdar 1552654012fSReza Sabdar if (ndmp_smf_get_pg_name(handle, env, &pgname)) { 156*f093add7SJan Kryl ndmp_smf_scf_fini(handle); 1572654012fSReza Sabdar ndmp_errno = ENDMP_SMF_PROP_GRP; 1582654012fSReza Sabdar return (-1); 1592654012fSReza Sabdar } 1602654012fSReza Sabdar 161*f093add7SJan Kryl if (ndmp_smf_create_service_pgroup(handle, pgname)) { 162*f093add7SJan Kryl ndmp_smf_scf_fini(handle); 1632654012fSReza Sabdar return (-1); 1642654012fSReza Sabdar } 1652654012fSReza Sabdar 166*f093add7SJan Kryl if (ndmp_smf_start_transaction(handle)) { 167*f093add7SJan Kryl ndmp_smf_scf_fini(handle); 1682654012fSReza Sabdar return (-1); 169*f093add7SJan Kryl } 1702654012fSReza Sabdar 171*f093add7SJan Kryl if (env_val) 172*f093add7SJan Kryl rc = ndmp_smf_set_property(handle, env, env_val); 173*f093add7SJan Kryl else 174*f093add7SJan Kryl rc = ndmp_smf_delete_property(handle, env); 175*f093add7SJan Kryl 176*f093add7SJan Kryl if (ndmp_config_saveenv(handle, (rc == 0)) == 0) 177*f093add7SJan Kryl return (rc); 178*f093add7SJan Kryl else 179*f093add7SJan Kryl return (-1); 1802654012fSReza Sabdar } 1812654012fSReza Sabdar 1822654012fSReza Sabdar static int 1838b87c155SJan Kryl ndmp_smf_get_pg_name(ndmp_scfhandle_t *h, const char *pname, char **pgname) 1842654012fSReza Sabdar { 1852654012fSReza Sabdar scf_value_t *value; 1862654012fSReza Sabdar scf_property_t *prop; 1872654012fSReza Sabdar int i; 1882654012fSReza Sabdar 1892654012fSReza Sabdar for (i = 0; i < NPG; i++) { 1902654012fSReza Sabdar if (scf_service_get_pg(h->scf_service, ndmp_pg[i], 1912654012fSReza Sabdar h->scf_pg) != 0) 1922654012fSReza Sabdar return (-1); 1932654012fSReza Sabdar 1942654012fSReza Sabdar if ((value = scf_value_create(h->scf_handle)) == NULL) 1952654012fSReza Sabdar return (-1); 1962654012fSReza Sabdar 1972654012fSReza Sabdar if ((prop = scf_property_create(h->scf_handle)) == NULL) { 1982654012fSReza Sabdar scf_value_destroy(value); 1992654012fSReza Sabdar return (-1); 2002654012fSReza Sabdar } 2012654012fSReza Sabdar /* 2022654012fSReza Sabdar * This will fail if property does not exist in the property 2032654012fSReza Sabdar * group. Check the next property group in case of failure. 2042654012fSReza Sabdar */ 2052654012fSReza Sabdar if ((scf_pg_get_property(h->scf_pg, pname, prop)) != 0) { 2062654012fSReza Sabdar scf_value_destroy(value); 2072654012fSReza Sabdar scf_property_destroy(prop); 2082654012fSReza Sabdar continue; 2092654012fSReza Sabdar } 2102654012fSReza Sabdar 2112654012fSReza Sabdar *pgname = ndmp_pg[i]; 2122654012fSReza Sabdar scf_value_destroy(value); 2132654012fSReza Sabdar scf_property_destroy(prop); 2142654012fSReza Sabdar return (0); 2152654012fSReza Sabdar } 2162654012fSReza Sabdar return (-1); 2172654012fSReza Sabdar } 2182654012fSReza Sabdar 2192654012fSReza Sabdar /* 2202654012fSReza Sabdar * Basically commit the transaction. 2212654012fSReza Sabdar */ 2222654012fSReza Sabdar static int 223*f093add7SJan Kryl ndmp_config_saveenv(ndmp_scfhandle_t *handle, boolean_t commit) 2242654012fSReza Sabdar { 2252654012fSReza Sabdar int ret = 0; 2262654012fSReza Sabdar 227*f093add7SJan Kryl ret = ndmp_smf_end_transaction(handle, commit); 2282654012fSReza Sabdar 2292654012fSReza Sabdar ndmp_smf_scf_fini(handle); 2302654012fSReza Sabdar return (ret); 2312654012fSReza Sabdar } 2322654012fSReza Sabdar 2332654012fSReza Sabdar /* 2342654012fSReza Sabdar * Must be called when done. Called with the handle allocated in 2352654012fSReza Sabdar * ndmp_smf_scf_init(), it cleans up the state and frees any SCF resources 2362654012fSReza Sabdar * still in use. 2372654012fSReza Sabdar */ 2382654012fSReza Sabdar static void 2392654012fSReza Sabdar ndmp_smf_scf_fini(ndmp_scfhandle_t *handle) 2402654012fSReza Sabdar { 241*f093add7SJan Kryl if (handle == NULL) 242*f093add7SJan Kryl return; 243*f093add7SJan Kryl 2442654012fSReza Sabdar scf_scope_destroy(handle->scf_scope); 2452654012fSReza Sabdar scf_service_destroy(handle->scf_service); 2462654012fSReza Sabdar scf_pg_destroy(handle->scf_pg); 2472654012fSReza Sabdar handle->scf_state = NDMP_SCH_STATE_UNINIT; 2482654012fSReza Sabdar (void) scf_handle_unbind(handle->scf_handle); 2492654012fSReza Sabdar scf_handle_destroy(handle->scf_handle); 2502654012fSReza Sabdar free(handle); 2512654012fSReza Sabdar } 2522654012fSReza Sabdar 2532654012fSReza Sabdar /* 2542654012fSReza Sabdar * Must be called before using any of the SCF functions. Returns 2552654012fSReza Sabdar * ndmp_scfhandle_t pointer if success. 2562654012fSReza Sabdar */ 2572654012fSReza Sabdar static ndmp_scfhandle_t * 2588b87c155SJan Kryl ndmp_smf_scf_init(const char *svc_name) 2592654012fSReza Sabdar { 2602654012fSReza Sabdar ndmp_scfhandle_t *handle; 2612654012fSReza Sabdar 2622654012fSReza Sabdar handle = (ndmp_scfhandle_t *)calloc(1, sizeof (ndmp_scfhandle_t)); 2632654012fSReza Sabdar if (handle != NULL) { 2642654012fSReza Sabdar handle->scf_state = NDMP_SCH_STATE_INITIALIZING; 2652654012fSReza Sabdar if (((handle->scf_handle = 2662654012fSReza Sabdar scf_handle_create(SCF_VERSION)) != NULL) && 2672654012fSReza Sabdar (scf_handle_bind(handle->scf_handle) == 0)) { 2682654012fSReza Sabdar if ((handle->scf_scope = 2692654012fSReza Sabdar scf_scope_create(handle->scf_handle)) == NULL) 2702654012fSReza Sabdar goto err; 2712654012fSReza Sabdar 2722654012fSReza Sabdar if (scf_handle_get_local_scope(handle->scf_handle, 2732654012fSReza Sabdar handle->scf_scope) != 0) 2742654012fSReza Sabdar goto err; 2752654012fSReza Sabdar 2762654012fSReza Sabdar if ((handle->scf_service = 2772654012fSReza Sabdar scf_service_create(handle->scf_handle)) == NULL) 2782654012fSReza Sabdar goto err; 2792654012fSReza Sabdar 2802654012fSReza Sabdar if (scf_scope_get_service(handle->scf_scope, svc_name, 2812654012fSReza Sabdar handle->scf_service) != SCF_SUCCESS) 2822654012fSReza Sabdar goto err; 2832654012fSReza Sabdar 2842654012fSReza Sabdar if ((handle->scf_pg = 2852654012fSReza Sabdar scf_pg_create(handle->scf_handle)) == NULL) 2862654012fSReza Sabdar goto err; 2872654012fSReza Sabdar 2882654012fSReza Sabdar handle->scf_state = NDMP_SCH_STATE_INIT; 2892654012fSReza Sabdar } else { 2902654012fSReza Sabdar goto err; 2912654012fSReza Sabdar } 2922654012fSReza Sabdar } else { 2932654012fSReza Sabdar ndmp_errno = ENDMP_MEM_ALLOC; 2942654012fSReza Sabdar handle = NULL; 2952654012fSReza Sabdar } 2962654012fSReza Sabdar return (handle); 2972654012fSReza Sabdar 2982654012fSReza Sabdar /* Error handling/unwinding */ 2992654012fSReza Sabdar err: 3002654012fSReza Sabdar (void) ndmp_smf_scf_fini(handle); 3012654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 3022654012fSReza Sabdar return (NULL); 3032654012fSReza Sabdar } 3042654012fSReza Sabdar 3052654012fSReza Sabdar /* 3062654012fSReza Sabdar * Create a new property group at service level. 3072654012fSReza Sabdar */ 3082654012fSReza Sabdar static int 3098b87c155SJan Kryl ndmp_smf_create_service_pgroup(ndmp_scfhandle_t *handle, const char *pgroup) 3102654012fSReza Sabdar { 3112654012fSReza Sabdar int err; 3122654012fSReza Sabdar 3132654012fSReza Sabdar /* 3142654012fSReza Sabdar * Only create a handle if it doesn't exist. It is ok to exist since 3152654012fSReza Sabdar * the pg handle will be set as a side effect. 3162654012fSReza Sabdar */ 3172654012fSReza Sabdar if (handle->scf_pg == NULL) { 3182654012fSReza Sabdar if ((handle->scf_pg = 3192654012fSReza Sabdar scf_pg_create(handle->scf_handle)) == NULL) 3202654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 3212654012fSReza Sabdar return (-1); 3222654012fSReza Sabdar } 3232654012fSReza Sabdar 3242654012fSReza Sabdar /* 3252654012fSReza Sabdar * If the pgroup exists, we are done. If it doesn't, then we need to 3262654012fSReza Sabdar * actually add one to the service instance. 3272654012fSReza Sabdar */ 3282654012fSReza Sabdar if (scf_service_get_pg(handle->scf_service, 3292654012fSReza Sabdar pgroup, handle->scf_pg) != 0) { 3302654012fSReza Sabdar /* Doesn't exist so create one */ 3312654012fSReza Sabdar if (scf_service_add_pg(handle->scf_service, pgroup, 3322654012fSReza Sabdar SCF_GROUP_FRAMEWORK, 0, handle->scf_pg) != 0) { 3332654012fSReza Sabdar err = scf_error(); 3342654012fSReza Sabdar switch (err) { 3352654012fSReza Sabdar case SCF_ERROR_PERMISSION_DENIED: 3362654012fSReza Sabdar ndmp_errno = ENDMP_SMF_PERM; 3372654012fSReza Sabdar return (-1); 3382654012fSReza Sabdar default: 3392654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 3402654012fSReza Sabdar return (-1); 3412654012fSReza Sabdar } 3422654012fSReza Sabdar } 3432654012fSReza Sabdar } 3442654012fSReza Sabdar return (0); 3452654012fSReza Sabdar } 3462654012fSReza Sabdar 3472654012fSReza Sabdar /* 3482654012fSReza Sabdar * Start transaction on current pg in handle. The pg could be service or 3492654012fSReza Sabdar * instance level. Must be called after pg handle is obtained from create or 3502654012fSReza Sabdar * get. 3512654012fSReza Sabdar */ 3522654012fSReza Sabdar static int 3532654012fSReza Sabdar ndmp_smf_start_transaction(ndmp_scfhandle_t *handle) 3542654012fSReza Sabdar { 3552654012fSReza Sabdar /* 3562654012fSReza Sabdar * Lookup the property group and create it if it doesn't already 3572654012fSReza Sabdar * exist. 3582654012fSReza Sabdar */ 3592654012fSReza Sabdar if (handle->scf_state == NDMP_SCH_STATE_INIT) { 3602654012fSReza Sabdar if ((handle->scf_trans = 3612654012fSReza Sabdar scf_transaction_create(handle->scf_handle)) != NULL) { 3622654012fSReza Sabdar if (scf_transaction_start(handle->scf_trans, 3632654012fSReza Sabdar handle->scf_pg) != 0) { 3642654012fSReza Sabdar scf_transaction_destroy(handle->scf_trans); 3652654012fSReza Sabdar handle->scf_trans = NULL; 3662654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 3672654012fSReza Sabdar return (-1); 3682654012fSReza Sabdar } 3692654012fSReza Sabdar } else { 3702654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 3712654012fSReza Sabdar return (-1); 3722654012fSReza Sabdar } 3732654012fSReza Sabdar } 3742654012fSReza Sabdar if (scf_error() == SCF_ERROR_PERMISSION_DENIED) { 3752654012fSReza Sabdar ndmp_errno = ENDMP_SMF_PERM; 3762654012fSReza Sabdar return (-1); 3772654012fSReza Sabdar } 3782654012fSReza Sabdar 3792654012fSReza Sabdar return (0); 3802654012fSReza Sabdar } 3812654012fSReza Sabdar 3822654012fSReza Sabdar /* 3832654012fSReza Sabdar * Commit the changes that were added to the transaction in the handle. Do all 3842654012fSReza Sabdar * necessary cleanup. 3852654012fSReza Sabdar */ 3862654012fSReza Sabdar static int 387*f093add7SJan Kryl ndmp_smf_end_transaction(ndmp_scfhandle_t *handle, boolean_t commit) 3882654012fSReza Sabdar { 389*f093add7SJan Kryl int rc = 0; 390*f093add7SJan Kryl 391*f093add7SJan Kryl if (commit) { 3922654012fSReza Sabdar if (scf_transaction_commit(handle->scf_trans) < 0) { 3932654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 394*f093add7SJan Kryl rc = -1; 395*f093add7SJan Kryl } 3962654012fSReza Sabdar } 3972654012fSReza Sabdar 3982654012fSReza Sabdar scf_transaction_destroy_children(handle->scf_trans); 3992654012fSReza Sabdar scf_transaction_destroy(handle->scf_trans); 4002654012fSReza Sabdar handle->scf_trans = NULL; 4012654012fSReza Sabdar 402*f093add7SJan Kryl return (rc); 4032654012fSReza Sabdar } 4042654012fSReza Sabdar 4052654012fSReza Sabdar /* 4062654012fSReza Sabdar * Deletes property in current pg 4072654012fSReza Sabdar */ 4082654012fSReza Sabdar static int 4098b87c155SJan Kryl ndmp_smf_delete_property(ndmp_scfhandle_t *handle, const char *propname) 4102654012fSReza Sabdar { 4112654012fSReza Sabdar scf_transaction_entry_t *entry = NULL; 4122654012fSReza Sabdar 4132654012fSReza Sabdar /* 4142654012fSReza Sabdar * Properties must be set in transactions and don't take effect until 4152654012fSReza Sabdar * the transaction has been ended/committed. 4162654012fSReza Sabdar */ 4172654012fSReza Sabdar if ((entry = scf_entry_create(handle->scf_handle)) != NULL) { 4182654012fSReza Sabdar if (scf_transaction_property_delete(handle->scf_trans, entry, 4192654012fSReza Sabdar propname) != 0) { 4202654012fSReza Sabdar scf_entry_destroy(entry); 4212654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 4222654012fSReza Sabdar return (-1); 4232654012fSReza Sabdar } 4242654012fSReza Sabdar } else { 4252654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 4262654012fSReza Sabdar return (-1); 4272654012fSReza Sabdar } 4282654012fSReza Sabdar if ((scf_error()) == SCF_ERROR_PERMISSION_DENIED) { 4292654012fSReza Sabdar ndmp_errno = ENDMP_SMF_PERM; 4302654012fSReza Sabdar scf_entry_destroy(entry); 4312654012fSReza Sabdar return (-1); 4322654012fSReza Sabdar } 4332654012fSReza Sabdar 4342654012fSReza Sabdar return (0); 4352654012fSReza Sabdar } 4362654012fSReza Sabdar 4372654012fSReza Sabdar /* 4382654012fSReza Sabdar * Sets property in current pg 4392654012fSReza Sabdar */ 4402654012fSReza Sabdar static int 441*f093add7SJan Kryl ndmp_smf_set_property(ndmp_scfhandle_t *handle, const char *propname, 442*f093add7SJan Kryl const char *valstr) 4432654012fSReza Sabdar { 4442654012fSReza Sabdar int ret = 0; 4452654012fSReza Sabdar scf_value_t *value = NULL; 4462654012fSReza Sabdar scf_transaction_entry_t *entry = NULL; 447*f093add7SJan Kryl scf_property_t *prop = NULL; 4482654012fSReza Sabdar scf_type_t type; 4492654012fSReza Sabdar int64_t valint; 4502654012fSReza Sabdar uint8_t valbool; 4512654012fSReza Sabdar 4522654012fSReza Sabdar /* 4532654012fSReza Sabdar * Properties must be set in transactions and don't take effect until 4542654012fSReza Sabdar * the transaction has been ended/committed. 4552654012fSReza Sabdar */ 456*f093add7SJan Kryl if (((value = scf_value_create(handle->scf_handle)) == NULL) || 457*f093add7SJan Kryl ((entry = scf_entry_create(handle->scf_handle)) == NULL) || 458*f093add7SJan Kryl ((prop = scf_property_create(handle->scf_handle)) == NULL) || 459*f093add7SJan Kryl (scf_pg_get_property(handle->scf_pg, propname, prop) != 0) || 460*f093add7SJan Kryl (scf_property_get_value(prop, value) != 0)) { 461*f093add7SJan Kryl ret = -1; 462*f093add7SJan Kryl goto out; 463*f093add7SJan Kryl } 464*f093add7SJan Kryl 4652654012fSReza Sabdar type = scf_value_type(value); 466*f093add7SJan Kryl if ((scf_transaction_property_change(handle->scf_trans, entry, propname, 467*f093add7SJan Kryl type) != 0) && 468*f093add7SJan Kryl (scf_transaction_property_new(handle->scf_trans, entry, propname, 469*f093add7SJan Kryl type) != 0)) { 470*f093add7SJan Kryl ret = -1; 471*f093add7SJan Kryl goto out; 472*f093add7SJan Kryl } 473*f093add7SJan Kryl 4742654012fSReza Sabdar switch (type) { 4752654012fSReza Sabdar case SCF_TYPE_ASTRING: 476*f093add7SJan Kryl if ((scf_value_set_astring(value, valstr)) != SCF_SUCCESS) 4772654012fSReza Sabdar ret = -1; 4782654012fSReza Sabdar break; 4792654012fSReza Sabdar case SCF_TYPE_INTEGER: 4802654012fSReza Sabdar valint = strtoll(valstr, 0, 0); 481*f093add7SJan Kryl scf_value_set_integer(value, valint); 4822654012fSReza Sabdar break; 4832654012fSReza Sabdar case SCF_TYPE_BOOLEAN: 4842654012fSReza Sabdar if (strncmp(valstr, "yes", 3)) 4852654012fSReza Sabdar valbool = 0; 4862654012fSReza Sabdar else 4872654012fSReza Sabdar valbool = 1; 488*f093add7SJan Kryl scf_value_set_boolean(value, valbool); 4892654012fSReza Sabdar break; 4902654012fSReza Sabdar default: 4912654012fSReza Sabdar ret = -1; 4922654012fSReza Sabdar } 493*f093add7SJan Kryl if (scf_entry_add_value(entry, value) == 0) { 4942654012fSReza Sabdar /* The value is in the transaction */ 4952654012fSReza Sabdar value = NULL; 496*f093add7SJan Kryl } else { 497*f093add7SJan Kryl ret = -1; 4982654012fSReza Sabdar } 4992654012fSReza Sabdar /* The entry is in the transaction */ 5002654012fSReza Sabdar entry = NULL; 501*f093add7SJan Kryl 502*f093add7SJan Kryl out: 5032654012fSReza Sabdar if (ret == -1) { 5042654012fSReza Sabdar if ((scf_error() == SCF_ERROR_PERMISSION_DENIED)) 5052654012fSReza Sabdar ndmp_errno = ENDMP_SMF_PERM; 5062654012fSReza Sabdar else 5072654012fSReza Sabdar ndmp_errno = ENDMP_SMF_INTERNAL; 5082654012fSReza Sabdar } 509*f093add7SJan Kryl scf_property_destroy(prop); 5102654012fSReza Sabdar scf_value_destroy(value); 5112654012fSReza Sabdar scf_entry_destroy(entry); 5122654012fSReza Sabdar return (ret); 5132654012fSReza Sabdar } 5142654012fSReza Sabdar 5152654012fSReza Sabdar /* 5162654012fSReza Sabdar * Gets a property value.upto sz size. Caller is responsible to have enough 5172654012fSReza Sabdar * memory allocated. 5182654012fSReza Sabdar */ 5192654012fSReza Sabdar static int 5208b87c155SJan Kryl ndmp_smf_get_property(ndmp_scfhandle_t *handle, const char *propname, 5212654012fSReza Sabdar char *valstr, size_t sz) 5222654012fSReza Sabdar { 5232654012fSReza Sabdar int ret = 0; 524*f093add7SJan Kryl scf_value_t *value = NULL; 525*f093add7SJan Kryl scf_property_t *prop = NULL; 5262654012fSReza Sabdar scf_type_t type; 5272654012fSReza Sabdar int64_t valint; 5282654012fSReza Sabdar uint8_t valbool; 5292654012fSReza Sabdar char valstrbuf[NDMP_PROP_LEN]; 5302654012fSReza Sabdar 5312654012fSReza Sabdar if (((value = scf_value_create(handle->scf_handle)) != NULL) && 5322654012fSReza Sabdar ((prop = scf_property_create(handle->scf_handle)) != NULL) && 5332654012fSReza Sabdar (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 5342654012fSReza Sabdar if (scf_property_get_value(prop, value) == 0) { 5352654012fSReza Sabdar type = scf_value_type(value); 5362654012fSReza Sabdar switch (type) { 5372654012fSReza Sabdar case SCF_TYPE_ASTRING: 5382654012fSReza Sabdar if (scf_value_get_astring(value, valstr, 5392654012fSReza Sabdar sz) < 0) { 5402654012fSReza Sabdar ret = -1; 5412654012fSReza Sabdar } 5422654012fSReza Sabdar break; 5432654012fSReza Sabdar case SCF_TYPE_INTEGER: 5442654012fSReza Sabdar if (scf_value_get_integer(value, 5452654012fSReza Sabdar &valint) != 0) { 5462654012fSReza Sabdar ret = -1; 5472654012fSReza Sabdar break; 5482654012fSReza Sabdar } 5492654012fSReza Sabdar valstrbuf[NDMP_PROP_LEN - 1] = '\0'; 5502654012fSReza Sabdar (void) strncpy(valstr, lltostr(valint, 5512654012fSReza Sabdar &valstrbuf[NDMP_PROP_LEN - 1]), 5522654012fSReza Sabdar NDMP_PROP_LEN); 5532654012fSReza Sabdar break; 5542654012fSReza Sabdar case SCF_TYPE_BOOLEAN: 5552654012fSReza Sabdar if (scf_value_get_boolean(value, 5562654012fSReza Sabdar &valbool) != 0) { 5572654012fSReza Sabdar ret = -1; 5582654012fSReza Sabdar break; 5592654012fSReza Sabdar } 5602654012fSReza Sabdar if (valbool == 1) 5612654012fSReza Sabdar (void) strncpy(valstr, "yes", 4); 5622654012fSReza Sabdar else 5632654012fSReza Sabdar (void) strncpy(valstr, "no", 3); 5642654012fSReza Sabdar break; 5652654012fSReza Sabdar default: 5662654012fSReza Sabdar ret = -1; 5672654012fSReza Sabdar } 5682654012fSReza Sabdar } else { 5692654012fSReza Sabdar ret = -1; 5702654012fSReza Sabdar } 5712654012fSReza Sabdar } else { 5722654012fSReza Sabdar ret = -1; 5732654012fSReza Sabdar } 5742654012fSReza Sabdar scf_value_destroy(value); 5752654012fSReza Sabdar scf_property_destroy(prop); 5762654012fSReza Sabdar return (ret); 5772654012fSReza Sabdar } 578