00001
00002
00003
00004
00005 #include <SUM.h>
00006 #include <sys/errno.h>
00007 #include <sys/wait.h>
00008 #include <rpc/pmap_clnt.h>
00009 #include <sum_rpc.h>
00010 #include <soi_error.h>
00011 #include <tape.h>
00012 #include <printk.h>
00013 #include <stdio.h>
00014 #include <unistd.h>
00015 #include <sys/types.h>
00016 #include <sys/stat.h>
00017 #include <fcntl.h>
00018
00019 #include <sys/mtio.h>
00020
00021
00022 #define MAX_WAIT 20
00023 #define VDUMP "/usr/local/logs/SUM/t950_status.verify"
00024
00025 void write_time();
00026 void logkey();
00027 int rb_verify(char *action, int slot, int slotordrive);
00028 int drive_ready();
00029 extern int errno;
00030 #ifdef ROBOT_0
00031 static void robot0prog_1();
00032 #endif
00033 #ifdef ROBOT_1
00034 static void robot1prog_1();
00035 #endif
00036 static struct timeval TIMEOUT = { 120, 0 };
00037 uint32_t rinfo;
00038 uint32_t procnum;
00039
00040 static FILE *logfp;
00041 CLIENT *current_client, *clnttape;
00042 SVCXPRT *glb_transp;
00043 int debugflg = 0;
00044 char *dbname;
00045 char *timetag;
00046 char thishost[MAX_STR];
00047 char datestr[32];
00048 char logfile[MAX_STR];
00049 char robotname[MAX_STR];
00050
00051 int soi_errno = NO_ERROR;
00052
00053
00054 void open_log(char *filename)
00055 {
00056 if((logfp=fopen(filename, "a+")) == NULL) {
00057 fprintf(stderr, "Can't open the log file %s\n", filename);
00058 }
00059 }
00060
00061
00062
00063 static char *datestring()
00064 {
00065 struct timeval tvalr;
00066 struct tm *t_ptr;
00067
00068 gettimeofday(&tvalr, NULL);
00069 t_ptr = localtime((const time_t *)&tvalr);
00070 sprintf(datestr, "%s", asctime(t_ptr));
00071 datestr[19] = (char)NULL;
00072 return(&datestr[4]);
00073 }
00074
00075
00076
00077
00078 int write_log(const char *fmt, ...)
00079 {
00080 va_list args;
00081 char string[4096];
00082
00083 va_start(args, fmt);
00084 vsprintf(string, fmt, args);
00085 if(logfp) {
00086 fprintf(logfp, string);
00087 fflush(logfp);
00088 }
00089 else
00090 fprintf(stderr, string);
00091 va_end(args);
00092 return(0);
00093 }
00094
00095
00096 void sighandler(sig)
00097 int sig;
00098 {
00099 if(sig == SIGTERM) {
00100 write_log("*** %s %s got SIGTERM. Exiting.\n", datestring(), robotname);
00101 exit(1);
00102 }
00103 if(sig == SIGINT) {
00104 write_log("*** %s %s got SIGINT. Exiting.\n", datestring(), robotname);
00105
00106 exit(1);
00107 }
00108 write_log("*** %s %s got an illegal signal %d, ignoring...\n",
00109 datestring(), robotname, sig);
00110 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
00111 signal(SIGINT, sighandler);
00112 if (signal(SIGALRM, SIG_IGN) != SIG_IGN)
00113 signal(SIGALRM, sighandler);
00114 }
00115
00116
00117 void get_cmd(int argc, char *argv[])
00118 {
00119 int c;
00120
00121 while(--argc > 0 && (*++argv)[0] == '-') {
00122 while(c = *++argv[0])
00123 switch(c) {
00124 case 'd':
00125 debugflg=1;
00126 break;
00127 default:
00128 break;
00129 }
00130 }
00131 if(argc != 2) {
00132 printf("\nERROR: robotn_svc must be call with dbname and timestamp\n");
00133 exit(1);
00134 }
00135 else {
00136 dbname = argv[0];
00137 timetag = argv[1];
00138 }
00139 }
00140
00141
00142 void setup()
00143 {
00144 int pid;
00145 char *cptr;
00146
00147
00148
00149
00150
00151 sprintf(thishost, "localhost");
00152 #ifdef ROBOT_0
00153 sprintf(robotname, "robot0_svc");
00154 #endif
00155 #ifdef ROBOT_1
00156 sprintf(robotname, "robot1_svc");
00157 #endif
00158
00159 pid = getppid();
00160 sprintf(logfile, "/usr/local/logs/SUM/tape_svc_%s.log", timetag);
00161 open_log(logfile);
00162 printk_set(write_log, write_log);
00163 write_log("\n## %s %s on %s for pid = %d ##\n",
00164 datestring(), robotname, thishost, pid);
00165
00166
00167 signal(SIGINT, sighandler);
00168 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
00169 signal(SIGTERM, sighandler);
00170 if (signal(SIGALRM, SIG_IGN) != SIG_IGN)
00171 signal(SIGALRM, sighandler);
00172 }
00173
00174
00175 int main(int argc, char *argv[])
00176 {
00177 register SVCXPRT *transp;
00178
00179 get_cmd(argc, argv);
00180
00181
00182 #ifdef ROBOT_0
00183 (void) pmap_unset(ROBOT0PROG, ROBOT0VERS);
00184 transp = svctcp_create(RPC_ANYSOCK, 0, 0);
00185 if (transp == NULL) {
00186 write_log("***cannot create tcp service\n");
00187 exit(1);
00188 }
00189 if(!svc_register(transp,ROBOT0PROG,ROBOT0VERS,robot0prog_1,IPPROTO_TCP)) {
00190 write_log("***unable to register (ROBOT0PROG, ROBOT0VERS, tcp)\n");
00191 exit(1);
00192 }
00193 #endif
00194 #ifdef ROBOT_1
00195 (void) pmap_unset(ROBOT1PROG, ROBOT1VERS);
00196 transp = svctcp_create(RPC_ANYSOCK, 0, 0);
00197 if (transp == NULL) {
00198 write_log("***cannot create tcp service\n");
00199 exit(1);
00200 }
00201 if(!svc_register(transp,ROBOT1PROG,ROBOT1VERS,robot1prog_1,IPPROTO_TCP)) {
00202 write_log("***unable to register (ROBOT1PROG, ROBOT1VERS, tcp)\n");
00203 exit(1);
00204 }
00205 #endif
00206 sleep(2);
00207 setup();
00208
00209 clnttape = clnt_create(thishost, TAPEPROG, TAPEVERS, "tcp");
00210 if(!clnttape) {
00211 clnt_pcreateerror("Can't get client handle to tape_svc");
00212 write_log("tape_svc not there on %s\n", thishost);
00213 exit(1);
00214 }
00215
00216
00217
00218
00219 svc_run();
00220 write_log("!!!Fatal Error: svc_run() returned in robot[n]_svc\n");
00221 exit(1);
00222 }
00223
00224
00225
00226
00227 static void
00228 #ifdef ROBOT_0
00229 robot0prog_1(rqstp, transp)
00230 #endif
00231 #ifdef ROBOT_1
00232 robot1prog_1(rqstp, transp)
00233 #endif
00234 struct svc_req *rqstp;
00235 SVCXPRT *transp;
00236 {
00237 union __svcargun {
00238 Rkey tapedo_1_arg;
00239 } argument;
00240 char *result, *call_err;
00241 enum clnt_stat clnt_stat;
00242
00243 bool_t (*xdr_argument)(), (*xdr_result)();
00244 char *(*local)();
00245
00246 switch (rqstp->rq_proc) {
00247 case NULLPROC:
00248 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00249 return;
00250 case ROBOTDO:
00251 xdr_argument = xdr_Rkey;
00252 xdr_result = xdr_Rkey;;
00253 local = (char *(*)()) robotdo_1;
00254 break;
00255 case ROBOTDOORDO:
00256 xdr_argument = xdr_Rkey;
00257 xdr_result = xdr_Rkey;;
00258 local = (char *(*)()) robotdoordo_1;
00259 break;
00260 default:
00261 write_log("**robot[0,1]prog_1() dispatch default procedure %d,ignore\n", rqstp->rq_proc);
00262 svcerr_noproc(transp);
00263 return;
00264 }
00265 bzero((char *)&argument, sizeof(argument));
00266 if (!svc_getargs(transp, (xdrproc_t)xdr_argument, (char *)&argument)) {
00267 write_log("***Error on svc_getargs()\n");
00268 svcerr_decode(transp);
00269
00270
00271
00272
00273 svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00274 return;
00275
00276 }
00277 glb_transp = transp;
00278
00279 result = (*local)(&argument, rqstp);
00280
00281 if(result) {
00282 if(result == (char *)1) {
00283
00284 }
00285 else {
00286 if(debugflg) {
00287 write_log("\nKEYS in robot[0,1]_svc response to tape_svc are:\n");
00288 keyiterate(logkey, (KEY *)result);
00289 }
00290 clnt_stat=clnt_call(current_client, procnum, (xdrproc_t)xdr_result,
00291 (char *)result, (xdrproc_t)xdr_void, 0, TIMEOUT);
00292 if(clnt_stat != 0) {
00293 clnt_perrno(clnt_stat);
00294 write_log("***Error in robotn_svc on clnt_call() back to %d procedure\n", procnum);
00295 call_err = clnt_sperror(current_client, "Err");
00296 write_log("%s\n", call_err);
00297 }
00298
00299 freekeylist((KEY **)&result);
00300 }
00301 }
00302 if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)&argument)) {
00303 write_log("**unable to free arguments\n");
00304
00305 }
00306 return;
00307 }
00308
00309
00310
00311
00312
00313
00314 void send_ack()
00315 {
00316
00317 if (!svc_sendreply(glb_transp, (xdrproc_t)xdr_uint32_t, (char *)&rinfo)) {
00318 write_log("***Error on immed ack back to client. FATAL???\n");
00319 svcerr_systemerr(glb_transp);
00320 }
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 KEY *robotdo_1(KEY *params)
00367 {
00368 CLIENT *client;
00369 static KEY *retlist;
00370 int sim, d, s, ret, s1, s2, rv;
00371 int loadcmd = 0;
00372 char *cmd;
00373 char errstr[128], scr[80], action[80];
00374
00375 if(findkey(params, "DEBUGFLG")) {
00376 debugflg = getkey_int(params, "DEBUGFLG");
00377 if(debugflg) {
00378 write_log("!!Keylist in robotdo_1() is:\n");
00379 keyiterate(logkey, params);
00380 }
00381 }
00382 rinfo = 0;
00383 send_ack();
00384 retlist = newkeylist();
00385 add_keys(params, &retlist);
00386 client = (CLIENT *)getkey_fileptr(params, "current_client");
00387
00388 setkey_fileptr(&retlist, "current_client", (FILE *)client);
00389 sim = 0;
00390 if(findkey(params, "sim")) {
00391 sim = getkey_int(params, "sim");
00392 }
00393
00394 if(findkey(params, "cmd1")) {
00395 cmd = GETKEY_str(params, "cmd1");
00396 if(strstr(cmd, " load ")) {
00397 loadcmd = 1;
00398 }
00399 sscanf(cmd, "%s %s %s %s %d %d", scr, scr, scr, action, &s, &d);
00400 s--;
00401 if(strstr(cmd, " transfer ")) {
00402 d--;
00403 }
00404 write_log("*Rb:cmd: %s\n", cmd);
00405 if(sim) {
00406 sleep(2);
00407 }
00408 else {
00409 sleep(2);
00410 system(cmd);
00411 rv = rb_verify(action, s, d);
00412 if(rv != 1) {
00413 write_log("Err Retry: Can't verify: %s\n", cmd);
00414 system(cmd);
00415 rv = rb_verify(action, s, d);
00416 if(rv != 1) {
00417 write_log("***Rb:failure\n\n");
00418 setkey_int(&retlist, "STATUS", 1);
00419 sprintf(errstr, "Error on: %s", cmd);
00420 setkey_str(&retlist, "ERRSTR", errstr);
00421 current_client = clnttape;
00422 procnum = TAPERESPROBOTDO;
00423 return(retlist);
00424 }
00425 }
00426 }
00427 if(strstr(cmd, " transfer ")) {
00428 sscanf(cmd, "%s %s %s %s %d %d", scr, scr, scr, scr, &s1, &s2);
00429 write_log("***Rb:success transfer %d %d\n\n", s1, s2);
00430 }
00431 else {
00432 write_log("***Rb:success\n\n");
00433 }
00434 }
00435 if(findkey(params, "cmd2")) {
00436 cmd = GETKEY_str(params, "cmd2");
00437 if(strstr(cmd, " load ")) {
00438 loadcmd = 1;
00439 }
00440 sscanf(cmd, "%s %s %s %s %d %d", scr, scr, scr, action, &s, &d);
00441 s--;
00442 if(strstr(cmd, " transfer ")) {
00443 d--;
00444 }
00445 write_log("*Rb:cmd: %s\n", cmd);
00446 if(sim) {
00447 sleep(2);
00448 }
00449 else {
00450 sleep(2);
00451 system(cmd);
00452 rv = rb_verify(action, s, d);
00453 if(rv != 1) {
00454 write_log("Err Retry: Can't verify: %s\n", cmd);
00455 system(cmd);
00456 rv = rb_verify(action, s, d);
00457 if(rv != 1) {
00458 write_log("***Rb:failure\n\n");
00459 setkey_int(&retlist, "STATUS", 1);
00460 sprintf(errstr, "Error on: %s", cmd);
00461 setkey_str(&retlist, "ERRSTR", errstr);
00462 current_client = clnttape;
00463 procnum = TAPERESPROBOTDO;
00464 return(retlist);
00465 }
00466 }
00467 }
00468 write_log("***Rb:success\n\n");
00469 }
00470 current_client = clnttape;
00471 procnum = TAPERESPROBOTDO;
00472 setkey_int(&retlist, "STATUS", 0);
00473 if(loadcmd) {
00474 if(!drive_ready(sim, d)) {
00475 setkey_int(&retlist, "STATUS", 1);
00476 sprintf(errstr, "Error: drive not ready after: %s", cmd);
00477 setkey_str(&retlist, "ERRSTR", errstr);
00478 }
00479 }
00480 return(retlist);
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 KEY *robotdoordo_1(KEY *params)
00496 {
00497 CLIENT *client;
00498 static KEY *retlist;
00499 int sim, reqcnt, i, mvdoor2slot;
00500 char *cmd, *cptr;
00501 char ext[96], errstr[128];
00502
00503
00504 if(debugflg) {
00505 write_log("!!Keylist in robotdoordo_1() is:\n");
00506 keyiterate(logkey, params);
00507 }
00508 mvdoor2slot = 0;
00509 rinfo = 0;
00510 send_ack();
00511 retlist = newkeylist();
00512 add_keys(params, &retlist);
00513 client = (CLIENT *)getkey_fileptr(params, "current_client");
00514
00515 setkey_fileptr(&retlist, "current_client", (FILE *)client);
00516 current_client = clnttape;
00517 procnum = TAPERESPROBOTDOORDO;
00518 sim = 0;
00519 if(findkey(params, "sim")) {
00520 sim = getkey_int(params, "sim");
00521 }
00522 reqcnt = getkey_int(params, "reqcnt");
00523 cptr = GETKEY_str(params, "OP");
00524 if(!strcmp(cptr, "door")) {
00525 mvdoor2slot = 1;
00526 }
00527 for(i=0; i < reqcnt; i++) {
00528 sprintf(ext, "cmd_%d", i);
00529 cmd = GETKEY_str(params, ext);
00530 if(mvdoor2slot)
00531 write_log("*Rb:t50door: %s\n", cmd);
00532 else
00533 write_log("*Rb:door: %s\n", cmd);
00534 if(sim) {
00535 sleep(2);
00536 }
00537 else {
00538 sleep(2);
00539 if(system(cmd)) {
00540 write_log("Err Retry: %s\n", cmd);
00541 if(system(cmd)) {
00542 if(mvdoor2slot)
00543 write_log("**Rb:t50doorfailure\n\n");
00544 else
00545 write_log("**Rb:doorfailure\n\n");
00546 setkey_int(&retlist, "STATUS", 1);
00547 sprintf(errstr, "Error on: %s", cmd);
00548 setkey_str(&retlist, "ERRSTR", errstr);
00549 return(retlist);
00550 }
00551 }
00552 }
00553 if(mvdoor2slot)
00554 write_log("**Rb:t50doorsuccess\n\n");
00555 else
00556 write_log("**Rb:doorsuccess\n\n");
00557 }
00558 if(mvdoor2slot)
00559 write_log("**Rb:t50doorcomplete\n\n");
00560 else
00561 write_log("**Rb:doorcomplete\n\n");
00562 setkey_int(&retlist, "STATUS", 0);
00563 return(retlist);
00564 }
00565
00566
00567
00568
00569 int drive_ready(int sim, int drive)
00570 {
00571 int fd;
00572 int ret = 1;
00573 int waitcnt = 0;
00574 char devname[16];
00575 struct mtget mt_stat;
00576
00577 if(sim) { return(1); }
00578 sprintf(devname, "/dev/nst%d", drive);
00579 fd = open(devname, O_RDONLY | O_NONBLOCK);
00580 while(1) {
00581 ioctl(fd, MTIOCGET, &mt_stat);
00582
00583 if(mt_stat.mt_gstat == 0) {
00584 if(++waitcnt == MAX_WAIT) {
00585 ret = 0;
00586 break;
00587 }
00588 sleep(1);
00589 }
00590 else break;
00591 }
00592 close(fd);
00593 return(ret);
00594 }
00595
00596 void write_time()
00597 {
00598 struct timeval tvalr;
00599 struct tm *t_ptr;
00600 char datestr[32];
00601
00602 gettimeofday(&tvalr, NULL);
00603 t_ptr = localtime((const time_t *)&tvalr.tv_sec);
00604 sprintf(datestr, "%s", asctime(t_ptr));
00605 write_log("%s", datestr);
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 int rb_verify(char *action, int slot, int slotordrive)
00621 {
00622 FILE *finv;
00623 int s, sord, retry;
00624 int drivenum, slotnum, i, j, k, tstate;
00625 char *drive_tapes[MAX_DRIVES], *slot_tapes[MAX_SLOTS];
00626 char *token, *cptr;
00627 char cmd[MAXSTR], row[MAXSTR];
00628
00629 retry = 6;
00630 while(retry) {
00631 sprintf(cmd, "/usr/sbin/mtx -f %s status 1> %s 2>&1", LIBDEV, VDUMP);
00632 if(system(cmd)) {
00633 write_log("***Verify: failure. errno=%d\n", errno);
00634 return(-1);
00635 }
00636 if (!(finv = fopen(VDUMP, "r"))) {
00637 write_log("**Fatal error: can't open %s\n", VDUMP);
00638 return(-1);
00639 }
00640 drivenum = slotnum = 0;
00641 for(i=0; i < MAX_DRIVES; i++) { drive_tapes[i] = "NoTape"; }
00642 while (fgets (row,MAXSTR,finv)) {
00643 if(strstr(row, "Data Transfer Element")) {
00644 if(strstr(row, ":Full")) {
00645 token = (char *)strtok(row, "=");
00646 token = (char *)strtok(NULL, "=");
00647 if(!token) {
00648 token = "NoTape";
00649
00650
00651 cptr = index(token, ' ');
00652 if(cptr) {
00653 *cptr = (char)NULL;
00654 }
00655 else {
00656 write_log("Bad mtx line: %s\n", row);
00657 token = "NoTape";
00658 }
00659 }
00660 drive_tapes[drivenum] = (char *)strdup(token);
00661 }
00662
00663
00664 drivenum++;
00665 }
00666 else if(strstr(row, "Storage Element")) {
00667 if(strstr(row, ":Full")) {
00668 token = (char *)strtok(row, "=");
00669 token = (char *)strtok(NULL, "=");
00670 if(!token) {
00671 token = "NoTape";
00672 } else {
00673 cptr = index(token, ' ');
00674 if(cptr) {
00675 *cptr = (char)NULL;
00676 }
00677 else {
00678 write_log("Bad mtx line: %s\n", row);
00679 token = "NoTape";
00680 }
00681 }
00682 slot_tapes[slotnum] = (char *)strdup(token);
00683 }
00684 else {
00685 slot_tapes[slotnum] = "NoTape";
00686 }
00687
00688
00689 slotnum++;
00690 }
00691 }
00692 fclose(finv);
00693 if(slotnum != MAX_SLOTS) {
00694 write_log("Inv returned wrong # of slots. Retry.\n");
00695 --retry;
00696 if(retry == 0) {
00697 write_log("***Fatal error: Can't do tape inventory\n");
00698 return(-1);
00699 }
00700 }
00701 else { retry = 0; }
00702 }
00703
00704 if(!strcmp(action, "unload")) {
00705 if(strcmp(drive_tapes[slotordrive], "NoTape")) {
00706 return(0);
00707 }
00708 if(!strcmp(slot_tapes[slot], "NoTape")) {
00709 return(0);
00710 }
00711 return(1);
00712 }
00713 else if(!strcmp(action, "load")) {
00714 if(!strcmp(drive_tapes[slotordrive], "NoTape")) {
00715 return(0);
00716 }
00717 if(strcmp(slot_tapes[slot], "NoTape")) {
00718 return(0);
00719 }
00720 return(1);
00721 }
00722 else {
00723 if(strcmp(slot_tapes[slot], "NoTape")) {
00724 return(0);
00725 }
00726 if(!strcmp(slot_tapes[slotordrive], "NoTape")) {
00727 return(0);
00728 }
00729 return(1);
00730 }
00731 }