Merge pull request 'kernel: v4 waits for a key in arch_halt(), not a spin (#151); Try it deployed' (#153) from StarForth-v4.0.0 into master
This commit was merged in pull request #153.
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# Deploying "Try it" on the server
|
||||
|
||||
The public demo: each visitor gets a StarshipOS machine of their own in the browser, resumed at
|
||||
Zuse's prompt, gone when they leave. Two at a time on today's server (384 MiB each); a third visitor
|
||||
is told every machine is busy and to try back in a few minutes. Issues #115, #116, #117.
|
||||
|
||||
Run as root on the server, **after PR #148 is merged** (it carries the 384 MiB guests and the busy
|
||||
message), **while CI is idle** (each step that boots QEMU boots one, in the foreground).
|
||||
|
||||
## 1. The checkout and what the build needs (~15 min)
|
||||
|
||||
```bash
|
||||
apt-get install -y ttyd qemu-system-x86 ovmf python3 git
|
||||
git clone https://gitea.starshipos-f18.org/rajames/LithosAnanke.git /opt/starshipos-demo
|
||||
cd /opt/starshipos-demo
|
||||
git checkout master # after #148: alpha.3's kernel, and the demo's limits
|
||||
make ARCH=amd64 init INIT_DOCS=0 INIT_PROOFS=0 # amd64 only: no docs, no Isabelle
|
||||
```
|
||||
|
||||
Master after #148 is the `v4.0.0-alpha.3` kernel unchanged, plus #148's scripts.
|
||||
|
||||
## 2. The demo's own Zuse (~3 min, two QEMU boots)
|
||||
|
||||
```bash
|
||||
demo/mint-zuse.sh /var/lib/starshipos-demo-zuse
|
||||
ls -la /var/lib/starshipos-demo-zuse/zusestick.img # the stick every session attaches
|
||||
```
|
||||
|
||||
Never anyone's real Zuse: minted for the demo (#111), its writes discarded in every session.
|
||||
|
||||
## 3. The image and the saved machine (~2 min, one QEMU boot)
|
||||
|
||||
```bash
|
||||
demo/build-iso.sh /tmp/StarshipOS.iso
|
||||
DEMO_PROMPT='[zuse@Hera]' demo/make-snapshot.sh /tmp/StarshipOS.iso /var/lib/starshipos-demo \
|
||||
/var/lib/starshipos-demo-zuse/zusestick.img
|
||||
ls -la /var/lib/starshipos-demo/ # StarshipOS.iso identity.img vars.fd state
|
||||
```
|
||||
|
||||
The saved machine belongs to this image, this QEMU and 384 MiB: re-run step 3 after any of them
|
||||
changes. Sessions already running keep theirs.
|
||||
|
||||
## 4. The service (~5 min)
|
||||
|
||||
Ubuntu's `ttyd` package starts its own `ttyd.service`, which runs **`login` on port 7681** -- our
|
||||
port. Left running, it takes the port, and Apache hands visitors the server's own login prompt
|
||||
(found 2026-11-08, after step 5). Disable it first:
|
||||
|
||||
```bash
|
||||
systemctl disable --now ttyd # the package's service: a login prompt on 7681
|
||||
useradd --system --home /var/lib/starshipos-demo --shell /usr/sbin/nologin starshipos-demo
|
||||
chown -R starshipos-demo: /var/lib/starshipos-demo
|
||||
cp demo/starshipos-demo.service /etc/systemd/system/
|
||||
systemctl daemon-reload && systemctl enable --now starshipos-demo
|
||||
systemctl status starshipos-demo --no-pager | head -5
|
||||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:7681/ # 200: ttyd answers
|
||||
ss -ltnp | grep 7681 # the ttyd of starshipos-demo, nothing else
|
||||
```
|
||||
|
||||
The service expects the checkout's `demo/` at `/opt/starshipos-demo/demo` (step 1 put it there).
|
||||
|
||||
## 5. TLS and Apache for try.starshipos-f18.com (~10 min)
|
||||
|
||||
DNS: `try.starshipos-f18.com` must point at this server (an A record) before certbot.
|
||||
|
||||
```bash
|
||||
a2enmod proxy proxy_http proxy_wstunnel headers ssl rewrite
|
||||
certbot certonly --apache -d try.starshipos-f18.com
|
||||
cp demo/apache-demo.conf /etc/apache2/sites-available/starshipos-demo.conf
|
||||
a2ensite starshipos-demo && apachectl configtest && systemctl reload apache2
|
||||
curl -sI https://try.starshipos-f18.com/ | head -3 # 200, its own certificate
|
||||
```
|
||||
|
||||
`apache-demo.conf` lets only the .com frame the terminal (`frame-ancestors`).
|
||||
|
||||
## 6. The check (done 2026-11-08)
|
||||
|
||||
From outside: a session ready 1.5 s after the page opens; `3 4 + .` answers `7 ok`, `: SQUARE DUP *
|
||||
; 7 SQUARE .` answers `49 ok`; a third visitor at once is told every machine is busy. The
|
||||
certificate is try.starshipos-f18.com's own (Let's Encrypt), and only the .com may frame it.
|
||||
|
||||
## 7. Tell Claude
|
||||
|
||||
Then I check from outside: a session reaches `[zuse@Hera] ok>`, `3 4 + .` answers `7 ok`, a third
|
||||
visitor gets the busy message, and the .com's Try it page shows the console. Then the "Try it" link
|
||||
goes into the .com's navigation (#117).
|
||||
|
||||
## If something goes wrong
|
||||
|
||||
- `journalctl -u starshipos-demo -n 50` -- ttyd and the sessions
|
||||
- A session that ends at once: the saved machine does not match (re-run step 3)
|
||||
- Memory: `free -h` -- a session's QEMU holds ~150 MB of its 384 MiB guest; two at most
|
||||
(`DEMO_MAX_GUESTS` in the service)
|
||||
- CPU: an idle guest keeps a host core busy (the kernel's idle loop polls -- its own issue), so the
|
||||
service caps all sessions together at one core (`CPUQuota=100%`, `Nice=19`). After changing the
|
||||
service file: `systemctl daemon-reload && systemctl restart starshipos-demo`
|
||||
+2
-1
@@ -20,7 +20,8 @@ XWiki "Try it" page (iframe) -> Apache: TLS, websocket -> ttyd -> start-session.
|
||||
| `start-session.sh` | One visitor's session: resumes the saved machine, ends it on hang-up, close or time-out (#112) |
|
||||
| `console.py` | Joins the visitor's terminal to the machine only once it runs, discarding keys typed while it loads |
|
||||
| `qemu-args.sh` | The machine, shared by the two above: a resumed machine must match the saved one exactly |
|
||||
| `starshipos-demo.service` | ttyd as a systemd service, on localhost, at most 3 sessions (#114) |
|
||||
| `starshipos-demo.service` | ttyd as a systemd service, on localhost; two guests at once, a busy message for the rest (#114, #116) |
|
||||
| `DEPLOY.md` | Putting it on the server, step by step |
|
||||
| `apache-demo.conf` | Example vhost: TLS, the websocket, framing allowed for the `.com` only (#115) |
|
||||
| `xwiki-try-it.xwiki` | The "Try it" page, its own page on the `.com` XWiki (`TryIt`), in the landing page's style |
|
||||
|
||||
|
||||
@@ -30,8 +30,14 @@ ProtectHome=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ReadOnlyPaths=/var/lib/starshipos-demo
|
||||
MemoryMax=4G
|
||||
CPUQuota=300%
|
||||
# Sized for this server (3.8 GiB, both wikis, Gitea, Nexus, CI): an idle StarshipOS guest keeps a
|
||||
# host core busy -- the kernel's idle loop polls (measured 2026-11-08: 100% of a core at the
|
||||
# prompt, 148 MiB resident) -- so all sessions together get one core at the lowest priority, and
|
||||
# the wikis and Gitea never starve; with two visitors each runs at half speed. 1 GiB holds two
|
||||
# sessions with room. Raise both with the server (8 GB: MemoryMax=2G, CPUQuota=200%).
|
||||
MemoryMax=1G
|
||||
CPUQuota=100%
|
||||
Nice=19
|
||||
TasksMax=200
|
||||
|
||||
[Install]
|
||||
|
||||
@@ -6243,3 +6243,39 @@ review list begun meanwhile goes to the milestone v4.0.0-alpha.4.
|
||||
- With both wikis up again (Shenandoah, the .com's heap at 512 MiB, the .org's given 256 more): the
|
||||
server at 2.6 of 3.8 GiB used, 1.2 GiB available, 2 GiB of swap used; Build 204 (three images, the
|
||||
v4 tests) passed alongside them.
|
||||
|
||||
### 4. Try it, deployed (2026-11-08)
|
||||
|
||||
Captain Bob ran `demo/DEPLOY.md` on the server (#115): try.starshipos-f18.com with its own Let's
|
||||
Encrypt certificate, ttyd behind Apache, framing allowed to the .com alone. Checked from outside: a
|
||||
session ready 1.5 s after the page opens, `3 4 + .` -> `7 ok`, `: SQUARE DUP * ; 7 SQUARE .` ->
|
||||
`49 ok`, a third visitor at once told every machine is busy.
|
||||
|
||||
Found on the way:
|
||||
- Ubuntu's `ttyd` package starts its own `ttyd.service` -- `login` on port 7681, ours -- and
|
||||
until it was disabled the page served the server's login prompt to anyone. `DEPLOY.md` step 4
|
||||
now disables it first and checks what listens on 7681.
|
||||
- **An idle StarshipOS keeps a host core 100% busy** (#151): the demo machine at its prompt, idle
|
||||
20 s, QEMU at 100% of a core, 148 MiB resident -- the kernel's idle loop polls, never halts. Two
|
||||
visitors' sessions with Gitea's diff statistics on a burst of pushes (#152, 1.75 GiB) filled the
|
||||
server's swap and stalled both wikis. The service now caps all sessions together at one core at
|
||||
the lowest priority (`CPUQuota=100%`, `Nice=19`, `MemoryMax=1G`), until #151 is fixed.
|
||||
- **Try it in the .com's navigation** (#117): "Try it" added to the canvas's Home and Inquiries
|
||||
artboards, the .com rebuilt from them (`site/com`) and installed. Checked as a visitor: the home
|
||||
page, the "Try it" link, the Try it page in 1.1 s, its framed console Ready.
|
||||
|
||||
### 5. #151: the idle loop halts (2026-11-08)
|
||||
|
||||
Ruled (Captain Bob): "Fix the kernel problem." The v4 system waited for a key -- `sk_v4_readline()`
|
||||
with nothing typed, and `sk_v4_identity_wait()` headless until Zuse -- in `arch_relax()`, a spin.
|
||||
Both now wait in `arch_halt()` (`hlt` on amd64, `wfi` on aarch64 and riscv64) until the next
|
||||
interrupt: the heartbeat's timer, which is ISR-driven on all three (`heartbeat_tick()`), wakes them
|
||||
at 100 Hz, so a key is seen within a tick, as the cursor's blink and the identity beat already
|
||||
were. v3's REPL (`repl.c`) still spins; v3 is not in acceptance.
|
||||
|
||||
Verified: idle at Zuse's prompt for 20 s, QEMU's CPU **100% -> 1%** of a core on amd64 (the demo
|
||||
machine), and **1%** on aarch64 and riscv64 (`logs/20261108-011614`, `-011931`); the acceptance
|
||||
protocol passes -- amd64 `logs/20261108-005539`, aarch64 `-005753`, riscv64 `-010136`, POST
|
||||
538/538, `dict_hash 0xfec8c47cfc6f437f` on all three, `7 ok` typed and answered; the stick loaded
|
||||
high; `test-32` (39 programs, 0 failures). The demo's CPU cap (`CPUQuota=100%`) can be relaxed
|
||||
once this reaches the server.
|
||||
|
||||
@@ -113,7 +113,11 @@ static int sk_v4_readline(void)
|
||||
} else {
|
||||
heartbeat_service();
|
||||
}
|
||||
arch_relax();
|
||||
/* Nothing typed: wait for the next interrupt, not in a spin (#151 -- the spin kept a
|
||||
* CPU core 100% busy at the prompt, and the demo's host with it). The heartbeat's
|
||||
* timer wakes it at 100 Hz, so a key is seen within a tick, as the blink and the
|
||||
* identity beat are. */
|
||||
arch_halt();
|
||||
continue;
|
||||
}
|
||||
if (c == '\r' || c == '\n') {
|
||||
|
||||
@@ -331,7 +331,7 @@ void sk_v4_identity_wait(void)
|
||||
while (!g_zuse_session) {
|
||||
sk_v4_discard_input();
|
||||
sk_v4_identity_beat();
|
||||
arch_relax();
|
||||
arch_halt(); /* headless, until Zuse: wait for the next tick, not a spin (#151) */
|
||||
}
|
||||
sk_v4_discard_input();
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -32,6 +32,7 @@ html, body, #xwikimaincontainer, #xwikimaincontainerinner, #contentcontainer, #c
|
||||
<a href="/bin/view/Main/" style="font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 22px; color: #EEF2F7 !important; text-decoration: none; letter-spacing: 0.02em">starship<span style="color: #F5891F !important">OS</span></a>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 24px; font-size: 14px">
|
||||
<a href="/bin/view/Main/" style="color: #C8D1DE !important; text-decoration: none">Home</a>
|
||||
<a href="/bin/view/TryIt/" style="color: #C8D1DE !important; text-decoration: none">Try it</a>
|
||||
<a href="/bin/view/Inquiries/" aria-current="page" style="color: #EEF2F7 !important; text-decoration: none; border-bottom: 2px solid #F5891F !important">Inquiries</a>
|
||||
<a href="https://starshipos-f18.org/" style="color: #F5891F !important; text-decoration: none">Contributors →</a>
|
||||
</div>
|
||||
|
||||
@@ -34,6 +34,7 @@ html, body, #xwikimaincontainer, #xwikimaincontainerinner, #contentcontainer, #c
|
||||
<a href="#system" style="color: #C8D1DE !important; text-decoration: none">System</a>
|
||||
<a href="#research" style="color: #C8D1DE !important; text-decoration: none">Research</a>
|
||||
<a href="#silicon" style="color: #C8D1DE !important; text-decoration: none">Silicon</a>
|
||||
<a href="/bin/view/TryIt/" style="color: #C8D1DE !important; text-decoration: none">Try it</a>
|
||||
<a href="/bin/view/Inquiries/" style="color: #C8D1DE !important; text-decoration: none">Inquiries</a>
|
||||
<a href="https://starshipos-f18.org/" style="color: #F5891F !important; text-decoration: none">Contributors →</a>
|
||||
</div>
|
||||
|
||||
@@ -22,6 +22,7 @@ a{color:#F5891F}a:hover{color:#FFB061}
|
||||
<a href="Main.dc.html" style="font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 22px; color: #EEF2F7; text-decoration: none; letter-spacing: 0.02em">starship<span style="color: {{accent}}">OS</span></a>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 24px; font-size: 14px">
|
||||
<a href="Main.dc.html" style="color: #C8D1DE; text-decoration: none">Home</a>
|
||||
<a href="TryIt.dc.html" style="color: #C8D1DE; text-decoration: none">Try it</a>
|
||||
<a href="Inquiries.dc.html" aria-current="page" style="color: #EEF2F7; text-decoration: none; border-bottom: 2px solid {{accent}}">Inquiries</a>
|
||||
<a href="https://starshipos.org" style="color: {{accent}}; text-decoration: none">Contributors →</a>
|
||||
</div>
|
||||
|
||||
@@ -24,6 +24,7 @@ a{color:#F5891F}a:hover{color:#FFB061}
|
||||
<a href="#system" style="color: #C8D1DE; text-decoration: none">System</a>
|
||||
<a href="#research" style="color: #C8D1DE; text-decoration: none">Research</a>
|
||||
<a href="#silicon" style="color: #C8D1DE; text-decoration: none">Silicon</a>
|
||||
<a href="TryIt.dc.html" style="color: #C8D1DE; text-decoration: none">Try it</a>
|
||||
<a href="Inquiries.dc.html" style="color: #C8D1DE; text-decoration: none">Inquiries</a>
|
||||
<a href="https://starshipos.org" style="color: {{accent}}; text-decoration: none">Contributors →</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user