00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <SUM.h>
00013 #include <soi_key.h>
00014 #include <sys/time.h>
00015 #include <sys/errno.h>
00016 #include <sys/stat.h>
00017 #include <rpc/rpc.h>
00018 #include <rpc/pmap_clnt.h>
00019 #include <sum_rpc.h>
00020 #include <soi_error.h>
00021 #include <printk.h>
00022
00023 char *get_eff_date(int plusdays);
00024
00025 #define TODAY (atol(get_eff_date(0)))
00026 #define TAR_FILE_SZ 500000000
00027 #define ARCH_CHUNK 30
00028 #define NOTAPEARC "/usr/local/logs/soc/NOTAPEARC"
00029 #define MYNAME "tapearcX"
00030 #define MANIFESTMVDIR "/usr/local/logs/manifest/DONE"
00031
00032 extern void printkey (KEY *key);
00033 void usage();
00034 void get_cmd(int argc, char *argv[]);
00035 void setup();
00036 void goaway();
00037 void print_list(char *title, PADATA *p);
00038 void print_entry(PADATA *p);
00039 void sighandler(int sig);
00040 KEY *tapearcdo_1(KEY *params);
00041 static void tapearcprog_1(struct svc_req *rqstp, SVCXPRT *transp);
00042
00043
00044 static struct timeval TIMEOUT = { 120, 0 };
00045 static int WRTSTATUS;
00046 uint32_t rinfo;
00047 int TAPEARCDO_called;
00048 int curr_group_id;
00049 int filegroup;
00050 int thispid;
00051 PADATA *walker;
00052 PADATA *aplist = NULL;
00053 KEY *alist;
00054 FILE *fpman;
00055 CLIENT *current_client, *clnttape;
00056 SVCXPRT *glb_transp;
00057 SVCXPRT *transp;
00058
00059 int count_list(PADATA *p);
00060 int storeunitarch(int docnt);
00061 int soi_errno = NO_ERROR;
00062 char *dbname = "jsoc_sums";
00063 char *username;
00064 char *manifest;
00065 char *mfilename;
00066 char manifestmv[MAX_STR];
00067 char thishost[MAX_STR];
00068 char mline[256];
00069 time_t now;
00070 int verbose = 0;
00071 int debugflg = 0;
00072 int test60d = 0;
00073 int archive_minimum = 0;
00074 int archive_pending = 0;
00075 int is_connected=0;
00076 int ctrlcnt = 0;
00077 int found = 0;
00078 int do_tape_called = 0;
00079 int mstatus;
00080
00081 static struct timeval first[6], second[6];
00082 float ftmp;
00083
00084
00085 void StartTimer(int n)
00086 {
00087 gettimeofday (&first[n], NULL);
00088 }
00089
00090 float StopTimer(int n)
00091 {
00092 gettimeofday (&second[n], NULL);
00093 if (first[n].tv_usec > second[n].tv_usec) {
00094 second[n].tv_usec += 1000000;
00095 second[n].tv_sec--;
00096 }
00097 return (float) (second[n].tv_sec-first[n].tv_sec) +
00098 (float) (second[n].tv_usec-first[n].tv_usec)/1000000.0;
00099 }
00100
00101
00102
00103
00104
00105
00106 int find_tapearc()
00107 {
00108 FILE *fplog;
00109 char acmd[128], line[128], look[64];
00110 char log[] = "/usr/local/logs/SUM/find_tapearc.log";
00111 int count = 0;
00112
00113 sprintf(acmd, "ps -ef | grep tapearc 1> %s 2>&1", log);
00114 if(system(acmd)) {
00115 printf("Can't execute %s.\n", acmd);
00116 return(-1);
00117 }
00118 if((fplog=fopen(log, "r")) == NULL) {
00119 printf("Can't open %s to find tapearc\n", log);
00120 return(-1);
00121 }
00122 sprintf(look, " %s", dbname);
00123 while(fgets(line, 128, fplog)) {
00124 if (strstr(line, look) && strstr(line, "tapearc")) {
00125 if(!strstr(line, "sh ")) count++;
00126 }
00127 }
00128 fclose(fplog);
00129 return (count);
00130 }
00131
00132 int count_list(PADATA *p) {
00133 PADATA *walker = p;
00134 int count=0;
00135 while (walker) {
00136 count++;
00137 walker=walker->next;
00138 }
00139 return count;
00140 }
00141
00142
00143 void print_entry(PADATA *p) {
00144 if (!p) return;
00145 printf ("%d\t%15.6e\t%s\n", p->group_id, p->bytes, p->wd);
00146 }
00147
00148 void print_list(char *title, PADATA *p) {
00149 PADATA *walker = p;
00150 if (title) printf("\n%s\n", title);
00151 while (walker) {
00152 print_entry (walker);
00153 walker = walker->next;
00154 }
00155 }
00156
00157 int send_mail(char *fmt, ...)
00158 {
00159 va_list args;
00160 char string[1024], cmd[1024];
00161
00162 va_start(args, fmt);
00163 vsprintf(string, fmt, args);
00164
00165 sprintf(cmd, "echo \"%s\" | Mail -s \"tapearc mail\" jsoc_sysadm@sun.stanford.edu", string);
00166 system(cmd);
00167 va_end(args);
00168 return(0);
00169 }
00170
00171 void usage()
00172 {
00173 printf("This is a stand alone program that will archive all the SUMS\n");
00174 printf("archive pending storage units, from the given manifest file,\n");
00175 printf("to the tape_svc supported drives.\n");
00176 printf("The maifest file is produced by tape_do_archive.pl\n");
00177 printf("Usage: tapearcX [-d] [-h] manifiest_file\n");
00178 printf(" where -d = pass a debug flag onto tape_svc\n");
00179 printf(" -h = help. print usage\n");
00180 printf("Sample call:\n");
00181 printf(" tapearcX /usr/local/logs/manifest/manifest.group3\n");
00182 printf("NOTE: you must be user production to run.\n");
00183 exit(1);
00184 }
00185
00186
00187 void get_cmd(int argc, char *argv[])
00188 {
00189 int c;
00190
00191 while(--argc > 0 && (*++argv)[0] == '-') {
00192 while((c = *++argv[0]))
00193 switch(c) {
00194 case 'd':
00195 debugflg=1;
00196 break;
00197 case 'v':
00198 verbose=1;
00199 break;
00200 case 'h':
00201 usage();
00202 break;
00203 default:
00204 usage();
00205 break;
00206 }
00207 }
00208 if(argc != 1) usage();
00209 manifest = argv[0];
00210 if(mfilename = rindex(manifest, '/')) mfilename++;
00211 else mfilename = manifest;
00212 sprintf(manifestmv, "%s/%s.%ld", MANIFESTMVDIR, mfilename, TODAY);
00213 thispid = getpid();
00214 }
00215
00216
00217
00218
00219
00220
00221 void goaway()
00222 {
00223 if(is_connected)
00224 if(DS_DisConnectDB())
00225 fprintf(stderr, "DS_DisconnectDB() error\n");
00226 if(rename(manifest, manifestmv)) {
00227 fprintf(stderr, "Can't mv %s to %s\n", manifest, manifestmv);
00228 }
00229 exit(1);
00230 }
00231
00232
00233 void sighandler(int sig)
00234 {
00235 char line[80];
00236
00237
00238
00239
00240 if(ctrlcnt++ == 0) {
00241 printf("\nInterrupt not allowed during tape write operations...\n");
00242 printf("Hit ^C again for an option to abort...\n");
00243 }
00244 else {
00245 printf("Do you want to force an abort (make sure you know what you're doing) [y/n] = ");
00246 if(gets(line) == NULL) { return; }
00247 if(!strcmp(line, "y")) { goaway(); }
00248 }
00249 }
00250
00251
00252
00253 void setup()
00254 {
00255 char *cptr;
00256 int n;
00257 char pgport[32];
00258
00259 printk_set(printf, printf);
00260 gethostname(thishost, MAX_STR);
00261 cptr = index(thishost, '.');
00262 if(cptr) *cptr = (char)NULL;
00263
00264 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
00265 signal(SIGINT, sighandler);
00266 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
00267 signal(SIGTERM, sighandler);
00268
00269
00270
00271 (void) pmap_unset(TAPEARCPROG, (u_long)filegroup);
00272 transp = svctcp_create(RPC_ANYSOCK, 0, 0);
00273 if (transp == NULL) {
00274 printf("***cannot create tcp service\n");
00275 exit(1);
00276 }
00277 if (!svc_register(transp, TAPEARCPROG, (u_long)filegroup, tapearcprog_1, IPPROTO_TCP)) {
00278 printf("***unable to register (TAPEARCPROG, (u_long)filegroup, tcp)\n");
00279 exit(1);
00280 }
00281 printf("Registered TAPEARCPROG with vers# %d\n", filegroup);
00282
00283 clnttape = clnt_create(thishost, TAPEPROG, TAPEVERS, "tcp");
00284 if(!clnttape) {
00285 clnt_pcreateerror("Can't get client handle to tape_svc in tapearc");
00286 printf("tapearc can't get tape_svc handle on %s\n", thishost);
00287 exit(1);
00288 }
00289
00290 if (DS_ConnectDB(dbname)) {
00291 fprintf(stderr,"Error in connecting to database %s\n", dbname);
00292 goaway();
00293 }
00294 is_connected=1;
00295 }
00296
00297
00298
00299 int call_tape_svc() {
00300 int status;
00301 uint32_t retstat;
00302 char *call_err;
00303
00304 WRTSTATUS = 0;
00305 StartTimer(0);
00306 setkey_int(&alist, "tapearcvers", filegroup);
00307 setkey_int(&alist, "tapearcXpid", thispid);
00308 status = clnt_call(clnttape, WRITEDO, (xdrproc_t)xdr_Rkey, (char *)alist,
00309 (xdrproc_t)xdr_uint32_t, (char *)&retstat, TIMEOUT);
00310 if(status != 0) {
00311 clnt_perrno(status);
00312 printf("***Error on clnt_call() to tape_svc WRITEDO procedure\n");
00313 call_err = clnt_sperror(clnttape, "Err");
00314 printf("%s\n", call_err);
00315 if(status != RPC_TIMEDOUT) {
00316 printf("I'm aborting now...\n");
00317 goaway();
00318 }
00319 else {
00320
00321 ftmp = StopTimer(0);
00322 printf("Measured timeout was %f sec\n", ftmp);
00323 printf("RESULT_PEND (!!ASSUMED). Arc in progress...\n");
00324 return(0);
00325 }
00326 }
00327 if(retstat == RESULT_PEND) {
00328 printf("RESULT_PEND. Arc in progress...\n");
00329 }
00330 else {
00331 if(retstat == NO_TAPE_IN_GROUP) {
00332 printf("Can't assign tape for group\n");
00333 printf("Check tape_svc log for any error messages\n");
00334 printf("I'm aborting now...\n");
00335 goaway();
00336 }
00337 else if(retstat == NO_CLNTTCP_CREATE) {
00338 printf("NO_CLNTTCP_CREATE error on ret from clnt_call(clntape,WRITEDO)\n");
00339 printf("Check tape_svc log for any error messages\n");
00340 printf("I'm aborting now...\n");
00341 goaway();
00342 }
00343 else if(retstat == SUM_TAPE_SVC_OFF) {
00344 printf("SUM_TAPE_SVC_OFF error on ret from clnt_call(clntape,WRITEDO)\n");
00345 printf("The tape_svc has been set off line. I'm aborting\n");
00346 goaway();
00347 }
00348 else
00349 printf("retstat = %d on ret from clnt_call(clntape,WRITEDO)\n",retstat);
00350 }
00351 return(0);
00352 }
00353
00354
00355
00356
00357 int do_tape_file()
00358 {
00359 struct stat stbuf;
00360 int i = 0;
00361 char name[128];
00362 double total_bytes = 0.0;
00363
00364 do_tape_called = 1;
00365 walker = aplist;
00366 if(!walker) return(1);
00367 alist = newkeylist();
00368 while(walker) {
00369 if(stat(walker->wd, &stbuf)) {
00370 send_mail("%s: Don't archive bad dir: %s \n", MYNAME, walker->wd);
00371 printf("%s: Don't archive bad dir: %s \n", MYNAME, walker->wd);
00372 }
00373 else {
00374 if(walker->group_id < 0) {
00375 send_mail("%s: Don't archive neg group#: %d \n ds_index=%u\n", MYNAME, walker->group_id, walker->ds_index);
00376 printf("%s: Don't archive neg group#: %d \n", MYNAME, walker->group_id);
00377 }
00378 else {
00379 sprintf(name, "wd_%d", i);
00380 setkey_str(&alist, name, walker->wd);
00381 sprintf(name, "effective_date_%d", i);
00382 setkey_str(&alist, name, walker->effective_date);
00383 sprintf(name, "sumid_%d", i);
00384 setkey_uint64(&alist, name, walker->sumid);
00385 sprintf(name, "bytes_%d", i);
00386 setkey_double(&alist, name, walker->bytes);
00387 total_bytes += walker->bytes;
00388 sprintf(name, "status_%d", i);
00389 setkey_int(&alist, name, walker->status);
00390 sprintf(name, "archsub_%d", i);
00391 setkey_int(&alist, name, walker->archsub);
00392 sprintf(name, "group_id_%d", i);
00393 setkey_int(&alist, name, walker->group_id);
00394 sprintf(name, "safe_id_%d", i);
00395 setkey_int(&alist, name, walker->safe_id);
00396 sprintf(name, "ds_index_%d", i);
00397 setkey_uint64(&alist, name, walker->ds_index);
00398 sprintf(name, "username_%d", i);
00399 setkey_str(&alist, name, username);
00400 i++;
00401 }
00402 }
00403 walker=walker->next;
00404 }
00405 setkey_double(&alist, "total_bytes", total_bytes);
00406 setkey_int(&alist, "DEBUGFLG", debugflg);
00407 setkey_int(&alist, "reqcnt", i);
00408 call_tape_svc();
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418 int file_from_manifest()
00419 {
00420 char *token;
00421 int group;
00422 int l_status = DAAP;
00423 int l_archsub = DAADP;
00424 char dsname[96], sudir[32];
00425 char eff_date[32];
00426 uint64_t sumid, sunum;
00427 double bytes;
00428
00429 while(fgets(mline, 256, fpman)) {
00430 if(!strncmp(mline, "\n", 1)) { continue; }
00431 if(strstr(mline, "#File ")) {
00432
00433 printf("Found next file: %s\n", mline);
00434 print_list ("archive pending list for prev file", aplist);
00435 if(found) do_tape_file();
00436 fgets(mline, 256, fpman);
00437 aplist = NULL;
00438 if(found) {
00439 found = 0;
00440 return(1);
00441 }
00442 return(0);
00443 }
00444 found = 1;
00445 token = (char *)strtok(mline, " ");
00446 group = (int)atoi(token);
00447 token = (char *)strtok(NULL, " ");
00448 strcpy(dsname, token);
00449 token = (char *)strtok(NULL, " ");
00450 sunum = (uint64_t)strtol(token, NULL, 0);
00451 token = (char *)strtok(NULL, " ");
00452 strcpy(sudir, token);
00453 token = (char *)strtok(NULL, " ");
00454 bytes = (double)strtod(token, NULL);
00455 token = (char *)strtok(NULL, " ");
00456 sumid = (uint64_t)strtol(token, NULL, 0);
00457 token = (char *)strtok(NULL, " ");
00458 strcpy(eff_date, token);
00459 setpadatar(&aplist, sudir, sumid, bytes, l_status, l_archsub, eff_date, group, 0, sunum);
00460 }
00461 if(found) do_tape_file();
00462 found = 0;
00463
00464
00465 return(-1);
00466 }
00467
00468 int main(int argc, char *argv[])
00469 {
00470 FILE *notapearc;
00471 char *token;
00472
00473 get_cmd(argc, argv);
00474 if(!(username = (char *)getenv("USER"))) username = "nouser";
00475 if(strcmp(username, "production")) {
00476 printf("!!NOTE: You must be user production to run tapearc!\n");
00477 exit(1);
00478 }
00479 if((notapearc=fopen(NOTAPEARC, "r")) != NULL) {
00480 printf("Can't run a tapearc while Imp/Exp of tapes is active\n");
00481 fclose(notapearc);
00482 exit(-1);
00483 }
00484
00485 printf ("Current effective_date is %ld\n", TODAY);
00486 time (&now); printf ("%s\n",asctime(localtime(&now)));
00487 printf ("Datasets will be archived according to manifest file %s\n",
00488 manifest);
00489 if((fpman=fopen(manifest, "r")) == NULL) {
00490 printf("Can't open manifest file %s\n", manifest);
00491 return(-1);
00492 }
00493 while(fgets(mline, 256, fpman)) {
00494 if(!strncmp(mline, "#group=", 7)) {
00495 token = (char *)strtok(mline, "=");
00496 token = (char *)strtok(NULL, " ");
00497 filegroup = (int)atoi(token);
00498 }
00499 if(!strncmp(mline, "#File ", 6)) {
00500 printf("%s\n", mline);
00501 fgets(mline, 256, fpman);
00502 break;
00503 }
00504 }
00505 setup();
00506 while(1) {
00507 mstatus = file_from_manifest();
00508 if(mstatus == 0) continue;
00509 if(mstatus == -1) {
00510
00511 if(do_tape_called == 0) {
00512 goaway();
00513 }
00514 }
00515 break;
00516 }
00517 do_tape_called = 0;
00518
00519 svc_run();
00520 }
00521
00522
00523
00524
00525
00526 static void
00527 tapearcprog_1(rqstp, transp)
00528 struct svc_req *rqstp;
00529 SVCXPRT *transp;
00530 {
00531 union __svcargun {
00532 Rkey tapearcdo_1_arg;
00533 } argument;
00534 char *result;
00535
00536 bool_t (*xdr_argument)(), (*xdr_result)();
00537 char *(*local)();
00538 switch (rqstp->rq_proc) {
00539 case NULLPROC:
00540 printf("Called NULLPROC in tapearcprog_1()\n");
00541 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00542 return;
00543 case TAPEARCDO:
00544
00545 TAPEARCDO_called = 1;
00546 xdr_argument = xdr_Rkey;
00547 xdr_result = xdr_Rkey;;
00548 local = (char *(*)()) tapearcdo_1;
00549 break;
00550 default:
00551 printf("**tapearcprog_1() dispatch default procedure %ld,ignore\n", rqstp->rq_proc);
00552 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00553 svcerr_noproc(transp);
00554 return;
00555 }
00556 bzero((char *)&argument, sizeof(argument));
00557 if (!svc_getargs(transp, (xdrproc_t)xdr_argument, (char *)&argument)) {
00558 printf("***Error on svc_getargs()\n");
00559 svcerr_decode(transp);
00560 svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00561 return;
00562
00563 }
00564
00565 if(!svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL)) {
00566 svcerr_systemerr(transp);
00567 return;
00568 }
00569 glb_transp = transp;
00570 result = (*local)(&argument, rqstp);
00571
00572
00573 if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)&argument)) {
00574 printf("**unable to free arguments\n");
00575
00576 }
00577 return;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 KEY *tapearcdo_1(KEY *params)
00626 {
00627 int groupid;
00628 uint64_t index;
00629
00630
00631 groupid = getkey_int(params, "group_id");
00632 index = getkey_uint64(params, "ds_index_0");
00633 if(findkey(params, "DEBUGFLG")) {
00634 debugflg = getkey_int(params, "DEBUGFLG");
00635 if(debugflg) {
00636 printf("!!TEMP in tapearcdo_1() call in tapearc. keylist is:\n");
00637 keyiterate(printkey, params);
00638 }
00639 }
00640 if(WRTSTATUS = getkey_int(params, "STATUS")) {
00641 printf("**Error return for write of group_id=%d 1st ds_index=%lu\n",
00642 groupid, index);
00643 }
00644 else {
00645 printf("Successful write for group_id=%d 1st_ds_index=%lu\n",
00646 groupid, index);
00647 }
00648 if(mstatus == -1) {
00649 goaway();
00650 }
00651 while(1) {
00652 mstatus = file_from_manifest();
00653 if(mstatus == 0) continue;
00654 if(mstatus == -1) {
00655
00656 if(do_tape_called == 0) {
00657 goaway();
00658 }
00659 }
00660 break;
00661 }
00662 do_tape_called = 0;
00663 return((KEY *)1);
00664 }
00665
00666
00667
00668
00669 char *get_eff_date(int plusdays)
00670 {
00671 struct timeval tvalr;
00672 struct tm *t_ptr;
00673 time_t newtime;
00674 char *timestr;
00675
00676 if(gettimeofday(&tvalr, NULL) == -1) {
00677 return("200712121212");
00678 }
00679 t_ptr = localtime(&tvalr.tv_sec);
00680 t_ptr->tm_mday = t_ptr->tm_mday + plusdays;
00681 newtime = mktime(t_ptr);
00682 t_ptr = localtime(&newtime);
00683 timestr = (char *)malloc(32);
00684 sprintf(timestr, "%04d%02d%02d%02d%02d",
00685 t_ptr->tm_year+1900, t_ptr->tm_mon+1, t_ptr->tm_mday,
00686 t_ptr->tm_hour, t_ptr->tm_min);
00687 return(timestr);
00688 }