|
root / stub / src / contract.reef
contract.reef Reef 105 lines 3.6 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
// 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<i32, String> {
    // 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<i32, String> {
    // 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<i32, String> {
    // 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")
}