Skip to main content
Deutsch  •  English  •  Español  •  Français  •  Italiano  •  Polska  •  Portuguese  •  Български  •  Русский  •  Українська  •  やまと  •  中国  •  فارsi

🦾 Il braccio in C: il modulo oa

Se coa è la mente che disegna il piano di volo, il binario oa ("uova") è il braccio che lo esegue. È deliberatamente minuscolo — poche centinaia di righe di C più il parser cJSON integrato — e deliberatamente cieco: non sa nulla di distribuzioni, YAML o template. Riceve /tmp/coa/oa-plan.json, lo percorre passo dopo passo e, in base al campo module di ciascun task, lo esegue nativamente in C oppure lo delega al tecnico Go (coa ell).


📥 1. Invocazione e struttura (main.c)​

oa accetta il piano sia da file che da STDIN, oltre a offrire una maniglia di emergenza per lo smontaggio:

oa /tmp/coa/oa-plan.json # lettura da file
cat /tmp/coa/oa-plan.json | oa # lettura da STDIN (pipe)
oa cleanup [work_dir] # smontaggio di emergenza (default: /home/eggs)

Ogni passo viene registrato in /var/log/penguins-eggs.log.


🔀 2. Lo smistatore (engine.c)​

L'intera logica di instradamento risiede in una funzione cristallina:

int is_native_module(const char *module) {
if (strcmp(module, "users") == 0 ||
strcmp(module, "umount") == 0) {
return 1; // eseguito nativamente in C
}
return 0; // delegato a coa ell (Go)
}
  • Modulo nativo (users, umount): run_native() lo esegue direttamente in-process tramite syscall di sistema.
  • Qualsiasi altro modulo: run_go_worker() effettua un fork, invia il singolo task come JSON grezzo nello STDIN del processo figlio ed esegue coa ell, raccogliendone l'output nel log condiviso e verificando l'exit code. Un task, un processo worker, un codice di uscita.

⚙️ 3. I moduli nativi in C (native.c e oa-yocto.c)​

Solo le operazioni che richiedono davvero di lavorare a stretto contatto con il metallo risiedono in C:

A. users — pulizia e iniezione (stile OpenEmbedded/Yocto)​

Gestisce l'identità del sistema live operando direttamente sui 6 database di account dentro <live_root>/etc/ (passwd, shadow, group, gshadow, subuid, subgid) tramite la micro-libreria oa-yocto.c:

  1. Purge: a meno che la modalità non sia clone o crypted, tutti gli utenti umani dell'host (UID 1000–59999, secondo le soglie OpenEmbedded-Core) vengono rimossi dai database della live, preservando gli account di sistema e garantendo il funzionamento out-of-the-box dei container rootless (subuid/subgid).
  2. Inject: inietta nativamente l'utente live dichiarato nel piano (credenziali predefinite live / evolution), con password cifrata SHA-512, gruppi primari/secondari e permessi della home popolata da /etc/skel.

B. umount — la discesa sicura (MNT_DETACH)​

Smonta l'albero di lavoro in ordine rigoroso utilizzando la syscall umount2() con il flag MNT_DETACH (lazy unmount), impedendo qualsiasi blocco del kernel o dell'host su mount occupati:

  1. API filesystem dentro liveroot (dev/pts, dev, proc, sys, run, tmp);
  2. Overlay mount (usr, var);
  3. Bind mount standard (opt, root, srv);
  4. I lowerdir dell'overlay dentro .overlay;
  5. Infine liveroot stesso.

È la medesima routine invocata da sudo eggs destroy e dal comando oa cleanup.


🧬 4. Anatomia dei sorgenti (oa/src/)​

FileRuolo
src/main.cEntry point CLI: legge il piano JSON, lo analizza con cJSON e guida il ciclo dei task.
src/engine.cIl dispatcher: instrada ogni task verso il C (run_native) o verso coa ell (fork + pipe).
src/native.cI moduli nativi: users (Purge & Inject) e umount (lazy teardown).
src/oa-yocto.cMicro-libreria a zero dipendenze per la manipolazione dei file di identità (passwd, shadow, group, gshadow, subuid, subgid).
src/logger.cLogger minimale su file (/var/log/penguins-eggs.log).
src/cJSON.cParser JSON vendored — l'unica dipendenza di terze parti.