|
|
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.