static void execCmdline(strlist_t *cmdline, strlist_t *env, const char *workdir) { custr_t *execname; execname = execName(strlist_get(cmdline, 0), env, workdir); dlog("EXECNAME \"%s\"\n", custr_cstr(execname)); /* * We need to drop privs *after* we've setup /dev/zfd/[0-2] since that * requires being root. */ dlog("DROP PRIVS\n"); if (grp != NULL) { if (setgid(grp->gr_gid) != 0) { fatal(ERR_SETGID, "setgid(%d): %s\n", grp->gr_gid, strerror(errno)); } } if (pwd != NULL) { if (initgroups(pwd->pw_name, grp->gr_gid) != 0) { fatal(ERR_INITGROUPS, "initgroups(%s,%d): %s\n", pwd->pw_name, grp->gr_gid, strerror(errno)); } if (setuid(pwd->pw_uid) != 0) { fatal(ERR_SETUID, "setuid(%d): %s\n", pwd->pw_uid, strerror(errno)); } } execve(custr_cstr(execname), strlist_array(cmdline), strlist_array(env)); fatal(ERR_EXEC_FAILED, "execve(%s) failed: %s\n", execname, strerror(errno)); }
int main(int argc, char *argv[]) { char *execname; /* * We write the log to stderr and expect cn-agent to log/parse the output. * It can know that dockerexec finished when it sees either a line that * starts with: * * <timestamp> FATAL * * or: * * <timestamp> EXEC * * the former indicating that we failed and the latter that the next action * will be execve(). */ log_stream = stderr; if (argc < 2) { fatal(ERR_NO_COMMAND, "no command specified on cmdline, argc: %d\n", argc); } /* NOTE: all of these will call fatal() if there's a problem */ getUserGroupData(); setupWorkdir(); buildCmdEnv(); /* cleanup mess from mdata-client */ close(4); /* /dev/urandom from mdata-client */ close(5); /* event port from mdata-client */ close(6); /* /native/.zonecontrol/metadata.sock from mdata-client */ /* TODO: ensure we cleaned up everything else mdata created for us */ // TODO: close any descriptors which are not to be attached to this // exec cmd? Or let the zlogin caller deal with that? dlog("DROP PRIVS\n"); if (grp != NULL) { if (setgid(grp->gr_gid) != 0) { fatal(ERR_SETGID, "setgid(%d): %s\n", grp->gr_gid, strerror(errno)); } } if (pwd != NULL) { if (initgroups(pwd->pw_name, grp->gr_gid) != 0) { fatal(ERR_INITGROUPS, "initgroups(%s,%d): %s\n", pwd->pw_name, grp->gr_gid, strerror(errno)); } if (setuid(pwd->pw_uid) != 0) { fatal(ERR_SETUID, "setuid(%d): %s\n", pwd->pw_uid, strerror(errno)); } } // find execname from argv[1] (w/ path), then execute it. execname = execName(argv[1]); // calls fatal() if fails // Message for cn-agent that dockerexec is done and child should start // now. dlog("EXEC\n"); execve(execname, argv+1, env); // If execve() has failed, this next message should go to the user since // stdout and stderr should now be connected to them. fatal(ERR_EXEC_FAILED, "execve(%s) failed: %s\n", argv[1], strerror(errno)); /* NOTREACHED */ abort(); }
//###################################################################################################################################### AliAnalysisAlien* CreateAlienHandler ( const char* gridMode, const char* tag, unsigned int nr_test_files, unsigned int TTL, const char* outdir, const char subworkdir, const char* extradirlvl ) { AliAnalysisAlien* plugin = new AliAnalysisAlien(); if ( !plugin ) { std::cout << "!!! -->> alien handler could not be created <<-- !!!" << std::endl; return NULL;} plugin->AddIncludePath("-I."); plugin->AddIncludePath("-I$ALICE_PHYSICS/include"); plugin->AddIncludePath("-I$ALICE_ROOT/include"); plugin->AddIncludePath("-I$FASTJET/include"); plugin->AddIncludePath("-I/usr/include"); // unsigned int kGridMaxMergeFiles = 100; // Number of files merged in a chunk grid run range // unsigned int kMaxInitFailed = 10 ; // Optionally set number of failed jobs that will trigger killing waiting sub-jobs. TString kGridOutdir = outdir ; // AliEn output directory. If blank will become output_<kTrainName> TString kGridSubWorkDir = subworkdir ; // sub working directory not to confuse different run xmls TString kGridExtraAliendirLevel = extradirlvl ; // sub working directory not to confuse different run xmls TString kWorkDir = tag; // AliEn work dir; relative to AliEn $HOME TString kTrainName = "cdfjets"; // *CHANGE ME* (no blancs or special characters) TString macroName(""); macroName = Form("%s.C", kTrainName.Data()); TString execName(""); execName = Form("%s.sh", kTrainName.Data()); TString jdlName(""); jdlName = Form("%s.jdl", kTrainName.Data()); // Set run mode. Can be "full", "test", "offline", "submit" or "merge" plugin->SetRunMode(gridMode); if (std::strcmp(gridMode, "test")) { plugin->SetCheckCopy(kFALSE); } // Set the number of test files; set to kGridFilesPerJob as to evaluate the memory consumption and ttl on grid plugin->SetNtestFiles ( nr_test_files ); // Job tag plugin->SetJobTag(tag); // AliEn directory containing the input packages plugin->SetGridWorkingDir(tag); // Declare alien output directory. Relative to working directory. plugin->SetGridOutputDir( kGridOutdir.Data() ); // In this case will be $HOME/work/output // Optionally modify the executable name (default analysis.sh) plugin->SetExecutable(execName.Data()); // Optionally set a name for the generated analysis macro (default MyAnalysis.C) plugin->SetAnalysisMacro(macroName.Data()); // Optionally modify the name of the generated JDL (default analysis.jdl) plugin->SetJDLName(jdlName.Data()); // Use the output files connected to output containers from the analysis manager // rather than the files defined by SetOutputFiles plugin->SetDefaultOutputs(kTRUE); //******************** PLUGIN OPTIONS ************************ // min (nr,4) replicas in grid storage plugin->SetNumberOfReplicas(2); // Optionally set time to live plugin->SetTTL(TTL); // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore) plugin->SetSplitMaxInputFileNumber ( nr_test_files ); // Use xrootd tweaks to reduce timeouts in file access plugin->SetFastReadOption ( kFALSE ); // Maximum initial consecutive subjobs accepted to fail. // plugin->SetMaxInitFailed ( kMaxInitFailed ); // Optionally resubmit threshold. // plugin->SetMasterResubmitThreshold(90); // Number of runs per masterjob // plugin->SetNrunsPerMaster(1); // exit from aliensh after submmiting job plugin->SetDropToShell ( kTRUE ); // Overwrite existing files if any plugin->SetOverwriteMode(); // write the output to subdirs named after run number // plugin->SetOutputToRunNo(1); // Optionally set input format (default xml-single) plugin->SetInputFormat("xml-single"); // Optionally modify job price (default 1) plugin->SetPrice(1); // We split per SE or file plugin->SetSplitMode("se"); // MERGING - Enable merging via automatic JDL plugin->SetMergeViaJDL(kTRUE); // Maximum number of files to be merged in one chunk plugin->SetOneStageMerging(kFALSE); // Maximum number of merging stages plugin->SetMaxMergeStages(2); // Optionally set maximum number of files merged in a chunk (default 100, put 0 to ignore) // plugin->SetMaxMergeFiles ( kGridMaxMergeFiles ); return plugin; }