|
|
1.1 ! root 1: /* ! 2: * ilwrite() : write driver ! 3: * 1. copy Lock request info to lockbuf ! 4: * 2. follow action in l_act ! 5: * 3. Error return conditions ! 6: * -1: lockrequest fails(only on act=1) ! 7: * -2: attempt to release a lock not set ! 8: * by calling program ! 9: * -3: illegal action requested ! 10: */ ! 11: ! 12: # include <stdio.h> ! 13: # include <sys/param.h> ! 14: # include <sys/socket.h> ! 15: # include <netinet/in.h> ! 16: # include <sys/ioctl.h> ! 17: # include <errno.h> ! 18: # include <ildr.h> ! 19: # include <sys/time.h> ! 20: # include <netdb.h> ! 21: # include <sccs.h> ! 22: ! 23: # define TRUE 1 ! 24: # define FALSE 0 ! 25: ! 26: # ifdef DEBUG ! 27: static int ildebug = TRUE; ! 28: # endif DEBUG ! 29: ! 30: SCCSID(@(#)ildr.c 8.1 12/31/84) ! 31: ! 32: int From_server; /* read connection from socket server */ ! 33: long Read_fmt; /* bit mask for select */ ! 34: char *Prog_name; /* program name for abnormal errors */ ! 35: extern int errno; /* error number */ ! 36: ! 37: /* ! 38: ** main ! 39: ** initilize the socket to the socket server, and then sit and on ! 40: ** a select waiting for input. ! 41: */ ! 42: main(ac,av) ! 43: int ac; ! 44: char **av; ! 45: { ! 46: long read_fd, /* bit mask of useable descriptors*/ ! 47: num_des; /* number of readable descriptors */ ! 48: int abnormal(); /* error function */ ! 49: register int i; /* index */ ! 50: ! 51: ! 52: /* ! 53: ** close all the files descriptors, so we can have more INGRES ! 54: ** processes. We are lmited by file descriptors. ! 55: */ ! 56: # ifdef DEBUG ! 57: setbuf(stdout,NULL); ! 58: printf("DRIVER: starting up\n"); ! 59: close(0); /* guarantee that 0 is what is attached to the socket server */ ! 60: for ( i = 3 ; i < NOFILE ; i++ ) ! 61: # else ! 62: for ( i = 0 ; i < NOFILE ; i++ ) ! 63: # endif DEBUG ! 64: close(i); ! 65: ! 66: /* ! 67: ** set up all the signals. Catching any signal ! 68: ** is an error. We do a "warm start" in this condition ! 69: */ ! 70: for ( i = 0 ; i < NSIG ; i++ ) ! 71: signal(i,abnormal); ! 72: signal(SIGPIPE,SIG_IGN); /* ignore this one, in case a process simply dies in mid stride */ ! 73: Prog_name = *av; ! 74: /* ! 75: ** if ac == 2, then we are restarted from the the lock driver ! 76: ** itself, and we don't have to reattach ourselves to the magic ! 77: ** ingres socket. ! 78: */ ! 79: if ( ac == 2 ) ! 80: From_server = 0; ! 81: else ! 82: From_server = init_socket(); ! 83: Read_fmt = (1<<From_server); ! 84: ! 85: /* ! 86: ** infinite loop waiting for something to happen ! 87: */ ! 88: for ( ;; ) ! 89: { ! 90: read_fd = Read_fmt; ! 91: ! 92: /* ! 93: ** wake up whenever something happens ! 94: */ ! 95: while ( (num_des = select(NOFILE,&read_fd,0,0,0)) == 0 ) ! 96: { ! 97: # ifdef DEBUG ! 98: printf("select returns 0 (%o)\n",read_fd); ! 99: # endif DEBUG ! 100: read_fd = Read_fmt; ! 101: } ! 102: # ifdef DEBUG ! 103: printf("select returns %d (%o)\n",num_des,read_fd); ! 104: # endif DEBUG ! 105: if ( num_des == -1 ) ! 106: { ! 107: # ifdef DEBUG ! 108: perror("DRIVER:num_des = -1"); ! 109: # endif DEBUG ! 110: /* ! 111: ** a bit of defensive programming. ! 112: ** If there is an EBADF (bad file descriptor) error ! 113: ** then we assume that a file descriptor has shut down, ! 114: ** with out tellng us. We go to a function to figure ! 115: ** out what has died. ! 116: */ ! 117: if ( errno == EBADF ) ! 118: close_up(Read_fmt); ! 119: sleep(1); ! 120: continue; ! 121: } ! 122: if ( (read_fd & (1<<From_server)) ) ! 123: { ! 124: num_des--; ! 125: new_proc(); ! 126: read_fd &= ~(1<<From_server); ! 127: } ! 128: if ( num_des > 0 ) ! 129: { ! 130: for ( i = 0 ; i < NOFILE ; i++ ) ! 131: if ( (read_fd & (1<<i)) ) ! 132: ilwrite(i); ! 133: } ! 134: } ! 135: }/* main */ ! 136: ! 137: /* ! 138: ** new_proc ! 139: ** start up a new connection to an Ingres process ! 140: */ ! 141: new_proc() ! 142: { ! 143: register int fd; ! 144: auto int to_ioctl = 1; ! 145: struct sockaddr_in addr; ! 146: auto int len; ! 147: ! 148: len = sizeof (addr); ! 149: if ( (fd = accept(From_server,&addr,&len)) != -1 ) ! 150: { ! 151: Read_fmt |= (1<<fd); ! 152: ioctl(fd,FIONBIO,&to_ioctl); ! 153: } ! 154: # ifdef DEBUG ! 155: else ! 156: { ! 157: perror("accept"); ! 158: sleep(1); ! 159: } ! 160: printf("DRIVER: new file %d (%o)\n",fd,(1<<fd)); ! 161: # endif DEBUG ! 162: }/* new_proc */ ! 163: ! 164: ! 165: ! 166: ilwrite(read_desc) ! 167: register int read_desc; ! 168: { ! 169: struct Lockreq lockbuf; ! 170: register int i; ! 171: register int blockflag; ! 172: extern int errno; ! 173: ! 174: errno = 0; ! 175: # ifdef DEBUG ! 176: printf("DRIVER: entering ilwrite, read_desc = %d\n",read_desc); ! 177: # endif DEBUG ! 178: if ( read(read_desc,&lockbuf, sizeof ( lockbuf)) != sizeof ( lockbuf ) ) ! 179: { ! 180: # ifdef DEBUG ! 181: printf("Read error, errno = %d\n",errno); ! 182: # endif DEBUG ! 183: if ( errno == EWOULDBLOCK ) ! 184: return; ! 185: if ( errno == ECONNRESET ) ! 186: { ! 187: ilrma(read_desc,TRUE); ! 188: close(read_desc); ! 189: Read_fmt &= ~(1<<read_desc); ! 190: return; ! 191: } ! 192: send_info(read_desc,-5); ! 193: return; ! 194: } ! 195: ! 196: # ifdef DEBUG ! 197: if (ildebug) ! 198: printf("ildr: act %d, type %d, mode %d, read_desc %d\n", ! 199: lockbuf.lr_act, lockbuf.lr_type, lockbuf.lr_mod, read_desc); ! 200: # endif DEBUG ! 201: if (( lockbuf.lr_act < A_RLS1) ! 202: && ((lockbuf.lr_type < T_CS) || (lockbuf.lr_type > T_DB ) ! 203: || (lockbuf.lr_mod < M_EXCL) || (lockbuf.lr_mod > M_SHARE ))) ! 204: { ! 205: # ifdef DEBUG ! 206: printf("Illegal request\n"); ! 207: # endif DEBUG ! 208: send_info(read_desc,-5); ! 209: return; ! 210: } ! 211: /* ! 212: * follow action from lock request ! 213: */ ! 214: switch(lockbuf.lr_act) ! 215: { ! 216: case A_RTN: ! 217: # ifdef DEBUG ! 218: if ( ildebug ) ! 219: printf("Driver: A_RTN\n"); ! 220: # endif DEBUG ! 221: ! 222: /* ! 223: ** attempt to set lock. ! 224: ** error return if failure. ! 225: */ ! 226: for ( i = 0; i <= lockbuf.lr_type; i++) ! 227: { ! 228: if (Lockset[i] == 0) ! 229: { ! 230: # ifdef DEBUG ! 231: if (ildebug) ! 232: printf("ildr: lock %d not available\n", i); ! 233: # endif DEBUG ! 234: send_info(read_desc,-1); ! 235: return; ! 236: } ! 237: } ! 238: if (ilunique(&lockbuf) >= 0) ! 239: { ! 240: send_info(read_desc,-1); ! 241: return; ! 242: } ! 243: # ifdef DEBUG ! 244: if ( ildebug ) ! 245: printf("Driver: lock assigned\n"); ! 246: # endif DEBUG ! 247: ilenter(&lockbuf,read_desc); ! 248: break; ! 249: ! 250: case A_SLP: ! 251: # ifdef DEBUG ! 252: if ( ildebug ) ! 253: printf("Driver: A_SLP\n"); ! 254: # endif DEBUG ! 255: if ( set_lock(read_desc,lockbuf) == -1 ) ! 256: return; ! 257: # ifdef DEBUG ! 258: if ( ildebug ) ! 259: printf("Driver: got lock\n"); ! 260: # endif DEBUG ! 261: break; ! 262: case A_RLS1: ! 263: /* remove 1 lock */ ! 264: # ifdef DEBUG ! 265: if ( ildebug ) ! 266: printf("Driver: A_RLS1\n"); ! 267: # endif DEBUG ! 268: if ((i = ilfind(&lockbuf,read_desc)) >= 0) ! 269: { ! 270: ilrm(i,read_desc); ! 271: } ! 272: else ! 273: { ! 274: send_info(read_desc,-2); ! 275: return; ! 276: } ! 277: # ifdef DEBUG ! 278: if ( ildebug ) ! 279: printf("Driver: released\n"); ! 280: # endif DEBUG ! 281: break; ! 282: ! 283: case A_RLSA: ! 284: /* remove all locks for this process id*/ ! 285: # ifdef DEBUG ! 286: if ( ildebug ) ! 287: printf("Driver: A_RLSA\n"); ! 288: # endif DEBUG ! 289: ilrma(read_desc,FALSE); ! 290: break; ! 291: ! 292: case A_ABT: /* remove all locks */ ! 293: # ifdef DEBUG ! 294: if ( ildebug ) ! 295: printf("Driver: A_ABT\n"); ! 296: # endif DEBUG ! 297: ilclose(); ! 298: break; ! 299: ! 300: default : ! 301: # ifdef DEBUG ! 302: if ( ildebug ) ! 303: printf("DRIVER: garbage\n"); ! 304: # endif DEBUG ! 305: send_info(read_desc,-3); ! 306: } ! 307: send_info(read_desc,0); ! 308: } ! 309: /* ! 310: * ilunique- check for match on key ! 311: * ! 312: * return index of Locktab if match found ! 313: * else return -1 ! 314: */ ! 315: static ! 316: ilunique(ll) ! 317: register struct Lockreq *ll; ! 318: { ! 319: register int k; ! 320: register struct Lockform *p; ! 321: register struct Lockreq *q; ! 322: ! 323: for (k = 0; k < NLOCKS; k++) ! 324: { ! 325: p = &Locktab[k]; ! 326: if ((p->l_mod != M_EMTY) ! 327: && (ilcomp(p->l_key,ll->lr_key) == 0) ! 328: && (p->l_type == ll->lr_type) ! 329: && ( (p->l_mod == M_EXCL) || (ll->lr_mod == M_EXCL)) ) { ! 330: # ifdef DEBUG ! 331: if (ildebug) { ! 332: register int i; ! 333: ! 334: printf("ildr: lock "); ! 335: for (i = 0; i < KEYSIZE; i++) ! 336: printf("%c", ll->lr_key[i]); ! 337: printf(" busy\n"); ! 338: } ! 339: # endif DEBUG ! 340: return(k); ! 341: } ! 342: } ! 343: return(-1); ! 344: } ! 345: ! 346: static ! 347: ilfind(ll,key) ! 348: register struct Lockreq *ll; ! 349: int key; ! 350: { ! 351: register int k; ! 352: register struct Lockform *p; ! 353: register struct Lockreq *q; ! 354: ! 355: for (k = 0; k < NLOCKS; k++) ! 356: { ! 357: p = &Locktab[k]; ! 358: if ((p->l_mod != M_EMTY) ! 359: && (ilcomp(p->l_key,ll->lr_key) == 0) ! 360: && (p->l_type == ll->lr_type) ! 361: && (p->l_pid == key)) ! 362: return(k); ! 363: } ! 364: return(-1); ! 365: }/* ilfind */ ! 366: ! 367: /* ! 368: * remove the lth Lock ! 369: * if the correct user is requesting the move. ! 370: */ ! 371: static ! 372: ilrm(l,key,remove_all) ! 373: int l; ! 374: int key; ! 375: int remove_all; ! 376: { ! 377: register struct Lockform *a; ! 378: register k; ! 379: ! 380: ! 381: a = &Locktab[l]; ! 382: if (a->l_pid == key && a->l_mod != M_EMTY) ! 383: { ! 384: if ( !remove_all && a->l_type == T_DB ) ! 385: return; ! 386: a->l_mod = M_EMTY; ! 387: a->l_pid = 0; ! 388: if (a->l_wflag == W_ON) ! 389: { ! 390: a->l_wflag = W_OFF; ! 391: wakeup(&Locktab[l]); ! 392: } ! 393: for (k = 0; k <= a->l_type; k++) ! 394: { ! 395: Lockset[k]++; ! 396: if (Lockset[k] == 1) ! 397: wakeup(&Lockset[k]); ! 398: } ! 399: } ! 400: }/* ilrm */ ! 401: ! 402: /* ! 403: * ilrma releases all locks for a given process id(pd) ! 404: * -- called from sys1.c$exit() code. ! 405: */ ! 406: ilrma(key,remove_all) ! 407: int key; ! 408: int remove_all; ! 409: { ! 410: register int i; ! 411: ! 412: # ifdef DEBUG ! 413: printf("DRVIER: Removing all, key = %d\n",key); ! 414: # endif DEBUG ! 415: for ( i = 0; i < NLOCKS; i++ ) ! 416: ilrm(i,key,remove_all); ! 417: } ! 418: ! 419: /* ! 420: * enter Lockbuf in locktable ! 421: * return position in Locktable ! 422: * error return of -1 ! 423: */ ! 424: static ! 425: ilenter(ll,key) ! 426: register struct Lockreq *ll; ! 427: int key; ! 428: { ! 429: int k,l; ! 430: register char *f,*t; ! 431: register struct Lockform *p; ! 432: ! 433: for (k = 0; k < NLOCKS; k++) ! 434: { ! 435: p = &Locktab[k]; ! 436: if (p->l_mod == M_EMTY) ! 437: { ! 438: p->l_pid = key; ! 439: p->l_type = ll->lr_type; ! 440: Locktab[k].l_mod = p->l_mod = ll->lr_mod; ! 441: f = ll->lr_key; ! 442: t = p->l_key; ! 443: for (l = 0; l < KEYSIZE; l++) ! 444: *t++ = *f++; ! 445: for (l = 0; l <= ll->lr_type; l++) ! 446: Lockset[l]--; ! 447: # ifdef DEBUG ! 448: if ( ildebug ) ! 449: printf("DRIVER: ilenter %d, mod %d, omod = %d\n",k,p->l_mod,Locktab[k].l_mod); ! 450: # endif DEBUG ! 451: return(k); ! 452: } ! 453: } ! 454: # ifdef DEBUG ! 455: if ( ildebug ) ! 456: printf("DRIVER: ilenter -1\n"); ! 457: # endif DEBUG ! 458: return (-1); ! 459: } ! 460: ! 461: /* ! 462: * ilcomp- string compare ! 463: * returns 0 if strings match ! 464: * returns -1 otherwise ! 465: */ ! 466: static ! 467: ilcomp(s1,s2) ! 468: register char *s1,*s2; ! 469: { ! 470: register int k; ! 471: ! 472: for (k = 0; k < KEYSIZE; k++) ! 473: if ( *s1++ != *s2++) ! 474: # ifdef DEBUG ! 475: { ! 476: if ( ildebug ) ! 477: printf("DRIVER: ilcomp returning -1\n"); ! 478: return ( -1 ); ! 479: } ! 480: # else DEBUG ! 481: return (-1); ! 482: # endif DEBUG ! 483: return (0); ! 484: } ! 485: ! 486: /* ! 487: * ilclose- releases all locks ! 488: */ ! 489: static ! 490: ilclose() ! 491: { ! 492: register int k; ! 493: register caddr_t c; ! 494: # ifdef DEBUG ! 495: printf("DRIVER: entered close\n"); ! 496: # endif DEBUG ! 497: ! 498: for (k = 0; k < NLOCKS; k++) ! 499: wakeup( &Locktab[k] ); ! 500: for (k = 0; k < 4; k++) ! 501: wakeup( &Lockset[k]); ! 502: for (c = (caddr_t)&Locktab[0].l_pid; c < (caddr_t)&Locktab[NLOCKS];) ! 503: *c++ = 0; ! 504: Lockset[0] = NLOCKS; ! 505: Lockset[1] = PLOCKS; ! 506: Lockset[2] = RLOCKS; ! 507: Lockset[3] = DLOCKS; ! 508: }/* ilclose */ ! 509: ! 510: /* ! 511: ** set_lock ! 512: ** attempt to set a lock. If we can't, block the process and ! 513: ** return -1, if we can than set the lock and return 0. ! 514: */ ! 515: set_lock(read_desc,lockbuf) ! 516: register int read_desc; ! 517: struct Lockreq lockbuf; ! 518: { ! 519: register int blockflag; ! 520: register int i; ! 521: ! 522: /* ! 523: ** attempt to set lock. ! 524: ** sleep on blocking address if failure. ! 525: */ ! 526: ! 527: do ! 528: { ! 529: do ! 530: { ! 531: blockflag = TRUE; ! 532: for ( i = 0; i <= lockbuf.lr_type; i++) ! 533: if (Lockset[i] == 0) ! 534: { ! 535: # ifdef DEBUG ! 536: if (ildebug) ! 537: printf("ildr: lock %d not available\n", i); ! 538: # endif DEBUG ! 539: wait_on(read_desc,&Lockset[i],lockbuf); ! 540: return(-1); ! 541: } ! 542: } while (!blockflag); ! 543: ! 544: if (( i = ilunique(&lockbuf)) >= 0 ) ! 545: { ! 546: blockflag = FALSE; ! 547: Locktab[i].l_wflag = W_ON; ! 548: wait_on(read_desc,&Locktab[i],lockbuf); ! 549: return(-1); ! 550: } ! 551: } while (!blockflag); ! 552: ilenter(&lockbuf,read_desc); ! 553: return ( 0 ); ! 554: }/* set_lock */ ! 555: ! 556: /* ! 557: ** send_info ! 558: ** Send the data down the socket. Don't do it if it would cause the driver ! 559: ** to block. ! 560: */ ! 561: send_info(fd,data) ! 562: register int fd; ! 563: int data; ! 564: { ! 565: auto int wdes = ( 1<<fd ); ! 566: struct timeval time; ! 567: ! 568: errno = 0; ! 569: time.tv_sec = 10; ! 570: time.tv_usec = 0; ! 571: ! 572: if ( select(NOFILE,0,&wdes,0,&time) != 1 ) ! 573: { ! 574: Read_fmt &= ~(1<<fd); ! 575: ilrma(fd,TRUE); ! 576: close(fd); ! 577: } ! 578: else ! 579: if ( write(fd,&data,sizeof (int)) != sizeof (int) ) ! 580: { ! 581: if ( errno == 0 ) ! 582: return; ! 583: Read_fmt &= ~(1<<fd); ! 584: ilrma(fd,TRUE); ! 585: close(fd); ! 586: } ! 587: }/* send_info */ ! 588: ! 589: struct Wait { ! 590: int wait_fd; /* file descriptor to send lock info to off of */ ! 591: int wait_lock; /* what lock we are waiting for */ ! 592: struct Lockreq wait_req; /* the lock request */ ! 593: struct Wait *next; ! 594: }; ! 595: struct Wait *Wait_queue = NULL; ! 596: ! 597: /* ! 598: ** wait_on ! 599: ** Set up to wait for a free lock. ! 600: */ ! 601: wait_on(fd,lock,req) ! 602: register int fd, lock; ! 603: struct Lockreq req; ! 604: { ! 605: register struct Wait *ptr; ! 606: char *calloc(); ! 607: ! 608: ptr = (struct Wait *)calloc(1,sizeof (struct Wait)); ! 609: ptr->wait_fd = fd; ! 610: ptr->wait_lock = lock; ! 611: ptr->wait_req = req; ! 612: ptr->next = Wait_queue; ! 613: Wait_queue = ptr; ! 614: }/* wait_on */ ! 615: ! 616: /* ! 617: ** wakeup ! 618: ** See if there is anythng waiting on the newly freed lock. If there is, ! 619: ** tell it it can have the lock now. ! 620: */ ! 621: wakeup(lock) ! 622: register int lock; ! 623: { ! 624: register struct Wait *ptr,*back; ! 625: ! 626: for ( back = NULL, ptr = Wait_queue ; ptr != NULL ; back = ptr, ptr = ptr->next ) ! 627: { ! 628: if ( ptr->wait_lock == lock ) ! 629: { ! 630: if ( set_lock(ptr->wait_fd,ptr->wait_req) == 0 ) ! 631: { ! 632: send_info(ptr->wait_fd,0); ! 633: if ( back != NULL ) ! 634: back->next = ptr->next; ! 635: else ! 636: Wait_queue = Wait_queue->next; ! 637: cfree(ptr); ! 638: return; ! 639: } ! 640: } ! 641: } ! 642: }/* wakeup */ ! 643: ! 644: /* ! 645: ** abnormal ! 646: ** a signal has come down and hit us. We restart the entire ! 647: ** program, and hope it goes away ! 648: */ ! 649: abnormal(sig) ! 650: int sig; ! 651: { ! 652: extern int errno; ! 653: ! 654: # ifdef DEBUG ! 655: printf("DRIVER: error %d, restarting\n",sig); ! 656: # endif ! 657: ! 658: execl("/etc/lock_driver","lock_driver","restart",0); ! 659: execl(Prog_name,Prog_name,"restart",0); ! 660: execlp("lock_driver","lock_driver","restart",0); ! 661: exit(4); ! 662: }/* abnormal */ ! 663: ! 664: /* ! 665: ** close_up ! 666: ** try and find a closed up file descriptor. ! 667: */ ! 668: close_up(fmt) ! 669: long fmt; ! 670: { ! 671: long rdesc; ! 672: register int i; ! 673: struct timeval time; ! 674: ! 675: errno = 0; ! 676: time.tv_sec = 0; ! 677: time.tv_usec = 0; ! 678: ! 679: for ( i = 0 ; i < NOFILE ; i++ ) ! 680: { ! 681: if ( (1<<i) & fmt ) ! 682: { ! 683: rdesc = (1<<i); ! 684: if ( select(NOFILE,&rdesc,0,0,&time) == -1 ) ! 685: { ! 686: /* ! 687: ** the server socket has closed down. ! 688: ** BOY ARE WE IN TROUBLE ! 689: */ ! 690: if ( i == From_server ) ! 691: { ! 692: sleep(1); ! 693: # ifdef DEBUG ! 694: printf("Restarting socket\n"); ! 695: # endif DEBUG ! 696: init_socket(); ! 697: } ! 698: if ( errno == EBADF ) ! 699: { ! 700: shutdown(i,2); ! 701: close(i); ! 702: Read_fmt &= ~(1<<i); ! 703: ilrma(i,TRUE); ! 704: } ! 705: } ! 706: } ! 707: } ! 708: }/* close_up */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.