📄 pnp.c
字号:
#ifdef OPENPROMS /* * Add up how much physical memory the prom has passed us. */ pa.memsize = 0; for (pmem = *romp->v_availmemory; pmem; pmem = pmem->next) pa.memsize += pmem->size;#else pa.memsize = *romp->v_memorysize;#endif pa.memsize /= 1024; pa.disksize = 0; pa.hostid = hostid; if (idprom (IDFORM_1, &id) == IDFORM_1) { lchex (hostid + 0, id.id_machine); lchex (hostid + 2, id.id_serial >> 16); lchex (hostid + 4, id.id_serial >> 8); lchex (hostid + 6, id.id_serial); } else hostid [0] = '\0'; didit++; } return &pa;} /* We must acquire a server willing to give us a configuration * in the cases of new configurations and reconfigurations. * This times out ... caller must retry. * TIME: 2 minutes. */static intpnp_acquire (ifp, svrp, errp) register struct ifnet *ifp; struct sockaddr_in *svrp; pnp_errcode *errp;{ enum clnt_stat stat; struct timeval tv; pnp_acquire_arg *pap = get_acquire_arg (); pnp_errcode err; int i; PMeter (CHKPT_ACQUIRE); tv.tv_sec = 20; tv.tv_usec = 0; /* this version of the protocol requires that NO responses * be generated for diskless ACQUIREs unless they're * successful. */ for (i = 0; i < 6; i++) { stat = pmap_rmtcall (&(ifp->if_broadaddr), (u_long)PNPD_PROG, (u_long)PNPD_VERS, PNP_ACQUIRE, xdr_pnp_acquire_arg, (char *) pap, xdr_pnp_errcode, (char *) errp, tv, svrp); if (!stat) { twiddler (1); return 0; } else twiddler (0); } *errp = pnp_failure; return -1;} /* Issue the setup request to this system. We've * already got the port number. * TIME: 2 minutes. */static pnp_errcodepnp_setup (clnt, errp) register CLIENT *clnt; pnp_errcode *errp;{ int i; enum clnt_stat stat; pnp_setup_arg ps; struct timeval tv; struct sockaddr_in sp; PMeter (CHKPT_SETUP); ps.pa = *get_acquire_arg (); ps.name = "*"; /* request name allocation */ ps.keydata = ""; /* pointless on diskless systems */ tv.tv_sec = 20; tv.tv_usec = 0; for (i = 0; i < 6; i++) { stat = clntkudp_callit_addr (clnt, PNP_SETUP, xdr_pnp_setup_arg, (char *) &ps, xdr_pnp_errcode, (char *) errp, tv, &sp); if (!stat) { twiddler (0); return 0; } else twiddler (1); } *errp = pnp_failure; return -1;} /* after a successful setup request, poll the server until * timeout, failure, or success. */static pnp_errcodepnp_poll (clnt, errp) register CLIENT *clnt; pnp_errcode *errp;{ int i; register enum clnt_stat stat; pnp_setup_arg ps; struct timeval tv; struct sockaddr_in sp; int missedpolls; PMeter (CHKPT_POLL); ps.pa = *get_acquire_arg (); ps.name = "*"; /* request name allocation */ ps.keydata = ""; /* pointless on diskless systems */ tv.tv_sec = PNP_POLLTIME; tv.tv_usec = 0; missedpolls = 0; *errp = pnp_success; do { /* XXX the timeout here isn't 20 seconds, it's * more like 1:25 !! */ stat = clntkudp_callit_addr (clnt, PNP_POLL, xdr_pnp_setup_arg, (char *) &ps, xdr_pnp_errcode, (char *) errp, tv, &sp);#ifdef sun386 if (stat || *errp != pnp_in_progress) { if (chkpt_now < CHKPT_PNPDONE - CHKPT_POLL_INCR) PMeter (chkpt_now += CHKPT_POLL_INCR); else printf("Installation is taking more time than expected ...\n"); }#else if (stat || *errp != pnp_in_progress) (void) putchar ('.');#endif sun386 if (stat) { missedpolls++; *errp = pnp_in_progress; } else { missedpolls = 0; if (*errp == pnp_in_progress) xsleep (PNP_POLLTIME); } } while (missedpolls < PNP_MISSEDPOLLS && *errp == pnp_in_progress); if (missedpolls < PNP_MISSEDPOLLS) return 0; *errp = pnp_failure; return -1;} /* perform all the pnp setup procedures; the caller should * reboot if this returns zero, else exit to monitor or halt. */static intdo_pnp (){ pnp_errcode sts; how_to_boot how; struct sockaddr_in server; char *msg; struct ifnet *ifp; register CLIENT *clnt = (CLIENT *) 0;#ifdef sun386#ifndef REDRAW#define REDRAW 0 /* not 54 */#define DOIT 54#endif REDRAW (*romp->v_init_pmeter)("Install", DOIT); /**/ printf ("\033[H\033[J");#else (void) putchar ('\n'); (void) printf ("Trying to start Automatic System Installation. . .\n"); (void) putchar ('\n');#endif PMeter (CHKPT_START); if (init_inet (&ifp) < 0) return -1; PMeter (CHKPT_VERIFY); if (!is_pnp_net (ifp)) { printf ("%s\n\n%s\n\n", MSG_NONPNPNET, MSG_SEEADMIN); return -1; } goto acquire_server;restart_pnp: if (clnt) { CLNT_DESTROY (clnt); clnt = (CLIENT *)0; } /* In the case of some packet-lost errors, it's * possible to be set up, but not know it. * See if that happened. */ if ((sts = pnp_whoami (ifp)) == pnp_success) return 0; /* the top: start the pnp sequence by finding a * willing server, then requesting it set this system * up, and polling until it's done. timeouts and * some errors will cause a restart of the whole * sequence. */acquire_server: if (pnp_acquire (ifp, &server, &sts) < 0) {startup_timeout: printf ("%s\n", MSG_ACQUIRETIMEOUT); goto restart_pnp; } /* XXX this is a protocol error for diskless systems. */ if (sts != pnp_success) { printf ("%s\n%s\n\n%s\n\n", MSG_PROTOERR, MSG_RETRY, MSG_SEEADMIN); xsleep (10); goto restart_pnp; }got_server: printf ("Using installation server at "); { char *p = (char *)&(server.sin_addr);#define UC(b) (((int)b)&0xff) printf("%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); } clnt = clntkudp_create (&server, PNPD_PROG, PNPD_VERS, 10, u.u_cred); if (!clnt) {printf ("** CLNTKUDP_CREATE ERROR\n"); goto acquire_server; } if (pnp_setup (clnt, &sts) < 0) goto startup_timeout; switch (sts) { case pnp_success: /* rare at best */ goto pnpdone; case pnp_in_progress: break; case pnp_busy_retry: printf ("%s\n", MSG_BUSYRETRY); xsleep (PNP_POLLTIME); goto restart_pnp; case pnp_wait: printf ("%s\n\n", MSG_WAIT); for (;;) continue; /* NOTREACHED */ case pnp_no_software: msg = MSG_NOSOFTWARE; goto explain; case pnp_no_diskspace: msg = MSG_NOSPACE; goto explain; case pnp_nomore_clients: msg = MSG_NOCLIENTS; goto explain; case pnp_failure: default: msg = MSG_SETUPFAIL; explain: printf ("%s\n", msg); CLNT_DESTROY (clnt); clnt = (CLIENT *)0; goto acquire_server; } printf ("Waiting for Installation to complete.\n"); /* if poll times out, there's the possibility that the * server crashed after complete setup but before * sending out completion status */ if (pnp_poll (clnt, &sts) < 0) { printf ("%s\n", MSG_POLLTIMEOUT); goto restart_pnp; } switch (sts) { case pnp_success:pnpdone: printf ("Installation is complete. Rebooting SunOS.\n"); CLNT_DESTROY (clnt); xsleep (5); return 0; case pnp_unknown_client: msg = MSG_WHOAREYOU; break; case pnp_no_software: msg = MSG_NOSOFTWARE; break; case pnp_no_diskspace: msg = MSG_NOSPACE; break; case pnp_nomore_clients: msg = MSG_NOCLIENTS; break; case pnp_failure: default: printf ("%d\n", sts); msg = MSG_POLLERR; break; } printf ("%s\n%s\n\n%s\n\n", MSG_SETUPERR, msg, MSG_RETRY); goto restart_pnp;}main(){ register struct bootparam *bp; int sts;#ifdef sun2 int *mem_p;#endif sun2 if (romp->v_bootparam == 0) bp = (struct bootparam *)0x2000; /* Old Sun-1 address */ else bp = *(romp->v_bootparam); /* S-2: via romvec */ boot_bp = bp;#ifdef sun2 mem_p = (int *)&(bp->bp_strings[96]); *mem_p = 0x220000; bp->bp_strings[95] = '\0'; memory_avail = 0x220000;#endif sun2#if defined(sun3) || defined(sun3x) /* * Allocate memory starting below the top of physical * memory, to avoid tromping on kadb. */ memory_avail = *romp->v_memoryavail - 0x100000;#endif sun3 || sun3x#ifdef sun4 memory_avail = *romp->v_memoryavail - 0x200000;#endif sun4#ifdef OPENPROMS /* * We'll avoid dealing with holes in the physical memory by * only using the first chunk (which is guaranteed to be mapped * by the monitor). This should be enough. */ memory_avail = (*(romp->v_availmemory))->address + (*(romp->v_availmemory))->size - 0x100000;#endif OPENPROMS#ifdef DRARP_REQUEST use_drarp = 1;#endif DRARP_REQUEST kmem_init(); bhinit(); binit(); init_syscalls();#ifdef RPCDEBUG rpcdebug = 4;#endif sts = do_pnp (); (void) putchar ('\n'); if (sts) (*romp->v_exit_to_mon)(); /* or halt */ else (*romp->v_boot_me)("");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -