Annotation of researchv8dc/netfs/setup.c, revision 1.1.1.1

1.1       root        1: #include "stdio.h"
                      2: #include "sys/param.h"
                      3: #include "sys/stat.h"
                      4: #include "sys/neta.h"
                      5: #include "errno.h"
                      6: #include "sys/ioctl.h"
                      7: #include "signal.h"
                      8: #include "setjmp.h"
                      9: 
                     10: #define RMFSTYP 1      /* file system type for remote file system */
                     11: 
                     12: struct friend {
                     13:        char *who;
                     14:        char *mount;
                     15:        int dev;
                     16:        int silent;
                     17:        int status;
                     18:        int chan;
                     19: } friends[NOFILE];
                     20: int nfriends;
                     21: #define DEAD   0
                     22: #define OK     1
                     23: #define PROBE  2
                     24: #define KILL   3
                     25: 
                     26: char *states[] = { "dead", "ok", "probe", "kill", "?"};
                     27: 
                     28: struct senda x;
                     29: struct rcva y;
                     30: extern int errno;
                     31: extern char *ctime();
                     32: extern char *malloc();
                     33: struct stat stb;
                     34: long looked;
                     35: jmp_buf jmpbuf;
                     36: 
                     37: main()
                     38: {      int i;
                     39: /* any signal but SIGALRM (14) will start it over.  SIGALRM is used to
                     40:  * interrupt hung reads.  SIGCHLD is ignored too */
                     41:        sigalrm(0);
                     42:        if(setjmp(jmpbuf) == 1)
                     43:                rdfile();
                     44:        else
                     45:                sigcatch();
                     46:        probe();
                     47: }
                     48: sigalrm(n)
                     49: {
                     50:        fprintf(stderr, "sigalrm %d\n", n);
                     51:        fflush(stderr);
                     52:        if(n == SIGALRM || n == 0)      /* otherwise might get SIGCHLD in sleep */
                     53:                signal(SIGALRM, sigalrm);
                     54:        signal(SIGCHLD, sigalrm);
                     55: }
                     56: sigcatch(n)
                     57: {      int i;
                     58:        for(i = 1; i < NSIG; i++)
                     59:                if(i != SIGALRM && i != SIGCHLD)        /* alarm and tdkdial */
                     60:                        (void) signal(i, sigcatch);
                     61:        fprintf(stderr, "sigcatch %d\n", n);
                     62:        fflush(stderr);
                     63:        switch(i) {
                     64:        case SIGILL: case SIGBUS: case SIGSEGV:
                     65:                restart();
                     66:        }
                     67:        longjmp(jmpbuf, 1);
                     68: }
                     69: restart()
                     70: {
                     71:        fprintf(stderr, "execing\n");
                     72:        fflush(stderr);
                     73:        execl("/etc/net/setup", "setup", 0);
                     74:        execl("/usr/net/setup", "setup", 0);
                     75:        /* if that doesn't work */
                     76:        fprintf(stderr, "oops, calling main\n");
                     77:        fflush(stderr);
                     78:        main();         /* ho ho */
                     79: }
                     80: probe()
                     81: {      int i;
                     82:        static int lastdone;
                     83:        long now;
                     84: loop:
                     85:        if(lastdone >= nfriends) {
                     86:                lastdone = 0;
                     87:                sleep(30);
                     88:                if(stat("/etc/net/friends", &stb) == 0 && stb.st_mtime > looked)
                     89:                        rdfile();
                     90:                if(stat("/usr/net/friends", &stb) == 0 && stb.st_mtime > looked)
                     91:                        rdfile();
                     92:                if(time((long *)0) > looked + 1200)
                     93:                        rdfile();
                     94:        }
                     95:        i = lastdone++;
                     96:        switch(friends[i].status) {
                     97:        default:
                     98:                break;
                     99:        case PROBE:
                    100:        case OK:
                    101:                friends[i].status++;
                    102:                doprobe(friends + i);
                    103:                if(friends[i].status != OK) {
                    104:                        now = time(0);
                    105:                        fprintf(stderr, "hmm %s %s %s\n", friends[i].who,
                    106:                                states[friends[i].status], ctime(&now));
                    107:                }
                    108:                break;
                    109:        case KILL:      /* over the limit */
                    110:                now = time(0);
                    111:                fprintf(stderr, "%s timed out %s 0x%x %s", friends[i].who,
                    112:                        states[friends[i].status], friends[i].chan, ctime(&now));
                    113:                errno = 0;
                    114:                gmount(RMFSTYP, friends[i].dev, 1, 0, 0);
                    115:                if(errno == 0 || errno == EINVAL) {
                    116:                        friends[i].status = DEAD;
                    117:                        fprintf(stderr, "dead now\n");
                    118:                }
                    119:                else
                    120:                        perror("xmount");
                    121:                break;
                    122:        }
                    123:        goto loop;
                    124: }      
                    125: doprobe(x)
                    126: struct friend *x;
                    127: {      struct stat stb;
                    128:        if(stat(x->mount, &stb) == 0 && stb.st_dev == x->dev)
                    129:                x->status = OK;
                    130: }
                    131: startup(p)
                    132: struct friend *p;
                    133: {      int fd, i;
                    134:        char version;
                    135:        fd = callfs(p->who);
                    136:        if(fd < 0) {
                    137:                fprintf(stderr, "callfs %s failed\n", p->who);
                    138:                return;
                    139:        }
                    140:        (void) fstat(fd, &stb);
                    141:        fprintf(stderr, "starting %s (0x%x)", p->who, stb.st_rdev);
                    142:        gmount(RMFSTYP, p->dev, 1, 0, 0);       /* just in case */
                    143:        perror("xunmount");
                    144:        x.trannum = 0;
                    145:        version = x.version = NETVERSION;
                    146:        x.cmd = NSTART;
                    147:        x.uid = p->silent;
                    148:        x.dev = p->dev;
                    149:        alarm(30);
                    150:        x.ta = time(0);
                    151:        if((write(fd, &version, 1) != 1) || write(fd, (char *)&x, sizeof(x))
                    152:                != sizeof(x)) {
                    153:                        perror("write in setup");
                    154:                        fprintf(stderr, "%s\n", p->who);
                    155:                        close(fd);
                    156:                        alarm(0);
                    157:                        return;
                    158:        }
                    159:        if((i = read(fd, (char *)&y, sizeof(y))) != sizeof(y)) {
                    160:                if(y.trannum == -1)
                    161:                        fprintf(stderr, "version mismatch %s\n", p->who);
                    162:                else {
                    163:                        fprintf(stderr, "read %d chars for %s\n", i, p->who);
                    164:                        perror((char *)&y);
                    165:                }
                    166:                close(fd);
                    167:                return;
                    168:        }
                    169:        alarm(0);
                    170:        if(y.errno != 0) {
                    171:                errno = y.errno;
                    172:                perror("nak in setup");
                    173:                close(fd);
                    174:                return;
                    175:        }
                    176:        if(gmount(RMFSTYP, p->dev, 0, fd, p->mount) != 0) {
                    177:                perror("xmount");
                    178:                fprintf(stderr, "unmounting it\n");     /* garbage collection*/
                    179:                gmount(RMFSTYP, p->dev, 1, 0, 0);
                    180:                perror("xunmount");
                    181:                close(fd);
                    182:                /* and try again later */
                    183:                return;
                    184:        }
                    185:        p->status = OK;
                    186:        fprintf(stderr, "started %s on %s dev %d silent %d chan 0x%x\n", p->who,
                    187:                p->mount, p->dev/256, p->silent, p->chan = stb.st_rdev);
                    188:        close(fd);
                    189: }
                    190: 
                    191: #define skip for(; *p == ' ' || *p == '\t'; p++)
                    192: #define note for(s = p; *p != ' ' && *p != '\t' && *p != '\n'; p++)
                    193: struct friend *
                    194: cnvt(s)
                    195: char *s;
                    196: {      static struct friend x;
                    197:        char *p;
                    198:        s[strlen(s)] = '\n';
                    199:        p = s;
                    200:        skip;
                    201:        if(*p == '\n') {
                    202:                x.who = "#";
                    203:                return(&x);
                    204:        }
                    205:        note;
                    206:        if(*p == '\n')
                    207:                return(0);
                    208:        *p++ = 0;
                    209:        x.who = malloc(strlen(s) + 1);
                    210:        strcpy(x.who, s);
                    211:        s = p;
                    212:        skip;
                    213:        note;
                    214:        if(*p == '\n')
                    215:                return(0);
                    216:        *p++ = 0;
                    217:        x.mount = malloc(strlen(s) + 1);
                    218:        strcpy(x.mount, s);
                    219:        s = p;
                    220:        skip;
                    221:        note;
                    222:        if(*p == '\n')
                    223:                return(0);
                    224:        *p++ = 0;
                    225:        x.dev = 256 * atoi(s);
                    226:        s = p;
                    227:        skip;
                    228:        note;
                    229:        *p++ = 0;
                    230:        x.silent = atoi(s);
                    231:        x.status = DEAD;
                    232:        return(&x);
                    233: }
                    234: 
                    235: rdfile()
                    236: {      FILE *fd;
                    237:        int i;
                    238:        char line[128];
                    239:        struct friend *p;
                    240:        alarm(0);               /* disable the sleep in probe */
                    241:        fd = fopen("/etc/net/friends", "r");
                    242:        if(fd == NULL) {
                    243:                fd = fopen("/usr/net/friends","r");
                    244:                if(fd == NULL) {
                    245:                        perror("friends");
                    246:                        exit(1);
                    247:                }
                    248:        }
                    249:        for(;;) {
                    250: onward:
                    251:                (void) fgets(line, sizeof(line), fd);
                    252:                if(feof(fd))
                    253:                        break;
                    254:                p = cnvt(line);
                    255:                if(p == 0) {
                    256:                        fprintf(stderr, "weird friends line %s\n", line);
                    257:                        continue;
                    258:                }
                    259:                if(p->who[0] == '#')
                    260:                        continue;
                    261:                for(i = 0; i < nfriends; i++) {
                    262:                        if(strcmp(p->who, friends[i].who))
                    263:                                continue;
                    264:                        if(friends[i].status != OK) {
                    265:                                looked = time(0);
                    266:                                fprintf(stderr, "\nrdfile %s (%s) %s",
                    267:                                        states[friends[i].status],
                    268:                                        friends[i].who, ctime(&looked));
                    269:                                /* off the mother */
                    270:                                if(friends[i].status != DEAD) {
                    271:                                        friends[i].status = KILL;
                    272:                                        fprintf(stderr, "bye %s\n", friends[i].who);
                    273:                                }
                    274:                        }
                    275:                        if(friends[i].status != DEAD)
                    276:                                goto onward;
                    277:                        /* one could free the space */
                    278:                        fprintf(stderr, "new friend %s\n", p->who);
                    279:                        friends[i] = *p;
                    280:                        startup(friends + i);
                    281:                        goto onward;
                    282:                }
                    283:                for(i = 0; i < nfriends; i++)
                    284:                        if(friends[i].status == DEAD) {
                    285:                                friends[i] = *p;
                    286:                                fprintf(stderr, "new friend %s\n", p->who);
                    287:                                startup(friends + i);
                    288:                                goto onward;
                    289:                        }
                    290:                if(i < nfriends)
                    291:                        continue;
                    292:                if(nfriends >= NOFILE) {
                    293:                        fprintf(stderr, "friends overflow\n");
                    294:                        abort();
                    295:                }
                    296:                fprintf(stderr, "new friend %s\n", p->who);
                    297:                friends[nfriends++] = *p;
                    298:                startup(friends + nfriends - 1);
                    299:        }
                    300:        fclose(fd);
                    301:        looked = time(0);
                    302:        fprintf(stderr, "ok %s", ctime(&looked));
                    303: }
                    304: 
                    305: callfs(srvr)
                    306: char *srvr;
                    307: {
                    308:        int rem, v;
                    309:        extern int pk_ld, dkp_ld;
                    310:        long x;
                    311: 
                    312:        alarm(30);
                    313:        x = time(0);
                    314:        fprintf(stderr, "%d tdkdial %s %s", getpid(), srvr, ctime(&x));
                    315:        fflush(stderr);
                    316:        rem = _tdkdial(3, 2, srvr);
                    317:        x = time(0);
                    318:        alarm(0);
                    319:        if (rem < 0) {
                    320:                fprintf(stderr, " %d can't rexec err = %d\n", getpid(), errno);
                    321:                fflush(stderr);
                    322:                return(-1);
                    323:        }
                    324:        else
                    325:                fprintf(stderr, "tdkdial ok %s", ctime(&x));
                    326:        /* v = ioctl(rem, FIOPUSHLD, &dkp_ld);  /* should be dkproto */
                    327:        v = dkproto(rem, dkp_ld);
                    328:        x = time(0);
                    329:        if (v < 0) {
                    330:                perror("can't start protocol");
                    331:                fprintf(stderr, "\t%s", ctime(&x));
                    332:                close(rem);
                    333:                return(-1);
                    334:        }
                    335:        else
                    336:                fprintf(stderr, "protocol started\n");
                    337:        return(rem);
                    338: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.