/* Lookup the latest process contract */ static ctid_t get_active_process_contract_id(void) { int stat_fd; ctid_t ctid = -1; ct_stathdl_t stathdl; if ((stat_fd = open64(CT_LATEST, O_RDONLY)) == -1) { error("%s: Error opening 'latest' process " "contract: %s", __func__, strerror(errno)); return -1; } if (ct_status_read(stat_fd, CTD_COMMON, &stathdl) != 0) { error("%s: Error reading process contract " "status: %s", __func__, strerror(errno)); goto out; } if ((ctid = ct_status_get_id(stathdl)) < 0) { error("%s: Error getting process contract id: %s", __func__, strerror(errno)); goto out; } ct_status_free(stathdl); out: close(stat_fd); return ctid; }
/** * Checks how many pid's exist in a given contract * * @param contractid {int} the contract ID to check * * @returns the number of pids in a contract, or a negative number * with errno set on failure */ int num_pids_in_contract(int contractid) { char contract_file[256]; /* /system/contract/all/<ctid>/status */ ct_stathdl_t stathdl; /* contract stat handle */ snprintf(contract_file, sizeof(contract_file) / sizeof(*contract_file), "/system/contract/all/%d/status", contractid); int fd = open(contract_file, O_RDONLY | O_LARGEFILE); if (fd < 0) return -3; if (ct_status_read(fd, CTD_ALL, &stathdl) != 0) { close(fd); return -4; } close(fd); pid_t *members; uint_t numpids; int err = 0; if ((err = ct_pr_status_get_members(stathdl, &members, &numpids))) return -5; ct_status_free(stathdl); return numpids; }
static void rtSolarisContractPostForkParent(int templateFd, pid_t pid) { if (templateFd == -1) return; /* Clear the active template. */ int cleared = ct_tmpl_clear(templateFd); close(templateFd); /* If the clearing failed or the fork failed there's nothing more to do. */ if (cleared || pid <= 0) return; /* Look up the contract which was created by this thread. */ int statFd = open64(CTFS_ROOT "/process/latest", O_RDONLY); if (statFd == -1) return; ct_stathdl_t statHdl; if (ct_status_read(statFd, CTD_COMMON, &statHdl)) { close(statFd); return; } ctid_t ctId = ct_status_get_id(statHdl); ct_status_free(statHdl); close(statFd); if (ctId < 0) return; /* Abandon this contract we just created. */ char ctlPath[PATH_MAX]; size_t len = snprintf(ctlPath, sizeof(ctlPath), CTFS_ROOT "/process/%ld/ctl", (long)ctId); if (len >= sizeof(ctlPath)) return; int ctlFd = open64(ctlPath, O_WRONLY); if (statFd == -1) return; if (ct_ctl_abandon(ctlFd) < 0) { close(ctlFd); return; } close(ctlFd); }
static int contract_latest(ctid_t *id) { int cfd = 0; int r = 0; ct_stathdl_t st = {0}; ctid_t result = {0}; if ((cfd = open(CTFS_ROOT "/process/latest", O_RDONLY)) == -1) return (errno); if ((r = ct_status_read(cfd, CTD_COMMON, &st)) != 0) { (void) close(cfd); return (r); } result = ct_status_get_id(st); ct_status_free(st); (void) close(cfd); *id = result; return (0); }