diff --git a/mxq_group.c b/mxq_group.c index f9ec96a..558fabd 100644 --- a/mxq_group.c +++ b/mxq_group.c @@ -12,7 +12,7 @@ #include "mx_util.h" #include "mx_mysql.h" -#define GROUP_FIELDS_CNT 29 +#define GROUP_FIELDS_CNT 30 #define GROUP_FIELDS \ " group_id," \ " group_name," \ @@ -27,6 +27,7 @@ " job_threads," \ " job_memory," \ " job_time," \ + " job_max_per_node," \ " group_jobs," \ " group_jobs_inq," \ " group_jobs_running," \ @@ -70,6 +71,8 @@ static int bind_result_group_fields(struct mx_mysql_bind *result, struct mxq_gro res += mx_mysql_bind_var(result, idx++, uint64, &(g->job_memory)); res += mx_mysql_bind_var(result, idx++, uint32, &(g->job_time)); + res += mx_mysql_bind_var(result, idx++, uint16, &(g->job_max_per_node)); + res += mx_mysql_bind_var(result, idx++, uint64, &(g->group_jobs)); res += mx_mysql_bind_var(result, idx++, uint64, &(g->group_jobs_inq)); res += mx_mysql_bind_var(result, idx++, uint64, &(g->group_jobs_running)); diff --git a/mxq_group.h b/mxq_group.h index 8ab438d..db6b441 100644 --- a/mxq_group.h +++ b/mxq_group.h @@ -31,6 +31,8 @@ struct mxq_group { uint64_t job_memory; uint32_t job_time; + uint16_t job_max_per_node; + uint64_t group_jobs; uint64_t group_jobs_inq; uint64_t group_jobs_running; diff --git a/mxqd.c b/mxqd.c index 6d4c340..e923b06 100644 --- a/mxqd.c +++ b/mxqd.c @@ -446,6 +446,10 @@ void group_init(struct mxq_group_list *group) } jobs_max /= g->job_threads; + /* limit maximum number of jobs on user/group request */ + if (jobs_max > g->job_max_per_node) + jobs_max = g->job_max_per_node; + slots_max = jobs_max * slots_per_job; memory_max = jobs_max * g->job_memory; diff --git a/mxqsub.c b/mxqsub.c index 00bd144..87a476b 100644 --- a/mxqsub.c +++ b/mxqsub.c @@ -82,6 +82,9 @@ static void print_usage(void) " to specify years, weeks, days, hours and minutes\n" " Defaults to minutes if no suffix is set.\n" "\n" + " --max-jobs-per-node=NUMBER limit the number of jobs executed on each cluster node\n" + " (default: 0 [limited by the server])\n" + "\n" "Job handling:\n" " Define what to do if something bad happens:\n" "\n" @@ -170,6 +173,7 @@ static int load_group_id(struct mx_mysql *mysql, struct mxq_group *g) " AND job_threads = ?" " AND job_memory = ?" " AND job_time = ?" + " AND job_max_per_node = ?" " AND group_priority = ?" " AND group_status = 0" " AND group_flags & ? = 0 " @@ -189,8 +193,9 @@ static int load_group_id(struct mx_mysql *mysql, struct mxq_group *g) res += mx_mysql_statement_param_bind(stmt, 6, uint16, &(g->job_threads)); res += mx_mysql_statement_param_bind(stmt, 7, uint64, &(g->job_memory)); res += mx_mysql_statement_param_bind(stmt, 8, uint32, &(g->job_time)); - res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->group_priority)); - res += mx_mysql_statement_param_bind(stmt, 10, uint64, &(flags)); + res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->job_max_per_node)); + res += mx_mysql_statement_param_bind(stmt, 10, uint16, &(g->group_priority)); + res += mx_mysql_statement_param_bind(stmt, 11, uint64, &(flags)); assert(res == 0); res = mx_mysql_statement_execute(stmt, &num_rows); @@ -250,6 +255,7 @@ static int load_group_id_by_group_id(struct mx_mysql *mysql, struct mxq_group *g " AND job_threads = ?" " AND job_memory = ?" " AND job_time = ?" + " AND job_max_per_node = ?" " AND group_priority = ?" " AND group_status = 0" " AND group_id = ?" @@ -270,9 +276,10 @@ static int load_group_id_by_group_id(struct mx_mysql *mysql, struct mxq_group *g res += mx_mysql_statement_param_bind(stmt, 6, uint16, &(g->job_threads)); res += mx_mysql_statement_param_bind(stmt, 7, uint64, &(g->job_memory)); res += mx_mysql_statement_param_bind(stmt, 8, uint32, &(g->job_time)); - res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->group_priority)); - res += mx_mysql_statement_param_bind(stmt, 10, uint64, &(g->group_id)); - res += mx_mysql_statement_param_bind(stmt, 11, uint64, &(flags)); + res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->job_max_per_node)); + res += mx_mysql_statement_param_bind(stmt, 10, uint16, &(g->group_priority)); + res += mx_mysql_statement_param_bind(stmt, 11, uint64, &(g->group_id)); + res += mx_mysql_statement_param_bind(stmt, 12, uint64, &(flags)); assert(res == 0); res = mx_mysql_statement_execute(stmt, &num_rows); @@ -325,6 +332,7 @@ static int load_group_id_run_or_wait(struct mx_mysql *mysql, struct mxq_group *g " AND job_threads = ?" " AND job_memory = ?" " AND job_time = ?" + " AND job_max_per_node = ?" " AND group_priority = ?" " AND group_status = 0" " AND (" @@ -349,8 +357,9 @@ static int load_group_id_run_or_wait(struct mx_mysql *mysql, struct mxq_group *g res += mx_mysql_statement_param_bind(stmt, 6, uint16, &(g->job_threads)); res += mx_mysql_statement_param_bind(stmt, 7, uint64, &(g->job_memory)); res += mx_mysql_statement_param_bind(stmt, 8, uint32, &(g->job_time)); - res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->group_priority)); - res += mx_mysql_statement_param_bind(stmt, 10, uint64, &(flags)); + res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->job_max_per_node)); + res += mx_mysql_statement_param_bind(stmt, 10, uint16, &(g->group_priority)); + res += mx_mysql_statement_param_bind(stmt, 11, uint64, &(flags)); assert(res == 0); res = mx_mysql_statement_execute(stmt, &num_rows); @@ -405,6 +414,7 @@ static int add_group(struct mx_mysql *mysql, struct mxq_group *g) " job_threads = ?," " job_memory = ?," " job_time = ?," + " job_max_per_node = ?," " group_priority = ?"); if (!stmt) { mx_log_err("mx_mysql_statement_prepare(): %m"); @@ -420,7 +430,8 @@ static int add_group(struct mx_mysql *mysql, struct mxq_group *g) res += mx_mysql_statement_param_bind(stmt, 6, uint16, &(g->job_threads)); res += mx_mysql_statement_param_bind(stmt, 7, uint64, &(g->job_memory)); res += mx_mysql_statement_param_bind(stmt, 8, uint32, &(g->job_time)); - res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->group_priority)); + res += mx_mysql_statement_param_bind(stmt, 9, uint16, &(g->job_max_per_node)); + res += mx_mysql_statement_param_bind(stmt, 10, uint16, &(g->group_priority)); assert(res == 0); res = mx_mysql_statement_execute(stmt, &num_rows); @@ -585,6 +596,7 @@ int main(int argc, char *argv[]) u_int16_t arg_threads; u_int64_t arg_memory; u_int32_t arg_time; + u_int16_t arg_max_per_node; u_int64_t arg_groupid; char *arg_workdir; char *arg_stdout; @@ -646,6 +658,8 @@ int main(int argc, char *argv[]) MX_OPTION_REQUIRED_ARG("memory", 'm'), MX_OPTION_REQUIRED_ARG("runtime", 't'), + MX_OPTION_REQUIRED_ARG("max-jobs-per-node", 6), + MX_OPTION_REQUIRED_ARG("define", 'D'), MX_OPTION_OPTIONAL_ARG("mysql-default-file", 'M'), @@ -666,6 +680,7 @@ int main(int argc, char *argv[]) arg_threads = 1; arg_memory = 2048; arg_time = 0; + arg_max_per_node = 0; arg_workdir = current_workdir; arg_stdout = "/dev/null"; arg_stderr = "stdout"; @@ -829,6 +844,13 @@ int main(int argc, char *argv[]) } break; + case 6: + if (mx_strtou16(optctl.optarg, &arg_max_per_node) < 0) { + mx_log_crit("--max-jobs-per-node '%s': %m", optctl.optarg); + exit(EX_CONFIG); + } + break; + case 'w': if (!(*optctl.optarg)) { mx_log_crit("--workdir '%s': String is empty.", optctl.optarg); @@ -944,6 +966,8 @@ int main(int argc, char *argv[]) group.job_memory = arg_memory; group.job_time = arg_time; + group.job_max_per_node = arg_max_per_node; + job.job_flags = arg_jobflags; job.job_priority = arg_priority; job.job_workdir = arg_workdir; diff --git a/mysql/alter_tables_0.15.0.sql b/mysql/alter_tables_0.15.0.sql new file mode 100644 index 0000000..b1e8d15 --- /dev/null +++ b/mysql/alter_tables_0.15.0.sql @@ -0,0 +1,5 @@ +ALTER TABLE mxq_group + ADD COLUMN + job_max_per_node INT2 UNSIGNED NOT NULL DEFAULT 0 + AFTER + job_time; diff --git a/mysql/create_tables.sql b/mysql/create_tables.sql index 30365ce..cee2cd0 100644 --- a/mysql/create_tables.sql +++ b/mysql/create_tables.sql @@ -18,6 +18,8 @@ CREATE TABLE IF NOT EXISTS mxq_group ( job_memory INT8 UNSIGNED NOT NULL DEFAULT 1024, job_time INT4 UNSIGNED NOT NULL DEFAULT 15, + job_max_per_node INT2 UNSIGNED NOT NULL DEFAULT 0, + group_jobs INT8 UNSIGNED NOT NULL DEFAULT 0, group_jobs_inq INT8 UNSIGNED NOT NULL DEFAULT 0, group_jobs_running INT8 UNSIGNED NOT NULL DEFAULT 0, diff --git a/web/pages/mxq/mxq.in b/web/pages/mxq/mxq.in index 4c4f531..0e85317 100755 --- a/web/pages/mxq/mxq.in +++ b/web/pages/mxq/mxq.in @@ -252,6 +252,8 @@ job_threads : $o{job_threads} job_memory : $o{job_memory} job_time : $o{job_time} +job_max_per_node : $o{job_max_per_node} + group_jobs : $o{group_jobs} group_jobs_inq : $o{group_jobs_inq} group_jobs_running : $o{group_jobs_running}