diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c index 43923e315d65c02307b13acf5252e4a304475e1a..f72b73c68a98175b85f93049e1e3229eff443514 100644 --- a/src/common/assoc_mgr.c +++ b/src/common/assoc_mgr.c @@ -232,14 +232,14 @@ extern int assoc_mgr_fill_in_assoc(void *db_conn, acct_association_rec_t *assoc, debug3("not the right account"); continue; } -/* We shouldn't have to do this since we only have this clusters - * assocs here */ -/* if(found_assoc->cluster */ -/* && strcasecmp(assoc->cluster, */ -/* found_assoc->cluster)) { */ -/* debug3("not the right cluster"); */ -/* continue; */ -/* } */ + + /* only check for on the slurmdbd */ + if(!local_cluster_name && found_assoc->cluster + && strcasecmp(assoc->cluster, + found_assoc->cluster)) { + debug3("not the right cluster"); + continue; + } if(assoc->partition && (!found_assoc->partition @@ -390,7 +390,7 @@ extern int assoc_mgr_update_local_assocs(acct_update_object_t *update) return SLURM_SUCCESS; slurm_mutex_lock(&local_association_lock); - itr = list_iterator_create(local_user_list); + itr = list_iterator_create(local_association_list); while((object = list_pop(update->objects))) { if(local_cluster_name) { /* only update the local clusters assocs */ @@ -399,8 +399,47 @@ extern int assoc_mgr_update_local_assocs(acct_update_object_t *update) } list_iterator_reset(itr); while((rec = list_next(itr))) { - if(object->id == rec->id) + if(object->id) { + if(object->id == rec->id) { + break; + } + continue; + } else { + if(!object->user && rec->user) { + debug3("we are looking for a " + "nonuser association"); + continue; + } else if(object->uid != rec->uid) { + debug3("not the right user"); + continue; + } + + if(object->acct + && (!rec->acct + || strcasecmp(object->acct, + rec->acct))) { + debug3("not the right account"); + continue; + } + + /* only check for on the slurmdbd */ + if(!local_cluster_name && object->acct + && (!rec->cluster + || strcasecmp(object->cluster, + rec->cluster))) { + debug3("not the right cluster"); + continue; + } + + if(object->partition + && (!rec->partition + || strcasecmp(object->partition, + rec->partition))) { + debug3("not the right partition"); + continue; + } break; + } } //info("%d assoc %u", update->type, object->id); switch(update->type) { @@ -409,8 +448,31 @@ extern int assoc_mgr_update_local_assocs(acct_update_object_t *update) //rc = SLURM_ERROR; break; } + debug("updating the assocs here on %u", rec->id); + if((int)object->fairshare >= 0) { + rec->fairshare = object->fairshare; + } + + if((int)object->max_jobs >= 0) { + rec->max_jobs = object->max_jobs; + } + + if((int)object->max_nodes_per_job >= 0) { + rec->max_nodes_per_job = + object->max_nodes_per_job; + } + + if((int)object->max_wall_duration_per_job >= 0) { + rec->max_wall_duration_per_job = + object->max_wall_duration_per_job; + } + + if((int)object->max_cpu_secs_per_job >= 0) { + rec->max_cpu_secs_per_job = + object->max_cpu_secs_per_job; + } - /* fix me: do updates here */ + /* fix me: do more updates here */ break; case ACCT_ADD_ASSOC: if(rec) { diff --git a/src/common/slurm_accounting_storage.c b/src/common/slurm_accounting_storage.c index 55d61de00ebb019f69d7616475fd3d9156014094..7fc971d288f0b30f418ddf485a7e7d80fab83596 100644 --- a/src/common/slurm_accounting_storage.c +++ b/src/common/slurm_accounting_storage.c @@ -59,7 +59,8 @@ typedef struct slurm_acct_storage_ops { void *(*get_conn) (bool rollback); - int (*close_conn) (void **db_conn, bool commit); + int (*close_conn) (void **db_conn); + int (*commit) (void *db_conn, bool commit); int (*add_users) (void *db_conn, uint32_t uid, List user_list); int (*add_coord) (void *db_conn, uint32_t uid, @@ -179,6 +180,7 @@ static slurm_acct_storage_ops_t * _acct_storage_get_ops( static const char *syms[] = { "acct_storage_p_get_connection", "acct_storage_p_close_connection", + "acct_storage_p_commit", "acct_storage_p_add_users", "acct_storage_p_add_coord", "acct_storage_p_add_accts", @@ -1154,6 +1156,11 @@ extern void pack_acct_association_cond(void *in, Buf buffer) acct_association_cond_t *object = (acct_association_cond_t *)in; if(!object) { + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); pack32(0, buffer); pack32(0, buffer); pack32(0, buffer); @@ -1189,6 +1196,8 @@ extern void pack_acct_association_cond(void *in, Buf buffer) } count = 0; + pack32(object->fairshare, buffer); + if(object->id_list) count = list_count(object->id_list); @@ -1201,6 +1210,11 @@ extern void pack_acct_association_cond(void *in, Buf buffer) } count = 0; + pack32(object->max_cpu_secs_per_job, buffer); + pack32(object->max_jobs, buffer); + pack32(object->max_nodes_per_job, buffer); + pack32(object->max_wall_duration_per_job, buffer); + if(object->partition_list) count = list_count(object->partition_list); @@ -1254,6 +1268,8 @@ extern int unpack_acct_association_cond(void **object, Buf buffer) list_append(object_ptr->cluster_list, tmp_info); } + safe_unpack32(&object_ptr->fairshare, buffer); + safe_unpack32(&count, buffer); object_ptr->id_list = list_create(slurm_destroy_char); for(i=0; i<count; i++) { @@ -1261,6 +1277,11 @@ extern int unpack_acct_association_cond(void **object, Buf buffer) list_append(object_ptr->id_list, tmp_info); } + safe_unpack32(&object_ptr->max_cpu_secs_per_job, buffer); + safe_unpack32(&object_ptr->max_jobs, buffer); + safe_unpack32(&object_ptr->max_nodes_per_job, buffer); + safe_unpack32(&object_ptr->max_wall_duration_per_job, buffer); + safe_unpack32(&count, buffer); object_ptr->partition_list = list_create(slurm_destroy_char); for(i=0; i<count; i++) { @@ -1508,11 +1529,19 @@ extern void *acct_storage_g_get_connection(bool rollback) return (*(g_acct_storage_context->ops.get_conn))(rollback); } -extern int acct_storage_g_close_connection(void **db_conn, bool commit) +extern int acct_storage_g_close_connection(void **db_conn) +{ + if (slurm_acct_storage_init(NULL) < 0) + return SLURM_ERROR; + return (*(g_acct_storage_context->ops.close_conn))(db_conn); + +} + +extern int acct_storage_g_commit(void *db_conn, bool commit) { if (slurm_acct_storage_init(NULL) < 0) return SLURM_ERROR; - return (*(g_acct_storage_context->ops.close_conn))(db_conn, commit); + return (*(g_acct_storage_context->ops.commit))(db_conn, commit); } diff --git a/src/common/slurm_accounting_storage.h b/src/common/slurm_accounting_storage.h index 116d5da353a86293610bebd390ddce465d8260f8..4f3ace4c1de1bbc023371c59befd494a79b578d8 100644 --- a/src/common/slurm_accounting_storage.h +++ b/src/common/slurm_accounting_storage.h @@ -103,9 +103,19 @@ typedef struct { typedef struct { List acct_list; /* list of char * */ List cluster_list; /* list of char * */ + uint32_t fairshare; /* fairshare number */ List id_list; /* list of char */ + uint32_t max_cpu_secs_per_job; /* max number of cpu seconds this + * association can have per job */ + uint32_t max_jobs; /* max number of jobs this association can run + * at one time */ + uint32_t max_nodes_per_job; /* max number of nodes this + * association can allocate per job */ + uint32_t max_wall_duration_per_job; /* longest time this + * association can run a job */ List partition_list; /* list of char * */ char *parent_acct; /* name of parent account */ + List user_list; /* list of char * */ } acct_association_cond_t; @@ -243,16 +253,26 @@ extern int slurm_acct_storage_fini(void); /* unload the plugin */ /* * get a new connection to the storage unit + * IN: bool weither to be able to rollback or not * RET: pointer used to access db */ extern void *acct_storage_g_get_connection(bool rollback); /* * release connection to the storage unit + * IN/OUT: void ** pointer returned from + * acct_storage_g_get_connection() which will be freed. + * RET: SLURM_SUCCESS on success SLURM_ERROR else + */ +extern int acct_storage_g_close_connection(void **db_conn); + +/* + * commit or rollback changes made without closing connection * IN: void * pointer returned from acct_storage_g_get_connection() + * IN: bool - true will commit changes false will rollback * RET: SLURM_SUCCESS on success SLURM_ERROR else */ -extern int acct_storage_g_close_connection(void **db_conn, bool commit); +extern int acct_storage_g_commit(void *db_conn, bool commit); /* * add users to accounting system diff --git a/src/common/slurmdbd_defs.c b/src/common/slurmdbd_defs.c index d1a12ddfc63afa6f6f498dbd83a945e93283808a..e337e0bd9726288d187c4e63fdb7d299cb037bf2 100644 --- a/src/common/slurmdbd_defs.c +++ b/src/common/slurmdbd_defs.c @@ -88,7 +88,7 @@ static bool rollback_started = 0; static void * _agent(void *x); static void _agent_queue_del(void *x); -static void _close_slurmdbd_fd(bool commit); +static void _close_slurmdbd_fd(); static void _create_agent(void); static bool _fd_readable(slurm_fd fd); static int _fd_writeable(slurm_fd fd); @@ -102,7 +102,7 @@ static void _reopen_slurmdbd_fd(void); static int _save_dbd_rec(int fd, Buf buffer); static void _save_dbd_state(void); static int _send_init_msg(void); -static int _send_fini_msg(bool commit); +static int _send_fini_msg(void); static int _send_msg(Buf buffer); static void _sig_handler(int signal); static void _shutdown_agent(void); @@ -137,13 +137,13 @@ extern int slurm_open_slurmdbd_conn(char *auth_info, bool rollback) } /* Close the SlurmDBD socket connection */ -extern int slurm_close_slurmdbd_conn(bool commit) +extern int slurm_close_slurmdbd_conn() { /* NOTE: agent_lock not needed for _shutdown_agent() */ _shutdown_agent(); slurm_mutex_lock(&slurmdbd_lock); - _close_slurmdbd_fd(commit); + _close_slurmdbd_fd(); xfree(slurmdbd_auth_info); slurm_mutex_unlock(&slurmdbd_lock); @@ -369,7 +369,7 @@ extern Buf pack_slurmdbd_msg(slurmdbd_msg_t *req) slurmdbd_auth_info); break; case DBD_FINI: - slurmdbd_pack_fini_msg((dbd_fini_msg_t *)&req->data, buffer); + slurmdbd_pack_fini_msg((dbd_fini_msg_t *)req->data, buffer); break; case DBD_JOB_COMPLETE: slurmdbd_pack_job_complete_msg((dbd_job_comp_msg_t *)req->data, @@ -567,14 +567,15 @@ static int _send_init_msg(void) return rc; } -static int _send_fini_msg(bool commit) +static int _send_fini_msg() { Buf buffer; dbd_fini_msg_t req; buffer = init_buf(1024); pack16((uint16_t) DBD_FINI, buffer); - req.commit = commit; + req.commit = 0; + req.close_conn = 1; slurmdbd_pack_fini_msg(&req, buffer); _send_msg(buffer); @@ -584,11 +585,11 @@ static int _send_fini_msg(bool commit) } /* Close the SlurmDbd connection */ -static void _close_slurmdbd_fd(bool commit) +static void _close_slurmdbd_fd() { if (slurmdbd_fd >= 0) { if(rollback_started) { - if (_send_fini_msg(commit) != SLURM_SUCCESS) + if (_send_fini_msg() != SLURM_SUCCESS) error("slurmdbd: Sending fini msg: %m"); else debug("slurmdbd: Sent fini msg"); @@ -603,7 +604,7 @@ static void _close_slurmdbd_fd(bool commit) static void _reopen_slurmdbd_fd(void) { info("slurmdbd: reopening connection"); - _close_slurmdbd_fd(1); + _close_slurmdbd_fd(); _open_slurmdbd_fd(); } @@ -1664,6 +1665,7 @@ unpack_error: void inline slurmdbd_pack_fini_msg(dbd_fini_msg_t *msg, Buf buffer) { + pack16(msg->close_conn, buffer); pack16(msg->commit, buffer); } @@ -1673,7 +1675,9 @@ slurmdbd_unpack_fini_msg(dbd_fini_msg_t **msg, Buf buffer) dbd_fini_msg_t *msg_ptr = xmalloc(sizeof(dbd_fini_msg_t)); *msg = msg_ptr; + safe_unpack16(&msg_ptr->close_conn, buffer); safe_unpack16(&msg_ptr->commit, buffer); + return SLURM_SUCCESS; unpack_error: diff --git a/src/common/slurmdbd_defs.h b/src/common/slurmdbd_defs.h index 02b842d1291f3ea8740c2ec2f8983a28c5ec3e9a..125b1a7d6146cec69892b9f4ac76c97b169003f9 100644 --- a/src/common/slurmdbd_defs.h +++ b/src/common/slurmdbd_defs.h @@ -161,6 +161,8 @@ typedef struct dbd_init_msg { } dbd_init_msg_t; typedef struct dbd_fini_msg { + uint16_t close_conn; /* to close connection 1, 0 will keep + connection open */ uint16_t commit; /* to rollback(0) or commit(1) changes */ } dbd_fini_msg_t; @@ -279,7 +281,7 @@ typedef struct dbd_step_start_msg { extern int slurm_open_slurmdbd_conn(char *auth_info, bool rollback); /* Close the SlurmDBD socket connection */ -extern int slurm_close_slurmdbd_conn(bool commit); +extern int slurm_close_slurmdbd_conn(); /* Send an RPC to the SlurmDBD. Do not wait for the reply. The RPC * will be queued and processed later if the SlurmDBD is not responding. diff --git a/src/database/mysql_common.c b/src/database/mysql_common.c index 03561b08f4a0c9c9d07d9b7386bb3b984cee3129..eb3c1dd17a1bc0a0d13b31c8f24b6f635619ea5a 100644 --- a/src/database/mysql_common.c +++ b/src/database/mysql_common.c @@ -63,6 +63,23 @@ static int _clear_results(MYSQL *mysql_db) return SLURM_SUCCESS; } +static MYSQL_RES *_get_first_result(MYSQL *mysql_db) +{ + MYSQL_RES *result = NULL; + int rc = 0; + do { + /* did current statement return data? */ + if((result = mysql_store_result(mysql_db))) + return result; + + /* more results? -1 = no, >0 = error, 0 = yes (keep looping) */ + if ((rc = mysql_next_result(mysql_db)) > 0) + debug3("error: Could not execute statement %d\n", rc); + } while (rc == 0); + + return NULL; +} + static int _mysql_make_table_current(MYSQL *mysql_db, char *table_name, storage_field_t *fields) { @@ -177,7 +194,7 @@ extern int mysql_get_db_connection(MYSQL **mysql_db, char *db_name, extern int mysql_close_db_connection(MYSQL **mysql_db) { - if(*mysql_db) { + if(mysql_db && *mysql_db) { mysql_close(*mysql_db); *mysql_db = NULL; } @@ -210,7 +227,7 @@ extern MYSQL_RES *mysql_db_query_ret(MYSQL *mysql_db, char *query) MYSQL_RES *result = NULL; if(mysql_db_query(mysql_db, query) != SLURM_ERROR) { - result = mysql_store_result(mysql_db); + result = _get_first_result(mysql_db); if(!result && mysql_field_count(mysql_db)) { /* should have returned data */ error("We should have gotten a result: %s", diff --git a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c index 77f5dc4c542e529917b3c5376ff111b5b9a48070..2a07fa84ead6716a25f25842ec6dc64433f2361b 100644 --- a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c +++ b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c @@ -234,7 +234,12 @@ extern void * acct_storage_p_get_connection(bool commit) return NULL; } -extern int acct_storage_p_close_connection(void **db_conn, bool rollback) +extern int acct_storage_p_close_connection(void **db_conn) +{ + return SLURM_SUCCESS; +} + +extern int acct_storage_p_commit(void *db_conn, bool commit) { return SLURM_SUCCESS; } diff --git a/src/plugins/accounting_storage/gold/accounting_storage_gold.c b/src/plugins/accounting_storage/gold/accounting_storage_gold.c index 013ceb189e783885575b6a1356c4a78ae09c0a03..9c9eb32b66abe0a082e94c75e9d9f63f816de697 100644 --- a/src/plugins/accounting_storage/gold/accounting_storage_gold.c +++ b/src/plugins/accounting_storage/gold/accounting_storage_gold.c @@ -716,7 +716,12 @@ extern void * acct_storage_p_get_connection(bool rollback) return NULL; } -extern int acct_storage_p_close_connection(void **db_conn, bool commit) +extern int acct_storage_p_close_connection(void **db_conn) +{ + return SLURM_SUCCESS; +} + +extern int acct_storage_p_commit(void *db_conn, bool commit) { return SLURM_SUCCESS; } diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c index 943e59c1828a38cd86b6e0a288c855afcb4e719d..1283e12a57ed7f9186323fc2cd5072ac304ce3df 100644 --- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c +++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c @@ -99,12 +99,15 @@ char *step_table = "step_table"; char *txn_table = "txn_table"; char *user_table = "user_table"; +extern int acct_storage_p_commit(mysql_conn_t *mysql_conn, bool commit); + extern int acct_storage_p_add_associations(mysql_conn_t *mysql_conn, uint32_t uid, List association_list); extern List acct_storage_p_get_associations(mysql_conn_t *mysql_conn, acct_association_cond_t *assoc_q); + /* This function will take the object given and free it later so it * needed to be removed from a list if in one before */ @@ -178,6 +181,49 @@ static int _get_affected_rows(MYSQL *mysql_db) return rows; } +static int _modify_common(mysql_conn_t *mysql_conn, + uint16_t type, + time_t now, + char *user_name, + char *table, + char *cond_char, + char *vals) +{ + char *query = NULL; + int rc = SLURM_SUCCESS; + + xstrfmtcat(query, + "update %s set mod_time=%d%s " + "where deleted=0 && %s;", + table, now, vals, + cond_char); + xstrfmtcat(query, + "insert into %s " + "(timestamp, action, name, actor, info) " + "values (%d, %d, \"%s\", '%s', \"%s\");", + txn_table, + now, type, cond_char, user_name, vals); + debug3("query\n%s", query); + rc = mysql_db_query(mysql_conn->acct_mysql_db, query); + xfree(query); + + if(rc != SLURM_SUCCESS) { + if(mysql_conn->rollback) { + mysql_db_query(mysql_conn->acct_mysql_db, "ROLLBACK;"); + mysql_autocommit(mysql_conn->acct_mysql_db, 1); + } + list_destroy(mysql_conn->update_list); + mysql_conn->update_list = + list_create(destroy_acct_update_object); + + return SLURM_ERROR; + } else if(mysql_conn->rollback) { + mysql_conn->trans_started = 1; + } + + return SLURM_SUCCESS; +} + static int _remove_common(mysql_conn_t *mysql_conn, uint16_t type, time_t now, @@ -372,7 +418,7 @@ static int _mysql_acct_check_tables(MYSQL *acct_mysql_db) { "max_jobs", "int default NULL" }, { "max_nodes_per_job", "int default NULL" }, { "max_wall_duration_per_job", "int default NULL" }, - { "max_cpu_seconds_per_job", "int default NULL" }, + { "max_cpu_secs_per_job", "int default NULL" }, { NULL, NULL} }; @@ -428,6 +474,7 @@ static int _mysql_acct_check_tables(MYSQL *acct_mysql_db) { "gid", "smallint unsigned not null" }, { "partition", "tinytext not null" }, { "blockid", "tinytext" }, + { "account", "tinytext" }, { "eligible", "int unsigned default 0 not null" }, { "submit", "int unsigned default 0 not null" }, { "start", "int unsigned default 0 not null" }, @@ -684,22 +731,60 @@ extern void *acct_storage_p_get_connection(bool rollback) #endif } -extern int acct_storage_p_close_connection(mysql_conn_t **mysql_conn, - bool commit) +extern int acct_storage_p_close_connection(mysql_conn_t **mysql_conn) { #ifdef HAVE_MYSQL - if(!(*mysql_conn)) + if(!mysql_conn || !(*mysql_conn)) return SLURM_SUCCESS; - //info("got %d commits", list_count((*mysql_conn)->update_list)); + /* frees mysql_conn->query */ + acct_storage_p_commit((*mysql_conn), 0); + + mysql_close_db_connection(&(*mysql_conn)->acct_mysql_db); + list_destroy((*mysql_conn)->update_list); + xfree((*mysql_conn)); + + return SLURM_SUCCESS; +#else + return SLURM_ERROR; +#endif +} + +extern int acct_storage_p_commit(mysql_conn_t *mysql_conn, bool commit) +{ +#ifdef HAVE_MYSQL + + if(!mysql_conn) + return SLURM_ERROR; + + debug4("got %d commits", list_count(mysql_conn->update_list)); - if(!commit && (*mysql_conn)->query) { - //info("running\n%s", (*mysql_conn)->query); - if(mysql_db_query((*mysql_conn)->acct_mysql_db, - (*mysql_conn)->query) == SLURM_ERROR) - error("undo failed"); - } else if(commit && list_count((*mysql_conn)->update_list)) { + if(!commit) { + debug4("rollback"); + if(mysql_conn->query) { + //info("running\n%s", mysql_conn->query); + if(mysql_db_query(mysql_conn->acct_mysql_db, + mysql_conn->query) == SLURM_ERROR) + error("undo failed"); + } else if(mysql_conn->trans_started) { + info("rolling back"); + if(mysql_db_query(mysql_conn->acct_mysql_db, + "ROLLBACK;")) + error("rollback failed"); + mysql_conn->trans_started = 0; + mysql_autocommit(mysql_conn->acct_mysql_db, 1); + } + + } else if(mysql_conn->trans_started) { + debug4("commiting"); + if(mysql_db_query(mysql_conn->acct_mysql_db, "COMMIT;")) + error("commit failed"); + mysql_conn->trans_started = 0; + mysql_autocommit(mysql_conn->acct_mysql_db, 1); + } + + if(commit && list_count(mysql_conn->update_list)) { int rc; char *query = NULL; MYSQL_RES *result = NULL; @@ -709,17 +794,17 @@ extern int acct_storage_p_close_connection(mysql_conn_t **mysql_conn, slurm_msg_t resp; ListIterator itr = NULL; acct_update_object_t *object = NULL; - + slurm_msg_t_init(&req); slurm_msg_t_init(&resp); - + memset(&msg, 0, sizeof(accounting_update_msg_t)); - msg.update_list = (*mysql_conn)->update_list; - + msg.update_list = mysql_conn->update_list; + xstrfmtcat(query, "select control_host, control_port from %s " "where deleted=0 && control_port != 0", cluster_table); - if(!(result = mysql_db_query_ret((*mysql_conn)->acct_mysql_db, + if(!(result = mysql_db_query_ret(mysql_conn->acct_mysql_db, query))) { xfree(query); goto skip; @@ -734,10 +819,10 @@ extern int acct_storage_p_close_connection(mysql_conn_t **mysql_conn, rc = slurm_send_recv_node_msg(&req, &resp, 0); if ((rc != 0) || !resp.auth_cred) { - error("fini: %m"); + error("update cluster: %m to %s(%s)", + row[0], row[1]); if (resp.auth_cred) - g_slurm_auth_destroy( - resp.auth_cred); + g_slurm_auth_destroy(resp.auth_cred); rc = SLURM_ERROR; } if (resp.auth_cred) @@ -756,11 +841,19 @@ extern int acct_storage_p_close_connection(mysql_conn_t **mysql_conn, } mysql_free_result(result); skip: - itr = list_iterator_create((*mysql_conn)->update_list); + /* NOTE: you can not use list_pop, or list_push + anywhere either, since mysql is + exporting something of the same type as a macro, + which messes everything up (my_list.h is the bad boy). + So we are just going to delete each item as it + comes out. + */ + itr = list_iterator_create(mysql_conn->update_list); while((object = list_next(itr))) { - if(!object->objects - || !list_count(object->objects)) + if(!object->objects || !list_count(object->objects)) { + list_delete_item(itr); continue; + } switch(object->type) { case ACCT_MODIFY_USER: case ACCT_ADD_USER: @@ -779,14 +872,12 @@ extern int acct_storage_p_close_connection(mysql_conn_t **mysql_conn, object->type); break; } + list_delete_item(itr); } list_iterator_destroy(itr); } - mysql_close_db_connection(&(*mysql_conn)->acct_mysql_db); - list_destroy((*mysql_conn)->update_list); - xfree((*mysql_conn)->query); - xfree((*mysql_conn)); - + xfree(mysql_conn->query); + return SLURM_SUCCESS; #else return SLURM_ERROR; @@ -1155,21 +1246,21 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid, now, now, object->name); xstrfmtcat(extra, ", mod_time=%d", now); - if(object->default_fairshare) { + if((int)object->default_fairshare >= 0) { xstrcat(cols, ", fairshare"); xstrfmtcat(vals, ", %u", object->default_fairshare); xstrfmtcat(extra, ", fairshare=%u", object->default_fairshare); } - if(object->default_max_jobs) { + if((int)object->default_max_jobs >= 0) { xstrcat(cols, ", max_jobs"); xstrfmtcat(vals, ", %u", object->default_max_jobs); xstrfmtcat(extra, ", max_jobs=%u", object->default_max_jobs); } - if(object->default_max_nodes_per_job) { + if((int)object->default_max_nodes_per_job >= 0) { xstrcat(cols, ", max_nodes_per_job"); xstrfmtcat(vals, ", %u", object->default_max_nodes_per_job); @@ -1177,7 +1268,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid, object->default_max_nodes_per_job); } - if(object->default_max_wall_duration_per_job) { + if((int)object->default_max_wall_duration_per_job >= 0) { xstrcat(cols, ", max_wall_duration_per_job"); xstrfmtcat(vals, ", %u", object->default_max_wall_duration_per_job); @@ -1185,11 +1276,11 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid, object->default_max_wall_duration_per_job); } - if(object->default_max_cpu_secs_per_job) { - xstrcat(cols, ", max_cpu_seconds_per_job"); + if((int)object->default_max_cpu_secs_per_job >= 0) { + xstrcat(cols, ", max_cpu_secs_per_job"); xstrfmtcat(vals, ", %u", object->default_max_cpu_secs_per_job); - xstrfmtcat(extra, ", max_cpu_seconds_per_job=%u", + xstrfmtcat(extra, ", max_cpu_secs_per_job=%u", object->default_max_cpu_secs_per_job); } @@ -1203,7 +1294,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid, cluster_table, now, now, object->name, now); - //info("query\n%s", query); + debug3("query\n%s", query); rc = mysql_db_query(mysql_conn->acct_mysql_db, query); xfree(query); if(rc != SLURM_SUCCESS) { @@ -1217,7 +1308,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid, affect_rows = _get_affected_rows(mysql_conn->acct_mysql_db); if(!affect_rows) { - debug("nothing changed %d", affect_rows); + debug2("nothing changed %d", affect_rows); xfree(extra); xfree(cols); xfree(vals); @@ -1253,7 +1344,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid, txn_table, txn_table, now, DBD_ADD_CLUSTERS, object->name, user, extra); - //info("query\n%s",query); + debug4("query\n%s",query); rc = mysql_db_query(mysql_conn->acct_mysql_db, query); xfree(query); if(rc != SLURM_SUCCESS) { @@ -1314,7 +1405,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid, xfree(cols); xfree(vals); xfree(extra); -// info("query is %s", query); + debug3("query is %s", query); rc = mysql_db_query(mysql_conn->acct_mysql_db, query); xfree(query); @@ -1482,9 +1573,9 @@ extern int acct_storage_p_add_associations(mysql_conn_t *mysql_conn, } if((int)object->max_cpu_secs_per_job >= 0) { - xstrcat(cols, ", max_cpu_seconds_per_job"); + xstrcat(cols, ", max_cpu_secs_per_job"); xstrfmtcat(vals, ", %d", object->max_cpu_secs_per_job); - xstrfmtcat(extra, ", max_cpu_seconds_per_job=%d", + xstrfmtcat(extra, ", max_cpu_secs_per_job=%d", object->max_cpu_secs_per_job); } @@ -1923,7 +2014,8 @@ extern List acct_storage_p_modify_clusters(mysql_conn_t *mysql_conn, List ret_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; - char *vals = NULL, *extra = NULL, *query = NULL; + char *vals = NULL, *assoc_vals = NULL, *extra = NULL, *query = NULL, + *name_char = NULL, *assoc_char= NULL; time_t now = time(NULL); struct passwd *pw = NULL; char *user = NULL; @@ -1955,29 +2047,101 @@ extern List acct_storage_p_modify_clusters(mysql_conn_t *mysql_conn, xstrcat(extra, ")"); } - xstrfmtcat(vals, "mod_time=%d", now); - - if(cluster->control_host) + + if(cluster->control_host) { xstrfmtcat(vals, ", control_host='%s'", cluster->control_host); - if(cluster->control_port) + } + if(cluster->control_port) { xstrfmtcat(vals, ", control_port=%u", cluster->control_port); - - if(!extra || !vals) { + } + + if((int)cluster->default_fairshare >= 0) { + xstrfmtcat(assoc_vals, ", fairshare=%u", + cluster->default_fairshare); + } + + if((int)cluster->default_max_jobs >= 0) { + xstrfmtcat(assoc_vals, ", max_jobs=%u", + cluster->default_max_jobs); + } + + if((int)cluster->default_max_nodes_per_job >= 0) { + xstrfmtcat(assoc_vals, ", max_nodes_per_job=%u", + cluster->default_max_nodes_per_job); + } + + if((int)cluster->default_max_wall_duration_per_job >= 0) { + xstrfmtcat(assoc_vals, ", max_wall_duration_per_job=%u", + cluster->default_max_wall_duration_per_job); + } + + if((int)cluster->default_max_cpu_secs_per_job >= 0) { + xstrfmtcat(assoc_vals, ", max_cpu_secs_per_job=%u", + cluster->default_max_cpu_secs_per_job); + } + + if(!vals && !assoc_vals) { error("Nothing to change"); return NULL; } - query = xstrdup_printf("select name from %s %s;", cluster_table, extra); + xstrfmtcat(query, "select name from %s %s;", cluster_table, extra); + xfree(extra); + //debug3("query\n%s",query); if(!(result = mysql_db_query_ret(mysql_conn->acct_mysql_db, query))) { xfree(query); + error("no result given for %s", extra); return NULL; } xfree(query); - + + rc = 0; ret_list = list_create(slurm_destroy_char); while((row = mysql_fetch_row(result))) { - char *object = xstrdup(row[0]); + acct_association_rec_t *assoc = NULL; + + object = xstrdup(row[0]); list_append(ret_list, object); + if(!rc) { + xstrfmtcat(name_char, "name='%s'", object); + xstrfmtcat(assoc_char, "cluster='%s'", object); + rc = 1; + } else { + xstrfmtcat(name_char, " || name='%s'", object); + xstrfmtcat(assoc_char, " || cluster='%s'", object); + } + if(assoc_vals) { + assoc = xmalloc(sizeof(acct_association_rec_t)); + assoc->cluster = xstrdup(object); + assoc->acct = xstrdup("root"); + if((int)cluster->default_fairshare >= 0) { + assoc->fairshare = cluster->default_fairshare; + } + + if((int)cluster->default_max_jobs >= 0) { + assoc->max_jobs = cluster->default_max_jobs; + } + + if((int)cluster->default_max_nodes_per_job >= 0) { + assoc->max_nodes_per_job = + cluster->default_max_nodes_per_job; + } + + if((int)cluster->default_max_wall_duration_per_job + >= 0) { + assoc->max_wall_duration_per_job = cluster-> + default_max_wall_duration_per_job; + } + + if((int)cluster->default_max_cpu_secs_per_job >= 0) { + assoc->max_cpu_secs_per_job = cluster-> + default_max_cpu_secs_per_job; + } + if(_addto_update_list(mysql_conn->update_list, + ACCT_MODIFY_ASSOC, + assoc) != SLURM_SUCCESS) + error("couldn't add to the update list"); + } } mysql_free_result(result); @@ -1985,38 +2149,38 @@ extern List acct_storage_p_modify_clusters(mysql_conn_t *mysql_conn, debug3("didn't effect anything"); list_destroy(ret_list); xfree(vals); - xfree(extra); return NULL; } - query = xstrdup_printf("update %s set %s %s;", - cluster_table, vals, extra); - xstrfmtcat(query, - "insert into %s " - "(timestamp, action, name, actor, info) " - "values (%d, %d, \"%s\", '%s', \"%s\");", - txn_table, - now, DBD_MODIFY_CLUSTERS, extra, user, vals); - xfree(vals); - xfree(extra); - - rc = mysql_db_query(mysql_conn->acct_mysql_db, query); - xfree(query); - if(rc != SLURM_SUCCESS) { - error("Couldn't modify assocs"); - list_destroy(ret_list); - ret_list = NULL; + if(mysql_conn->rollback) + mysql_autocommit(mysql_conn->acct_mysql_db, 0); + + if(vals) { + char *send_char = xstrdup_printf("(%s)", name_char); + + if(_modify_common(mysql_conn, DBD_MODIFY_CLUSTERS, now, + user, cluster_table, send_char, vals) + == SLURM_ERROR) { + error("Couldn't modify cluster 1"); + list_destroy(ret_list); + ret_list = NULL; + goto end_it; + } } - - if(mysql_conn->rollback) { - char *roll = mysql_conn->query; - mysql_conn->query = xstrdup_printf(""); - if(roll) { - xstrfmtcat(mysql_conn->query, "%s", roll); - xfree(roll); - } + + if(assoc_vals) { + char *send_char = xstrdup_printf("acct='root' && (%s)", + assoc_char); + if(_modify_common(mysql_conn, DBD_MODIFY_CLUSTERS, now, + user, assoc_table, send_char, assoc_vals) + == SLURM_ERROR) { + error("Couldn't modify cluster"); + list_destroy(ret_list); + ret_list = NULL; + goto end_it; + } } - +end_it: return ret_list; #else return NULL; @@ -2135,7 +2299,7 @@ extern List acct_storage_p_modify_associations(mysql_conn_t *mysql_conn, } if((int)assoc->max_cpu_secs_per_job >= 0) { - xstrfmtcat(vals, ", max_cpu_seconds_per_job=%d", + xstrfmtcat(vals, ", max_cpu_secs_per_job=%d", assoc->max_cpu_secs_per_job); } @@ -2299,8 +2463,9 @@ extern List acct_storage_p_remove_users(mysql_conn_t *mysql_conn, uint32_t uid, return NULL; } - if(!_remove_common(mysql_conn, DBD_REMOVE_USERS, now, - user_name, user_table, name_char, assoc_char)) { + if(_remove_common(mysql_conn, DBD_REMOVE_USERS, now, + user_name, user_table, name_char, assoc_char) + == SLURM_ERROR) { list_destroy(ret_list); xfree(name_char); xfree(assoc_char); @@ -2434,8 +2599,9 @@ extern List acct_storage_p_remove_accts(mysql_conn_t *mysql_conn, uint32_t uid, return NULL; } - if(!_remove_common(mysql_conn, DBD_REMOVE_ACCOUNTS, now, - user_name, acct_table, name_char, assoc_char)) { + if(_remove_common(mysql_conn, DBD_REMOVE_ACCOUNTS, now, + user_name, acct_table, name_char, assoc_char) + == SLURM_ERROR) { list_destroy(ret_list); xfree(name_char); xfree(assoc_char); @@ -2503,7 +2669,6 @@ extern List acct_storage_p_remove_clusters(mysql_conn_t *mysql_conn, return NULL; } xfree(query); - rc = 0; ret_list = list_create(slurm_destroy_char); while((row = mysql_fetch_row(result))) { @@ -2526,8 +2691,9 @@ extern List acct_storage_p_remove_clusters(mysql_conn_t *mysql_conn, return NULL; } - if(!_remove_common(mysql_conn, DBD_REMOVE_CLUSTERS, now, - user_name, cluster_table, name_char, assoc_char)) { + if(_remove_common(mysql_conn, DBD_REMOVE_CLUSTERS, now, + user_name, cluster_table, name_char, assoc_char) + == SLURM_ERROR) { list_destroy(ret_list); xfree(name_char); xfree(assoc_char); @@ -2658,8 +2824,9 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, return NULL; } - if(!_remove_common(mysql_conn, DBD_REMOVE_ASSOCS, now, - user_name, assoc_table, name_char, NULL)) { + if(_remove_common(mysql_conn, DBD_REMOVE_ASSOCS, now, + user_name, assoc_table, name_char, NULL) + == SLURM_ERROR) { list_destroy(ret_list); xfree(name_char); return NULL; @@ -3082,7 +3249,7 @@ extern List acct_storage_p_get_associations(mysql_conn_t *mysql_conn, "max_jobs", "max_nodes_per_job", "max_wall_duration_per_job", - "max_cpu_seconds_per_job", + "max_cpu_secs_per_job", }; enum { ASSOC_REQ_ID, diff --git a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h index b7bbfdf03bfaa521b210ee919c03f85ad84e13ed..b0356a0af5754701903142af009f879975292416 100644 --- a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h +++ b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h @@ -61,6 +61,7 @@ typedef struct { MYSQL *acct_mysql_db; bool rollback; char *query; + bool trans_started; List update_list; } mysql_conn_t; diff --git a/src/plugins/accounting_storage/none/accounting_storage_none.c b/src/plugins/accounting_storage/none/accounting_storage_none.c index ee0df18eb296c9e2518f8b6ab5d7ffaa20338aae..a175810fe8c8dbdb614b15a09b02a52fedb3a925 100644 --- a/src/plugins/accounting_storage/none/accounting_storage_none.c +++ b/src/plugins/accounting_storage/none/accounting_storage_none.c @@ -92,7 +92,12 @@ extern void * acct_storage_p_get_connection(bool commit) return NULL; } -extern int acct_storage_p_close_connection(void **db_conn, bool rollback) +extern int acct_storage_p_close_connection(void **db_conn) +{ + return SLURM_SUCCESS; +} + +extern int acct_storage_p_commit(void *db_conn, bool commit) { return SLURM_SUCCESS; } diff --git a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c index 15f01de0171f6fc50aaeb5d6ec2190d273673408..242dd7bc1af736fe311df03b4b604b77037f0a5d 100644 --- a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c +++ b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c @@ -687,10 +687,10 @@ extern void *acct_storage_p_get_connection(bool rollback) #endif } -extern int acct_storage_p_close_connection(PGconn **acct_pgsql_db, bool commit) +extern int acct_storage_p_close_connection(PGconn **acct_pgsql_db) { #ifdef HAVE_PGSQL - pgsql_close_db_connection(acct_pgsql_db, commit); + pgsql_close_db_connection(acct_pgsql_db, 1); return SLURM_SUCCESS; #else @@ -698,6 +698,11 @@ extern int acct_storage_p_close_connection(PGconn **acct_pgsql_db, bool commit) #endif } +extern int acct_storage_p_commit(void *db_conn, bool commit) +{ + return SLURM_SUCCESS; +} + extern int acct_storage_p_add_users(PGconn *acct_pgsql_db, uint32_t uid, List user_list) { @@ -1062,7 +1067,7 @@ try_again: if(!reinit) { error("It looks like the storage has gone " "away trying to reconnect"); - acct_storage_p_close_connection(&acct_pgsql_db, 1); + acct_storage_p_close_connection(&acct_pgsql_db); acct_pgsql_db = acct_storage_p_get_connection(0); reinit = 1; goto try_again; diff --git a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c index e0ab8d654b4088ef43db469d703219637ae29bad..b5b9a6af2d704480914c83d30e39b11ce42f4cee 100644 --- a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c +++ b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c @@ -138,9 +138,30 @@ extern void *acct_storage_p_get_connection(bool rollback) return NULL; } -extern int acct_storage_p_close_connection(void **db_conn, bool commit) +extern int acct_storage_p_close_connection(void **db_conn) { - return slurm_close_slurmdbd_conn(commit); + return slurm_close_slurmdbd_conn(); +} + +extern int acct_storage_p_commit(void *db_conn, bool commit) +{ + slurmdbd_msg_t req; + dbd_fini_msg_t get_msg; + int rc, resp_code; + + memset(&get_msg, 0, sizeof(dbd_fini_msg_t)); + + get_msg.close_conn = 0; + get_msg.commit = (uint16_t)commit; + + req.msg_type = DBD_FINI; + req.data = &get_msg; + rc = slurm_send_slurmdbd_recv_rc_msg(&req, &resp_code); + + if(resp_code != SLURM_SUCCESS) + rc = resp_code; + + return rc; } extern int acct_storage_p_add_users(void *db_conn, uint32_t uid, List user_list) diff --git a/src/sacct/options.c b/src/sacct/options.c index ecf0a6b79b5f9b8d5aacb94de0a6d947eed5c0e0..fb396908c32fa2a3cd60c8c1adb60463bdf9af9a 100644 --- a/src/sacct/options.c +++ b/src/sacct/options.c @@ -1219,7 +1219,7 @@ void sacct_fini() if(params.opt_completion) g_slurm_jobcomp_fini(); else { - acct_storage_g_close_connection(&acct_db_conn, 1); + acct_storage_g_close_connection(&acct_db_conn); slurm_acct_storage_fini(); } } diff --git a/src/sacct/sacct.c b/src/sacct/sacct.c index cec42997f3521dbc51942d9b445a609016104d00..962502e3cedac87357b9d633976e0b47899c672c 100644 --- a/src/sacct/sacct.c +++ b/src/sacct/sacct.c @@ -153,9 +153,6 @@ void _print_header(void); */ sacct_parameters_t params; fields_t fields[] = {{"account", print_account}, -#ifdef HAVE_BG - {"blockid", print_blockid}, -#endif {"cpu", print_cpu}, {"cputime", print_cputime}, {"elapsed", print_elapsed}, diff --git a/src/sacctmgr/Makefile.am b/src/sacctmgr/Makefile.am index 7287581ee771301456f3c3f6d27e06b5ec0d290f..352b6beaf87c133384d7b45befbc9305bee8922a 100644 --- a/src/sacctmgr/Makefile.am +++ b/src/sacctmgr/Makefile.am @@ -7,12 +7,12 @@ INCLUDES = -I$(top_srcdir) bin_PROGRAMS = sacctmgr sacctmgr_SOURCES = \ - user_functions.c \ - cluster_functions.c \ account_functions.c \ - sacctmgr.c \ - sacctmgr.h \ - common.c + cluster_functions.c \ + common.c \ + print.c print.h \ + sacctmgr.c sacctmgr.h \ + user_functions.c convenience_libs = $(top_builddir)/src/api/libslurmhelper.la diff --git a/src/sacctmgr/Makefile.in b/src/sacctmgr/Makefile.in index 80e15fa56a7c1eb5808777f9ba35e41a49d6852c..f42cad5b49b64fcc2b3cfd9497b81025c08a6afa 100644 --- a/src/sacctmgr/Makefile.in +++ b/src/sacctmgr/Makefile.in @@ -69,9 +69,9 @@ CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) -am_sacctmgr_OBJECTS = user_functions.$(OBJEXT) \ - cluster_functions.$(OBJEXT) account_functions.$(OBJEXT) \ - sacctmgr.$(OBJEXT) common.$(OBJEXT) +am_sacctmgr_OBJECTS = account_functions.$(OBJEXT) \ + cluster_functions.$(OBJEXT) common.$(OBJEXT) print.$(OBJEXT) \ + sacctmgr.$(OBJEXT) user_functions.$(OBJEXT) sacctmgr_OBJECTS = $(am_sacctmgr_OBJECTS) am__DEPENDENCIES_1 = sacctmgr_DEPENDENCIES = $(convenience_libs) $(am__DEPENDENCIES_1) @@ -263,12 +263,12 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I$(top_srcdir) sacctmgr_SOURCES = \ - user_functions.c \ - cluster_functions.c \ account_functions.c \ - sacctmgr.c \ - sacctmgr.h \ - common.c + cluster_functions.c \ + common.c \ + print.c print.h \ + sacctmgr.c sacctmgr.h \ + user_functions.c convenience_libs = $(top_builddir)/src/api/libslurmhelper.la sacctmgr_LDADD = \ @@ -350,6 +350,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/account_functions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cluster_functions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sacctmgr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user_functions.Po@am__quote@ diff --git a/src/sacctmgr/account_functions.c b/src/sacctmgr/account_functions.c index 8de8a6525443715feb7478f55fb5d0c69e8226c4..5bc07ff63306955e77f543544fa50d0e85fa90a7 100644 --- a/src/sacctmgr/account_functions.c +++ b/src/sacctmgr/account_functions.c @@ -168,71 +168,6 @@ static void _print_cond(acct_account_cond_t *acct_cond) acct_qos_str(acct_cond->qos)); } -/* static void _update_existing(acct_account_cond_t *acct_cond, */ -/* acct_account_rec_t *new_acct, */ -/* acct_association_rec_t *new_assoc) */ -/* { */ -/* ListIterator itr = NULL; */ -/* char *tmp_char = NULL; */ -/* acct_account_rec_t *acct = NULL; */ -/* acct_association_rec_t *assoc = NULL; */ - -/* if(!acct_cond) { */ -/* error("no acct_account_cond_t * given"); */ -/* return; */ -/* } */ - -/* if(acct_cond->acct_list */ -/* && list_count(acct_cond->acct_list)) { */ -/* itr = list_iterator_create(acct_cond->acct_list); */ -/* while((tmp_char = list_next(itr))) { */ -/* if(!(acct = sacctmgr_find_account(tmp_char))) { */ -/* printf(" Acct '%s' does not exist, " */ -/* "not removing.\n", tmp_char); */ -/* list_remove(itr); */ -/* continue; */ -/* } */ - -/* if(!new_acct) { */ -/* sacctmgr_remove_from_list(sacctmgr_account_list, */ -/* acct); */ -/* } else if(new_acct->interface_node) { */ -/* xfree(acct->interface_node); */ -/* acct->interface_node = */ -/* xstrdup(new_acct->interface_node); */ -/* } */ - -/* if(!(assoc = sacctmgr_find_association( */ -/* NULL, "template_acct", */ -/* tmp_char, NULL))) { */ -/* printf(" Can't find template account for '%s' " */ -/* "something is messed up.\n", tmp_char); */ -/* continue; */ -/* } */ -/* if(!new_assoc) { */ -/* sacctmgr_remove_from_list( */ -/* sacctmgr_association_list, assoc); */ -/* continue; */ -/* } */ - -/* if(new_assoc->fairshare) */ -/* assoc->fairshare = new_assoc->fairshare; */ -/* if(new_assoc->max_jobs) */ -/* assoc->max_jobs = new_assoc->max_jobs; */ -/* if(new_assoc->max_nodes_per_job) */ -/* assoc->max_nodes_per_job = */ -/* new_assoc->max_nodes_per_job; */ -/* if(new_assoc->max_wall_duration_per_job) */ -/* assoc->max_wall_duration_per_job = */ -/* new_assoc->max_wall_duration_per_job; */ -/* if(new_assoc->max_cpu_secs_per_job) */ -/* assoc->max_cpu_secs_per_job = */ -/* new_assoc->max_cpu_secs_per_job; */ -/* } */ -/* list_iterator_destroy(itr); */ -/* } */ -/* } */ - static void _print_rec(acct_account_rec_t *acct) { if(!acct) { @@ -255,6 +190,39 @@ static void _print_rec(acct_account_rec_t *acct) } +static void _remove_existing_accounts(List ret_list) +{ + ListIterator itr = NULL; + ListIterator itr2 = NULL; + char *tmp_char = NULL; + acct_account_rec_t *acct = NULL; + acct_association_rec_t *assoc = NULL; + acct_cluster_rec_t *cluster = NULL; + + if(!ret_list) { + error("no return list given"); + return; + } + + itr = list_iterator_create(ret_list); + itr2 = list_iterator_create(sacctmgr_cluster_list); + + while((tmp_char = list_next(itr))) { + if((acct = sacctmgr_find_account(tmp_char))) + sacctmgr_remove_from_list(sacctmgr_account_list, acct); + + list_iterator_reset(itr2); + while((cluster = list_next(itr2))) { + if((assoc = sacctmgr_find_account_base_assoc( + tmp_char, cluster->name))) + sacctmgr_remove_from_list( + sacctmgr_association_list, assoc); + } + } + list_iterator_destroy(itr); + list_iterator_destroy(itr2); +} + extern int sacctmgr_add_account(int argc, char *argv[]) { @@ -283,43 +251,38 @@ extern int sacctmgr_add_account(int argc, char *argv[]) int limit_set = 0; for (i=0; i<argc; i++) { - if (strncasecmp (argv[i], "Names=", 6) == 0) { - addto_char_list(name_list, argv[i]+6); - } else if (strncasecmp (argv[i], "Name=", 5) == 0) { - addto_char_list(name_list, argv[i]+5); - } else if (strncasecmp (argv[i], "Parent=", 7) == 0) { - parent = xstrdup(argv[i]+7); - } else if (strncasecmp (argv[i], "Description=", 12) == 0) { - description = xstrdup(argv[i]+12); - } else if (strncasecmp (argv[i], "Organization=", 13) == 0) { - organization = xstrdup(argv[i]+13); - } else if (strncasecmp (argv[i], "Qos=", 8) == 0) { - qos = str_2_acct_qos(argv[i]+8); - } else if (strncasecmp (argv[i], "QosLevel=", 14) == 0) { - qos = str_2_acct_qos(argv[i]+14); - } else if (strncasecmp (argv[i], "FairShare=", 10) == 0) { - fairshare = atoi(argv[i]+10); + int end = parse_option_end(argv[i]); + if(!end) { + addto_char_list(name_list, argv[i]+end); + } else if (strncasecmp (argv[i], "Cluster", 1) == 0) { + addto_char_list(cluster_list, argv[i]+end); + } else if (strncasecmp (argv[i], "Description", 1) == 0) { + description = xstrdup(argv[i]+end); + } else if (strncasecmp (argv[i], "FairShare", 1) == 0) { + fairshare = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxJobs=", 8) == 0) { - max_jobs = atoi(argv[i]+8); + } else if (strncasecmp (argv[i], "MaxCPUSecs", 4) == 0) { + max_cpu_secs_per_job = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxNodes=", 9) == 0) { - max_nodes_per_job = atoi(argv[i]+9); + } else if (strncasecmp (argv[i], "MaxJobs", 4) == 0) { + max_jobs = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxWall=", 8) == 0) { - max_wall_duration_per_job = atoi(argv[i]+8); + } else if (strncasecmp (argv[i], "MaxNodes", 4) == 0) { + max_nodes_per_job = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxCPUSecs=", 11) == 0) { - max_cpu_secs_per_job = atoi(argv[i]+11); + } else if (strncasecmp (argv[i], "MaxWall", 4) == 0) { + max_wall_duration_per_job = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "Cluster=", 8) == 0) { - addto_char_list(cluster_list, - argv[i]+8); - } else if (strncasecmp (argv[i], "Clusters=", 9) == 0) { - addto_char_list(cluster_list, - argv[i]+9); + } else if (strncasecmp (argv[i], "Names", 1) == 0) { + addto_char_list(name_list, argv[i]+end); + } else if (strncasecmp (argv[i], "Organization", 1) == 0) { + organization = xstrdup(argv[i]+end); + } else if (strncasecmp (argv[i], "Parent", 1) == 0) { + parent = xstrdup(argv[i]+end); + } else if (strncasecmp (argv[i], "QosLevel", 1) == 0) { + qos = str_2_acct_qos(argv[i]+end); } else { - addto_char_list(name_list, argv[i]); + printf(" Unknown option: %s", argv[i]); } } @@ -367,8 +330,8 @@ extern int sacctmgr_add_account(int argc, char *argv[]) /* we are adding these lists to the global lists and will be freed when they are */ - acct_list = list_create(NULL); - assoc_list = list_create(NULL); + acct_list = list_create(destroy_acct_account_rec); + assoc_list = list_create(destroy_acct_association_rec); itr = list_iterator_create(name_list); while((name = list_next(itr))) { acct = NULL; @@ -392,7 +355,6 @@ extern int sacctmgr_add_account(int argc, char *argv[]) acct->qos = qos; xstrfmtcat(acct_str, " %s\n", name); list_append(acct_list, acct); - list_append(sacctmgr_account_list, acct); } itr_c = list_iterator_create(cluster_list); @@ -436,8 +398,6 @@ extern int sacctmgr_add_account(int argc, char *argv[]) list_append(acct->assoc_list, assoc); else list_append(assoc_list, assoc); - list_append(sacctmgr_association_list, assoc); - } list_iterator_destroy(itr_c); } @@ -489,22 +449,32 @@ end_it: if(!list_count(acct_list) && !list_count(assoc_list)) printf(" Nothing new added.\n"); - else - changes_made = 1; - if(list_count(acct_list)) { - rc = acct_storage_g_add_accounts(db_conn, my_uid, - acct_list); - account_changes = 1; - association_changes = 1; - } + if(list_count(acct_list)) + rc = acct_storage_g_add_accounts(db_conn, my_uid, acct_list); + - list_destroy(acct_list); - if(list_count(assoc_list)) { + if(rc == SLURM_SUCCESS && list_count(assoc_list)) rc = acct_storage_g_add_associations(db_conn, my_uid, assoc_list); - association_changes = 1; + + if(rc == SLURM_SUCCESS) { + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + while((acct = list_pop(acct_list))) { + list_append(sacctmgr_account_list, acct); + while((assoc = list_pop(acct->assoc_list))) { + list_append(sacctmgr_association_list, + assoc); + } + } + while((assoc = list_pop(assoc_list))) { + list_append(sacctmgr_association_list, assoc); + } + } else + acct_storage_g_commit(db_conn, 0); } + list_destroy(acct_list); list_destroy(assoc_list); xfree(parent); @@ -529,17 +499,18 @@ extern int sacctmgr_list_account(int argc, char *argv[]) acct_cond->organization_list = list_create(slurm_destroy_char); for (i=0; i<argc; i++) { - if (strncasecmp (argv[i], "Names=", 6) == 0) { - addto_char_list(acct_cond->acct_list, argv[i]+6); - } else if (strncasecmp (argv[i], "Descriptions=", 13) == 0) { + int end = parse_option_end(argv[i]); + if (strncasecmp (argv[i], "Names", 1) == 0) { + addto_char_list(acct_cond->acct_list, argv[i]+end); + } else if (strncasecmp (argv[i], "Description", 1) == 0) { addto_char_list(acct_cond->description_list, - argv[i]+13); - } else if (strncasecmp (argv[i], "Organizations=", 14) == 0) { + argv[i]+end); + } else if (strncasecmp (argv[i], "Organization", 1) == 0) { addto_char_list(acct_cond->organization_list, - argv[i]+14); - } else if (strncasecmp (argv[i], "QosLevel=", 14) == 0) { + argv[i]+end); + } else if (strncasecmp (argv[i], "Qoslevel", 1) == 0) { acct_cond->qos = - str_2_acct_qos(argv[i]+14); + str_2_acct_qos(argv[i]+end); } else { error("Valid options are 'Names=' " "'Descriptions=' 'Oranizations=' " @@ -547,7 +518,6 @@ extern int sacctmgr_list_account(int argc, char *argv[]) } } - acct_list = acct_storage_g_get_accounts(db_conn, acct_cond); destroy_acct_account_cond(acct_cond); @@ -594,6 +564,7 @@ extern int sacctmgr_modify_account(int argc, char *argv[]) acct_cond->acct_list = list_create(slurm_destroy_char); acct_cond->description_list = list_create(slurm_destroy_char); acct_cond->organization_list = list_create(slurm_destroy_char); + assoc_cond->cluster_list = list_create(slurm_destroy_char); assoc_cond->acct_list = list_create(slurm_destroy_char); @@ -616,11 +587,17 @@ extern int sacctmgr_modify_account(int argc, char *argv[]) printf(" You didn't give me anything to set\n"); destroy_acct_account_cond(acct_cond); destroy_acct_account_rec(acct); + destroy_acct_association_cond(assoc_cond); + destroy_acct_association_rec(assoc); return SLURM_ERROR; } else if(!cond_set) { if(!commit_check("You didn't set any conditions with 'WHERE'.\n" "Are you sure you want to continue?")) { printf("Aborted\n"); + destroy_acct_account_cond(acct_cond); + destroy_acct_account_rec(acct); + destroy_acct_association_cond(assoc_cond); + destroy_acct_association_rec(assoc); return SLURM_SUCCESS; } } @@ -629,25 +606,28 @@ extern int sacctmgr_modify_account(int argc, char *argv[]) _print_rec(acct); printf("\n Where\n"); _print_cond(acct_cond); - if((ret_list = acct_storage_g_modify_accounts(db_conn, my_uid, acct_cond, acct))) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); - printf(" Effected...\n"); + printf(" Modified accounts...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); - changes_made = 1; + if(commit_check("Would you like to commit changes?")) + acct_storage_g_commit(db_conn, 1); + else + acct_storage_g_commit(db_conn, 0); list_destroy(ret_list); } else { rc = SLURM_ERROR; } destroy_acct_account_cond(acct_cond); destroy_acct_account_rec(acct); - + destroy_acct_association_cond(assoc_cond); + destroy_acct_association_rec(assoc); return rc; } @@ -665,32 +645,39 @@ extern int sacctmgr_delete_account(int argc, char *argv[]) acct_cond->acct_list = list_create(slurm_destroy_char); acct_cond->description_list = list_create(slurm_destroy_char); acct_cond->organization_list = list_create(slurm_destroy_char); - assoc_cond->acct_list = list_create(slurm_destroy_char); + assoc_cond->user_list = list_create(slurm_destroy_char); + assoc_cond->acct_list = list_create(slurm_destroy_char); + assoc_cond->cluster_list = list_create(slurm_destroy_char); + assoc_cond->partition_list = list_create(slurm_destroy_char); + if(!_set_cond(&i, argc, argv, acct_cond, assoc_cond)) { printf(" No conditions given to remove, not executing.\n"); + destroy_acct_account_cond(acct_cond); + destroy_acct_association_cond(assoc_cond); return SLURM_ERROR; } - printf(" Deleting accounts where..."); - _print_cond(acct_cond); - if((ret_list = acct_storage_g_remove_accounts(db_conn, my_uid, acct_cond))) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); - printf(" Effected...\n"); + printf(" Deleting accounts...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); - changes_made = 1; - account_changes = 1; + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + _remove_existing_accounts(ret_list); + } else + acct_storage_g_commit(db_conn, 0);; list_destroy(ret_list); } else { rc = SLURM_ERROR; } destroy_acct_account_cond(acct_cond); + destroy_acct_association_cond(assoc_cond); return rc; } diff --git a/src/sacctmgr/cluster_functions.c b/src/sacctmgr/cluster_functions.c index 09508b5c019d5101f3c208deb66c7cf6d8304c15..ff618b83430a45d9cc4b960d97c9376358381e45 100644 --- a/src/sacctmgr/cluster_functions.c +++ b/src/sacctmgr/cluster_functions.c @@ -38,26 +38,29 @@ \*****************************************************************************/ #include "sacctmgr.h" +#include "print.h" static int _set_cond(int *start, int argc, char *argv[], acct_cluster_cond_t *cluster_cond) { int i; int set = 0; + int end = 0; for (i=(*start); i<argc; i++) { - if (strncasecmp (argv[i], "Name=", 5) == 0) { - addto_char_list(cluster_cond->cluster_list, argv[i]+5); - set = 1; - } else if (strncasecmp (argv[i], "Names=", 6) == 0) { - addto_char_list(cluster_cond->cluster_list, argv[i]+6); - set = 1; - } else if (strncasecmp (argv[i], "Set", 3) == 0) { + end = parse_option_end(argv[i]); + if (strncasecmp (argv[i], "Set", 3) == 0) { i--; break; - } else { + } else if(!end) { addto_char_list(cluster_cond->cluster_list, argv[i]); set = 1; + } else if (strncasecmp (argv[i], "Names", 1) == 0) { + addto_char_list(cluster_cond->cluster_list, + argv[i]+end); + set = 1; + } else { + printf(" Unknown condition: %s", argv[i]); } } (*start) = i; @@ -70,28 +73,35 @@ static int _set_rec(int *start, int argc, char *argv[], { int i; int set = 0; + int end = 0; for (i=(*start); i<argc; i++) { - if (strncasecmp (argv[i], "FairShare=", 10) == 0) { - cluster->default_fairshare = atoi(argv[i]+10); + end = parse_option_end(argv[i]); + if (strncasecmp (argv[i], "Where", 5) == 0) { + i--; + break; + } else if(!end) { + printf(" Bad format on %s: End your option with " + "an '=' sign\n", argv[i]); + } else if (strncasecmp (argv[i], "FairShare", 1) == 0) { + cluster->default_fairshare = atoi(argv[i]+end); set = 1; - } else if (strncasecmp (argv[i], "MaxJobs=", 8) == 0) { - cluster->default_max_jobs = atoi(argv[i]+8); + } else if (strncasecmp (argv[i], "MaxJobs", 4) == 0) { + cluster->default_max_jobs = atoi(argv[i]+end); set = 1; - } else if (strncasecmp (argv[i], "MaxNodes=", 9) == 0) { - cluster->default_max_nodes_per_job = atoi(argv[i]+9); + } else if (strncasecmp (argv[i], "MaxNodes", 4) == 0) { + cluster->default_max_nodes_per_job = atoi(argv[i]+end); set = 1; - } else if (strncasecmp (argv[i], "MaxWall=", 8) == 0) { - cluster->default_max_wall_duration_per_job = atoi(argv[i]+8); + } else if (strncasecmp (argv[i], "MaxWall", 4) == 0) { + cluster->default_max_wall_duration_per_job = + atoi(argv[i]+end); set = 1; } else if (strncasecmp (argv[i], "MaxCPUSecs=", 11) == 0) { - cluster->default_max_cpu_secs_per_job = atoi(argv[i]+11); + cluster->default_max_cpu_secs_per_job = + atoi(argv[i]+end); set = 1; - } else if (strncasecmp (argv[i], "Where", 5) == 0) { - i--; - break; } else { - printf(" error: Valid options are\n"); + printf(" Unknown option: %s", argv[i]); } } (*start) = i; @@ -100,33 +110,12 @@ static int _set_rec(int *start, int argc, char *argv[], } -static void _print_cond(acct_cluster_cond_t *cluster_cond) -{ - ListIterator itr = NULL; - char *tmp_char = NULL; - - if(!cluster_cond) { - error("no acct_cluster_cond_t * given"); - return; - } - - if(cluster_cond->cluster_list - && list_count(cluster_cond->cluster_list)) { - itr = list_iterator_create(cluster_cond->cluster_list); - tmp_char = list_next(itr); - printf(" Names = %s\n", tmp_char); - while((tmp_char = list_next(itr))) { - printf(" or %s\n", tmp_char); - } - } -} - -static void _update_existing(List ret_list, - acct_cluster_rec_t *new_cluster) +static void _remove_existing_clusters(List ret_list) { ListIterator itr = NULL; char *tmp_char = NULL; acct_cluster_rec_t *cluster = NULL; + acct_association_rec_t *assoc = NULL; if(!ret_list) { error("no return list given"); @@ -136,35 +125,13 @@ static void _update_existing(List ret_list, itr = list_iterator_create(ret_list); while((tmp_char = list_next(itr))) { - if(!(cluster = sacctmgr_find_cluster(tmp_char))) { - printf(" Cluster '%s' does not exist, " - "not removing.\n", tmp_char); - list_remove(itr); - continue; - } - if(new_cluster) { - if(new_cluster->default_fairshare) - cluster->default_fairshare = - new_cluster->default_fairshare; - if(new_cluster->default_max_jobs) - cluster->default_max_jobs = - new_cluster->default_max_jobs; - if(new_cluster->default_max_nodes_per_job) - cluster->default_max_nodes_per_job = - new_cluster->default_max_nodes_per_job; - if(new_cluster->default_max_wall_duration_per_job) - cluster->default_max_wall_duration_per_job = - new_cluster-> - default_max_wall_duration_per_job; - if(new_cluster->default_max_cpu_secs_per_job) - cluster->default_max_cpu_secs_per_job = - new_cluster-> - default_max_cpu_secs_per_job; - - } else + if((cluster = sacctmgr_find_cluster(tmp_char))) sacctmgr_remove_from_list(sacctmgr_cluster_list, cluster); - + + if((assoc = sacctmgr_find_root_assoc(cluster->name))) + sacctmgr_remove_from_list(sacctmgr_association_list, + assoc); } list_iterator_destroy(itr); } @@ -223,46 +190,61 @@ extern int sacctmgr_add_cluster(int argc, char *argv[]) printf(" Adding Cluster(s)\n"); printf(" Name = %s\n", cluster->name); - - printf(" User Defaults =\n"); - + if(limit_set) + printf(" User Defaults =\n"); if(cluster->default_fairshare <= 0) cluster->default_fairshare = 1; - printf(" Fairshare = %u\n", cluster->default_fairshare); + else + printf(" Fairshare = %u\n", cluster->default_fairshare); - if(cluster->default_max_jobs) + if(cluster->default_max_cpu_secs_per_job <= 0) + cluster->default_max_cpu_secs_per_job = -1; + else + printf(" MaxCPUSecs = %u\n", + cluster->default_max_cpu_secs_per_job); + if(cluster->default_max_jobs <= 0) + cluster->default_max_jobs = -1; + else printf(" MaxJobs = %u\n", cluster->default_max_jobs); - if(cluster->default_max_nodes_per_job) + if(cluster->default_max_nodes_per_job <= 0) + cluster->default_max_nodes_per_job = -1; + else printf(" MaxNodes = %u\n", cluster->default_max_nodes_per_job); - if(cluster->default_max_wall_duration_per_job) + if(cluster->default_max_wall_duration_per_job <= 0) + cluster->default_max_wall_duration_per_job = -1; + else printf(" MaxWall = %u\n", cluster->default_max_wall_duration_per_job); - if(cluster->default_max_cpu_secs_per_job) - printf(" MaxCPUSecs = %u\n", - cluster->default_max_cpu_secs_per_job); cluster_list = list_create(NULL); list_append(cluster_list, cluster); rc = acct_storage_g_add_clusters(db_conn, my_uid, cluster_list); - if(rc == SLURM_SUCCESS) - changes_made = 1; - + if(rc == SLURM_SUCCESS) { + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + + list_append(sacctmgr_cluster_list, cluster); + assoc = xmalloc(sizeof(acct_association_rec_t)); + list_append(sacctmgr_association_list, assoc); + assoc->acct = xstrdup("root"); + assoc->cluster = xstrdup(cluster->name); + assoc->fairshare = cluster->default_fairshare; + assoc->max_jobs = cluster->default_max_jobs; + assoc->max_nodes_per_job = + cluster->default_max_nodes_per_job; + assoc->max_wall_duration_per_job = + cluster->default_max_wall_duration_per_job; + assoc->max_cpu_secs_per_job = + cluster->default_max_cpu_secs_per_job; + } else + acct_storage_g_commit(db_conn, 0); + } else { + printf(" error: problem adding clusters\n"); + } list_destroy(cluster_list); - list_append(sacctmgr_cluster_list, cluster); - assoc = xmalloc(sizeof(acct_association_rec_t)); - list_append(sacctmgr_association_list, assoc); - assoc->acct = xstrdup("root"); - assoc->cluster = xstrdup(cluster->name); - assoc->fairshare = cluster->default_fairshare; - assoc->max_jobs = cluster->default_max_jobs; - assoc->max_nodes_per_job = cluster->default_max_nodes_per_job; - assoc->max_wall_duration_per_job = - cluster->default_max_wall_duration_per_job; - assoc->max_cpu_secs_per_job = cluster->default_max_cpu_secs_per_job; - return rc; } @@ -275,6 +257,9 @@ extern int sacctmgr_list_cluster(int argc, char *argv[]) int i=0; ListIterator itr = NULL; acct_cluster_rec_t *cluster = NULL; + print_field_t name_field; +/* print_field_t fs_field; */ + List print_fields_list; /* types are of print_field_t */ cluster_cond->cluster_list = list_create(slurm_destroy_char); for (i=0; i<argc; i++) { @@ -287,30 +272,40 @@ extern int sacctmgr_list_cluster(int argc, char *argv[]) } } + print_fields_list = list_create(NULL); + + name_field.name = "Name"; + name_field.len = 10; + name_field.print_routine = print_str; + list_append(print_fields_list, &name_field); + +/* fs_field.name = "FS"; */ +/* fs_field.len = 4; */ +/* fs_field.print_routine = print_str; */ +/* list_append(print_fields_list, &fs_field); */ + cluster_list = acct_storage_g_get_clusters(db_conn, cluster_cond); destroy_acct_cluster_cond(cluster_cond); if(!cluster_list) return SLURM_ERROR; + + itr = list_iterator_create(cluster_list); - printf("%-15s %-15s %-5s\n%-15s %-15s %-5s\n", - "Name", "Control Host", "Port", - "---------------", - "---------------", - "-----"); + print_header(print_fields_list); while((cluster = list_next(itr))) { - printf("%-15.15s %-15.15s %-5u\n", - cluster->name, - cluster->control_host, - cluster->control_port); + print_str(VALUE, &name_field, cluster->name); + //print_int(VALUE, &fs_field, cluster->default_fairshare); + printf("\n"); } printf("\n"); list_iterator_destroy(itr); list_destroy(cluster_list); + list_destroy(print_fields_list); return rc; } @@ -318,9 +313,6 @@ extern int sacctmgr_modify_cluster(int argc, char *argv[]) { int rc = SLURM_SUCCESS; int i=0; -/* acct_association_rec_t *assoc = xmalloc(sizeof(acct_association_rec_t)); */ -/* acct_association_cond_t *assoc_cond = */ -/* xmalloc(sizeof(acct_association_cond_t)); */ acct_cluster_rec_t *cluster = xmalloc(sizeof(acct_cluster_rec_t)); acct_cluster_cond_t *cluster_cond = xmalloc(sizeof(acct_cluster_cond_t)); @@ -329,7 +321,6 @@ extern int sacctmgr_modify_cluster(int argc, char *argv[]) List ret_list = NULL; cluster_cond->cluster_list = list_create(slurm_destroy_char); - //assoc_cond->cluster_list = list_create(slurm_destroy_char); for (i=0; i<argc; i++) { if (strncasecmp (argv[i], "Where", 5) == 0) { @@ -361,48 +352,58 @@ extern int sacctmgr_modify_cluster(int argc, char *argv[]) } } -// _update_existing(cluster_cond, cluster, assoc); - - //assoc_cond->acct_list = list_create(slurm_destroy_char); - //list_push(assoc_cond->acct_list, "template_account"); - printf(" Setting\n"); if(rec_set) printf(" User Defaults =\n"); - if(cluster->default_fairshare) + if((int)cluster->default_fairshare <= 0) + cluster->default_fairshare = 1; + else printf(" Fairshare = %u\n", cluster->default_fairshare); - if(cluster->default_max_jobs) + + if((int)cluster->default_max_cpu_secs_per_job <= 0) + cluster->default_max_cpu_secs_per_job = -1; + else + printf(" MaxCPUSecs = %u\n", + cluster->default_max_cpu_secs_per_job); + if((int)cluster->default_max_jobs <= 0) + cluster->default_max_jobs = -1; + else printf(" MaxJobs = %u\n", cluster->default_max_jobs); - if(cluster->default_max_nodes_per_job) - printf(" MaxNodes = %u\n", cluster->default_max_nodes_per_job); - if(cluster->default_max_wall_duration_per_job) + if((int)cluster->default_max_nodes_per_job <= 0) + cluster->default_max_nodes_per_job = -1; + else + printf(" MaxNodes = %u\n", + cluster->default_max_nodes_per_job); + if((int)cluster->default_max_wall_duration_per_job <= 0) + cluster->default_max_wall_duration_per_job = -1; + else printf(" MaxWall = %u\n", cluster->default_max_wall_duration_per_job); - if(cluster->default_max_cpu_secs_per_job) - printf(" MaxCPUSecs = %u\n", - cluster->default_max_cpu_secs_per_job); - printf("\n Where\n"); - _print_cond(cluster_cond); cluster_list = list_create(destroy_acct_cluster_rec); list_append(cluster_list, cluster); - - if((ret_list = acct_storage_g_modify_clusters(db_conn, my_uid, - cluster_cond, - cluster))) { + ret_list = acct_storage_g_modify_clusters( + db_conn, my_uid, cluster_cond, cluster); + if(ret_list && list_count(ret_list)) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); - printf(" Effected...\n"); + printf(" Modifying clusters...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); - changes_made = 1; - list_destroy(ret_list); + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + } else + acct_storage_g_commit(db_conn, 0);; } else { + printf(" error: problem modifying clusters\n"); rc = SLURM_ERROR; } + if(ret_list) + list_destroy(ret_list); + destroy_acct_cluster_cond(cluster_cond); destroy_acct_cluster_rec(cluster); @@ -414,49 +415,46 @@ extern int sacctmgr_delete_cluster(int argc, char *argv[]) int rc = SLURM_SUCCESS; acct_cluster_cond_t *cluster_cond = xmalloc(sizeof(acct_cluster_cond_t)); - acct_association_cond_t *assoc_cond = - xmalloc(sizeof(acct_association_cond_t)); int i=0; List ret_list = NULL; cluster_cond->cluster_list = list_create(slurm_destroy_char); - assoc_cond->cluster_list = list_create(slurm_destroy_char); if(!_set_cond(&i, argc, argv, cluster_cond)) { printf(" No conditions given to remove, not executing.\n"); destroy_acct_cluster_cond(cluster_cond); - destroy_acct_association_cond(assoc_cond); return SLURM_ERROR; } if(!list_count(cluster_cond->cluster_list)) { destroy_acct_cluster_cond(cluster_cond); - destroy_acct_association_cond(assoc_cond); return SLURM_SUCCESS; } - printf(" Deleting clusters where...\n"); - _print_cond(cluster_cond); - - if((ret_list = acct_storage_g_remove_clusters(db_conn, my_uid, - cluster_cond))) { - _update_existing(ret_list, NULL); - - + ret_list = acct_storage_g_remove_clusters( + db_conn, my_uid, cluster_cond); + if(ret_list && list_count(ret_list)) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); - printf(" Effected...\n"); + printf(" Deleting clusters...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); - changes_made = 1; - list_destroy(ret_list); + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + _remove_existing_clusters(ret_list); + } else + acct_storage_g_commit(db_conn, 0);; + } else { + printf(" error: problem deleting clusters\n"); rc = SLURM_ERROR; } + + if(ret_list) + list_destroy(ret_list); destroy_acct_cluster_cond(cluster_cond); - destroy_acct_association_cond(assoc_cond); return rc; } diff --git a/src/sacctmgr/common.c b/src/sacctmgr/common.c index ecc77f34e07c94471005a42bbceb9d559bf01381..35da3a1f6b140e3d326ef119a0645215c67ace3a 100644 --- a/src/sacctmgr/common.c +++ b/src/sacctmgr/common.c @@ -1,5 +1,5 @@ /*****************************************************************************\ - * print.c - definitions for all printing functions. + * common.c - definitions for functions common to all modules in sacctmgr. ***************************************************************************** * Copyright (C) 2008 Lawrence Livermore National Security. * Copyright (C) 2002-2007 The Regents of the University of California. @@ -39,90 +39,19 @@ #include "sacctmgr.h" #define FORMAT_STRING_SIZE 32 - -extern void print_header(void) -{ -/* int i,j; */ -/* for (i=0; i<nprintfields; i++) { */ -/* if (i) */ -/* printf(" "); */ -/* j=printfields[i]; */ -/* (fields[j].print_routine)(HEADLINE, 0); */ -/* } */ -/* printf("\n"); */ -/* for (i=0; i<nprintfields; i++) { */ -/* if (i) */ -/* printf(" "); */ -/* j=printfields[i]; */ -/* (fields[j].print_routine)(UNDERSCORE, 0); */ -/* } */ -/* printf("\n"); */ -} - -extern int print_str(char *str, int width, bool right, bool cut_output) -{ - char format[64]; - int printed = 0; - - if (right == true && width != 0) - snprintf(format, 64, "%%%ds", width); - else if (width != 0) - snprintf(format, 64, "%%.%ds", width); - else { - format[0] = '%'; - format[1] = 's'; - format[2] = '\0'; - } - - if ((width == 0) || (cut_output == false)) { - if ((printed = printf(format, str)) < 0) - return printed; - } else { - char temp[width + 1]; - snprintf(temp, width + 1, format, str); - if ((printed = printf("%s",temp)) < 0) - return printed; - } - - while (printed++ < width) - printf(" "); - - return printed; -} -extern void print_date(void) +extern int parse_option_end(char *option) { - time_t now; - - now = time(NULL); - printf("%s", ctime(&now)); - -} - -extern int print_secs(long time, int width, bool right, bool cut_output) -{ - char str[FORMAT_STRING_SIZE]; - long days, hours, minutes, seconds; - - seconds = time % 60; - minutes = (time / 60) % 60; - hours = (time / 3600) % 24; - days = time / 86400; - - if (days) - snprintf(str, FORMAT_STRING_SIZE, - "%ld-%2.2ld:%2.2ld:%2.2ld", - days, hours, minutes, seconds); - else if (hours) - snprintf(str, FORMAT_STRING_SIZE, - "%ld:%2.2ld:%2.2ld", - hours, minutes, seconds); - else - snprintf(str, FORMAT_STRING_SIZE, - "%ld:%2.2ld", - minutes, seconds); - - print_str(str, width, right, cut_output); - return SLURM_SUCCESS; + int end = 0; + + if(!option) + return 0; + + while(option[end] && option[end] != '=') + end++; + if(!option[end]) + return 0; + end++; + return end; } extern void addto_char_list(List char_list, char *names) diff --git a/src/sacctmgr/print.c b/src/sacctmgr/print.c new file mode 100644 index 0000000000000000000000000000000000000000..e7c0728ed7d7c2163d7bfb07882333467ba6b3b5 --- /dev/null +++ b/src/sacctmgr/print.c @@ -0,0 +1,116 @@ +/*****************************************************************************\ + * print.c - definitions for all printing functions. + ***************************************************************************** + * Copyright (C) 2008 Lawrence Livermore National Security. + * Copyright (C) 2002-2007 The Regents of the University of California. + * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). + * Written by Danny Auble <da@llnl.gov> + * LLNL-CODE-402394. + * + * This file is part of SLURM, a resource management program. + * For details, see <http://www.llnl.gov/linux/slurm/>. + * + * SLURM is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * In addition, as a special exception, the copyright holders give permission + * to link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. You must obey the GNU + * General Public License in all respects for all of the code used other than + * OpenSSL. If you modify file(s) with this exception, you may extend this + * exception to your version of the file(s), but you are not obligated to do + * so. If you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files in + * the program, then also delete it here. + * + * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with SLURM; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +\*****************************************************************************/ +#include "print.h" + +extern void destroy_print_field(void *object) +{ + print_field_t *field = (print_field_t *)object; + + if(field) { + xfree(field->name); + xfree(field); + } +} + +extern void print_header(List print_fields_list) +{ + ListIterator itr = NULL; + print_field_t *object = NULL; + + if(!print_fields_list) + return; + + itr = list_iterator_create(print_fields_list); + while((object = list_next(itr))) { + (object->print_routine)(HEADLINE, object, 0); + } + list_iterator_reset(itr); + printf("\n"); + while((object = list_next(itr))) { + (object->print_routine)(UNDERSCORE, object, 0); + } + list_iterator_destroy(itr); + printf("\n"); +} + +extern void print_date(void) +{ + time_t now; + + now = time(NULL); + printf("%s", ctime(&now)); + +} + +extern void print_str(type_t type, print_field_t *field, char *value) +{ + switch(type) { + case HEADLINE: + printf("%-*.*s ", field->len, field->len, field->name); + break; + case UNDERSCORE: + printf("%-*.*s ", field->len, field->len, + "---------------------------------------"); + break; + case VALUE: + printf("%-*s ", field->len, value); + break; + default: + printf("%-*s ", field->len, "n/a"); + break; + } +} + +extern void print_int(type_t type, print_field_t *field, uint32_t value) +{ + switch(type) { + case HEADLINE: + printf("%-*.*s ", field->len, field->len, field->name); + break; + case UNDERSCORE: + printf("%-*.*s ", field->len, field->len, + "---------------------------------------"); + break; + case VALUE: + printf("%-*u ", field->len, value); + break; + default: + printf("%-*.*s ", field->len, field->len, "n/a"); + break; + } +} diff --git a/src/sacctmgr/print.h b/src/sacctmgr/print.h new file mode 100644 index 0000000000000000000000000000000000000000..09e7d192afa26c4d6dcdb98a7e4f71d9ec5b56e1 --- /dev/null +++ b/src/sacctmgr/print.h @@ -0,0 +1,87 @@ +/*****************************************************************************\ + * print.h - definitions for all printing functions. + ***************************************************************************** + * Copyright (C) 2008 Lawrence Livermore National Security. + * Copyright (C) 2002-2007 The Regents of the University of California. + * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). + * Written by Danny Auble <da@llnl.gov> + * LLNL-CODE-402394. + * + * This file is part of SLURM, a resource management program. + * For details, see <http://www.llnl.gov/linux/slurm/>. + * + * SLURM is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * In addition, as a special exception, the copyright holders give permission + * to link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. You must obey the GNU + * General Public License in all respects for all of the code used other than + * OpenSSL. If you modify file(s) with this exception, you may extend this + * exception to your version of the file(s), but you are not obligated to do + * so. If you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files in + * the program, then also delete it here. + * + * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with SLURM; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +\*****************************************************************************/ +#ifndef __SACCTMGR_PRINT_H__ +#define __SACCTMGR_PRINT_H__ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#if HAVE_GETOPT_H +# include <getopt.h> +#else +# include "src/common/getopt.h" +#endif + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STRING_H +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#include <time.h> +#include <unistd.h> + +#include <slurm/slurm.h> + +#include "src/common/xstring.h" +#include "src/common/slurm_accounting_storage.h" +#include "src/common/jobacct_common.h" + +typedef enum { HEADLINE, + UNDERSCORE, + VALUE +} type_t; + +typedef struct { + char *name; /* name to be printed in header */ + uint16_t len; /* what is the width of the print */ + void (*print_routine) (); /* what is the function to print with */ +} print_field_t; + +extern void destroy_print_field(void *object); +extern void print_header(List print_fields_list); +extern void print_date(void); +extern void print_str(type_t type, print_field_t *field, char *value); +extern void print_int(type_t type, print_field_t *field, uint32_t value); + +#endif diff --git a/src/sacctmgr/sacctmgr.c b/src/sacctmgr/sacctmgr.c index 44f606cc0fc6c4e019e7e8942549d484dfff3a08..7343d908382c4221545fb4a78018dcf75c871b81 100644 --- a/src/sacctmgr/sacctmgr.c +++ b/src/sacctmgr/sacctmgr.c @@ -77,8 +77,6 @@ static void _delete_it (int argc, char *argv[]); static int _get_command (int *argc, char *argv[]); static void _print_version( void ); static int _process_command (int argc, char *argv[]); -static void _close_db(); -static void _handle_intr(); static void _usage (); int @@ -168,8 +166,6 @@ main (int argc, char *argv[]) db_conn = acct_storage_g_get_connection(rollback_flag); my_uid = getuid(); - xsignal(SIGINT, _handle_intr); - if (input_field_count) exit_flag = 1; else @@ -181,8 +177,9 @@ main (int argc, char *argv[]) break; error_code = _get_command (&input_field_count, input_fields); } - _close_db(); + acct_storage_g_close_connection(&db_conn); + printf("\n"); exit(exit_code); } @@ -311,23 +308,6 @@ _process_command (int argc, char *argv[]) fprintf(stderr, "no input"); } else if (strncasecmp (argv[0], "all", 3) == 0) { all_flag = 1; - } else if (strncasecmp (argv[0], "commit", 3) == 0) { - if(changes_made && rollback_flag) { - acct_storage_g_close_connection(&db_conn, 1); - db_conn = acct_storage_g_get_connection(rollback_flag); - association_changes = 0; - account_changes = 0; - cluster_changes = 0; - user_changes = 0; - changes_made = 0; - } - } else if (strncasecmp (argv[0], "rollback", 4) == 0) { - if(changes_made && rollback_flag) { - acct_storage_g_close_connection(&db_conn, 0); - db_conn = acct_storage_g_get_connection(rollback_flag); - do_rollback(); - changes_made = 0; - } } else if (strncasecmp (argv[0], "exit", 1) == 0) { if (argc > 1) { exit_code = 1; @@ -573,39 +553,6 @@ static void _delete_it (int argc, char *argv[]) } } -static void _close_db() -{ - if(changes_made && rollback_flag) { - if(commit_check("Would you like to commit changes?")) - acct_storage_g_close_connection(&db_conn, 1); - else { - acct_storage_g_close_connection(&db_conn, 0); - printf("Changes discarded.\n"); - } - } else - acct_storage_g_close_connection(&db_conn, 0); - printf("\n"); - exit_flag = 1; -} - -static void _handle_intr() -{ - static int been_here = 0; - - if(!been_here) { - been_here = 1; - if(changes_made && rollback_flag) - printf("interrupt (one more to discard any changes)\n"); - _close_db(); - exit(1); - } else { /* second Ctrl-C in half as many seconds */ - acct_storage_g_close_connection(&db_conn, 0); - if(changes_made && rollback_flag) - printf("Changes discarded.\n"); - printf("\n"); - exit(1); - } -} /* _usage - show the valid sacctmgr commands */ void _usage () { @@ -632,7 +579,6 @@ sacctmgr [<OPTION>] [<COMMAND>] \n\ add <ENTITY> <SPECS> add entity \n\ associations when using show/list will list the \n\ associations asspciated with the entity. \n\ - commit commit current updates \n\ delete <ENTITY> <SPECS> delete the specified entity(s) \n\ exit terminate sacctmgr \n\ help print this description of use. \n\ @@ -644,7 +590,6 @@ sacctmgr [<OPTION>] [<COMMAND>] \n\ oneliner report output one record per line. \n\ quiet print no messages other than error messages. \n\ quit terminate this command. \n\ - rollback rollback current updates \n\ show same as list \n\ verbose enable detailed logging. \n\ version display tool version number. \n\ @@ -653,21 +598,19 @@ sacctmgr [<OPTION>] [<COMMAND>] \n\ <ENTITY> may be \"cluster\", \"account\", or \"user\". \n\ \n\ <SPECS> are different for each command entity pair. \n\ - list cluster - Fairshare=, MaxCPUSecs=, \n\ - MaxJobs=, MaxNodes=, MaxWall=, and Names= \n\ + list cluster - Names= \n\ add cluster - Fairshare=, MaxCPUSecs=, \n\ - MaxJobs=, MaxNodes=, MaxWall=, and Name= \n\ + MaxJobs=, MaxNodes=, MaxWall=, and Names= \n\ modify cluster - (set options) Fairshare=, MaxCPUSecs=, \n\ MaxJobs=, MaxNodes=, and MaxWall= \n\ - (where options) Fairshare=, MaxCPUSecs=, \n\ - MaxJobs=, MaxNodes=, MaxWall=, and Name= \n\ + (where options) Names= \n\ delete cluster - Names= \n\ \n\ list account - Clusters=, Descriptions=, Names=, \n\ Organizations=, Parents=, and ShowAssocs \n\ add account - Clusters=, Description=, Fairshare=, \n\ MaxCPUSecs=, MaxJobs=, MaxNodes=, MaxWall=, \n\ - Name=, Organization=, Parent=, and QosLevel \n\ + Names=, Organization=, Parent=, and QosLevel \n\ modify account - (set options) Description=, Fairshare=, \n\ MaxCPUSecs=, MaxJobs=, MaxNodes=, MaxWall=, \n\ Organization=, Parent=, and QosLevel= \n\ @@ -678,14 +621,16 @@ sacctmgr [<OPTION>] [<COMMAND>] \n\ \n\ list user - AdminLevel=, DefaultAccounts=, Names=, \n\ QosLevel=, and ShowAssocs \n\ - add user - Accounts=, AdminLevel=, DefaultAccount=, \n\ - Fairshare=, MaxCPUSecs=, MaxJobs=, \n\ - MaxNodes=, MaxWall=, Name=, and QosLevel= \n\ - modify user - (set options) DefaultAccount=, AdminLevel=, \n\ + add user - Accounts=, AdminLevel=, Clusters=, \n\ + DefaultAccount=, Fairshare=, MaxCPUSecs=, \n\ + MaxJobs=, MaxNodes=, MaxWall=, Names=, \n\ + Partitions=, and QosLevel= \n\ + modify user - (set options) AdminLevel=, DefaultAccount=, \n\ Fairshare=, MaxCPUSecs=, MaxJobs=, \n\ - MaxNodes=, and MaxWall=, and QosLevel= \n\ - (where options) AdminLevel=, DefaultAccounts=, \n\ - and Names= \n\ + MaxNodes=, MaxWall=, and QosLevel= \n\ + (where options) Accounts=, AdminLevel=, \n\ + Clusters=, DefaultAccounts=, Names=, \n\ + Partitions=, and QosLevel= \n\ delete user - Accounts=, AdminLevel=, Clusters=, \n\ DefaultAccounts=, and Names= \n\ \n\ diff --git a/src/sacctmgr/sacctmgr.h b/src/sacctmgr/sacctmgr.h index 0e6c9ea2e892eaf62dc62bf1a013d5cc991bc7a0..1a477f0abeb52b2e9f091d153b91a7c25c5d9b82 100644 --- a/src/sacctmgr/sacctmgr.h +++ b/src/sacctmgr/sacctmgr.h @@ -152,10 +152,7 @@ extern int sacctmgr_delete_account(int argc, char *argv[]); extern int sacctmgr_delete_cluster(int argc, char *argv[]); /* common.c */ -extern void print_header(void); -extern int print_str(char *str, int width, bool right, bool cut_output); -extern void print_date(void); -extern int print_secs(long time, int width, bool right, bool cut_output); +extern int parse_option_end(char *option); extern void addto_char_list(List char_list, char *names); extern void destroy_sacctmgr_action(void *object); extern int commit_check(char *warning); diff --git a/src/sacctmgr/user_functions.c b/src/sacctmgr/user_functions.c index d92f9a8faa68221b2aacfa2b5738320202ae0f51..88c28200ba2af1667122942a8d78eb10bc6f7562 100644 --- a/src/sacctmgr/user_functions.c +++ b/src/sacctmgr/user_functions.c @@ -39,93 +39,121 @@ #include "sacctmgr.h" static int _set_cond(int *start, int argc, char *argv[], - acct_user_cond_t *user_cond) + acct_user_cond_t *user_cond, + acct_association_cond_t *assoc_cond) { int i; - int set = 0; + int u_set = 0; + int a_set = 0; + int end = 0; for (i=(*start); i<argc; i++) { - if (strncasecmp (argv[i], "Name=", 5) == 0) { - addto_char_list(user_cond->user_list, argv[i]+5); - set = 1; - } else if (strncasecmp (argv[i], "Names=", 6) == 0) { - addto_char_list(user_cond->user_list, argv[i]+6); - set = 1; - } else if (strncasecmp (argv[i], "DefaultAccount=", 15) == 0) { - addto_char_list(user_cond->def_acct_list, - argv[i]+15); - set = 1; - } else if (strncasecmp (argv[i], "Default=", 8) == 0) { - addto_char_list(user_cond->def_acct_list, - argv[i]+8); - set = 1; - } else if (strncasecmp (argv[i], "Qos=", 4) == 0) { - user_cond->qos = - str_2_acct_qos(argv[i]+4); - set = 1; - } else if (strncasecmp (argv[i], "QosLevel=", 9) == 0) { - user_cond->qos = - str_2_acct_qos(argv[i]+9); - set = 1; - } else if (strncasecmp (argv[i], "Admin=", 6) == 0) { - user_cond->admin_level = - str_2_acct_admin_level(argv[i]+6); - set = 1; - } else if (strncasecmp (argv[i], "AdminLevel=", 11) == 0) { - user_cond->admin_level = - str_2_acct_admin_level(argv[i]+11); - set = 1; - } else if (strncasecmp (argv[i], "Set", 3) == 0) { + end = parse_option_end(argv[i]); + if (strncasecmp (argv[i], "Set", 3) == 0) { i--; break; - } else { + } else if(!end) { addto_char_list(user_cond->user_list, argv[i]); - set = 1; + addto_char_list(assoc_cond->user_list, argv[i]); + u_set = 1; + } else if (strncasecmp (argv[i], "Account", 2) == 0) { + addto_char_list(assoc_cond->acct_list, argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "AdminLevel", 2) == 0) { + user_cond->admin_level = + str_2_acct_admin_level(argv[i]+end); + u_set = 1; + } else if (strncasecmp (argv[i], "Clusters", 1) == 0) { + addto_char_list(assoc_cond->cluster_list, argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "DefaultAccount", 1) == 0) { + addto_char_list(user_cond->def_acct_list, + argv[i]+end); + u_set = 1; + } else if (strncasecmp (argv[i], "Names", 1) == 0) { + addto_char_list(user_cond->user_list, argv[i]+end); + addto_char_list(assoc_cond->user_list, argv[i]); + u_set = 1; + } else if (strncasecmp (argv[i], "Partition", 3) == 0) { + addto_char_list(assoc_cond->partition_list, + argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "QosLevel", 1) == 0) { + user_cond->qos = + str_2_acct_qos(argv[i]+end); + u_set = 1; + } else { + printf(" Unknown condition: %s", argv[i]); } } (*start) = i; - return set; + if(u_set && a_set) + return 3; + else if(u_set) + return 1; + else if(a_set) + return 2; + return 0; } static int _set_rec(int *start, int argc, char *argv[], - acct_user_rec_t *user) + acct_user_rec_t *user, + acct_association_rec_t *association) { int i; - int set = 0; + int u_set = 0; + int a_set = 0; + int end = 0; for (i=(*start); i<argc; i++) { - if (strncasecmp (argv[i], "DefaultAccount=", 15) == 0) { - user->default_acct = xstrdup(argv[i]+15); - set = 1; - } else if (strncasecmp (argv[i], "Default=", 8) == 0) { - user->default_acct = xstrdup(argv[i]+8); - set = 1; - } else if (strncasecmp (argv[i], "Qos=", 4) == 0) { - user->qos = str_2_acct_qos(argv[i]+4); - set = 1; - } else if (strncasecmp (argv[i], "QosLevel=", 9) == 0) { - user->qos = str_2_acct_qos(argv[i]+9); - set = 1; - } else if (strncasecmp (argv[i], "Admin=", 6) == 0) { - user->admin_level = - str_2_acct_admin_level(argv[i]+6); - set = 1; - } else if (strncasecmp (argv[i], "AdminLevel=", 11) == 0) { - user->admin_level = - str_2_acct_admin_level(argv[i]+11); - set = 1; - } else if (strncasecmp (argv[i], "Where", 5) == 0) { + end = parse_option_end(argv[i]); + if (strncasecmp (argv[i], "Where", 5) == 0) { i--; break; + } else if(!end) { + printf(" Bad format on %s: End your option with " + "an '=' sign\n", argv[i]); + } else if (strncasecmp (argv[i], "AdminLevel", 2) == 0) { + user->admin_level = + str_2_acct_admin_level(argv[i]+end); + u_set = 1; + } else if (strncasecmp (argv[i], "DefaultAccount", 1) == 0) { + user->default_acct = xstrdup(argv[i]+end); + u_set = 1; + } else if (strncasecmp (argv[i], "Fairshare", 1) == 0) { + association->fairshare = atoi(argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "MaxCPUSec", 4) == 0) { + association->max_cpu_secs_per_job = + atoi(argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "MaxJobs", 4) == 0) { + association->max_jobs = atoi(argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "MaxNodes", 4) == 0) { + association->max_nodes_per_job = atoi(argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "MaxWall", 4) == 0) { + association->max_wall_duration_per_job = + atoi(argv[i]+end); + a_set = 1; + } else if (strncasecmp (argv[i], "QosLevel", 1) == 0) { + user->qos = str_2_acct_qos(argv[i]+end); + u_set = 1; } else { - printf(" error: Valid options are 'DefaultAccount=' " - "'QosLevel=' and 'AdminLevel='\n"); + printf(" Unknown option: %s", argv[i]); } } (*start) = i; - return set; + if(u_set && a_set) + return 3; + else if(u_set) + return 1; + else if(a_set) + return 2; + return 0; } static void _print_cond(acct_user_cond_t *user_cond) @@ -186,6 +214,24 @@ static void _print_rec(acct_user_rec_t *user) acct_admin_level_str(user->admin_level)); } +static void _remove_existing_users(List ret_list) +{ + ListIterator itr = NULL; + char *tmp_char = NULL; + acct_user_rec_t *user = NULL; + + if(!ret_list) { + error("no return list given"); + return; + } + + itr = list_iterator_create(ret_list); + while((tmp_char = list_next(itr))) { + if((user = sacctmgr_find_user(tmp_char))) + sacctmgr_remove_from_list(sacctmgr_cluster_list, user); + } + list_iterator_destroy(itr); +} extern int sacctmgr_add_user(int argc, char *argv[]) { @@ -219,6 +265,8 @@ extern int sacctmgr_add_user(int argc, char *argv[]) char *user_str = NULL; char *assoc_str = NULL; int limit_set = 0; + int first = 1; + int acct_first = 1; if(!list_count(sacctmgr_cluster_list)) { printf(" Can't add users, no cluster defined yet.\n" @@ -233,61 +281,45 @@ extern int sacctmgr_add_user(int argc, char *argv[]) assoc_cond->partition_list = list_create(slurm_destroy_char); for (i=0; i<argc; i++) { - if (strncasecmp (argv[i], "Names=", 6) == 0) { - addto_char_list(assoc_cond->user_list, argv[i]+6); - } else if (strncasecmp (argv[i], "Name=", 5) == 0) { - addto_char_list(assoc_cond->user_list, argv[i]+5); - } else if (strncasecmp (argv[i], "Default=", 8) == 0) { - default_acct = xstrdup(argv[i]+8); + int end = parse_option_end(argv[i]); + if(!end) { + addto_char_list(assoc_cond->user_list, argv[i]+end); + } else if (strncasecmp (argv[i], "Accounts", 2) == 0) { addto_char_list(assoc_cond->acct_list, - argv[i]+8); - } else if (strncasecmp (argv[i], "DefaultAccount=", 15) == 0) { - default_acct = xstrdup(argv[i]+15); + argv[i]+end); + } else if (strncasecmp (argv[i], "AdminLevel", 2) == 0) { + admin_level = str_2_acct_admin_level(argv[i]+end); + } else if (strncasecmp (argv[i], "Clusters", 1) == 0) { + addto_char_list(assoc_cond->cluster_list, + argv[i]+end); + } else if (strncasecmp (argv[i], "DefaultAccount", 1) == 0) { + default_acct = xstrdup(argv[i]+end); addto_char_list(assoc_cond->acct_list, - argv[i]+15); - } else if (strncasecmp (argv[i], "Qos=", 4) == 0) { - qos = str_2_acct_qos(argv[i]+4); - } else if (strncasecmp (argv[i], "QosLevel=", 9) == 0) { - qos = str_2_acct_qos(argv[i]+9); - } else if (strncasecmp (argv[i], "Admin=", 6) == 0) { - admin_level = str_2_acct_admin_level(argv[i]+6); - } else if (strncasecmp (argv[i], "AdminLevel=", 11) == 0) { - admin_level = str_2_acct_admin_level(argv[i]+11); - } else if (strncasecmp (argv[i], "FairShare=", 10) == 0) { - fairshare = atoi(argv[i]+10); + argv[i]+end); + } else if (strncasecmp (argv[i], "FairShare", 1) == 0) { + fairshare = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxJobs=", 8) == 0) { - max_jobs = atoi(argv[i]+8); + } else if (strncasecmp (argv[i], "MaxCPUSecs", 4) == 0) { + max_cpu_secs_per_job = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxNodes=", 9) == 0) { - max_nodes_per_job = atoi(argv[i]+9); + } else if (strncasecmp (argv[i], "MaxJobs", 4) == 0) { + max_jobs = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxWall=", 8) == 0) { - max_wall_duration_per_job = atoi(argv[i]+8); + } else if (strncasecmp (argv[i], "MaxNodes", 4) == 0) { + max_nodes_per_job = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "MaxCPUSecs=", 11) == 0) { - max_cpu_secs_per_job = atoi(argv[i]+11); + } else if (strncasecmp (argv[i], "MaxWall", 4) == 0) { + max_wall_duration_per_job = atoi(argv[i]+end); limit_set = 1; - } else if (strncasecmp (argv[i], "Account=", 8) == 0) { - addto_char_list(assoc_cond->acct_list, - argv[i]+8); - } else if (strncasecmp (argv[i], "Accounts=", 9) == 0) { - addto_char_list(assoc_cond->acct_list, - argv[i]+9); - } else if (strncasecmp (argv[i], "Cluster=", 8) == 0) { - addto_char_list(assoc_cond->cluster_list, - argv[i]+8); - } else if (strncasecmp (argv[i], "Clusters=", 9) == 0) { - addto_char_list(assoc_cond->cluster_list, - argv[i]+9); - } else if (strncasecmp (argv[i], "Partition=", 10) == 0) { - addto_char_list(assoc_cond->partition_list, - argv[i]+10); - } else if (strncasecmp (argv[i], "Partitions=", 11) == 0) { + } else if (strncasecmp (argv[i], "Names", 1) == 0) { + addto_char_list(assoc_cond->user_list, argv[i]+end); + } else if (strncasecmp (argv[i], "Partitions", 1) == 0) { addto_char_list(assoc_cond->partition_list, - argv[i]+11); + argv[i]+end); + } else if (strncasecmp (argv[i], "QosLevel", 1) == 0) { + qos = str_2_acct_qos(argv[i]+end); } else { - addto_char_list(assoc_cond->user_list, argv[i]); + printf(" Unknown option: %s", argv[i]); } } @@ -309,21 +341,25 @@ extern int sacctmgr_add_user(int argc, char *argv[]) list_iterator_destroy(itr_c); } + if(!default_acct) { + itr_a = list_iterator_create(assoc_cond->acct_list); + default_acct = xstrdup(list_next(itr_a)); + list_iterator_destroy(itr_a); + } + /* we are adding these lists to the global lists and will be freed when they are */ - user_list = list_create(NULL); - assoc_list = list_create(NULL); + user_list = list_create(destroy_acct_user_rec); + assoc_list = list_create(destroy_acct_association_rec); itr = list_iterator_create(assoc_cond->user_list); while((name = list_next(itr))) { - int acct_first = 1; user = NULL; if(!sacctmgr_find_user(name)) { - int first = 1; if(!default_acct) { printf(" Need a default account for " "these users to add.\n"); rc = SLURM_ERROR; - goto end_it; + goto no_default; } if(first) { if(!sacctmgr_find_account(default_acct)) { @@ -345,7 +381,6 @@ extern int sacctmgr_add_user(int argc, char *argv[]) xstrfmtcat(user_str, " %s\n", name); list_append(user_list, user); - list_append(sacctmgr_user_list, user); } itr_a = list_iterator_create(assoc_cond->acct_list); @@ -377,12 +412,16 @@ extern int sacctmgr_add_user(int argc, char *argv[]) temp_assoc = sacctmgr_find_account_base_assoc( account, cluster); if(!temp_assoc) { - printf(" error: This account '%s' " - "doesn't exist on " - "cluster %s\n" - " Contact your admin " - "to add this account.\n", - account, cluster); + if(acct_first) + printf(" error: This " + "account '%s' " + "doesn't exist on " + "cluster %s\n" + " Contact your " + "admin " + "to add this account.\n", + account, cluster); + continue; }/* else */ /* printf("got %u %s %s %s %s\n", */ @@ -460,8 +499,6 @@ extern int sacctmgr_add_user(int argc, char *argv[]) assoc); else list_append(assoc_list, assoc); - list_append(sacctmgr_association_list, - assoc); xstrfmtcat(assoc_str, " U = %s" "\tA = %s" @@ -508,7 +545,7 @@ extern int sacctmgr_add_user(int argc, char *argv[]) list_iterator_destroy(itr_a); acct_first = 0; } -end_it: +no_default: list_iterator_destroy(itr); destroy_acct_association_cond(assoc_cond); @@ -547,20 +584,49 @@ end_it: max_cpu_secs_per_job); } - if(!list_count(user_list) && !list_count(assoc_list)) + if(!list_count(user_list) && !list_count(assoc_list)) { printf(" Nothing new added.\n"); - else - changes_made = 1; - - if(list_count(user_list)) + goto end_it; + } + + if(list_count(user_list)) { rc = acct_storage_g_add_users(db_conn, my_uid, user_list); + } + + if(rc == SLURM_SUCCESS) { + if(list_count(assoc_list)) + rc = acct_storage_g_add_associations(db_conn, my_uid, + assoc_list); + } else { + printf(" error: Problem adding users\n"); + rc = SLURM_ERROR; + goto end_it; + } + + if(rc == SLURM_SUCCESS) { + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + while((user = list_pop(user_list))) { + list_append(sacctmgr_user_list, user); + while((assoc = list_pop(user->assoc_list))) { + list_append(sacctmgr_association_list, + assoc); + } + } + while((assoc = list_pop(assoc_list))) { + list_append(sacctmgr_association_list, assoc); + } + } else + acct_storage_g_commit(db_conn, 0); + } else { + printf(" error: Problem adding user associations"); + rc = SLURM_ERROR; + } + +end_it: list_destroy(user_list); - if(list_count(assoc_list)) - rc = acct_storage_g_add_associations(db_conn, my_uid, - assoc_list); list_destroy(assoc_list); - xfree(default_acct); return rc; @@ -570,6 +636,8 @@ extern int sacctmgr_list_user(int argc, char *argv[]) { int rc = SLURM_SUCCESS; acct_user_cond_t *user_cond = xmalloc(sizeof(acct_user_cond_t)); + acct_association_cond_t *assoc_cond = + xmalloc(sizeof(acct_association_cond_t)); List user_list; int i=0; ListIterator itr = NULL; @@ -577,11 +645,17 @@ extern int sacctmgr_list_user(int argc, char *argv[]) user_cond->user_list = list_create(slurm_destroy_char); user_cond->def_acct_list = list_create(slurm_destroy_char); + + assoc_cond->user_list = list_create(slurm_destroy_char); + assoc_cond->acct_list = list_create(slurm_destroy_char); + assoc_cond->cluster_list = list_create(slurm_destroy_char); + assoc_cond->partition_list = list_create(slurm_destroy_char); - _set_cond(&i, argc, argv, user_cond); + _set_cond(&i, argc, argv, user_cond, assoc_cond); user_list = acct_storage_g_get_users(db_conn, user_cond); destroy_acct_user_cond(user_cond); + destroy_acct_association_cond(assoc_cond); if(!user_list) return SLURM_ERROR; @@ -611,6 +685,9 @@ extern int sacctmgr_modify_user(int argc, char *argv[]) int rc = SLURM_SUCCESS; acct_user_cond_t *user_cond = xmalloc(sizeof(acct_user_cond_t)); acct_user_rec_t *user = xmalloc(sizeof(acct_user_rec_t)); + acct_association_cond_t *assoc_cond = + xmalloc(sizeof(acct_association_cond_t)); + acct_association_rec_t *assoc = xmalloc(sizeof(acct_association_rec_t)); int i=0; int cond_set = 0, rec_set = 0; List ret_list = NULL; @@ -618,18 +695,23 @@ extern int sacctmgr_modify_user(int argc, char *argv[]) user_cond->user_list = list_create(slurm_destroy_char); user_cond->def_acct_list = list_create(slurm_destroy_char); + assoc_cond->user_list = list_create(slurm_destroy_char); + assoc_cond->acct_list = list_create(slurm_destroy_char); + assoc_cond->cluster_list = list_create(slurm_destroy_char); + assoc_cond->partition_list = list_create(slurm_destroy_char); + for (i=0; i<argc; i++) { if (strncasecmp (argv[i], "Where", 5) == 0) { i++; - if(_set_cond(&i, argc, argv, user_cond)) - cond_set = 1; + cond_set = _set_cond(&i, argc, argv, + user_cond, assoc_cond); + } else if (strncasecmp (argv[i], "Set", 3) == 0) { i++; - if(_set_rec(&i, argc, argv, user)) - rec_set = 1; + rec_set = _set_rec(&i, argc, argv, user, assoc); } else { - if(_set_cond(&i, argc, argv, user_cond)) - cond_set = 1; + cond_set = _set_cond(&i, argc, argv, + user_cond, assoc_cond); } } @@ -637,11 +719,17 @@ extern int sacctmgr_modify_user(int argc, char *argv[]) printf(" You didn't give me anything to set\n"); destroy_acct_user_cond(user_cond); destroy_acct_user_rec(user); + destroy_acct_association_cond(assoc_cond); + destroy_acct_association_rec(assoc); return SLURM_ERROR; } else if(!cond_set) { if(!commit_check("You didn't set any conditions with 'WHERE'.\n" "Are you sure you want to continue?")) { printf("Aborted\n"); + destroy_acct_user_cond(user_cond); + destroy_acct_user_rec(user); + destroy_acct_association_cond(assoc_cond); + destroy_acct_association_rec(assoc); return SLURM_SUCCESS; } } @@ -655,18 +743,23 @@ extern int sacctmgr_modify_user(int argc, char *argv[]) user_cond, user))) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); - printf(" Effected...\n"); + printf(" Modified users...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); - changes_made = 1; + if(commit_check("Would you like to commit changes?")) + acct_storage_g_commit(db_conn, 1); + else + acct_storage_g_commit(db_conn, 0); list_destroy(ret_list); } else { rc = SLURM_ERROR; } destroy_acct_user_cond(user_cond); destroy_acct_user_rec(user); + destroy_acct_association_cond(assoc_cond); + destroy_acct_association_rec(assoc); return rc; } @@ -675,35 +768,47 @@ extern int sacctmgr_delete_user(int argc, char *argv[]) { int rc = SLURM_SUCCESS; acct_user_cond_t *user_cond = xmalloc(sizeof(acct_user_cond_t)); + acct_association_cond_t *assoc_cond = + xmalloc(sizeof(acct_association_cond_t)); int i=0; List ret_list = NULL; user_cond->user_list = list_create(slurm_destroy_char); user_cond->def_acct_list = list_create(slurm_destroy_char); - if(!_set_cond(&i, argc, argv, user_cond)) { + assoc_cond->user_list = list_create(slurm_destroy_char); + assoc_cond->acct_list = list_create(slurm_destroy_char); + assoc_cond->cluster_list = list_create(slurm_destroy_char); + assoc_cond->partition_list = list_create(slurm_destroy_char); + + if(!_set_cond(&i, argc, argv, user_cond, assoc_cond)) { printf(" No conditions given to remove, not executing.\n"); + destroy_acct_user_cond(user_cond); + destroy_acct_association_cond(assoc_cond); return SLURM_ERROR; } - printf(" Deleting users where..."); - _print_cond(user_cond); - if((ret_list = acct_storage_g_remove_users(db_conn, my_uid, user_cond))) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); - printf(" Effected...\n"); + printf(" Deleting users...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); - changes_made = 1; + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + _remove_existing_users(ret_list); + } else + acct_storage_g_commit(db_conn, 0); list_destroy(ret_list); } else { rc = SLURM_ERROR; } + destroy_acct_user_cond(user_cond); + destroy_acct_association_cond(assoc_cond); return rc; } diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c index 1a528d63d26464cc34dd763d34c70593846ae7de..edab5c15b9a18992ff100af2edb4936131d693bc 100644 --- a/src/slurmctld/controller.c +++ b/src/slurmctld/controller.c @@ -445,7 +445,7 @@ int main(int argc, char *argv[]) recover = 2; /* Save any pending state save RPCs */ - acct_storage_g_close_connection(&acct_db_conn, 1); + acct_storage_g_close_connection(&acct_db_conn); assoc_mgr_fini(); } diff --git a/src/slurmdbd/proc_req.c b/src/slurmdbd/proc_req.c index d0d3d54ef57c7f221c7caec4b667a674fa329d66..c5a7d027db8ace0eaa5971985c088766e672e0fa 100644 --- a/src/slurmdbd/proc_req.c +++ b/src/slurmdbd/proc_req.c @@ -826,9 +826,12 @@ static int _fini_conn(void **db_conn, Buf in_buffer, Buf *out_buffer) goto end_it; } - debug2("DBD_FINI: COMMIT:%u", fini_msg->commit); - acct_storage_g_close_connection(db_conn, fini_msg->commit); - + debug2("DBD_FINI: CLOSE:%u COMMIT:%u", + fini_msg->close_conn, fini_msg->commit); + if(fini_msg->close_conn == 1) + rc = acct_storage_g_close_connection(db_conn); + else + rc = acct_storage_g_commit((*db_conn), fini_msg->commit); end_it: slurmdbd_free_fini_msg(fini_msg); *out_buffer = make_dbd_rc_msg(rc, comment, DBD_FINI); diff --git a/src/slurmdbd/rpc_mgr.c b/src/slurmdbd/rpc_mgr.c index 2ed43238414fb2acb36921eb4f119481fa536ff4..c41e6271cdf9a9c415e86214c6788502207c8a15 100644 --- a/src/slurmdbd/rpc_mgr.c +++ b/src/slurmdbd/rpc_mgr.c @@ -237,7 +237,7 @@ static void * _service_connection(void *arg) xfree(msg); } - acct_storage_g_close_connection(&db_conn, 0); + acct_storage_g_close_connection(&db_conn); if (slurm_close_accepted_conn(conn->newsockfd) < 0) error("close(%d): %m", conn->newsockfd); diff --git a/src/slurmdbd/slurmdbd.c b/src/slurmdbd/slurmdbd.c index c2fe980e7f50d2640625421d1403d96eebb3b6c3..0d959de01b427cdb0eea0838e2c016470ceff24e 100644 --- a/src/slurmdbd/slurmdbd.c +++ b/src/slurmdbd/slurmdbd.c @@ -137,10 +137,10 @@ int main(int argc, char *argv[]) if(assoc_mgr_init(db_conn, 0) == SLURM_ERROR) { error("Problem getting cache of data"); - acct_storage_g_close_connection(&db_conn, 0); + acct_storage_g_close_connection(&db_conn); goto end_it; } - acct_storage_g_close_connection(&db_conn, 0); + acct_storage_g_close_connection(&db_conn); /* Create attached thread to process incoming RPCs */ slurm_attr_init(&thread_attr); if (pthread_create(&rpc_handler_thread, &thread_attr, rpc_mgr, NULL))