xref: /titanic_41/usr/src/cmd/cmd-inet/lib/nwamd/enm.c (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey  * CDDL HEADER START
36ba597c5SAnurag S. Maskey  *
46ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey  *
86ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey  * and limitations under the License.
126ba597c5SAnurag S. Maskey  *
136ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey  *
196ba597c5SAnurag S. Maskey  * CDDL HEADER END
206ba597c5SAnurag S. Maskey  */
216ba597c5SAnurag S. Maskey 
226ba597c5SAnurag S. Maskey /*
23f6da83d4SAnurag S. Maskey  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
246ba597c5SAnurag S. Maskey  */
256ba597c5SAnurag S. Maskey 
266ba597c5SAnurag S. Maskey #include <arpa/inet.h>
276ba597c5SAnurag S. Maskey #include <errno.h>
286ba597c5SAnurag S. Maskey #include <inet/ip.h>
296ba597c5SAnurag S. Maskey #include <libdladm.h>
306ba597c5SAnurag S. Maskey #include <libdllink.h>
316ba597c5SAnurag S. Maskey #include <libdlwlan.h>
326ba597c5SAnurag S. Maskey #include <libscf.h>
336ba597c5SAnurag S. Maskey #include <netinet/in.h>
346ba597c5SAnurag S. Maskey #include <netdb.h>
356ba597c5SAnurag S. Maskey #include <stdio.h>
366ba597c5SAnurag S. Maskey #include <stdlib.h>
376ba597c5SAnurag S. Maskey #include <string.h>
386ba597c5SAnurag S. Maskey #include <sys/socket.h>
396ba597c5SAnurag S. Maskey #include <sys/types.h>
406ba597c5SAnurag S. Maskey 
416ba597c5SAnurag S. Maskey #include <libnwam.h>
426ba597c5SAnurag S. Maskey #include "conditions.h"
436ba597c5SAnurag S. Maskey #include "events.h"
446ba597c5SAnurag S. Maskey #include "objects.h"
456ba597c5SAnurag S. Maskey #include "util.h"
466ba597c5SAnurag S. Maskey 
476ba597c5SAnurag S. Maskey /*
486ba597c5SAnurag S. Maskey  * enm.c - contains routines which handle ENM (external network modifier)
496ba597c5SAnurag S. Maskey  * abstraction.  ENMs represent scripts or services that can be activated either
506ba597c5SAnurag S. Maskey  * manually or in response to network conditions.
516ba597c5SAnurag S. Maskey  */
526ba597c5SAnurag S. Maskey 
536ba597c5SAnurag S. Maskey #define	CTRUN	"/usr/bin/ctrun"
546ba597c5SAnurag S. Maskey 
556ba597c5SAnurag S. Maskey static int
enm_create_init_fini_event(nwam_enm_handle_t enmh,void * data)566ba597c5SAnurag S. Maskey enm_create_init_fini_event(nwam_enm_handle_t enmh, void *data)
576ba597c5SAnurag S. Maskey {
586ba597c5SAnurag S. Maskey 	boolean_t *init = data;
596ba597c5SAnurag S. Maskey 	char *name;
606ba597c5SAnurag S. Maskey 	nwamd_event_t enm_event;
616ba597c5SAnurag S. Maskey 
626ba597c5SAnurag S. Maskey 	if (nwam_enm_get_name(enmh, &name) != NWAM_SUCCESS) {
63*f6904bc3SRenee Danson Sommerfeld 		nlog(LOG_ERR, "enm_init_fini: could not get enm name");
646ba597c5SAnurag S. Maskey 		return (0);
656ba597c5SAnurag S. Maskey 	}
666ba597c5SAnurag S. Maskey 
676ba597c5SAnurag S. Maskey 	enm_event = nwamd_event_init(*init ?
686ba597c5SAnurag S. Maskey 	    NWAM_EVENT_TYPE_OBJECT_INIT : NWAM_EVENT_TYPE_OBJECT_FINI,
696ba597c5SAnurag S. Maskey 	    NWAM_OBJECT_TYPE_ENM, 0, name);
706ba597c5SAnurag S. Maskey 	if (enm_event != NULL)
716ba597c5SAnurag S. Maskey 		nwamd_event_enqueue(enm_event);
726ba597c5SAnurag S. Maskey 	free(name);
736ba597c5SAnurag S. Maskey 
746ba597c5SAnurag S. Maskey 	return (0);
756ba597c5SAnurag S. Maskey }
766ba597c5SAnurag S. Maskey 
776ba597c5SAnurag S. Maskey /*
786ba597c5SAnurag S. Maskey  * Walk all ENMs, creating init events for each.
796ba597c5SAnurag S. Maskey  */
806ba597c5SAnurag S. Maskey void
nwamd_init_enms(void)816ba597c5SAnurag S. Maskey nwamd_init_enms(void)
826ba597c5SAnurag S. Maskey {
836ba597c5SAnurag S. Maskey 	boolean_t init = B_TRUE;
846ba597c5SAnurag S. Maskey 
856ba597c5SAnurag S. Maskey 	(void) nwam_walk_enms(enm_create_init_fini_event, &init, 0, NULL);
866ba597c5SAnurag S. Maskey }
876ba597c5SAnurag S. Maskey 
886ba597c5SAnurag S. Maskey /*
896ba597c5SAnurag S. Maskey  * Walk all ENMs, creating fini events for each.
906ba597c5SAnurag S. Maskey  */
916ba597c5SAnurag S. Maskey void
nwamd_fini_enms(void)926ba597c5SAnurag S. Maskey nwamd_fini_enms(void)
936ba597c5SAnurag S. Maskey {
946ba597c5SAnurag S. Maskey 	boolean_t init = B_FALSE;
956ba597c5SAnurag S. Maskey 
966ba597c5SAnurag S. Maskey 	(void) nwam_walk_enms(enm_create_init_fini_event, &init, 0, NULL);
976ba597c5SAnurag S. Maskey }
986ba597c5SAnurag S. Maskey 
996ba597c5SAnurag S. Maskey static boolean_t
enm_is_enabled(nwam_enm_handle_t enmh)1006ba597c5SAnurag S. Maskey enm_is_enabled(nwam_enm_handle_t enmh)
1016ba597c5SAnurag S. Maskey {
1026ba597c5SAnurag S. Maskey 	nwam_value_t enabledval;
1036ba597c5SAnurag S. Maskey 	boolean_t enabled = B_FALSE;
1046ba597c5SAnurag S. Maskey 
1056ba597c5SAnurag S. Maskey 	if (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ENABLED,
1066ba597c5SAnurag S. Maskey 	    &enabledval) != NWAM_SUCCESS) {
1076ba597c5SAnurag S. Maskey 		/* It's legal for a conditional ENM to not specify "enabled" */
1086ba597c5SAnurag S. Maskey 		return (B_FALSE);
1096ba597c5SAnurag S. Maskey 	}
1106ba597c5SAnurag S. Maskey 	if (nwam_value_get_boolean(enabledval, &enabled) != NWAM_SUCCESS) {
1116ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "enm_is_enabled: could not retrieve "
1126ba597c5SAnurag S. Maskey 		    "enabled value");
1136ba597c5SAnurag S. Maskey 	}
1146ba597c5SAnurag S. Maskey 	nwam_value_free(enabledval);
1156ba597c5SAnurag S. Maskey 	return (enabled);
1166ba597c5SAnurag S. Maskey }
1176ba597c5SAnurag S. Maskey 
1186ba597c5SAnurag S. Maskey static int64_t
enm_get_activation_mode(nwam_enm_handle_t enmh)1196ba597c5SAnurag S. Maskey enm_get_activation_mode(nwam_enm_handle_t enmh)
1206ba597c5SAnurag S. Maskey {
1216ba597c5SAnurag S. Maskey 	uint64_t activation;
1226ba597c5SAnurag S. Maskey 	int64_t ret;
1236ba597c5SAnurag S. Maskey 	nwam_value_t activationval;
1246ba597c5SAnurag S. Maskey 
1256ba597c5SAnurag S. Maskey 	if (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ACTIVATION_MODE,
1266ba597c5SAnurag S. Maskey 	    &activationval)  != NWAM_SUCCESS) {
1276ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "enm_get_activation_mode: could not retrieve "
1286ba597c5SAnurag S. Maskey 		    "activation mode value");
1296ba597c5SAnurag S. Maskey 		return (-1);
1306ba597c5SAnurag S. Maskey 	}
1316ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(activationval, &activation) != NWAM_SUCCESS) {
1326ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "enm_get_activation_mode: could not retrieve "
1336ba597c5SAnurag S. Maskey 		    "activation mode value");
1346ba597c5SAnurag S. Maskey 		ret = -1;
1356ba597c5SAnurag S. Maskey 	} else {
1366ba597c5SAnurag S. Maskey 		ret = activation;
1376ba597c5SAnurag S. Maskey 	}
1386ba597c5SAnurag S. Maskey 	nwam_value_free(activationval);
1396ba597c5SAnurag S. Maskey 
1406ba597c5SAnurag S. Maskey 	return (ret);
1416ba597c5SAnurag S. Maskey }
1426ba597c5SAnurag S. Maskey 
1436ba597c5SAnurag S. Maskey static void *
nwamd_enm_activate_deactivate_thread(void * arg)1446ba597c5SAnurag S. Maskey nwamd_enm_activate_deactivate_thread(void *arg)
1456ba597c5SAnurag S. Maskey {
1466ba597c5SAnurag S. Maskey 	char *object_name = arg;
1476ba597c5SAnurag S. Maskey 	nwamd_object_t object;
1486ba597c5SAnurag S. Maskey 	nwam_enm_handle_t enmh;
1496ba597c5SAnurag S. Maskey 	nwam_value_t scriptval = NULL;
1506ba597c5SAnurag S. Maskey 	nwam_state_t state;
1516ba597c5SAnurag S. Maskey 	nwam_aux_state_t aux_state;
152874067a0SAnurag S. Maskey 	char *script, *copy = NULL;
153874067a0SAnurag S. Maskey 	const char **argv = NULL;
1546ba597c5SAnurag S. Maskey 	boolean_t going_online, disable_succeeded = B_FALSE;
1556ba597c5SAnurag S. Maskey 	int ret;
1566ba597c5SAnurag S. Maskey 
1576ba597c5SAnurag S. Maskey 	object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM, object_name);
1586ba597c5SAnurag S. Maskey 	if (object == NULL) {
1596ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_enm_activate_deactivate_thread: "
160*f6904bc3SRenee Danson Sommerfeld 		    "could not find enm %s", object_name);
161874067a0SAnurag S. Maskey 		goto done;
1626ba597c5SAnurag S. Maskey 	}
1636ba597c5SAnurag S. Maskey 	enmh = object->nwamd_object_handle;
1646ba597c5SAnurag S. Maskey 
1656ba597c5SAnurag S. Maskey 	going_online =
1666ba597c5SAnurag S. Maskey 	    (object->nwamd_object_state == NWAM_STATE_OFFLINE_TO_ONLINE);
1676ba597c5SAnurag S. Maskey 	/*
1686ba597c5SAnurag S. Maskey 	 * We're starting if current state is offline* and stopping otherwise.
1696ba597c5SAnurag S. Maskey 	 */
1706ba597c5SAnurag S. Maskey 	if (nwam_enm_get_prop_value(enmh,
1716ba597c5SAnurag S. Maskey 	    going_online ? NWAM_ENM_PROP_START : NWAM_ENM_PROP_STOP,
1726ba597c5SAnurag S. Maskey 	    &scriptval) != NWAM_SUCCESS ||
1736ba597c5SAnurag S. Maskey 	    nwam_value_get_string(scriptval, &script) != NWAM_SUCCESS) {
1746ba597c5SAnurag S. Maskey 		/*
1756ba597c5SAnurag S. Maskey 		 * If we're stopping, it's not an error for no script to
1766ba597c5SAnurag S. Maskey 		 * be specified.
1776ba597c5SAnurag S. Maskey 		 */
1786ba597c5SAnurag S. Maskey 		nlog(going_online ? LOG_ERR : LOG_DEBUG,
1796ba597c5SAnurag S. Maskey 		    "nwamd_enm_activate_deactivate_thread: "
180874067a0SAnurag S. Maskey 		    "no script specified for enm %s", object_name);
1816ba597c5SAnurag S. Maskey 		if (going_online) {
1826ba597c5SAnurag S. Maskey 			state = NWAM_STATE_MAINTENANCE;
1836ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_METHOD_MISSING;
1846ba597c5SAnurag S. Maskey 		} else {
1856ba597c5SAnurag S. Maskey 			disable_succeeded = B_TRUE;
1866ba597c5SAnurag S. Maskey 		}
1876ba597c5SAnurag S. Maskey 	} else {
188874067a0SAnurag S. Maskey 		char *lasts;
189874067a0SAnurag S. Maskey 		const char **newargv;
1906ba597c5SAnurag S. Maskey 		int i = 0;
191874067a0SAnurag S. Maskey 		struct timeval now;
1926ba597c5SAnurag S. Maskey 
1936ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_enm_activate_deactivate_thread: "
194*f6904bc3SRenee Danson Sommerfeld 		    "running script %s for enm %s", script, object_name);
1956ba597c5SAnurag S. Maskey 
1966ba597c5SAnurag S. Maskey 		/*
1976ba597c5SAnurag S. Maskey 		 * The script may take a number of arguments. We need to
1986ba597c5SAnurag S. Maskey 		 * create a string array consisting of the wrapper command
1996ba597c5SAnurag S. Maskey 		 * (ctrun), ENM script name, arguments and NULL array
2006ba597c5SAnurag S. Maskey 		 * terminator.  Start with an array of size equal to the
2016ba597c5SAnurag S. Maskey 		 * string length (since the number of arguments will always
2026ba597c5SAnurag S. Maskey 		 * be less than this) and shrink array to the actual number
2036ba597c5SAnurag S. Maskey 		 * of arguments when we have parsed the string.
2046ba597c5SAnurag S. Maskey 		 */
2056ba597c5SAnurag S. Maskey 		if ((copy = strdup(script)) == NULL ||
2066ba597c5SAnurag S. Maskey 		    (argv = calloc(strlen(script), sizeof (char *))) == NULL) {
2076ba597c5SAnurag S. Maskey 			ret = 1;
2086ba597c5SAnurag S. Maskey 			goto err;
2096ba597c5SAnurag S. Maskey 		}
2106ba597c5SAnurag S. Maskey 		argv[i++] = CTRUN;
2116ba597c5SAnurag S. Maskey 		argv[i++] = strtok_r(copy, " ", &lasts);
2126ba597c5SAnurag S. Maskey 		if (argv[1] == NULL) {
2136ba597c5SAnurag S. Maskey 			ret = 1;
2146ba597c5SAnurag S. Maskey 			goto err;
2156ba597c5SAnurag S. Maskey 		}
2166ba597c5SAnurag S. Maskey 
2176ba597c5SAnurag S. Maskey 		for (; (argv[i] = strtok_r(NULL, " ", &lasts)) != NULL; i++) {}
2186ba597c5SAnurag S. Maskey 
2196ba597c5SAnurag S. Maskey 		newargv = realloc(argv, (i + 1) * sizeof (char *));
2206ba597c5SAnurag S. Maskey 		argv = newargv;
2216ba597c5SAnurag S. Maskey 
222874067a0SAnurag S. Maskey 		/* Store the current time as the time the script began */
223874067a0SAnurag S. Maskey 		(void) gettimeofday(&now, NULL);
224874067a0SAnurag S. Maskey 		object->nwamd_script_time = now;
225874067a0SAnurag S. Maskey 
226874067a0SAnurag S. Maskey 		/*
227874067a0SAnurag S. Maskey 		 * Release the object so that it is not blocked while the
228874067a0SAnurag S. Maskey 		 * script is running.
229874067a0SAnurag S. Maskey 		 */
230874067a0SAnurag S. Maskey 		nwamd_object_release(object);
231874067a0SAnurag S. Maskey 
2326ba597c5SAnurag S. Maskey 		ret = nwamd_start_childv(CTRUN, argv);
2336ba597c5SAnurag S. Maskey 
234874067a0SAnurag S. Maskey 		/*
235874067a0SAnurag S. Maskey 		 * Find the object again, now that the script has finished
236874067a0SAnurag S. Maskey 		 * running.  Check if this ENM was re-read during that time by
237874067a0SAnurag S. Maskey 		 * comparing the object's script time with the one from above.
238874067a0SAnurag S. Maskey 		 */
239874067a0SAnurag S. Maskey 		object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM, object_name);
240874067a0SAnurag S. Maskey 		if (object == NULL) {
241874067a0SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_activate_deactivate_thread: "
242*f6904bc3SRenee Danson Sommerfeld 			    "could not find enm %s after running script",
243874067a0SAnurag S. Maskey 			    object_name);
244874067a0SAnurag S. Maskey 			goto done;
245874067a0SAnurag S. Maskey 		}
246874067a0SAnurag S. Maskey 
247874067a0SAnurag S. Maskey 		if (object->nwamd_script_time.tv_sec != now.tv_sec ||
248874067a0SAnurag S. Maskey 		    object->nwamd_script_time.tv_usec != now.tv_usec) {
249874067a0SAnurag S. Maskey 			nlog(LOG_INFO, "nwamd_enm_activate_deactivate_thread: "
250*f6904bc3SRenee Danson Sommerfeld 			    "enm %s has been refreshed, nothing to do",
251874067a0SAnurag S. Maskey 			    object_name);
252874067a0SAnurag S. Maskey 			nwamd_object_release(object);
253874067a0SAnurag S. Maskey 			goto done;
254874067a0SAnurag S. Maskey 		}
255874067a0SAnurag S. Maskey 		(void) gettimeofday(&object->nwamd_script_time, NULL);
256874067a0SAnurag S. Maskey 
2576ba597c5SAnurag S. Maskey err:
2586ba597c5SAnurag S. Maskey 		/*
2596ba597c5SAnurag S. Maskey 		 * If script execution fails and we're not destroying the
2606ba597c5SAnurag S. Maskey 		 * object, go to maintenance.
2616ba597c5SAnurag S. Maskey 		 */
2626ba597c5SAnurag S. Maskey 		if (ret != 0) {
2636ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_activate_deactivate_thread: "
264*f6904bc3SRenee Danson Sommerfeld 			    "execution of '%s' failed for enm %s",
265874067a0SAnurag S. Maskey 			    script, object_name);
2666ba597c5SAnurag S. Maskey 			if (object->nwamd_object_aux_state !=
2676ba597c5SAnurag S. Maskey 			    NWAM_AUX_STATE_UNINITIALIZED) {
2686ba597c5SAnurag S. Maskey 				state = NWAM_STATE_MAINTENANCE;
2696ba597c5SAnurag S. Maskey 				aux_state = NWAM_AUX_STATE_METHOD_FAILED;
2706ba597c5SAnurag S. Maskey 			} else {
2716ba597c5SAnurag S. Maskey 				state = NWAM_STATE_UNINITIALIZED;
2726ba597c5SAnurag S. Maskey 				aux_state = NWAM_AUX_STATE_UNINITIALIZED;
2736ba597c5SAnurag S. Maskey 			}
2746ba597c5SAnurag S. Maskey 		} else {
2756ba597c5SAnurag S. Maskey 			if (going_online) {
2766ba597c5SAnurag S. Maskey 				state = NWAM_STATE_ONLINE;
2776ba597c5SAnurag S. Maskey 				aux_state = NWAM_AUX_STATE_ACTIVE;
2786ba597c5SAnurag S. Maskey 			} else {
2796ba597c5SAnurag S. Maskey 				disable_succeeded = B_TRUE;
2806ba597c5SAnurag S. Maskey 			}
2816ba597c5SAnurag S. Maskey 		}
2826ba597c5SAnurag S. Maskey 	}
2836ba597c5SAnurag S. Maskey 
2846ba597c5SAnurag S. Maskey 	if (disable_succeeded) {
2856ba597c5SAnurag S. Maskey 		/*
2866ba597c5SAnurag S. Maskey 		 * If aux state is "manual disable", we know
2876ba597c5SAnurag S. Maskey 		 * this was a disable request, otherwise it was
2886ba597c5SAnurag S. Maskey 		 * _fini request or a condition satisfaction
2896ba597c5SAnurag S. Maskey 		 * failure.
2906ba597c5SAnurag S. Maskey 		 */
2916ba597c5SAnurag S. Maskey 		switch (object->nwamd_object_aux_state) {
2926ba597c5SAnurag S. Maskey 		case NWAM_AUX_STATE_MANUAL_DISABLE:
2936ba597c5SAnurag S. Maskey 			state = NWAM_STATE_DISABLED;
2946ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_MANUAL_DISABLE;
2956ba597c5SAnurag S. Maskey 			break;
2966ba597c5SAnurag S. Maskey 		case NWAM_AUX_STATE_UNINITIALIZED:
2976ba597c5SAnurag S. Maskey 			state = NWAM_STATE_UNINITIALIZED;
2986ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_UNINITIALIZED;
2996ba597c5SAnurag S. Maskey 			break;
3006ba597c5SAnurag S. Maskey 		default:
3016ba597c5SAnurag S. Maskey 			state = NWAM_STATE_OFFLINE;
3026ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_CONDITIONS_NOT_MET;
3036ba597c5SAnurag S. Maskey 			break;
3046ba597c5SAnurag S. Maskey 		}
3056ba597c5SAnurag S. Maskey 	}
3066ba597c5SAnurag S. Maskey 
3076ba597c5SAnurag S. Maskey 	/* If state/aux state are uninitialized/unintialized, destroy the ENM */
3086ba597c5SAnurag S. Maskey 	if (state == NWAM_STATE_UNINITIALIZED &&
3096ba597c5SAnurag S. Maskey 	    aux_state == NWAM_AUX_STATE_UNINITIALIZED) {
3106ba597c5SAnurag S. Maskey 		object->nwamd_object_state = state;
3116ba597c5SAnurag S. Maskey 		object->nwamd_object_aux_state = aux_state;
3126ba597c5SAnurag S. Maskey 		(void) nwamd_object_release_and_destroy_after_preserve(object);
3136ba597c5SAnurag S. Maskey 	} else {
3146ba597c5SAnurag S. Maskey 		nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
3156ba597c5SAnurag S. Maskey 		    object->nwamd_object_name, state, aux_state);
3166ba597c5SAnurag S. Maskey 		(void) nwamd_object_release_after_preserve(object);
3176ba597c5SAnurag S. Maskey 	}
3186ba597c5SAnurag S. Maskey 
319874067a0SAnurag S. Maskey done:
320874067a0SAnurag S. Maskey 	/* object_name was malloc() before this thread was created, free() it */
321874067a0SAnurag S. Maskey 	free(object_name);
322874067a0SAnurag S. Maskey 	free(argv);
323874067a0SAnurag S. Maskey 	free(copy);
324874067a0SAnurag S. Maskey 	nwam_value_free(scriptval);
3256ba597c5SAnurag S. Maskey 	return (NULL);
3266ba597c5SAnurag S. Maskey }
3276ba597c5SAnurag S. Maskey 
3286ba597c5SAnurag S. Maskey /*
3296ba597c5SAnurag S. Maskey  * Run start/stop method for ENM in a separate thread.  The object lock is not
3306ba597c5SAnurag S. Maskey  * held across threads, so we duplicate the object name for the method
3316ba597c5SAnurag S. Maskey  * execution thread.  Returns true if thread is successfully launched.
3326ba597c5SAnurag S. Maskey  */
3336ba597c5SAnurag S. Maskey boolean_t
nwamd_enm_run_method(nwamd_object_t object)3346ba597c5SAnurag S. Maskey nwamd_enm_run_method(nwamd_object_t object)
3356ba597c5SAnurag S. Maskey {
3366ba597c5SAnurag S. Maskey 	char *name;
3376ba597c5SAnurag S. Maskey 	pthread_t script;
3386ba597c5SAnurag S. Maskey 
3396ba597c5SAnurag S. Maskey 	/*
3406ba597c5SAnurag S. Maskey 	 * Launch separate thread to wait for execution of script
3416ba597c5SAnurag S. Maskey 	 * to complete.  Do not hold object lock across threads.
3426ba597c5SAnurag S. Maskey 	 */
3436ba597c5SAnurag S. Maskey 	if ((name = strdup(object->nwamd_object_name)) == NULL) {
3446ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_enm_run_method: %s: out of memory",
3456ba597c5SAnurag S. Maskey 		    object->nwamd_object_name);
3466ba597c5SAnurag S. Maskey 		return (B_FALSE);
3476ba597c5SAnurag S. Maskey 	}
3486ba597c5SAnurag S. Maskey 
3496ba597c5SAnurag S. Maskey 	if (pthread_create(&script, NULL,
3506ba597c5SAnurag S. Maskey 	    nwamd_enm_activate_deactivate_thread, name) != 0) {
3516ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_enm_run_method: could not create "
3526ba597c5SAnurag S. Maskey 		    "enm script thread for %s", name);
3536ba597c5SAnurag S. Maskey 		free(name);
3546ba597c5SAnurag S. Maskey 		return (B_FALSE);
3556ba597c5SAnurag S. Maskey 	}
3566ba597c5SAnurag S. Maskey 	/* "name" will be freed by the newly-created thread. */
3576ba597c5SAnurag S. Maskey 
3586ba597c5SAnurag S. Maskey 	/* detach thread so that it doesn't become a zombie */
3596ba597c5SAnurag S. Maskey 	(void) pthread_detach(script);
3606ba597c5SAnurag S. Maskey 
3616ba597c5SAnurag S. Maskey 	return (B_TRUE);
3626ba597c5SAnurag S. Maskey }
3636ba597c5SAnurag S. Maskey 
3646ba597c5SAnurag S. Maskey /*
3656ba597c5SAnurag S. Maskey  * Activate the ENM, either in response to an enable event or conditions
3666ba597c5SAnurag S. Maskey  * being satisfied.
3676ba597c5SAnurag S. Maskey  */
3686ba597c5SAnurag S. Maskey static void
nwamd_enm_activate(const char * object_name)3696ba597c5SAnurag S. Maskey nwamd_enm_activate(const char *object_name)
3706ba597c5SAnurag S. Maskey {
3716ba597c5SAnurag S. Maskey 	nwamd_object_t object;
3726ba597c5SAnurag S. Maskey 	nwam_value_t fmrival;
3736ba597c5SAnurag S. Maskey 	char *fmri, *smf_state;
3746ba597c5SAnurag S. Maskey 	int ret;
3756ba597c5SAnurag S. Maskey 	nwam_enm_handle_t enmh;
3766ba597c5SAnurag S. Maskey 	nwam_state_t state;
3776ba597c5SAnurag S. Maskey 	nwam_aux_state_t aux_state;
3786ba597c5SAnurag S. Maskey 	nwam_error_t err;
3796ba597c5SAnurag S. Maskey 	boolean_t ran_method = B_FALSE;
3806ba597c5SAnurag S. Maskey 
3816ba597c5SAnurag S. Maskey 	object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM, object_name);
3826ba597c5SAnurag S. Maskey 	if (object == NULL) {
383*f6904bc3SRenee Danson Sommerfeld 		nlog(LOG_ERR, "nwamd_enm_activate: could not find enm %s",
3846ba597c5SAnurag S. Maskey 		    object_name);
3856ba597c5SAnurag S. Maskey 		return;
3866ba597c5SAnurag S. Maskey 	}
3876ba597c5SAnurag S. Maskey 	state = object->nwamd_object_state;
3886ba597c5SAnurag S. Maskey 	aux_state = object->nwamd_object_aux_state;
3896ba597c5SAnurag S. Maskey 	enmh = object->nwamd_object_handle;
3906ba597c5SAnurag S. Maskey 
391*f6904bc3SRenee Danson Sommerfeld 	nlog(LOG_DEBUG, "nwamd_enm_activate: activating enm %s",
3926ba597c5SAnurag S. Maskey 	    object->nwamd_object_name);
3936ba597c5SAnurag S. Maskey 
3946ba597c5SAnurag S. Maskey 	err = nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_FMRI, &fmrival);
3956ba597c5SAnurag S. Maskey 	switch (err) {
3966ba597c5SAnurag S. Maskey 	case NWAM_SUCCESS:
3976ba597c5SAnurag S. Maskey 
3986ba597c5SAnurag S. Maskey 		if (nwam_value_get_string(fmrival, &fmri) != NWAM_SUCCESS) {
3996ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_activate: could not retrieve "
400*f6904bc3SRenee Danson Sommerfeld 			    "fmri string for enm %s",
4016ba597c5SAnurag S. Maskey 			    object->nwamd_object_name);
4026ba597c5SAnurag S. Maskey 			nwam_value_free(fmrival);
4036ba597c5SAnurag S. Maskey 			state = NWAM_STATE_MAINTENANCE;
4046ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_INVALID_CONFIG;
4056ba597c5SAnurag S. Maskey 			break;
4066ba597c5SAnurag S. Maskey 		}
4076ba597c5SAnurag S. Maskey 
4086ba597c5SAnurag S. Maskey 		if ((smf_state = smf_get_state(fmri)) == NULL) {
409*f6904bc3SRenee Danson Sommerfeld 			nlog(LOG_ERR, "nwamd_enm_activate: invalid fmri %s "
410*f6904bc3SRenee Danson Sommerfeld 			    "for enm %s", fmri, object->nwamd_object_name);
4116ba597c5SAnurag S. Maskey 			nwam_value_free(fmrival);
4126ba597c5SAnurag S. Maskey 			state = NWAM_STATE_MAINTENANCE;
4136ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_INVALID_CONFIG;
4146ba597c5SAnurag S. Maskey 			break;
4156ba597c5SAnurag S. Maskey 		}
4166ba597c5SAnurag S. Maskey 
417*f6904bc3SRenee Danson Sommerfeld 		nlog(LOG_DEBUG, "nwamd_enm_activate: activating %s for enm %s",
4186ba597c5SAnurag S. Maskey 		    fmri, object->nwamd_object_name);
4196ba597c5SAnurag S. Maskey 
4206ba597c5SAnurag S. Maskey 		if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
4216ba597c5SAnurag S. Maskey 			ret = smf_restart_instance(fmri);
4226ba597c5SAnurag S. Maskey 		else if (strcmp(smf_state, SCF_STATE_STRING_OFFLINE) == 0)
4236ba597c5SAnurag S. Maskey 			ret = smf_restart_instance(fmri);
4246ba597c5SAnurag S. Maskey 		else if (strcmp(smf_state, SCF_STATE_STRING_DISABLED) == 0)
4256ba597c5SAnurag S. Maskey 			ret = smf_enable_instance(fmri, SMF_TEMPORARY);
4266ba597c5SAnurag S. Maskey 		else
4276ba597c5SAnurag S. Maskey 			ret = smf_restore_instance(fmri);
4286ba597c5SAnurag S. Maskey 
4296ba597c5SAnurag S. Maskey 		if (ret == 0) {
4306ba597c5SAnurag S. Maskey 			state = NWAM_STATE_ONLINE;
4316ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_ACTIVE;
4326ba597c5SAnurag S. Maskey 		} else {
4336ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_activate: failed to enable "
434*f6904bc3SRenee Danson Sommerfeld 			    "fmri %s for enm %s", fmri,
4356ba597c5SAnurag S. Maskey 			    object->nwamd_object_name);
4366ba597c5SAnurag S. Maskey 			state = NWAM_STATE_MAINTENANCE;
4376ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_METHOD_FAILED;
4386ba597c5SAnurag S. Maskey 		}
4396ba597c5SAnurag S. Maskey 		free(smf_state);
4406ba597c5SAnurag S. Maskey 		nwam_value_free(fmrival);
4416ba597c5SAnurag S. Maskey 		break;
4426ba597c5SAnurag S. Maskey 	default:
4436ba597c5SAnurag S. Maskey 		/*
4446ba597c5SAnurag S. Maskey 		 * Must be a method-based ENM with start (and stop) script(s).
4456ba597c5SAnurag S. Maskey 		 */
4466ba597c5SAnurag S. Maskey 		if (!nwamd_enm_run_method(object)) {
4476ba597c5SAnurag S. Maskey 			/* Could not launch method execution thread */
4486ba597c5SAnurag S. Maskey 			state = NWAM_STATE_MAINTENANCE;
4496ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_METHOD_FAILED;
4506ba597c5SAnurag S. Maskey 		} else {
4516ba597c5SAnurag S. Maskey 			ran_method = B_TRUE;
4526ba597c5SAnurag S. Maskey 		}
4536ba597c5SAnurag S. Maskey 		break;
4546ba597c5SAnurag S. Maskey 	}
4556ba597c5SAnurag S. Maskey 
4566ba597c5SAnurag S. Maskey 	if (state != object->nwamd_object_state ||
4576ba597c5SAnurag S. Maskey 	    aux_state != object->nwamd_object_aux_state) {
4586ba597c5SAnurag S. Maskey 		nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
4596ba597c5SAnurag S. Maskey 		    object->nwamd_object_name, state, aux_state);
4606ba597c5SAnurag S. Maskey 	}
4616ba597c5SAnurag S. Maskey 
4626ba597c5SAnurag S. Maskey 	/*
4636ba597c5SAnurag S. Maskey 	 * If the method thread was created, we drop the lock to the ENM
4646ba597c5SAnurag S. Maskey 	 * object without decreasing the reference count, ensuring it will not
4656ba597c5SAnurag S. Maskey 	 * be destroyed until method execution has completed.
4666ba597c5SAnurag S. Maskey 	 */
4676ba597c5SAnurag S. Maskey 	if (ran_method) {
4686ba597c5SAnurag S. Maskey 		nwamd_object_release_and_preserve(object);
4696ba597c5SAnurag S. Maskey 	} else {
4706ba597c5SAnurag S. Maskey 		nwamd_object_release(object);
4716ba597c5SAnurag S. Maskey 	}
4726ba597c5SAnurag S. Maskey }
4736ba597c5SAnurag S. Maskey 
4746ba597c5SAnurag S. Maskey /* Deactivates the ENM. */
4756ba597c5SAnurag S. Maskey static void
nwamd_enm_deactivate(const char * object_name)4766ba597c5SAnurag S. Maskey nwamd_enm_deactivate(const char *object_name)
4776ba597c5SAnurag S. Maskey {
4786ba597c5SAnurag S. Maskey 	nwamd_object_t object;
4796ba597c5SAnurag S. Maskey 	nwam_enm_handle_t enmh;
4806ba597c5SAnurag S. Maskey 	nwam_value_t fmrival;
4816ba597c5SAnurag S. Maskey 	char *fmri, *smf_state;
4826ba597c5SAnurag S. Maskey 	int ret;
4836ba597c5SAnurag S. Maskey 	nwam_state_t state;
4846ba597c5SAnurag S. Maskey 	nwam_aux_state_t aux_state;
4856ba597c5SAnurag S. Maskey 	boolean_t destroying = B_FALSE;
4866ba597c5SAnurag S. Maskey 
4876ba597c5SAnurag S. Maskey 	object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM, object_name);
4886ba597c5SAnurag S. Maskey 	if (object == NULL) {
489*f6904bc3SRenee Danson Sommerfeld 		nlog(LOG_ERR, "nwamd_enm_deactivate: could not find enm %s",
4906ba597c5SAnurag S. Maskey 		    object_name);
4916ba597c5SAnurag S. Maskey 		return;
4926ba597c5SAnurag S. Maskey 	}
4936ba597c5SAnurag S. Maskey 
4946ba597c5SAnurag S. Maskey 	state = object->nwamd_object_state;
4956ba597c5SAnurag S. Maskey 	aux_state = object->nwamd_object_aux_state;
4966ba597c5SAnurag S. Maskey 	enmh = object->nwamd_object_handle;
4976ba597c5SAnurag S. Maskey 	state = object->nwamd_object_state;
4986ba597c5SAnurag S. Maskey 	/* If destroying, we don't care about method failure/config err */
4996ba597c5SAnurag S. Maskey 	destroying = (aux_state == NWAM_AUX_STATE_UNINITIALIZED);
5006ba597c5SAnurag S. Maskey 
5016ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG, "nwamd_enm_deactivate: deactivating enm %s",
5026ba597c5SAnurag S. Maskey 	    object->nwamd_object_name);
5036ba597c5SAnurag S. Maskey 
5046ba597c5SAnurag S. Maskey 	if (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_FMRI, &fmrival)
5056ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
5066ba597c5SAnurag S. Maskey 		/*
5076ba597c5SAnurag S. Maskey 		 * Must be a method-based ENM with start (and stop) script(s).
5086ba597c5SAnurag S. Maskey 		 * Script execution thread will take care of the rest.
5096ba597c5SAnurag S. Maskey 		 * If the method thread was created, we drop the lock to the ENM
5106ba597c5SAnurag S. Maskey 		 * object without decreasing the reference count, ensuring it
5116ba597c5SAnurag S. Maskey 		 * will not be destroyed until method execution has completed.
5126ba597c5SAnurag S. Maskey 		 */
5136ba597c5SAnurag S. Maskey 		if (nwamd_enm_run_method(object)) {
5146ba597c5SAnurag S. Maskey 			nwamd_object_release_and_preserve(object);
5156ba597c5SAnurag S. Maskey 			return;
5166ba597c5SAnurag S. Maskey 		}
5176ba597c5SAnurag S. Maskey 		/* Could not launch method execution thread */
5186ba597c5SAnurag S. Maskey 		if (!destroying) {
5196ba597c5SAnurag S. Maskey 			state = NWAM_STATE_MAINTENANCE;
5206ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_METHOD_FAILED;
5216ba597c5SAnurag S. Maskey 		}
5226ba597c5SAnurag S. Maskey 	} else {
5236ba597c5SAnurag S. Maskey 		if (nwam_value_get_string(fmrival, &fmri) != NWAM_SUCCESS) {
524*f6904bc3SRenee Danson Sommerfeld 			nlog(LOG_ERR, "nwamd_enm_deactivate: could not "
525*f6904bc3SRenee Danson Sommerfeld 			    "retrieve fmri string for enm %s",
5266ba597c5SAnurag S. Maskey 			    object->nwamd_object_name);
5276ba597c5SAnurag S. Maskey 			if (!destroying) {
5286ba597c5SAnurag S. Maskey 				state = NWAM_STATE_MAINTENANCE;
5296ba597c5SAnurag S. Maskey 				aux_state = NWAM_AUX_STATE_INVALID_CONFIG;
5306ba597c5SAnurag S. Maskey 			}
5316ba597c5SAnurag S. Maskey 		} else {
5326ba597c5SAnurag S. Maskey 			if ((smf_state = smf_get_state(fmri)) == NULL) {
5336ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "nwamd_enm_deactivate: invalid "
534*f6904bc3SRenee Danson Sommerfeld 				    "fmri %s for enm %s", fmri,
5356ba597c5SAnurag S. Maskey 				    object->nwamd_object_name);
5366ba597c5SAnurag S. Maskey 				nwam_value_free(fmrival);
5376ba597c5SAnurag S. Maskey 				if (!destroying) {
5386ba597c5SAnurag S. Maskey 					state = NWAM_STATE_MAINTENANCE;
5396ba597c5SAnurag S. Maskey 					aux_state =
5406ba597c5SAnurag S. Maskey 					    NWAM_AUX_STATE_INVALID_CONFIG;
5416ba597c5SAnurag S. Maskey 				}
5426ba597c5SAnurag S. Maskey 				goto done;
5436ba597c5SAnurag S. Maskey 			}
5446ba597c5SAnurag S. Maskey 			free(smf_state);
5456ba597c5SAnurag S. Maskey 
5466ba597c5SAnurag S. Maskey 			nlog(LOG_DEBUG, "nwamd_enm_deactivate: deactivating %s "
547*f6904bc3SRenee Danson Sommerfeld 			    "for enm %s", fmri, object->nwamd_object_name);
5486ba597c5SAnurag S. Maskey 
5496ba597c5SAnurag S. Maskey 			ret = smf_disable_instance(fmri, SMF_TEMPORARY);
5506ba597c5SAnurag S. Maskey 
5516ba597c5SAnurag S. Maskey 			if (ret != 0) {
5526ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "nwamd_enm_deactivate: "
5536ba597c5SAnurag S. Maskey 				    "smf_disable_instance(%s) failed for "
554*f6904bc3SRenee Danson Sommerfeld 				    "enm %s: %s", fmri,
5556ba597c5SAnurag S. Maskey 				    object->nwamd_object_name,
5566ba597c5SAnurag S. Maskey 				    scf_strerror(scf_error()));
5576ba597c5SAnurag S. Maskey 				if (!destroying) {
5586ba597c5SAnurag S. Maskey 					state = NWAM_STATE_MAINTENANCE;
5596ba597c5SAnurag S. Maskey 					aux_state =
5606ba597c5SAnurag S. Maskey 					    NWAM_AUX_STATE_METHOD_FAILED;
5616ba597c5SAnurag S. Maskey 				}
5626ba597c5SAnurag S. Maskey 			}
5636ba597c5SAnurag S. Maskey 		}
5646ba597c5SAnurag S. Maskey 		nwam_value_free(fmrival);
5656ba597c5SAnurag S. Maskey 	}
5666ba597c5SAnurag S. Maskey done:
5676ba597c5SAnurag S. Maskey 	if (state == object->nwamd_object_state &&
5686ba597c5SAnurag S. Maskey 	    aux_state == object->nwamd_object_aux_state) {
5696ba597c5SAnurag S. Maskey 		/*
5706ba597c5SAnurag S. Maskey 		 * If aux state is "manual disable", we know
5716ba597c5SAnurag S. Maskey 		 * this was a disable request, otherwise it was
5726ba597c5SAnurag S. Maskey 		 * a _fini request or a condition satisfaction
5736ba597c5SAnurag S. Maskey 		 * failure.
5746ba597c5SAnurag S. Maskey 		 */
5756ba597c5SAnurag S. Maskey 		switch (object->nwamd_object_aux_state) {
5766ba597c5SAnurag S. Maskey 		case NWAM_AUX_STATE_MANUAL_DISABLE:
5776ba597c5SAnurag S. Maskey 			state = NWAM_STATE_DISABLED;
5786ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_MANUAL_DISABLE;
5796ba597c5SAnurag S. Maskey 			break;
5806ba597c5SAnurag S. Maskey 		case NWAM_AUX_STATE_UNINITIALIZED:
5816ba597c5SAnurag S. Maskey 			state = NWAM_STATE_UNINITIALIZED;
5826ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_UNINITIALIZED;
5836ba597c5SAnurag S. Maskey 			break;
5846ba597c5SAnurag S. Maskey 		default:
5856ba597c5SAnurag S. Maskey 			state = NWAM_STATE_OFFLINE;
5866ba597c5SAnurag S. Maskey 			aux_state = NWAM_AUX_STATE_CONDITIONS_NOT_MET;
5876ba597c5SAnurag S. Maskey 			break;
5886ba597c5SAnurag S. Maskey 		}
5896ba597c5SAnurag S. Maskey 	}
5906ba597c5SAnurag S. Maskey 
5916ba597c5SAnurag S. Maskey 	/* Only change state if we aren't destroying the ENM */
5926ba597c5SAnurag S. Maskey 	if (!destroying && (state != object->nwamd_object_state ||
5936ba597c5SAnurag S. Maskey 	    aux_state != object->nwamd_object_aux_state)) {
5946ba597c5SAnurag S. Maskey 		nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
5956ba597c5SAnurag S. Maskey 		    object->nwamd_object_name, state, aux_state);
5966ba597c5SAnurag S. Maskey 	}
5976ba597c5SAnurag S. Maskey 
5986ba597c5SAnurag S. Maskey 	/* If state/aux state are uninitialized/unintialized, destroy the ENM */
5996ba597c5SAnurag S. Maskey 	if (state == NWAM_STATE_UNINITIALIZED &&
6006ba597c5SAnurag S. Maskey 	    aux_state == NWAM_AUX_STATE_UNINITIALIZED) {
6016ba597c5SAnurag S. Maskey 		(void) nwamd_object_release_and_destroy(object);
6026ba597c5SAnurag S. Maskey 	} else {
6036ba597c5SAnurag S. Maskey 		(void) nwamd_object_release(object);
6046ba597c5SAnurag S. Maskey 	}
6056ba597c5SAnurag S. Maskey }
6066ba597c5SAnurag S. Maskey 
6076ba597c5SAnurag S. Maskey /*
6086ba597c5SAnurag S. Maskey  * Determine whether an ENM should be (de)activated.
6096ba597c5SAnurag S. Maskey  */
6106ba597c5SAnurag S. Maskey /* ARGSUSED1 */
6116ba597c5SAnurag S. Maskey static int
nwamd_enm_check(nwamd_object_t object,void * data)6126ba597c5SAnurag S. Maskey nwamd_enm_check(nwamd_object_t object, void *data)
6136ba597c5SAnurag S. Maskey {
6146ba597c5SAnurag S. Maskey 	nwam_enm_handle_t enmh;
6156ba597c5SAnurag S. Maskey 	nwam_value_t conditionval;
6166ba597c5SAnurag S. Maskey 	int64_t eactivation;
6176ba597c5SAnurag S. Maskey 	boolean_t enabled, satisfied;
6186ba597c5SAnurag S. Maskey 	char **conditions;
6196ba597c5SAnurag S. Maskey 	nwam_state_t state;
6206ba597c5SAnurag S. Maskey 	uint_t nelem;
6216ba597c5SAnurag S. Maskey 
6226ba597c5SAnurag S. Maskey 	state = object->nwamd_object_state;
6236ba597c5SAnurag S. Maskey 
6246ba597c5SAnurag S. Maskey 	enmh = object->nwamd_object_handle;
6256ba597c5SAnurag S. Maskey 
6266ba597c5SAnurag S. Maskey 	eactivation = enm_get_activation_mode(enmh);
6276ba597c5SAnurag S. Maskey 	if (eactivation == -1)
6286ba597c5SAnurag S. Maskey 		return (0);
6296ba597c5SAnurag S. Maskey 
6306ba597c5SAnurag S. Maskey 	switch (eactivation) {
6316ba597c5SAnurag S. Maskey 	case NWAM_ACTIVATION_MODE_MANUAL:
6326ba597c5SAnurag S. Maskey 		enabled = enm_is_enabled(enmh);
6336ba597c5SAnurag S. Maskey 
6346ba597c5SAnurag S. Maskey 		if (enabled) {
6356ba597c5SAnurag S. Maskey 			nlog(LOG_DEBUG, "nwamd_enm_check: %s is enabled",
6366ba597c5SAnurag S. Maskey 			    object->nwamd_object_name);
6376ba597c5SAnurag S. Maskey 			switch (state) {
6386ba597c5SAnurag S. Maskey 			case NWAM_STATE_ONLINE:
6396ba597c5SAnurag S. Maskey 			case NWAM_STATE_MAINTENANCE:
6406ba597c5SAnurag S. Maskey 				/* Do nothing */
6416ba597c5SAnurag S. Maskey 				break;
6426ba597c5SAnurag S. Maskey 			default:
6436ba597c5SAnurag S. Maskey 				if (nwamd_enm_action(object->nwamd_object_name,
6446ba597c5SAnurag S. Maskey 				    NWAM_ACTION_ENABLE) != 0) {
645*f6904bc3SRenee Danson Sommerfeld 					nlog(LOG_ERR, "nwamd_enm_check: "
646*f6904bc3SRenee Danson Sommerfeld 					    "enable failed for enm %s",
6476ba597c5SAnurag S. Maskey 					    object->nwamd_object_name);
6486ba597c5SAnurag S. Maskey 				}
6496ba597c5SAnurag S. Maskey 				break;
6506ba597c5SAnurag S. Maskey 			}
6516ba597c5SAnurag S. Maskey 		} else {
6526ba597c5SAnurag S. Maskey 			nlog(LOG_DEBUG, "nwamd_enm_check: %s is disabled",
6536ba597c5SAnurag S. Maskey 			    object->nwamd_object_name);
6546ba597c5SAnurag S. Maskey 			switch (state) {
6556ba597c5SAnurag S. Maskey 			case NWAM_STATE_ONLINE:
6566ba597c5SAnurag S. Maskey 				if (nwamd_enm_action(object->nwamd_object_name,
6576ba597c5SAnurag S. Maskey 				    NWAM_ACTION_DISABLE) != 0) {
6586ba597c5SAnurag S. Maskey 					nlog(LOG_ERR, "nwamd_enm_check: "
6596ba597c5SAnurag S. Maskey 					    "disable failed for enm %s",
6606ba597c5SAnurag S. Maskey 					    object->nwamd_object_name);
6616ba597c5SAnurag S. Maskey 				}
6626ba597c5SAnurag S. Maskey 				break;
6636ba597c5SAnurag S. Maskey 			case NWAM_STATE_MAINTENANCE:
6646ba597c5SAnurag S. Maskey 				/* Do nothing */
6656ba597c5SAnurag S. Maskey 				break;
6666ba597c5SAnurag S. Maskey 			case NWAM_STATE_DISABLED:
6676ba597c5SAnurag S. Maskey 				/* Do nothing */
6686ba597c5SAnurag S. Maskey 				break;
6696ba597c5SAnurag S. Maskey 			default:
6706ba597c5SAnurag S. Maskey 				nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
6716ba597c5SAnurag S. Maskey 				    object->nwamd_object_name,
6726ba597c5SAnurag S. Maskey 				    NWAM_STATE_DISABLED,
6736ba597c5SAnurag S. Maskey 				    NWAM_AUX_STATE_MANUAL_DISABLE);
6746ba597c5SAnurag S. Maskey 				break;
6756ba597c5SAnurag S. Maskey 			}
6766ba597c5SAnurag S. Maskey 		}
6776ba597c5SAnurag S. Maskey 		break;
6786ba597c5SAnurag S. Maskey 
6796ba597c5SAnurag S. Maskey 	case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY:
6806ba597c5SAnurag S. Maskey 	case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL:
6816ba597c5SAnurag S. Maskey 		if (nwam_enm_get_prop_value(enmh,
6826ba597c5SAnurag S. Maskey 		    NWAM_ENM_PROP_CONDITIONS, &conditionval) != NWAM_SUCCESS) {
6836ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_check: could not retrieve "
6846ba597c5SAnurag S. Maskey 			    "condition value");
6856ba597c5SAnurag S. Maskey 			break;
6866ba597c5SAnurag S. Maskey 		}
6876ba597c5SAnurag S. Maskey 		if (nwam_value_get_string_array(conditionval,
6886ba597c5SAnurag S. Maskey 		    &conditions, &nelem) != NWAM_SUCCESS) {
6896ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_check: could not retrieve "
6906ba597c5SAnurag S. Maskey 			    "condition value");
6916ba597c5SAnurag S. Maskey 			nwam_value_free(conditionval);
6926ba597c5SAnurag S. Maskey 			break;
6936ba597c5SAnurag S. Maskey 		}
6946ba597c5SAnurag S. Maskey 		satisfied = nwamd_check_conditions((uint64_t)eactivation,
6956ba597c5SAnurag S. Maskey 		    conditions, nelem);
6966ba597c5SAnurag S. Maskey 
6976ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_enm_check: conditions for enm %s "
6986ba597c5SAnurag S. Maskey 		    "%s satisfied", object->nwamd_object_name,
6996ba597c5SAnurag S. Maskey 		    satisfied ? "is" : "is not");
7006ba597c5SAnurag S. Maskey 		if (state != NWAM_STATE_ONLINE && satisfied) {
7016ba597c5SAnurag S. Maskey 			nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
7026ba597c5SAnurag S. Maskey 			    object->nwamd_object_name,
7036ba597c5SAnurag S. Maskey 			    NWAM_STATE_OFFLINE_TO_ONLINE,
7046ba597c5SAnurag S. Maskey 			    NWAM_AUX_STATE_METHOD_RUNNING);
7056ba597c5SAnurag S. Maskey 		}
7066ba597c5SAnurag S. Maskey 		if (state == NWAM_STATE_ONLINE && !satisfied) {
7076ba597c5SAnurag S. Maskey 			nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
7086ba597c5SAnurag S. Maskey 			    object->nwamd_object_name,
7096ba597c5SAnurag S. Maskey 			    NWAM_STATE_ONLINE_TO_OFFLINE,
7106ba597c5SAnurag S. Maskey 			    NWAM_AUX_STATE_CONDITIONS_NOT_MET);
7116ba597c5SAnurag S. Maskey 		}
7126ba597c5SAnurag S. Maskey 		nwam_value_free(conditionval);
7136ba597c5SAnurag S. Maskey 		break;
7146ba597c5SAnurag S. Maskey 
7156ba597c5SAnurag S. Maskey 	}
7166ba597c5SAnurag S. Maskey 	return (0);
7176ba597c5SAnurag S. Maskey }
7186ba597c5SAnurag S. Maskey 
7196ba597c5SAnurag S. Maskey void
nwamd_enm_check_conditions(void)7206ba597c5SAnurag S. Maskey nwamd_enm_check_conditions(void)
7216ba597c5SAnurag S. Maskey {
7226ba597c5SAnurag S. Maskey 	(void) nwamd_walk_objects(NWAM_OBJECT_TYPE_ENM, nwamd_enm_check, NULL);
7236ba597c5SAnurag S. Maskey }
7246ba597c5SAnurag S. Maskey 
7256ba597c5SAnurag S. Maskey int
nwamd_enm_action(const char * enm,nwam_action_t action)7266ba597c5SAnurag S. Maskey nwamd_enm_action(const char *enm, nwam_action_t action)
7276ba597c5SAnurag S. Maskey {
7286ba597c5SAnurag S. Maskey 	nwamd_event_t event = nwamd_event_init_object_action
7296ba597c5SAnurag S. Maskey 	    (NWAM_OBJECT_TYPE_ENM, enm, NULL, action);
7306ba597c5SAnurag S. Maskey 	if (event == NULL)
7316ba597c5SAnurag S. Maskey 		return (1);
7326ba597c5SAnurag S. Maskey 	nwamd_event_enqueue(event);
7336ba597c5SAnurag S. Maskey 	return (0);
7346ba597c5SAnurag S. Maskey }
7356ba597c5SAnurag S. Maskey 
7366ba597c5SAnurag S. Maskey /*
7376ba597c5SAnurag S. Maskey  * Event handling functions.
7386ba597c5SAnurag S. Maskey  */
7396ba597c5SAnurag S. Maskey 
7406ba597c5SAnurag S. Maskey /* Handle ENM initialization/refresh event */
7416ba597c5SAnurag S. Maskey void
nwamd_enm_handle_init_event(nwamd_event_t event)7426ba597c5SAnurag S. Maskey nwamd_enm_handle_init_event(nwamd_event_t event)
7436ba597c5SAnurag S. Maskey {
7446ba597c5SAnurag S. Maskey 	nwamd_object_t object;
7456ba597c5SAnurag S. Maskey 	nwam_enm_handle_t enmh;
7466ba597c5SAnurag S. Maskey 	nwam_error_t err;
7476ba597c5SAnurag S. Maskey 	boolean_t manual_disabled = B_FALSE;
7486ba597c5SAnurag S. Maskey 
7496ba597c5SAnurag S. Maskey 	if ((err = nwam_enm_read(event->event_object, 0, &enmh))
7506ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
7516ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_enm_handle_init_event: could not "
7526ba597c5SAnurag S. Maskey 		    "read object '%s': %s", event->event_object,
7536ba597c5SAnurag S. Maskey 		    nwam_strerror(err));
7546ba597c5SAnurag S. Maskey 		nwamd_event_do_not_send(event);
7556ba597c5SAnurag S. Maskey 		return;
7566ba597c5SAnurag S. Maskey 	}
7576ba597c5SAnurag S. Maskey 	if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM,
7586ba597c5SAnurag S. Maskey 	    event->event_object)) != NULL) {
7596ba597c5SAnurag S. Maskey 		nwam_enm_free(object->nwamd_object_handle);
7606ba597c5SAnurag S. Maskey 		object->nwamd_object_handle = enmh;
7616ba597c5SAnurag S. Maskey 	} else {
7626ba597c5SAnurag S. Maskey 		object = nwamd_object_init(NWAM_OBJECT_TYPE_ENM,
7636ba597c5SAnurag S. Maskey 		    event->event_object, enmh, NULL);
7646ba597c5SAnurag S. Maskey 		object->nwamd_object_state = NWAM_STATE_OFFLINE;
7656ba597c5SAnurag S. Maskey 		object->nwamd_object_aux_state =
7666ba597c5SAnurag S. Maskey 		    NWAM_AUX_STATE_CONDITIONS_NOT_MET;
7676ba597c5SAnurag S. Maskey 	}
768874067a0SAnurag S. Maskey 	/* (Re)set script time to now as the object has just been (re)read */
769874067a0SAnurag S. Maskey 	(void) gettimeofday(&object->nwamd_script_time, NULL);
770874067a0SAnurag S. Maskey 
7716ba597c5SAnurag S. Maskey 	manual_disabled = (enm_get_activation_mode(enmh) ==
7726ba597c5SAnurag S. Maskey 	    NWAM_ACTIVATION_MODE_MANUAL && !enm_is_enabled(enmh));
7736ba597c5SAnurag S. Maskey 
7746ba597c5SAnurag S. Maskey 	/*
7756ba597c5SAnurag S. Maskey 	 * If this ENM is ONLINE, and not manual and disabled (since in
7766ba597c5SAnurag S. Maskey 	 * that case it was online but we've just set enabled = false as part
7776ba597c5SAnurag S. Maskey 	 * of a disable action), then it is still active but refreshing.
7786ba597c5SAnurag S. Maskey 	 * Change states to re-activate itself.
7796ba597c5SAnurag S. Maskey 	 */
7806ba597c5SAnurag S. Maskey 	if (!manual_disabled &&
7816ba597c5SAnurag S. Maskey 	    object->nwamd_object_state == NWAM_STATE_ONLINE) {
7826ba597c5SAnurag S. Maskey 		nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
7836ba597c5SAnurag S. Maskey 		    event->event_object, NWAM_STATE_OFFLINE_TO_ONLINE,
7846ba597c5SAnurag S. Maskey 		    NWAM_AUX_STATE_METHOD_RUNNING);
7856ba597c5SAnurag S. Maskey 	}
7866ba597c5SAnurag S. Maskey 	nwamd_object_release(object);
7876ba597c5SAnurag S. Maskey }
7886ba597c5SAnurag S. Maskey 
7896ba597c5SAnurag S. Maskey /* Handle ENM finish event */
7906ba597c5SAnurag S. Maskey void
nwamd_enm_handle_fini_event(nwamd_event_t event)7916ba597c5SAnurag S. Maskey nwamd_enm_handle_fini_event(nwamd_event_t event)
7926ba597c5SAnurag S. Maskey {
7936ba597c5SAnurag S. Maskey 	nwamd_event_t state_event;
7946ba597c5SAnurag S. Maskey 
7956ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG, "nwamd_enm_handle_fini_event(%s)", event->event_object);
7966ba597c5SAnurag S. Maskey 
7976ba597c5SAnurag S. Maskey 	/*
7986ba597c5SAnurag S. Maskey 	 * Simulate a state event so that the state machine can correctly
7996ba597c5SAnurag S. Maskey 	 * deactivate the ENM and free up the handle.
8006ba597c5SAnurag S. Maskey 	 */
8016ba597c5SAnurag S. Maskey 	state_event = nwamd_event_init_object_state(NWAM_OBJECT_TYPE_ENM,
8026ba597c5SAnurag S. Maskey 	    event->event_object, NWAM_STATE_ONLINE_TO_OFFLINE,
8036ba597c5SAnurag S. Maskey 	    NWAM_AUX_STATE_UNINITIALIZED);
8046ba597c5SAnurag S. Maskey 	if (state_event == NULL) {
8056ba597c5SAnurag S. Maskey 		nwamd_event_do_not_send(event);
8066ba597c5SAnurag S. Maskey 		return;
8076ba597c5SAnurag S. Maskey 	}
8086ba597c5SAnurag S. Maskey 	nwamd_enm_handle_state_event(state_event);
8096ba597c5SAnurag S. Maskey 	nwamd_event_fini(state_event);
8106ba597c5SAnurag S. Maskey 	/*
8116ba597c5SAnurag S. Maskey 	 * Do not free the handle and object.
8126ba597c5SAnurag S. Maskey 	 * nwamd_enm_activate_deactivate_thread() and
8136ba597c5SAnurag S. Maskey 	 * nwamd_enm_deactivate() does this after running the stop script
8146ba597c5SAnurag S. Maskey 	 * and disabling the FMRI respectively.
8156ba597c5SAnurag S. Maskey 	 */
8166ba597c5SAnurag S. Maskey }
8176ba597c5SAnurag S. Maskey 
8186ba597c5SAnurag S. Maskey void
nwamd_enm_handle_action_event(nwamd_event_t event)8196ba597c5SAnurag S. Maskey nwamd_enm_handle_action_event(nwamd_event_t event)
8206ba597c5SAnurag S. Maskey {
8216ba597c5SAnurag S. Maskey 	nwamd_object_t object;
8226ba597c5SAnurag S. Maskey 
8236ba597c5SAnurag S. Maskey 	switch (event->event_msg->nwe_data.nwe_object_action.nwe_action) {
8246ba597c5SAnurag S. Maskey 	case NWAM_ACTION_ENABLE:
8256ba597c5SAnurag S. Maskey 		object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM,
8266ba597c5SAnurag S. Maskey 		    event->event_object);
8276ba597c5SAnurag S. Maskey 		if (object == NULL) {
8286ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_handle_action_event: "
8296ba597c5SAnurag S. Maskey 			    "could not find enm %s", event->event_object);
8306ba597c5SAnurag S. Maskey 			nwamd_event_do_not_send(event);
8316ba597c5SAnurag S. Maskey 			return;
8326ba597c5SAnurag S. Maskey 		}
8336ba597c5SAnurag S. Maskey 		if (object->nwamd_object_state == NWAM_STATE_ONLINE) {
8346ba597c5SAnurag S. Maskey 			nlog(LOG_DEBUG, "nwamd_enm_handle_action_event: "
8356ba597c5SAnurag S. Maskey 			    "enm %s already online, nothing to do",
8366ba597c5SAnurag S. Maskey 			    event->event_object);
8376ba597c5SAnurag S. Maskey 			nwamd_object_release(object);
8386ba597c5SAnurag S. Maskey 			return;
8396ba597c5SAnurag S. Maskey 		}
8406ba597c5SAnurag S. Maskey 		nwamd_object_release(object);
8416ba597c5SAnurag S. Maskey 
8426ba597c5SAnurag S. Maskey 		nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
8436ba597c5SAnurag S. Maskey 		    event->event_object, NWAM_STATE_OFFLINE_TO_ONLINE,
8446ba597c5SAnurag S. Maskey 		    NWAM_AUX_STATE_METHOD_RUNNING);
8456ba597c5SAnurag S. Maskey 		break;
8466ba597c5SAnurag S. Maskey 	case NWAM_ACTION_DISABLE:
8476ba597c5SAnurag S. Maskey 		object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM,
8486ba597c5SAnurag S. Maskey 		    event->event_object);
8496ba597c5SAnurag S. Maskey 		if (object == NULL) {
8506ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_enm_handle_action_event: "
8516ba597c5SAnurag S. Maskey 			    "could not find enm %s", event->event_object);
8526ba597c5SAnurag S. Maskey 			nwamd_event_do_not_send(event);
8536ba597c5SAnurag S. Maskey 			return;
8546ba597c5SAnurag S. Maskey 		}
8556ba597c5SAnurag S. Maskey 		if (object->nwamd_object_state == NWAM_STATE_DISABLED) {
8566ba597c5SAnurag S. Maskey 			nlog(LOG_DEBUG, "nwamd_enm_handle_action_event: "
8576ba597c5SAnurag S. Maskey 			    "enm %s already disabled, nothing to do",
8586ba597c5SAnurag S. Maskey 			    event->event_object);
8596ba597c5SAnurag S. Maskey 			nwamd_object_release(object);
8606ba597c5SAnurag S. Maskey 			return;
8616ba597c5SAnurag S. Maskey 		}
8626ba597c5SAnurag S. Maskey 		nwamd_object_release(object);
8636ba597c5SAnurag S. Maskey 
8646ba597c5SAnurag S. Maskey 		nwamd_object_set_state(NWAM_OBJECT_TYPE_ENM,
8656ba597c5SAnurag S. Maskey 		    event->event_object, NWAM_STATE_ONLINE_TO_OFFLINE,
8666ba597c5SAnurag S. Maskey 		    NWAM_AUX_STATE_MANUAL_DISABLE);
8676ba597c5SAnurag S. Maskey 		break;
8686ba597c5SAnurag S. Maskey 	case NWAM_ACTION_ADD:
8696ba597c5SAnurag S. Maskey 	case NWAM_ACTION_REFRESH:
8706ba597c5SAnurag S. Maskey 		nwamd_enm_handle_init_event(event);
8716ba597c5SAnurag S. Maskey 		break;
8726ba597c5SAnurag S. Maskey 	case NWAM_ACTION_DESTROY:
8736ba597c5SAnurag S. Maskey 		nwamd_enm_handle_fini_event(event);
8746ba597c5SAnurag S. Maskey 		break;
8756ba597c5SAnurag S. Maskey 	default:
8766ba597c5SAnurag S. Maskey 		nlog(LOG_INFO, "nwam_enm_handle_action_event: "
8776ba597c5SAnurag S. Maskey 		    "unexpected action");
8786ba597c5SAnurag S. Maskey 		nwamd_event_do_not_send(event);
8796ba597c5SAnurag S. Maskey 		break;
8806ba597c5SAnurag S. Maskey 	}
8816ba597c5SAnurag S. Maskey }
8826ba597c5SAnurag S. Maskey 
8836ba597c5SAnurag S. Maskey void
nwamd_enm_handle_state_event(nwamd_event_t event)8846ba597c5SAnurag S. Maskey nwamd_enm_handle_state_event(nwamd_event_t event)
8856ba597c5SAnurag S. Maskey {
8866ba597c5SAnurag S. Maskey 	nwamd_object_t object;
8876ba597c5SAnurag S. Maskey 	nwam_state_t new_state;
8886ba597c5SAnurag S. Maskey 	nwam_aux_state_t new_aux_state;
8896ba597c5SAnurag S. Maskey 
8906ba597c5SAnurag S. Maskey 	if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM,
8916ba597c5SAnurag S. Maskey 	    event->event_object)) == NULL) {
892*f6904bc3SRenee Danson Sommerfeld 		nlog(LOG_INFO, "nwamd_enm_handle_state_event: "
893*f6904bc3SRenee Danson Sommerfeld 		    "state event for nonexistent enm %s", event->event_object);
8946ba597c5SAnurag S. Maskey 		nwamd_event_do_not_send(event);
8956ba597c5SAnurag S. Maskey 		return;
8966ba597c5SAnurag S. Maskey 	}
8976ba597c5SAnurag S. Maskey 	new_state = event->event_msg->nwe_data.nwe_object_state.nwe_state;
8986ba597c5SAnurag S. Maskey 	new_aux_state =
8996ba597c5SAnurag S. Maskey 	    event->event_msg->nwe_data.nwe_object_state.nwe_aux_state;
9006ba597c5SAnurag S. Maskey 
9016ba597c5SAnurag S. Maskey 	if (new_state == object->nwamd_object_state &&
9026ba597c5SAnurag S. Maskey 	    new_aux_state == object->nwamd_object_aux_state) {
9036ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_enm_handle_state_event: "
904*f6904bc3SRenee Danson Sommerfeld 		    "enm %s already in state (%s , %s)",
9056ba597c5SAnurag S. Maskey 		    object->nwamd_object_name, nwam_state_to_string(new_state),
9066ba597c5SAnurag S. Maskey 		    nwam_aux_state_to_string(new_aux_state));
9076ba597c5SAnurag S. Maskey 		nwamd_object_release(object);
9086ba597c5SAnurag S. Maskey 		return;
9096ba597c5SAnurag S. Maskey 	}
9106ba597c5SAnurag S. Maskey 
9116ba597c5SAnurag S. Maskey 	object->nwamd_object_state = new_state;
9126ba597c5SAnurag S. Maskey 	object->nwamd_object_aux_state = new_aux_state;
9136ba597c5SAnurag S. Maskey 
914*f6904bc3SRenee Danson Sommerfeld 	nlog(LOG_DEBUG, "nwamd_enm_handle_state_event: changing state for enm "
9156ba597c5SAnurag S. Maskey 	    "%s to (%s , %s)", object->nwamd_object_name,
9166ba597c5SAnurag S. Maskey 	    nwam_state_to_string(object->nwamd_object_state),
9176ba597c5SAnurag S. Maskey 	    nwam_aux_state_to_string(object->nwamd_object_aux_state));
9186ba597c5SAnurag S. Maskey 
9196ba597c5SAnurag S. Maskey 	nwamd_object_release(object);
9206ba597c5SAnurag S. Maskey 
9216ba597c5SAnurag S. Maskey 	/*
9226ba597c5SAnurag S. Maskey 	 * State machine for ENMs.
9236ba597c5SAnurag S. Maskey 	 */
9246ba597c5SAnurag S. Maskey 	switch (new_state) {
9256ba597c5SAnurag S. Maskey 	case NWAM_STATE_OFFLINE_TO_ONLINE:
9266ba597c5SAnurag S. Maskey 		nwamd_enm_activate(event->event_object);
9276ba597c5SAnurag S. Maskey 		break;
9286ba597c5SAnurag S. Maskey 	case NWAM_STATE_ONLINE_TO_OFFLINE:
9296ba597c5SAnurag S. Maskey 		nwamd_enm_deactivate(event->event_object);
9306ba597c5SAnurag S. Maskey 		break;
9316ba597c5SAnurag S. Maskey 	case NWAM_STATE_DISABLED:
9326ba597c5SAnurag S. Maskey 	case NWAM_STATE_OFFLINE:
9336ba597c5SAnurag S. Maskey 	case NWAM_STATE_UNINITIALIZED:
9346ba597c5SAnurag S. Maskey 	case NWAM_STATE_MAINTENANCE:
9356ba597c5SAnurag S. Maskey 	case NWAM_STATE_DEGRADED:
9366ba597c5SAnurag S. Maskey 	default:
9376ba597c5SAnurag S. Maskey 		/* do nothing */
9386ba597c5SAnurag S. Maskey 		break;
9396ba597c5SAnurag S. Maskey 	}
9406ba597c5SAnurag S. Maskey }
941