Beispiel #1
0
int main(int argc, char *argv[])
{
	int c;
	struct option long_options[] = {
		{"disable-tryagain", no_argument, 0, 'd'},
		{"parameter", required_argument, 0, 'p'},
		{"operation-id", required_argument, 0, 'o'},
		{"operation-name", required_argument, 0, 'O'},
		{"admin-owner", required_argument, 0, 'a'},
		{"help", no_argument, 0, 'h'},
		{"timeout", required_argument, 0, 't'},
		{"verbose", no_argument, 0, 'v'},
		{0, 0, 0, 0}
	};
	SaAisErrorT error;
	SaImmHandleT immHandle;
	SaImmAdminOwnerNameT adminOwnerName = basename(argv[0]);
	bool releaseAdmo=true;
	bool explicitAdmo=false;
	SaImmAdminOwnerHandleT ownerHandle;
	SaNameT objectName;
	const SaNameT *objectNames[] = { &objectName, NULL };
	SaAisErrorT operationReturnValue = -1;
	SaImmAdminOperationParamsT_2 *param;
	const SaImmAdminOperationParamsT_2 **params;
	SaImmAdminOperationParamsT_2 **out_params=NULL;
	SaImmAdminOperationIdT operationId = -1;
	unsigned long timeoutVal = 60;  /* Default timeout value */
	int disable_tryagain = false;
	int isFirst = 1;
	int verbose = 0;

	int params_len = 0;

	/* Support for long DN */
	setenv("SA_ENABLE_EXTENDED_NAMES", "1", 1);
	/* osaf_extended_name_init() is added to prevent future safe use of
	 * osaf_extended_name_* before saImmOmInitialize and saImmOiInitialize */
	osaf_extended_name_init();

	params = realloc(NULL, sizeof(SaImmAdminOperationParamsT_2 *));
	params[0] = NULL;
	SaStringT opName = NULL;

	while (1) {
		c = getopt_long(argc, argv, "dp:o:O:a:t:hv", long_options, NULL);

		if (c == -1)	/* have all command-line options have been parsed? */
			break;

		switch (c) {
		case 'd':
			disable_tryagain = true;
			break;
		case 'o':
			if(operationId != -1) {
				fprintf(stderr, "Cannot set admin operation more then once");
				exit(EXIT_FAILURE);
			}
			operationId = strtoll(optarg, (char **)NULL, 10);
			if ((operationId == 0) && ((errno == EINVAL) || (errno == ERANGE))) {
				fprintf(stderr, "Illegal operation ID\n");
				exit(EXIT_FAILURE);
			}
			break;
		case 'O':
			if(operationId != -1) {
				fprintf(stderr, "Cannot set admin operation more then once");
				exit(EXIT_FAILURE);
			}
			operationId = SA_IMM_PARAM_ADMOP_ID_ESC;
			params_len++;
			params = realloc(params, (params_len + 1) * sizeof(SaImmAdminOperationParamsT_2 *));
			param = malloc(sizeof(SaImmAdminOperationParamsT_2));
			params[params_len - 1] = param;
			params[params_len] = NULL;
			param->paramName = strdup(SA_IMM_PARAM_ADMOP_NAME);
			param->paramType = SA_IMM_ATTR_SASTRINGT;
			param->paramBuffer = malloc(sizeof(SaStringT));
			*((SaStringT *)(param->paramBuffer)) = strdup(optarg);
			opName = strdup(optarg);
			break;
		case 'p':
			params_len++;
			params = realloc(params, (params_len + 1) * sizeof(SaImmAdminOperationParamsT_2 *));
			param = malloc(sizeof(SaImmAdminOperationParamsT_2));
			params[params_len - 1] = param;
			params[params_len] = NULL;
			if (init_param(param, optarg) == -1) {
				fprintf(stderr, "Illegal parameter: %s\n", optarg);
				exit(EXIT_FAILURE);
			}
			break;
		case 't':
			timeoutVal = strtoll(optarg, (char **)NULL, 10);

			if ((timeoutVal == 0) || (errno == EINVAL) || (errno == ERANGE)) {
				fprintf(stderr, "Illegal timeout value\n");
				exit(EXIT_FAILURE);
			}
			break;
		case 'a':
			adminOwnerName = (SaImmAdminOwnerNameT)malloc(strlen(optarg) + 1);
			strcpy(adminOwnerName, optarg);
			releaseAdmo=false;
			explicitAdmo=true;
			break;
		case 'h':
			usage(basename(argv[0]));
			exit(EXIT_SUCCESS);
			break;
		case 'v':
			verbose = 1;
			break;
		default:
			fprintf(stderr, "Try '%s --help' for more information\n", argv[0]);
			exit(EXIT_FAILURE);
			break;
		}
	}

	if (operationId == -1) {
		fprintf(stderr, "error - must specify admin operation ID %llx\n", operationId);
		exit(EXIT_FAILURE);
	}

	/* Need at least one object to operate on */
	if ((argc - optind) == 0) {
		fprintf(stderr, "error - wrong number of arguments\n");
		exit(EXIT_FAILURE);
	}

	signal(SIGALRM, sigalarmh);
	(void) alarm(timeoutVal);

	immutilWrapperProfile.errorsAreFatal = 0;
	immutilWrapperProfile.nTries = disable_tryagain ? 0 : timeoutVal;
	immutilWrapperProfile.retryInterval = 1000;

	error = immutil_saImmOmInitialize(&immHandle, NULL, &immVersion);
	if (error != SA_AIS_OK) {
		fprintf(stderr, "error - saImmOmInitialize FAILED: %s\n", saf_error(error));
		exit(EXIT_FAILURE);
	}

	if((optind < argc) && (!explicitAdmo)) {
		saAisNameLend(argv[optind], &objectName);

		if(strcmp(saAisNameBorrow(&objectName), OPENSAF_IMM_OBJECT_DN)==0) {
			releaseAdmo=false;
			adminOwnerName = (SaImmAdminOwnerNameT) malloc(strlen(OPENSAF_IMM_SERVICE_NAME) + 1);
			strcpy(adminOwnerName, OPENSAF_IMM_SERVICE_NAME);
			printf("[using admin-owner: '%s']\n", adminOwnerName);
		}
	}

	error = immutil_saImmOmAdminOwnerInitialize(immHandle, adminOwnerName, releaseAdmo?SA_TRUE:SA_FALSE, &ownerHandle);
	if (error != SA_AIS_OK) {
		fprintf(stderr, "error - saImmOmAdminOwnerInitialize FAILED: %s\n", saf_error(error));
		exit(EXIT_FAILURE);
	}

	/* Remaining arguments should be object names on which the admin op should be performed. */
	while (optind < argc) {
		saAisNameLend(argv[optind], &objectName);

		error = immutil_saImmOmAdminOwnerSet(ownerHandle, objectNames, SA_IMM_ONE);
		if (error != SA_AIS_OK) {
			if (error == SA_AIS_ERR_NOT_EXIST) {
				if(strcmp(adminOwnerName, saAisNameBorrow(&objectName))==0) {
					/* AdminOwnerName == ImplementerName - Could be direct admin-op on OI */
					goto retry;
				}
				fprintf(stderr, "error - saImmOmAdminOwnerSet - object '%s' does not exist\n",
					saAisNameBorrow(&objectName));
			}
			else
				fprintf(stderr, "error - saImmOmAdminOwnerSet FAILED: %s\n", saf_error(error));
			exit(EXIT_FAILURE);
		}
retry:
		error = immutil_saImmOmAdminOperationInvoke_o2(ownerHandle, &objectName, 0, operationId,
			params, &operationReturnValue, SA_TIME_ONE_SECOND * timeoutVal, &out_params);

		if (error != SA_AIS_OK) {
			fprintf(stderr, "error - saImmOmAdminOperationInvoke_2 FAILED: %s\n",
				saf_error(error));
			exit(EXIT_FAILURE);
		}

		if (operationReturnValue != SA_AIS_OK ) {
			unsigned int ix = 0;

			if ((operationReturnValue == SA_AIS_ERR_TRY_AGAIN) && !disable_tryagain) {
				sleep(1);
				goto retry;
			}

			fprintf(stderr, "error - saImmOmAdminOperationInvoke_2 admin-op RETURNED: %s\n",
				saf_error(operationReturnValue));
			
			while(out_params && out_params[ix]) {
				if(strcmp(out_params[ix]->paramName, SA_IMM_PARAM_ADMOP_ERROR) == 0) {
					assert(out_params[ix]->paramType == SA_IMM_ATTR_SASTRINGT);
					SaStringT errStr = (*((SaStringT *) out_params[ix]->paramBuffer));
					fprintf(stderr, "error-string: %s\n", errStr);
				}
				++ix;
			}

			/* After printing error string, print all returned parameters */
			if (verbose && out_params && out_params[0]) {
				if(!isFirst)
					printf("\n");

				print_params(argv[optind], out_params);
			}
			

			exit(EXIT_FAILURE);
		}


		if (((opName && (strncmp(opName,"display",7)==0))||verbose) &&out_params && out_params[0]) {
			if(!isFirst)
				printf("\n");
			else
				isFirst = 0;

			print_params(argv[optind], out_params);
		}


		error = saImmOmAdminOperationMemoryFree(ownerHandle, out_params);
		if (error != SA_AIS_OK) {
			fprintf(stderr, "error - saImmOmAdminOperationMemoryFree FAILED: %s\n", saf_error(error));
			exit(EXIT_FAILURE);
		}

		if(releaseAdmo) {
			error = immutil_saImmOmAdminOwnerRelease(ownerHandle, objectNames, SA_IMM_ONE);
			if (error != SA_AIS_OK) {
				fprintf(stderr, "error - saImmOmAdminOwnerRelease FAILED: %s\n", saf_error(error));
				exit(EXIT_FAILURE);
			}
		}

		optind++;
	}

	error = immutil_saImmOmAdminOwnerFinalize(ownerHandle);
	if (SA_AIS_OK != error) {
		fprintf(stderr, "error - saImmOmAdminOwnerFinalize FAILED: %s\n", saf_error(error));
		exit(EXIT_FAILURE);
	}

	error = immutil_saImmOmFinalize(immHandle);
	if (SA_AIS_OK != error) {
		fprintf(stderr, "error - saImmOmFinalize FAILED: %s\n", saf_error(error));
		exit(EXIT_FAILURE);
	}

	exit(EXIT_SUCCESS);
}
/**
 * Forever wait on events and process them.
 */
static void main_process(void)
{
	NCS_SEL_OBJ mbx_fd;
	SaAisErrorT error = SA_AIS_OK;

	TRACE_ENTER();

	/*
	  The initialization of the IMM OM handle below is done to use a feature in the
	  IMM implementation. As long as one handle is initialized, IMM will not release the 
	  MDS subscription just reused it for new handles.
	  When SMF uses SmfImmUtils new handles are created and released during the execution.
	  If the campaign is big the MDS system limit of max number of subscriptions may be exceeded
	  i.e. "ERR    |MDTM: SYSTEM has crossed the max =500 subscriptions"
	  The code below will ensure there is always one IMM OM handle initialized.
	*/
	SaImmHandleT omHandle;
	SaVersionT immVersion = { 'A', 2, 1 };
	SaAisErrorT rc = immutil_saImmOmInitialize(&omHandle, NULL, &immVersion);
	if (rc != SA_AIS_OK) {
		LOG_ER("immutil_saImmOmInitialize faild, rc = %d", rc);
		return;
	}
	/* end of IMM featue code */

	mbx_fd = ncs_ipc_get_sel_obj(&smfd_cb->mbx);

	/* Set up all file descriptors to listen to */
	if (smfd_cb->nid_started)
		fds[SMFD_AMF_FD].fd = smfd_cb->usr1_sel_obj.rmv_obj;
	else
		fds[SMFD_AMF_FD].fd = smfd_cb->amfSelectionObject;

	fds[SMFD_AMF_FD].events = POLLIN;
	fds[SMFD_MBX_FD].fd = mbx_fd.rmv_obj;
	fds[SMFD_MBX_FD].events = POLLIN;
	fds[SMFD_COI_FD].fd = smfd_cb->campaignSelectionObject;
	fds[SMFD_COI_FD].events = POLLIN;

	while (1) {

		if (smfd_cb->campaignOiHandle != 0) {
			fds[SMFD_COI_FD].fd = smfd_cb->campaignSelectionObject;
			fds[SMFD_COI_FD].events = POLLIN;
			nfds = SMFD_MAX_FD;
		} else {
			nfds = SMFD_MAX_FD -1 ;
		}
		
		int ret = poll(fds, nfds, -1);

		if (ret == -1) {
			if (errno == EINTR)
				continue;

			LOG_ER("poll failed - %s", strerror(errno));
			break;
		}

		/* Process all the AMF messages */
		if (fds[SMFD_AMF_FD].revents & POLLIN) {
			if (smfd_cb->amf_hdl != 0) {
				/* dispatch all the AMF pending function */
				if ((error =
				     saAmfDispatch(smfd_cb->amf_hdl,
						   SA_DISPATCH_ALL)) !=
				    SA_AIS_OK) {
					LOG_ER("saAmfDispatch failed: %u",
					       error);
					break;
				}
			} else {
				TRACE("SIGUSR1 event rec");

				if (smfd_amf_init(smfd_cb) != NCSCC_RC_SUCCESS) {
					LOG_ER("init amf failed");
					break;
				}

				TRACE("AMF Initialization SUCCESS......");
				fds[SMFD_AMF_FD].fd =
				    smfd_cb->amfSelectionObject;
			}
		}

		/* Process all the Mail box events */
		if (fds[SMFD_MBX_FD].revents & POLLIN) {
			/* dispatch all the MBX events */
			smfd_process_mbx(&smfd_cb->mbx);
		}

		/* Process all the Imm callback events */
		if (fds[SMFD_COI_FD].revents & POLLIN) {
			if ((error =
			     saImmOiDispatch(smfd_cb->campaignOiHandle,
					     SA_DISPATCH_ALL)) != SA_AIS_OK) {
				/*
				 ** BAD_HANDLE is interpreted as an IMM service restart. Try
				 ** reinitialize the IMM OI API in a background thread and let
				 ** this thread do business as usual especially handling write
				 ** requests.
				 **
				 ** All other errors are treated as non-recoverable (fatal) and will
				 ** cause an exit of the process.
				 */
				if (error == SA_AIS_ERR_BAD_HANDLE) {
					TRACE("main: saImmOiDispatch returned BAD_HANDLE");

					/*
					 ** Invalidate the IMM OI handle, this info is used in other
					 ** locations. E.g. giving TRY_AGAIN responses to a create and
					 ** close app stream requests. That is needed since the IMM OI
					 ** is used in context of these functions.
					 */
					saImmOiFinalize(smfd_cb->campaignOiHandle );
					smfd_cb->campaignOiHandle = 0;

					/* Initiate IMM reinitializtion in the background */
					smfd_coi_reinit_bg(smfd_cb);
					

				} else if (error != SA_AIS_OK) {
					LOG_ER("main: saImmOiDispatch FAILED %u", error);
					break;
				}
			}
		}
	}

	rc = immutil_saImmOmAdminOwnerFinalize(omHandle);
	if (rc != SA_AIS_OK) {
		LOG_ER("immutil_saImmOmAdminOwnerFinalize faild, rc = %d", rc);
	}
}