void set_job_status(job *j, int status) { int fg_job = 0; if (j->state == FG) { fg_job = 1; } if (WIFSTOPPED(status)) { j->state = ST; print_job(*j); } else { j->state = TM; if (!fg_job) print_job(*j); initialize_job(j, j->jid); if(WIFSIGNALED(status)) { fprintf(stderr, "Terminated by signal %d.\n", (int) j->pid, WTERMSIG(status)); } } }
int main(int argc, char **argv) { //LOGFILE = stdout; LOGFILE = fopen("/tmp/taskcontroller.log", "a+"); int i=0; for (i=0; i<argc; i++) fprintf(LOGFILE, "Arg[%i] = %s\n", i, argv[i]); //Minimum number of arguments required to run the task-controller if (argc < 4) { display_usage(LOGFILE); return INVALID_ARGUMENT_NUMBER; } int command; const char * job_id = NULL; const char * task_id = NULL; const char * cred_file = NULL; const char * script_file = NULL; const char * current_dir = NULL; const char * job_xml = NULL; int exit_code = 0; char * dir_to_be_deleted = NULL; char *executable_file = get_executable(); #ifndef HADOOP_CONF_DIR #error HADOOP_CONF_DIR must be defined #endif char *orig_conf_file = STRINGIFY(HADOOP_CONF_DIR) "/" CONF_FILENAME; char *conf_file = realpath(orig_conf_file, NULL); if (conf_file == NULL) { fprintf(LOGFILE, "Configuration file %s not found.\n", orig_conf_file); return INVALID_CONFIG_FILE; } if (check_configuration_permissions(conf_file) != 0) { return INVALID_CONFIG_FILE; } read_config(conf_file); free(conf_file); // look up the task tracker group in the config file char *tt_group = get_value(TT_GROUP_KEY); if (tt_group == NULL) { fprintf(LOGFILE, "Can't get configured value for %s.\n", TT_GROUP_KEY); exit(INVALID_CONFIG_FILE); } struct group *group_info = getgrnam(tt_group); if (group_info == NULL) { fprintf(LOGFILE, "Can't get group information for %s - %s.\n", tt_group, strerror(errno)); exit(INVALID_CONFIG_FILE); } set_tasktracker_uid(getuid(), group_info->gr_gid); // if we are running from a setuid executable, make the real uid root setuid(0); // set the real and effective group id to the task tracker group setgid(group_info->gr_gid); if (check_taskcontroller_permissions(executable_file) != 0) { fprintf(LOGFILE, "Invalid permissions on task-controller binary.\n"); return INVALID_TASKCONTROLLER_PERMISSIONS; } //checks done for user name if (argv[optind] == NULL) { fprintf(LOGFILE, "Invalid user name \n"); return INVALID_USER_NAME; } int ret = set_user(argv[optind]); if (ret != 0) { return ret; } optind = optind + 1; command = atoi(argv[optind++]); fprintf(LOGFILE, "main : command provided %d\n",command); fprintf(LOGFILE, "main : user is %s\n", user_detail->pw_name); switch (command) { case INITIALIZE_JOB: if (argc < 7) { fprintf(LOGFILE, "Too few arguments (%d vs 7) for initialize job\n", argc); return INVALID_ARGUMENT_NUMBER; } job_id = argv[optind++]; cred_file = argv[optind++]; job_xml = argv[optind++]; exit_code = initialize_job(user_detail->pw_name, job_id, cred_file, job_xml, argv + optind); break; case LAUNCH_TASK_JVM: if (argc < 7) { fprintf(LOGFILE, "Too few arguments (%d vs 7) for launch task\n", argc); return INVALID_ARGUMENT_NUMBER; } job_id = argv[optind++]; task_id = argv[optind++]; current_dir = argv[optind++]; script_file = argv[optind++]; exit_code = run_task_as_user(user_detail->pw_name, job_id, task_id, current_dir, script_file); break; case SIGNAL_TASK: if (argc < 5) { fprintf(LOGFILE, "Too few arguments (%d vs 5) for signal task\n", argc); return INVALID_ARGUMENT_NUMBER; } else { char* end_ptr = NULL; char* option = argv[optind++]; int task_pid = strtol(option, &end_ptr, 10); if (option == end_ptr || *end_ptr != '\0') { fprintf(LOGFILE, "Illegal argument for task pid %s\n", option); return INVALID_ARGUMENT_NUMBER; } option = argv[optind++]; int signal = strtol(option, &end_ptr, 10); if (option == end_ptr || *end_ptr != '\0') { fprintf(LOGFILE, "Illegal argument for signal %s\n", option); return INVALID_ARGUMENT_NUMBER; } exit_code = signal_user_task(user_detail->pw_name, task_pid, signal); } break; case DELETE_AS_USER: dir_to_be_deleted = argv[optind++]; exit_code= delete_as_user(user_detail->pw_name, dir_to_be_deleted); break; case DELETE_LOG_AS_USER: dir_to_be_deleted = argv[optind++]; exit_code= delete_log_directory(dir_to_be_deleted); break; case RUN_COMMAND_AS_USER: exit_code = run_command_as_user(user_detail->pw_name, argv + optind); break; default: exit_code = INVALID_COMMAND_PROVIDED; } fclose(LOGFILE); return exit_code; }
void test_init_job() { printf("\nTesting init job\n"); if (seteuid(0) != 0) { printf("FAIL: seteuid to root failed - %s\n", strerror(errno)); exit(1); } FILE* creds = fopen(TEST_ROOT "/creds.txt", "w"); if (creds == NULL) { printf("FAIL: failed to create credentials file - %s\n", strerror(errno)); exit(1); } if (fprintf(creds, "secret key\n") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(creds) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } FILE* job_xml = fopen(TEST_ROOT "/job.xml", "w"); if (job_xml == NULL) { printf("FAIL: failed to create job file - %s\n", strerror(errno)); exit(1); } if (fprintf(job_xml, "<jobconf/>\n") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(job_xml) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } if (seteuid(user_detail->pw_uid) != 0) { printf("FAIL: failed to seteuid back to user - %s\n", strerror(errno)); exit(1); } fflush(stdout); fflush(stderr); pid_t child = fork(); if (child == -1) { printf("FAIL: failed to fork process for init_job - %s\n", strerror(errno)); exit(1); } else if (child == 0) { char *final_pgm[] = {"touch", "my-touch-file", 0}; if (initialize_job(username, "job_4", TEST_ROOT "/creds.txt", final_pgm) != 0) { printf("FAIL: failed in child\n"); exit(42); } // should never return exit(1); } int status = 0; if (waitpid(child, &status, 0) <= 0) { printf("FAIL: failed waiting for process %d - %s\n", child, strerror(errno)); exit(1); } if (access(TEST_ROOT "/logs/userlogs/job_4", R_OK) != 0) { printf("FAIL: failed to create job log directory\n"); exit(1); } char* job_dir = get_job_directory(TEST_ROOT "/local-1", username, "job_4"); if (access(job_dir, R_OK) != 0) { printf("FAIL: failed to create job directory %s\n", job_dir); exit(1); } char buffer[100000]; sprintf(buffer, "%s/jobToken", job_dir); if (access(buffer, R_OK) != 0) { printf("FAIL: failed to create credentials %s\n", buffer); exit(1); } sprintf(buffer, "%s/my-touch-file", job_dir); if (access(buffer, R_OK) != 0) { printf("FAIL: failed to create touch file %s\n", buffer); exit(1); } free(job_dir); job_dir = get_job_log_directory("logs","job_4"); if (access(job_dir, R_OK) != 0) { printf("FAIL: failed to create job log directory %s\n", job_dir); exit(1); } free(job_dir); }
/* 受け付けた文字列を解析して結果をjob構造体に入れる関数 */ job* parse_line(char *buf) { job *curr_job = NULL; process *curr_prc = NULL; parse_state state = ARGUMENT; int index=0, arg_index=0; /* 改行文字まで解析する */ while(*buf != '\n') { /* 空白およびタブを読んだときの処理 */ if(*buf == ' ' || *buf == '\t') { buf++; if(index) { index = 0; state = ARGUMENT; ++arg_index; } } /* 以下の3条件は、状態を遷移させる項目である */ else if(*buf == '<') { state = IN_REDIRCT; buf++; index = 0; } else if(*buf == '>') { buf++; index = 0; if(state == OUT_REDIRCT_TRUNC) { state = OUT_REDIRCT_APPEND; if(curr_prc) curr_prc->output_option = APPEND; } else { state = OUT_REDIRCT_TRUNC; } } else if(*buf == '|') { state = ARGUMENT; buf++; index = 0; arg_index = 0; if(curr_job) { strcpy(curr_prc->program_name, curr_prc->argument_list[0]); curr_prc->next = initialize_process(); curr_prc = curr_prc->next; } } /* &を読めば、modeをBACKGROUNDに設定し、解析を終了する */ else if(*buf == '&') { buf++; if(curr_job) { curr_job->mode = BACKGROUND; break; } } /* 以下の3条件は、各状態でprocess構造体の各メンバに文字を格納する */ /* 状態ARGUMENTは、 リダイレクション対象ファイル名以外の文字(プログラム名、オプション)を 読む状態 */ /* 状態IN_REDIRCTは入力リダイレクション対象ファイル名を読む状態 */ /* 状態OUT_REDIRCT_*は出力リダイレクション対象ファイル名を読む状態 */ else if(state == ARGUMENT) { if(!curr_job) { curr_job = initialize_job(); curr_prc = curr_job->process_list; } if(!curr_prc->argument_list[arg_index]) initialize_argument_list_element(curr_prc, arg_index); curr_prc->argument_list[arg_index][index++] = *buf++; } else if(state == IN_REDIRCT) { if(!curr_prc->input_redirection) initialize_input_redirection(curr_prc); curr_prc->input_redirection[index++] = *buf++; } else if(state == OUT_REDIRCT_TRUNC || state == OUT_REDIRCT_APPEND) { if(!curr_prc->output_redirection) initialize_output_redirection(curr_prc); curr_prc->output_redirection[index++] = *buf++; } } /* 最後に、引数の0番要素をprogram_nameにコピーする */ if(curr_prc) strcpy(curr_prc->program_name, curr_prc->argument_list[0]); return curr_job; }
void initialize_jobs(job *jobs) { int i; for (i=0; i<MAXJOBS; i++) { initialize_job(&jobs[i], i); } }
void remove_job(job *jobs, int jid) { initialize_job(&jobs[jid], jid); }