ProcFamilyProxy::~ProcFamilyProxy() { // if we started a ProcD, shut it down and remove the environment // variable marker // if (m_procd_pid != -1) { stop_procd(); UnsetEnv("CONDOR_PROCD_ADDRESS_BASE"); UnsetEnv("CONDOR_PROCD_ADDRESS"); } // clean up allocated memory // delete m_client; delete m_reaper_helper; // update instantiated flag // s_instantiated = false; }
bool VMType::createConfigUsingScript(const char* configfile) { vmprintf(D_FULLDEBUG, "Inside VMType::createConfigUsingScript\n"); if( !configfile || m_scriptname.IsEmpty() ) { return false; } // Set temporary environments for script program StringList name_list; const char *name; ExprTree* expr = NULL; m_classAd.ResetExpr(); while( m_classAd.NextExpr(name, expr) ) { if( !strncasecmp( name, "JobVM", strlen("JobVM") ) || !strncasecmp( name, "VMPARAM", strlen("VMPARAM") )) { name_list.append(name); SetEnv(name, ExprTreeToString(expr)); } } ArgList systemcmd; if( m_prog_for_script.IsEmpty() == false ) { systemcmd.AppendArg(m_prog_for_script); } systemcmd.AppendArg(m_scriptname); systemcmd.AppendArg("createconfig"); systemcmd.AppendArg(configfile); int result = systemCommand(systemcmd, m_file_owner); // UnSet temporary environments for script program const char *tmp_name = NULL; name_list.rewind(); while( (tmp_name = name_list.next()) != NULL ) { UnsetEnv(tmp_name); } if( result != 0 ) { vmprintf(D_ALWAYS, "Failed to create Configuration file('%s') using " "script program('%s')\n", configfile, m_scriptname.Value()); return false; } return true; }
/* * Entry point. */ int main(int argc, char ** argv) { JavaVM *vm = 0; JNIEnv *env = 0; char *jarfile = 0; char *classname = 0; char *s = 0; char *main_class = NULL; jstring mainClassName; jclass mainClass; jmethodID mainID; jobjectArray mainArgs; int ret; InvocationFunctions ifn; jlong start, end; char jrepath[MAXPATHLEN], jvmpath[MAXPATHLEN]; char ** original_argv = argv; /* * Error message to print or display; by default the message will * only be displayed in a window. */ char * message = "Fatal exception occurred. Program will exit."; jboolean messageDest = JNI_FALSE; if (getenv("_JAVA_LAUNCHER_DEBUG") != 0) { _launcher_debug = JNI_TRUE; printf("----_JAVA_LAUNCHER_DEBUG----\n"); } /* * Make sure the specified version of the JRE is running. * * There are three things to note about the SelectVersion() routine: * 1) If the version running isn't correct, this routine doesn't * return (either the correct version has been exec'd or an error * was issued). * 2) Argc and Argv in this scope are *not* altered by this routine. * It is the responsibility of subsequent code to ignore the * arguments handled by this routine. * 3) As a side-effect, the variable "main_class" is guaranteed to * be set (if it should ever be set). This isn't exactly the * poster child for structured programming, but it is a small * price to pay for not processing a jar file operand twice. */ SelectVersion(argc, argv, &main_class); /* copy original argv */ { int i; original_argv = (char**)MemAlloc(sizeof(char*)*(argc+1)); for(i = 0; i < argc+1; i++) original_argv[i] = argv[i]; } CreateExecutionEnvironment(&argc, &argv, jrepath, sizeof(jrepath), jvmpath, sizeof(jvmpath), original_argv); ifn.CreateJavaVM = 0; ifn.GetDefaultJavaVMInitArgs = 0; if (_launcher_debug) start = CounterGet(); if (!LoadJavaVM(jvmpath, &ifn)) { exit(6); } if (_launcher_debug) { end = CounterGet(); printf("%ld micro seconds to LoadJavaVM\n", (long)(jint)Counter2Micros(end-start)); } #ifdef JAVA_ARGS /* javac, jar and friends. */ progname = "java"; #else /* java, oldjava, javaw and friends */ #ifdef PROGNAME progname = PROGNAME; #else progname = *argv; if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) { progname = s + 1; } #endif /* PROGNAME */ #endif /* JAVA_ARGS */ ++argv; --argc; #ifdef JAVA_ARGS /* Preprocess wrapper arguments */ TranslateDashJArgs(&argc, &argv); if (!AddApplicationOptions()) { exit(1); } #endif /* Set default CLASSPATH */ if ((s = getenv("CLASSPATH")) == 0) { s = "."; } #ifndef JAVA_ARGS SetClassPath(s); #endif /* * Parse command line options; if the return value of * ParseArguments is false, the program should exit. */ if (!ParseArguments(&argc, &argv, &jarfile, &classname, &ret)) { exit(ret); } /* Override class path if -jar flag was specified */ if (jarfile != 0) { SetClassPath(jarfile); } /* set the -Dsun.java.command pseudo property */ SetJavaCommandLineProp(classname, jarfile, argc, argv); /* Set the -Dsun.java.launcher pseudo property */ SetJavaLauncherProp(); /* * Done with all command line processing and potential re-execs so * clean up the environment. */ (void)UnsetEnv(ENV_ENTRY); /* Initialize the virtual machine */ if (_launcher_debug) start = CounterGet(); if (!InitializeJVM(&vm, &env, &ifn)) { ReportErrorMessage("Could not create the Java virtual machine.", JNI_TRUE); exit(1); } if (printVersion || showVersion) { PrintJavaVersion(env); if ((*env)->ExceptionOccurred(env)) { ReportExceptionDescription(env); goto leave; } if (printVersion) { ret = 0; message = NULL; goto leave; } if (showVersion) { fprintf(stderr, "\n"); } } /* If the user specified neither a class name nor a JAR file */ if (jarfile == 0 && classname == 0) { PrintUsage(); message = NULL; goto leave; } FreeKnownVMs(); /* after last possible PrintUsage() */ if (_launcher_debug) { end = CounterGet(); printf("%ld micro seconds to InitializeJVM\n", (long)(jint)Counter2Micros(end-start)); } /* At this stage, argc/argv have the applications' arguments */ if (_launcher_debug) { int i = 0; printf("Main-Class is '%s'\n", classname ? classname : ""); printf("Apps' argc is %d\n", argc); for (; i < argc; i++) { printf(" argv[%2d] = '%s'\n", i, argv[i]); } } ret = 1; /* Get the application's main class */ if (jarfile != 0) { mainClassName = GetMainClassName(env, jarfile); if ((*env)->ExceptionOccurred(env)) { ReportExceptionDescription(env); goto leave; } if (mainClassName == NULL) { const char * format = "Failed to load Main-Class manifest " "attribute from\n%s"; message = (char*)MemAlloc((strlen(format) + strlen(jarfile)) * sizeof(char)); sprintf(message, format, jarfile); messageDest = JNI_TRUE; goto leave; } classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0); if (classname == NULL) { ReportExceptionDescription(env); goto leave; } mainClass = LoadClass(env, classname); if(mainClass == NULL) { /* exception occured */ ReportExceptionDescription(env); message = "Could not find the main class. Program will exit."; goto leave; } (*env)->ReleaseStringUTFChars(env, mainClassName, classname); } else { mainClassName = NewPlatformString(env, classname); if (mainClassName == NULL) { const char * format = "Failed to load Main Class: %s"; message = (char *)MemAlloc((strlen(format) + strlen(classname)) * sizeof(char) ); sprintf(message, format, classname); messageDest = JNI_TRUE; goto leave; } classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0); if (classname == NULL) { ReportExceptionDescription(env); goto leave; } mainClass = LoadClass(env, classname); if(mainClass == NULL) { /* exception occured */ ReportExceptionDescription(env); message = "Could not find the main class. Program will exit."; goto leave; } (*env)->ReleaseStringUTFChars(env, mainClassName, classname); } /* Get the application's main method */ mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V"); if (mainID == NULL) { if ((*env)->ExceptionOccurred(env)) { ReportExceptionDescription(env); } else { message = "No main method found in specified class."; messageDest = JNI_TRUE; } goto leave; } { /* Make sure the main method is public */ jint mods; jmethodID mid; jobject obj = (*env)->ToReflectedMethod(env, mainClass, mainID, JNI_TRUE); if( obj == NULL) { /* exception occurred */ ReportExceptionDescription(env); goto leave; } mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, obj), "getModifiers", "()I"); if ((*env)->ExceptionOccurred(env)) { ReportExceptionDescription(env); goto leave; } mods = (*env)->CallIntMethod(env, obj, mid); if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */ message = "Main method not public."; messageDest = JNI_TRUE; goto leave; } } /* Build argument array */ mainArgs = NewPlatformStringArray(env, argv, argc); if (mainArgs == NULL) { ReportExceptionDescription(env); goto leave; } /* Invoke main method. */ (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); if ((*env)->ExceptionOccurred(env)) { /* * Formerly, we used to call the "uncaughtException" method of * the main thread group, but this was later shown to be * unnecessary since the default definition merely printed out * the same exception stack trace as ExceptionDescribe and * could never actually be overridden by application programs. */ ReportExceptionDescription(env); goto leave; } /* * Detach the current thread so that it appears to have exited when * the application's main method exits. */ if ((*vm)->DetachCurrentThread(vm) != 0) { message = "Could not detach main thread."; messageDest = JNI_TRUE; goto leave; } ret = 0; message = NULL; leave: (*vm)->DestroyJavaVM(vm); if(message != NULL && !noExitErrorMessage) ReportErrorMessage(message, messageDest); return ret; }
void CreateExecutionEnvironment(int *pargc, char ***pargv, char jrepath[], jint so_jrepath, char jvmpath[], jint so_jvmpath) { /* * First, determine if we are running the desired data model. If we * are running the desired data model, all the error messages * associated with calling GetJREPath, ReadKnownVMs, etc. should be * output. However, if we are not running the desired data model, * some of the errors should be suppressed since it is more * informative to issue an error message based on whether or not the * os/processor combination has dual mode capabilities. */ jboolean jvmpathExists; /* Compute/set the name of the executable */ SetExecname(*pargv); /* Check data model flags, and exec process, if needed */ { char *arch = (char *)GetArch(); /* like sparc or sparcv9 */ char * jvmtype = NULL; int argc = *pargc; char **argv = *pargv; int running = CURRENT_DATA_MODEL; int wanted = running; /* What data mode is being asked for? Current model is fine unless another model is asked for */ #ifdef SETENV_REQUIRED jboolean mustsetenv = JNI_FALSE; char *runpath = NULL; /* existing effective LD_LIBRARY_PATH setting */ char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */ char* newpath = NULL; /* path on new LD_LIBRARY_PATH */ char* lastslash = NULL; char** newenvp = NULL; /* current environment */ #ifdef __solaris__ char* dmpath = NULL; /* data model specific LD_LIBRARY_PATH, Solaris only */ #endif /* __solaris__ */ #endif /* SETENV_REQUIRED */ char** newargv = NULL; int newargc = 0; /* * Starting in 1.5, all unix platforms accept the -d32 and -d64 * options. On platforms where only one data-model is supported * (e.g. ia-64 Linux), using the flag for the other data model is * an error and will terminate the program. */ { /* open new scope to declare local variables */ int i; newargv = (char **)JLI_MemAlloc((argc+1) * sizeof(char*)); newargv[newargc++] = argv[0]; /* scan for data model arguments and remove from argument list; last occurrence determines desired data model */ for (i=1; i < argc; i++) { if (JLI_StrCmp(argv[i], "-J-d64") == 0 || JLI_StrCmp(argv[i], "-d64") == 0) { wanted = 64; continue; } if (JLI_StrCmp(argv[i], "-J-d32") == 0 || JLI_StrCmp(argv[i], "-d32") == 0) { wanted = 32; continue; } newargv[newargc++] = argv[i]; if (IsJavaArgs()) { if (argv[i][0] != '-') continue; } else { if (JLI_StrCmp(argv[i], "-classpath") == 0 || JLI_StrCmp(argv[i], "-cp") == 0) { i++; if (i >= argc) break; newargv[newargc++] = argv[i]; continue; } if (argv[i][0] != '-') { i++; break; } } } /* copy rest of args [i .. argc) */ while (i < argc) { newargv[newargc++] = argv[i++]; } newargv[newargc] = NULL; /* * newargv has all proper arguments here */ argc = newargc; argv = newargv; } /* If the data model is not changing, it is an error if the jvmpath does not exist */ if (wanted == running) { /* Find out where the JRE is that we will be using. */ if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) { JLI_ReportErrorMessage(JRE_ERROR1); exit(2); } /* Find the specified JVM type */ if (ReadKnownVMs(jrepath, arch, JNI_FALSE) < 1) { JLI_ReportErrorMessage(CFG_ERROR7); exit(1); } jvmpath[0] = '\0'; jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE); if (JLI_StrCmp(jvmtype, "ERROR") == 0) { JLI_ReportErrorMessage(CFG_ERROR9); exit(4); } if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch )) { JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath); exit(4); } /* * we seem to have everything we need, so without further ado * we return back, otherwise proceed to set the environment. */ #ifdef SETENV_REQUIRED mustsetenv = RequiresSetenv(wanted, jvmpath); JLI_TraceLauncher("mustsetenv: %s\n", mustsetenv ? "TRUE" : "FALSE"); if (mustsetenv == JNI_FALSE) { return; } #else return; #endif /* SETENV_REQUIRED */ } else { /* do the same speculatively or exit */ #ifdef DUAL_MODE if (running != wanted) { /* Find out where the JRE is that we will be using. */ if (!GetJREPath(jrepath, so_jrepath, GetArchPath(wanted), JNI_TRUE)) { /* give up and let other code report error message */ JLI_ReportErrorMessage(JRE_ERROR2, wanted); exit(1); } /* * Read in jvm.cfg for target data model and process vm * selection options. */ if (ReadKnownVMs(jrepath, GetArchPath(wanted), JNI_TRUE) < 1) { /* give up and let other code report error message */ JLI_ReportErrorMessage(JRE_ERROR2, wanted); exit(1); } jvmpath[0] = '\0'; jvmtype = CheckJvmType(pargc, pargv, JNI_TRUE); if (JLI_StrCmp(jvmtype, "ERROR") == 0) { JLI_ReportErrorMessage(CFG_ERROR9); exit(4); } /* exec child can do error checking on the existence of the path */ jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted)); #ifdef SETENV_REQUIRED mustsetenv = RequiresSetenv(wanted, jvmpath); #endif /* SETENV_REQUIRED */ } #else JLI_ReportErrorMessage(JRE_ERROR2, wanted); exit(1); #endif } #ifdef SETENV_REQUIRED if (mustsetenv) { /* * We will set the LD_LIBRARY_PATH as follows: * * o $JVMPATH (directory portion only) * o $JRE/lib/$LIBARCHNAME * o $JRE/../lib/$LIBARCHNAME * * followed by the user's previous effective LD_LIBRARY_PATH, if * any. */ #ifdef __solaris__ /* * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH * variables: * * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if * data-model specific variables are not set. * * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH * for 64-bit binaries. * * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH * for 32-bit binaries. * * The vm uses LD_LIBRARY_PATH to set the java.library.path system * property. To shield the vm from the complication of multiple * LD_LIBRARY_PATH variables, if the appropriate data model * specific variable is set, we will act as if LD_LIBRARY_PATH had * the value of the data model specific variant and the data model * specific variant will be unset. Note that the variable for the * *wanted* data model must be used (if it is set), not simply the * current running data model. */ switch (wanted) { case 0: if (running == 32) { dmpath = getenv("LD_LIBRARY_PATH_32"); wanted = 32; } else { dmpath = getenv("LD_LIBRARY_PATH_64"); wanted = 64; } break; case 32: dmpath = getenv("LD_LIBRARY_PATH_32"); break; case 64: dmpath = getenv("LD_LIBRARY_PATH_64"); break; default: JLI_ReportErrorMessage(JRE_ERROR3, __LINE__); exit(1); /* unknown value in wanted */ break; } /* * If dmpath is NULL, the relevant data model specific variable is * not set and normal LD_LIBRARY_PATH should be used. */ if (dmpath == NULL) { runpath = getenv("LD_LIBRARY_PATH"); } else { runpath = dmpath; } #else /* * If not on Solaris, assume only a single LD_LIBRARY_PATH * variable. */ runpath = getenv("LD_LIBRARY_PATH"); #endif /* __solaris__ */ /* runpath contains current effective LD_LIBRARY_PATH setting */ jvmpath = JLI_StringDup(jvmpath); new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) + 2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) + JLI_StrLen(jvmpath) + 52); newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH="); /* * Create desired LD_LIBRARY_PATH value for target data model. */ { /* remove the name of the .so from the JVM path */ lastslash = JLI_StrRChr(jvmpath, '/'); if (lastslash) *lastslash = '\0'; sprintf(new_runpath, "LD_LIBRARY_PATH=" "%s:" "%s/lib/%s:" "%s/../lib/%s", jvmpath, #ifdef DUAL_MODE jrepath, GetArchPath(wanted), jrepath, GetArchPath(wanted) #else jrepath, arch, jrepath, arch #endif ); /* * Check to make sure that the prefix of the current path is the * desired environment variable setting, though the RequiresSetenv * checks if the desired runpath exists, this logic does a more * comprehensive check. */ if (runpath != NULL && JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath)) == 0 && (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') && (running == wanted) /* data model does not have to be changed */ #ifdef __solaris__ && (dmpath == NULL) /* data model specific variables not set */ #endif ) { return; } } /* * Place the desired environment setting onto the prefix of * LD_LIBRARY_PATH. Note that this prevents any possible infinite * loop of execv() because we test for the prefix, above. */ if (runpath != 0) { JLI_StrCat(new_runpath, ":"); JLI_StrCat(new_runpath, runpath); } if (putenv(new_runpath) != 0) { exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set properly */ } /* * Unix systems document that they look at LD_LIBRARY_PATH only * once at startup, so we have to re-exec the current executable * to get the changed environment variable to have an effect. */ #ifdef __solaris__ /* * If dmpath is not NULL, remove the data model specific string * in the environment for the exec'ed child. */ if (dmpath != NULL) (void)UnsetEnv((wanted == 32) ? "LD_LIBRARY_PATH_32" : "LD_LIBRARY_PATH_64"); #endif newenvp = environ; } #endif /* SETENV_REQUIRED */ { char *newexec = execname; #ifdef DUAL_MODE /* * If the data model is being changed, the path to the * executable must be updated accordingly; the executable name * and directory the executable resides in are separate. In the * case of 32 => 64, the new bits are assumed to reside in, e.g. * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32, * the bits are assumed to be in "olddir/../execname". For example, * * olddir/sparcv9/execname * olddir/amd64/execname * * for Solaris SPARC and Linux amd64, respectively. */ if (running != wanted) { char *oldexec = JLI_StrCpy(JLI_MemAlloc(JLI_StrLen(execname) + 1), execname); char *olddir = oldexec; char *oldbase = JLI_StrRChr(oldexec, '/'); newexec = JLI_MemAlloc(JLI_StrLen(execname) + 20); *oldbase++ = 0; sprintf(newexec, "%s/%s/%s", olddir, ((wanted == 64) ? LIBARCH64NAME : ".."), oldbase); argv[0] = newexec; } #endif /* DUAL_MODE */ JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n"); (void) fflush(stdout); (void) fflush(stderr); #ifdef SETENV_REQUIRED if (mustsetenv) { execve(newexec, argv, newenvp); } else { execv(newexec, argv); } #else execv(newexec, argv); #endif /* SETENV_REQUIRED */ JLI_ReportErrorMessageSys(JRE_ERROR4, newexec); #ifdef DUAL_MODE if (running != wanted) { JLI_ReportErrorMessage(JRE_ERROR5, wanted, running); #ifdef __solaris__ #ifdef __sparc JLI_ReportErrorMessage(JRE_ERROR6); #else JLI_ReportErrorMessage(JRE_ERROR7); #endif /* __sparc */ } #endif /* __solaris__ */ #endif /* DUAL_MODE */ } exit(1); } }
int handle_gahp_command(char ** argv, int argc) { // Assume it's been verified if (strcasecmp (argv[0], GAHP_COMMAND_JOB_REMOVE)==0) { int req_id = 0; int cluster_id, proc_id; if (!(argc == 5 && get_int (argv[1], &req_id) && get_job_id (argv[3], &cluster_id, &proc_id))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } enqueue_command ( SchedDRequest::createRemoveRequest( req_id, cluster_id, proc_id, argv[4])); return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_HOLD)==0) { int req_id = 0; int cluster_id, proc_id; if (!(argc == 5 && get_int (argv[1], &req_id) && get_job_id (argv[3], &cluster_id, &proc_id))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } enqueue_command ( SchedDRequest::createHoldRequest( req_id, cluster_id, proc_id, argv[4])); return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_RELEASE)==0) { int req_id = 0; int cluster_id, proc_id; if (!(argc == 5 && get_int (argv[1], &req_id) && get_job_id (argv[3], &cluster_id, &proc_id))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } enqueue_command ( SchedDRequest::createReleaseRequest( req_id, cluster_id, proc_id, argv[4])); return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_STATUS_CONSTRAINED) ==0) { int req_id; if (!(argc == 4 && get_int (argv[1], &req_id))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } char * constraint = argv[3]; enqueue_command ( SchedDRequest::createStatusConstrainedRequest( req_id, constraint)); return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_UPDATE_CONSTRAINED) ==0) { int req_id; ClassAd * classad; if (!(argc == 5 && get_int (argv[1], &req_id) && get_class_ad (argv[4], &classad))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } char * constraint = argv[3]; enqueue_command ( SchedDRequest::createUpdateConstrainedRequest( req_id, constraint, classad)); delete classad; return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_UPDATE) ==0) { int req_id; ClassAd * classad; int cluster_id, proc_id; if (!(argc == 5 && get_int (argv[1], &req_id) && get_job_id (argv[3], &cluster_id, &proc_id) && get_class_ad (argv[4], &classad))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } //char * constraint = argv[3]; enqueue_command ( SchedDRequest::createUpdateRequest( req_id, cluster_id, proc_id, classad)); delete classad; return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_SUBMIT) ==0) { int req_id; ClassAd * classad; if (!(argc == 4 && get_int (argv[1], &req_id) && get_class_ad (argv[3], &classad))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } enqueue_command ( SchedDRequest::createSubmitRequest( req_id, classad)); delete classad; return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_UPDATE_LEASE) ==0) { int req_id; int num_jobs; if (!(argc >= 4 && get_int (argv[1], &req_id) && get_int (argv[3], &num_jobs))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } job_expiration * expirations = new job_expiration[num_jobs]; int i; for (i=0; i<num_jobs; i++) { if (!get_job_id(argv[4+i*2], &(expirations[i].cluster), &(expirations[i].proc))) { delete[] expirations; return FALSE; } if (!get_ulong (argv[4+i*2+1], &(expirations[i].expiration))) { delete [] expirations; return FALSE; } } enqueue_command ( SchedDRequest::createUpdateLeaseRequest( req_id, num_jobs, expirations)); delete [] expirations; return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_STAGE_IN) ==0) { int req_id; ClassAd * classad; if (!(argc == 4 && get_int (argv[1], &req_id) && get_class_ad (argv[3], &classad))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } enqueue_command ( SchedDRequest::createJobStageInRequest( req_id, classad)); delete classad; return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_STAGE_OUT) ==0) { int req_id; int cluster_id, proc_id; if (!(argc == 4 && get_int (argv[1], &req_id) && get_job_id (argv[3], &cluster_id, &proc_id))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } enqueue_command ( SchedDRequest::createJobStageOutRequest( req_id, cluster_id, proc_id)); return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_JOB_REFRESH_PROXY)==0) { int req_id = 0; int cluster_id, proc_id; if (!(argc == 5 && get_int (argv[1], &req_id) && get_job_id (argv[3], &cluster_id, &proc_id))) { dprintf (D_ALWAYS, "Invalid args to %s\n", argv[0]); return FALSE; } enqueue_command ( SchedDRequest::createRefreshProxyRequest( req_id, cluster_id, proc_id, argv[4])); return TRUE; } else if (strcasecmp (argv[0], GAHP_COMMAND_INITIALIZE_FROM_FILE)==0) { static bool init_done = false; if ( init_done == false ) { SetEnv( "X509_USER_PROXY", argv[1] ); UnsetEnv( "X509_USER_CERT" ); UnsetEnv( "X509_USER_KEY" ); proxySubjectName = x509_proxy_identity_name( argv[1] ); if ( !proxySubjectName ) { dprintf( D_ALWAYS, "Failed to query certificate identity " "from %s\n", argv[1] ); return TRUE; } Reconfig(); init_done = true; } return TRUE; } dprintf (D_ALWAYS, "Invalid command %s\n", argv[0]); return FALSE; }
bool glexec_starter_prepare(const char* starter_path, const char* proxy_file, const ArgList& orig_args, const Env* orig_env, const int orig_std_fds[3], ArgList& glexec_args, Env& glexec_env, int glexec_std_fds[3]) { // if GLEXEC_STARTER is set, use glexec to invoke the // starter (or fail if we can't). this involves: // - verifying that we have a delegated proxy from // the user stored, since we need to hand it to // glexec so it can look up the UID/GID // - invoking 'glexec_starter_setup.sh' via glexec to // setup the starter's "private directory" for a copy // of the job's proxy to go into, as well as the StarterLog // and execute dir // - adding the contents of the GLEXEC and config param // and the path to 'condor_glexec_wrapper' to the front // of the command line // - setting up glexec's environment (setting the // mode, handing off the proxy, etc.) // - creating a UNIX-domain socket to use to communicate // with our wrapper script, and munging the std_fds // array // verify that we have a stored proxy if( proxy_file == NULL ) { dprintf( D_ALWAYS, "cannot use glexec to spawn starter: no proxy " "(is GLEXEC_STARTER set in the shadow?)\n" ); return false; } // using the file name of the proxy that was stashed ealier, construct // the name of the starter's "private directory". the naming scheme is // (where XXXXXX is randomly generated via condor_mkstemp): // - $(GLEXEC_USER_DIR)/startd-tmp-proxy-XXXXXX // - startd's copy of the job's proxy // - $(GLEXEC_USER_DIR)/starter-tmp-dir-XXXXXX // - starter's private dir // MyString glexec_private_dir; char* dir_part = condor_dirname(proxy_file); ASSERT(dir_part != NULL); glexec_private_dir = dir_part; free(dir_part); glexec_private_dir += "/starter-tmp-dir-"; const char* random_part = proxy_file; random_part += strlen(random_part) - 6; glexec_private_dir += random_part; dprintf(D_ALWAYS, "GLEXEC: starter private dir is '%s'\n", glexec_private_dir.Value()); // get the glexec command line prefix from config char* glexec_argstr = param( "GLEXEC" ); if ( ! glexec_argstr ) { dprintf( D_ALWAYS, "cannot use glexec to spawn starter: " "GLEXEC not given in config\n" ); return false; } // cons up a command line for my_system. we'll run the // script $(LIBEXEC)/glexec_starter_setup.sh, which // will create the starter's "private directory" (and // its log and execute subdirectories). the value of // glexec_private_dir will be passed as an argument to // the script // parse the glexec args for invoking glexec_starter_setup.sh. // do not free them yet, except on an error, as we use them // again below. MyString setup_err; ArgList glexec_setup_args; glexec_setup_args.SetArgV1SyntaxToCurrentPlatform(); if( ! glexec_setup_args.AppendArgsV1RawOrV2Quoted( glexec_argstr, &setup_err ) ) { dprintf( D_ALWAYS, "GLEXEC: failed to parse GLEXEC from config: %s\n", setup_err.Value() ); free( glexec_argstr ); return 0; } // set up the rest of the arguments for the glexec setup script char* tmp = param("LIBEXEC"); if (tmp == NULL) { dprintf( D_ALWAYS, "GLEXEC: LIBEXEC not defined; can't find setup script\n" ); free( glexec_argstr ); return 0; } MyString libexec = tmp; free(tmp); MyString setup_script = libexec; setup_script += "/glexec_starter_setup.sh"; glexec_setup_args.AppendArg(setup_script.Value()); glexec_setup_args.AppendArg(glexec_private_dir.Value()); // debug info. this display format totally screws up the quoting, but // my_system gets it right. MyString disp_args; glexec_setup_args.GetArgsStringForDisplay(&disp_args, 0); dprintf (D_ALWAYS, "GLEXEC: about to glexec: ** %s **\n", disp_args.Value()); // the only thing actually needed by glexec at this point is the cert, so // that it knows who to map to. the pipe outputs the username that glexec // ended up using, on a single text line by itself. SetEnv( "GLEXEC_CLIENT_CERT", proxy_file ); // create the starter's private dir int ret = my_system(glexec_setup_args); // clean up UnsetEnv( "GLEXEC_CLIENT_CERT"); if ( ret != 0 ) { dprintf(D_ALWAYS, "GLEXEC: error creating private dir: my_system returned %d\n", ret); free( glexec_argstr ); return 0; } // now prepare the starter command line, starting with glexec and its // options (if any), then condor_glexec_wrapper. MyString err; if( ! glexec_args.AppendArgsV1RawOrV2Quoted( glexec_argstr, &err ) ) { dprintf( D_ALWAYS, "failed to parse GLEXEC from config: %s\n", err.Value() ); free( glexec_argstr ); return 0; } free( glexec_argstr ); MyString wrapper_path = libexec; wrapper_path += "/condor_glexec_wrapper"; glexec_args.AppendArg(wrapper_path.Value()); // complete the command line by adding in the original // arguments. we also make sure that the full path to the // starter is given int starter_path_pos = glexec_args.Count(); glexec_args.AppendArgsFromArgList( orig_args ); glexec_args.RemoveArg( starter_path_pos ); glexec_args.InsertArg( starter_path, starter_path_pos ); // set up the environment stuff if( orig_env ) { // first merge in the original glexec_env.MergeFrom( *orig_env ); } // GLEXEC_MODE - get account from lcmaps glexec_env.SetEnv( "GLEXEC_MODE", "lcmaps_get_account" ); // GLEXEC_CLIENT_CERT - cert to use for the mapping glexec_env.SetEnv( "GLEXEC_CLIENT_CERT", proxy_file ); #if defined(HAVE_EXT_GLOBUS) && !defined(SKIP_AUTHENTICATION) // GLEXEC_SOURCE_PROXY - proxy to provide to the child // (file is owned by us) glexec_env.SetEnv( "GLEXEC_SOURCE_PROXY", proxy_file ); dprintf (D_ALWAYS, "GLEXEC: setting GLEXEC_SOURCE_PROXY to %s\n", proxy_file); // GLEXEC_TARGET_PROXY - child-owned file to copy its proxy to. // this needs to be in a directory owned by that user, and not world // writable. glexec enforces this. hence, all the whoami/mkdir mojo // above. MyString child_proxy_file = glexec_private_dir; child_proxy_file += "/glexec_starter_proxy"; dprintf (D_ALWAYS, "GLEXEC: setting GLEXEC_TARGET_PROXY to %s\n", child_proxy_file.Value()); glexec_env.SetEnv( "GLEXEC_TARGET_PROXY", child_proxy_file.Value() ); // _CONDOR_GSI_DAEMON_PROXY - starter's proxy MyString var_name; var_name.sprintf("_CONDOR_%s", STR_GSI_DAEMON_PROXY); glexec_env.SetEnv( var_name.Value(), child_proxy_file.Value() ); var_name.sprintf("_condor_%s", STR_GSI_DAEMON_PROXY); glexec_env.SetEnv( var_name.Value(), child_proxy_file.Value() ); #endif // the EXECUTE dir should be owned by the mapped user. we created this // earlier, and now we override it in the condor_config via the // environment. MyString execute_dir = glexec_private_dir; execute_dir += "/execute"; glexec_env.SetEnv ( "_CONDOR_EXECUTE", execute_dir.Value()); glexec_env.SetEnv ( "_condor_EXECUTE", execute_dir.Value()); // the LOG dir should be owned by the mapped user. we created this // earlier, and now we override it in the condor_config via the // environment. MyString log_dir = glexec_private_dir; log_dir += "/log"; glexec_env.SetEnv ( "_CONDOR_LOG", log_dir.Value()); glexec_env.SetEnv ( "_condor_LOG", log_dir.Value()); glexec_env.SetEnv ( "_CONDOR_LOCK", log_dir.Value()); glexec_env.SetEnv ( "_condor_LOCK", log_dir.Value()); // PROCD_ADDRESS: the Starter that we are about to create will // not have access to our ProcD. we'll explicitly set PROCD_ADDRESS // to be in its LOG directory. the Starter will see that its // PROCD_ADDRESS knob is different from what it inherits in // CONDOR_PROCD_ADDRESS, and know it needs to create its own ProcD // MyString procd_address = log_dir; procd_address += "/procd_pipe"; glexec_env.SetEnv( "_CONDOR_PROCD_ADDRESS", procd_address.Value() ); glexec_env.SetEnv( "_condor_PROCD_ADDRESS", procd_address.Value() ); // CONDOR_GLEXEC_STARTER_CLEANUP_FLAG: this serves as a flag in the // Starter's environment that it will check for in order to determine // whether to do GLEXEC_STARTER-specific cleanup // glexec_env.SetEnv( "CONDOR_GLEXEC_STARTER_CLEANUP_FLAG", "CONDOR_GLEXEC_STARTER_CLEANUP_FLAG" ); // now set up a socket pair for communication with // condor_glexec_wrapper // if (socketpair(PF_UNIX, SOCK_STREAM, 0, s_saved_sock_fds) == -1) { dprintf(D_ALWAYS, "GLEXEC: socketpair error: %s\n", strerror(errno)); return false; } glexec_std_fds[0] = s_saved_sock_fds[1]; if (orig_std_fds == NULL) { s_saved_starter_stdin = -1; glexec_std_fds[1] = glexec_std_fds[2] = -1; } else { s_saved_starter_stdin = orig_std_fds[0]; glexec_std_fds[1] = orig_std_fds[1]; glexec_std_fds[2] = orig_std_fds[2]; } // save the environment we're handing back to the caller for use in // glexec_starter_handle_env() // s_saved_env.Clear(); s_saved_env.MergeFrom(glexec_env); return true; }
void Condor_Auth_X509 :: erase_env() { UnsetEnv( "X509_USER_PROXY" ); }
void CreateExecutionEnvironment(int *pargc, char ***pargv, char jrepath[], jint so_jrepath, char jvmpath[], jint so_jvmpath, char jvmcfg[], jint so_jvmcfg) { /* * First, determine if we are running the desired data model. If we * are running the desired data model, all the error messages * associated with calling GetJREPath, ReadKnownVMs, etc. should be * output, otherwise we simply exit with an error, as we no longer * support dual data models. */ jboolean jvmpathExists; /* Compute/set the name of the executable */ SetExecname(*pargv); /* Check data model flags, and exec process, if needed */ { char *arch = LIBARCHNAME; /* like sparc or sparcv9 */ char * jvmtype = NULL; int argc = *pargc; char **argv = *pargv; int running = CURRENT_DATA_MODEL; /* * As of jdk9, there is no support for dual mode operations, however * for legacy error reporting purposes and until -d options are supported * we need this. */ int wanted = running; #ifdef SETENV_REQUIRED jboolean mustsetenv = JNI_FALSE; char *runpath = NULL; /* existing effective LD_LIBRARY_PATH setting */ char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */ char* newpath = NULL; /* path on new LD_LIBRARY_PATH */ char* lastslash = NULL; char** newenvp = NULL; /* current environment */ size_t new_runpath_size; #ifdef __solaris__ char* dmpath = NULL; /* data model specific LD_LIBRARY_PATH, Solaris only */ #endif /* __solaris__ */ #endif /* SETENV_REQUIRED */ char** newargv = NULL; int newargc = 0; /* * Starting in 1.5, all unix platforms accept the -d32 and -d64 * options. On platforms where only one data-model is supported * (e.g. ia-64 Linux), using the flag for the other data model is * an error and will terminate the program. */ { /* open new scope to declare local variables */ int i; newargv = (char **)JLI_MemAlloc((argc+1) * sizeof(char*)); newargv[newargc++] = argv[0]; /* scan for data model arguments and remove from argument list; last occurrence determines desired data model */ for (i=1; i < argc; i++) { if (JLI_StrCmp(argv[i], "-J-d64") == 0 || JLI_StrCmp(argv[i], "-d64") == 0) { wanted = 64; continue; } if (JLI_StrCmp(argv[i], "-J-d32") == 0 || JLI_StrCmp(argv[i], "-d32") == 0) { wanted = 32; continue; } newargv[newargc++] = argv[i]; if (IsJavaArgs()) { if (argv[i][0] != '-') continue; } else { if (JLI_StrCmp(argv[i], "-classpath") == 0 || JLI_StrCmp(argv[i], "-cp") == 0) { i++; if (i >= argc) break; newargv[newargc++] = argv[i]; continue; } if (argv[i][0] != '-') { i++; break; } } } /* copy rest of args [i .. argc) */ while (i < argc) { newargv[newargc++] = argv[i++]; } newargv[newargc] = NULL; /* * newargv has all proper arguments here */ argc = newargc; argv = newargv; } /* If the data model is not changing, it is an error if the jvmpath does not exist */ if (wanted == running) { /* Find out where the JRE is that we will be using. */ if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) { JLI_ReportErrorMessage(JRE_ERROR1); exit(2); } JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg", jrepath, FILESEP, FILESEP, arch, FILESEP); /* Find the specified JVM type */ if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) { JLI_ReportErrorMessage(CFG_ERROR7); exit(1); } jvmpath[0] = '\0'; jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE); if (JLI_StrCmp(jvmtype, "ERROR") == 0) { JLI_ReportErrorMessage(CFG_ERROR9); exit(4); } if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch, 0 )) { JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath); exit(4); } /* * we seem to have everything we need, so without further ado * we return back, otherwise proceed to set the environment. */ #ifdef SETENV_REQUIRED mustsetenv = RequiresSetenv(jvmpath); JLI_TraceLauncher("mustsetenv: %s\n", mustsetenv ? "TRUE" : "FALSE"); if (mustsetenv == JNI_FALSE) { JLI_MemFree(newargv); return; } #else JLI_MemFree(newargv); return; #endif /* SETENV_REQUIRED */ } else { /* do the same speculatively or exit */ JLI_ReportErrorMessage(JRE_ERROR2, wanted); exit(1); } #ifdef SETENV_REQUIRED if (mustsetenv) { /* * We will set the LD_LIBRARY_PATH as follows: * * o $JVMPATH (directory portion only) * o $JRE/lib/$LIBARCHNAME * o $JRE/../lib/$LIBARCHNAME * * followed by the user's previous effective LD_LIBRARY_PATH, if * any. */ #ifdef __solaris__ /* * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH * variables: * * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if * data-model specific variables are not set. * * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH * for 64-bit binaries. * The vm uses LD_LIBRARY_PATH to set the java.library.path system * property. To shield the vm from the complication of multiple * LD_LIBRARY_PATH variables, if the appropriate data model * specific variable is set, we will act as if LD_LIBRARY_PATH had * the value of the data model specific variant and the data model * specific variant will be unset. Note that the variable for the * *wanted* data model must be used (if it is set), not simply the * current running data model. */ switch (wanted) { case 0: case 64: dmpath = getenv("LD_LIBRARY_PATH_64"); wanted = 64; break; default: JLI_ReportErrorMessage(JRE_ERROR3, __LINE__); exit(1); /* unknown value in wanted */ break; } /* * If dmpath is NULL, the relevant data model specific variable is * not set and normal LD_LIBRARY_PATH should be used. */ if (dmpath == NULL) { runpath = getenv("LD_LIBRARY_PATH"); } else { runpath = dmpath; } #else /* ! __solaris__ */ /* * If not on Solaris, assume only a single LD_LIBRARY_PATH * variable. */ runpath = getenv(LD_LIBRARY_PATH); #endif /* __solaris__ */ /* runpath contains current effective LD_LIBRARY_PATH setting */ jvmpath = JLI_StringDup(jvmpath); new_runpath_size = ((runpath != NULL) ? JLI_StrLen(runpath) : 0) + 2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) + #ifdef AIX /* On AIX we additionally need 'jli' in the path because ld doesn't support $ORIGIN. */ JLI_StrLen(jrepath) + JLI_StrLen(arch) + JLI_StrLen("/lib//jli:") + #endif JLI_StrLen(jvmpath) + 52; new_runpath = JLI_MemAlloc(new_runpath_size); newpath = new_runpath + JLI_StrLen(LD_LIBRARY_PATH "="); /* * Create desired LD_LIBRARY_PATH value for target data model. */ { /* remove the name of the .so from the JVM path */ lastslash = JLI_StrRChr(jvmpath, '/'); if (lastslash) *lastslash = '\0'; sprintf(new_runpath, LD_LIBRARY_PATH "=" "%s:" "%s/lib/%s:" #ifdef AIX "%s/lib/%s/jli:" /* Needed on AIX because ld doesn't support $ORIGIN. */ #endif "%s/../lib/%s", jvmpath, jrepath, arch, #ifdef AIX jrepath, arch, #endif jrepath, arch ); /* * Check to make sure that the prefix of the current path is the * desired environment variable setting, though the RequiresSetenv * checks if the desired runpath exists, this logic does a more * comprehensive check. */ if (runpath != NULL && JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath)) == 0 && (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') && (running == wanted) /* data model does not have to be changed */ #ifdef __solaris__ && (dmpath == NULL) /* data model specific variables not set */ #endif /* __solaris__ */ ) { JLI_MemFree(newargv); JLI_MemFree(new_runpath); return; } } /* * Place the desired environment setting onto the prefix of * LD_LIBRARY_PATH. Note that this prevents any possible infinite * loop of execv() because we test for the prefix, above. */ if (runpath != 0) { /* ensure storage for runpath + colon + NULL */ if ((JLI_StrLen(runpath) + 1 + 1) > new_runpath_size) { JLI_ReportErrorMessageSys(JRE_ERROR11); exit(1); } JLI_StrCat(new_runpath, ":"); JLI_StrCat(new_runpath, runpath); } if (putenv(new_runpath) != 0) { exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set properly */ } /* * Unix systems document that they look at LD_LIBRARY_PATH only * once at startup, so we have to re-exec the current executable * to get the changed environment variable to have an effect. */ #ifdef __solaris__ /* * If dmpath is not NULL, remove the data model specific string * in the environment for the exec'ed child. */ if (dmpath != NULL) (void)UnsetEnv("LD_LIBRARY_PATH_64"); #endif /* __solaris */ newenvp = environ; } #endif /* SETENV_REQUIRED */ { char *newexec = execname; JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n"); (void) fflush(stdout); (void) fflush(stderr); #ifdef SETENV_REQUIRED if (mustsetenv) { execve(newexec, argv, newenvp); } else { execv(newexec, argv); } #else /* !SETENV_REQUIRED */ execv(newexec, argv); #endif /* SETENV_REQUIRED */ JLI_ReportErrorMessageSys(JRE_ERROR4, newexec); } exit(1); } }