/* * OpenPBS (Portable Batch System) v2.3 Software License * * Copyright (c) 1999-2000 Veridian Information Solutions, Inc. * All rights reserved. * * --------------------------------------------------------------------------- * For a license to use or redistribute the OpenPBS software under conditions * other than those described below, or to purchase support for this software, * please contact Veridian Systems, PBS Products Department ("Licensor") at: * * www.OpenPBS.org +1 650 967-4675 sales@OpenPBS.org * 877 902-4PBS (US toll-free) * --------------------------------------------------------------------------- * * This license covers use of the OpenPBS v2.3 software (the "Software") at * your site or location, and, for certain users, redistribution of the * Software to other sites and locations. Use and redistribution of * OpenPBS v2.3 in source and binary forms, with or without modification, * are permitted provided that all of the following conditions are met. * After December 31, 2001, only conditions 3-6 must be met: * * 1. Commercial and/or non-commercial use of the Software is permitted * provided a current software registration is on file at www.OpenPBS.org. * If use of this software contributes to a publication, product, or * service, proper attribution must be given; see www.OpenPBS.org/credit.html * * 2. Redistribution in any form is only permitted for non-commercial, * non-profit purposes. There can be no charge for the Software or any * software incorporating the Software. Further, there can be no * expectation of revenue generated as a consequence of redistributing * the Software. * * 3. Any Redistribution of source code must retain the above copyright notice * and the acknowledgment contained in paragraph 6, this list of conditions * and the disclaimer contained in paragraph 7. * * 4. Any Redistribution in binary form must reproduce the above copyright * notice and the acknowledgment contained in paragraph 6, this list of * conditions and the disclaimer contained in paragraph 7 in the * documentation and/or other materials provided with the distribution. * * 5. Redistributions in any form must be accompanied by information on how to * obtain complete source code for the OpenPBS software and any * modifications and/or additions to the OpenPBS software. The source code * must either be included in the distribution or be available for no more * than the cost of distribution plus a nominal fee, and all modifications * and additions to the Software must be freely redistributable by any party * (including Licensor) without restriction. * * 6. All advertising materials mentioning features or use of the Software must * display the following acknowledgment: * * "This product includes software developed by NASA Ames Research Center, * Lawrence Livermore National Laboratory, and Veridian Information * Solutions, Inc. * Visit www.OpenPBS.org for OpenPBS software support, * products, and information." * * 7. DISCLAIMER OF WARRANTY * * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT * ARE EXPRESSLY DISCLAIMED. * * IN NO EVENT SHALL VERIDIAN CORPORATION, ITS AFFILIATED COMPANIES, OR THE * U.S. GOVERNMENT OR ANY OF ITS AGENCIES BE LIABLE FOR ANY DIRECT OR INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This license will be governed by the laws of the Commonwealth of Virginia, * without reference to its choice of law rules. */ #include /* the master config generated by configure */ #include #include #include #include #include #include #include #include #include "pbs_error.h" #include "pbs_ifl.h" #include "log.h" #include "../lib/Liblog/pbs_log.h" #include "resmon.h" #include "cmds.h" #include "rm.h" extern void site_cmds(Tcl_Interp *); char badparm[] = "%s: bad parameter"; char missingfd[] = "%s: missing file descriptor"; char not_connected[] = "not connected"; char fail[] = "failed"; Tcl_Obj *pbserr; int connector = -1; char *getreq_err(int *local_errno, int stream); struct batch_status *pbs_statserver_err(int c, struct attrl *attrib, char *extend, int *local_errno); struct batch_status *pbs_statjob_err(int c, char *id, struct attrl *attrib, char *extend, int *local_errno); struct batch_status *pbs_selstat_err(int c, struct attropl *attrib, char *extend, int *local_errno); struct batch_status *pbs_statnode_err(int c, char *id, struct attrl *attrib, char *extend, int *local_errno); struct batch_status *pbs_statque_err(int c, char *id, struct attrl *attrib, char *extend, int *local_errno); int pbs_rerunjob_err(int c, char *jobid, char *extend, int *local_errno); int pbs_movejob_err(int c, char *jobid, char *destin, char *extend, int *local_errno); int pbs_asyrunjob_err(int c, char *jobid, char *location, char *extend, int *local_errno); int pbs_runjob_err(int c, char *jobid, char *location, char *extend, int *rc); int pbs_deljob_err(int c, char *jobid, char *extend, int *local_errno); int pbs_holdjob_err(int c, char *jobid, char *holdtype, char *extend, int *local_errno); int pbs_manager_err(int c, int command, int objtype, char *objname, struct attropl *attrib, char *extend, int *local_errno); int pbs_alterjob_err(int c, char *jobid, struct attrl *attrib, char *extend, int *local_errno); #define SET_PBSERR(value) \ (void)Tcl_ObjSetVar2(interp, pbserr, NULL, \ Tcl_NewIntObj((value)), TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) int OpenRM( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int port = 0; int fd; char *host; if (objc == 3) { if (Tcl_GetIntFromObj(interp, objv[2], &port) != TCL_OK) return TCL_ERROR; } else if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "host ?port?"); return TCL_ERROR; } host = Tcl_GetStringFromObj(objv[1], NULL); if ((fd = openrm(host, port)) < 0) { Tcl_PosixError(interp); log_err(-1, Tcl_GetStringFromObj(objv[0], NULL), host); } Tcl_SetObjResult(interp, Tcl_NewIntObj(fd)); return TCL_OK; } int CloseRM( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int fd, ret; char *cmd; int local_errno = 0; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (objc != 2) { sprintf(log_buffer, missingfd, cmd); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &fd) != TCL_OK) return TCL_ERROR; if ((ret = closerm_err(&local_errno, fd)) == -1) { Tcl_PosixError(interp); log_err(local_errno, cmd, Tcl_GetStringFromObj(objv[1], NULL)); } Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return TCL_OK; } int DownRM( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int fd, ret; char *cmd; int local_errno = 0; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (objc != 2) { sprintf(log_buffer, missingfd, cmd); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &fd) != TCL_OK) return TCL_ERROR; if ((ret = downrm(&local_errno, fd)) == -1) { Tcl_PosixError(interp); log_err(-1, cmd, Tcl_GetStringFromObj(objv[1], NULL)); } Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return TCL_OK; } int ConfigRM( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int fd, ret; int local_errno = 0; char *cmd, *filename; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (objc != 3) { sprintf(log_buffer, "%s: missing file descriptor or filename", cmd); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &fd) != TCL_OK) return TCL_ERROR; filename = Tcl_GetStringFromObj(objv[2], NULL); ret = configrm(fd, &local_errno, filename); if (ret == -1) { Tcl_PosixError(interp); log_err(local_errno, cmd, filename); } Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return TCL_OK; } int AddREQ( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int fd, ret; int local_errno = 0; char *cmd, *request; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (objc != 3) { sprintf(log_buffer, "%s: missing file descriptor or request", cmd); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &fd) != TCL_OK) return TCL_ERROR; request = Tcl_GetStringFromObj(objv[2], NULL); ret = addreq_err(fd, &local_errno, request); if (ret == -1) { Tcl_PosixError(interp); log_err(local_errno, cmd, request); } Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return TCL_OK; } int AllREQ( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { int ret; if (argc != 2) { sprintf(log_buffer, "%s: missing request", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } ret = allreq(strdup(argv[1])); Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return TCL_OK; } int GetREQ( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int fd; int local_errno = 0; char *ret; char *cmd; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (objc != 2) { sprintf(log_buffer, missingfd, cmd); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &fd) != TCL_OK) return TCL_ERROR; if ((ret = getreq_err(&local_errno, fd)) == NULL) { if (local_errno) { Tcl_PosixError(interp); log_err(local_errno, cmd, Tcl_GetStringFromObj(objv[1], NULL)); } } else { int err = 0; Tcl_SetResult(interp, ret, (Tcl_FreeProc *)free); if (*ret == '?') { if (strlen(ret) > (size_t)2 && /* look for err num */ Tcl_GetInt(interp, &ret[2], &err) != TCL_OK) return TCL_ERROR; } SET_PBSERR(err); } return TCL_OK; } int FlushREQ( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { if (argc != 1) { sprintf(log_buffer, badparm, argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } flushreq(); return TCL_OK; } int ActiveREQ( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { int ret; if (argc != 1) { sprintf(log_buffer, badparm, argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } ret = activereq(); if (ret == -1) { Tcl_PosixError(interp); sprintf(log_buffer, "result %d", ret); log_err(-1, argv[0], log_buffer); } Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return TCL_OK; } int FullResp( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { int flag; if (argc != 2) { sprintf(log_buffer, "%s: missing flag", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (Tcl_GetBoolean(interp, argv[1], &flag) != TCL_OK) return TCL_ERROR; fullresp(flag); SET_PBSERR(0); return TCL_OK; } int PBS_Connect( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *server = NULL; if (argc == 2) server = strdup(argv[1]); else if (argc != 1) { sprintf(log_buffer, "%s: wrong # args: ?server?", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector >= 0) pbs_disconnect(connector); if ((connector = pbs_connect(server)) < 0) { Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); sprintf(log_buffer, "%s (%d)", server ? server : "DefaultServer", connector * -1); log_err(-1, argv[0], log_buffer); } else Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); return TCL_OK; } int PBS_Disconnect( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; if (argc != 1) { sprintf(log_buffer, badparm, argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector >= 0 && pbs_disconnect(connector)) { Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, -1); log_err(-1, argv[0], log_buffer); } else { Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); connector = -1; } return TCL_OK; } Tcl_Obj *attrlist( Tcl_Interp *interp, struct attrl *ap) { Tcl_Obj *ret; ret = Tcl_NewListObj(0, NULL); /* null list */ while (ap) { Tcl_Obj *twol[2]; twol[0] = Tcl_NewStringObj(ap->name, -1); if (ap->resource) { Tcl_AppendStringsToObj(twol[0], TCL_ATRSEP, ap->resource, NULL); } twol[1] = Tcl_NewStringObj(ap->value, -1); Tcl_ListObjAppendElement(interp, ret, Tcl_NewListObj(2, twol)); ap = ap->next; } return (ret); } void batresult( Tcl_Interp *interp, struct batch_status *bs) { Tcl_Obj *batchl; struct batch_status *bp; batchl = Tcl_NewObj(); /* empty list */ for (bp = bs; bp; bp = bp->next) { Tcl_Obj *threel[3]; threel[0] = Tcl_NewStringObj(bp->name, -1); threel[1] = attrlist(interp, bp->attribs); threel[2] = Tcl_NewStringObj(bp->text, -1); Tcl_ListObjAppendElement(interp, batchl, Tcl_NewListObj(3, threel)); } Tcl_SetObjResult(interp, batchl); pbs_statfree(bs); } int PBS_StatServ( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; int local_errno = 0; struct batch_status *bs; Tcl_Obj *threel[3]; if (argc != 1) { sprintf(log_buffer, badparm, argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if ((bs = pbs_statserver_err(connector, NULL, NULL, &local_errno)) == NULL) { if (local_errno != PBSE_NONE) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); } } else { threel[0] = Tcl_NewStringObj(bs->name, -1); threel[1] = attrlist(interp, bs->attribs); threel[2] = Tcl_NewStringObj(bs->text, -1); Tcl_SetObjResult(interp, Tcl_NewListObj(3, threel)); pbs_statfree(bs); } return TCL_OK; } int PBS_StatJob( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; int local_errno = 0; struct batch_status *bs; if (argc != 1) { sprintf(log_buffer, badparm, argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if ((bs = pbs_statjob_err(connector, NULL, NULL, NULL, &local_errno)) == NULL) { if (local_errno != PBSE_NONE) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); } } else batresult(interp, bs); return TCL_OK; } int PBS_SelStat( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; struct batch_status *bs; int local_errno = 0; static struct attropl att1 = { NULL, strdup("queue_type"), NULL, strdup("E"), EQ }; static struct attropl att2 = { &att1, strdup("job_state"), NULL, strdup("Q"), EQ }; if (argc != 1) { sprintf(log_buffer, badparm, argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if ((bs = pbs_selstat_err(connector, &att2, NULL, &local_errno)) == NULL) { if (local_errno != PBSE_NONE) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); } } else batresult(interp, bs); return TCL_OK; } int PBS_StatQue( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; int local_errno = 0; struct batch_status *bs; if (argc != 1) { sprintf(log_buffer, badparm, argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if ((bs = pbs_statque_err(connector, NULL, NULL, NULL, &local_errno)) == NULL) { if (local_errno != PBSE_NONE) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); } } else batresult(interp, bs); return TCL_OK; } int PBS_StatNode( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *msg, *cmd; char *node = NULL; int local_errno = 0; struct batch_status *bs; if (objc == 2) node = Tcl_GetStringFromObj(objv[1], NULL); else if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, "?node?"); return TCL_ERROR; } cmd = Tcl_GetStringFromObj(objv[0], NULL); if (connector < 0) { log_err(-1, cmd, not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if ((bs = pbs_statnode_err(connector, node, NULL, NULL, &local_errno)) == NULL) { if (local_errno != PBSE_NONE) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, cmd, log_buffer); } } else batresult(interp, bs); return TCL_OK; } int PBS_AsyRunJob( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; char *location = NULL; int local_errno = 0; if (argc == 3) location = strdup(argv[2]); else if (argc != 2) { sprintf(log_buffer, "%s: wrong # args: job_id ?location?", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); if (pbs_asyrunjob_err(connector, strdup(argv[1]), location, NULL, &local_errno)) { Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); } return TCL_OK; } int PBS_RunJob( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; char *location = NULL; int local_errno = 0; if (argc == 3) location = strdup(argv[2]); else if (argc != 2) { sprintf(log_buffer, "%s: wrong # args: job_id ?location?", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if (pbs_runjob_err(connector, strdup(argv[1]), location, NULL, &local_errno)) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); } else Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); return TCL_OK; } int PBS_ReRun( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; char *extend = strdup("0"); int local_errno = 0; if (argc != 2) { sprintf(interp->result, "%s: wrong # args: job_id", argv[0]); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } interp->result = strdup("0"); if (pbs_rerunjob_err(connector, strdup(argv[1]), extend, &local_errno)) { interp->result = strdup("-1"); msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); } else { Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); } sprintf(log_buffer, "%d", local_errno); return TCL_OK; } int PBS_MoveJob( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; char *location = NULL; char job_id_out[PBS_MAXCLTJOBID]; char server_out[MAXSERVERNAME]; int local_errno = 0; if (argc == 3) location = strdup(argv[2]); else if (argc != 2) { sprintf(log_buffer, "%s: wrong # args: job_id ?location?", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if (get_server(argv[1], job_id_out, sizeof(job_id_out), server_out, sizeof(server_out))) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s", msg ? msg : fail); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (pbs_movejob_err(connector, job_id_out, location, NULL, &local_errno)) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); } else Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); return TCL_OK; } int PBS_DelJob( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; char *message = NULL; int local_errno = 0; if (argc == 3) message = strdup(argv[2]); else if (argc != 2) { sprintf(log_buffer, "%s: wrong # args: job_id ?message?", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if (pbs_deljob_err(connector, strdup(argv[1]), message, &local_errno)) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); } else Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); return TCL_OK; } int PBS_HoldJob( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { char *msg; int local_errno = 0; if (argc != 2) { sprintf(log_buffer, "%s: wrong # args: job_id", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if (pbs_holdjob_err(connector, strdup(argv[1]), strdup(SYSTEM_HOLD), NULL, &local_errno)) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, argv[0], log_buffer); Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); } else Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); return TCL_OK; } int PBS_QueueOp( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[], struct attropl *attr) { int merr; int local_errno = 0; if (argc != 2) { sprintf(log_buffer, "%s: wrong # args: queue", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (connector < 0) { log_err(-1, argv[0], not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } merr = pbs_manager_err(connector, MGR_CMD_SET, MGR_OBJ_QUEUE, strdup(argv[1]), attr, NULL, &local_errno); if (merr != 0) { sprintf(log_buffer, "%s: %s", argv[0], pbs_geterrmsg(connector)); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); return TCL_OK; } int PBS_EnableQueue( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { static struct attropl attr = { NULL, strdup("enabled"), NULL, strdup("TRUE"), SET }; return PBS_QueueOp(clientData, interp, argc, argv, &attr); } int PBS_DisableQueue( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { static struct attropl attr = { NULL, strdup("enabled"), NULL, strdup("FALSE"), SET }; return PBS_QueueOp(clientData, interp, argc, argv, &attr); } int PBS_StartQueue( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { static struct attropl attr = { NULL, strdup("started"), NULL, strdup("TRUE"), SET }; return PBS_QueueOp(clientData, interp, argc, argv, &attr); } int PBS_StopQueue( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { static struct attropl attr = { NULL, strdup("started"), NULL, strdup("FALSE"), SET }; return PBS_QueueOp(clientData, interp, argc, argv, &attr); } int PBS_AlterJob( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *msg; int i, num, tre, ret; Tcl_Obj **listp, **indp; int local_errno = 0; struct attrl *attrs, *atp = NULL; char *cmd; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "job_id attribute(s)"); return TCL_ERROR; } if ((ret = Tcl_ListObjGetElements(interp, objv[2], &num, &listp)) != TCL_OK) return ret; cmd = Tcl_GetStringFromObj(objv[0], NULL); attrs = NULL; for (i = 0; i < num; i++) { if ((ret = Tcl_ListObjGetElements(interp, listp[i], &tre, &indp)) != TCL_OK) goto done; if (tre != 3) { sprintf(log_buffer, "%s: bad attribute format: %s", cmd, Tcl_GetStringFromObj(listp[i], NULL)); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); ret = TCL_ERROR; goto done; } atp = (struct attrl *)malloc(sizeof(struct attrl)); atp->name = strdup(Tcl_GetStringFromObj(indp[0], NULL)); atp->resource = strdup(Tcl_GetStringFromObj(indp[1], NULL)); atp->value = strdup(Tcl_GetStringFromObj(indp[2], NULL)); atp->next = attrs; attrs = atp; } if (connector < 0) { log_err(-1, cmd, not_connected); SET_PBSERR(PBSE_NOSERVER); goto done; } if (pbs_alterjob_err(connector, Tcl_GetStringFromObj(objv[1], NULL), atp, NULL, &local_errno)) { Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s (%d)", msg ? msg : fail, local_errno); log_err(-1, cmd, log_buffer); } else Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); done: for (atp = attrs; attrs; atp = attrs) { attrs = atp->next; free(atp->name); free(atp->resource); free(atp->value); free(atp); } return ret; } int PBS_RescQuery( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *msg; int i, num, ret; Tcl_Obj **listp, *fourl[4], *retl; char *cmd; char **res_array; int *avail_array, *alloc_array, *reser_array, *down_array; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "{resource1 resource2 ...}"); return TCL_ERROR; } if ((ret = Tcl_ListObjGetElements(interp, objv[1], &num, &listp)) != TCL_OK) return ret; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (connector < 0) { log_err(-1, cmd, not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } res_array = (char **)malloc(sizeof(char *) * num); avail_array = (int *)malloc(sizeof(int) * num); alloc_array = (int *)malloc(sizeof(int) * num); reser_array = (int *)malloc(sizeof(int) * num); down_array = (int *)malloc(sizeof(int) * num); for (i = 0; i < num; i++) res_array[i] = Tcl_GetStringFromObj(listp[i], NULL); retl = Tcl_NewObj(); /* empty list */ if (pbs_rescquery(connector, res_array, num, avail_array, alloc_array, reser_array, down_array)) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s", msg ? msg : fail); log_err(-1, cmd, log_buffer); } else { for (i = 0; i < num; i++) { fourl[0] = Tcl_NewIntObj(avail_array[i]); fourl[1] = Tcl_NewIntObj(alloc_array[i]); fourl[2] = Tcl_NewIntObj(reser_array[i]); fourl[3] = Tcl_NewIntObj(down_array[i]); Tcl_ListObjAppendElement(interp, retl, Tcl_NewListObj(4, fourl)); } } Tcl_SetObjResult(interp, retl); free(res_array); free(avail_array); free(alloc_array); free(reser_array); free(down_array); return TCL_OK; } int PBS_RescReserve( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *msg; int i, num, ret; Tcl_Obj **listp; char *cmd; char **res_array; resource_t resid; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "resource_id {resource1 resource2 ...}"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &resid) != TCL_OK) return TCL_ERROR; if ((ret = Tcl_ListObjGetElements(interp, objv[2], &num, &listp)) != TCL_OK) return ret; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (connector < 0) { log_err(-1, cmd, not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } res_array = (char **)malloc(sizeof(char *) * num); for (i = 0; i < num; i++) res_array[i] = Tcl_GetStringFromObj(listp[i], NULL); if (pbs_rescreserve(connector, res_array, num, &resid)) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s", msg ? msg : fail); log_err(-1, cmd, log_buffer); } Tcl_SetObjResult(interp, Tcl_NewIntObj(resid)); return TCL_OK; } int PBS_RescRelease( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *msg; int ret; char *cmd; resource_t resid; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "resource_id"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &resid) != TCL_OK) return TCL_ERROR; cmd = Tcl_GetStringFromObj(objv[0], NULL); if (connector < 0) { log_err(-1, cmd, not_connected); SET_PBSERR(PBSE_NOSERVER); return TCL_OK; } if ((ret = pbs_rescrelease(connector, resid)) != 0) { msg = pbs_geterrmsg(connector); sprintf(log_buffer, "%s", msg ? msg : fail); log_err(-1, cmd, log_buffer); } Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return TCL_OK; } int DateTime( ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { time_t when; struct tm tm, *t = NULL; int i, yyy, len; char rtime[64], hold[8]; static const char *wkday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL }; switch (argc) { case 1: /* current date/time */ when = time((time_t *)NULL); sprintf(log_buffer, "%ld", (long)when); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_OK; case 2: strncpy(rtime, argv[1], sizeof(rtime)); len = strlen(rtime); when = 0; if (len < 12) break; /* absolute date/time */ for (i = 0; i < len; i++) { if (!isdigit(rtime[i])) break; } if (i != len || len > 14) { sprintf(log_buffer, "%s: bad absolute date format: %s", argv[0], rtime); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } yyy = len - 10; for (i = 0; i < yyy; i++) hold[i] = rtime[i]; hold[i] = '\0'; tm.tm_year = atoi(hold); hold[0] = rtime[i++]; hold[1] = rtime[i++]; hold[2] = '\0'; tm.tm_mon = atoi(hold) - 1; hold[0] = rtime[i++]; hold[1] = rtime[i++]; tm.tm_mday = atoi(hold); hold[0] = rtime[i++]; hold[1] = rtime[i++]; tm.tm_hour = atoi(hold); hold[0] = rtime[i++]; hold[1] = rtime[i++]; tm.tm_min = atoi(hold); hold[0] = rtime[i++]; hold[1] = rtime[i]; tm.tm_sec = atoi(hold); tm.tm_isdst = -1; when = mktime(&tm); if (when == -1) { sprintf(log_buffer, "%s: could not convert date: %s", argv[0], rtime); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewLongObj((long)when)); return TCL_OK; case 3: /* relative weekday */ for (i = 0; wkday[i]; i++) { if (strcmp(argv[1], wkday[i]) == 0) break; } if (wkday[i] == NULL) { sprintf(log_buffer, "%s: unrecognized weekday: %s", argv[0], argv[1]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } when = time((time_t *)NULL); t = localtime(&when); t->tm_mday += (i - t->tm_wday + 7) % 7; t->tm_hour = 0; t->tm_min = 0; t->tm_sec = 0; t->tm_isdst = -1; when = mktime(t); strncpy(rtime, argv[2], sizeof(rtime)); len = strlen(rtime); break; default: sprintf(log_buffer, "%s: wrong # args: ?day? ?time?", argv[0]); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (len != 8 || rtime[2] != ':' || rtime[5] != ':' || !isdigit(rtime[0]) || !isdigit(rtime[1]) || !isdigit(rtime[3]) || !isdigit(rtime[4]) || !isdigit(rtime[6]) || !isdigit(rtime[7])) { sprintf(log_buffer, "%s: bad relative time format: %s", argv[0], rtime); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } rtime[2] = rtime[5] = '\0'; when += atoi(&rtime[0]) * 3600 + atoi(&rtime[3]) * 60 + atoi(&rtime[6]); Tcl_SetObjResult(interp, Tcl_NewLongObj((long)when)); return TCL_OK; } int StrFtime( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { struct tm *t; long hold; time_t when; if (objc != 3) { sprintf(log_buffer, "%s: wrong # args: format time", Tcl_GetStringFromObj(objv[0], NULL)); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_ERROR; } if (Tcl_GetLongFromObj(interp, objv[2], &hold) != TCL_OK) return TCL_ERROR; when = (time_t)hold; t = localtime(&when); (void)strftime(log_buffer, LOG_BUF_SIZE, Tcl_GetStringFromObj(objv[1], NULL), t); Tcl_SetResult(interp, log_buffer, TCL_VOLATILE); return TCL_OK; } void add_cmds( Tcl_Interp *interp) { Tcl_CreateObjCommand(interp, "openrm", OpenRM, NULL, NULL); Tcl_CreateObjCommand(interp, "closerm", CloseRM, NULL, NULL); Tcl_CreateObjCommand(interp, "downrm", DownRM, NULL, NULL); Tcl_CreateObjCommand(interp, "configrm", ConfigRM, NULL, NULL); Tcl_CreateObjCommand(interp, "getreq", GetREQ, NULL, NULL); Tcl_CreateObjCommand(interp, "addreq", AddREQ, NULL, NULL); Tcl_CreateCommand(interp, "allreq", AllREQ, NULL, NULL); Tcl_CreateCommand(interp, "flushreq", FlushREQ, NULL, NULL); Tcl_CreateCommand(interp, "activereq", ActiveREQ, NULL, NULL); Tcl_CreateCommand(interp, "fullresp", FullResp, NULL, NULL); Tcl_CreateCommand(interp, "pbsconnect", PBS_Connect, NULL, NULL); Tcl_CreateCommand(interp, "pbsdisconnect", PBS_Disconnect, NULL, NULL); Tcl_CreateCommand(interp, "pbsstatserv", PBS_StatServ, NULL, NULL); Tcl_CreateCommand(interp, "pbsstatjob", PBS_StatJob, NULL, NULL); Tcl_CreateCommand(interp, "pbsstatque", PBS_StatQue, NULL, NULL); Tcl_CreateObjCommand(interp, "pbsstatnode", PBS_StatNode, NULL, NULL); Tcl_CreateCommand(interp, "pbsselstat", PBS_SelStat, NULL, NULL); Tcl_CreateCommand(interp, "pbsrunjob", PBS_RunJob, NULL, NULL); Tcl_CreateCommand(interp, "pbsmovejob", PBS_MoveJob, NULL, NULL); Tcl_CreateCommand(interp, "pbsqenable", PBS_EnableQueue, NULL, NULL); Tcl_CreateCommand(interp, "pbsqdisable", PBS_DisableQueue, NULL, NULL); Tcl_CreateCommand(interp, "pbsqstart", PBS_StartQueue, NULL, NULL); Tcl_CreateCommand(interp, "pbsqstop", PBS_StopQueue, NULL, NULL); Tcl_CreateCommand(interp, "pbsasyrunjob", PBS_AsyRunJob, NULL, NULL); Tcl_CreateCommand(interp, "pbsdeljob", PBS_DelJob, NULL, NULL); Tcl_CreateCommand(interp, "pbsholdjob", PBS_HoldJob, NULL, NULL); Tcl_CreateObjCommand(interp, "pbsalterjob", PBS_AlterJob, NULL, NULL); Tcl_CreateObjCommand(interp, "pbsrescquery", PBS_RescQuery, NULL, NULL); Tcl_CreateObjCommand(interp, "pbsrescreserve", PBS_RescReserve, NULL, NULL); Tcl_CreateObjCommand(interp, "pbsrescrelease", PBS_RescRelease, NULL, NULL); Tcl_CreateCommand(interp, "datetime", DateTime, NULL, NULL); Tcl_CreateObjCommand(interp, "strftime", StrFtime, NULL, NULL); /* * Extended scheduler commands from Univ. of Colorado */ Tcl_CreateCommand(interp, "pbsrerunjob", PBS_ReRun, NULL, NULL); pbserr = Tcl_NewStringObj("pbs_errno", -1); Tcl_ObjSetVar2(interp, pbserr, NULL, \ Tcl_NewIntObj((0)), TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); site_cmds(interp); }