u3: replaces u3_serf_uncram with u3u_uncram()

This commit is contained in:
Joe Bryan 2020-08-25 17:45:17 -07:00
parent 24b91af888
commit dd8a74cea2
5 changed files with 185 additions and 90 deletions

View File

@ -11,3 +11,7 @@
*/
c3_o
u3u_cram(c3_c* dir_c, c3_d eve_d);
/* u3u_uncram(): restore persistent state from a rock.
*/
c3_o
u3u_uncram(c3_c* dir_c, c3_d eve_d);

View File

@ -24,11 +24,6 @@
u3_noun
u3_serf_init(u3_serf* sef_u);
/* u3_serf_uncram(): initialize from rock at [eve_d].
*/
void
u3_serf_uncram(u3_serf* sef_u, c3_d eve_d);
/* u3_serf_writ(): apply writ [wit], producing plea [*pel] on c3y.
*/
c3_o

View File

@ -444,6 +444,34 @@ u3u_uniq(void)
ur_hcon_free(rot_u);
}
/* _cu_rock_path(): format rock path.
*/
static c3_o
_cu_rock_path(c3_c* dir_c, c3_d eve_d, c3_c** out_c)
{
c3_w nam_w = 1 + snprintf(0, 0, "%s/.urb/roc/%" PRIu64 ".jam", dir_c, eve_d);
c3_c* nam_c = c3_malloc(nam_w);
c3_i ret_i;
ret_i = snprintf(nam_c, nam_w, "%s/.urb/roc/%" PRIu64 ".jam", dir_c, eve_d);
if ( ret_i < 0 ) {
fprintf(stderr, "rock: path format failed (%s, %" PRIu64 "): %s\r\n",
dir_c, eve_d, strerror(errno));
c3_free(nam_c);
return c3n;
}
else if ( ret_i >= nam_w ) {
fprintf(stderr, "rock: path format failed (%s, %" PRIu64 "): truncated\r\n",
dir_c, eve_d);
c3_free(nam_c);
return c3n;
}
*out_c = nam_c;
return c3y;
}
/* _cu_rock_path_make(): format rock path, creating directory if necessary..
*/
static c3_o
@ -628,3 +656,136 @@ u3u_cram(c3_c* dir_c, c3_d eve_d)
return ret_o;
}
/* _cu_rock_load(): load a rock into a byte buffer.
*/
static c3_o
_cu_rock_load(c3_c* dir_c, c3_d eve_d, c3_d* out_d, c3_y** out_y)
{
c3_i fid_i;
c3_d len_d;
// open rock file
//
{
c3_c* nam_c;
if ( c3n == _cu_rock_path(dir_c, eve_d, &nam_c) ) {
return c3n;
}
if ( -1 == (fid_i = open(nam_c, O_RDONLY, 0644)) ) {
fprintf(stderr, "rock: open failed (%s, %" PRIu64 "): %s\r\n",
dir_c, eve_d, strerror(errno));
c3_free(nam_c);
return c3n;
}
c3_free(nam_c);
}
// measure rock file
//
{
struct stat buf_b;
if ( -1 == fstat(fid_i, &buf_b) ) {
fprintf(stderr, "rock: stat failed (%s, %" PRIu64 "): %s\r\n",
dir_c, eve_d, strerror(errno));
close(fid_i);
return c3n;
}
len_d = buf_b.st_size;
}
// mmap rock file
//
{
void* ptr_v;
if ( MAP_FAILED == (ptr_v = mmap(0, len_d, PROT_READ, MAP_SHARED, fid_i, 0)) ) {
fprintf(stderr, "rock: mmap failed (%s, %" PRIu64 "): %s\r\n",
dir_c, eve_d, strerror(errno));
close(fid_i);
return c3n;
}
*out_d = len_d;
*out_y = (c3_y*)ptr_v;
}
close(fid_i);
return c3y;
}
/* u3u_uncram(): restore persistent state from a rock.
*/
c3_o
u3u_uncram(c3_c* dir_c, c3_d eve_d)
{
c3_d len_d;
c3_y* byt_y;
// load rock file into buffer
//
if ( c3n == _cu_rock_load(dir_c, eve_d, &len_d, &byt_y) ) {
return c3n;
}
// bypassing page tracking as an optimization
//
// NB: u3e_yolo() will mark all as dirty, and
// u3e_save() will reinstate protection flags
//
if ( c3n == u3e_yolo() ) {
fprintf(stderr, "uncram: unable to bypass page tracking, continuing\r\n");
}
// reinitialize loom
//
// NB: hot jet state is not yet re-established
//
u3m_pave(c3y, c3n);
// cue rock, restore persistent state
//
// XX errors are fatal, barring a full "u3m_reboot"-type operation.
//
{
u3_noun roc, cod, ref = u3s_cue_xeno(len_d, byt_y);
if ( u3r_pq(ref, c3__fast, &roc, &cod) ) {
u3z(ref);
fprintf(stderr, "uncram: failed: invalid rock format\r\n");
exit(1);
}
u3A->roc = u3k(roc);
u3j_load(u3k(cod));
u3z(ref);
}
// allocate new hot jet state; re-establish warm
//
u3j_boot(c3y);
u3j_ream();
// restore event number
//
u3A->ent_d = eve_d;
// mark all pages dirty
//
u3e_foul();
// leave rocks on disk
//
// if ( c3n == u3m_rock_drop(dir_c, eve_d) ) {
// u3l_log("serf: warning: orphaned state file\r\n");
// }
return c3y;
}

View File

@ -189,7 +189,12 @@ _cw_serf_commence(c3_i argc, c3_c* argv[])
u3V.sen_d = u3V.dun_d = u3m_boot(dir_c);
if ( eve_d ) {
u3_serf_uncram(&u3V, eve_d);
// XX need not be fatal, need a u3m_reboot equivalent
//
if ( c3n == u3u_uncram(u3V.dir_c, eve_d) ) {
fprintf(stderr, "serf (%" PRIu64 "): rock load failed\r\n", eve_d);
exit(1);
}
}
}
@ -292,7 +297,12 @@ _cw_queu(c3_i argc, c3_c* argv[])
memset(&u3V, 0, sizeof(u3V));
u3V.dir_c = strdup(dir_c);
u3V.sen_d = u3V.dun_d = u3m_boot(dir_c);
u3_serf_uncram(&u3V, eve_d);
if ( c3n == u3u_uncram(dir_c, eve_d) ) {
fprintf(stderr, "urbit-worker: queu: failed\r\n");
exit(1);
}
u3e_save();
fprintf(stderr, "urbit-worker: queu: rock loaded at event %" PRIu64 "\r\n", eve_d);

View File

@ -277,27 +277,6 @@ u3_serf_grab(void)
fflush(stderr);
}
/* _serf_cram(): deduplicate and compact memory. ORPHANED
*/
static void
_serf_cram(u3_serf* sef_u)
{
u3_serf_grab();
u3l_log("serf (%" PRIu64 "): compacting loom\r\n", sef_u->dun_d);
if ( c3n == u3m_rock_stay(sef_u->dir_c, sef_u->dun_d) ) {
u3l_log("serf: unable to jam state\r\n");
return;
}
u3_serf_uncram(sef_u, sef_u->dun_d);
u3l_log("serf (%" PRIu64 "): compacted loom\r\n", sef_u->dun_d);
u3_serf_grab();
}
/* u3_serf_post(): update serf state post-writ.
*/
void
@ -971,11 +950,18 @@ u3_serf_live(u3_serf* sef_u, u3_noun com, u3_noun* ret)
u3l_log("serf (%" PRIu64 "): saving rock\r\n", sef_u->dun_d);
if ( c3n == u3m_rock_stay(sef_u->dir_c, eve_d) ) {
if ( c3n == u3u_cram(sef_u->dir_c, eve_d) ) {
fprintf(stderr, "serf (%" PRIu64 "): unable to jam state\r\n", eve_d);
return c3n;
}
if ( u3r_mug(u3A->roc) != sef_u->mug_l ) {
fprintf(stderr, "serf (%" PRIu64 "): mug mismatch 0x%08x 0x%08x\r\n",
eve_d, sef_u->mug_l, u3r_mug(u3A->roc));
return c3n;
}
u3e_save();
u3_serf_grab();
*ret = u3nc(c3__live, u3_nul);
@ -1120,67 +1106,6 @@ _serf_ripe(u3_serf* sef_u)
return u3nc(u3i_chubs(1, &sef_u->dun_d), sef_u->mug_l);
}
/* u3_serf_uncram(): initialize from rock at [eve_d].
*/
void
u3_serf_uncram(u3_serf* sef_u, c3_d eve_d)
{
c3_o roc_o;
c3_c nam_c[8193];
snprintf(nam_c, 8192, "%s/.urb/roc/%" PRIu64 ".jam", sef_u->dir_c, eve_d);
struct stat buf_b;
c3_i fid_i = open(nam_c, O_RDONLY, 0644);
if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) {
fprintf(stderr, "serf: rock: %s not found\r\n", nam_c);
roc_o = c3n;
}
else {
fprintf(stderr, "serf: rock: %s found\r\n", nam_c);
roc_o = c3y;
}
close(fid_i);
if ( c3y == roc_o ) {
if ( c3n == u3e_hold() ) {
fprintf(stderr, "serf: unable to backup checkpoint\r\n");
}
else {
u3m_wipe();
if ( c3n == u3m_rock_load(sef_u->dir_c, eve_d) ) {
fprintf(stderr, "serf: compaction failed, restoring checkpoint\r\n");
if ( c3n == u3e_fall() ) {
fprintf(stderr, "serf: unable to restore checkpoint\r\n");
c3_assert(0);
}
}
if ( c3n == u3e_drop() ) {
fprintf(stderr, "serf: warning: orphaned backup checkpoint file\r\n");
}
// leave rocks on disk
//
// if ( c3n == u3m_rock_drop(sef_u->dir_c, sef_u->dun_d) ) {
// u3l_log("serf: warning: orphaned state file\r\n");
// }
fprintf(stderr, "serf (%" PRIu64 "): compacted loom\r\n", eve_d);
sef_u->sen_d = sef_u->dun_d = eve_d;
// save now for flexibility
//
u3e_save();
}
}
}
/* u3_serf_init(): init or restore, producing status.
*/
u3_noun