static int set_rctl(char *rctl, uint64_t value, rctl_priv_t priv) { rctlblk_t *oblk, *nblk; boolean_t priv_deny = B_FALSE; int priv_sig = 0; if (value == LX_RLIM64_INFINITY) value = get_rctl_max(rctl); /* * The brand library cannot use malloc(3C) so we allocate the space * with SAFE_ALLOCA(). Thus there's no need to free it when we're done. */ oblk = (rctlblk_t *)SAFE_ALLOCA(rctlblk_size()); nblk = (rctlblk_t *)SAFE_ALLOCA(rctlblk_size()); if (getrctl(rctl, NULL, oblk, RCTL_FIRST) == -1) return (-errno); do { if (rctlblk_get_privilege(oblk) == RCPRIV_PRIVILEGED && rctlblk_get_local_action(oblk, &priv_sig) & RCTL_LOCAL_DENY) priv_deny = B_TRUE; if (rctlblk_get_privilege(oblk) != priv) continue; /* we're already at this value, nothing to do */ if (rctlblk_get_value(oblk) == value) return (0); /* non-root cannot raise privileged limit */ if (priv == RCPRIV_PRIVILEGED && geteuid() != 0 && value > rctlblk_get_value(oblk)) return (-EPERM); bcopy(oblk, nblk, rctlblk_size()); rctlblk_set_value(nblk, value); if (setrctl(rctl, oblk, nblk, RCTL_REPLACE) == -1) return (-errno); return (0); } while (getrctl(rctl, oblk, oblk, RCTL_NEXT) != -1); /* not there, add it */ bzero(nblk, rctlblk_size()); rctlblk_set_value(nblk, value); rctlblk_set_privilege(nblk, priv); if (priv_deny) { rctlblk_set_local_action(nblk, RCTL_LOCAL_DENY, 0); } else { rctlblk_set_local_action(nblk, RCTL_LOCAL_SIGNAL, priv_sig); } if (setrctl(rctl, NULL, nblk, RCTL_INSERT) == -1) return (-errno); return (0); }
static uint64_t get_zone_cap(zoneid_t zid) { rctlblk_t *rblk; uint64_t mcap; struct ps_prochandle *pr; if ((rblk = (rctlblk_t *)malloc(rctlblk_size())) == NULL) return (UINT64_MAX); if ((pr = grab_zone_proc(zid)) == NULL) { free(rblk); return (UINT64_MAX); } if (pr_getrctl(pr, "zone.max-physical-memory", NULL, rblk, RCTL_FIRST)) { Pdestroy_agent(pr); Prelease(pr, 0); free(rblk); return (UINT64_MAX); } Pdestroy_agent(pr); Prelease(pr, 0); mcap = rctlblk_get_value(rblk); free(rblk); return (mcap); }
extern gboolean port_class_init (void (*user_add_event) (gpointer, fnode_event_t*)) { rctlblk_t *rblk; FK_W ("%s\n", __func__); if ((rblk = malloc (rctlblk_size ())) == NULL) { FK_W ("[kernel] rblk malloc %s\n", g_strerror (errno)); return FALSE; } if (getrctl ("process.max-port-events", NULL, rblk, RCTL_FIRST) == -1) { FK_W ("[kernel] getrctl %s\n", g_strerror (errno)); free (rblk); return FALSE; } else { max_port_events = rctlblk_get_value(rblk); FK_W ("[kernel] max_port_events = %u\n", max_port_events); free (rblk); } if ((_obj_fen_hash = g_hash_table_new(g_direct_hash, g_direct_equal)) == NULL) { FK_W ("[kernel] fobj hash initializing faild\n"); return FALSE; } if ((g_eventq = g_queue_new ()) == NULL) { FK_W ("[kernel] FEN global event queue initializing faild\n"); } if (user_add_event == NULL) { return FALSE; } add_event_cb = user_add_event; return TRUE; }
int main (void) { rctlblk_t *old_rblk; rctlblk_t *new_rblk; char *name = "process.max-file-descriptor"; int fd; if (((old_rblk = malloc (rctlblk_size ())) == NULL) || ((new_rblk = malloc (rctlblk_size ())) == NULL)) err_msg ("malloc failed"); if (getrctl (name, NULL, old_rblk, RCTL_FIRST) == -1) err_msg ("getrctl failed"); memcpy (new_rblk, old_rblk, rctlblk_size ()); printf ("Before...\n"); print_rctl (old_rblk); rctlblk_set_value (new_rblk, 10); rctlblk_set_local_action (new_rblk, RCTL_LOCAL_DENY | RCTL_LOCAL_SIGNAL, SIGTERM); if (setrctl (name, NULL, old_rblk, RCTL_DELETE) == -1) err_msg ("setrctl (RCTL_DELETE) failed"); if (setrctl (name, NULL, new_rblk, RCTL_INSERT) == -1) err_msg ("setrctl (RCTL_INSERT) failed"); if (getrctl (name, NULL, new_rblk, RCTL_FIRST) == -1) err_msg ("getrctl failed"); printf ("After...\n"); print_rctl (new_rblk); for (;;) { fd = open ("/tmp", O_RDONLY); printf ("Returned file descriptor = %d\n", fd); } }
static int lx_semctl_ipcinfo(void *buf) { struct lx_seminfo i; rctlblk_t *rblk; int rblksz; uint_t nids; int idbuf; int err; uint64_t val; rblksz = rctlblk_size(); if ((rblk = (rctlblk_t *)SAFE_ALLOCA(rblksz)) == NULL) return (-ENOMEM); bzero(&i, sizeof (i)); err = get_rctlval(rblk, "project.max-sem-ids", (ulong_t)MAXINT, &val); if (err < 0) return (err); i.semmni = (int)val; err = get_rctlval(rblk, "process.max-sem-nsems", (ulong_t)MAXINT, &val); if (err < 0) return (err); i.semmsl = (int)val; err = get_rctlval(rblk, "process.max-sem-ops", (ulong_t)MAXINT, &val); if (err < 0) return (err); i.semopm = (int)val; /* * We don't have corresponding rctls for these fields. The values * are taken from the formulas used to derive the defaults listed * in the Linux header file. We're lying, but trying to be * coherent about it. */ i.semmap = i.semmni; i.semmns = i.semmni * i.semmsl; i.semmnu = INT_MAX; i.semume = INT_MAX; i.semvmx = LX_SEMVMX; if (semids(&idbuf, 0, &nids) < 0) return (-errno); i.semusz = nids; i.semaem = INT_MAX; if (uucopy(&i, buf, sizeof (i)) != 0) return (-errno); return (nids); }
void glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) { #if GLIBTOP_SOLARIS_RELEASE < 51000 kvm_t * const kd = server->machine->kd; glibtop_shm_limits sinfo; memset (buf, 0, sizeof (glibtop_shm_limits)); if(!(server->sysdeps.shm_limits)) return; if(kvm_read(kd, nlst[0].n_value, (void *)&sinfo, sizeof(glibtop_shm_limits)) != sizeof(glibtop_shm_limits)) return; buf->shmmax = sinfo.shmmax; buf->shmmni = sinfo.shmmni; #if GLIBTOP_SOLARIS_RELEASE < 50900 buf->shmmin = sinfo.shmmin; buf->shmseg = sinfo.shmseg; # endif #endif #if GLIBTOP_SOLARIS_RELEASE >= 51000 rctlblk_t *rblk; if ((rblk = malloc(rctlblk_size())) == NULL) return; if (getrctl("project.max-shm-memory", NULL, rblk, RCTL_FIRST) == -1) return; else buf->shmmax = rctlblk_get_value(rblk); if (getrctl("project.max-shm-ids", NULL, rblk, RCTL_FIRST) == -1) return; else buf->shmmni = rctlblk_get_value(rblk); #endif buf->flags = _glibtop_sysdeps_shm_limits; }
extern gboolean port_class_init (void (*user_process_events_callback) (gpointer, node_event_t*)) { rctlblk_t *rblk; if ((rblk = malloc (rctlblk_size ())) == NULL) { FK_W ("[kernel] rblk malloc %s\n", g_strerror (errno)); return FALSE; } if (getrctl ("process.max-port-events", NULL, rblk, RCTL_FIRST) == -1) { FK_W ("[kernel] getrctl %s\n", g_strerror (errno)); free (rblk); return FALSE; } else { max_port_events = rctlblk_get_value(rblk); FK_W ("max_port_events = %u\n", max_port_events); free (rblk); } renamed_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); if (renamed_hash == NULL) { FK_W ("[kernel] FEN global renamed queue initializing faild\n"); return FALSE; } if ((g_eventq = g_queue_new ()) == NULL) { FK_W ("[kernel] FEN global event queue initializing faild\n"); return FALSE; } if (user_process_events_callback == NULL) { FK_W ("[kernel] FEN global no user_process_events_callback\n"); return FALSE; } user_process_events_cb = user_process_events_callback; memset (&zero_wait, 0, sizeof (timespec_t)); pevents = g_malloc(PE_ALLOC * sizeof(port_event_t)); if (pevents == NULL) { FK_W ("[kernel] FEN global alloc pevents failed\n"); return FALSE; } return TRUE; }
static int lx_shmctl_ipcinfo(void *buf) { struct lx_shminfo s; rctlblk_t *rblk; int rblksz; int err; uint64_t val; rblksz = rctlblk_size(); if ((rblk = (rctlblk_t *)SAFE_ALLOCA(rblksz)) == NULL) return (-ENOMEM); bzero(&s, sizeof (s)); err = get_rctlval(rblk, "project.max-shm-ids", ULONG_MAX, &val); if (err < 0) return (err); s.shmmni = val; err = get_rctlval(rblk, "project.max-shm-memory", ULONG_MAX, &val); if (err < 0) return (err); s.shmmax = val; /* * We don't have corresponding rctls for these fields. The values * are taken from the formulas used to derive the defaults listed * in the Linux header file. We're lying, but trying to be * coherent about it. */ s.shmmin = 1; s.shmseg = ULONG_MAX; s.shmall = s.shmmax / getpagesize(); if (uucopy(&s, buf, sizeof (s))) return (-errno); return (0); }
static uint64_t get_rctl_max(char *rctl) { rctlblk_t *rblk; uint64_t inf; /* * The brand library cannot use malloc(3C) so we allocate the space * with SAFE_ALLOCA(). Thus there's no need to free it when we're done. */ rblk = (rctlblk_t *)SAFE_ALLOCA(rctlblk_size()); if (getrctl(rctl, NULL, rblk, RCTL_FIRST) == -1) return (-errno); do { switch (rctlblk_get_privilege(rblk)) { case RCPRIV_BASIC: case RCPRIV_PRIVILEGED: inf = rctlblk_get_value(rblk); if (rctlblk_get_local_flags(rblk) & RCTL_LOCAL_MAXIMAL && rctlblk_get_global_flags(rblk) & RCTL_GLOBAL_INFINITE) return (inf); break; case RCPRIV_SYSTEM: inf = rctlblk_get_value(rblk); return (inf); break; } } while (getrctl(rctl, rblk, rblk, RCTL_NEXT) != -1); /* Somehow we have no max, use the Linux infinite value */ return (LX_RLIM64_INFINITY); }
static int lx_msgctl_ipcinfo(int cmd, void *buf) { struct lx_msginfo m; rctlblk_t *rblk; int idbuf, rblksz, msgseg, maxmsgs; uint_t nids; int rval; int err; uint64_t val; rblksz = rctlblk_size(); if ((rblk = (rctlblk_t *)SAFE_ALLOCA(rblksz)) == NULL) return (-ENOMEM); bzero(&m, sizeof (m)); err = get_rctlval(rblk, "project.max-msg-ids", (ulong_t)MAXINT, &val); if (err < 0) return (err); m.msgmni = (int)val; err = get_rctlval(rblk, "process.max-msg-qbytes", (ulong_t)MAXINT, &val); if (err < 0) return (err); m.msgmnb = (int)val; if (cmd == LX_IPC_INFO) { err = get_rctlval(rblk, "process.max-msg-messages", (ulong_t)MAXINT, &val); if (err < 0) return (err); maxmsgs = (int)val; m.msgtql = maxmsgs * m.msgmni; m.msgmap = m.msgmnb; m.msgpool = m.msgmax * m.msgmnb; rval = 0; } else { if (msgids(&idbuf, 0, &nids) < 0) return (-errno); m.msgpool = nids; /* * For these fields, we can't even come up with a good fake * approximation. These are listed as 'obsolete' or * 'unused' in the header files, so hopefully nobody is * relying on them anyway. */ m.msgtql = INT_MAX; m.msgmap = INT_MAX; rval = nids; } /* * We don't have corresponding rctls for these fields. The values * are taken from the formulas used to derive the defaults listed * in the Linux header file. We're lying, but trying to be * coherent about it. */ m.msgmax = m.msgmnb; m.msgssz = 16; msgseg = (m.msgpool * 1024) / m.msgssz; m.msgseg = (msgseg > 0xffff) ? 0xffff : msgseg; if (uucopy(&m, buf, sizeof (m))) return (-errno); return (rval); }
static int getrlimit_common(int resource, uint64_t *rlim_curp, uint64_t *rlim_maxp) { char *rctl; rctlblk_t *rblk; int64_t cur = -1; boolean_t cur_inf = B_FALSE; int64_t max = -1; boolean_t max_inf = B_FALSE; if (resource < 0 || resource >= LX_RLIMIT_NLIMITS) return (-EINVAL); rctl = l_to_rctl[resource]; if (rctl == NULL) { switch (resource) { case LX_RLIMIT_LOCKS: case LX_RLIMIT_NICE: case LX_RLIMIT_RTPRIO: case LX_RLIMIT_RTTIME: *rlim_maxp = fake_limits[resource].rlim_max; *rlim_curp = fake_limits[resource].rlim_cur; return (0); default: lx_unsupported("Unsupported resource type %d\n", resource); return (-ENOTSUP); } } /* * The brand library cannot use malloc(3C) so we allocate the space * with SAFE_ALLOCA(). Thus there's no need to free it when we're done. */ rblk = (rctlblk_t *)SAFE_ALLOCA(rctlblk_size()); if (getrctl(rctl, NULL, rblk, RCTL_FIRST) == -1) return (-errno); do { switch (rctlblk_get_privilege(rblk)) { case RCPRIV_BASIC: cur = rctlblk_get_value(rblk); if (rctlblk_get_local_flags(rblk) & RCTL_LOCAL_MAXIMAL && rctlblk_get_global_flags(rblk) & RCTL_GLOBAL_INFINITE) cur_inf = B_TRUE; break; case RCPRIV_PRIVILEGED: max = rctlblk_get_value(rblk); if (rctlblk_get_local_flags(rblk) & RCTL_LOCAL_MAXIMAL && rctlblk_get_global_flags(rblk) & RCTL_GLOBAL_INFINITE) max_inf = B_TRUE; break; } } while (getrctl(rctl, rblk, rblk, RCTL_NEXT) != -1); /* Confirm we got values. For many rctls "basic" is not set. */ if (max == -1) max = LX_RLIM64_INFINITY; if (cur == -1) cur = max; if (cur_inf) *rlim_curp = LX_RLIM64_INFINITY; else *rlim_curp = cur; if (max_inf) *rlim_maxp = LX_RLIM64_INFINITY; else *rlim_maxp = max; return (0); }