// contract.reef — illumos process contract FFI bindings // // Provides Reef wrappers around libcontract for managing service processes. // Process contracts are an illumos kernel feature — this module ONLY works // on illumos/Hammerhead. // // Reference: illumos libcontract(3LIB), contract(5), process(5) // Source reference: hammerhead/usr/src/cmd/svc/startd/contract.c // C FFI declarations for libcontract extern "C" { // Template management fn ct_tmpl_activate(fd: i32) -> i32; fn ct_tmpl_clear(fd: i32) -> i32; fn ct_tmpl_set_informative(fd: i32, events: u32) -> i32; fn ct_tmpl_set_critical(fd: i32, events: u32) -> i32; // Process contract template fn ct_pr_tmpl_set_fatal(fd: i32, events: u32) -> i32; fn ct_pr_tmpl_set_param(fd: i32, params: u32) -> i32; // Contract status fn ct_status_read(fd: i32, detail: i32, statp: *mut CtStatus) -> i32; fn ct_status_free(status: *mut CtStatus); fn ct_status_get_id(status: *CtStatus) -> i32; // Contract control fn ct_ctl_abandon(fd: i32) -> i32; fn ct_ctl_adopt(fd: i32) -> i32; // POSIX fn open(path: *const u8, flags: i32) -> i32; fn close(fd: i32) -> i32; fn fork() -> i32; fn execvp(file: *const u8, argv: *const *const u8) -> i32; fn setsid() -> i32; fn sigsend(idtype: i32, id: i64, sig: i32) -> i32; fn poll(fds: *mut PollFd, nfds: i32, timeout: i32) -> i32; } // Contract event flags const CT_PR_EV_EMPTY: u32 = 0x01; // all processes exited const CT_PR_EV_FORK: u32 = 0x02; // process forked const CT_PR_EV_EXIT: u32 = 0x04; // process exited const CT_PR_EV_CORE: u32 = 0x08; // process dumped core const CT_PR_EV_SIGNAL: u32 = 0x10; // fatal signal const CT_PR_EV_HWERR: u32 = 0x20; // hardware error // Contract parameter flags const CT_PR_INHERIT: u32 = 0x01; // inherit contract on fork const CT_PR_NOORPHAN: u32 = 0x02; // kill orphans on contract abandon // Contract template path const CTFS_PROCESS_TEMPLATE: &str = "/system/contract/process/template"; const CTFS_PROCESS_LATEST: &str = "/system/contract/process/latest"; const CTFS_PROCESS_BUNDLE: &str = "/system/contract/process/bundle"; // Managed contract handle struct Contract { id: i32, // contract ID from kernel service_name: String, bundle_fd: i32, // fd for event monitoring } // Set up a contract template for forking a service fn setup_template() -> Result { // TODO: implement // 1. open(CTFS_PROCESS_TEMPLATE, O_RDWR) // 2. ct_tmpl_set_informative(fd, CT_PR_EV_EMPTY) // 3. ct_tmpl_set_critical(fd, CT_PR_EV_EMPTY | CT_PR_EV_HWERR) // 4. ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR) // 5. ct_pr_tmpl_set_param(fd, CT_PR_INHERIT | CT_PR_NOORPHAN) // 6. ct_tmpl_activate(fd) // 7. Return fd Err("not yet implemented") } // After fork(), retrieve the contract ID for the new child fn get_latest_contract() -> Result { // TODO: implement // 1. open(CTFS_PROCESS_LATEST, O_RDONLY) // 2. ct_status_read() // 3. ct_status_get_id() // 4. Return contract ID Err("not yet implemented") } // Open the contract bundle fd for poll()-based event monitoring fn open_bundle() -> Result { // TODO: implement Err("not yet implemented") } // Kill all processes in a contract fn kill_contract(contract_id: i32, signal: i32) -> Result<(), String> { // TODO: implement using sigsend(P_CTID, contract_id, signal) Err("not yet implemented") } // Re-adopt an existing contract (after zyginit restart) fn adopt_contract(contract_id: i32) -> Result<(), String> { // TODO: implement Err("not yet implemented") }