Mercurial > illumos > illumos-gate
changeset 11994:5cb9130500d6
6935812 race in enm deactivate when switching NCPs
author | Anurag S. Maskey <Anurag.Maskey@Sun.COM> |
---|---|
date | Thu, 25 Mar 2010 13:53:44 -0400 |
parents | a39d3ec14d8f |
children | caff1bd711f5 |
files | usr/src/cmd/cmd-inet/lib/nwamd/enm.c usr/src/cmd/cmd-inet/lib/nwamd/objects.h |
diffstat | 2 files changed, 52 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/cmd-inet/lib/nwamd/enm.c Thu Mar 25 11:22:48 2010 -0600 +++ b/usr/src/cmd/cmd-inet/lib/nwamd/enm.c Thu Mar 25 13:53:44 2010 -0400 @@ -151,7 +151,8 @@ nwam_value_t scriptval = NULL; nwam_state_t state; nwam_aux_state_t aux_state; - char *script; + char *script, *copy = NULL; + const char **argv = NULL; boolean_t going_online, disable_succeeded = B_FALSE; int ret; @@ -159,12 +160,8 @@ if (object == NULL) { nlog(LOG_ERR, "nwamd_enm_activate_deactivate_thread: " "could not find ENM %s", object_name); - free(object_name); - return (NULL); + goto done; } - /* object_name was malloc() before this thread was created, free() it */ - free(object_name); - enmh = object->nwamd_object_handle; going_online = @@ -182,8 +179,7 @@ */ nlog(going_online ? LOG_ERR : LOG_DEBUG, "nwamd_enm_activate_deactivate_thread: " - "no script specified for enm %s", - object->nwamd_object_name); + "no script specified for enm %s", object_name); if (going_online) { state = NWAM_STATE_MAINTENANCE; aux_state = NWAM_AUX_STATE_METHOD_MISSING; @@ -191,13 +187,13 @@ disable_succeeded = B_TRUE; } } else { - char *copy = NULL, *lasts; - const char **newargv, **argv = NULL; + char *lasts; + const char **newargv; int i = 0; + struct timeval now; nlog(LOG_DEBUG, "nwamd_enm_activate_deactivate_thread: " - "running script %s for ENM %s", script, - object->nwamd_object_name); + "running script %s for ENM %s", script, object_name); /* * The script may take a number of arguments. We need to @@ -225,8 +221,41 @@ newargv = realloc(argv, (i + 1) * sizeof (char *)); argv = newargv; + /* Store the current time as the time the script began */ + (void) gettimeofday(&now, NULL); + object->nwamd_script_time = now; + + /* + * Release the object so that it is not blocked while the + * script is running. + */ + nwamd_object_release(object); + ret = nwamd_start_childv(CTRUN, argv); + /* + * Find the object again, now that the script has finished + * running. Check if this ENM was re-read during that time by + * comparing the object's script time with the one from above. + */ + object = nwamd_object_find(NWAM_OBJECT_TYPE_ENM, object_name); + if (object == NULL) { + nlog(LOG_ERR, "nwamd_enm_activate_deactivate_thread: " + "could not find ENM %s after running script", + object_name); + goto done; + } + + if (object->nwamd_script_time.tv_sec != now.tv_sec || + object->nwamd_script_time.tv_usec != now.tv_usec) { + nlog(LOG_INFO, "nwamd_enm_activate_deactivate_thread: " + "ENM %s has been refreshed, nothing to do", + object_name); + nwamd_object_release(object); + goto done; + } + (void) gettimeofday(&object->nwamd_script_time, NULL); + err: /* * If script execution fails and we're not destroying the @@ -235,7 +264,7 @@ if (ret != 0) { nlog(LOG_ERR, "nwamd_enm_activate_deactivate_thread: " "execution of '%s' failed for ENM %s", - script, object->nwamd_object_name); + script, object_name); if (object->nwamd_object_aux_state != NWAM_AUX_STATE_UNINITIALIZED) { state = NWAM_STATE_MAINTENANCE; @@ -252,10 +281,7 @@ disable_succeeded = B_TRUE; } } - free(argv); - free(copy); } - nwam_value_free(scriptval); if (disable_succeeded) { /* @@ -292,6 +318,12 @@ (void) nwamd_object_release_after_preserve(object); } +done: + /* object_name was malloc() before this thread was created, free() it */ + free(object_name); + free(argv); + free(copy); + nwam_value_free(scriptval); return (NULL); } @@ -737,6 +769,9 @@ object->nwamd_object_aux_state = NWAM_AUX_STATE_CONDITIONS_NOT_MET; } + /* (Re)set script time to now as the object has just been (re)read */ + (void) gettimeofday(&object->nwamd_script_time, NULL); + manual_disabled = (enm_get_activation_mode(enmh) == NWAM_ACTIVATION_MODE_MANUAL && !enm_is_enabled(enmh));
--- a/usr/src/cmd/cmd-inet/lib/nwamd/objects.h Thu Mar 25 11:22:48 2010 -0600 +++ b/usr/src/cmd/cmd-inet/lib/nwamd/objects.h Thu Mar 25 13:53:44 2010 -0400 @@ -54,6 +54,7 @@ void *nwamd_object_handle; /* can point at ENMs, locations, etc. */ nwamd_ncu_t *nwamd_object_data; + struct timeval nwamd_script_time; nwam_state_t nwamd_object_state; nwam_aux_state_t nwamd_object_aux_state; uu_list_node_t nwamd_object_node;