static char rcsid[] = "$Id: cmds.c,v 1.45 2004/01/14 18:46:20 pvmsrc Exp $"; /* * PVM version 3.4: Parallel Virtual Machine System * University of Tennessee, Knoxville TN. * Oak Ridge National Laboratory, Oak Ridge TN. * Emory University, Atlanta GA. * Authors: J. J. Dongarra, G. E. Fagg, M. Fischer * G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci, * P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam * (C) 1997 All Rights Reserved * * NOTICE * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted * provided that the above copyright notice appear in all copies and * that both the copyright notice and this permission notice appear in * supporting documentation. * * Neither the Institutions (Emory University, Oak Ridge National * Laboratory, and University of Tennessee) nor the Authors make any * representations about the suitability of this software for any * purpose. This software is provided ``as is'' without express or * implied warranty. * * PVM version 3 was funded in part by the U.S. Department of Energy, * the National Science Foundation and the State of Tennessee. */ /* * cmds.c * * PVM console commands. * * $Log: cmds.c,v $ * Revision 1.45 2004/01/14 18:46:20 pvmsrc * Added new AIX5* arches. * (Spanker=kohl) * * Revision 1.44 2001/09/26 23:37:22 pvmsrc * Made hd_vmid additions to hostd mirror struct... * - don't know if this is really necessary, but wtf. * (Spanker=kohl) * * Revision 1.43 2001/09/25 21:18:13 pvmsrc * Minor TMPNAMFUN()/tmpnam() cleanup. * - moved macro def to pvm3.h, renamed PVMTNPMAN(). * - same for LEN_OF_TMP_NAM -> PVMTMPNAMLEN. * - mostly a huge waste of time, since *both* tmpnam() & mktemp() * produce the same "dangerous" warning message in Linux/gcc... * - damn. * (Spanker=kohl) * * Revision 1.42 2001/08/17 20:18:32 pvmsrc * Added --host= option to spawn command. * - allows passing IP address in place of host name. * - used gnu-like syntax at Paul Gray's suggestion... :-) * (Spanker=kohl) * * Revision 1.41 2001/07/30 17:46:08 pvmsrc * O.K., Paul's bug was legit. Some goofy (Mandrake) Linux passes * stderr back through rsh... * - weed out lines with stuff like "/bin/ls: ... No such file..." * (Spanker=kohl) * * Revision 1.40 2001/07/30 16:52:00 pvmsrc * Minor cleanup to auto-diag routine... * - slightly more solid checking for leftover /tmp/pvmd.* files. * - inspired by a pseudo-bug report from Paul Gray, could be bogus... * :-) * (Spanker=kohl) * * Revision 1.39 2001/07/30 16:02:31 pvmsrc * epm -> csm... * (Spanker=kohl) * * Revision 1.38 2001/04/23 14:41:41 pvmsrc * Tweaked spawn_cmd() parsing to allow -:wd working directory spec. * - i.e. without a host or arch specified... * - fixed help spawn text. * (Spanker=kohl) * * Revision 1.37 2001/02/02 17:05:50 pvmsrc * Fixed typo in Win32 diagnostic message output. * (Spanker=kohl) * * Revision 1.36 2000/03/29 20:01:40 pvmsrc * Stoopid typo... :-Q * (Spanker=kohl) * * Revision 1.35 2000/02/18 22:01:42 pvmsrc * Cleaned up Windows side of diagnose_cant_start_pvm()... * - lose any '\r' at end of rsh output. * - use "chdir" instead of "pwd" for Windows O.S. check. * - minor typos... * (Spanker=kohl) * * Revision 1.34 2000/02/15 18:06:20 pvmsrc * Modified jobs_cmd() to dump task ids for traced jobs... * - can't use output buffers, must use TRC_ID->tevtask_list list. * - snagged necessary state constants from trclib.h, can't just * #include it, as it #includes fricking everything... :-Q * (Spanker=kohl) * * Revision 1.33 2000/02/15 17:06:42 pvmsrc * Added new getopt / setopt console commands. * - for setting PVM console task's PVM options (like PvmShowTids). * Fixed debug flags in tickle help. * (Spanker=kohl) * * Revision 1.32 2000/02/14 20:30:59 pvmsrc * Lose #define-d RSHCOMMAND usage. * - use new pvmgetrsh() routine, which checks for PVM_RSH or else * uses old RSHCOMMAND interface. * (Spanker=kohl) * * Revision 1.31 2000/02/10 22:17:38 pvmsrc * Cleaned up diagnose_cant_start_pvmd() test routine a bunch. * - replaced gobs of inline code with new do_rsh_cmd() routine. * - added new check_env_var() routine to sort through extra * garbage in rsh commands when checking env vars... * (Spanker=kohl) * * Revision 1.30 2000/02/10 20:43:37 pvmsrc * Added checking for new PVM_TMP env var on remote host. * - in diagnose_cant_start_pvm()... * - use in place of hard-coded /tmp or \TEMP... * (Spanker=kohl) * * Revision 1.29 2000/01/26 23:34:17 pvmsrc * *** Added Killer Routine of All Time - diagnose_cant_start_pvm() *** * Nearly 800 lines of pure joy! :-D * - on "Can't start pvmd" error, tries to rsh to host and checks * everything from rhosts to $PVM_ROOT to /tmp/pmvd.* crap files. * - should theoretically work on both Unix and Windows machines, * for both Unix and Windows remote hosts (tested for Unix :-). * - with any luck this will cut bug mail in half... yeah right. * (Spanker=kohl) * * Revision 1.28 1999/07/08 18:59:39 kohl * Fixed "Log" keyword placement. * - indent with " * " for new CVS. * * Revision 1.27 1999/06/11 17:27:35 pvmsrc * When breaking up multiline commands into subcommands, * dump out each command as you execute it, along with a fresh prompt. * (Spanker=kohl) * * Revision 1.26 1999/06/10 16:57:16 pvmsrc * Fixed docmd() to handle commands with '\n's in them... * - a la file input redirection, cut & paste, etc. * - break string into individual commands and execute. * (Spanker=kohl) * * Revision 1.25 1999/02/05 20:36:17 pvmsrc * More contributions from Edward Vigmond . * - better readline interface, with command completion & help. * (Spanker=kohl) * * Revision 1.24 1998/11/20 19:43:07 pvmsrc * Changes so that win32 will compile & build. Also, common * source for win32 & unix. * (Spanker=sscott) * * Revision 1.23 1998/01/28 23:03:39 pvmsrc * Fixed tracing bogusness! * - host add / del notifies for tracing were getting scrunched by * console host add notify, etc... * - moved message / notify tag constants to job.h and USED THEM. * - initialized nextjob properly... * - added new "joboffset" global in cons.c for dumping more * reasonable job numbers to user. * (Spanker=kohl) * * Revision 1.22 1997/12/31 22:13:15 pvmsrc * Updated "xpvm" trace mask settings. * (Spanker=kohl) * * Revision 1.21 1997/08/29 16:56:53 pvmsrc * Added TEV_USER_DEFINED to "xpvm" default trace mask settings... * (Spanker=kohl) * * Revision 1.20 1997/07/09 13:21:03 pvmsrc * Fixed Author Header. * * Revision 1.19 1997/05/13 14:37:38 pvmsrc * Changed header file $includes: * - ../src/listmac.h -> listmac.h * - ../src/bfunc.h -> bfunc.h * - use -I$(PVMDIR)/src in Makefile.aimk instead. * * Revision 1.18 1997/05/02 20:18:51 pvmsrc * D-Oh. * * Revision 1.17 1997/05/01 15:41:14 pvmsrc * SGI Compiler Warning Cleanup. * * Revision 1.16 1997/04/30 21:15:35 pvmsrc * SGI Compiler Warning Cleanup. * * Revision 1.15 1997/04/17 12:53:15 pvmsrc * rename of pvm_mboxinfo() to include word "get" * * Revision 1.14 1997/04/10 20:34:35 pvmsrc * "CVS": Modified Files: * Typo... * * Revision 1.13 1997/04/10 20:09:33 pvmsrc * Rewrote names_cmd() for new pvm_mboxinfo() syntax. * - pvm_getnames() is history. * * Revision 1.12 1997/04/09 20:18:13 pvmsrc * Minor fixes (like being able to actually pass args to "reset"... :-). * * Revision 1.11 1997/04/09 19:53:12 pvmsrc * Merged resetinfo_cmd() command into reset_cmd() routine. * - check for args, adjust calling parms to pvmreset()... * * Revision 1.10 1997/04/09 18:31:58 pvmsrc * Added new "resetinfo" command. * - like a reset, but without all the task bloodshed... :-)~ * * Revision 1.9 1997/04/08 17:08:46 pvmsrc * Extracted guts of reset_cmd() routine: * - created new system pvmreset() routine for general usage. * * Revision 1.8 1997/04/01 19:35:44 pvmsrc * Corrected flag to PvmMbox... * * Revision 1.7 1997/04/01 17:04:45 pvmsrc * Updated mbox stuff: * - changed args of pvm_putinfo(). * - renamed pvm_getinfo() (again) -> pvm_recvinfo(), w/ new syntax. * * Revision 1.6 1997/03/27 20:09:51 pvmsrc * Added PvmNoSpawnParent to pvm_spawn() calls in spawn_cmd(). * * Revision 1.5 1997/02/17 16:29:04 pvmsrc * Added checking of pvm_getnoresets() list in reset_cmd(). * * Revision 1.4 1997/01/28 19:13:17 pvmsrc * New Copyright Notice & Authors. * * Revision 1.3 1996/10/24 23:03:39 pvmsrc * Updated to new tracing facilty. * - new trace_cmd() options: * * "xpvm" mask mimick. * * "buf" trace buffer size query & set. * * "opt" trace options query & set. * - new job creation handling for spawn command, * tracing vs. output vs. both... * - installed new trc_print_tmask() library call for trace mask dump. * * Revision 1.2 1996/10/08 18:29:39 pvmsrc * Renamed routines: * - pvm_put() -> pvm_putinfo(). * - pvm_get() -> pvm_getinfo(). * * Revision 1.1 1996/09/23 20:25:35 pvmsrc * Initial revision * * Revision 1.8 1995/11/02 15:11:40 manchek * added to tickle help * * Revision 1.7 1995/09/05 19:06:52 manchek * help text lowercase * * Revision 1.6 1995/07/03 18:59:51 manchek * help text * * Revision 1.5 1995/07/03 18:57:29 manchek * added ps 's' flag, tickle help 100. * ps doesn't print tasks with tid 0 unless -x flag used * * Revision 1.4 1995/05/17 15:26:17 manchek * added "return 0" to lots of commands. * added idump command * * Revision 1.3 1994/10/15 18:38:56 manchek * updated task flags and ps list headers * * Revision 1.2 1994/06/03 20:01:51 manchek * version 3.3.0 * * Revision 1.1 1993/08/30 23:30:32 manchek * Initial revision * */ #include #include #ifdef SYSVSTR #include #else #include #endif #include #include #include #include #include #include "cmd.h" #include "myalloc.h" #include "listmac.h" #include "bfunc.h" #include "job.h" #ifndef WIN32 #include #endif #define PVMERRMSG(n) ((n) <= 0 && (n) > -pvm_nerr \ ? pvm_errlist[-(n)] : "Unknown Error") char *getenv(); void i_dump(); extern char **environ; extern char *pvm_errlist[]; extern int pvm_nerr; extern struct Pvmtevinfo pvmtevinfo[]; extern char *prompt; int add_cmd(); int alias_cmd(); int conf_cmd(); int delete_cmd(); int echo_cmd(); int export_cmd(); int getopt_cmd(); int halt_cmd(); int help_cmd(); int id_cmd(); int idump_cmd(); /* int insert_cmd(); */ int jobs_cmd(); int kill_cmd(); /* int lookup_cmd(); */ int mstat_cmd(); int names_cmd(); int quit_cmd(); int pstat_cmd(); int put_cmd(); /* int remove_cmd(); */ int reset_cmd(); int setenv_cmd(); int setopt_cmd(); int sig_cmd(); int spawn_cmd(); int start_cmd(); int tasks_cmd(); int tickle_cmd(); int trace_cmd(); int unalias_cmd(); int unexport_cmd(); int version_cmd(); extern struct alias *aliases; /* from cons.c */ extern struct pvmhostinfo *hostlist; /* from cons.c */ extern struct job *joblist; /* from job.c */ extern int mytid; /* from cons.c */ extern int narchs; /* from cons.c */ extern int joboffset; /* from cons.c */ extern int nextjob; /* from cons.c */ extern int nhosts; /* from cons.c */ struct cmdsw commands[] = { { "add", 2, 0, add_cmd }, { "alias", 1, 0, alias_cmd }, { "conf", 1, 1, conf_cmd }, { "delete", 2, 0, delete_cmd }, { "echo", 1, 0, echo_cmd }, { "export", 1, 0, export_cmd }, { "getopt", 1, 2, getopt_cmd }, { "halt", 1, 1, halt_cmd }, { "help", 1, 2, help_cmd }, { "id", 1, 1, id_cmd }, { "idump", 1, 2, idump_cmd }, /* { "insert", 4, 4, insert_cmd }, */ { "jobs", 1, 2, jobs_cmd }, { "kill", 2, 0, kill_cmd }, /* { "lookup", 3, 3, lookup_cmd }, */ { "mstat", 2, 0, mstat_cmd }, { "names", 1, 2, names_cmd }, { "ps", 1, 2, tasks_cmd }, { "pstat", 2, 0, pstat_cmd }, { "put", 4, 4, put_cmd }, { "quit", 1, 1, quit_cmd }, /* { "remove", 3, 3, remove_cmd }, */ { "reset", 1, 4, reset_cmd }, { "setenv", 1, 0, setenv_cmd }, { "setopt", 3, 3, setopt_cmd }, { "sig", 3, 0, sig_cmd }, { "spawn", 2, 0, spawn_cmd }, { "trace", 1, 0, trace_cmd }, { "tickle", 2, 11, tickle_cmd }, { "unalias", 2, 0, unalias_cmd }, { "unexport", 1, 0, unexport_cmd }, { "version", 1, 1, version_cmd }, { 0, 0, 0, 0 } }; /* Host descriptor (pieces lifted from pvm3/src/host.h - pvmd stuff) */ struct hostd { int hd_ref; /* num refs to this struct */ int hd_hostpart; /* host tid base */ char *hd_name; /* name */ char *hd_arch; /* cpu arch class */ char *hd_login; /* loginname [used master only] */ char *hd_dpath; /* daemon executable */ char *hd_epath; /* task exec search path */ char *hd_bpath; /* debugger executable */ char *hd_wdir; /* pvmd working dir */ char *hd_sopts; /* hoster options */ int hd_flag; int hd_dsig; /* data signature */ int hd_err; /* error code */ int hd_mtu; /* max snd/rcv length */ /* struct sockaddr_in hd_sad; /^ UDP address/port */ int hd_rxseq; /* expected next seq num from host */ int hd_txseq; /* next tx seq num to host */ /* struct pkt *hd_txq; /^ not-yet-sent packet queue to host */ /* struct pkt *hd_opq; /^ outstanding packets to host */ int hd_nop; /* length of opq */ /* struct pkt *hd_rxq; /^ packet reordering queue from host */ /* struct pmsg *hd_rxm; /^ to-us msg reassembly from host */ /* struct timeval hd_rtt; /^ estd round-trip time to host */ int hd_speed; /* cpu relative speed */ /* struct mca *hd_mcas; /^ from-host mca cache */ char *hd_aname; /* name to use for network address */ char *hd_vmid; /* virtual machine id for host */ }; freealias(ap) struct alias *ap; { LISTDELETE(ap, a_link, a_rlink); MY_FREE(ap->a_name); while (ap->a_num-- > 0) MY_FREE(ap->a_args[ap->a_num]); MY_FREE(ap->a_args); MY_FREE(ap); return 0; } struct alias * newalias(name, num, args) char *name; int num; char **args; { struct alias *ap, *ap2; ap = TALLOC(1, struct alias, "alias"); ap->a_name = STRALLOC(name); ap->a_args = TALLOC(num + 1, char *, "aargs"); ap->a_num = num; while (num-- > 0) ap->a_args[num] = STRALLOC(args[num]); for (ap2 = aliases->a_link; ap2 != aliases; ap2 = ap2->a_link) if (strcmp(ap2->a_name, name) > 0) break; LISTPUTBEFORE(ap2, ap, a_link, a_rlink); return ap; } struct alias * findalias(name) char *name; { struct alias *ap; for (ap = aliases->a_link; ap != aliases; ap = ap->a_link) if (!strcmp(ap->a_name, name)) return ap; return (struct alias*)0; } docmd(cmd) char *cmd; { char *p; struct cmdsw *csp; struct alias *ap; int i; int ac; char *av[128]; int self; char *nextcmd = NULL; int first = 1; /* * check for '\n's in command, separate commands */ nextcmd = cmd; do { /* * look for a newline... */ cmd = nextcmd; while ( *nextcmd != '\0' && *nextcmd != '\n' ) nextcmd++; if ( *nextcmd == '\n' ) { *nextcmd++ = '\0'; if ( !first ) printf( prompt ); else first = 0; printf( "%s\n", cmd ); } /* * parse command */ ac = sizeof(av)/sizeof(av[0]) - 1; if (acav(cmd, &ac, av)) { fputs("command too long\n", stdout); return 0; } if (!ac) return 0; /* * resolve aliases */ for (ap = aliases->a_link; ap != aliases; ap = ap->a_link) ap->a_flag = 0; while (ap = findalias(av[0])) { if (ap->a_flag) { printf("alias loop\n"); return 0; } ap->a_flag = 1; if (ap->a_num > 1) { if (ac + ap->a_num > sizeof(av)/sizeof(av[0])) { fputs("command too long\n", stdout); return 0; } for (i = ac; --i > 0; ) av[i + ap->a_num - 1] = av[i]; ac += ap->a_num - 1; } self = !strcmp(av[0], ap->a_args[0]); for (i = ap->a_num; i-- > 0; ) av[i] = ap->a_args[i]; if (self) break; } /* * find command and call it */ av[ac] = 0; p = av[0]; for (csp = commands; csp->cmd; csp++) { if (!strcmp(csp->cmd, p)) { if (ac >= csp->a1 && (ac <= csp->a2 || !csp->a2)) (csp->fun)(ac, av); else printf("%s: wrong #args\n", p); break; } } if (!csp->cmd) printf("%s: not found\n", p); } while ( *nextcmd != '\0' ); return 0; } /**************** ** Commands ** ** ** ****************/ add_cmd(ac, av) int ac; char **av; { int diagnose = 0; int cc; int *sv; int i; av++; ac--; sv = TALLOC(ac, int, "int"); if ((cc = pvm_addhosts(av, ac, sv)) >= 0) { if (cc > 0) pvm_recv(-1, HostsAddedTag); /* waste the notify message */ printf("%d successful\n", cc); fputs(" HOST DTID\n", stdout); for (i = 0; i < ac; i++) if ((cc = sv[i]) < 0) { printf("%24s %8s\n", av[i], PVMERRMSG(cc)); if (cc == PvmCantStart) diagnose++; } else printf("%24s %8x\n", av[i], cc); /* Try to Further Diagnose "PvmCantStart" Cases... */ /* Otherwise, sure to generate MORE BUG MAIL!!! :-Q */ if ( diagnose ) { printf( "\nAuto-Diagnosing Failed Hosts...\n" ); for (i = 0; i < ac; i++) { if (sv[i] == PvmCantStart) { printf( "%s...\n", av[i] ); diagnose_cant_start_pvm( av[i] ); printf( "\n" ); } } } } MY_FREE(sv); pvm_config(&nhosts, &narchs, &hostlist); return 0; } diagnose_cant_start_pvm( hostline ) char *hostline; { FILE *fp; #ifndef WIN32 struct passwd *pw; #endif struct hostd hp; struct stat statck; char lhost[1024]; char pvmarch[1024]; char pvmroot[1024]; char pvmtmp[1024]; char result[1024]; char result2[1024]; char tcmd[1024]; char tmp[255]; char user[1024]; int remote_os = -1; int len; int i; /* Extract Raw Host Name from Add Command */ if ( parsehost(hostline, &hp) < 0 ) { printf( "Error Parsing Host String!\n" ); printf( "Cannot Auto-Diagnose!\n" ); return( 0 ); } /* Get Local Hostname */ gethostname( lhost, 1024 ); /* Get Local User */ #ifndef WIN32 if ( (pw = getpwuid( getuid() )) != NULL ) strcpy( user, pw->pw_name ); else strcpy( user, "" ); #else strcpy( user, MyGetUserName() ); #endif /* Ping / Timeout Test */ /* * Maybe later - for now rsh returns "Connection timed out" * printf( "Pinging Host \"%s\"...\n", hp.hd_name ); sprintf( tcmd, "ping -c 1 %s 1>%s 2>&1", hp.hd_name, tfile ); system( tcmd ); fp = fopen( tfile, "r" ); if ( fp != NULL ) { while ( fgets( result, 1024, fp ) != NULL ) { printf( "%s\n", result ); } fclose( fp ); } else printf( "Ping Command Failed - Test Skipped...\n" ); unlink( tfile ); */ /* Verify Rsh Path */ printf( "Verifying Local Path to \"rsh\"...\n" ); strcpy( tcmd, pvmgetrsh() ); if ( stat( tcmd, &statck ) < 0 ) { printf( "\nError - File %s Not Found!\n", tcmd ); #ifndef WIN32 printf( "Use \"whereis rsh\" or \"which rsh\" to determine\n" ); printf( "where \"rsh\" is on your system and modify the\n" ); printf( "$PVM_ROOT/conf/$PVM_ARCH.def configuration file\n" ); #else printf( "Determine the path to the \"rsh\" command on your\n" ); printf( "system, and edit %PVM_ROOT%\\conf\\WIN32.def\n" ); #endif printf( "to adjust the path for the -DRSHCOMMAND=\\\"\\\"\n" ); printf( "flag. Then recompile PVM and your applications.\n" ); return( 0 ); } else printf( "Rsh found in %s - O.K.\n", tcmd ); /* Rsh Test */ if ( do_rsh_cmd( &hp, "Testing Rsh/Rhosts Access to", "echo YES", result, 1024 ) ) { /* check result */ if ( !strncmp( result, "YES", 3 ) ) printf( "Rsh/Rhosts Access is O.K.\n" ); else { printf( "\nRsh/Rhosts Access FAILED - \"%s\"\n", result ); printf( "Make sure host %s is up and connected to\n", hp.hd_name ); printf( "a network and check its DNS / IP address.\n" ); printf( "Also verify that %s is allowed\n", lhost ); printf( "rsh access on %s\n", hp.hd_name ); printf( "Add this line to the $HOME/.rhosts on %s:\n", hp.hd_name ); printf( "%s %s\n", lhost, user ); return( 0 ); } } else return( 0 ); /* Is Remote Host O.S. Windows or Unix? */ if ( do_rsh_cmd( &hp, "Checking O.S. Type (Unix test) on", "pwd", result, 1024 ) ) { /* Unix-land */ if ( result[0] == '/' ) { printf( "Host %s is Unix-based.\n", hp.hd_name ); remote_os = 0; } else if ( do_rsh_cmd( &hp, "Checking O.S. Type (Win test) on", "chdir", result2, 1024 ) ) { /* Windows-land */ len = strlen( result2 ); if ( len >= 3 && result2[0] >= 'A' && result2[0] <= 'Z' && result2[1] == ':' && result2[2] == '\\' ) { printf( "Host %s is Windows-based.\n", hp.hd_name ); remote_os = 1; } /* Hmmm... Go Figure. */ else { len = strlen( result ); for ( i=0 ; i < len - 1 && remote_os < 0 ; i++ ) { if ( result[i] == '/' ) { printf( "Assuming Host %s to be Unix-based.\n", hp.hd_name ); remote_os = 0; } else if ( result[0] == '\\' ) { printf( "Assuming Host %s to be Windows-based.\n", hp.hd_name ); remote_os = 1; } } if ( remote_os < 0 ) { len = strlen( result2 ); if ( !len ) { printf( "Assuming Host %s to be Unix-based.\n", hp.hd_name ); remote_os = 0; } else { for ( i=0 ; i < len - 1 && remote_os < 0 ; i++ ) { if ( result2[i] == '/' ) { printf( "Assuming Host %s to be Unix-based.\n", hp.hd_name ); remote_os = 0; } else if ( result2[0] == '\\' ) { printf( "Assuming Host %s to be Windows-based.\n", hp.hd_name ); remote_os = 1; } } } } if ( remote_os < 0 ) { printf( "Error - Cannot Determine Remote O.S.!\n" ); printf( "Can't Auto-Diagnose.\n" ); return( 0 ); } } } } else return( 0 ); /* PVM_ROOT Test */ if ( do_rsh_cmd( &hp, ( remote_os == 0 ) ? "Checking $PVM_ROOT on" : "Checking %PVM_ROOT% on", ( remote_os == 0 ) ? "echo $PVM_ROOT" : "echo %PVM_ROOT%", result, 1024 ) ) { /* check for undefined variable (Unix) */ if ( remote_os == 0 && !check_env_var( "PVM_ROOT", result ) ) { printf( "\nThe $PVM_ROOT Environment Variable is Not Set!\n" ); printf( "Use one of the shell *.stub files in\n" ); printf( "the pvm3/lib directory to set up the\n" ); printf( "PVM environment on host %s.\n", hp.hd_name ); return( 0 ); } /* check for undefined variable (Windows) */ else if ( remote_os == 1 && !strncmp( result, "ECHO", 4 ) ) { printf( "\nThe %%PVM_ROOT%% Environment Variable is Not Set!\n" ); printf( "Check your PVM installation on host %s or\n", hp.hd_name ); printf( "set the %%PVM_ROOT%% environment variable\n" ); printf( "in the C:\\AUTOEXEC.BAT file to point to\n" ); printf( "PVM3.4 directory:\n" ); printf( "set PVM_ROOT = C:\\PVM3.4\n" ); return( 0 ); } /* check for bogus relative path (Unix) */ else if ( remote_os == 0 && result[0] != '/' ) { printf( "\nThe value of the $PVM_ROOT environment\n" ); printf( "variable on %s is invalid (\"%s\").\n", hp.hd_name, result ); printf( "Use the absolute path to the pvm3/ directory.\n" ); return( 0 ); } /* check for bogus relative path (Windows) */ else if ( remote_os == 1 && ( result[1] != ':' || result[2] != '\\' ) ) { printf( "\nThe value of the %%PVM_ROOT%% environment\n" ); printf( "variable on %s is invalid (\"%s\").\n", hp.hd_name, result ); printf( "Use the absolute path to the PVM3.4 directory.\n" ); return( 0 ); } /* appears to be O.K., fall through to next test */ else { strcpy( pvmroot, result ); printf( "%sPVM_ROOT%s on %s Appears O.K. (\"%s\")\n", ( remote_os == 0 ) ? "$" : "%", ( remote_os == 0 ) ? "" : "%", hp.hd_name, pvmroot ); } } else return( 0 ); /* Pvmd Script Existence Test (a.k.a. $PVM_ROOT Validity Test) */ if ( do_rsh_cmd( &hp, "Verifying Location of PVM Daemon Script on", ( remote_os == 0 ) ? "\\ls $PVM_ROOT/lib/pvmd" : "dir /B /L %PVM_ROOT%\\lib\\pvmd.bat", result, 1024 ) ) { /* expected pvmd script path */ if ( remote_os == 0 ) sprintf( tmp, "%s/lib/pvmd", pvmroot ); else sprintf( tmp, "pvmd.bat" ); /* check existence of pvmd script */ if ( strcmp( result, tmp ) ) { printf( "\nPVM Daemon Script \"%s\"\n", tmp ); printf( "Was Not Found on %s\n", hp.hd_name ); printf( "Please check the setting of %sPVM_ROOT%s...\n", ( remote_os == 0 ) ? "$" : "%", ( remote_os == 0 ) ? "" : "%" ); return( 0 ); } else printf( "PVM Daemon Script Found (\"%s\")\n", tmp ); } else return( 0 ); /* Determine Remote Host Architecture */ if ( do_rsh_cmd( &hp, "Determining PVM Architecture on", ( remote_os == 0 ) ? "echo $PVM_ARCH" : "echo %PVM_ARCH%", result, 1024 ) ) { /* check for undefined variable */ if ( ( remote_os == 0 && check_env_var( "PVM_ARCH", result ) ) || ( remote_os == 1 && strncmp( result, "ECHO", 4 ) ) ) { printf( "%sPVM_ARCH%s on %s set to %s\n", ( remote_os == 0 ) ? "$" : "%", ( remote_os == 0 ) ? "" : "%", hp.hd_name, result ); strcpy( pvmarch, result ); } else { printf( "%sPVM_ARCH%s not set on %s\n", ( remote_os == 0 ) ? "$" : "%", ( remote_os == 0 ) ? "" : "%", hp.hd_name ); if ( remote_os == 1 ) { printf( "Assuming WIN32.\n" ); strcpy( pvmarch, "WIN32" ); } else pvmarch[0] = '\0'; } } else return( 0 ); /* Manually Determine Remote Host Architecture (Unix Only) */ if ( remote_os == 0 && pvmarch[0] == '\0' ) { if ( do_rsh_cmd( &hp, "Manually Determining PVM Architecture on", "$PVM_ROOT/lib/pvmgetarch", result, 1024 ) ) { len = strlen( result ); /* sanity check */ if ( len > 1 ) { printf( "$PVM_ARCH for %s is %s.\n", hp.hd_name, result ); strcpy( pvmarch, result ); } else { printf( "Could Not Determine $PVM_ARCH.\n" ); printf( "Can't Further Auto-Diagnose.\n" ); return( 0 ); } } else return( 0 ); } /* Existence of pvmd3 Executable? */ if ( remote_os == 0 ) sprintf( tmp, "\\ls $PVM_ROOT/lib/%s/pvmd3", pvmarch ); else sprintf( tmp, "dir /B /L %%PVM_ROOT%%\\lib\\%s\\pvmd3.exe", pvmarch ); if ( do_rsh_cmd( &hp, "Verifying Existence of PVM Daemon Executable on", tmp, result, 1024 ) ) { /* expected pvmd executable path */ if ( remote_os == 0 ) sprintf( tmp, "%s/lib/%s/pvmd3", pvmroot, pvmarch ); else sprintf( tmp, "pvmd3.exe" ); /* check existence of pvmd executable */ if ( strcmp( result, tmp ) ) { printf( "\nPVM Daemon Executable \"%s\"\n", tmp ); printf( "Was Not Found on %s!\n", hp.hd_name ); printf( "Has PVM been compiled there?\n" ); return( 0 ); } else printf( "PVM Daemon Executable Found (\"%s\")\n", tmp ); } else return( 0 ); /* Determine Remote Host Temp Directory (if set) */ if ( do_rsh_cmd( &hp, "Determining PVM Temporary Directory on", ( remote_os == 0 ) ? "echo $PVM_TMP" : "echo %PVM_TMP%", result, 1024 ) ) { /* check for undefined variable */ if ( ( remote_os == 0 && check_env_var( "PVM_TMP", result ) ) || ( remote_os == 1 && strncmp( result, "ECHO", 4 ) ) ) { printf( "%sPVM_TMP%s on %s set to %s\n", ( remote_os == 0 ) ? "$" : "%", ( remote_os == 0 ) ? "" : "%", hp.hd_name, result ); strcpy( pvmtmp, result ); } else { printf( "%sPVM_TMP%s not set on %s\n", ( remote_os == 0 ) ? "$" : "%", ( remote_os == 0 ) ? "" : "%", hp.hd_name ); if ( remote_os == 1 ) { printf( "Assuming C:\\TEMP.\n" ); strcpy( pvmtmp, "C:\\TEMP" ); } else { printf( "Assuming /tmp.\n" ); strcpy( pvmtmp, "/tmp" ); } } } else return( 0 ); /* Pvmd Already Running There / Leftover Pvmd Files? */ if ( remote_os == 0 ) sprintf( tmp, "\\ls -l %s/pvmd.* | grep %s", pvmtmp, ( hp.hd_login != NULL ) ? hp.hd_login : user ); else /* should really also check %TEMP% */ sprintf( tmp, "dir /B /L %s\\pvmd.%s", pvmtmp, ( hp.hd_login != NULL ) ? hp.hd_login : user ); if ( do_rsh_cmd( &hp, "Checking for Leftover PVM Daemon Files on", tmp, result, 1024 ) ) { len = strlen( result ); /* Find Any? (Unix) */ if ( remote_os == 0 ) { /* search for a '/pvmd', if found assume a hit */ for ( i=0 ; i < len - 1 ; i++ ) { /* bail out if "/bin/ls: ... No such file..." */ if ( !strncmp( result + i, "ls:", 3 ) ) break; else if ( !strncmp( result + i, "/pvmd.", 6 ) ) { printf( "\nPVM Daemon Files Found on %s!\n", hp.hd_name ); printf( "PVM Could Already Be Running or else it\n" ); printf( "crashed and left behind a %s/pvmd.\n", pvmtmp ); printf( "daemon file.\n" ); printf( "Halt PVM if it is running on %s, or else\n", hp.hd_name ); printf( "remove any leftover %s/pvmd.* files.\n", pvmtmp ); return( 0 ); } } printf( "No PVM Daemon Files Found.\n" ); } /* Find Any? (Windows) */ else if ( remote_os == 1 && !strncmp( result, "pvmd", 4 ) ) { printf( "\nPVM Daemon Files Found on %s!\n", hp.hd_name ); printf( "Either PVM is Already Running or else it\n" ); printf( "crashed and left behind a \\TEMP\\pvmd.%s\n", ( hp.hd_login != NULL ) ? hp.hd_login : user ); printf( "daemon file.\n" ); printf( "Halt PVM if it is running on %s, or else\n", hp.hd_name ); printf( "remove any leftover \\TEMP\\pvmd.* files.\n" ); return( 0 ); } /* No Pvmd Files, O.K.? */ else printf( "No PVM Daemon Files Found.\n" ); } else return( 0 ); /* Hmmm... Must Be O.K. (ha ha ha) */ printf( "\nHost %s Appears to Be Correctly Configured.\n", hp.hd_name ); #ifndef WIN32 printf( "Please check your local %s/pvml.%d log file\n", pvmgettmp(), getuid() ); #else printf( "Please check your local %s\\pvml.%s log file\n", pvmgettmp(), user ); #endif printf( "for error messages, or else email \"%s\" for\n", "pvm@msr.csm.ornl.gov" ); printf( "further assistance.\n" ); return( 1 ); } do_rsh_cmd( hp, label, cmd, result, rsize ) struct hostd *hp; char *label; char *cmd; char *result; int rsize; { FILE *fp; char tfile[1024]; char tcmd[1024]; char tmp[255]; int ret = 1; int len; /* Generate Temporary File for Test Output */ (void)PVMTMPNAMFUN(tfile); /* Dump Test Label */ printf( "%s Host \"%s\"...\n", label, hp->hd_name ); /* Construct Rsh Command */ sprintf( tcmd, "%s ", pvmgetrsh() ); if ( hp->hd_login != NULL ) { sprintf( tmp, "-l %s ", hp->hd_login ); strcat( tcmd, tmp ); } sprintf( tmp, "%s '%s' ", hp->hd_name, cmd ); strcat( tcmd, tmp ); #ifndef WIN32 sprintf( tmp, "1>%s 2>&1", tfile ); #else sprintf( tmp, "> %s", tfile ); #endif strcat( tcmd, tmp ); /* Execute Rsh Command */ system( tcmd ); /* Collect Rsh Command Results */ fp = fopen( tfile, "r" ); if ( fp != NULL ) { if ( fgets( result, rsize, fp ) != NULL ) { /* strip off '\n' */ len = strlen( result ); if ( len > 0 && result[ len - 1 ] == '\n' ) result[ len - 1 ] = '\0'; /* strip off any '\r' */ len = strlen( result ); if ( len > 0 && result[ len - 1 ] == '\r' ) result[ len - 1 ] = '\0'; } else { printf( "Error Parsing Output - Can't Auto-Diagnose.\n" ); ret = 0; } fclose( fp ); } else { printf( "Rsh Command Failed - Check Your Execution Path!\n" ); ret = 0; } unlink( tfile ); return( ret ); } check_env_var( name, result ) char *name; char *result; { char *ptr; int nlen = strlen( name ); /* Standard "FOO - Undefined variable" Response? */ if ( !strncmp( result, name, nlen ) ) return( 0 ); /* Check for preceding garbage before standard response */ ptr = result + 1; while ( *ptr != '\0' && strlen( ptr ) >= nlen ) { if ( !strncmp( ptr, name, nlen ) ) return( 0 ); ptr++; } /* Look for "[Uu]ndefined" in result... */ ptr = result; while ( *ptr != '\0' && strlen( ptr ) >= 9 ) { if ( !strncmp( ptr, "Undefined", nlen ) || !strncmp( ptr, "undefined", nlen ) ) return( 0 ); ptr++; } /* Must Be O.K. */ return( 1 ); } /* parsehost() * * Parse hostfile line into hostd. * (lifted from pvm3/src/host.c - pvmd code... hacked a little :-) */ int parsehost(buf, hp) char *buf; struct hostd *hp; { char *av[10]; /* parsed words */ int ac; int err = 0; ac = sizeof(av)/sizeof(av[0]); if (acav(buf, &ac, av)) { printf("parsehost(): line too long\n"); goto bad; } if (!ac) goto bad; /* Initialize Host Struct Fields */ hp->hd_name = (char *) NULL; hp->hd_arch = (char *) NULL; hp->hd_login = (char *) NULL; hp->hd_dpath = (char *) NULL; hp->hd_epath = (char *) NULL; hp->hd_bpath = (char *) NULL; hp->hd_wdir = (char *) NULL; hp->hd_sopts = (char *) NULL; hp->hd_vmid = (char *) NULL; /* add options to host descriptor */ while (--ac > 0) { if (!strncmp(av[ac], "lo=", 3)) { if (hp->hd_login) MY_FREE(hp->hd_login); hp->hd_login = STRALLOC(av[ac] + 3); continue; } if (!strncmp(av[ac], "dx=", 3)) { if (hp->hd_dpath) MY_FREE(hp->hd_dpath); hp->hd_dpath = STRALLOC(av[ac] + 3); continue; } if (!strncmp(av[ac], "ep=", 3)) { if (hp->hd_epath) MY_FREE(hp->hd_epath); hp->hd_epath = STRALLOC(av[ac] + 3); continue; } if (!strncmp(av[ac], "sp=", 3)) { hp->hd_speed = atoi(av[ac] + 3); /* hp->hd_flag |= HF_SPEED; */ continue; } if (!strncmp(av[ac], "bx=", 3)) { if (hp->hd_bpath) MY_FREE(hp->hd_bpath); hp->hd_bpath = STRALLOC(av[ac] + 3); continue; } if (!strncmp(av[ac], "wd=", 3)) { if (hp->hd_wdir) MY_FREE(hp->hd_wdir); hp->hd_wdir = STRALLOC(av[ac] + 3); continue; } if (!strncmp(av[ac], "so=", 3)) { if (hp->hd_sopts) MY_FREE(hp->hd_sopts); hp->hd_sopts = STRALLOC(av[ac] + 3); continue; } if (!strncmp(av[ac], "ip=", 3)) { if (hp->hd_aname) MY_FREE(hp->hd_aname); hp->hd_aname = STRALLOC(av[ac] + 3); continue; } if (!strncmp(av[ac], "id=", 3)) { if (hp->hd_vmid) MY_FREE(hp->hd_vmid); hp->hd_vmid = STRALLOC(av[ac] + 3); continue; } printf("parsehost(): unknown option \"%s\"\n", av[ac]); err++; } if (err) goto bad; if (hp->hd_name) MY_FREE(hp->hd_name); hp->hd_name = STRALLOC(av[0]); return 0; bad: return -1; } alias_cmd(ac, av) int ac; char **av; { struct alias *ap; char *p; int i; if (ac < 3) { for (ap = aliases->a_link; ap != aliases; ap = ap->a_link) { fputs(ap->a_name, stdout); p = "\t"; for (i = 0; i < ap->a_num; i++) { printf("%s%s", p, ap->a_args[i]); p = " "; } fputs("\n", stdout); } } else { if (ap = findalias(av[1])) freealias(ap); newalias(av[1], ac - 2, av + 2); } return 0; } conf_cmd(ac, av) int ac; char **av; { int i; ac = ac; av = av; if (!pvm_config(&nhosts, &narchs, &hostlist)) { printf("%d host%s, %d data format%s\n", nhosts, (nhosts > 1 ? "s" : ""), narchs, (narchs > 1 ? "s" : "")); fputs(" HOST DTID ARCH SPEED DSIG\n", stdout); for (i = 0; i < nhosts; i++) printf("%24s %8x %8s%8d 0x%08x\n", hostlist[i].hi_name, hostlist[i].hi_tid, hostlist[i].hi_arch, hostlist[i].hi_speed, hostlist[i].hi_dsig); } return 0; } delete_cmd(ac, av) int ac; char **av; { int cc; int i; int *sv; av++; ac--; sv = TALLOC(ac, int, "int"); if ((cc = pvm_delhosts(av, ac, sv)) >= 0) { printf("%d successful\n", cc); fputs(" HOST STATUS\n", stdout); for (i = 0; i < ac; i++) { printf("%24s ", av[i]); if ((cc = sv[i]) < 0) printf("%8s\n", PVMERRMSG(cc)); else printf("deleted\n"); } } MY_FREE(sv); return 0; } echo_cmd(ac, av) int ac; char **av; { int i; char *p = ""; for (i = 1; i < ac; i++) { printf("%s%s", p, av[i]); p = " "; } printf("\n"); return 0; } halt_cmd(ac, av) int ac; char **av; { ac = ac; av = av; if (!pvm_halt()) { pvmendtask(); exit(0); } return 0; } char *helptx[] = { "add add Add hosts to virtual machine", "add Syntax: add hostname ...", "alias alias Define/list command aliases", "alias Syntax: alias [name command args ...]", "conf conf List virtual machine configuration", "conf Syntax: conf", "conf Output fields:", "conf HOST host name", "conf DTID tid base of pvmd", "conf ARCH xhost architecture", "conf SPEED host relative speed", "delete delete Delete hosts from virtual machine", "delete Syntax: delete hostname ...", "echo echo Echo arguments", "echo Syntax: echo [ arg ... ]", "export export Add environment variables to spawn export list", "export Syntax: export [ varname ... ]", "getopt getopt Display PVM options for the console task", "getopt Syntax: getopt [ what ]", "halt halt Stop pvmds", "halt Syntax: halt", "help help Print helpful information about a command", "help Syntax: help [ command ]", "id id Print console task id", "id Syntax: id", "idump-idump Call i_dump to display heap contents", "idump-Syntax: idump [ how ]", /* "insert-insert Add entry to database", "insert-Syntax: insert name index|-1 hexvalue", */ "jobs jobs Display list of running jobs", "jobs Syntax: jobs [ options ]", "jobs Options: -l give long listing", "kill kill Terminate tasks", "kill Syntax: kill [ options ] tid ...", "kill Options: -c kill children of tid", /* "lookup-lookup Find entry in database", "lookup-Syntax: lookup name index|-1", */ "names names List message mailbox names", "names Syntax: names [ pattern ]", "mstat mstat Show status of hosts", "mstat Syntax: mstat name ...", "ps ps List tasks", "ps Syntax: ps [ -axh ]", "ps Options: -a all hosts (default is local)", "ps -hhost specific host tid", "ps -nhost specific host name", "ps -l long (show process id)", "ps -x show all tasks (e.g. console and nulls)", "ps Output fields:", "ps HOST host name", "ps TID task id", "ps PTID parent task id", "ps PID task process id", "ps FLAG status", "ps COMMAND executable name", "ps FLAG values:", "ps f task process is child of pvmd", "ps c task connected to pvmd", "ps a task waiting authorization", "ps o task connection being closed", "ps s task needs too many shared pages, is deadlocked", "ps H hoster task", "ps R resource manager task", "ps T tasker task", "pstat pstat Show status of tasks", "pstat Syntax: pstat tid ...", "put put Add entry to message mailbox", "put Syntax: put name flags", "quit quit Exit console", "quit Syntax: quit", /* "remove-remove Delete entry from database", "remove-Syntax: remove name index", */ "reset reset Kill all tasks, delete leftover mboxes", "reset Syntax: reset\n", "reset reset info Delete orphaned persistent mbox entries", "reset Syntax: reset info [ class [ index ] ]", "setenv setenv Display or set environment variables", "setenv Syntax: setenv [ name [ value ] ]", "setopt setopt Set PVM options - for the console task *only*!", "setopt Syntax: setopt what value", "sig sig Send signal to task", "sig Syntax: sig signum task ...", "spawn spawn Spawn task", "spawn Syntax: spawn [ options ] file [ arg ... ]", "spawn Options: -(count) number of tasks, default is 1", "spawn -(host) spawn on host, default is any", "spawn -(host):(wd) spawn on host, in directory 'wd'", "spawn --host=(IP) spawn on host with given IP addr", "spawn --host=(IP):(wd) spawn on IP, in directory 'wd'", "spawn -(ARCH) spawn on hosts of ARCH", "spawn -(ARCH):(wd) spawn on hosts of ARCH, in 'wd'", "spawn -:(wd) spawn in working directory 'wd'", "spawn -? enable debugging", "spawn -> redirect job output to console", "spawn ->(file) redirect output of job to file", "spawn ->>(file) append output of job to file", "spawn -@ trace job, output to terminal", "spawn -@(file) trace job, output to file", "tickle-tickle Tickle pvmd", "tickle-Syntax: tickle how [ arg ... ]", "tickle-How:", "tickle- 0 dump heap", "tickle- 1 dump host table", "tickle- 2 dump local task table", "tickle- 3 dump waitc list", "tickle- 4 dump message mailbox", "tickle- 5 get debugmask", "tickle- 6 (mask) set debugmask", "tickle- mask is the sum of the following bits for information about", "tickle- 1 Packet routing", "tickle- 2 Message routing and entry points", "tickle- 4 Task state", "tickle- 8 Slave pvmd startup", "tickle- 16 Host table updates", "tickle- 32 Select loop", "tickle- 64 IP network", "tickle- 128 Multiprocessor nodes", "tickle- 256 Resource manager interface", "tickle- 512 Application warnings (scrapped messages etc.)", "tickle- 1024 Wait contexts", "tickle- 2048 Shared memory operations", "tickle- 4096 Semaphores", "tickle- 8192 Locks", "tickle- 16384 Message routing", "tickle- 32768 Message mailbox", "tickle- 65536 Tracer tracing", "tickle- 131072 Multicast tracking", "tickle- 7 (num) set nopax", "tickle- 8 (dtid) trigger hostfail", "tickle- 9 (rst) dump pvmd statistics, clear if rst true", "tickle- 100 dump shared memory data structures", "trace trace Set/display trace event mask", "trace Syntax: trace", "trace trace [+] name ...", "trace trace - name ...", "trace trace [+] *", "trace trace - *", "trace trace xpvm (default mask for XPVM display)", "trace trace buf nbytes", "trace trace buf", "trace trace opt < full | time | count >", "trace trace opt", "unalias unalias Undefine command alias", "unalias Syntax: unalias name ...", "unexport unexport Remove environment variables from spawn export list", "unexport Syntax: unexport [ varname ... ]", "version version Show libpvm version", "version Syntax: version", 0 }; help_cmd(ac, av) int ac; char **av; { char **p; char *topic; int l; struct cmdsw *csp; /* if not specified, topic = help */ if (ac > 1) topic = av[1]; else topic = "help"; l = strlen(topic); /* search through messages for ones matching topic */ for (p = helptx; *p; p++) { if (!strncmp(topic, *p, l) && ((*p)[l] == ' ' || (*p)[l] == '-')) printf("%s\n", (*p) + l + 1); } if (!strcmp(topic, "help")) { printf("Commands are:\n"); for (csp = commands; csp->cmd; csp++) { l = strlen(csp->cmd); for (p = helptx; *p; p++) if (!strncmp(csp->cmd, *p, l) && (*p)[l] == ' ') { printf(" %s\n", (*p) + l + 1); break; } } } return 0; } id_cmd(ac, av) int ac; char **av; { ac = ac; av = av; printf("t%x\n", mytid); return 0; } idump_cmd(ac, av) int ac; char **av; { int how = 0; if (ac > 1) how = atoi(av[1]); i_dump(how); return 0; } /* insert_cmd(ac, av) int ac; char **av; { int cc; int data; ac = ac; data = axtoi(av[3]); if ((cc = pvm_insert(av[1], axtoi(av[2]), data)) >= 0) printf("%s, %d = 0x%08x\n", av[1], cc, data); else if (cc == PvmDupEntry) printf("already exists\n"); return 0; } */ jobs_cmd(ac, av) int ac; char **av; { struct job *jp; struct obuf *op; int l = 0; int ntask; struct pvmtaskinfo *tip; TRC_TEVTASK tt; if (ac > 1 && !strcmp(av[1], "-l")) { l = 1; print_task_hdr(0); if (!hostlist) pvm_config(&nhosts, &narchs, &hostlist); } for (jp = joblist->j_link; jp != joblist; jp = jp->j_link) { printf("%c%d:%s", (jp->j_flag & JOB_TRACE ? 'T' : ' '), jp->j_jid - joboffset, (l ? "\n" : "")); if (jp->j_flag & JOB_TRACE) { tt = jp->j_trcid->tevtask_list; while ( tt ) { if ( tt->tevstatus == TRC_TASK_ALIVE || tt->outstatus == TRC_TASK_OUT ) { if (l) { if (!pvm_tasks(tt->tid, &ntask, &tip) && ntask == 1) print_task_rec(&tip[0], 0); else printf(" t%x", tt->tid); printf("\n"); } else printf(" t%x", tt->tid); } tt = tt->next; } if (!l) printf("\n"); } else if (jp->j_obufs) { for (op = jp->j_obufs->o_link; op != jp->j_obufs; op = op->o_link) if (l) { if (!pvm_tasks(op->o_tid, &ntask, &tip) && ntask == 1) print_task_rec(&tip[0], 0); else printf(" t%x", op->o_tid); printf("\n"); } else printf(" t%x", op->o_tid); if (!l) printf("\n"); } } return 0; } kill_cmd(ac, av) int ac; char **av; { int i; int tid, tid2; char *p; int host = 0; int cflg = 0; struct pvmtaskinfo *tip; int ntask; if (ac > 1 && av[1][0] == '-') { ac--; for (p = *++av; *p; p++) switch (*p) { case 'c': cflg = 1; break; case '-': break; default: printf("unknown flag -%c\n", *p); break; } } if (ac < 2) { fputs("incorrect arg count\n", stdout); return 1; } if (cflg && pvm_tasks(host, &ntask, &tip) < 0) return 1; while (ac > 1) { ac--; tid = tidtoi(*++av); if (cflg) { for (i = 0; i < ntask; i++) if (tip[i].ti_ptid == tid) { tid2 = tip[i].ti_tid; if (tid2 != mytid) pvm_kill(tid2); } } else { if (tid == mytid) printf("t%x: that's me.\n", tid); else pvm_kill(tid); } } return 0; } /* lookup_cmd(ac, av) int ac; char **av; { int cc, data = 0; ac = ac; if ((cc = pvm_lookup(av[1], axtoi(av[2]), &data)) >= 0) printf("%s, %d = 0x%08x\n", av[1], cc, data); else if (cc == PvmNoEntry) printf("no such entry\n"); return 0; } */ mstat_cmd(ac, av) int ac; char **av; { int i; int cc; for (i = 1; i < ac; i++) { cc = pvm_mstat(av[i]); printf("%24s %s\n", av[i], (cc < 0 ? PVMERRMSG(cc) : "ok")); } return 0; } pstat_cmd(ac, av) int ac; char **av; { int i; int tid; int cc; for (i = 1; i < ac; i++) { tid = tidtoi(av[i]); cc = pvm_pstat(tid); printf("t%8x %s\n", tid, (cc < 0 ? PVMERRMSG(cc) : "run")); } return 0; } quit_cmd() { printf("\n"); if (mytid > 0) { pvm_exit(); printf("pvmd still running.\n"); } #ifdef WIN32 WSACleanup(); #endif exit(0); return 0; /* for stupid SGI compiler :-Q */ } /* remove_cmd(ac, av) int ac; char **av; { int cc; ac = ac; if ((cc = pvm_delete(av[1], axtoi(av[2]))) > 0) printf("deleted %s, %d\n", av[1], cc); else if (cc == PvmNoEntry) printf("no such entry\n"); return 0; } */ reset_cmd(ac, av) int ac; char **av; { char *class = (char *) NULL; int killtasks = 1; int index = -1; /* Check for Info (mbox) Reset */ if ( ac > 1 ) { if ( !strcmp( av[1], "info" ) ) { killtasks = 0; if ( ac > 2 ) { class = av[2]; if ( ac > 3 ) index = atoi( av[3] ); } } else { printf( "\"%s\" arg to reset not valid\n", av[1] ); return 1; } } /* Call the universal VM-spanker routine... :-) */ pvmreset( mytid, killtasks, class, index ); return 0; } setenv_cmd(ac, av) int ac; char **av; { char **pp; char *p; char *sep; int n; int i; switch (ac) { case 1: for (pp = environ; *pp; pp++) printf("%s\n", *pp); break; case 2: if (p = getenv(av[1])) printf("%s\n", p); break; default: if (ac > 2) { n = 0; for (i = ac; i-- > 1; ) n += strlen(av[i]) + 1; p = TALLOC(n, char, "env"); strcpy(p, av[1]); strcat(p, "="); sep = ""; for (i = 2; i < ac; i++) { strcat(p, sep); strcat(p, av[i]); sep = " "; } pvmputenv(p); } break; } return 0; } static char *setop_strs[] = { "PvmRoute", "PvmDebugMask", "PvmAutoErr", "PvmOutputTid", "PvmOutputCode", "PvmTraceTid", "PvmTraceCode", "PvmTraceBuffer", "PvmTraceOptions", "PvmFragSize", "PvmResvTids", "PvmSelfOutputTid", "PvmSelfOutputCode", "PvmSelfTraceTid", "PvmSelfTraceCode", "PvmSelfTraceBuffer", "PvmSelfTraceOptions", "PvmShowTids", #if defined(IMA_AIX4MP) || defined(IMA_AIX5MP) \ || defined(IMA_ALPHAMP) || defined(IMA_CSPP) \ || defined(IMA_HPPAMP) || defined(IMA_RS6KMP) \ || defined(IMA_SGIMP) || defined(IMA_SGIMP6) \ || defined(IMA_SGIMP64) || defined(IMA_SUNMP) "PvmPollType", "PvmPollTime", #else "", "", #endif "PvmOutputContext", "PvmTraceContext", "PvmSelfOutputContext", "PvmSelfTraceContext", "PvmNoReset", NULL }; setopt_cmd(ac, av) int ac; char **av; { char **name; int what = -1; int value; int cc; int i; name = setop_strs; i = 1; while ( *name != NULL && what < 0 ) { if ( !strcmp( *name, av[1] ) ) what = i; else { name++; i++; } } if ( what > 0 ) { value = atoi( av[2] ); cc = pvm_setopt( what, value ); printf("%s Changed from %d to %d\n", av[1], cc, value ); } else printf("PVM Option \"%s\" Unknown.\n", av[1] ); return 0; } getopt_cmd(ac, av) int ac; char **av; { char **name; int what = -1; int value; int cc; int i; switch( ac ) { case 1: name = setop_strs; i = 1; while ( *name != NULL ) { if ( strcmp( *name, "" ) ) { cc = pvm_getopt( i ); printf("%s Currently Set to %d\n", *name, cc ); } name++; i++; } break; case 2: name = setop_strs; i = 1; while ( *name != NULL && what < 0 ) { if ( !strcmp( *name, av[1] ) ) what = i; else { name++; i++; } } if ( what > 0 ) { cc = pvm_getopt( what ); printf("%s Currently Set to %d\n", av[1], cc ); } else printf("PVM Option \"%s\" Unknown.\n", av[1] ); break; } return 0; } sig_cmd(ac, av) int ac; char **av; { int i; int signum; int tid; signum = atoi(av[1]); for (i = 2; i < ac; i++) { tid = tidtoi(av[i]); pvm_sendsig(tid, signum); } return 0; } spawn_cmd(ac, av) int ac; char **av; { int *tids = 0; char *where = 0; int flags = PvmNoSpawnParent; int count = 1; int i; int oflg = 0; int tflg = 0; int app; char *ofn = 0; char *tfn = 0; struct job *jp, *jp2; void status_msg(); void event_dump_hdr(); void output_dump_hdr(); while (av[1][0] == '-') { if (ac < 3) { fputs("incorrect arg count\n", stdout); return 1; } if (av[1][1] == '~') { flags |= PvmHostCompl; av[1]++; } if (av[1][1] == '.' || islower(av[1][1])) { where = av[1] + 1; flags |= PvmTaskHost; } if (av[1][1] == ':') where = av[1] + 1; if (isupper(av[1][1])) { where = av[1] + 1; flags |= PvmTaskArch; } if (av[1][1] == '?') flags |= PvmTaskDebug; if (isdigit(av[1][1])) count = atoi(av[1] + 1); if (av[1][1] == '>') { oflg = 1; app = 0; ofn = av[1] + 2; if (av[1][2] == '>') { app = 1; ofn++; } if (!*ofn) ofn = 0; /* printf("%s to %s\n", (app ? "Append" : "Write"), (ofn ? ofn : "(console)")); */ } if (av[1][1] == '@') { tflg = 1; tfn = av[1] + 2; if (!*tfn) tfn = ""; } /* gnu-like host (where) arg, allows IP's to be used... */ if (av[1][1] == '-') { if ( !strncmp( &(av[1][2]), "host=", 5 ) ) { where = av[1] + 7; flags |= PvmTaskHost; } } av++; ac--; } if (tflg) { jp2 = job_new(nextjob); jp2->j_flag |= JOB_TRACE; jp2->j_trcid = trc_get_tracer_id(); jp2->j_trcid->status_msg = status_msg; if (tfn && !strcmp(tfn,"")) jp2->j_trcid->event_dump_hdr = event_dump_hdr; if (oflg && !ofn) ofn = ""; if (ofn) jp2->j_trcid->output_dump_hdr = output_dump_hdr; jp2->j_trcid->event_ctx = pvm_getcontext(); jp2->j_trcid->event_tag = nextjob; jp2->j_trcid->output_ctx = pvm_getcontext(); jp2->j_trcid->output_tag = nextjob + 1; trc_set_tracing_codes( jp2->j_trcid ); printf("[%d]\n", nextjob - joboffset); nextjob += 2; trc_set_trace_file( jp2->j_trcid, tfn ); if (!trc_reset_trace_file( jp2->j_trcid )) { job_free(jp2); return 1; } trc_save_host_status_events( jp2->j_trcid ); if (ofn) { trc_set_output_file( jp2->j_trcid, ofn ); if (!trc_open_output_file( jp2->j_trcid )) { job_free(jp2); return 1; } } oflg = 0; } else { pvm_setopt(PvmTraceTid, 0); if (oflg) { pvm_setopt(PvmOutputTid, mytid); pvm_setopt(PvmOutputContext, pvm_getcontext()); pvm_setopt(PvmOutputCode, nextjob); jp = job_new(nextjob); printf("[%d]\n", nextjob - joboffset); nextjob++; if (ofn) { jp->j_ff = fopen(ofn, (app ? "a" : "w")); if (!jp->j_ff) { perror(ofn); job_free(jp); return 1; } } } else pvm_setopt(PvmOutputTid, 0); } tids = TALLOC(count > 1 ? count : 1, int, "int"); if ((i = pvm_spawn(av[1], &av[2], flags, where, count, tids)) >= 0) { if (oflg & !i) job_free(jp); if (tflg & !i) job_free(jp2); printf("%d successful\n", i); for (i = 0; i < count; i++) if (tids[i] < 0) printf("%s\n", PVMERRMSG(tids[i])); else printf("t%x\n", tids[i]); } MY_FREE(tids); return 0; } static char *tflgs[] = { 0, "f", "c", "a", "o", "s", 0, 0, "R", "H", "T" }; char * task_flags(f) int f; { static char buf[64]; int bit, i; sprintf(buf, "%x/", f); i = sizeof(tflgs)/sizeof(tflgs[0]) - 1; bit = 1 << i; while (i >= 0) { if ((f & bit) && tflgs[i]) { strcat(buf, tflgs[i]); strcat(buf, ","); } bit /= 2; i--; } buf[strlen(buf) - 1] = 0; return buf; } print_task_hdr(lflg) int lflg; { if (lflg) fputs(" HOST TID PTID PID FLAG 0x COMMAND\n", stdout); else fputs(" HOST TID FLAG 0x COMMAND\n", stdout); return 0; } print_task_rec(tip, lflg) struct pvmtaskinfo *tip; int lflg; { struct pvmhostinfo *hip = 0; if (hostlist) { for (hip = hostlist + nhosts - 1; hip >= hostlist; hip--) if (hip->hi_tid == tip->ti_host) break; if (hip < hostlist) hip = 0; } if (hip) printf("%24s", hip->hi_name); else printf("%24x", tip->ti_host); if (tip->ti_tid == mytid) printf(" (cons)"); else printf(" %8x", tip->ti_tid); if (lflg) { if (tip->ti_ptid == mytid) printf(" (cons)"); else if (tip->ti_ptid) printf(" %8x", tip->ti_ptid); else printf(" -"); printf(" %6d", tip->ti_pid); } printf(" %9s", task_flags(tip->ti_flag)); printf(" %-12s", tip->ti_a_out[0] ? tip->ti_a_out : "-"); return 0; } tasks_cmd(ac, av) int ac; char **av; { struct pvmtaskinfo *tip; int ntask; int i; struct pvmhostinfo *hip = 0; int xflg = 0; char *p; int host = pvm_tidtohost(mytid); int lflg = 0; if (!hostlist) pvm_config(&nhosts, &narchs, &hostlist); if (ac > 1) { for (p = av[1]; *p; p++) switch (*p) { case 'n': p++; if (!strcmp(p, ".")) pvm_tidtohost(mytid); else { for (hip = hostlist + nhosts; --hip >= hostlist; ) if (!(strcmp(p, hip->hi_name))) { host = hip->hi_tid; break; } if (hip < hostlist) printf("unknown host %s\n", p); } while (*p) p++; p--; break; case 'h': host = tidtoi(++p); while (*p) p++; p--; break; case 'a': host = 0; break; case 'l': lflg = 1; break; case 'x': xflg = 1; break; case '-': break; default: printf("unknown flag -%c\n", *p); break; } } if (!pvm_tasks(host, &ntask, &tip)) { print_task_hdr(lflg); for (i = 0; i < ntask; i++) { if (!xflg && (tip[i].ti_tid == mytid || tip[i].ti_tid == 0)) continue; print_task_rec(&tip[i], lflg); printf("\n"); } } return 0; } tickle_cmd(ac, av) int ac; char **av; { int nar; int arg[10]; int i; ac--; av++; for (nar = 0; nar < ac; nar++) arg[nar] = axtoi(av[nar]); if (!pvm_tickle(nar, arg, &nar, arg)) { printf("("); for (i = 0; i < nar; i++) printf(" %d", arg[i]); printf(" )\n"); } return 0; } printtm(who) int who; { Pvmtmask tm; pvm_gettmask(who, tm); trc_print_tmask(tm); return 0; } trace_cmd(ac, av) int ac; char **av; { static int topt = PvmTraceFull; static int tbuf = 0; int i; int onoff = 1; int e; int l; char buf[64]; char *optstr; Pvmtmask tm; int settm; if (ac == 1) { printtm(PvmTaskChild); return 0; } pvm_gettmask(PvmTaskChild, tm); settm = 0; for (i = 1; i < ac; i++) { if (!strcmp(av[i], "+")) { onoff = 1; } else if (!strcmp(av[i], "-")) { onoff = 0; } else if (!strcmp(av[i], "*")) { for (e = TEV_FIRST; e <= TEV_MAX; e++) { if (onoff) TEV_MASK_SET(tm, e); else TEV_MASK_UNSET(tm, e); } settm++; } else if (!strcmp(av[i], "buf")) { if ( i + 1 < ac ) { tbuf = atoi(av[++i]); pvm_setopt( PvmTraceBuffer, tbuf ); } else { printf("\nTrace Buffering set to %d bytes\n\n", tbuf); } } else if (!strcmp(av[i], "opt")) { if ( i + 1 < ac ) { i++; if ( !strcmp( av[i], "full" ) ) topt = PvmTraceFull; else if ( !strcmp( av[i], "time" ) ) topt = PvmTraceTime; else if ( !strcmp( av[i], "count" ) ) topt = PvmTraceCount; else { printf( "\nError: Unknown Trace Option \"%s\"\n\n", av[i] ); } pvm_setopt( PvmTraceOptions, topt ); } else { switch ( topt ) { case PvmTraceFull: optstr = "full"; break; case PvmTraceTime: optstr = "time"; break; case PvmTraceCount: optstr = "count"; break; default: { sprintf( buf, "", topt ); optstr = buf; } } printf("\nTrace Options set to \"%s\"\n\n", optstr ); } } else if (!strcmp(av[i], "xpvm")) { TEV_MASK_INIT( tm ); TEV_MASK_SET( tm, TEV_BARRIER ); TEV_MASK_SET( tm, TEV_BCAST ); TEV_MASK_SET( tm, TEV_JOINGROUP ); TEV_MASK_SET( tm, TEV_LVGROUP ); TEV_MASK_SET( tm, TEV_MYTID ); TEV_MASK_SET( tm, TEV_PARENT ); TEV_MASK_SET( tm, TEV_SIBLINGS ); TEV_MASK_SET( tm, TEV_SPAWN ); TEV_MASK_SET( tm, TEV_SENDSIG ); TEV_MASK_SET( tm, TEV_KILL ); TEV_MASK_SET( tm, TEV_EXIT ); TEV_MASK_SET( tm, TEV_MCAST ); TEV_MASK_SET( tm, TEV_SEND ); TEV_MASK_SET( tm, TEV_RECV ); TEV_MASK_SET( tm, TEV_RECVF ); TEV_MASK_SET( tm, TEV_NRECV ); TEV_MASK_SET( tm, TEV_PSEND ); TEV_MASK_SET( tm, TEV_PRECV ); TEV_MASK_SET( tm, TEV_TRECV ); TEV_MASK_SET( tm, TEV_PROBE ); TEV_MASK_SET( tm, TEV_ADDMHF ); TEV_MASK_SET( tm, TEV_DELMHF ); TEV_MASK_SET( tm, TEV_MHF_INVOKE ); TEV_MASK_SET( tm, TEV_USER_DEFINED ); settm++; } else { if (!strncmp(av[i], "pvm_", 4)) strcpy(buf, av[i] + 4); else strcpy(buf, av[i]); for (e = TEV_FIRST; e <= TEV_MAX; e++) if (!strcmp(pvmtevinfo[e].name, buf) || !strcmp(pvmtevinfo[e].name, av[i])) break; if ( e <= TEV_MAX ) { if (onoff) TEV_MASK_SET(tm, e); else TEV_MASK_UNSET(tm, e); settm++; } else printf("no such event \"%s\"\n", av[i]); } } if ( settm ) pvm_settmask(PvmTaskChild, tm); return 0; } unalias_cmd(ac, av) int ac; char **av; { struct alias *ap; int i; for (i = 1; i < ac; i++) if (ap = findalias(av[i])) freealias(ap); return 0; } version_cmd(ac, av) int ac; char **av; { ac = ac; av = av; printf("%s\n", pvm_version()); return 0; } names_cmd(ac, av) int ac; char **av; { struct pvmmboxinfo *classes; int nclasses; int i, j; int cc; pvm_getmboxinfo((ac > 1 ? av[1] : "*"), &nclasses, &classes); for ( i=0 ; i < nclasses ; i++ ) { printf("<%s>:\n", classes[i].mi_name); for ( j=0 ; j < classes[i].mi_nentries ; j++ ) printf("\tindex=%d owner=0x%x/%d flags=0x%x\n", classes[i].mi_indices[j], classes[i].mi_owners[j], classes[i].mi_owners[j], classes[i].mi_flags[j] ); printf("\n"); } return 0; } put_cmd(ac, av) int ac; char **av; { int cc; pvm_packf("%+ %d", PvmDataDefault, 0); cc = pvm_putinfo(av[1], pvm_getsbuf(), (int)atoi(av[2])); if (cc < 0) printf("%s\n", pvm_errlist[-cc]); return 0; } export_cmd(ac, av) int ac; char **av; { int i; char *p; if (ac == 1) { p = getenv("PVM_EXPORT"); printf("PVM_EXPORT=%s\n", p ? p : ""); } else { for (i = 1; i < ac; i++) pvm_export(av[i]); } return 0; } unexport_cmd(ac, av) int ac; char **av; { int i; for (i = 1; i < ac; i++) pvm_unexport(av[i]); return 0; }