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