2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use is subject to license terms.
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP configuration management
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* NDMP properties configuration */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define NPG (sizeof (ndmp_pg) / sizeof (ndmp_pg[0]))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Handle Init states */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* NDMP scf handle structure */
f093add7b63e274f746dd55365f052cded44cc16Jan Krylstatic int ndmp_config_saveenv(ndmp_scfhandle_t *, boolean_t);
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylstatic ndmp_scfhandle_t *ndmp_smf_scf_init(const char *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void ndmp_smf_scf_fini(ndmp_scfhandle_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int ndmp_smf_start_transaction(ndmp_scfhandle_t *);
f093add7b63e274f746dd55365f052cded44cc16Jan Krylstatic int ndmp_smf_end_transaction(ndmp_scfhandle_t *, boolean_t);
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylstatic int ndmp_smf_set_property(ndmp_scfhandle_t *, const char *,
8b87c15576a5138f88a969448b43561bf5968c09Jan Kryl const char *);
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylstatic int ndmp_smf_get_property(ndmp_scfhandle_t *, const char *, char *,
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylstatic int ndmp_smf_create_service_pgroup(ndmp_scfhandle_t *, const char *);
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylstatic int ndmp_smf_delete_property(ndmp_scfhandle_t *, const char *);
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylstatic int ndmp_smf_get_pg_name(ndmp_scfhandle_t *, const char *, char **);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This routine send a refresh signal to ndmpd service which cause ndmpd
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * property table to be refeshed with current ndmpd properties value from SMF.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns value of the specified variable/property. The return value is a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * string pointer to the locally allocated memory if the config param is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * defined otherwise it would be NULL.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((handle = ndmp_smf_scf_init(NDMP_GROUP_FMRI_PREFIX)) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_smf_get_pg_name(handle, prop, &pgname)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_smf_create_service_pgroup(handle, pgname)) {
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_smf_get_property(handle, prop, lval, NDMP_PROP_LEN) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((handle = ndmp_smf_scf_init(NDMP_GROUP_FMRI_PREFIX)) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_smf_get_pg_name(handle, env, &pgname)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl if (ndmp_smf_create_service_pgroup(handle, pgname)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl return (-1);
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylndmp_smf_get_pg_name(ndmp_scfhandle_t *h, const char *pname, char **pgname)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < NPG; i++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (scf_service_get_pg(h->scf_service, ndmp_pg[i],
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((value = scf_value_create(h->scf_handle)) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((prop = scf_property_create(h->scf_handle)) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This will fail if property does not exist in the property
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * group. Check the next property group in case of failure.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((scf_pg_get_property(h->scf_pg, pname, prop)) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Basically commit the transaction.
f093add7b63e274f746dd55365f052cded44cc16Jan Krylndmp_config_saveenv(ndmp_scfhandle_t *handle, boolean_t commit)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Must be called when done. Called with the handle allocated in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_smf_scf_init(), it cleans up the state and frees any SCF resources
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * still in use.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Must be called before using any of the SCF functions. Returns
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_scfhandle_t pointer if success.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar handle = (ndmp_scfhandle_t *)calloc(1, sizeof (ndmp_scfhandle_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar handle->scf_state = NDMP_SCH_STATE_INITIALIZING;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (scf_handle_get_local_scope(handle->scf_handle,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar scf_service_create(handle->scf_handle)) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (scf_scope_get_service(handle->scf_scope, svc_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Create a new property group at service level.
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylndmp_smf_create_service_pgroup(ndmp_scfhandle_t *handle, const char *pgroup)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Only create a handle if it doesn't exist. It is ok to exist since
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the pg handle will be set as a side effect.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the pgroup exists, we are done. If it doesn't, then we need to
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * actually add one to the service instance.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Doesn't exist so create one */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (scf_service_add_pg(handle->scf_service, pgroup,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Start transaction on current pg in handle. The pg could be service or
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * instance level. Must be called after pg handle is obtained from create or
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_smf_start_transaction(ndmp_scfhandle_t *handle)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Lookup the property group and create it if it doesn't already
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar scf_transaction_create(handle->scf_handle)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (scf_error() == SCF_ERROR_PERMISSION_DENIED) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Commit the changes that were added to the transaction in the handle. Do all
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * necessary cleanup.
f093add7b63e274f746dd55365f052cded44cc16Jan Krylndmp_smf_end_transaction(ndmp_scfhandle_t *handle, boolean_t commit)
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl if (scf_transaction_commit(handle->scf_trans) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar scf_transaction_destroy_children(handle->scf_trans);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Deletes property in current pg
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylndmp_smf_delete_property(ndmp_scfhandle_t *handle, const char *propname)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Properties must be set in transactions and don't take effect until
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the transaction has been ended/committed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((entry = scf_entry_create(handle->scf_handle)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (scf_transaction_property_delete(handle->scf_trans, entry,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((scf_error()) == SCF_ERROR_PERMISSION_DENIED) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Sets property in current pg
f093add7b63e274f746dd55365f052cded44cc16Jan Krylndmp_smf_set_property(ndmp_scfhandle_t *handle, const char *propname,
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl const char *valstr)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Properties must be set in transactions and don't take effect until
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the transaction has been ended/committed.
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl if (((value = scf_value_create(handle->scf_handle)) == NULL) ||
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl ((entry = scf_entry_create(handle->scf_handle)) == NULL) ||
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl ((prop = scf_property_create(handle->scf_handle)) == NULL) ||
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl (scf_pg_get_property(handle->scf_pg, propname, prop) != 0) ||
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl if ((scf_transaction_property_change(handle->scf_trans, entry, propname,
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl (scf_transaction_property_new(handle->scf_trans, entry, propname,
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl if ((scf_value_set_astring(value, valstr)) != SCF_SUCCESS)
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl /* The value is in the transaction */
f093add7b63e274f746dd55365f052cded44cc16Jan Kryl /* The entry is in the transaction */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((scf_error() == SCF_ERROR_PERMISSION_DENIED))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Gets a property value.upto sz size. Caller is responsible to have enough
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * memory allocated.
8b87c15576a5138f88a969448b43561bf5968c09Jan Krylndmp_smf_get_property(ndmp_scfhandle_t *handle, const char *propname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (((value = scf_value_create(handle->scf_handle)) != NULL) &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((prop = scf_property_create(handle->scf_handle)) != NULL) &&