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