From 0b87e7303745b0c00531957eb2afcefacb0fe5ca Mon Sep 17 00:00:00 2001 From: Danny Auble <da@llnl.gov> Date: Fri, 11 Apr 2008 20:25:55 +0000 Subject: [PATCH] svn merge -r13857:13860 https://eris.llnl.gov/svn/slurm/branches/slurm-1.2 --- NEWS | 1 + src/common/xstring.c | 35 ++++- .../mysql/accounting_storage_mysql.c | 146 +++++++++++------- 3 files changed, 118 insertions(+), 64 deletions(-) diff --git a/NEWS b/NEWS index 95a6636123b..7ed662fc63d 100644 --- a/NEWS +++ b/NEWS @@ -239,6 +239,7 @@ documents those changes that are of interest to users and admins. -- Record job eligible time in accounting database (for jobacct/gold only). -- Prevent user root from executing a job step within a job allocation belonging to another user. + -- fixed limiting issue for strings larger than 4096 in xstrfmtcat * Changes in SLURM 1.2.26 ========================= diff --git a/src/common/xstring.c b/src/common/xstring.c index a8cb2f03e01..ec6652814f9 100644 --- a/src/common/xstring.c +++ b/src/common/xstring.c @@ -197,17 +197,38 @@ void _xstrftimecat(char **buf, const char *fmt) */ int _xstrfmtcat(char **str, const char *fmt, ...) { + /* This code is the same as xstrdup_printf, but couldn't + * figure out how to pass the ... so just copied the code + */ + /* Start out with a size of 100 bytes. */ + int n, size = 100; + char *p = NULL; va_list ap; - int rc; - char buf[4096]; + + if((p = xmalloc(size)) == NULL) + return 0; + while(1) { + /* Try to print in the allocated space. */ + va_start(ap, fmt); + n = vsnprintf(p, size, fmt, ap); + va_end (ap); + /* If that worked, return the string. */ + if (n > -1 && n < size) + break; + /* Else try again with more space. */ + if (n > -1) /* glibc 2.1 */ + size = n + 1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + if ((p = xrealloc(p, size)) == NULL) + return 0; + } - va_start(ap, fmt); - rc = vsnprintf(buf, 4096, fmt, ap); - va_end(ap); + xstrcat(*str, p); - xstrcat(*str, buf); + xfree(p); - return rc; + return n; } /* diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c index d523b2b3a60..66ce869298a 100644 --- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c +++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c @@ -382,9 +382,7 @@ static int _remove_common(mysql_conn_t *mysql_conn, query = xstrdup_printf("delete from %s where creation_time>%d " "&& (%s);", table, day_old, name_char); - }/* else { */ -/* query = xstrdup_printf("delete from %s where %s",) */ -/* } */ + } xstrfmtcat(query, "update %s set mod_time=%d, deleted=1 " @@ -416,11 +414,14 @@ static int _remove_common(mysql_conn_t *mysql_conn, if(table != assoc_table) { /* If we are doing this on an assoc_table we have already done this, so don't */ - query = xstrdup_printf("select distinct t1.id " - "from %s as t1, %s as t2 " - "where %s && t1.lft between " - "t2.lft and t2.rgt;", + query = xstrdup_printf("select distinct id " + "from %s where %s order by lft;", assoc_table, assoc_table, assoc_char); + /* query = xstrdup_printf("select distinct t1.id " */ +/* "from %s as t1, %s as t2 " */ +/* "where %s && t1.lft between " */ +/* "t2.lft and t2.rgt;", */ +/* assoc_table, assoc_table, assoc_char); */ debug3("%d query\n%s", mysql_conn->conn, query); if(!(result = mysql_db_query_ret(mysql_conn->acct_mysql_db, @@ -455,7 +456,7 @@ static int _remove_common(mysql_conn_t *mysql_conn, } mysql_free_result(result); } else - loc_assoc_char = name_char; + loc_assoc_char = assoc_char; query = xstrdup_printf("delete from %s where creation_time>%d && (%s);" "delete from %s where creation_time>%d && (%s);" @@ -463,6 +464,18 @@ static int _remove_common(mysql_conn_t *mysql_conn, assoc_day_table, day_old, loc_assoc_char, assoc_hour_table, day_old, loc_assoc_char, assoc_month_table, day_old, loc_assoc_char); + debug3("%d query\n%s", mysql_conn->conn, query); + rc = mysql_db_query(mysql_conn->acct_mysql_db, query); + xfree(query); + if(rc != SLURM_SUCCESS) { + if(mysql_conn->rollback) { + mysql_db_rollback(mysql_conn->acct_mysql_db); + } + list_destroy(mysql_conn->update_list); + mysql_conn->update_list = + list_create(destroy_acct_update_object); + return SLURM_ERROR; + } xstrfmtcat(query, "update %s set mod_time=%d, deleted=1 where (%s);" "update %s set mod_time=%d, deleted=1 where (%s);" @@ -471,7 +484,7 @@ static int _remove_common(mysql_conn_t *mysql_conn, assoc_hour_table, now, loc_assoc_char, assoc_month_table, now, loc_assoc_char); - debug3("%d query\n%s", mysql_conn->conn, query); + debug3("%d query\n%s %d", mysql_conn->conn, query, strlen(query)); rc = mysql_db_query(mysql_conn->acct_mysql_db, query); xfree(query); if(rc != SLURM_SUCCESS) { @@ -488,9 +501,7 @@ static int _remove_common(mysql_conn_t *mysql_conn, * day, since they are most likely nothing we really wanted in * the first place. */ - if(table == assoc_table) { - assoc_char = name_char; - } else if(!assoc_char) { + if(!assoc_char) { error("no assoc_char"); if(mysql_conn->rollback) { mysql_db_rollback(mysql_conn->acct_mysql_db); @@ -501,7 +512,7 @@ static int _remove_common(mysql_conn_t *mysql_conn, return SLURM_ERROR; } - query = xstrdup_printf("select id from %s as t1 where " + query = xstrdup_printf("select id from %s where " "creation_time>%d && (%s);", assoc_table, day_old, assoc_char); @@ -2783,11 +2794,11 @@ extern List acct_storage_p_remove_users(mysql_conn_t *mysql_conn, uint32_t uid, list_append(ret_list, object); if(!rc) { xstrfmtcat(name_char, "name='%s'", object); - xstrfmtcat(assoc_char, "t1.user='%s'", object); + xstrfmtcat(assoc_char, "user='%s'", object); rc = 1; } else { xstrfmtcat(name_char, " || name='%s'", object); - xstrfmtcat(assoc_char, " || t1.user='%s'", object); + xstrfmtcat(assoc_char, " || user='%s'", object); } } mysql_free_result(result); @@ -2918,11 +2929,11 @@ extern List acct_storage_p_remove_accts(mysql_conn_t *mysql_conn, uint32_t uid, list_append(ret_list, object); if(!rc) { xstrfmtcat(name_char, "name='%s'", object); - xstrfmtcat(assoc_char, "t1.acct='%s'", object); + xstrfmtcat(assoc_char, "acct='%s'", object); rc = 1; } else { xstrfmtcat(name_char, " || name='%s'", object); - xstrfmtcat(assoc_char, " || t1.acct='%s'", object); + xstrfmtcat(assoc_char, " || acct='%s'", object); } } mysql_free_result(result); @@ -3009,13 +3020,11 @@ extern List acct_storage_p_remove_clusters(mysql_conn_t *mysql_conn, list_append(ret_list, object); if(!rc) { xstrfmtcat(name_char, "name='%s'", object); - xstrfmtcat(extra, "t1.cluster='%s'", object); - xstrfmtcat(assoc_char, "cluster='%s'", object); + xstrfmtcat(extra, "cluster='%s'", object); rc = 1; } else { xstrfmtcat(name_char, " || name='%s'", object); - xstrfmtcat(extra, " || t1.cluster='%s'", object); - xstrfmtcat(assoc_char, " || cluster='%s'", object); + xstrfmtcat(extra, " || cluster='%s'", object); } } mysql_free_result(result); @@ -3031,17 +3040,16 @@ extern List acct_storage_p_remove_clusters(mysql_conn_t *mysql_conn, query = xstrdup_printf("delete from %s where creation_time>%d && (%s);" "delete from %s where creation_time>%d && (%s);" "delete from %s where creation_time>%d && (%s);", - cluster_day_table, day_old, assoc_char, - cluster_hour_table, day_old, assoc_char, - cluster_month_table, day_old, assoc_char); + cluster_day_table, day_old, extra, + cluster_hour_table, day_old, extra, + cluster_month_table, day_old, extra); xstrfmtcat(query, "update %s set mod_time=%d, deleted=1 where (%s);" "update %s set mod_time=%d, deleted=1 where (%s);" "update %s set mod_time=%d, deleted=1 where (%s);", - cluster_day_table, now, assoc_char, - cluster_hour_table, now, assoc_char, - cluster_month_table, now, assoc_char); - xfree(assoc_char); + cluster_day_table, now, extra, + cluster_hour_table, now, extra, + cluster_month_table, now, extra); debug3("%d query\n%s", mysql_conn->conn, query); rc = mysql_db_query(mysql_conn->acct_mysql_db, query); xfree(query); @@ -3058,7 +3066,7 @@ extern List acct_storage_p_remove_clusters(mysql_conn_t *mysql_conn, return NULL; } - assoc_char = xstrdup_printf("t1.acct='root' && (%s)", extra); + assoc_char = xstrdup_printf("acct='root' && (%s)", extra); xfree(extra); if(_remove_common(mysql_conn, DBD_REMOVE_CLUSTERS, now, @@ -3087,7 +3095,8 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, List ret_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; - char *extra = NULL, *query = NULL, *name_char = NULL; + char *extra = NULL, *query = NULL, + *name_char = NULL, *assoc_char = NULL; time_t now = time(NULL); struct passwd *pw = NULL; char *user_name = NULL; @@ -3098,12 +3107,12 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, /* if this changes you will need to edit the corresponding * enum below also t1 is step_table */ char *rassoc_req_inx[] = { - "t1.id", - "t1.acct", - "t1.parent_acct", - "t1.cluster", - "t1.user", - "t1.partition" + "id", + "acct", + "parent_acct", + "cluster", + "user", + "partition" }; enum { @@ -3121,7 +3130,7 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, return NULL; } - xstrcat(extra, "where t1.id>0 && t1.deleted=0"); + xstrcat(extra, "where id>0 && deleted=0"); if((pw=getpwuid(uid))) { user_name = pw->pw_name; @@ -3134,7 +3143,7 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, while((object = list_next(itr))) { if(set) xstrcat(extra, " || "); - xstrfmtcat(extra, "t1.acct='%s'", object); + xstrfmtcat(extra, "acct='%s'", object); set = 1; } list_iterator_destroy(itr); @@ -3148,7 +3157,7 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, while((object = list_next(itr))) { if(set) xstrcat(extra, " || "); - xstrfmtcat(extra, "t1.cluster='%s'", object); + xstrfmtcat(extra, "cluster='%s'", object); set = 1; } list_iterator_destroy(itr); @@ -3162,7 +3171,7 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, while((object = list_next(itr))) { if(set) xstrcat(extra, " || "); - xstrfmtcat(extra, "t1.user='%s'", object); + xstrfmtcat(extra, "user='%s'", object); set = 1; } list_iterator_destroy(itr); @@ -3176,7 +3185,7 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, while((object = list_next(itr))) { if(set) xstrcat(extra, " || "); - xstrfmtcat(extra, "t1.id=%s", object); + xstrfmtcat(extra, "id=%s", object); set = 1; } list_iterator_destroy(itr); @@ -3184,7 +3193,7 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, } if(assoc_q->parent_acct) { - xstrfmtcat(extra, " && t1.parent_acct='%s'", + xstrfmtcat(extra, " && parent_acct='%s'", assoc_q->parent_acct); } @@ -3194,17 +3203,45 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, xstrcat(object, rassoc_req_inx[i]); } + query = xstrdup_printf("select lft, rgt from %s %s FOR UPDATE;", + assoc_table, extra); + xfree(extra); + if(!(result = mysql_db_query_ret(mysql_conn->acct_mysql_db, query))) { + xfree(query); + return NULL; + } + xfree(query); + + rc = 0; + while((row = mysql_fetch_row(result))) { + if(!rc) { + xstrfmtcat(name_char, "lft between %s and %s", + row[0], row[1]); + rc = 1; + } else { + xstrfmtcat(name_char, " || lft between %s and %s", + row[0], row[1]); + } + } + mysql_free_result(result); + + if(!name_char) { + debug3("didn't effect anything\n%s", query); + xfree(query); + return ret_list; + } + + xfree(query); query = xstrdup_printf("select distinct %s " - "from %s as t1, %s as t2 " - "%s && t1.lft between t2.lft and t2.rgt " - "FOR UPDATE;", + "from %s where (%s) order by lft;", object, - assoc_table, assoc_table, extra); + assoc_table, name_char); xfree(extra); xfree(object); debug3("%d query\n%s", mysql_conn->conn, query); if(!(result = mysql_db_query_ret(mysql_conn->acct_mysql_db, query))) { xfree(query); + xfree(name_char); return NULL; } @@ -3237,13 +3274,13 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, } } list_append(ret_list, object); - if(!rc) { - xstrfmtcat(name_char, "id=%s", row[RASSOC_ID]); + xstrfmtcat(assoc_char, "id=%s", row[RASSOC_ID]); rc = 1; } else { - xstrfmtcat(name_char, " || id=%s", row[RASSOC_ID]); + xstrfmtcat(assoc_char, " || id=%s", row[RASSOC_ID]); } + rem_assoc = xmalloc(sizeof(acct_association_rec_t)); rem_assoc->id = atoi(row[RASSOC_ID]); if(_addto_update_list(mysql_conn->update_list, @@ -3254,21 +3291,16 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, } mysql_free_result(result); - if(!list_count(ret_list)) { - debug3("didn't effect anything\n%s", query); - xfree(query); - return ret_list; - } - xfree(query); - if(_remove_common(mysql_conn, DBD_REMOVE_ASSOCS, now, - user_name, assoc_table, name_char, NULL) + user_name, assoc_table, name_char, assoc_char) == SLURM_ERROR) { list_destroy(ret_list); xfree(name_char); + xfree(assoc_char); return NULL; } xfree(name_char); + xfree(assoc_char); return ret_list; #else -- GitLab