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); }
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); }
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); }
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; }