Beispiel #1
0
static cfga_err_t
ap_suspend_check(apd_t *a, int cmd, int first, int last, int *suspend)
{
	int c;
	int rc;
	int skip;
	int check;

	skip = a->opts.skip;

	/*
	 * Check if any of the steps in the sequence
	 * may require a suspension of service and ask
	 * the user to confirm.
	 */
	for (check = 0, c = first; c <= last; c++)
		if (mask(c) & skip)
			continue;
		else if ((rc = ap_suspend_query(a, c, &check)) != CFGA_OK)
			return (rc);

	*suspend = check;

	/*
	 * If a suspend is required, ask for user confirmation.
	 * The force flag overrides the user confirmation.
	 */
	if (check && (!ap_getopt(a, OPT_FORCE)) && (!ap_confirm(a))) {
		ap_err(a, ERR_CMD_NACK, cmd);
		return (CFGA_NACK);
	}

	return (CFGA_OK);
}
Beispiel #2
0
cfga_err_t
ap_rcm_ctl(apd_t *a, int cmd)
{
	int i;
	int rv;
	int noop;
	int ncpus;
	int cm;
	uint_t flags;
	char *rsrc;
	char **rlist;
	rcmd_t *rcm;
	rcm_info_t *rinfo;
	rcm_handle_t *hd;
	cfga_err_t rc;
	cpuid_t *growcpuids;

	DBG("ap_rcm_ctl(%p)\n", (void *)a);

	if ((rcm = (rcmd_t *)a->rcm) == NULL) {
		ap_msg(a, MSG_SKIP, cmd, a->target);
		return (CFGA_OK);
	}

	hd = rcm->hd;
	rv = RCM_SUCCESS;
	rc = CFGA_OK;
	if (ap_getopt(a, OPT_FORCE))
		flags = RCM_FORCE;
	else
		flags = 0;
	rinfo = NULL;
	rlist = NULL;
	rsrc = NULL;
	noop = 0;

	switch (cmd) {
	case CMD_RCM_CAP_DEL:
		if (rcm->capinfo == NULL)
			noop++;
		else
			rc = ap_rcm_request_cap(a, rcm, hd, &rv, flags, &rinfo);
		break;
	case CMD_RCM_CAP_ADD:
		rc = ap_rcm_add_cap(a, rcm, hd, &rv, flags, &rinfo);
		break;
	case CMD_RCM_CAP_NOTIFY:
		rc = ap_rcm_notify_cap(a, rcm, hd, &rv, flags, &rinfo);
		break;
	case CMD_RCM_ONLINE:
		/* Refresh changed component states */
		if ((rc = ap_stat(a, 1)) != CFGA_OK) {
			noop++;
			break;
		}

		if (a->tgt == AP_BOARD) {
			rcm->firstcm = 0;
			rcm->lastcm = a->ncm - 1;

			/* Check if we need to grow our cpuids list */
			for (ncpus = 0, cm = rcm->firstcm; cm <= rcm->lastcm;
			    cm++) {
				ap_target_t type = ap_cm_type(a, cm);
				if ((type == AP_CPU) || (type == AP_CMP))
					ncpus += ap_cm_ncap(a, cm);
			}

			if (rcm->ncpus < ncpus) {
				if ((growcpuids =
				    (cpuid_t *)realloc(rcm->cpuids,
				    (ncpus * sizeof (cpuid_t)))) == NULL) {
					ap_err(a, ERR_NOMEM);
					return (CFGA_LIB_ERROR);
				}
				rcm->ncpus = ncpus;
				rcm->cpuids = growcpuids;
			}

		} else {
			rcm->firstcm = CM_DFLT;
			rcm->lastcm = CM_DFLT;
		}

		/*FALLTHROUGH*/

	case CMD_RCM_OFFLINE:
	case CMD_RCM_REMOVE: {
		uint_t nrsrc;

		if (cmd == CMD_RCM_REMOVE) {
			/*
			 * An unconfigure has just taken place, so
			 * refresh the changed component states.
			 */
			if ((rc = ap_stat(a, 1)) != CFGA_OK) {
				noop++;
				break;
			}
		}

		/* Check if this is an empty board, i.e. no components */
		if (a->ncm == 0) {
			noop++;
			break;
		}

		if ((rlist = rcm->rlist) == NULL) {
			rc = ap_rcm_rlist(a, rcm->firstcm, rcm->lastcm, &rlist,
			    cmd);
			if ((rc == CFGA_OK) && (rlist != NULL) &&
			    (rlist[0] != NULL)) {
				rcm->rlist = rlist;
			} else {
				/* Do not pass up empty resource list to RCM */
				noop++;
				break;
			}
		}
		for (nrsrc = 0; rlist[nrsrc] != NULL; nrsrc++)
			ap_msg(a, MSG_ISSUE, cmd, rlist[nrsrc]);
		if (cmd == CMD_RCM_OFFLINE)
			rv = (*rcm->request_offline_list)(hd, rlist, flags,
			    &rinfo);
		else if (cmd == CMD_RCM_ONLINE)
			rv = (*rcm->notify_online_list)(hd, rlist,
			    flags & ~RCM_FORCE, &rinfo);
		else
			rv = (*rcm->notify_remove_list)(hd, rlist,
			    flags & ~RCM_FORCE, &rinfo);
		break;
	}
	case CMD_RCM_SUSPEND: {
		timespec_t t;
		t.tv_sec = (time_t)0;
		t.tv_nsec = (long)0;
		rsrc = OS;
		ap_msg(a, MSG_ISSUE, cmd, rsrc);
		rv = (*rcm->request_suspend)(hd, rsrc, flags, &t, &rinfo);
		break;
	}
	case CMD_RCM_RESUME:
		rsrc = OS;
		ap_msg(a, MSG_ISSUE, cmd, rsrc);
		rv = (*rcm->notify_resume)(hd, rsrc, 0, &rinfo);
		break;
	default:
		ap_err(a, ERR_CMD_INVAL, cmd);
		return (CFGA_INVAL);
	}

	if (rv != RCM_SUCCESS) {
		rcm->rinfo = rinfo;
		rcm->infot = NULL;
		ap_err(a, ERR_RCM_CMD, cmd);
		(*rcm->free_info)(rinfo);
		if (rc == CFGA_OK)
			rc = CFGA_LIB_ERROR;	/* make sure error is set */
	}
	if ((rc == CFGA_OK) && (noop == 0)) {
		if (rlist)
			for (i = 0; rlist[i]; i++)
				ap_msg(a, MSG_DONE, cmd, rlist[i]);
		else if (rsrc)
			ap_msg(a, MSG_DONE, cmd, rsrc);
		else
			ap_msg(a, MSG_DONE, cmd, a->target);
	}

	return (rc);
}
Beispiel #3
0
cfga_err_t
ap_seq_exec(apd_t *a, int cmd, int first, int last)
{
	int c;
	int skip;
	int suspend;
	int resume;
	cfga_err_t rc;
	int recover_f = CMD_NONE;	/* first recovery cmd */
	int recover_l = CMD_NONE;	/* last recovery cmd */


	suspend = 0;
	resume = 0;

	skip = a->opts.skip;

	/*
	 * The unassign step is skipped unless explicity requested
	 * either by a -x request or as an option to a disconnect
	 * request.
	 */
	if (cmd != CMD_UNASSIGN && ap_getopt(a, OPT_UNASSIGN) == 0)
		skip |= mask(CMD_UNASSIGN);

	/*
	 * Check for platform options
	 */
	rc = ap_platopts_check(a, first, last);

	if (rc != CFGA_OK) {
		goto done;
	}

	for (c = first; c <= last; c++) {
		if (mask(c) & skip) {
			ap_msg(a, MSG_SKIP, c, a->target);
			continue;
		}

		DBG("exec %s\n", ap_cmd_name(c));

		/*
		 * If the suspend operation does not
		 * succeed, resume any devices already
		 * suspended as well as the device on
		 * which the operation failed.
		 */
		switch (c) {
		case CMD_SUSPEND_CHECK:
			/*
			 * Check whether the user allows a suspend
			 * operation if the suspend is required.
			 * Next step is to allow RCM clients to
			 * interpose on the suspend operation.
			 */
			rc = ap_suspend_check(a, cmd,
			    first + 1, last, &suspend);
			break;
		case CMD_RCM_SUSPEND:
			if (suspend && ((rc = ap_rcm_ctl(a, c)) == CFGA_OK)) {
				/*
				 * Mark the fact that a suspend operation
				 * is required, and that RCM clients have
				 * allowed the suspend.
				 */
				ap_setopt(a, OPT_SUSPEND_OK);
				resume++;
			}
			break;
		case CMD_RCM_RESUME:
			if (resume) {
				(void) ap_rcm_ctl(a, c);
				resume--;
			}
			break;
		case CMD_RCM_OFFLINE:
		case CMD_RCM_CAP_DEL:
			rc = ap_rcm_ctl(a, c);
			break;
		case CMD_RCM_ONLINE:
		case CMD_RCM_CAP_ADD:
		case CMD_RCM_REMOVE:
		case CMD_RCM_CAP_NOTIFY:
			(void) ap_rcm_ctl(a, c);
			break;

#ifdef	__x86
		/*
		 * Disable fast reboot if a CPU/MEM/IOH hotplug event happens.
		 * Note: this is a temporary solution and will be revised when
		 * fast reboot can support CPU/MEM/IOH DR operations in the
		 * future.
		 *
		 * ACPI BIOS generates some static ACPI tables, such as MADT,
		 * SRAT and SLIT, to describe the system hardware configuration
		 * on power-on. When a CPU/MEM/IOH hotplug event happens, those
		 * static tables won't be updated and will become stale.
		 *
		 * If we reset the system by fast reboot, BIOS will have no
		 * chance to regenerate those staled static tables. Fast reboot
		 * can't tolerate such inconsistency between staled ACPI tables
		 * and real hardware configuration yet.
		 *
		 * A temporary solution is introduced to disable fast reboot if
		 * CPU/MEM/IOH hotplug event happens. This solution should be
		 * revised when fast reboot is enhanced to support CPU/MEM/IOH
		 * DR operations.
		 */
		case CMD_ASSIGN:
		case CMD_POWERON:
		case CMD_POWEROFF:
		case CMD_UNASSIGN:
			if (!fastreboot_disabled &&
			    scf_fastreboot_default_set_transient(B_FALSE) ==
			    SCF_SUCCESS) {
				fastreboot_disabled = 1;
			}
			/* FALLTHROUGH */
#endif	/* __x86 */

		default:
			rc = ap_ioctl(a, c);
			break;
		}

		if (rc != CFGA_OK)
			break;

	}
done:

	if (resume)
		(void) ap_rcm_ctl(a, CMD_RCM_RESUME);

	/*
	 * Check if any operations failed. If so, attempt to rollback
	 * to previously known states.
	 * Note: The rollback is currently limited to RCM operations.
	 */
	if (rc != CFGA_OK) {
		if (c == CMD_UNCONFIGURE ||
		    c == CMD_RCM_OFFLINE ||
		    c == CMD_RCM_CAP_DEL) {
			DBG("ap_seq_exec: %s failed\n", ap_cmd_name(c));

			switch (c) {
			case CMD_UNCONFIGURE:
				/*
				 * If the unconfigure operation fails, perform
				 * an RCM_ONLINE and RCM_CAP_NOTIFY only. This
				 * keeps RCM clients consistent with the domain.
				 */
				recover_f = CMD_RCM_ONLINE;
				recover_l = CMD_RCM_ONLINE;
				DBG_RECOVER_MSG(recover_f, recover_l);
				(void) ap_seq_exec(a, cmd, recover_f,
				    recover_l);

				recover_f = CMD_RCM_CAP_NOTIFY;
				recover_l = CMD_RCM_CAP_NOTIFY;
				DBG_RECOVER_MSG(recover_f, recover_l);
				(void) ap_seq_exec(a, cmd, recover_f,
				    recover_l);
				break;
			case CMD_RCM_OFFLINE:
				recover_f = CMD_RCM_ONLINE;
				recover_l = CMD_RCM_CAP_ADD;
				DBG_RECOVER_MSG(recover_f, recover_l);
				(void) ap_seq_exec(a, cmd, recover_f,
				    recover_l);
				break;
			case CMD_RCM_CAP_DEL:
				recover_f = CMD_RCM_CAP_ADD;
				recover_l = CMD_RCM_CAP_ADD;
				DBG_RECOVER_MSG(recover_f, recover_l);
				(void) ap_seq_exec(a, cmd, recover_f,
				    recover_l);
				break;
			default:
				break;
			}

			DBG("recovery complete!\n");
		}
	}
	return (rc);
}
Beispiel #4
0
int main(int argc, char* argv[])
{
	LPVOID lpMsgBuf;
	char *filelist=NULL, *environment=NULL, *module=NULL;
	int c = NULL;
	while ((c=ap_getopt(argc, argv, OPTSTRING))!=-1) {
		switch (c) {
			case 'd':
				bUseTestFiles = TRUE;
				filelist = strdup(ap_optarg);
				break;
			case 'f':
				bUseTestFiles = FALSE;
				filelist = strdup(ap_optarg);
				break;
			case 'e':
				environment = strdup(ap_optarg);
				break;
			case 't':
				numThreads = atoi(ap_optarg);
				break;
			case 'i':
				iterations = atoi(ap_optarg);
				break;
			case 'm':
				module = strdup(ap_optarg);
				break;
			case 'h':
				_usage(argv[0]);
				exit(0);
				break;
		}
	}
	if (!module || !filelist) {
		_usage(argv[0]);
		exit(0);
	}

	GetTempPath(sizeof(temppath), temppath);
	hDll = LoadLibrary(module); // Load our DLL

	if (!hDll) {
		FormatMessage( 
		   FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
		    NULL,
		    GetLastError(),
		    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		    (LPTSTR) &lpMsgBuf,
		    0,
		    NULL 
		);
		fprintf(stderr,"Error: Dll 'php5isapi.dll' not found -%d\n%s\n", GetLastError(), lpMsgBuf);
		free (module);
		free(filelist);
		LocalFree( lpMsgBuf );
		return -1;
	}

	//
	// Find the exported functions

	IsapiGetExtensionVersion = (VersionProc)GetProcAddress(hDll,"GetExtensionVersion");
	if (!IsapiGetExtensionVersion) {
		fprintf(stderr,"Can't Get Extension Version %d\n", GetLastError());
		free (module);
		free(filelist);
		return -1;
	}
	IsapiHttpExtensionProc = (HttpExtProc)GetProcAddress(hDll,"HttpExtensionProc");
	if (!IsapiHttpExtensionProc) {
		fprintf(stderr,"Can't Get Extension proc %d\n", GetLastError());
		free (module);
		free(filelist);
		return -1;
	}
	TerminateExtensionProc = (TerminateProc) GetProcAddress(hDll, 
                                          "TerminateExtension");

	// This should really check if the version information matches what we
	// expect.
	//
	if (!IsapiGetExtensionVersion(&version_info) ) {
		fprintf(stderr,"Fatal: GetExtensionVersion failed\n");
		free (module);
		free(filelist);
		return -1;
	}

	if (bUseTestFiles) {
		char TestPath[MAX_PATH];
		if (filelist != NULL) 
			_snprintf(TestPath, sizeof(TestPath)-1, "%s\\tests", filelist);
		else strcpy(TestPath, "tests");
		DoTestFiles(TestPath, environment);
	} else {
		DoFileList(filelist, environment);
	}

	// cleanup
	if (TerminateExtensionProc) TerminateExtensionProc(0);

	// We should really free memory (e.g., from GetEnv), but we'll be dead
	// soon enough

	FreeLibrary(hDll);
	free (module);
	free(filelist);
	return 0;
}