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 */

Defined functions

abnormal defined in line 649; used 2 times
close_up defined in line 668; used 1 times
ilclose defined in line 489; used 1 times
ilcomp defined in line 466; used 2 times
ilenter defined in line 424; used 2 times
ilfind defined in line 346; used 1 times
ilrm defined in line 371; used 2 times
ilrma defined in line 406; used 5 times
ilunique defined in line 315; used 2 times
ilwrite defined in line 166; used 1 times
main defined in line 42; never used
new_proc defined in line 141; used 1 times
send_info defined in line 561; used 8 times
set_lock defined in line 515; used 2 times
wait_on defined in line 601; used 2 times
wakeup defined in line 621; used 4 times

Defined variables

From_server defined in line 32; used 7 times
Prog_name defined in line 34; used 3 times
Read_fmt defined in line 33; used 9 times
Wait_queue defined in line 595; used 5 times
ildebug defined in line 27; used 16 times

Defined struct's

Wait defined in line 589; used 12 times

Defined macros

FALSE defined in line 24; used 2 times
TRUE defined in line 23; used 6 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2188
Valid CSS Valid XHTML 1.0 Strict