mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Add live reindexing to redbean when zip changes
This commit is contained in:
parent
84001a246c
commit
daa32d27d4
2 changed files with 68 additions and 31 deletions
|
@ -40,9 +40,7 @@ OpenExecutable:
|
||||||
pushq MAP_ANONYMOUS(%rip) # -0x28(%rbp)
|
pushq MAP_ANONYMOUS(%rip) # -0x28(%rbp)
|
||||||
pushq MAP_PRIVATE(%rip) # -0x30(%rbp)
|
pushq MAP_PRIVATE(%rip) # -0x30(%rbp)
|
||||||
pushq MAP_FIXED(%rip) # -0x38(%rbp)
|
pushq MAP_FIXED(%rip) # -0x38(%rbp)
|
||||||
pushq MAP_SHARED(%rip) # -0x40(%rbp)
|
pushq __NR_mprotect(%rip) # -0x40(%rbp)
|
||||||
pushq __NR_mprotect(%rip) # -0x48(%rbp)
|
|
||||||
pushq __NR_mprotect(%rip) # -0x50(%rbp)
|
|
||||||
push %rbx # code buffer
|
push %rbx # code buffer
|
||||||
push %r12 # data buffer
|
push %r12 # data buffer
|
||||||
push %r14 # filename
|
push %r14 # filename
|
||||||
|
@ -98,7 +96,7 @@ OpenExecutable:
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
// Change protection.
|
// Change protection.
|
||||||
mov -0x48(%rbp),%eax # __NR_mprotect
|
mov -0x40(%rbp),%eax # __NR_mprotect
|
||||||
mov %rbx,%rdi
|
mov %rbx,%rdi
|
||||||
mov $PAGESIZE,%esi
|
mov $PAGESIZE,%esi
|
||||||
mov $PROT_READ|PROT_EXEC,%edx
|
mov $PROT_READ|PROT_EXEC,%edx
|
||||||
|
@ -133,7 +131,7 @@ OpenExecutable:
|
||||||
mov $ape_rom_filesz,%esi
|
mov $ape_rom_filesz,%esi
|
||||||
mov $PROT_READ|PROT_EXEC,%edx
|
mov $PROT_READ|PROT_EXEC,%edx
|
||||||
mov -0x38(%rbp),%r10d # MAP_FIXED
|
mov -0x38(%rbp),%r10d # MAP_FIXED
|
||||||
or -0x40(%rbp),%r10d # MAP_SHARED
|
or -0x30(%rbp),%r10d # MAP_PRIVATE
|
||||||
mov %r15d,%r8d
|
mov %r15d,%r8d
|
||||||
mov $ape_rom_offset,%r9d
|
mov $ape_rom_offset,%r9d
|
||||||
push %r9 # openbsd:pad
|
push %r9 # openbsd:pad
|
||||||
|
|
|
@ -241,6 +241,7 @@ static struct Assets {
|
||||||
static struct Shared {
|
static struct Shared {
|
||||||
int workers;
|
int workers;
|
||||||
long double nowish;
|
long double nowish;
|
||||||
|
long double lastreindex;
|
||||||
long double lastmeltdown;
|
long double lastmeltdown;
|
||||||
char currentdate[32];
|
char currentdate[32];
|
||||||
struct rusage server;
|
struct rusage server;
|
||||||
|
@ -318,6 +319,7 @@ static struct Shared {
|
||||||
long readresets;
|
long readresets;
|
||||||
long readtimeouts;
|
long readtimeouts;
|
||||||
long redirects;
|
long redirects;
|
||||||
|
long reindexes;
|
||||||
long reloads;
|
long reloads;
|
||||||
long rewrites;
|
long rewrites;
|
||||||
long serveroptions;
|
long serveroptions;
|
||||||
|
@ -379,13 +381,14 @@ static uint32_t clientaddrsize;
|
||||||
static lua_State *L;
|
static lua_State *L;
|
||||||
static size_t zsize;
|
static size_t zsize;
|
||||||
static char *content;
|
static char *content;
|
||||||
static uint8_t *cdir;
|
|
||||||
static uint8_t *zmap;
|
static uint8_t *zmap;
|
||||||
|
static uint8_t *zcdir;
|
||||||
static size_t hdrsize;
|
static size_t hdrsize;
|
||||||
static size_t msgsize;
|
static size_t msgsize;
|
||||||
static size_t amtread;
|
static size_t amtread;
|
||||||
static char *extrahdrs;
|
static char *extrahdrs;
|
||||||
static char *luaheaderp;
|
static char *luaheaderp;
|
||||||
|
static const char *zpath;
|
||||||
static const char *brand;
|
static const char *brand;
|
||||||
static const char *pidpath;
|
static const char *pidpath;
|
||||||
static const char *logpath;
|
static const char *logpath;
|
||||||
|
@ -408,6 +411,7 @@ static struct Url url;
|
||||||
static struct HttpRequest msg;
|
static struct HttpRequest msg;
|
||||||
static char slashpath[PATH_MAX];
|
static char slashpath[PATH_MAX];
|
||||||
|
|
||||||
|
static struct stat zst;
|
||||||
static long double startread;
|
static long double startread;
|
||||||
static long double lastrefresh;
|
static long double lastrefresh;
|
||||||
static long double startserver;
|
static long double startserver;
|
||||||
|
@ -1415,12 +1419,12 @@ static void IndexAssets(void) {
|
||||||
struct Asset *p;
|
struct Asset *p;
|
||||||
uint32_t i, n, m, step, hash;
|
uint32_t i, n, m, step, hash;
|
||||||
CHECK_GE(HASH_LOAD_FACTOR, 2);
|
CHECK_GE(HASH_LOAD_FACTOR, 2);
|
||||||
CHECK(READ32LE(cdir) == kZipCdir64HdrMagic ||
|
CHECK(READ32LE(zcdir) == kZipCdir64HdrMagic ||
|
||||||
READ32LE(cdir) == kZipCdirHdrMagic);
|
READ32LE(zcdir) == kZipCdirHdrMagic);
|
||||||
n = GetZipCdirRecords(cdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
m = roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR);
|
m = roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR);
|
||||||
p = xcalloc(m, sizeof(struct Asset));
|
p = xcalloc(m, sizeof(struct Asset));
|
||||||
for (cf = GetZipCdirOffset(cdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
||||||
lf = GetZipCfileOffset(zmap + cf);
|
lf = GetZipCfileOffset(zmap + cf);
|
||||||
if (!IsCompressionMethodSupported(ZIP_LFILE_COMPRESSIONMETHOD(zmap + lf))) {
|
if (!IsCompressionMethodSupported(ZIP_LFILE_COMPRESSIONMETHOD(zmap + lf))) {
|
||||||
|
@ -1447,17 +1451,17 @@ static void IndexAssets(void) {
|
||||||
assets.n = m;
|
assets.n = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpenZip(const char *path) {
|
static void OpenZip(void) {
|
||||||
int fd;
|
int fd;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
struct stat st;
|
if (zmap) munmap(zmap, zsize);
|
||||||
CHECK_NE(-1, (fd = open(path, O_RDONLY)));
|
CHECK_NE(-1, (fd = open(zpath, O_RDONLY)));
|
||||||
CHECK_NE(-1, fstat(fd, &st));
|
CHECK_NE(-1, fstat(fd, &zst));
|
||||||
CHECK((zsize = st.st_size));
|
CHECK((zsize = zst.st_size));
|
||||||
CHECK_NE(MAP_FAILED,
|
CHECK_NE(MAP_FAILED,
|
||||||
(zmap = mmap(NULL, zsize, PROT_READ, MAP_SHARED, fd, 0)));
|
(zmap = mmap(NULL, zsize, PROT_READ, MAP_SHARED, fd, 0)));
|
||||||
CHECK_NOTNULL((cdir = GetZipCdir(zmap, zsize)));
|
CHECK_NOTNULL((zcdir = GetZipCdir(zmap, zsize)));
|
||||||
if (endswith(path, ".com.dbg") && (p = memmem(zmap, zsize, "MZqFpD", 6))) {
|
if (endswith(zpath, ".com.dbg") && (p = memmem(zmap, zsize, "MZqFpD", 6))) {
|
||||||
zsize -= p - zmap;
|
zsize -= p - zmap;
|
||||||
zmap = p;
|
zmap = p;
|
||||||
}
|
}
|
||||||
|
@ -2080,11 +2084,11 @@ td { padding-right: 3em; }\r\n\
|
||||||
"<hr>\r\n"
|
"<hr>\r\n"
|
||||||
"</header>\r\n"
|
"</header>\r\n"
|
||||||
"<pre>\r\n",
|
"<pre>\r\n",
|
||||||
strnlen(GetZipCdirComment(cdir), GetZipCdirCommentSize(cdir)),
|
strnlen(GetZipCdirComment(zcdir), GetZipCdirCommentSize(zcdir)),
|
||||||
GetZipCdirComment(cdir));
|
GetZipCdirComment(zcdir));
|
||||||
memset(w, 0, sizeof(w));
|
memset(w, 0, sizeof(w));
|
||||||
n = GetZipCdirRecords(cdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
for (cf = GetZipCdirOffset(cdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
||||||
lf = GetZipCfileOffset(zmap + cf);
|
lf = GetZipCfileOffset(zmap + cf);
|
||||||
path = GetAssetPath(cf, &pathlen);
|
path = GetAssetPath(cf, &pathlen);
|
||||||
|
@ -2095,8 +2099,8 @@ td { padding-right: 3em; }\r\n\
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
n = GetZipCdirRecords(cdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
for (cf = GetZipCdirOffset(cdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
||||||
lf = GetZipCfileOffset(zmap + cf);
|
lf = GetZipCfileOffset(zmap + cf);
|
||||||
path = GetAssetPath(cf, &pathlen);
|
path = GetAssetPath(cf, &pathlen);
|
||||||
|
@ -2299,6 +2303,7 @@ static char *ServeStatusz(void) {
|
||||||
AppendLong1("readresets", shared->readresets);
|
AppendLong1("readresets", shared->readresets);
|
||||||
AppendLong1("readtimeouts", shared->readtimeouts);
|
AppendLong1("readtimeouts", shared->readtimeouts);
|
||||||
AppendLong1("redirects", shared->redirects);
|
AppendLong1("redirects", shared->redirects);
|
||||||
|
AppendLong1("reindexes", shared->reindexes);
|
||||||
AppendLong1("reloads", shared->reloads);
|
AppendLong1("reloads", shared->reloads);
|
||||||
AppendLong1("rewrites", shared->rewrites);
|
AppendLong1("rewrites", shared->rewrites);
|
||||||
AppendLong1("serveroptions", shared->serveroptions);
|
AppendLong1("serveroptions", shared->serveroptions);
|
||||||
|
@ -2507,6 +2512,13 @@ static char *Route(const char *host, size_t hostlen, const char *path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Reindex(void) {
|
||||||
|
LockInc(&shared->reindexes);
|
||||||
|
LOGF("reindexing");
|
||||||
|
OpenZip();
|
||||||
|
IndexAssets();
|
||||||
|
}
|
||||||
|
|
||||||
static const char *LuaCheckPath(lua_State *L, int idx, size_t *pathlen) {
|
static const char *LuaCheckPath(lua_State *L, int idx, size_t *pathlen) {
|
||||||
const char *path;
|
const char *path;
|
||||||
if (lua_isnoneornil(L, idx)) {
|
if (lua_isnoneornil(L, idx)) {
|
||||||
|
@ -3446,8 +3458,8 @@ static int LuaGetZipPaths(lua_State *L) {
|
||||||
size_t i, n, pathlen;
|
size_t i, n, pathlen;
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
i = 0;
|
i = 0;
|
||||||
n = GetZipCdirRecords(cdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
for (cf = GetZipCdirOffset(cdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
||||||
path = GetAssetPath(cf, &pathlen);
|
path = GetAssetPath(cf, &pathlen);
|
||||||
lua_pushlstring(L, path, pathlen);
|
lua_pushlstring(L, path, pathlen);
|
||||||
|
@ -3847,13 +3859,31 @@ static void LuaReload(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleReload(void) {
|
static void HandleReload(void) {
|
||||||
|
LockInc(&shared->reloads);
|
||||||
LOGF("reloading");
|
LOGF("reloading");
|
||||||
|
Reindex();
|
||||||
LuaReload();
|
LuaReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ZipCdirChanged(void) {
|
||||||
|
struct stat st;
|
||||||
|
if (!IsZipCdir32(zmap, zsize, zcdir - zmap) &&
|
||||||
|
!IsZipCdir64(zmap, zsize, zcdir - zmap)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (stat(zpath, &st) != -1 && st.st_ino != zst.st_ino) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void HandleHeartbeat(void) {
|
static void HandleHeartbeat(void) {
|
||||||
if (nowl() - lastrefresh > 60 * 60) RefreshTime();
|
if (nowl() - lastrefresh > 60 * 60) RefreshTime();
|
||||||
UpdateCurrentDate(nowl());
|
UpdateCurrentDate(nowl());
|
||||||
|
if (ZipCdirChanged()) {
|
||||||
|
shared->lastreindex = nowl();
|
||||||
|
kill(0, SIGUSR1);
|
||||||
|
}
|
||||||
getrusage(RUSAGE_SELF, &shared->server);
|
getrusage(RUSAGE_SELF, &shared->server);
|
||||||
#ifndef STATIC
|
#ifndef STATIC
|
||||||
LuaRun("/.heartbeat.lua");
|
LuaRun("/.heartbeat.lua");
|
||||||
|
@ -4344,6 +4374,10 @@ static void HandleMessages(void) {
|
||||||
LogClose(DescribeClose());
|
LogClose(DescribeClose());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (invalidated) {
|
||||||
|
HandleReload();
|
||||||
|
invalidated = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (msgsize == amtread) {
|
if (msgsize == amtread) {
|
||||||
amtread = 0;
|
amtread = 0;
|
||||||
|
@ -4363,6 +4397,10 @@ static void HandleMessages(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CollectGarbage();
|
CollectGarbage();
|
||||||
|
if (invalidated) {
|
||||||
|
HandleReload();
|
||||||
|
invalidated = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4485,7 +4523,7 @@ static void TuneSockets(void) {
|
||||||
setsockopt(server, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
setsockopt(server, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RestoreApe(const char *prog) {
|
static void RestoreApe(void) {
|
||||||
char *p;
|
char *p;
|
||||||
size_t n;
|
size_t n;
|
||||||
struct Asset *a;
|
struct Asset *a;
|
||||||
|
@ -4493,7 +4531,7 @@ static void RestoreApe(const char *prog) {
|
||||||
if (IsWindows()) return; /* TODO */
|
if (IsWindows()) return; /* TODO */
|
||||||
if (IsOpenbsd()) return; /* TODO */
|
if (IsOpenbsd()) return; /* TODO */
|
||||||
if (IsNetbsd()) return; /* TODO */
|
if (IsNetbsd()) return; /* TODO */
|
||||||
if (endswith(prog, ".com.dbg")) return;
|
if (endswith(zpath, ".com.dbg")) return;
|
||||||
close(OpenExecutable());
|
close(OpenExecutable());
|
||||||
if ((a = GetAssetZip("/.ape", 5)) && (p = LoadAsset(a, &n))) {
|
if ((a = GetAssetZip("/.ape", 5)) && (p = LoadAsset(a, &n))) {
|
||||||
mprotect(ape_rom_vaddr, PAGESIZE, PROT_READ | PROT_WRITE);
|
mprotect(ape_rom_vaddr, PAGESIZE, PROT_READ | PROT_WRITE);
|
||||||
|
@ -4506,7 +4544,7 @@ static void RestoreApe(const char *prog) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RedBean(int argc, char *argv[], const char *prog) {
|
void RedBean(int argc, char *argv[]) {
|
||||||
uint32_t addrsize;
|
uint32_t addrsize;
|
||||||
gmtoff = GetGmtOffset((lastrefresh = startserver = nowl()));
|
gmtoff = GetGmtOffset((lastrefresh = startserver = nowl()));
|
||||||
CHECK_GT(CLK_TCK, 0);
|
CHECK_GT(CLK_TCK, 0);
|
||||||
|
@ -4514,9 +4552,10 @@ void RedBean(int argc, char *argv[], const char *prog) {
|
||||||
(shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), FRAMESIZE),
|
(shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), FRAMESIZE),
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
|
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
|
||||||
-1, 0)));
|
-1, 0)));
|
||||||
OpenZip(prog);
|
zpath = (const char *)getauxval(AT_EXECFN);
|
||||||
|
OpenZip();
|
||||||
IndexAssets();
|
IndexAssets();
|
||||||
RestoreApe(prog);
|
RestoreApe();
|
||||||
SetDefaults();
|
SetDefaults();
|
||||||
GetOpts(argc, argv);
|
GetOpts(argc, argv);
|
||||||
LuaInit();
|
LuaInit();
|
||||||
|
@ -4603,6 +4642,6 @@ int main(int argc, char *argv[]) {
|
||||||
setenv("GDB", "", true);
|
setenv("GDB", "", true);
|
||||||
showcrashreports();
|
showcrashreports();
|
||||||
}
|
}
|
||||||
RedBean(argc, argv, (const char *)getauxval(AT_EXECFN));
|
RedBean(argc, argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue