Example #1
0
/****************************************************************************
  Name          :  ncs_eda_startup

  Description   :  This routine creates a EDSv agent infrastructure to interface
                   with EDSv service. Once the infrastructure is created from
                   then on use_count is incremented for every startup request.

  Arguments     :  - NIL-

  Return Values :  NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE

  Notes         :  None
******************************************************************************/
unsigned int ncs_eda_startup(void)
{
    NCS_LIB_REQ_INFO lib_create;
    TRACE_ENTER();

    osaf_mutex_lock_ordie(&s_agent_startup_mutex);
    if (eda_use_count > 0) {
        /* Already created, so just increment the use_count */
        eda_use_count++;
        osaf_mutex_unlock_ordie(&s_agent_startup_mutex);
        TRACE_LEAVE2("Library use count: %u", eda_use_count);
        return NCSCC_RC_SUCCESS;
    }

    /*** Init EDA ***/
    memset(&lib_create, 0, sizeof(lib_create));
    lib_create.i_op = NCS_LIB_REQ_CREATE;
    if (ncs_eda_lib_req(&lib_create) != NCSCC_RC_SUCCESS) {
        osaf_mutex_unlock_ordie(&s_agent_startup_mutex);
        return NCSCC_RC_FAILURE;
    } else {
        eda_use_count = 1;
        TRACE("EDA agent library initialized");
    }

    osaf_mutex_unlock_ordie(&s_agent_startup_mutex);
    TRACE_LEAVE2("Library use count: %u", eda_use_count);
    return NCSCC_RC_SUCCESS;
}
Example #2
0
/****************************************************************************
  Name          :  ncs_mqa_startup

  Description   :  This routine creates a MQSv agent infrastructure to interface
                   with MQSv service. Once the infrastructure is created from
                   then on use_count is incremented for every startup request.

  Arguments     :  - NIL-

  Return Values :  NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE

  Notes         :  None
******************************************************************************/
unsigned int ncs_mqa_startup(void)
{
	NCS_LIB_REQ_INFO lib_create;
	char *value = NULL;

	osaf_mutex_lock_ordie(&s_agent_startup_mutex);
	if (mqa_use_count > 0) {
		/* Already created, so just increment the use_count */
		mqa_use_count++;
		osaf_mutex_unlock_ordie(&s_agent_startup_mutex);
		return NCSCC_RC_SUCCESS;
	}

   /*** Init MQA ***/
	memset(&lib_create, 0, sizeof(lib_create));
	lib_create.i_op = NCS_LIB_REQ_CREATE;
	if (mqa_lib_req(&lib_create) != NCSCC_RC_SUCCESS) {
		osaf_mutex_unlock_ordie(&s_agent_startup_mutex);
		return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
	} else {
		printf("\nMQSV:MQA:ON");
		mqa_use_count = 1;
	}

	/* Initialize trace system first of all so we can see what is going. */
	if ((value = getenv("MQA_TRACE_PATHNAME")) != NULL) {
		logtrace_init("mqa", value, CATEGORY_ALL);
	}

	osaf_mutex_unlock_ordie(&s_agent_startup_mutex);
	return NCSCC_RC_SUCCESS;
}
Example #3
0
uint32_t ncsmds_adm_api(NCSMDS_ADMOP_INFO *mds_adm)
{
	uint32_t status = NCSCC_RC_SUCCESS;

	if (mds_adm == NULL) {
		m_MDS_LOG_ERR("MDS_PAPI : Invalid Input mds_adm = NULL in ncsmds_adm_api()");
		return NCSCC_RC_FAILURE;
	}
	osaf_mutex_lock_ordie(&gl_mds_library_mutex);
	if (gl_mds_mcm_cb == NULL) {
		m_MDS_LOG_ERR("MDS_PAPI : ncsmds_adm_api() : MDS is not initialized gl_mds_mcm_cb = NULL ");
		osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
		return NCSCC_RC_FAILURE;
	}

	switch (mds_adm->i_op) {
	case MDS_ADMOP_VDEST_CREATE:
		status = mds_mcm_vdest_create(mds_adm);
		break;

	case MDS_ADMOP_VDEST_CONFIG:
		status = mds_mcm_vdest_chg_role(mds_adm);
		break;

	case MDS_ADMOP_VDEST_DESTROY:
		status = mds_mcm_vdest_destroy(mds_adm);
		break;

	case MDS_ADMOP_VDEST_QUERY:
		status = mds_mcm_vdest_query(mds_adm);
		break;

	case MDS_ADMOP_PWE_CREATE:
		status = mds_mcm_pwe_create(mds_adm);
		break;

	case MDS_ADMOP_PWE_DESTROY:
		status = mds_mcm_pwe_destroy(mds_adm);
		break;

	case MDS_ADMOP_PWE_QUERY:
		status = mds_mcm_adm_pwe_query(mds_adm);
		break;

	default:
		m_MDS_LOG_ERR("MDS_PAPI : API Option Unsupported in ncsmds_adm_api()");
		status = NCSCC_RC_FAILURE;
		break;
	}

	osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
	return status;
}
Example #4
0
FILE *ncs_os_fopen(const char *fpath, const char *fmode)
{
	FILE *fp = NULL;
	int flags = 0;
	osaf_mutex_lock_ordie(&s_cloexec_mutex);
	fp = fopen(fpath, fmode);
	if (fp == NULL) {
		osaf_mutex_unlock_ordie(&s_cloexec_mutex);
		return NULL;
	}

	flags = fcntl(fileno(fp), F_GETFD, 0);
	fcntl(fileno(fp), F_SETFD, (flags | FD_CLOEXEC));

	osaf_mutex_unlock_ordie(&s_cloexec_mutex);

	return fp;
}
Example #5
0
uint32_t ncs_sel_obj_create(NCS_SEL_OBJ *o_sel_obj)
{
	int s_pair[2];
	int flags = 0;

	osaf_mutex_lock_ordie(&s_cloexec_mutex);
	if (0 != socketpair(AF_UNIX, SOCK_STREAM, 0, s_pair)) {
		syslog(LOG_ERR, "%s: socketpair failed - %s", __FUNCTION__, strerror(errno));
		osaf_mutex_unlock_ordie(&s_cloexec_mutex);
		return NCSCC_RC_FAILURE;
	}

	flags = fcntl(s_pair[0], F_GETFD, 0);
	fcntl(s_pair[0], F_SETFD, (flags | FD_CLOEXEC));

	flags = fcntl(s_pair[1], F_GETFD, 0);
	fcntl(s_pair[1], F_SETFD, (flags | FD_CLOEXEC));

	osaf_mutex_unlock_ordie(&s_cloexec_mutex);

	if (s_pair[0] > s_pair[1]) {
		/* Ensure s_pair[1] is equal or greater */
		int temp = s_pair[0];
		s_pair[0] = s_pair[1];
		s_pair[1] = temp;
	}
	o_sel_obj->raise_obj = s_pair[0];
	o_sel_obj->rmv_obj = s_pair[1];
	/* Raising indications should be a non-blocking operation. Otherwise, 
	   it can lead to deadlocks among reader and writer applications. 
	 */
	flags = fcntl(o_sel_obj->raise_obj, F_GETFL, 0);
	if (fcntl(o_sel_obj->raise_obj, F_SETFL, (flags | O_NONBLOCK)) == -1) {
		syslog(LOG_ERR, "%s: fcntl failed - %s", __FUNCTION__, strerror(errno));
		(void) ncs_sel_obj_destroy(*o_sel_obj);
		return NCSCC_RC_FAILURE;
	}

	return NCSCC_RC_SUCCESS;
}
Example #6
0
/***************************************************************************
 *
 * unsigned int
 * ncs_os_lock( NCS_OS_LOCK *, NCS_OS_LOCK_REQUEST )
 *
 * Description:
 *   This routine handles all operating system lock primitives.
 *
 * Synopsis:
 *
 * Call Arguments:
 *    lock    ............... pointer to a NCS_OS_LOCK
 *    request ............... action request
 *
 * Returns:
 *   Returns NCSCC_RC_SUCCESS if successful, otherwise NCSCC_RC_FAILURE.
 *
 * Notes:
 *
 ****************************************************************************/
unsigned int ncs_os_lock(NCS_OS_LOCK * lock, NCS_OS_LOCK_REQUEST request, unsigned int type)
{
	switch (request) {
	case NCS_OS_LOCK_CREATE: {
		pthread_mutexattr_t mutex_attr;

		if (pthread_mutexattr_init(&mutex_attr) != 0)
			return (NCSCC_RC_FAILURE);

		if (pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE) != 0)
			return (NCSCC_RC_FAILURE);

		if (pthread_mutex_init(&lock->lock, &mutex_attr) != 0) {
			pthread_mutexattr_destroy(&mutex_attr);
			return (NCSCC_RC_FAILURE);
		}

		if (pthread_mutexattr_destroy(&mutex_attr) != 0)
			return (NCSCC_RC_FAILURE);

		break;
	}
	case NCS_OS_LOCK_RELEASE:
		if (pthread_mutex_destroy(&lock->lock) != 0)
			return (NCSCC_RC_FAILURE);
		break;

	case NCS_OS_LOCK_LOCK:
		osaf_mutex_lock_ordie(&lock->lock);
		break;

	case NCS_OS_LOCK_UNLOCK:
		osaf_mutex_unlock_ordie(&lock->lock);
		break;

	default:
		return (NCSCC_RC_FAILURE);
	}

	return NCSCC_RC_SUCCESS;
}
Example #7
0
/****************************************************************************
  Name          :  ncs_cpa_shutdown 

  Description   :  This routine destroys the CPSv agent infrastructure created 
                   to interface CPSv service. If the registered users are > 1, 
                   it just decrements the use_count.   

  Arguments     :  - NIL -

  Return Values :  NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE

  Notes         :  None
******************************************************************************/
unsigned int ncs_cpa_shutdown(void)
{
	uint32_t rc = NCSCC_RC_SUCCESS;

	osaf_mutex_lock_ordie(&s_agent_startup_mutex);

	if (cpa_use_count > 1) {
		/* Still users extis, so just decrement the use_count */
		cpa_use_count--;
	} else if (cpa_use_count == 1) {
		NCS_LIB_REQ_INFO lib_destroy;

		memset(&lib_destroy, 0, sizeof(lib_destroy));
		lib_destroy.i_op = NCS_LIB_REQ_DESTROY;
		rc = cpa_lib_req(&lib_destroy);

		cpa_use_count = 0;
	}

	osaf_mutex_unlock_ordie(&s_agent_startup_mutex);

	return rc;
}
Example #8
0
/****************************************************************************
  Name          :  ncs_eda_shutdown

  Description   :  This routine destroys the EDSv agent infrastructure created
                   to interface EDSv service. If the registered users are > 1,
                   it just decrements the use_count.

  Arguments     :  - NIL -

  Return Values :  NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE

  Notes         :  None
******************************************************************************/
unsigned int ncs_eda_shutdown(void)
{
    uint32_t rc = NCSCC_RC_SUCCESS;
    TRACE_ENTER();

    osaf_mutex_lock_ordie(&s_agent_startup_mutex);
    if (eda_use_count > 1) {
        /* Still users extis, so just decrement the use_count */
        eda_use_count--;
    } else if (eda_use_count == 1) {
        NCS_LIB_REQ_INFO lib_destroy;

        memset(&lib_destroy, 0, sizeof(lib_destroy));
        lib_destroy.i_op = NCS_LIB_REQ_DESTROY;

        rc = ncs_eda_lib_req(&lib_destroy);

        eda_use_count = 0;
    }

    osaf_mutex_unlock_ordie(&s_agent_startup_mutex);
    TRACE_LEAVE2("Library use count: %u", eda_use_count);
    return rc;
}
Example #9
0
uint32_t ncsmds_api(NCSMDS_INFO *svc_to_mds_info)
{
	uint32_t status = NCSCC_RC_SUCCESS;

	if (svc_to_mds_info == NULL) {
		m_MDS_LOG_ERR("MDS_PAPI : Input svc_to_mds_info = NULL in ncsmds_api()");
		return NCSCC_RC_FAILURE;
	}

	osaf_mutex_lock_ordie(&gl_mds_library_mutex);
	if (gl_mds_mcm_cb == NULL) {
		m_MDS_LOG_ERR("MDS_PAPI : ncsmds_api() : MDS is not initialized gl_mds_mcm_cb = NULL ");
		osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
		return NCSCC_RC_FAILURE;
	}

	/* Vailidate pwe hdl */
	if (svc_to_mds_info->i_op == MDS_SEND || svc_to_mds_info->i_op == MDS_DIRECT_SEND) {
		/* Don't validate pwe hdl */
	} else {
		status = mds_validate_pwe_hdl((MDS_PWE_HDL)svc_to_mds_info->i_mds_hdl);
		if (status == NCSCC_RC_FAILURE) {
			m_MDS_LOG_ERR("MDS_PAPI : Invalid pwe hdl in ncsmds_api()");
			osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
			return NCSCC_RC_FAILURE;
		}
	}

	switch (svc_to_mds_info->i_op) {
	case MDS_INSTALL:
		status = mds_mcm_svc_install(svc_to_mds_info);
		break;

	case MDS_UNINSTALL:
		status = mds_mcm_svc_uninstall(svc_to_mds_info);
		break;

	case MDS_SUBSCRIBE:
	case MDS_RED_SUBSCRIBE:
		status = mds_mcm_svc_subscribe(svc_to_mds_info);
		break;

	case MDS_CANCEL:
		status = mds_mcm_svc_unsubscribe(svc_to_mds_info);
		break;
/*
    case MDS_SYS_SUBSCRIBE:
        status = mds_sys_subscribe(svc_to_mds_info);
        break;
*/
	case MDS_SEND:
	case MDS_DIRECT_SEND:
		status = mds_send(svc_to_mds_info);
		break;

	case MDS_RETRIEVE:
		status = mds_retrieve(svc_to_mds_info);
		break;

	case MDS_QUERY_DEST:
		status = mds_mcm_dest_query(svc_to_mds_info);
		break;

	case MDS_QUERY_PWE:
		status = mds_mcm_pwe_query(svc_to_mds_info);
		break;

	case MDS_NODE_SUBSCRIBE:
		status = mds_mcm_node_subscribe(svc_to_mds_info);
		break;

	case MDS_NODE_UNSUBSCRIBE:
		status = mds_mcm_node_unsubscribe(svc_to_mds_info);
		break;

	default:
		m_MDS_LOG_ERR("MDS_PAPI : API Option Unsupported in ncsmds_api()");
		status = NCSCC_RC_FAILURE;
		break;
	}

	osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
	return status;
}
Example #10
0
/**
 * Write a log record to file
 * The file must be opened for append
 * 
 * @param indata[in] Type wlrh_t
 * @param outdata[out], int errno, 0 if no error
 * @param max_outsize[in], always sizeof(int)
 * @return (-1) on error or number of written bytes
 */
int write_log_record_hdl(void *indata, void *outdata, size_t max_outsize, bool *timeout_f)
{
	int rc, bytes_written = 0;
	off_t file_length = 0;
	wlrh_t *params_in = (wlrh_t *) indata;
	/* The logrecord is stored in the indata buffer right after the
	 * wlrh_t structure
	 */
	char *logrecord = (char *) (indata + sizeof(wlrh_t));
	int *errno_out_p = (int *) outdata;
	*errno_out_p = 0;

//#define LLD_DELAY_WRTST /* LLDTEST */
#ifdef LLD_DELAY_WRTST /* Make "file system" hang for n sec at first write */
	static bool lld_once_f = true;
	const unsigned int lld_sleep_sec = 10;
#endif
	
	TRACE_ENTER();
	
 retry:
	rc = write(params_in->fd, &logrecord[bytes_written],
		 params_in->record_size - bytes_written);
	if (rc == -1) {
		if (errno == EINTR)
			goto retry;

		LOG_ER("%s - write FAILED: %s",__FUNCTION__, strerror(errno));
		*errno_out_p = errno;
		goto done;
	} else {
		/* Handle partial writes */
		bytes_written += rc;
		if (bytes_written < params_in->record_size)
			goto retry;
	}
#ifdef LLD_DELAY_WRTST /* LLDTEST Wait first time thread is used */
	if (strstr(logrecord, "xxx")) {
		if (lld_once_f == true) {
			lld_once_f = false;
			TRACE("LLDTEST xxx Hang write");
			//TRACE("LLDTEST: logrecord \"%s\"",logrecord);
			sleep(lld_sleep_sec);
			TRACE("LLDTEST End of sleep");
		}
	}
	if (strstr(logrecord, "yyy")) {
		lld_once_f = true;
		TRACE("LLDTEST yyy Rearmed Hang write");
	}
#endif
 
	/* If the thread was hanging and has timed out and the log record was
	 * written it is invalid and shall be removed from file (log service has
	 * returned SA_AIS_TRY_AGAIN). 
	 */
	osaf_mutex_lock_ordie(&lgs_ftcom_mutex); /* LOCK */
	if (*timeout_f == true) {
		TRACE("Timeout, removing last log record");
		file_length = lseek(params_in->fd, -bytes_written, SEEK_END);
		if (file_length != -1) {
			do { 
				rc = ftruncate(params_in->fd, file_length);
			} while ((rc == -1) && (errno == EINTR));
		}

		if (file_length == -1) {
			LOG_WA("%s - lseek error, Could not remove redundant log record, %s",
					__FUNCTION__,strerror(errno));
		} else if (rc == -1) {
			LOG_WA("%s - ftruncate error, Could not remove redundant log record, %s",
					__FUNCTION__,strerror(errno));			
		}
	}
	osaf_mutex_unlock_ordie(&lgs_ftcom_mutex); /* UNLOCK */
 
done:
	TRACE_LEAVE2("rc = %d",rc);
	return rc;
}
Example #11
0
uint32_t mds_lib_req(NCS_LIB_REQ_INFO *req)
{
	char *p_field = NULL;
	uint32_t node_id = 0, cluster_id, mds_tipc_ref = 0;	/* this mds tipc ref is random num part of the TIPC id */
	uint32_t status = NCSCC_RC_SUCCESS;
	NCS_SEL_OBJ destroy_ack_obj;
	char *ptr;

	switch (req->i_op) {
	case NCS_LIB_REQ_CREATE:

		mds_mutex_init_once();
		osaf_mutex_lock_ordie(&gl_mds_library_mutex);

		if (gl_mds_mcm_cb != NULL) {
			syslog(LOG_ERR, "MDS_LIB_CREATE : MDS is already initialized");
			osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
			return NCSCC_RC_FAILURE;
		}

		/* Initialize mcm database */
		mds_mcm_init();

		/* Extract parameters from req and fill adest and pcon_id */

		/* Get Node_id */
		p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "NODE_ID=");
		if (p_field != NULL) {
			if (sscanf(p_field + strlen("NODE_ID="), "%d", &node_id) != 1) {
				syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in NODE_ID argument\n");
				mds_mcm_destroy();
				osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
				return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
			}
		}

		/* Get Cluster_id */
		p_field = NULL;
		p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv,
							    "CLUSTER_ID=");
		if (p_field != NULL) {
			if (sscanf(p_field + strlen("CLUSTER_ID="), "%d", &cluster_id) != 1) {
				syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in CLUSTER_ID argument\n");
				mds_mcm_destroy();
				osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
				return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
			}
		}

		/* Get tipc_mcast_enabled */
		if ((ptr = getenv("MDS_TIPC_MCAST_ENABLED")) != NULL) {
			tipc_mcast_enabled = atoi(ptr);
			if (tipc_mcast_enabled != false)
				tipc_mcast_enabled = true;
				
			m_MDS_LOG_DBG("MDS_TIPC_MCAST_ENABLED: %d  Set argument \n",tipc_mcast_enabled);	
		}

		/*  to use cluster id in mds prefix? */

		/* Get gl_mds_log_level */
		/*  setting MDS_LOG_LEVEL from environment variable if given */
		if ((ptr = getenv("MDS_LOG_LEVEL")) != NULL) {
			gl_mds_log_level = atoi(ptr);
		} else {

			p_field = NULL;
			p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv,
								    "MDS_LOG_LEVEL=");
			if (p_field != NULL) {
				if (sscanf(p_field + strlen("MDS_LOG_LEVEL="), "%d", &gl_mds_log_level) != 1) {
					syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in MDS_LOG_LEVEL argument\n");
					mds_mcm_destroy();
					osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
					return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
				}
			}
		}
		/* gl_mds_log_level consistency check */
		if (gl_mds_log_level > 5 || gl_mds_log_level < 1) {
			/* gl_mds_log_level specified is outside range so reset to Default = 3 */
			gl_mds_log_level = 3;
		}

		/* Get gl_mds_checksum */

		/*  setting MDS_CHECKSUM from environment variable if given */
		if ((ptr = getenv("MDS_CHECKSUM")) != NULL) {
			gl_mds_checksum = atoi(ptr);
		} else {

			p_field = NULL;
			p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv,
								    "MDS_CHECKSUM=");
			if (p_field != NULL) {
				if (sscanf(p_field + strlen("MDS_CHECKSUM="), "%d", &gl_mds_checksum) != 1) {
					syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in MDS_CHECKSUM argument\n");
					mds_mcm_destroy();
					osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
					return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
				}
			}
		}
		/* gl_mds_checksum consistency check */
		if (gl_mds_checksum != 1) {
			/* gl_mds_checksum specified is not 1 so reset to 0 */
			gl_mds_checksum = 0;
		}

	    /*****************************/
		/* Timer value Configuration */
	    /*****************************/

		/* Get Subscription timer value */
		p_field = NULL;
		p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv,
							    "SUBSCRIPTION_TMR_VAL=");
		if (p_field != NULL) {
			if (sscanf(p_field + strlen("SUBSCRIPTION_TMR_VAL="), "%d", &MDS_SUBSCRIPTION_TMR_VAL) != 1) {
				syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in SUBSCRIPTION_TMR_VAL argument\n");
				mds_mcm_destroy();
				osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
				return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
			}
		}

		/* Get Await Active timer value */
		p_field = NULL;
		p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv,
							    "AWAIT_ACTIVE_TMR_VAL=");
		if (p_field != NULL) {
			if (sscanf(p_field + strlen("AWAIT_ACTIVE_TMR_VAL="), "%d", &MDS_AWAIT_ACTIVE_TMR_VAL) != 1) {
				syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in AWAIT_ACTIVE_TMR_VAL argument\n");
				mds_mcm_destroy();
				osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
				return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
			}
		}

		/* Get Quiesced timer value */
		p_field = NULL;
		p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv,
							    "QUIESCED_TMR_VAL=");
		if (p_field != NULL) {
			if (sscanf(p_field + strlen("QUIESCED_TMR_VAL="), "%d", &MDS_QUIESCED_TMR_VAL) != 1) {
				syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in QUIESCED_TMR_VAL argument\n");
				mds_mcm_destroy();
				osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
				return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
			}
		}

		/* Get Reassembly timer value */
		p_field = NULL;
		p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv,
							    "REASSEMBLE_TMR_VAL=");
		if (p_field != NULL) {
			if (sscanf(p_field + strlen("REASSEMBLE_TMR_VAL="), "%d", &MDTM_REASSEMBLE_TMR_VAL) != 1) {
				syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in REASSEMBLE_TMR_VAL argument\n");
				mds_mcm_destroy();
				osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
				return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
			}
		}

		mds_init_transport();
		/* Invoke MDTM-INIT.  */
		status = mds_mdtm_init(node_id, &mds_tipc_ref);
		if (status != NCSCC_RC_SUCCESS) {
			/*  todo cleanup */
			return NCSCC_RC_FAILURE;
		}
		gl_mds_mcm_cb->adest = m_MDS_GET_ADEST_FROM_NODE_ID_AND_PROCESS_ID(node_id, mds_tipc_ref);
		get_adest_details(gl_mds_mcm_cb->adest, gl_mds_mcm_cb->adest_details);	

		/* Initialize logging */
		{
			char buff[50], pref[50];
			snprintf(buff, sizeof(buff), PKGLOGDIR "/mds.log");
			memset(pref, 0 ,sizeof(pref));
			mds_log_init(buff, pref);
		}

		osaf_mutex_unlock_ordie(&gl_mds_library_mutex);

		break;

	case NCS_LIB_REQ_DESTROY:
		/* STEP 1: Invoke MDTM-Destroy. */
		/* mds_mdtm_destroy (); */
		/* STEP 2: Destroy MCM-CB;      */
		/* ncs_patricia_tree_destroy(&gl_mds_mcm_cb->vdest_list); */
		/* m_MMGR_FREE_MDS_CB(gl_mds_mcm_cb); */

		m_NCS_SEL_OBJ_CREATE(&destroy_ack_obj);

		/* Post a dummy message to MDS thread to guarantee that it
		   wakes up (and thereby sees the destroy_ind) */
		if (mds_destroy_event(destroy_ack_obj) == NCSCC_RC_FAILURE) {
			m_NCS_SEL_OBJ_DESTROY(&destroy_ack_obj);
			return NCSCC_RC_FAILURE;
		}
		/* Wait for indication from MDS thread that it is ok to kill it */
		osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(destroy_ack_obj), 70000); /* 70 seconds */
		m_MDS_LOG_DBG("LIB_DESTROY:Destroy ack from MDS thread in 70 s");

		/* Take the lock before killing the thread */
		osaf_mutex_lock_ordie(&gl_mds_library_mutex);

		/* Now two things have happened 
		   (1) MDS thread has acked the destroy-event. So it will do no further things beyound
		   MDS unlock
		   (2) We have obtained MDS-Lock. So, even the un-lock by MDS thead is completed
		   Now we can proceed with the systematic destruction of MDS internal Data */

		/* Free the objects related to destroy-indication. The destroy mailbox event
		   will be automatically freed by MDS processing or during MDS mailbox
		   destruction. Since we will be destroying the MDS-thread, the following 
		   selection-object can no longer be accessed. Hence, it is safe and correct 
		   to destroy it now */
		m_NCS_SEL_OBJ_DESTROY(&destroy_ack_obj);
		memset(&destroy_ack_obj, 0, sizeof(destroy_ack_obj));	/* Destroy info */

		/* Sanity check */
		if (gl_mds_mcm_cb == NULL) {
			syslog(LOG_ERR, "MDS_LIB_DESTROY : MDS is already Destroyed");
			osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
			return NCSCC_RC_FAILURE;
		}

		status = mds_mdtm_destroy();
		if (status != NCSCC_RC_SUCCESS) {
			/*  todo anything? */
		}
		status = mds_mcm_destroy();
		if (status != NCSCC_RC_SUCCESS) {
			/*  todo anything? */
		}

		/* Just Unlock the lock, Lock is never destroyed */
		osaf_mutex_unlock_ordie(&gl_mds_library_mutex);
		break;

	default:
		break;
	}

	return NCSCC_RC_SUCCESS;
}
Example #12
0
/**
 * Handler for mds register requests
 * Note: executed by and in context of the auth thread!
 * Communicates with the main thread (where the
 * real work is done) to get outcome of initialization request which is then
 * sent back to the client.
 * @param fd
 * @param creds credentials for client
 */
static void mds_register_callback(int fd, const struct ucred *creds)
{
	uint8_t buf[32];
	uint8_t *p = buf;

	TRACE_ENTER2("fd:%d, pid:%u", fd, creds->pid);

	int n = recv(fd, buf, sizeof(buf), 0);
	if (n == -1) {
		syslog(LOG_ERR, "%s: recv failed - %s", __FUNCTION__, strerror(errno));
		goto done;
	}

	if (n != 16) {
		syslog(LOG_ERR, "%s: recv failed - %d bytes", __FUNCTION__, n);
		goto done;
	}

	int type = ncs_decode_32bit(&p);

	NCSMDS_SVC_ID svc_id = ncs_decode_32bit(&p);
	MDS_DEST mds_dest = ncs_decode_64bit(&p);

	TRACE("mds: received %d from %"PRIx64", pid %d", type, mds_dest, creds->pid);

	if (type == MDS_REGISTER_REQ) {
		osaf_mutex_lock_ordie(&gl_mds_library_mutex);

		MDS_PROCESS_INFO *info = mds_process_info_get(mds_dest, svc_id);
		if (info == NULL) {
			MDS_PROCESS_INFO *info = calloc(1, sizeof(MDS_PROCESS_INFO));
			osafassert(info);
			info->mds_dest = mds_dest;
			info->svc_id = svc_id;
			info->uid = creds->uid;
			info->pid = creds->pid;
			info->gid = creds->gid;
			int rc = mds_process_info_add(info);
			osafassert(rc == NCSCC_RC_SUCCESS);
		} else {
			/* when can this happen? */
			LOG_NO("%s: dest %"PRIx64" already exist", __FUNCTION__, mds_dest);

			// just update credentials
			info->uid = creds->uid;
			info->pid = creds->pid;
			info->gid = creds->gid;
		}

		osaf_mutex_unlock_ordie(&gl_mds_library_mutex);

		p = buf;
		uint32_t sz = ncs_encode_32bit(&p, MDS_REGISTER_RESP);
		sz += ncs_encode_32bit(&p, 0); // result OK

		if ((n = send(fd, buf, sz, 0)) == -1)
			syslog(LOG_ERR, "%s: send to pid %d failed - %s",
					__FUNCTION__, creds->pid, strerror(errno));
	} else if (type == MDS_UNREGISTER_REQ) {
		osaf_mutex_lock_ordie(&gl_mds_library_mutex);

		MDS_PROCESS_INFO *info = mds_process_info_get(mds_dest, svc_id);
		if (info != NULL) {
			(void)mds_process_info_del(info);
		}
		osaf_mutex_unlock_ordie(&gl_mds_library_mutex);

		p = buf;
		uint32_t sz = ncs_encode_32bit(&p, MDS_UNREGISTER_RESP);
		sz += ncs_encode_32bit(&p, 0);  // result OK

		if ((n = send(fd, buf, sz, 0)) == -1)
			syslog(LOG_ERR, "%s: send to pid %d failed - %s",
					__FUNCTION__, creds->pid, strerror(errno));
	} else {
		syslog(LOG_ERR, "%s: recv failed - wrong type %d", __FUNCTION__, type);
		goto done;
	}

done:
	TRACE_LEAVE();
}
Example #13
0
/***************************************************************************
 *
 * ncs_os_process_execute_timed
 *
 * Description: To execute a module in a new process with time-out.
 *
 * Synopsis:
 *
 * Call Arguments:
 *   req - Request parameters.
 *
 * Returns:
 *   Success or failure
 *
 * Notes:
 *
 **************************************************************************/
uint32_t ncs_os_process_execute_timed(NCS_OS_PROC_EXECUTE_TIMED_INFO *req)
{
	int count;
	int pid;
	NCS_OS_ENVIRON_SET_NODE *node = NULL;

	if ((req->i_script == NULL) || (req->i_cb == NULL))
		return NCSCC_RC_FAILURE;

	if (req->i_set_env_args == NULL)
		count = 0;
	else {
		count = req->i_set_env_args->num_args;
		node = req->i_set_env_args->env_arg;
	}

	m_NCS_LOCK(&module_cb.tree_lock, NCS_LOCK_WRITE);

	if (module_cb.init != true) {
		/* this will initializes the execute module control block */
		if (start_exec_mod_cb() != NCSCC_RC_SUCCESS) {
			m_NCS_UNLOCK(&module_cb.tree_lock, NCS_LOCK_WRITE);
			syslog(LOG_ERR, "%s: start_exec_mod_cb failed", __FUNCTION__);
			return NCSCC_RC_FAILURE;
		}
	}

	osaf_mutex_lock_ordie(&s_cloexec_mutex);

	if ((pid = fork()) == 0) {
		/*
		 ** Make sure forked processes have default scheduling class
		 ** independent of the callers scheduling class.
		 */
		struct sched_param param = {.sched_priority = 0 };
		if (sched_setscheduler(0, SCHED_OTHER, &param) == -1)
			syslog(LOG_ERR, "%s: Could not setscheduler: %s", __FUNCTION__, strerror(errno));

		/* set the environment variables */
		for (; count > 0; count--) {
			setenv(node->name, node->value, node->overwrite);
			node++;
		}

		/* By default we close all inherited file descriptors in the child */
		if (getenv("OPENSAF_KEEP_FD_OPEN_AFTER_FORK") == NULL) {
			/* Close all inherited file descriptors */
			int i = sysconf(_SC_OPEN_MAX);
			if (i == -1) {
				syslog(LOG_ERR, "%s: sysconf failed - %s", __FUNCTION__, strerror(errno));
				exit(EXIT_FAILURE);
			}
			for (i--; i >= 0; --i)
				(void) close(i); /* close all descriptors */

			/* Redirect standard files to /dev/null */
			if (freopen("/dev/null", "r", stdin) == NULL)
				syslog(LOG_ERR, "%s: freopen stdin failed - %s", __FUNCTION__, strerror(errno));
			if (freopen("/dev/null", "w", stdout) == NULL)
				syslog(LOG_ERR, "%s: freopen stdout failed - %s", __FUNCTION__, strerror(errno));
			if (freopen("/dev/null", "w", stderr) == NULL)
				syslog(LOG_ERR, "%s: freopen stderr failed - %s", __FUNCTION__, strerror(errno));
		}

		/* RUNASROOT gives the OpenSAF user a possibility to maintain the < 4.2 behaviour.
		 * For example the UML environment needs this because of its simplified user management.
		 * OpenSAF processes will otherwise be started as the real host user and will
		 * have problems e.g. writing PID files to the root owned directory.
		 */
#ifndef RUNASROOT
		/* Check owner user ID of file and change group and user accordingly */
		{
			struct stat buf;
			if (stat(req->i_script, &buf) == 0) {
				if (setgid(buf.st_gid) == -1)
					syslog(LOG_ERR, "setgid %u failed - %s", buf.st_gid, strerror(errno));
				if (setuid(buf.st_uid) == -1)
					syslog(LOG_ERR, "setuid %u failed - %s", buf.st_uid, strerror(errno));
			} else {
				syslog(LOG_ERR, "Could not stat %s - %s", req->i_script, strerror(errno));
				exit(128);
			}
		}
#endif

		/* child part */
		if (execvp(req->i_script, req->i_argv) == -1) {
			syslog(LOG_ERR, "%s: execvp '%s' failed - %s", __FUNCTION__, req->i_script, strerror(errno));
			exit(128);
		}
	} else if (pid > 0) {
		/* 
		 * Parent - Add new pid in the tree,
		 * start a timer, Wait for a signal from child. 
		 */
		osaf_mutex_unlock_ordie(&s_cloexec_mutex);

		if (NCSCC_RC_SUCCESS != add_new_req_pid_in_list(req, pid)) {
			m_NCS_UNLOCK(&module_cb.tree_lock, NCS_LOCK_WRITE);
			syslog(LOG_ERR, "%s: failed to add PID", __FUNCTION__);
			return NCSCC_RC_FAILURE;
		}
	} else {
		/* fork ERROR */
		syslog(LOG_ERR, "%s: fork failed - %s", __FUNCTION__, strerror(errno));
		osaf_mutex_unlock_ordie(&s_cloexec_mutex);
		m_NCS_UNLOCK(&module_cb.tree_lock, NCS_LOCK_WRITE);
		return NCSCC_RC_FAILURE;
	}

	m_NCS_UNLOCK(&module_cb.tree_lock, NCS_LOCK_WRITE);
	return NCSCC_RC_SUCCESS;
}