Skip to content

Commit

Permalink
mxqkill: Add function cancel_group
Browse files Browse the repository at this point in the history
Refactor group cancellation and move the code from main() into
functions analogous to the jobs cancellation functions.

Add function cancel_group and its helpers.

We have omitted some constraints from the old code:

The group to be cancelled is no longer required to have groups_status OK
and is no longer required to have pending or running jobs. So it is now
accepted to cancel an inactive group and it is not an error to cancel a
group multiple times.

The old code will be removed in the next commit to get cleaner diffs.
  • Loading branch information
donald committed Aug 15, 2024
1 parent 71db964 commit 4d1aea0
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions mxqkill.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,86 @@ static void cancel_job(struct mx_mysql *mysql, uint64_t job_id, uint64_t user_ui
set_job_cancelled(mysql, job_id);
}

static void verify_group_owner(struct mx_mysql *mysql, uint64_t group_id, uint64_t user_uid) {
struct mx_mysql_stmt *stmt = mx_mysql_statement_prepare(mysql,
"SELECT user_uid FROM mxq_group"
" WHERE group_id = ?"
);
if (!stmt)
mx_die("mx_mysql_statement_prepare(): %s\n", mx_mysql_error());

mx_mysql_statement_param_bind(stmt, 0, uint64, &group_id);

unsigned long long num_rows;
int res = mx_mysql_statement_execute(stmt, &num_rows);
if (res < 0)
mx_die("mx_mysql_statement_execute(): %s\n", mx_mysql_error());

if (num_rows == 0)
mx_die("no such group_id %lu\n", group_id);

uint64_t uid;
mx_mysql_statement_result_bind(stmt, 0, uint64, &uid);

res = mx_mysql_statement_fetch(stmt);
if (res < 0)
mx_die("mx_mysql_statement_fetch: %s\n", mx_mysql_error());

if (uid != user_uid)
mx_die("group %lu: permission denied\n", group_id);

mx_mysql_statement_close(&stmt);
}

static void set_group_cancelled(struct mx_mysql *mysql, uint64_t group_id) {
struct mx_mysql_stmt *stmt = mx_mysql_statement_prepare(mysql,
"UPDATE mxq_group SET group_status = " status_str(MXQ_GROUP_STATUS_CANCELLED)
" WHERE group_id = ?"
);
if (!stmt)
mx_die("mx_mysql_statement_prepare(): %s\n", mx_mysql_error());

mx_mysql_statement_param_bind(stmt, 0, uint64, &group_id);

unsigned long long num_rows;
int res = mx_mysql_statement_execute(stmt, &num_rows);
if (res < 0)
mx_die("mx_mysql_statement_execute(): %s\n", mx_mysql_error());
if (num_rows == 0)
mx_die("no such group_id %lu\n", group_id);

mx_mysql_statement_close(&stmt);
}

static void cancel_pending_jobs(struct mx_mysql *mysql, uint64_t group_id) {
struct mx_mysql_stmt *stmt = mx_mysql_statement_prepare(mysql,
"UPDATE mxq_job SET job_cancelled = TRUE"
" WHERE group_id = ?"
" AND job_status = " status_str(MXQ_JOB_STATUS_INQ)
);
if (!stmt)
mx_die("mx_mysql_statement_prepare(): %s\n", mx_mysql_error());

mx_mysql_statement_param_bind(stmt, 0, uint64, &group_id);

unsigned long long num_rows;
int res = mx_mysql_statement_execute(stmt, &num_rows);
if (res < 0)
mx_die("mx_mysql_statement_execute(): %s\n", mx_mysql_error());
if (num_rows)
mx_log_notice("cancelled %llu jobs in group with group_id=%lu", num_rows, group_id);
mx_mysql_statement_close(&stmt);
}

void cancel_group(struct mx_mysql *mysql, uint64_t group_id, uint64_t user_uid) {

verify_group_owner(mysql, group_id, user_uid);
set_group_cancelled(mysql, group_id);
cancel_pending_jobs(mysql, group_id);
mx_log_notice("marked all running jobs in group with group_id=%lu to be killed by executing servers.", group_id);
mx_log_notice("deactivated group with group_id=%lu", group_id);
}

int main(int argc, char *argv[])
{
struct mx_mysql *mysql = NULL;
Expand Down

0 comments on commit 4d1aea0

Please sign in to comment.