Anatomi Masalah: Daemon Persisten di Ruang Produksi
TEXT
+-----------------------------------------------------------+
| Host Linux Database |
| |
| +-------------------+ +------------------------+ |
| | PostgreSQL / | | Codex CLI | |
| | Redis Engine | | (Interaksi Dev/DBA) | |
| +---------+---------+ +-----------+------------+ |
| | | (Trigger) |
| | Memori / Page Cache v |
| | Rebutan Resource +--------------------+ |
| +<---------------------+ codex-daemon | |
| | | (Persisten, Run) | |
| | I/O Bus & Lock +---------+----------+ |
| | Contention | |
| v v |
| +-------------------+ +------------------------+ |
| | NVMe Storage | | External Network Poll | |
| | (WAL / RDB) | | (Auto-Update Check) | |
| +-------------------+ +------------------------+ |
+-----------------------------------------------------------+- Membuka socket UNIX persisten di
/run/user/<uid>/codexd.sock. - Menggunakan SQLite lokal di
~/.codex/state.dbuntuk mencatat metrik status dan jejak audit. - Menjalankan thread pemantauan jaringan yang memicu resolving DNS dan pengunduhan biner bervolume puluhan megabyte ketika versi baru terdeteksi.
- Mengalokasikan heap memory dinamis yang memicu fragmentasi pada memori subsistem Linux.
Dampak Terhadap Storage Engine dan Memory Subsystem
1. Tekanan Copy-on-Write (CoW) pada Redis Fork()
fork() untuk snapshot BGSAVE dan Append Only File (AOF) rewrite. Secara teori kernel Linux, proses anak membagikan ruang alamat memori yang sama dengan proses induk melalui mekanisme Copy-on-Write. Selama memori tidak dimodifikasi, alokasi fisik tidak bertambah.
Ketika codex-daemon aktif, ia secara berkala melakukan pembacaan memori host, pemindaian tabel proses (/proc), dan operasi baca/tulis disk lokal. Pola alokasi memori yang agresif dari runtime daemon ini menyebabkan kernel memicu alokasi page table baru di bawah tekanan memori ketat. Saat Redis melakukan fork(), keberadaan daemon yang aktif mengotori memori bersama dapat memaksa kernel melakukan alokasi fisik seketika, meningkatkan latensi alokasi memori hingga ratusan milidetik dan memperbesar risiko aktivasi OOM (Out Of Memory) Killer pada instance yang beroperasi di ambang kapasitas 85-90% RAM.
2. Kompetisi I/O dan Degradasi PostgreSQL WAL Flush
fsync() pada PostgreSQL WAL tidak boleh mengalami antrean I/O yang panjang. Ketika daemon Codex memutuskan untuk mengunduh biner baru di latar belakang, ia menulis berkas sementara ke disk, mengekstrak arsip, dan melakukan verifikasi checksum. Aktivitas baca-tulis tak terkontrol ini menghabiskan bandwidth I/O lokal serta mengotori dirty pages pada subsistem buffer cache kernel Linux.
Akibatnya, thread PostgreSQL yang mengeksekusi transaksi dengan synchronous_commit = on akan terhenti pada status tunggu WALWriteLock karena antrean blok I/O (blk-mq) pada perangkat NVMe tersumbat oleh operasi tulis biner pembaruan Codex CLI.
Audit dan Rekonstruksi Syscall Daemon
strace dan perf.
Jalankan perintah audit berikut pada node target:
BASH
# Memeriksa layanan systemd user yang berjalan di luar sesi login interaktif
systemctl --user list-units --type=service --state=running
# Memeriksa socket dan proses biner codex yang aktif
ss -xlp | grep codex
ps aux | grep -E 'codex|codexd'codexd aktif, kita dapat merekam aktivitas pembaruan otomatis dan manipulasi I/O menggunakan perf atau strace:
BASH
# Melacak syscall file I/O dan network socket secara non-intrusif
sudo strace -f -p $(pgrep codexd) -e trace=file,network,process -TTEXT
[pid 18241] 10:14:02.120491 connect(7, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr('104.18.22.45')}, 16) = -1 EINPROGRESS
[pid 18241] 10:14:02.310112 openat(AT_FDCWD, '/home/deployer/.codex/state.db-wal', O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 9 <0.000412>
[pid 18241] 10:14:02.310890 fdatasync(9) = 0 <0.008431>
[pid 18241] 10:14:05.412891 openat(AT_FDCWD, '/home/deployer/.codex/tmp/update_x86_64.tar.gz', O_WRONLY|O_CREAT|O_TRUNC, 0644) = 10 <0.000120>
[pid 18241] 10:14:05.413110 write(10, '...', 65536) = 65536 <0.001890>fdatasync() dan penulisan berkas arsip berulang tersebut terjadi pada disk yang sama dengan partisi data PostgreSQL jika CLI dipasang oleh akun pengguna aplikasi tanpa segmentasi storage khusus.
Perbandingan Karakteristik Resource: Sebelum vs Sesudah Isolasi
| Parameter Metrik | Status: Default Codex Daemon Aktif | Status: Daemon Dinonaktifkan / Diisolasi | Dampak Sistemik |
|---|---|---|---|
| Memory Footprint Daemon | 185 MB - 420 MB (RSS) | 0 MB (Inaktif) | Menghilangkan kebocoran heap tak terduga |
| Fluktuasi CoW Memory (Redis) | Puncak kenaikan 1.8 GB saat BGSAVE | Stabil di ~220 MB saat BGSAVE | Mengurangi risiko aktivasi OOM Killer |
| Max Disk Latency (NVMe fsync) | 28.4 ms (Lonjakan saat update) | 0.85 ms (Stabil) | Mengeliminasi lonjakan latensi commit |
| PostgreSQL WALWriteLock Waits | 142 kejadian / 10 menit | < 2 kejadian / 10 menit | Mencegah transaksi menggantung (freeze) |
| Latensi Tail P99 Aplikasi | 48.2 ms | 3.1 ms | Peningkatan signifikan stabilitas SLA |
Langkah Remediasi: Eliminasi dan Hardening Isolasi
1. Menonaktifkan Auto-Update dan Daemon Persisten
/etc/environment atau ~/.bashrc) untuk memblokir auto-spawning daemon dan auto-update:
BASH
# Matikan integrasi daemon latar belakang dan pembaruan mandiri
export CODEX_DISABLE_BACKGROUND_DAEMON=1
export CODEX_AUTO_UPDATE=false
export CODEX_TELEMETRY_DISABLED=1
export CODEX_NO_DAEMON=trueBASH
# Matikan unit layanan yang sedang berjalan
systemctl --user stop codex-agent.service codexd.service 2>/dev/null || true
systemctl --user disable codex-agent.service codexd.service 2>/dev/null || true
# Masking unit agar tidak dapat dipanggil kembali oleh skrip apa pun
systemctl --user mask codex-agent.service codexd.service
# Hapus runtime socket yang tertinggal
rm -rf /run/user/$(id -u)/codexd.sock ~/.codex/run/codexd.sock2. Hardening Isolasi Resource Menggunakan Systemd Cgroups v2
systemd-run dengan alokasi batas memori dan pembatasan bobot I/O agar tidak bersinggungan dengan slice database:
BASH
#!/usr/bin/env bash
# Wrapper pengeksekusian perintah database migration dengan batasan cgroups
systemd-run --user --scope \\
--property='MemoryMax=128M' \\
--property='MemoryHigh=96M' \\
--property='IOWeight=20'