mirror of
https://github.com/urbit/shrub.git
synced 2025-01-02 09:32:29 +03:00
Merge pull request #1197 from urbit/ccr-fast-boot
cc-release: flexible boot sequence, fast-boot support
This commit is contained in:
commit
2f9d65ecd2
1
.travis/pin-arvo-commit.txt
Normal file
1
.travis/pin-arvo-commit.txt
Normal file
@ -0,0 +1 @@
|
||||
6d6ec85d6aa9200d366d0998326726ef1965d092
|
@ -2,6 +2,10 @@
|
||||
set -euo pipefail
|
||||
set -x
|
||||
|
||||
if [ ! -f ./pin-arvo-commit.txt ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f ./pin-brass-pill.txt ]; then
|
||||
echo "missing .travis/pin-brass-pill.txt"
|
||||
exit 1
|
||||
|
@ -6,7 +6,22 @@ var Urbit = runner.Urbit;
|
||||
var ERROR = runner.ERROR;
|
||||
var actions = runner.actions
|
||||
|
||||
var args = ['-cgSF', 'zod', '-B', 'brass.pill', 'zod'];
|
||||
var args =
|
||||
(function() {
|
||||
var commit;
|
||||
|
||||
try {
|
||||
commit = fs.readFileSync('./pin-arvo-commit.txt', 'utf-8');
|
||||
}
|
||||
catch (e) {
|
||||
return ['-cgSF', 'zod', '-B', 'brass.pill', 'zod'];
|
||||
}
|
||||
|
||||
var hash = commit.slice(0, 10);
|
||||
var pill = 'https://bootstrap.urbit.org/git-' + hash + '.pill';
|
||||
return ['-u', pill, '-cgPSF', 'zod', 'zod'];
|
||||
})();
|
||||
|
||||
var urbit = new Urbit(args);
|
||||
|
||||
// vere hangs (always?) with run in travis-ci with -P
|
||||
|
@ -546,8 +546,7 @@
|
||||
/* u3_opts: command line configuration.
|
||||
*/
|
||||
typedef struct _u3_opts {
|
||||
// XX find a way to re-enable -A (fastboot)
|
||||
// c3_c* arv_c; // -A, initial sync from
|
||||
c3_c* arv_c; // -A, initial sync from
|
||||
c3_o abo; // -a, abort aggressively
|
||||
c3_c* pil_c; // -B, bootstrap from
|
||||
c3_o bat; // -b, batch create
|
||||
@ -573,8 +572,7 @@
|
||||
c3_o qui; // -q, quiet
|
||||
c3_o rep; // -R, report build info
|
||||
c3_o has; // -S, Skip battery hashes
|
||||
// XX find a way to re-enable -s (auto-pill)
|
||||
// c3_o git; // -s, pill url from arvo git hash
|
||||
c3_o git; // -s, pill url from arvo git hash
|
||||
c3_o etn; // -t, trust snapshot for pre-boot
|
||||
c3_c* url_c; // -u, pill url
|
||||
c3_o vno; // -V, replay without reboots
|
||||
@ -666,10 +664,10 @@
|
||||
*/
|
||||
typedef struct _u3_pier {
|
||||
c3_c* pax_c; // pier directory
|
||||
c3_c* sys_c; // pill file
|
||||
c3_w wag_w; // config flags
|
||||
c3_d gen_d; // last event discovered
|
||||
c3_d but_d; // boot barrier
|
||||
c3_d lif_d; // lifecycle boot barrier
|
||||
c3_d tic_d[1]; // ticket (unstretched)
|
||||
c3_d sec_d[1]; // generator (unstretched)
|
||||
c3_d key_d[4]; // secret (stretched)
|
||||
@ -678,6 +676,7 @@
|
||||
c3_s por_s; // UDP port
|
||||
c3_o fak_o; // yes iff fake security
|
||||
u3_noun bot; // boot event XX review
|
||||
u3_noun pil; // pill XX review
|
||||
u3_disk* log_u; // event log
|
||||
u3_lord* god_u; // computer
|
||||
u3_ames* sam_u; // packet interface
|
||||
@ -1073,10 +1072,10 @@
|
||||
void
|
||||
u3_unix_ef_move(void);
|
||||
|
||||
/* u3_unix_initial_into(): intialize filesystem from urb/zod
|
||||
/* u3_unix_initial_into_card(): create initial filesystem sync card.
|
||||
*/
|
||||
void
|
||||
u3_unix_ef_initial_into(u3_pier *pir_u);
|
||||
u3_noun
|
||||
u3_unix_initial_into_card(c3_c* arv_c);
|
||||
|
||||
/* u3_unix_ef_look(): update filesystem from unix
|
||||
*/
|
||||
@ -1227,7 +1226,7 @@
|
||||
/* u3_pier_create(): create a pier, loading existing.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_pier_create(c3_w wag_w, c3_c* pax_c, c3_c* sys_c);
|
||||
u3_pier_create(c3_w wag_w, c3_c* pax_c);
|
||||
|
||||
/* u3_pier_interrupt(): interrupt running process.
|
||||
*/
|
||||
|
@ -72,10 +72,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
u3_Host.ops_u.dry = c3n;
|
||||
u3_Host.ops_u.etn = c3n;
|
||||
u3_Host.ops_u.gab = c3n;
|
||||
|
||||
// XX find a way to re-enable -s (auto-pill)
|
||||
//
|
||||
// u3_Host.ops_u.git = c3n;
|
||||
u3_Host.ops_u.git = c3n;
|
||||
|
||||
// always disable hashboard
|
||||
// XX temporary, remove once hashes are added
|
||||
@ -92,10 +89,8 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
u3_Host.ops_u.veb = c3n;
|
||||
u3_Host.ops_u.kno_w = DefaultKernel;
|
||||
|
||||
// XX re-enable -s, -A
|
||||
//
|
||||
while ( -1 != (ch_i=getopt(argc, argv,
|
||||
"G:J:B:K:H:w:u:e:E:f:F:k:m:p:LjabcCdgqtvxPDRS")) )
|
||||
"G:J:B:K:A:H:w:u:e:E:f:F:k:m:p:LjabcCdgqstvxPDRS")) )
|
||||
{
|
||||
switch ( ch_i ) {
|
||||
case 'J': {
|
||||
@ -111,10 +106,8 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
break;
|
||||
}
|
||||
case 'A': {
|
||||
// XX find a way to re-enable -A (fastboot)
|
||||
// u3_Host.ops_u.arv_c = strdup(optarg);
|
||||
// break;
|
||||
return c3n;
|
||||
u3_Host.ops_u.arv_c = strdup(optarg);
|
||||
break;
|
||||
}
|
||||
case 'H': {
|
||||
u3_Host.ops_u.dns_c = strdup(optarg);
|
||||
@ -188,8 +181,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
case 'D': { u3_Host.ops_u.dry = c3y; break; }
|
||||
case 'q': { u3_Host.ops_u.qui = c3y; break; }
|
||||
case 'v': { u3_Host.ops_u.veb = c3y; break; }
|
||||
// XX find a way to re-enable -s (auto-pill)
|
||||
// case 's': { u3_Host.ops_u.git = c3y; break; }
|
||||
case 's': { u3_Host.ops_u.git = c3y; break; }
|
||||
case 'S': { u3_Host.ops_u.has = c3y; break; }
|
||||
case 't': { u3_Host.ops_u.etn = c3y; break; }
|
||||
case '?': default: {
|
||||
@ -325,20 +317,18 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
return c3n;
|
||||
}
|
||||
else if ( u3_Host.ops_u.nuu == c3y
|
||||
&& u3_Host.ops_u.url_c == 0 ) {
|
||||
// XX find a way to re-enable -s (auto-pill)
|
||||
// && u3_Host.ops_u.git == c3n ) {
|
||||
&& u3_Host.ops_u.url_c == 0
|
||||
&& u3_Host.ops_u.git == c3n ) {
|
||||
u3_Host.ops_u.url_c =
|
||||
"https://bootstrap.urbit.org/urbit-" URBIT_VERSION ".pill";
|
||||
}
|
||||
// XX find a way to re-enable -A (fastboot)
|
||||
// else if ( u3_Host.ops_u.nuu == c3y
|
||||
// && u3_Host.ops_u.url_c == 0
|
||||
// && u3_Host.ops_u.arv_c == 0 ) {
|
||||
else if ( u3_Host.ops_u.nuu == c3y
|
||||
&& u3_Host.ops_u.url_c == 0
|
||||
&& u3_Host.ops_u.arv_c == 0 ) {
|
||||
|
||||
// fprintf(stderr, "-s only makes sense with -A\n");
|
||||
// return c3n;
|
||||
// }
|
||||
fprintf(stderr, "-s only makes sense with -A\n");
|
||||
return c3n;
|
||||
}
|
||||
|
||||
if ( u3_Host.ops_u.pil_c != 0 ) {
|
||||
struct stat s;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <vere/vere.h>
|
||||
|
||||
typedef struct _u3_serf {
|
||||
c3_w len_w; // boot sequence length
|
||||
c3_d evt_d; // last event processed
|
||||
c3_l mug_l; // hash of state
|
||||
c3_d key_d[4]; // disk key
|
||||
@ -74,7 +75,14 @@
|
||||
:: +writ: from lord to serf
|
||||
::
|
||||
+$ writ
|
||||
$% :: exit immediately
|
||||
$% :: prepare to boot
|
||||
::
|
||||
:: p: identity
|
||||
:: q: fake?
|
||||
:: r: number of boot formulas
|
||||
::
|
||||
[%boot p=@p q=? r=@]
|
||||
:: exit immediately
|
||||
::
|
||||
:: p: exit code
|
||||
::
|
||||
@ -360,34 +368,6 @@ _serf_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
|
||||
u3z(u3A->roc);
|
||||
u3A->roc = cor;
|
||||
|
||||
// single-home
|
||||
//
|
||||
// XX revise when real keys are supported
|
||||
// XX dispatch on evt_d, wire, or card tag?
|
||||
//
|
||||
if ( c3__boot == u3h(u3t(ovo)) ) {
|
||||
// ovo=[%boot *]
|
||||
// vir=[[wire %init @p] ~]
|
||||
// fec=[%init @p]
|
||||
//
|
||||
u3_noun fec = u3t(u3h(vir));
|
||||
|
||||
c3_assert( c3__init == u3h(fec) );
|
||||
c3_assert( u3_none == u3A->our );
|
||||
|
||||
u3A->our = u3k(u3t(fec));
|
||||
u3A->fak = ( c3__fake == u3h(u3t(u3t(ovo))) ) ? c3y : c3n;
|
||||
|
||||
{
|
||||
u3_noun nam = u3dc("scot", 'p', u3k(u3A->our));
|
||||
c3_c* nam_c = u3r_string(nam);
|
||||
fprintf(stderr, "boot: ship: %s%s\r\n", nam_c,
|
||||
(c3y == u3A->fak) ? " (fake)" : "");
|
||||
free(nam_c);
|
||||
u3z(nam);
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun sac = u3_nul;
|
||||
|
||||
// intercept |mass, observe |reset
|
||||
@ -436,10 +416,10 @@ _serf_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
|
||||
u3z(sac); u3z(ovo);
|
||||
}
|
||||
|
||||
/* _serf_poke_live(): apply event.
|
||||
/* _serf_work_live(): apply event.
|
||||
*/
|
||||
static void
|
||||
_serf_poke_live(c3_d evt_d, // event number
|
||||
_serf_work_live(c3_d evt_d, // event number
|
||||
c3_l mug_l, // mug of state
|
||||
u3_noun job) // event date
|
||||
{
|
||||
@ -545,10 +525,10 @@ _serf_boot_fire(u3_noun eve)
|
||||
return pro;
|
||||
}
|
||||
|
||||
/* _serf_poke_boot(): apply initial-stage event.
|
||||
/* _serf_work_boot(): apply initial-stage event.
|
||||
*/
|
||||
static void
|
||||
_serf_poke_boot(c3_d evt_d,
|
||||
_serf_work_boot(c3_d evt_d,
|
||||
c3_l mug_l,
|
||||
u3_noun job)
|
||||
{
|
||||
@ -559,7 +539,7 @@ _serf_poke_boot(c3_d evt_d,
|
||||
|
||||
fprintf(stderr, "serf: (%" PRIu64 ")| boot\r\n", evt_d);
|
||||
|
||||
if ( 5 == evt_d ) {
|
||||
if ( u3V.len_w == evt_d ) {
|
||||
u3_noun eve, pru;
|
||||
|
||||
eve = u3kb_flop(u3A->roe);
|
||||
@ -596,11 +576,11 @@ _serf_poke_work(c3_d evt_d, // event number
|
||||
c3_l mug_l, // mug of state
|
||||
u3_noun job) // full event
|
||||
{
|
||||
if ( evt_d < 6 ) {
|
||||
_serf_poke_boot(evt_d, mug_l, job);
|
||||
if ( evt_d <= u3V.len_w ) {
|
||||
_serf_work_boot(evt_d, mug_l, job);
|
||||
}
|
||||
else {
|
||||
_serf_poke_live(evt_d, mug_l, job);
|
||||
_serf_work_live(evt_d, mug_l, job);
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,6 +592,18 @@ _serf_poke_exit(c3_w cod_w) // exit code
|
||||
exit(cod_w);
|
||||
}
|
||||
|
||||
/* _serf_poke_boot(): prepare to boot.
|
||||
*/
|
||||
static void
|
||||
_serf_poke_boot(u3_noun who, u3_noun fak, c3_w len_w)
|
||||
{
|
||||
c3_assert( u3_none == u3A->our );
|
||||
|
||||
u3A->our = who;
|
||||
u3A->fak = fak;
|
||||
u3V.len_w = len_w;
|
||||
}
|
||||
|
||||
/* _serf_poke():
|
||||
*/
|
||||
void
|
||||
@ -628,6 +620,29 @@ _serf_poke(void* vod_p, u3_noun mat)
|
||||
goto error;
|
||||
}
|
||||
|
||||
case c3__boot: {
|
||||
u3_noun who, fak, len;
|
||||
c3_w len_w;
|
||||
|
||||
if ( (c3n == u3r_qual(jar, 0, &who, &fak, &len)) ||
|
||||
(c3n == u3ud(who)) ||
|
||||
(1 < u3r_met(7, who)) ||
|
||||
(c3n == u3ud(fak)) ||
|
||||
(1 < u3r_met(0, fak)) ||
|
||||
(c3n == u3ud(len)) ||
|
||||
(1 < u3r_met(3, len)) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
len_w = u3r_word(0, len);
|
||||
u3k(who);
|
||||
u3k(fak);
|
||||
u3z(jar);
|
||||
|
||||
return _serf_poke_boot(who, fak, len_w);
|
||||
}
|
||||
|
||||
case c3__work: {
|
||||
u3_noun evt, mug, job;
|
||||
c3_d evt_d;
|
||||
@ -676,7 +691,6 @@ _serf_poke(void* vod_p, u3_noun mat)
|
||||
goto error;
|
||||
}
|
||||
|
||||
fprintf(stderr, "serf: save\r\n");
|
||||
u3z(jar);
|
||||
|
||||
return u3e_save();
|
||||
@ -704,11 +718,15 @@ u3_serf_boot(void)
|
||||
0, // XX u3r_mug(u3A->roc),
|
||||
u3nc(u3k(u3A->our), u3k(u3A->fak))));
|
||||
|
||||
/* disable hashboard for fake ships
|
||||
*/
|
||||
// disable hashboard for fake ships
|
||||
//
|
||||
if ( c3y == u3A->fak ) {
|
||||
u3C.wag_w |= u3o_hashless;
|
||||
}
|
||||
|
||||
// no boot sequence expected
|
||||
//
|
||||
u3V.len_w = 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "serf: play %" PRIu64 "\r\n", nex_d);
|
||||
|
@ -2,6 +2,7 @@
|
||||
**
|
||||
** the main loop of the daemon process
|
||||
*/
|
||||
#include <curl/curl.h>
|
||||
#include <unistd.h>
|
||||
#include <uv.h>
|
||||
#include "all.h"
|
||||
@ -12,39 +13,123 @@
|
||||
static c3_c sag_w;
|
||||
|
||||
/*
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
:: wyrd: requires auth to a single relevant ship ::
|
||||
:: doom: requires auth to the daemon itself ::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|% ::
|
||||
+$ fate :: client to lord
|
||||
$% [%auth p=(unit ship) q=@] :: authenticate client
|
||||
[%wyrd p=ship q=wyrd] :: ship action
|
||||
[%doom p=doom] :: daemon command
|
||||
== ::
|
||||
+$ wyrd :: ship action
|
||||
$% [%susp ~] :: release this pier
|
||||
[%vent p=ovum] :: generate event
|
||||
== ::
|
||||
+$ doom :: daemon command
|
||||
$% [%boot p=boot q=@pill r=@t] :: boot (r=pier)
|
||||
[%exit ~] :: end the daemon
|
||||
[%pier p=(unit @t)] :: acquire a pier
|
||||
[%root p=ship q=wyrd] :: admin ship actions
|
||||
== ::
|
||||
+$ boot :: boot procedures
|
||||
$% [%come p=(unit ship)] :: mine a comet
|
||||
[%dawn p=seed] :: real keys
|
||||
[%fake p=who] :: fake keys
|
||||
== ::
|
||||
+$ pill :: boot sequence
|
||||
(each path=@t pill=@) ::
|
||||
+$ cede :: lord to client
|
||||
$% [%cede p=ship q[(list ovum)] :: send cards
|
||||
[%firm ~] :: accept command
|
||||
[%deny p=@t] :: reject command
|
||||
== ::
|
||||
-- ::
|
||||
:: king/client protocol:
|
||||
::
|
||||
|%
|
||||
:: +fate: client to lord
|
||||
::
|
||||
+$ fate
|
||||
$% :: authenticate client
|
||||
::
|
||||
[%auth p=(unit ship) q=@]
|
||||
:: ship action
|
||||
::
|
||||
[%wyrd p=ship q=wyrd]
|
||||
:: daemon command
|
||||
::
|
||||
[%doom p=doom]
|
||||
==
|
||||
:: +wyrd: ship action
|
||||
::
|
||||
:: Should require auth to a single relevant ship
|
||||
::
|
||||
+$ wyrd
|
||||
$% :: release this pier
|
||||
::
|
||||
:: XX not implemented
|
||||
::
|
||||
[%susp ~]
|
||||
:: generate event
|
||||
::
|
||||
:: XX partially implemented
|
||||
::
|
||||
[%vent p=ovum]
|
||||
==
|
||||
:: +doom: daemon command
|
||||
::
|
||||
:: Should require auth to the daemon itself
|
||||
::
|
||||
+$ doom
|
||||
$% :: boot
|
||||
::
|
||||
:: p: boot procedure
|
||||
:: q: pill specifier
|
||||
:: r: path to pier
|
||||
::
|
||||
[%boot p=boot q=pill r=@t]
|
||||
:: end the daemon
|
||||
::
|
||||
:: XX not implemented
|
||||
::
|
||||
[%exit ~]
|
||||
:: acquire a pier
|
||||
::
|
||||
:: XX used for restart, may not be right
|
||||
::
|
||||
[%pier p=(unit @t)]
|
||||
:: admin ship actions
|
||||
::
|
||||
:: XX not implemented
|
||||
::
|
||||
[%root p=ship q=wyrd]
|
||||
==
|
||||
:: +boot: boot procedures
|
||||
::
|
||||
+$ boot
|
||||
$% :: mine a comet
|
||||
::
|
||||
:: p: optionally under a specific star
|
||||
::
|
||||
[%come p=(unit ship)]
|
||||
:: boot with real keys
|
||||
::
|
||||
:: And perform pre-boot validation, retrieve snapshot, etc.
|
||||
::
|
||||
[%dawn p=seed]
|
||||
:: boot with fake keys
|
||||
::
|
||||
:: p: identity
|
||||
::
|
||||
[%fake p=ship]
|
||||
==
|
||||
:: +pill: boot-sequence ingredients
|
||||
::
|
||||
+$ pill
|
||||
%+ each
|
||||
:: %&: complete pill (either +brass or +solid)
|
||||
::
|
||||
:: p: jammed pill
|
||||
:: q: optional %into ovum overriding that of .p
|
||||
::
|
||||
[p=@ q=(unit ovum)]
|
||||
:: %|: incomplete pill (+ivory)
|
||||
::
|
||||
:: XX not implemented, needs generation of
|
||||
:: %veer ova for install %zuse and the vanes
|
||||
::
|
||||
:: p: jammed pill
|
||||
:: q: module ova
|
||||
:: r: userspace ova
|
||||
::
|
||||
[p=@ q=(list ovum) r=(list ovum)]
|
||||
:: +cede: lord to client
|
||||
::
|
||||
:: XX not implemented
|
||||
::
|
||||
+$ cede
|
||||
$% :: send cards
|
||||
::
|
||||
:: XX presumably the effects of %vent in +wyrd
|
||||
::
|
||||
[%cede p=ship q=(list ovum)]
|
||||
:: accept command
|
||||
::
|
||||
[%firm ~]
|
||||
:: reject command
|
||||
::
|
||||
[%deny p=@t]
|
||||
==
|
||||
--
|
||||
*/
|
||||
|
||||
void _king_auth(u3_noun auth);
|
||||
@ -333,20 +418,155 @@ _king_socket_connect(uv_stream_t *sock, int status)
|
||||
u3_newt_read((u3_moat *)mor_u);
|
||||
}
|
||||
|
||||
/* _boothack_pill(): parse CLI pill arguments into (each path pill)
|
||||
/* _king_curl_alloc(): allocate a response buffer for curl
|
||||
** XX deduplicate with dawn.c
|
||||
*/
|
||||
static size_t
|
||||
_king_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, uv_buf_t* buf_u)
|
||||
{
|
||||
size_t siz_t = uni_t * mem_t;
|
||||
buf_u->base = c3_realloc(buf_u->base, 1 + siz_t + buf_u->len);
|
||||
|
||||
memcpy(buf_u->base + buf_u->len, dat_v, siz_t);
|
||||
buf_u->len += siz_t;
|
||||
buf_u->base[buf_u->len] = 0;
|
||||
|
||||
return siz_t;
|
||||
}
|
||||
|
||||
/* _king_get_atom(): HTTP GET url_c, produce the response body as an atom.
|
||||
** XX deduplicate with dawn.c
|
||||
*/
|
||||
static u3_noun
|
||||
_king_get_atom(c3_c* url_c)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode result;
|
||||
long cod_l;
|
||||
|
||||
uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0);
|
||||
|
||||
if ( !(curl = curl_easy_init()) ) {
|
||||
fprintf(stderr, "failed to initialize libcurl\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url_c);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _king_curl_alloc);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);
|
||||
|
||||
result = curl_easy_perform(curl);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &cod_l);
|
||||
|
||||
// XX retry?
|
||||
//
|
||||
if ( CURLE_OK != result ) {
|
||||
fprintf(stderr, "failed to fetch %s: %s\n",
|
||||
url_c, curl_easy_strerror(result));
|
||||
exit(1);
|
||||
}
|
||||
if ( 300 <= cod_l ) {
|
||||
fprintf(stderr, "error fetching %s: HTTP %ld\n", url_c, cod_l);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
return u3i_bytes(buf_u.len, (const c3_y*)buf_u.base);
|
||||
}
|
||||
|
||||
/* _get_cmd_output(): Run a shell command and capture its output.
|
||||
Exits with an error if the command fails or produces no output.
|
||||
The 'out_c' parameter should be an array of sufficient length to hold
|
||||
the command's output, up to a max of len_c characters.
|
||||
*/
|
||||
static void
|
||||
_get_cmd_output(c3_c *cmd_c, c3_c *out_c, c3_w len_c)
|
||||
{
|
||||
FILE *fp = popen(cmd_c, "r");
|
||||
if ( NULL == fp ) {
|
||||
fprintf(stderr, "'%s' failed\n", cmd_c);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( NULL == fgets(out_c, len_c, fp) ) {
|
||||
fprintf(stderr, "'%s' produced no output\n", cmd_c);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
}
|
||||
|
||||
/* _arvo_hash(): get a shortened hash of the last git commit
|
||||
that modified the sys/ directory in arvo.
|
||||
hax_c must be an array with length >= 11.
|
||||
*/
|
||||
static void
|
||||
_arvo_hash(c3_c *out_c, c3_c *arv_c)
|
||||
{
|
||||
c3_c cmd_c[2048];
|
||||
|
||||
sprintf(cmd_c, "git -C %s log -1 HEAD --format=%%H -- sys/", arv_c);
|
||||
_get_cmd_output(cmd_c, out_c, 11);
|
||||
|
||||
out_c[10] = 0; // end with null-byte
|
||||
}
|
||||
|
||||
/* _git_pill_url(): produce a URL from which to download a pill
|
||||
based on the location of an arvo git repository.
|
||||
*/
|
||||
static void
|
||||
_git_pill_url(c3_c *out_c, c3_c *arv_c)
|
||||
{
|
||||
c3_c hax_c[11];
|
||||
|
||||
assert(NULL != arv_c);
|
||||
|
||||
if ( 0 != system("which git >> /dev/null") ) {
|
||||
fprintf(stderr, "boot: could not find git executable\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_arvo_hash(hax_c, arv_c);
|
||||
sprintf(out_c, "https://bootstrap.urbit.org/git-%s.pill", hax_c);
|
||||
}
|
||||
|
||||
/* _boothack_pill(): parse CLI pill arguments into +pill specifier
|
||||
*/
|
||||
static u3_noun
|
||||
_boothack_pill(void)
|
||||
{
|
||||
if ( 0 == u3_Host.ops_u.pil_c ) {
|
||||
// XX download default pill
|
||||
// XX support -u
|
||||
//
|
||||
fprintf(stderr, "boot: new ship must specify pill (-B)\r\n");
|
||||
exit(1);
|
||||
u3_noun arv = u3_nul;
|
||||
u3_noun pil;
|
||||
|
||||
if ( 0 != u3_Host.ops_u.pil_c ) {
|
||||
fprintf(stderr, "boot: loading pill %s\r\n", u3_Host.ops_u.pil_c);
|
||||
pil = u3m_file(u3_Host.ops_u.pil_c);
|
||||
}
|
||||
else {
|
||||
c3_c url_c[2048];
|
||||
|
||||
if ( (c3y == u3_Host.ops_u.git) &&
|
||||
(0 != u3_Host.ops_u.arv_c) )
|
||||
{
|
||||
_git_pill_url(url_c, u3_Host.ops_u.arv_c);
|
||||
}
|
||||
else {
|
||||
c3_assert( 0 != u3_Host.ops_u.url_c );
|
||||
strcpy(url_c, u3_Host.ops_u.url_c);
|
||||
}
|
||||
|
||||
fprintf(stderr, "boot: downloading pill %s\r\n", url_c);
|
||||
pil = _king_get_atom(url_c);
|
||||
}
|
||||
|
||||
return u3nc(c3y, u3i_string(u3_Host.ops_u.pil_c));
|
||||
if ( 0 != u3_Host.ops_u.arv_c ) {
|
||||
fprintf(stderr, "boot: preparing filesystem from %s\r\n",
|
||||
u3_Host.ops_u.arv_c);
|
||||
arv = u3nc(u3_nul, u3_unix_initial_into_card(u3_Host.ops_u.arv_c));
|
||||
}
|
||||
|
||||
return u3nt(c3y, pil, arv);
|
||||
}
|
||||
|
||||
/* _boothack_key(): parse a private key file or value
|
||||
|
@ -94,6 +94,53 @@ _pier_work_bail(void* vod_p,
|
||||
fprintf(stderr, "pier: work error: %s\r\n", err_c);
|
||||
}
|
||||
|
||||
/* _pier_save_boot_complete(): commit complete.
|
||||
*/
|
||||
static void
|
||||
_pier_save_boot_complete(void* vod_p)
|
||||
{
|
||||
// no-op, callback required by u3_foil_append()
|
||||
//
|
||||
}
|
||||
|
||||
/* _pier_save_boot(): save boot metadata.
|
||||
*/
|
||||
static void
|
||||
_pier_save_boot(u3_pier* pir_u, u3_atom mat)
|
||||
{
|
||||
// XX deduplicate with _pier_disk_commit_request
|
||||
//
|
||||
c3_d len_d = u3r_met(6, mat);
|
||||
c3_d* buf_d = c3_malloc(8 * len_d);
|
||||
|
||||
u3r_chubs(0, len_d, buf_d, mat);
|
||||
|
||||
u3_foil_append(_pier_save_boot_complete,
|
||||
(void*)0,
|
||||
pir_u->log_u->fol_u,
|
||||
buf_d,
|
||||
len_d);
|
||||
}
|
||||
|
||||
/* _pier_work_boot(): prepare serf boot.
|
||||
*/
|
||||
static void
|
||||
_pier_work_boot(u3_pier* pir_u, c3_o sav_o)
|
||||
{
|
||||
u3_lord* god_u = pir_u->god_u;
|
||||
|
||||
u3_noun who = u3i_chubs(2, pir_u->who_d);
|
||||
u3_noun len = u3i_chubs(1, &pir_u->lif_d);
|
||||
u3_noun msg = u3nq(c3__boot, who, pir_u->fak_o, len);
|
||||
u3_atom mat = u3ke_jam(msg);
|
||||
|
||||
if ( c3y == sav_o ) {
|
||||
_pier_save_boot(pir_u, u3k(mat));
|
||||
}
|
||||
|
||||
u3_newt_write(&god_u->inn_u, mat, 0);
|
||||
}
|
||||
|
||||
/* _pier_disk_shutdown(): close the log.
|
||||
*/
|
||||
static void
|
||||
@ -782,6 +829,39 @@ _pier_disk_load_commit(u3_pier* pir_u,
|
||||
c3_free(buf_d);
|
||||
|
||||
ovo = u3ke_cue(u3k(mat));
|
||||
|
||||
// single-home
|
||||
//
|
||||
if ( (0ULL == pos_d) &&
|
||||
(1ULL == lav_d) )
|
||||
{
|
||||
u3_noun who, fak, len;
|
||||
|
||||
c3_assert( c3__boot == u3h(ovo) );
|
||||
u3x_qual(ovo, 0, &who, &fak, &len);
|
||||
|
||||
c3_assert( c3y == u3ud(who) );
|
||||
c3_assert( 1 >= u3r_met(7, who) );
|
||||
c3_assert( c3y == u3ud(fak) );
|
||||
c3_assert( 1 >= u3r_met(0, fak) );
|
||||
c3_assert( c3y == u3ud(len) );
|
||||
c3_assert( 1 >= u3r_met(3, len) );
|
||||
|
||||
pir_u->fak_o = (c3_o)fak;
|
||||
pir_u->lif_d = u3r_word(0, len);
|
||||
u3r_chubs(0, 2, pir_u->who_d, who);
|
||||
|
||||
// Disable networking for fake ships
|
||||
//
|
||||
if ( c3y == pir_u->fak_o ) {
|
||||
u3_Host.ops_u.net = c3n;
|
||||
}
|
||||
|
||||
u3z(mat);
|
||||
u3z(ovo);
|
||||
break;
|
||||
}
|
||||
|
||||
c3_assert(c3__work == u3h(ovo));
|
||||
evt = u3h(u3t(ovo));
|
||||
job = u3k(u3t(u3t(u3t(ovo))));
|
||||
@ -846,160 +926,221 @@ _pier_disk_load_commit(u3_pier* pir_u,
|
||||
}
|
||||
|
||||
/* _pier_boot_vent(): create and enqueue boot sequence
|
||||
**
|
||||
** per cgy:
|
||||
** this new boot sequence is almost, but not quite,
|
||||
** the right thing. see new arvo.
|
||||
*/
|
||||
static void
|
||||
_pier_boot_vent(u3_pier* pir_u)
|
||||
{
|
||||
c3_w inx_w = 1;
|
||||
|
||||
if ( !u3A->sys ) {
|
||||
fprintf(stderr, "boot: loading pill %s\r\n", pir_u->sys_c);
|
||||
|
||||
u3A->sys = u3m_file(pir_u->sys_c);
|
||||
}
|
||||
// bot: boot formulas
|
||||
// mod: module ova
|
||||
// use: userpace ova
|
||||
//
|
||||
u3_noun bot, mod, use;
|
||||
|
||||
// extract boot formulas and module/userspace ova from pill
|
||||
//
|
||||
{
|
||||
u3_noun lal = u3ke_cue(u3k(u3A->sys));
|
||||
u3_noun pil_p, pil_q, pil_r;
|
||||
u3_noun pro;
|
||||
|
||||
/* this new boot sequence is almost, but not quite,
|
||||
** the right thing. see new arvo.
|
||||
*/
|
||||
{
|
||||
u3_noun who = u3i_chubs(2, pir_u->who_d);
|
||||
u3_noun bot, mod, fil;
|
||||
c3_assert( c3y == u3du(pir_u->pil) );
|
||||
|
||||
u3r_trel(lal, &bot, &mod, &fil);
|
||||
pir_u->but_d = 0;
|
||||
|
||||
/* insert boot sequence directly
|
||||
*/
|
||||
{
|
||||
u3_noun seq = u3k(bot);
|
||||
{
|
||||
u3_noun all = seq;
|
||||
|
||||
pir_u->but_d += u3kb_lent(u3k(all));
|
||||
while ( all ) {
|
||||
_pier_insert(pir_u, 0, u3k(u3h(all)));
|
||||
inx_w++;
|
||||
all = u3t(all);
|
||||
}
|
||||
}
|
||||
u3z(seq);
|
||||
}
|
||||
|
||||
/* insert module sequence, prepending first identity event
|
||||
*/
|
||||
{
|
||||
u3_noun seq = u3k(mod);
|
||||
|
||||
// prepend initial entropy
|
||||
// XX u3_pier_rand or _pier_zen?
|
||||
// XX move to _pier_loop_wake?
|
||||
//
|
||||
{
|
||||
c3_w eny_w[16];
|
||||
u3_noun eny;
|
||||
|
||||
c3_rand(eny_w);
|
||||
eny = u3i_words(16, eny_w);
|
||||
|
||||
u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
|
||||
u3_noun car = u3nc(c3__wack, eny);
|
||||
u3_noun ovo = u3nc(wir, car);
|
||||
|
||||
seq = u3nc(ovo, seq);
|
||||
}
|
||||
|
||||
// prepend identity event to module sequence
|
||||
// to set single-home
|
||||
//
|
||||
{
|
||||
u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
|
||||
u3_noun car = u3nc(c3__whom, u3k(who));
|
||||
u3_noun ovo = u3nc(wir, car);
|
||||
|
||||
seq = u3nc(ovo, seq);
|
||||
}
|
||||
|
||||
/* insert with timestamp
|
||||
*/
|
||||
{
|
||||
u3_noun all = seq;
|
||||
|
||||
pir_u->but_d += u3kb_lent(u3k(all));
|
||||
|
||||
while ( all ) {
|
||||
_pier_insert_ovum(pir_u, 0, u3k(u3h(all)));
|
||||
inx_w++;
|
||||
all = u3t(all);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XX moar boot sequence woes
|
||||
*/
|
||||
{
|
||||
// partially duplicates _pier_loop_wake()
|
||||
//
|
||||
c3_l cod_l;
|
||||
|
||||
cod_l = u3a_lush(c3__ames);
|
||||
{
|
||||
// stash domain for fake effect
|
||||
// XX this is horrible
|
||||
//
|
||||
u3_noun tuf = ( c3__fake == u3h(pir_u->bot) ) ? u3_nul :
|
||||
u3h(u3t(u3t(u3t(u3t(pir_u->bot)))));
|
||||
|
||||
|
||||
// send a fake effect to bring up listeners and configure domains
|
||||
// XX horrible hack
|
||||
//
|
||||
u3_ames_ef_turf(pir_u, u3k(tuf));
|
||||
}
|
||||
|
||||
u3_ames_ef_bake(pir_u);
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__behn);
|
||||
u3_behn_ef_bake(pir_u);
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
|
||||
/* insert legacy boot event
|
||||
*/
|
||||
{
|
||||
u3_noun ovo;
|
||||
|
||||
/* make legacy boot event
|
||||
*/
|
||||
{
|
||||
u3_noun wir = u3nq(u3_blip, c3__term, '1', u3_nul);
|
||||
|
||||
c3_assert( 0 != pir_u->bot);
|
||||
ovo = u3nt(wir, c3__boot, pir_u->bot);
|
||||
pir_u->bot = 0;
|
||||
}
|
||||
_pier_insert_ovum(pir_u, 0, ovo);
|
||||
}
|
||||
|
||||
/* insert filesystem install events
|
||||
*/
|
||||
{
|
||||
u3_noun all = fil;
|
||||
|
||||
while ( all ) {
|
||||
_pier_insert_ovum(pir_u, 0, u3k(u3h(all)));
|
||||
all = u3t(all);
|
||||
}
|
||||
}
|
||||
|
||||
u3z(who);
|
||||
if ( c3y == u3h(pir_u->pil) ) {
|
||||
u3x_trel(pir_u->pil, 0, &pil_p, &pil_q);
|
||||
}
|
||||
else {
|
||||
u3x_qual(pir_u->pil, 0, &pil_p, &pil_q, &pil_r);
|
||||
}
|
||||
|
||||
u3z(lal);
|
||||
pro = u3m_soft(0, u3ke_cue, u3k(pil_p));
|
||||
|
||||
if ( 0 != u3h(pro) ) {
|
||||
fprintf(stderr, "boot: failed: unable to parse pill\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u3x_trel(u3t(pro), &bot, &mod, &use);
|
||||
u3k(bot); u3k(mod); u3k(use);
|
||||
|
||||
// optionally replace filesystem in userspace
|
||||
//
|
||||
if ( c3y == u3h(pir_u->pil) ) {
|
||||
if ( u3_nul != pil_q ) {
|
||||
c3_w len_w = 0;
|
||||
u3_noun ova = use;
|
||||
u3_noun new = u3_nul;
|
||||
u3_noun ovo;
|
||||
|
||||
while ( u3_nul != ova ) {
|
||||
ovo = u3h(ova);
|
||||
|
||||
if ( c3__into == u3h(u3t(ovo)) ) {
|
||||
c3_assert( 0 == len_w );
|
||||
len_w++;
|
||||
ovo = u3k(u3t(pil_q));
|
||||
}
|
||||
|
||||
new = u3nc(u3k(ovo), new);
|
||||
ova = u3t(ova);
|
||||
}
|
||||
|
||||
c3_assert( 1 == len_w );
|
||||
|
||||
u3z(use);
|
||||
use = u3kb_flop(new);
|
||||
}
|
||||
}
|
||||
// prepend %lite module and userspace ova
|
||||
//
|
||||
else {
|
||||
mod = u3kb_weld(u3k(pil_q), mod);
|
||||
use = u3kb_weld(u3k(pil_r), use);
|
||||
}
|
||||
|
||||
u3z(pro);
|
||||
u3z(pir_u->pil);
|
||||
pir_u->pil = u3_nul;
|
||||
}
|
||||
|
||||
// prepend entropy to the module sequence
|
||||
//
|
||||
// XX also copy to _pier_loop_wake?
|
||||
//
|
||||
{
|
||||
c3_w eny_w[16];
|
||||
c3_rand(eny_w);
|
||||
|
||||
u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
|
||||
u3_noun car = u3nc(c3__wack, u3i_words(16, eny_w));
|
||||
|
||||
mod = u3nc(u3nc(wir, car), mod);
|
||||
}
|
||||
|
||||
// prepend identity to the module sequence, setting single-home
|
||||
//
|
||||
{
|
||||
u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
|
||||
u3_noun car = u3nc(c3__whom, u3i_chubs(2, pir_u->who_d));
|
||||
|
||||
mod = u3nc(u3nc(wir, car), mod);
|
||||
}
|
||||
|
||||
// insert boot sequence directly
|
||||
//
|
||||
// Note that these are not ovum or (pair @da ovum) events,
|
||||
// but raw nock formulas to be directly evaluated as the
|
||||
// subject of the lifecycle formula [%2 [%0 3] %0 2].
|
||||
// All subsequent events will be (pair @da ovum).
|
||||
//
|
||||
{
|
||||
u3_noun fol = bot;
|
||||
|
||||
// initialize the boot barrier
|
||||
//
|
||||
// And the initial lifecycle boot barrier.
|
||||
//
|
||||
pir_u->but_d = u3kb_lent(u3k(fol));
|
||||
pir_u->lif_d = pir_u->but_d;
|
||||
|
||||
while ( u3_nul != fol ) {
|
||||
_pier_insert(pir_u, 0, u3k(u3h(fol)));
|
||||
fol = u3t(fol);
|
||||
}
|
||||
}
|
||||
|
||||
// prepare serf for boot sequence
|
||||
//
|
||||
{
|
||||
pir_u->fak_o = ( c3__fake == u3h(pir_u->bot) ) ? c3y : c3n;
|
||||
fprintf(stderr, "boot: ship: %s%s\r\n",
|
||||
pir_u->who_c,
|
||||
(c3y == pir_u->fak_o) ? " (fake)" : "");
|
||||
|
||||
_pier_work_boot(pir_u, c3y);
|
||||
}
|
||||
|
||||
// insert module events
|
||||
//
|
||||
{
|
||||
u3_noun ova = mod;
|
||||
// add to the boot barrier
|
||||
//
|
||||
pir_u->but_d += u3kb_lent(u3k(ova));
|
||||
|
||||
while ( u3_nul != ova ) {
|
||||
_pier_insert_ovum(pir_u, 0, u3k(u3h(ova)));
|
||||
ova = u3t(ova);
|
||||
}
|
||||
}
|
||||
|
||||
// XX moar boot sequence woes
|
||||
//
|
||||
// some i/o must be initialized before legacy boot
|
||||
//
|
||||
{
|
||||
// partially duplicates _pier_loop_wake()
|
||||
//
|
||||
c3_l cod_l;
|
||||
|
||||
cod_l = u3a_lush(c3__ames);
|
||||
{
|
||||
// stash domain for fake effect
|
||||
//
|
||||
// XX this is horrible
|
||||
//
|
||||
u3_noun tuf = ( c3__fake == u3h(pir_u->bot) ) ? u3_nul :
|
||||
u3h(u3t(u3t(u3t(u3t(pir_u->bot)))));
|
||||
|
||||
|
||||
// send a fake effect to bring up listeners and configure domains
|
||||
//
|
||||
// XX horrible hack
|
||||
//
|
||||
u3_ames_ef_turf(pir_u, u3k(tuf));
|
||||
}
|
||||
|
||||
u3_ames_ef_bake(pir_u);
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__behn);
|
||||
u3_behn_ef_bake(pir_u);
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
|
||||
// insert legacy boot event
|
||||
//
|
||||
{
|
||||
// XX do something about this wire
|
||||
// XX route directly to %jael?
|
||||
//
|
||||
c3_assert( c3y == u3du(pir_u->bot) );
|
||||
|
||||
u3_noun wir = u3nq(u3_blip, c3__term, '1', u3_nul);
|
||||
u3_noun car = u3nc(c3__boot, pir_u->bot);
|
||||
u3_noun ovo = u3nc(wir, car);
|
||||
|
||||
_pier_insert_ovum(pir_u, 0, ovo);
|
||||
|
||||
pir_u->bot = u3_nul;
|
||||
}
|
||||
|
||||
// insert userspace events
|
||||
//
|
||||
// Currently just the initial filesystem
|
||||
//
|
||||
{
|
||||
u3_noun ova = use;
|
||||
|
||||
while ( u3_nul != ova ) {
|
||||
_pier_insert_ovum(pir_u, 0, u3k(u3h(ova)));
|
||||
ova = u3t(ova);
|
||||
}
|
||||
}
|
||||
|
||||
u3z(bot); u3z(mod); u3z(use);
|
||||
}
|
||||
|
||||
/* _pier_disk_consolidate(): integrate loaded information.
|
||||
@ -1323,8 +1464,8 @@ _pier_work_poke(void* vod_p,
|
||||
pir_u->who_d[0] = who_d[0];
|
||||
pir_u->who_d[1] = who_d[1];
|
||||
|
||||
/* Disable networking for fake ships
|
||||
*/
|
||||
// Disable networking for fake ships
|
||||
//
|
||||
if ( c3y == pir_u->fak_o ) {
|
||||
u3_Host.ops_u.net = c3n;
|
||||
}
|
||||
@ -1492,58 +1633,38 @@ _pier_work_create(u3_pier* pir_u)
|
||||
/* u3_pier_create(): create a pier, loading existing.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_pier_create(c3_w wag_w, c3_c* pax_c, c3_c* sys_c)
|
||||
u3_pier_create(c3_w wag_w, c3_c* pax_c)
|
||||
{
|
||||
u3_pier* pir_u;
|
||||
// create pier
|
||||
//
|
||||
u3_pier* pir_u = c3_calloc(sizeof *pir_u);
|
||||
|
||||
/* create pier
|
||||
*/
|
||||
{
|
||||
pir_u = c3_calloc(sizeof *pir_u);
|
||||
pir_u->pax_c = pax_c;
|
||||
pir_u->wag_w = wag_w;
|
||||
|
||||
pir_u->pax_c = c3_malloc(1 + strlen(pax_c));
|
||||
strcpy(pir_u->pax_c, pax_c);
|
||||
pir_u->sam_u = c3_calloc(sizeof(u3_ames));
|
||||
pir_u->teh_u = c3_calloc(sizeof(u3_behn));
|
||||
pir_u->unx_u = c3_calloc(sizeof(u3_unix));
|
||||
pir_u->sav_u = c3_calloc(sizeof(u3_save));
|
||||
|
||||
if ( 0 != sys_c ) {
|
||||
pir_u->sys_c = c3_malloc(1 + strlen(sys_c));
|
||||
strcpy(pir_u->sys_c, sys_c);
|
||||
}
|
||||
|
||||
pir_u->wag_w = wag_w;
|
||||
pir_u->gen_d = 0;
|
||||
pir_u->key_d[0] = pir_u->key_d[1] = pir_u->key_d[2] = pir_u->key_d[3] = 0;
|
||||
|
||||
pir_u->ent_u = pir_u->ext_u = 0;
|
||||
pir_u->log_u = 0;
|
||||
pir_u->god_u = 0;
|
||||
|
||||
pir_u->sam_u = c3_calloc(sizeof(u3_ames));
|
||||
pir_u->teh_u = c3_calloc(sizeof(u3_behn));
|
||||
pir_u->unx_u = c3_calloc(sizeof(u3_unix));
|
||||
pir_u->sav_u = c3_calloc(sizeof(u3_save));
|
||||
// start the serf process
|
||||
//
|
||||
if ( !(pir_u->god_u = _pier_work_create(pir_u)) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* start process
|
||||
*/
|
||||
{
|
||||
if ( !(pir_u->god_u = _pier_work_create(pir_u)) ) {
|
||||
return 0;
|
||||
}
|
||||
// install in the pier table
|
||||
//
|
||||
if ( 0 == u3K.all_w ) {
|
||||
u3K.all_w = 16;
|
||||
u3K.tab_u = c3_malloc(16 * sizeof(u3_pier*));
|
||||
}
|
||||
if ( u3K.len_w == u3K.all_w ) {
|
||||
u3K.all_w = 2 * u3K.all_w;
|
||||
u3K.tab_u = c3_realloc(u3K.tab_u, u3K.all_w * sizeof(u3_pier*));
|
||||
}
|
||||
u3K.tab_u[u3K.len_w++] = pir_u;
|
||||
|
||||
/* install in pier table
|
||||
*/
|
||||
{
|
||||
if ( 0 == u3K.all_w ) {
|
||||
u3K.all_w = 16;
|
||||
u3K.tab_u = c3_malloc(16 * sizeof(u3_pier*));
|
||||
}
|
||||
if ( u3K.len_w == u3K.all_w ) {
|
||||
u3K.all_w = 2 * u3K.all_w;
|
||||
u3K.tab_u = c3_realloc(u3K.tab_u, u3K.all_w * sizeof(u3_pier*));
|
||||
}
|
||||
u3K.tab_u[u3K.len_w++] = pir_u;
|
||||
}
|
||||
return pir_u;
|
||||
}
|
||||
|
||||
@ -1869,14 +1990,23 @@ _pier_boot_complete(u3_pier* pir_u,
|
||||
pir_u->god_u->dun_d,
|
||||
(c3y == nuu_o ? "new" : "old"));
|
||||
|
||||
u3_pier_work_save(pir_u);
|
||||
// start event replay by preparing serf to %boot
|
||||
//
|
||||
if ( (0 == pir_u->god_u->dun_d) &&
|
||||
(c3n == nuu_o) )
|
||||
{
|
||||
_pier_work_boot(pir_u, c3n);
|
||||
}
|
||||
else {
|
||||
u3_pier_work_save(pir_u);
|
||||
}
|
||||
|
||||
/* the main course
|
||||
*/
|
||||
// the main course
|
||||
//
|
||||
_pier_loop_wake(pir_u);
|
||||
|
||||
/* where does this go, not sure?
|
||||
*/
|
||||
// XX where should this go?
|
||||
//
|
||||
{
|
||||
if ( c3y == u3_Host.ops_u.veb ) {
|
||||
u3_term_ef_verb();
|
||||
@ -2013,85 +2143,55 @@ u3_pier_stub(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* _pier_boot_make(): create/load a pier.
|
||||
*/
|
||||
static u3_pier*
|
||||
_pier_boot_make(c3_w wag_w, u3_noun pax, u3_noun sys)
|
||||
{
|
||||
c3_c* pax_c = u3r_string(pax);
|
||||
c3_c* sys_c;
|
||||
u3_pier* pir_u;
|
||||
|
||||
if ( u3_nul == sys ) {
|
||||
sys_c = 0;
|
||||
}
|
||||
else {
|
||||
c3_assert( c3y == u3h(sys) );
|
||||
sys_c = u3r_string(u3t(sys));
|
||||
}
|
||||
|
||||
pir_u = u3_pier_create(wag_w, pax_c, sys_c);
|
||||
|
||||
u3z(pax); free(pax_c);
|
||||
u3z(sys); free(sys_c);
|
||||
|
||||
pir_u->por_s = 0;
|
||||
|
||||
return pir_u;
|
||||
}
|
||||
|
||||
/* u3_pier_boot(): start the new pier system.
|
||||
*/
|
||||
void
|
||||
u3_pier_boot(c3_w wag_w, // config flags
|
||||
u3_pier_boot(c3_w wag_w, // config flags
|
||||
u3_noun who, // identity
|
||||
u3_noun ven, // boot event
|
||||
u3_noun pil, // type-of/path-to pill
|
||||
u3_noun pax) // path to pier
|
||||
{
|
||||
u3_pier* pir_u;
|
||||
// make/load pier
|
||||
//
|
||||
u3_pier* pir_u = u3_pier_create(wag_w, u3r_string(pax));
|
||||
|
||||
/* make/load pier
|
||||
*/
|
||||
pir_u = _pier_boot_make(wag_w, pax, pil);
|
||||
|
||||
/* set boot params
|
||||
*/
|
||||
// set boot params
|
||||
//
|
||||
{
|
||||
{
|
||||
u3_noun how = u3dc("scot", 'p', u3k(who));
|
||||
|
||||
pir_u->who_c = u3r_string(how);
|
||||
u3z(how);
|
||||
fprintf(stderr, "boot: ship: %s\r\n", pir_u->who_c);
|
||||
}
|
||||
|
||||
u3r_chubs(0, 2, pir_u->who_d, who);
|
||||
// u3r_chubs(0, 1, pir_u->tic_d, tic);
|
||||
// u3r_chubs(0, 1, pir_u->sec_d, sec);
|
||||
|
||||
pir_u->bot = ven;
|
||||
|
||||
u3z(who);
|
||||
// u3z(tic);
|
||||
// u3z(sec);
|
||||
pir_u->bot = u3k(ven);
|
||||
pir_u->pil = u3k(pil);
|
||||
}
|
||||
|
||||
/* initialize boot i/o
|
||||
*/
|
||||
// initialize boot i/o
|
||||
//
|
||||
_pier_loop_init_pier(pir_u);
|
||||
|
||||
/* initialize polling handle
|
||||
*/
|
||||
// initialize polling handle
|
||||
//
|
||||
uv_prepare_init(u3_Host.lup_u, &pir_u->pep_u);
|
||||
uv_prepare_start(&pir_u->pep_u, _pier_loop_prepare);
|
||||
|
||||
/* initialize loop - move to _pier_boot_make().
|
||||
*/
|
||||
// initialize loop
|
||||
//
|
||||
_pier_loop_init();
|
||||
|
||||
/* XX: _pier_loop_exit() should be called somewhere, but is not.
|
||||
*/
|
||||
// XX: _pier_loop_exit() should be called somewhere, but is not.
|
||||
//
|
||||
|
||||
u3z(who);
|
||||
u3z(ven);
|
||||
u3z(pil);
|
||||
u3z(pax);
|
||||
}
|
||||
|
||||
/* u3_pier_stay(): resume the new pier system.
|
||||
@ -2099,25 +2199,27 @@ u3_pier_boot(c3_w wag_w, // config flags
|
||||
void
|
||||
u3_pier_stay(c3_w wag_w, u3_noun pax)
|
||||
{
|
||||
u3_pier* pir_u;
|
||||
// make/load pier
|
||||
//
|
||||
u3_pier* pir_u = u3_pier_create(wag_w, u3r_string(pax));
|
||||
|
||||
/* make/load pier
|
||||
*/
|
||||
pir_u = _pier_boot_make(wag_w, pax, u3_nul);
|
||||
// initialize boot i/o
|
||||
//
|
||||
_pier_loop_init_pier(pir_u);
|
||||
|
||||
/* initialize polling handle
|
||||
*/
|
||||
// initialize polling handle
|
||||
//
|
||||
uv_prepare_init(u3_Host.lup_u, &pir_u->pep_u);
|
||||
uv_prepare_start(&pir_u->pep_u, _pier_loop_prepare);
|
||||
|
||||
_pier_loop_init_pier(pir_u);
|
||||
|
||||
/* initialize loop - move to _pier_boot_make().
|
||||
*/
|
||||
// initialize loop
|
||||
//
|
||||
_pier_loop_init();
|
||||
|
||||
/* XX: _pier_loop_exit() should be called somewhere, but is not.
|
||||
*/
|
||||
// XX: _pier_loop_exit() should be called somewhere, but is not.
|
||||
//
|
||||
|
||||
u3z(pax);
|
||||
}
|
||||
|
||||
/* u3_pier_mark(): mark all Loom allocations in all u3_pier structs.
|
||||
|
@ -872,6 +872,135 @@ _unix_update_mount(u3_pier *pir_u, u3_umon* mon_u, u3_noun all)
|
||||
}
|
||||
}
|
||||
|
||||
/* _unix_initial_update_file(): read file, but don't watch
|
||||
** XX deduplicate with _unix_update_file()
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_initial_update_file(c3_c* pax_c, c3_c* bas_c)
|
||||
{
|
||||
struct stat buf_u;
|
||||
c3_i fid_i = open(pax_c, O_RDONLY, 0644);
|
||||
c3_ws len_ws, red_ws;
|
||||
c3_y* dat_y;
|
||||
|
||||
if ( fid_i < 0 || fstat(fid_i, &buf_u) < 0 ) {
|
||||
if ( ENOENT == errno ) {
|
||||
return u3_nul;
|
||||
}
|
||||
else {
|
||||
uL(fprintf(uH, "error opening initial file %s: %s\r\n",
|
||||
pax_c, strerror(errno)));
|
||||
return u3_nul;
|
||||
}
|
||||
}
|
||||
|
||||
len_ws = buf_u.st_size;
|
||||
dat_y = c3_malloc(len_ws);
|
||||
|
||||
red_ws = read(fid_i, dat_y, len_ws);
|
||||
|
||||
if ( close(fid_i) < 0 ) {
|
||||
uL(fprintf(uH, "error closing initial file %s: %s\r\n",
|
||||
pax_c, strerror(errno)));
|
||||
}
|
||||
|
||||
if ( len_ws != red_ws ) {
|
||||
if ( red_ws < 0 ) {
|
||||
uL(fprintf(uH, "error reading initial file %s: %s\r\n",
|
||||
pax_c, strerror(errno)));
|
||||
}
|
||||
else {
|
||||
uL(fprintf(uH, "wrong # of bytes read in initial file %s: %d %d\r\n",
|
||||
pax_c, len_ws, red_ws));
|
||||
}
|
||||
free(dat_y);
|
||||
return u3_nul;
|
||||
}
|
||||
else {
|
||||
u3_noun pax = _unix_string_to_path_helper(pax_c
|
||||
+ strlen(bas_c)
|
||||
+ 1); /* XX slightly less VERY BAD than before*/
|
||||
u3_noun mim = u3nt(c3__text, u3i_string("plain"), u3_nul);
|
||||
u3_noun dat = u3nt(mim, len_ws, u3i_bytes(len_ws, dat_y));
|
||||
|
||||
free(dat_y);
|
||||
return u3nc(u3nt(pax, u3_nul, dat), u3_nul);
|
||||
}
|
||||
}
|
||||
|
||||
/* _unix_initial_update_dir(): read directory, but don't watch
|
||||
** XX deduplicate with _unix_update_dir()
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c)
|
||||
{
|
||||
u3_noun can = u3_nul;
|
||||
|
||||
DIR* rid_u = opendir(pax_c);
|
||||
if ( !rid_u ) {
|
||||
uL(fprintf(uH, "error opening initial directory: %s: %s\r\n",
|
||||
pax_c, strerror(errno)));
|
||||
return u3_nul;
|
||||
}
|
||||
|
||||
while ( 1 ) {
|
||||
struct dirent ent_u;
|
||||
struct dirent* out_u;
|
||||
c3_w err_w;
|
||||
|
||||
if ( 0 != (err_w = readdir_r(rid_u, &ent_u, &out_u)) ) {
|
||||
uL(fprintf(uH, "error loading initial directory %s: %s\r\n",
|
||||
pax_c, strerror(errno)));
|
||||
c3_assert(0);
|
||||
}
|
||||
else if ( !out_u ) {
|
||||
break;
|
||||
}
|
||||
else if ( '.' == out_u->d_name[0] ) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
c3_c* pox_c = _unix_down(pax_c, out_u->d_name);
|
||||
|
||||
struct stat buf_u;
|
||||
|
||||
if ( 0 != stat(pox_c, &buf_u) ) {
|
||||
uL(fprintf(uH, "initial can't stat %s: %s\r\n",
|
||||
pox_c, strerror(errno)));
|
||||
free(pox_c);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if ( S_ISDIR(buf_u.st_mode) ) {
|
||||
can = u3kb_weld(_unix_initial_update_dir(pox_c, bas_c), can);
|
||||
}
|
||||
else {
|
||||
can = u3kb_weld(_unix_initial_update_file(pox_c, bas_c), can);
|
||||
}
|
||||
free(pox_c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( closedir(rid_u) < 0 ) {
|
||||
uL(fprintf(uH, "error closing initial directory %s: %s\r\n",
|
||||
pax_c, strerror(errno)));
|
||||
}
|
||||
|
||||
return can;
|
||||
}
|
||||
|
||||
/* u3_unix_initial_into_card(): create initial filesystem sync card.
|
||||
*/
|
||||
u3_noun
|
||||
u3_unix_initial_into_card(c3_c* arv_c)
|
||||
{
|
||||
u3_noun can = _unix_initial_update_dir(arv_c, arv_c);
|
||||
|
||||
return u3nc(u3nt(u3_blip, c3__sync, u3_nul),
|
||||
u3nq(c3__into, u3_nul, c3y, can));
|
||||
}
|
||||
|
||||
/* _unix_sign_cb: signal callback.
|
||||
*/
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user