/* 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;
}
示例#2
0
/**
 * 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);
}
示例#4
0
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);
}