[torquedev] new node attribute: "note"
Marcus R. Epperson
mrepper at sandia.gov
Wed Feb 7 15:11:27 MST 2007
Patch against: torque-2.2.0-snap.200702052054.tar.gz
This version makes no attempt to truncate or sanitize notes. It simply rejects them if they are too long or contain a newline (with appropriate warnings/errors to the user and in server_logs).
# pbsnodes -n $BIGNOTE node1
Warning: note exceeds length limit (256) - server may reject it...
Error setting note attribute for node1 - Illegal value for note
And the corresponding server_logs line:
...;PBS_Server;Req;set_note_str;Warning: Client attempted to set note with len (4510) > MAX_NOTE (256)
I believe I have addressed the other issues mentioned in previous emails. Please let me know if you see anything else amiss.
Also attached is a perl-PBS version of "pbsnodes -n". It was useful to me in testing, so I thought others might find it useful.
-Marcus
-------------- next part --------------
#!/usr/bin/perl
use strict;
use warnings;
use PBS qw/ pbs_connect pbs_manager pbs_default pbs_geterrmsg pbs_disconnect /;
use POSIX qw/ strerror /;
my $note = shift @ARGV;
usage() unless defined $note;
usage() unless @ARGV;
$note = "" if $note eq "n";
for my $node (@ARGV) {
my $con = cnt2server(pbs_default());
$con or die;
my $rc = PBS::pbs_manager($con, $PBS::MGR_CMD_SET, $PBS::MGR_OBJ_NODE, $node, {note=>$note}, undef);
print PBS::pbs_geterrmsg($con)."\n" if $rc;
pbs_disconnect($con);
}
# END
sub cnt2server {
my $server = shift;
my $con = pbs_connect($server);
if ($con <= 0) {
print "Connect to $server failed: ".get_modPBS_errmsg($PBS::pbs_errno)."\n";
return undef;
}
return $con;
}
sub get_modPBS_errmsg {
my $error=shift;
if ($error > $PBS::PBSE_) {
if ($error == $PBS::PBSE_BADHOST) {
return "Unknown Host";
} elsif ($error == $PBS::PBSE_NOCONNECTS) {
return "Too many open connections";
} elsif ($error == $PBS::PBSE_NOSERVER) {
return "No default server name";
} elsif ($error == $PBS::PBSE_SYSTEM) {
return "System call failure";
} elsif ($error == $PBS::PBSE_PERM) {
return "No Permission";
} else {
return "Communication failure";
}
}
return strerror($error) || "$error";
}
sub usage {
die "Usage: $0 <node>...\n";
}
-------------- next part --------------
--- torque-2.2.0-snap.200702052054.orig/src/cmds/pbsnodes.c 2007-02-05 20:54:47.000000000 -0700
+++ torque-2.2.0-snap.200702052054/src/cmds/pbsnodes.c 2007-02-07 13:58:29.000000000 -0700
@@ -122,6 +122,7 @@
#define ALLI 5
#define PURGE 6
#define DIAG 7
+#define NOTE 8
int quiet = 0;
@@ -143,6 +144,48 @@ mbool_t DisplayXML = FALSE;
/*
+ * set_note - set the note attribute for a node
+ *
+ */
+static int set_note(
+ int con,
+ char *name,
+ char *msg
+)
+{
+ char *errmsg;
+ struct attropl new;
+ int rc;
+
+ new.name = ATTR_NODE_note;
+ new.resource = NULL;
+ new.value = msg;
+ new.op = SET;
+ new.next = NULL;
+
+ rc = pbs_manager(
+ con,
+ MGR_CMD_SET,
+ MGR_OBJ_NODE,
+ name,
+ &new,
+ NULL);
+
+ if (rc && !quiet)
+ {
+ fprintf(stderr,"Error setting note attribute for %s - ", name);
+
+ if ((errmsg = pbs_geterrmsg(con)) != NULL)
+ fprintf(stderr,"%s\n", errmsg);
+ else
+ fprintf(stderr,"(error %d)\n", pbs_errno);
+ }
+
+ return rc;
+}
+
+
+/*
* cmp_node_name - compare two node names, allow the second to match the
* first if the same up to a dot ('.') in the second; i.e.
* "foo" == "foo.bar"
@@ -366,6 +409,9 @@ int main(
char **pa;
struct batch_status *pbstat;
int flag = ALLI;
+ char *note;
+ int note_flag = 0;
+ int len;
/* get default server, may be changed by -s option */
@@ -374,7 +420,7 @@ int main(
if (def_server == NULL)
def_server = "";
- while ((i = getopt(argc,argv,"acdlopqrs:x-:")) != EOF)
+ while ((i = getopt(argc,argv,"acdlopqrs:x-:n:")) != EOF)
{
switch(i)
{
@@ -440,6 +486,39 @@ int main(
break;
+ case 'n':
+
+ note_flag = 1;
+
+ /* preserve any previous option other than the default,
+ * to allow -n to be combined with -o, -c, etc
+ */
+ if ( flag == ALLI )
+ flag = NOTE;
+
+ note = strdup(optarg);
+
+ if ( note != NULL )
+ {
+ /* -n n is the same as -n "" -- it clears the note */
+ if ( !strcmp(note,"n") )
+ {
+ *note = '\0';
+ }
+
+ len = strlen(note);
+
+ if ( len > MAX_NOTE )
+ fprintf(stderr,"Warning: note exceeds length limit (%d) - server may reject it...\n",
+ MAX_NOTE);
+
+ if ( strchr(note,'\n') != NULL )
+ fprintf(stderr,"Warning: note contains a newline - server may reject it...\n");
+
+ }
+
+ break;
+
case '-':
if ((optarg != NULL) && !strcmp(optarg,"version"))
@@ -473,7 +552,7 @@ int main(
{
if (!quiet)
{
- fprintf(stderr,"usage:\t%s [-{c|d|o|p|r}][-s server] [-q] node node ...\n",
+ fprintf(stderr,"usage:\t%s [-{c|d|o|p|r}][-s server] [-n \"note\"] [-q] node node ...\n",
argv[0]);
fprintf(stderr,"\t%s -l [-s server] [-q]\n",
@@ -552,6 +631,16 @@ int main(
}
} /* END if ((flag == ALLI) || (flag == DOWN) || (flag == LIST) || (flag == DIAG)) */
+
+ if ( note_flag )
+ {
+ /* set the note attrib string on specified nodes */
+ for (pa = argv + optind;*pa;pa++)
+ {
+ set_note(con,*pa,note);
+ }
+ }
+
switch (flag)
{
case DIAG:
--- torque-2.2.0-snap.200702052054.orig/src/include/attribute.h 2006-10-19 17:10:09.000000000 -0600
+++ torque-2.2.0-snap.200702052054/src/include/attribute.h 2007-02-06 10:51:42.000000000 -0700
@@ -435,6 +435,8 @@ extern int node_np_action A_(( att
extern int node_ntype A_(( attribute*, void*, int));
extern int node_prop_list A_(( attribute*, void*, int));
extern int node_status_list A_(( attribute*, void*, int));
+extern int node_note A_(( attribute*, void*, int));
+extern int set_note_str A_((attribute *attr,attribute *new, enum batch_op));
/* Token manipulation functions */
--- torque-2.2.0-snap.200702052054.orig/src/include/pbs_ifl.h 2007-02-05 20:54:46.000000000 -0700
+++ torque-2.2.0-snap.200702052054/src/include/pbs_ifl.h 2007-02-07 14:01:21.000000000 -0700
@@ -263,6 +263,7 @@
#define ATTR_NODE_ntype "ntype"
#define ATTR_NODE_jobs "jobs"
#define ATTR_NODE_status "status"
+#define ATTR_NODE_note "note"
@@ -334,6 +335,8 @@
#ifndef MAXNAMLEN
#define MAXNAMLEN 255
#endif
+#define MAX_NOTE 256 /* max node note length */
+#define MAX_NOTE_STR "256" /* max node note length as a string literal (this MUST match MAX_NOTE) */
#define PBS_MAXUSER 16 /* max user name length */
#define PBS_MAXGRPN 16 /* max group name length */
--- torque-2.2.0-snap.200702052054.orig/src/include/pbs_nodes.h 2006-10-19 17:10:09.000000000 -0600
+++ torque-2.2.0-snap.200702052054/src/include/pbs_nodes.h 2007-02-06 10:51:42.000000000 -0700
@@ -123,6 +123,7 @@ struct pbsnode {
u_long *nd_addrs; /* IP addresses of host */
struct array_strings *nd_prop; /* array of properities */
struct array_strings *nd_status;
+ char *nd_note; /* note set by administrator */
int nd_stream; /* RPP stream to Mom on host */
enum psit nd_flag;
short nd_nprops; /* number of properties */
@@ -195,6 +196,7 @@ int tlist(tree *,char *,int);
#define WRITENODE_STATE 0x1 /*associated w/ offline*/
#define WRITE_NEW_NODESFILE 0x2 /*changed: deleted,ntype,or properties*/
+#define WRITENODE_NOTE 0x4 /*associated w/ note*/
/*
* Although at the present time a struct pbssnode doesn't have an array of
@@ -216,6 +218,7 @@ enum nodeattr {
ND_ATR_ntype,
ND_ATR_jobs,
NODE_ATR_status,
+ NODE_ATR_note,
ND_ATR_LAST }; /* WARNING: Must be the highest valued enum */
--- torque-2.2.0-snap.200702052054.orig/src/include/qmgr_node_public.h 2006-06-19 18:23:29.000000000 -0600
+++ torque-2.2.0-snap.200702052054/src/include/qmgr_node_public.h 2007-02-06 10:51:42.000000000 -0700
@@ -95,3 +95,4 @@ ATTR_NODE_properties,
ATTR_NODE_np,
ATTR_NODE_ntype,
ATTR_NODE_status,
+ATTR_NODE_note,
--- torque-2.2.0-snap.200702052054.orig/src/include/server_limits.h 2006-08-09 18:27:27.000000000 -0600
+++ torque-2.2.0-snap.200702052054/src/include/server_limits.h 2007-02-06 10:51:42.000000000 -0700
@@ -124,6 +124,7 @@
#define PBS_TRACKING "tracking"
#define NODE_DESCRIP "nodes"
#define NODE_STATUS "node_status"
+#define NODE_NOTE "node_note"
#define PBS_NET_MAX_CONNECTIONS 1024 /* increased from 256 */
--- torque-2.2.0-snap.200702052054.orig/src/lib/Libattr/attr_node_func.c 2006-10-19 17:10:15.000000000 -0600
+++ torque-2.2.0-snap.200702052054/src/lib/Libattr/attr_node_func.c 2007-02-07 14:48:46.000000000 -0700
@@ -96,6 +96,10 @@
#include "job.h"
#include "pbs_nodes.h"
#include "pbs_error.h"
+#include "log.h"
+#if SYSLOG
+#include <syslog.h>
+#endif
extern int LOGLEVEL;
@@ -1052,6 +1056,128 @@ int node_status_list(
return(rc);
} /* END node_status_list() */
-/* END attr_node_func.c */
+/*
+ * node_note - Either derive a note attribute from the node
+ * or update node's note from attribute's list.
+ */
+
+int node_note(
+
+ attribute *new, /*derive status into this attribute*/
+ void *pnode, /*pointer to a pbsnode struct */
+ int actmode) /*action mode; "NEW" or "ALTER" */
+
+ {
+ int rc = 0;
+ struct pbsnode *np;
+ attribute temp;
+
+ np = (struct pbsnode *)pnode; /* because of at_action arg type */
+
+ switch(actmode)
+ {
+ case ATR_ACTION_NEW:
+
+ /* if node has a note, then copy string into temp */
+ /* to use to setup a copy, otherwise setup empty */
+
+ if (np->nd_note != NULL)
+ {
+ /* setup temporary attribute with the string from the node */
+
+ temp.at_val.at_str = np->nd_note;
+ temp.at_flags = ATR_VFLAG_SET;
+ temp.at_type = ATR_TYPE_STR;
+
+ rc = set_note_str(new,&temp,SET);
+ }
+ else
+ {
+ /* node has no properties, setup empty attribute */
+
+ new->at_val.at_str = NULL;
+ new->at_flags = 0;
+ new->at_type = ATR_TYPE_STR;
+ }
+
+ break;
+
+ case ATR_ACTION_ALTER:
+
+ if (np->nd_note != NULL)
+ {
+ free(np->nd_note);
+
+ np->nd_note = NULL;
+ }
+
+ /* update node with new string */
+
+ np->nd_note = new->at_val.at_str;
+ new->at_val.at_str = NULL;
+ break;
+
+ default:
+
+ rc = PBSE_INTERNAL;
+
+ break;
+ } /* END switch(actmode) */
+
+ return(rc);
+ } /* END node_note() */
+
+
+
+/*
+ * a set_str() wrapper with sanity checks for notes
+ */
+int set_note_str(attr, new, op)
+ struct attribute *attr;
+ struct attribute *new;
+ enum batch_op op;
+ {
+ static char id[] = "set_note_str";
+ size_t nsize;
+ int rc = 0;
+
+ assert( attr && new && new->at_val.at_str && (new->at_flags & ATR_VFLAG_SET));
+ nsize = strlen(new->at_val.at_str); /* length of new note */
+
+ if (nsize > MAX_NOTE)
+ {
+ sprintf(log_buffer,"Warning: Client attempted to set note with len (%d) > MAX_NOTE (%d)",
+ nsize,
+ MAX_NOTE);
+
+ log_record(
+ PBSEVENT_SECURITY,
+ PBS_EVENTCLASS_REQUEST,
+ id,
+ log_buffer);
+
+ rc = PBSE_BADNDATVAL;
+ }
+
+ if ( strchr(new->at_val.at_str,'\n') != NULL )
+ {
+ sprintf(log_buffer,"Warning: Client attempted to set note with a newline char");
+
+ log_record(
+ PBSEVENT_SECURITY,
+ PBS_EVENTCLASS_REQUEST,
+ id,
+ log_buffer);
+
+ rc = PBSE_BADNDATVAL;
+ }
+
+ if ( rc )
+ return rc;
+ else
+ return set_str(attr,new,op);
+ } /* END set_note_str() */
+
+/* END attr_node_func.c */
--- torque-2.2.0-snap.200702052054.orig/src/server/node_attr_def.c 2006-10-19 17:10:34.000000000 -0600
+++ torque-2.2.0-snap.200702052054/src/server/node_attr_def.c 2007-02-06 10:51:42.000000000 -0700
@@ -195,5 +195,19 @@ attribute_def node_attr_def[] = {
MGR_ONLY_SET,
ATR_TYPE_ARST,
PARENT_TYPE_NODE,
- }
+ },
+
+/* NODE_ATR_note */
+ { ATTR_NODE_note, /* "note" */
+ decode_str,
+ encode_str,
+ set_note_str,
+ comp_str,
+ free_str,
+ node_note,
+ NO_USER_SET,
+ ATR_TYPE_STR,
+ PARENT_TYPE_NODE,
+ },
+
};
--- torque-2.2.0-snap.200702052054.orig/src/server/node_func.c 2006-10-19 17:10:29.000000000 -0600
+++ torque-2.2.0-snap.200702052054/src/server/node_func.c 2007-02-06 10:51:42.000000000 -0700
@@ -136,6 +136,7 @@ extern int svr_clnodes;
extern char *path_nodes_new;
extern char *path_nodes;
extern char *path_nodestate;
+extern char *path_nodenote;
extern int LOGLEVEL;
extern attribute_def node_attr_def[]; /* node attributes defs */
@@ -430,6 +431,7 @@ static short old_state = (short)0xdead;
static short old_ntype = (short)0xdead; /*node's ntype */
static int old_nprops = 0xdead; /*node's nprops */
static int old_nstatus = 0xdead; /*node's nstatus */
+static char *old_note = NULL; /*node's note */
@@ -457,6 +459,18 @@ void save_characteristic(
old_first = pnode->nd_first;
old_f_st = pnode->nd_f_st;
+ /* if there was a previous note stored here, free it first */
+ if (old_note != NULL)
+ {
+ free(old_note);
+ old_note = NULL;
+ }
+
+ if (pnode->nd_note != NULL)
+ {
+ old_note = strdup(pnode->nd_note);
+ }
+
return;
} /* END save_characteristic() */
@@ -546,6 +560,18 @@ int chk_characteristic(
if ((old_nprops != pnode->nd_nprops) || (old_first != pnode->nd_first))
*pneed_todo |= WRITE_NEW_NODESFILE;
+ if (pnode->nd_note != old_note) /* not both NULL or with the same address */
+ {
+ if (pnode->nd_note == NULL || old_note == NULL)
+ {
+ *pneed_todo |= WRITENODE_NOTE; /*node's note changed*/
+ }
+ else if (strcmp(pnode->nd_note,old_note))
+ {
+ *pneed_todo |= WRITENODE_NOTE; /*node's note changed*/
+ }
+ }
+
old_address = NULL;
return(0);
@@ -603,6 +629,8 @@ int status_nodeattrib(
atemp[i].at_val.at_jinfo = pnode;
else if (!strcmp ((padef + i)->at_name, ATTR_NODE_np))
atemp[i].at_val.at_long = pnode->nd_nsn;
+ else if (!strcmp ((padef + i)->at_name, ATTR_NODE_note))
+ atemp[i].at_val.at_str = pnode->nd_note;
else
{
/*we don't ever expect this*/
@@ -729,6 +757,7 @@ static void initialize_pbsnode(
pnode->nd_order = 0;
pnode->nd_prop = NULL;
pnode->nd_status = NULL;
+ pnode->nd_note = NULL;
pnode->nd_psn = NULL;
pnode->nd_state = INUSE_NEEDS_HELLO_PING | INUSE_DOWN;
pnode->nd_first = init_prop(pnode->nd_name);
@@ -1446,6 +1475,7 @@ int setup_nodes(void)
FILE *nin;
char line[256];
+ char note[MAX_NOTE+1];
char *nodename;
char propstr[256];
char *token;
@@ -1689,6 +1719,47 @@ int setup_nodes(void)
fclose(nin);
}
+ /* initialize note attributes */
+ nin = fopen(path_nodenote,"r");
+
+ if (nin != NULL)
+ {
+
+ while (fscanf(nin,"%s %" MAX_NOTE_STR "[^\n]",
+ line,
+ note) == 2)
+ {
+ for (i = 0;i < svr_totnodes;i++)
+ {
+ np = pbsndmast[i];
+
+ if (np->nd_state & INUSE_DELETED)
+ continue;
+
+ if (strcmp(np->nd_name,line) == 0)
+ {
+ np->nd_note = strdup(note);
+
+ if ( np->nd_note == NULL )
+ {
+ sprintf(log_buffer,"couldn't allocate space for note (node = %s)",
+ np->nd_name);
+
+ log_record(
+ PBSEVENT_SCHED,
+ PBS_EVENTCLASS_REQUEST,
+ id,
+ log_buffer);
+ }
+
+ break;
+ }
+ }
+ }
+
+ fclose(nin);
+ }
+
/* SUCCESS */
return(0);
--- torque-2.2.0-snap.200702052054.orig/src/server/node_manager.c 2006-12-21 16:28:26.000000000 -0700
+++ torque-2.2.0-snap.200702052054/src/server/node_manager.c 2007-02-06 10:51:42.000000000 -0700
@@ -136,6 +136,7 @@ static int svr_numcfgnodes = 0;
static int exclusive; /* node allocation type */
static FILE *nstatef = NULL;
+static FILE *nnotef = NULL;
static int num_addrnote_tasks = 0; /* number of outstanding send_cluster_addrs tasks */
extern int server_init_type;
@@ -148,6 +149,8 @@ extern char *path_home;
extern char *path_nodes;
extern char *path_nodes_new;
extern char *path_nodestate;
+extern char *path_nodenote;
+extern char *path_nodenote_new;
extern unsigned int pbs_mom_port;
extern char server_name[];
@@ -2101,6 +2104,94 @@ void write_node_state()
+/* Create a new node_note file then overwrite the previous one.
+ *
+ * The note file could get up to:
+ * (# of nodes) * (2 + MAX_NODE_NAME + MAX_NOTE) bytes in size
+ */
+int write_node_note()
+ {
+ static char id[] = "write_node_note";
+ struct pbsnode *np;
+ int i, j;
+ FILE *nin;
+
+ if (LOGLEVEL >= 2)
+ {
+ DBPRT(("%s: entered\n",
+ id))
+ }
+
+ if ((nin = fopen(path_nodenote_new,"w")) == NULL)
+ goto err1;
+
+ if ((svr_totnodes == 0) || (pbsndmast == NULL))
+ {
+ log_event(
+ PBSEVENT_ADMIN,
+ PBS_EVENTCLASS_SERVER,
+ "node_note",
+ "Server has empty nodes list");
+
+ fclose(nin);
+
+ return(-1);
+ }
+
+ /* for each node ... */
+
+ for (i = 0;i < svr_totnodes;++i)
+ {
+ np = pbsndmast[i];
+
+ if (np->nd_state & INUSE_DELETED)
+ continue;
+
+ /* write node name followed by its note string */
+
+ if (np->nd_note != NULL && np->nd_note != '\0')
+ {
+ fprintf(nin,"%s %s\n",
+ np->nd_name,
+ np->nd_note);
+ }
+ }
+
+ fflush(nin);
+
+ if (ferror(nin))
+ {
+ fclose(nin);
+ goto err1;
+ }
+
+ fclose(nin);
+
+ if (rename(path_nodenote_new, path_nodenote) != 0)
+ {
+ log_event(
+ PBSEVENT_ADMIN,
+ PBS_EVENTCLASS_SERVER,
+ "node_note",
+ "replacing old node note file failed");
+
+ return(-1);
+ }
+
+ return(0);
+
+ err1:
+ log_event(
+ PBSEVENT_ADMIN,
+ PBS_EVENTCLASS_SERVER,
+ "node_note",
+ "Node note file update failed");
+
+ return(-1);
+
+ } /* END write_node_note() */
+
+
/*
* free_prop - free list of prop structures created by proplist()
--- torque-2.2.0-snap.200702052054.orig/src/server/pbsd_init.c 2006-11-07 18:34:41.000000000 -0700
+++ torque-2.2.0-snap.200702052054/src/server/pbsd_init.c 2007-02-06 10:51:42.000000000 -0700
@@ -176,6 +176,8 @@ extern char *path_track;
extern char *path_nodes;
extern char *path_nodes_new;
extern char *path_nodestate;
+extern char *path_nodenote;
+extern char *path_nodenote_new;
extern char *path_resources;
extern int queue_rank;
@@ -425,6 +427,8 @@ int pbsd_init(
path_nodes = build_path(path_priv, NODE_DESCRIP, NULL);
path_nodes_new = build_path(path_priv, NODE_DESCRIP, new_tag);
path_nodestate = build_path(path_priv, NODE_STATUS, NULL);
+ path_nodenote = build_path(path_priv, NODE_NOTE, NULL);
+ path_nodenote_new = build_path(path_priv, NODE_NOTE, new_tag);
path_resources = build_path(path_home, PBS_RESOURCES, NULL);
init_resc_defs(path_resources);
--- torque-2.2.0-snap.200702052054.orig/src/server/pbsd_main.c 2007-02-05 20:54:49.000000000 -0700
+++ torque-2.2.0-snap.200702052054/src/server/pbsd_main.c 2007-02-06 10:51:42.000000000 -0700
@@ -168,6 +168,8 @@ char *path_track;
char *path_nodes;
char *path_nodes_new;
char *path_nodestate;
+char *path_nodenote;
+char *path_nodenote_new;
char *path_resources;
extern char *msg_daemonname;
extern int pbs_errno;
--- torque-2.2.0-snap.200702052054.orig/src/server/req_manager.c 2006-12-15 14:28:39.000000000 -0700
+++ torque-2.2.0-snap.200702052054/src/server/req_manager.c 2007-02-06 10:51:42.000000000 -0700
@@ -1634,6 +1634,15 @@ void mgr_node_set(
need_todo &= ~(WRITENODE_STATE);
}
+ if (need_todo & WRITENODE_NOTE)
+ {
+ /*some nodes have new "note"s*/
+
+ write_node_note( );
+
+ need_todo &= ~(WRITENODE_NOTE);
+ }
+
if (need_todo & WRITE_NEW_NODESFILE)
{
/*create/delete/prop/ntype change*/
More information about the torquedev
mailing list