/* * Set the fields in the 'target' clone to the specified values. * Then, look at all clones to determine which message types are * currently active and which clone is the primary console queue. * If the primary console queue changes to or from the backlog * queue, copy all messages from backlog to primary or vice versa. */ void log_update(log_t *target, queue_t *q, short flags, log_filter_t *filter) { log_t *lp; short active = SL_CONSOLE; zone_t *zptr = NULL; log_zone_t *lzp; zoneid_t zoneid = target->log_zoneid; int i; log_enter(); if (q != NULL) target->log_q = q; target->log_wanted = filter; target->log_flags = flags; target->log_overflow = 0; /* * Need to special case the global zone here since this may be * called before zone_init. */ if (zoneid == GLOBAL_ZONEID) { lzp = &log_global; } else if ((zptr = zone_find_by_id(zoneid)) == NULL) { log_exit(); return; /* zone is being destroyed, ignore update */ } else { lzp = zone_getspecific(log_zone_key, zptr); } ASSERT(lzp != NULL); for (i = LOG_LOGMAXIDX; i >= LOG_LOGMINIDX; i--) { lp = &lzp->lz_clones[i]; if (zoneid == GLOBAL_ZONEID && (lp->log_flags & SL_CONSOLE)) log_consq = lp->log_q; active |= lp->log_flags; } lzp->lz_active = active; if (zptr) zone_rele(zptr); if (log_consq == target->log_q) { if (flags & SL_CONSOLE) log_conswitch(&log_backlog, target); else log_conswitch(target, &log_backlog); } target->log_q = q; log_exit(); }
/* * Find a stack instance given the zoneid. * Increases the reference count if found; caller must do a * netstack_rele(). * * If there is no exact match then assume the shared stack instance * matches. * * Skip the unitialized ones. */ netstack_t * netstack_find_by_zoneid(zoneid_t zoneid) { netstack_t *ns; zone_t *zone; zone = zone_find_by_id(zoneid); if (zone == NULL) return (NULL); ns = zone->zone_netstack; ASSERT(ns != NULL); if (ns->netstack_flags & (NSF_UNINIT|NSF_CLOSING)) ns = NULL; else netstack_hold(ns); zone_rele(zone); return (ns); }
static int pset_bind(psetid_t pset, idtype_t idtype, id_t id, psetid_t *opset) { kthread_t *tp; proc_t *pp; task_t *tk; kproject_t *kpj; contract_t *ct; zone_t *zptr; psetid_t oldpset; int error = 0; void *projbuf, *zonebuf; pool_lock(); if ((pset != PS_QUERY) && (pset != PS_SOFT) && (pset != PS_HARD) && (pset != PS_QUERY_TYPE)) { /* * Check if the set actually exists before checking * permissions. This is the historical error * precedence. Note that if pset was PS_MYID, the * cpupart_get_cpus call will change it to the * processor set id of the caller (or PS_NONE if the * caller is not bound to a processor set). */ if (pool_state == POOL_ENABLED) { pool_unlock(); return (set_errno(ENOTSUP)); } if (cpupart_get_cpus(&pset, NULL, NULL) != 0) { pool_unlock(); return (set_errno(EINVAL)); } else if (pset != PS_NONE && secpolicy_pset(CRED()) != 0) { pool_unlock(); return (set_errno(EPERM)); } } /* * Pre-allocate enough buffers for FSS for all active projects * and for all active zones on the system. Unused buffers will * be freed later by fss_freebuf(). */ mutex_enter(&cpu_lock); projbuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_PROJ); zonebuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_ZONE); switch (idtype) { case P_LWPID: pp = curproc; mutex_enter(&pidlock); mutex_enter(&pp->p_lock); if (id == P_MYID) { tp = curthread; } else { if ((tp = idtot(pp, id)) == NULL) { mutex_exit(&pp->p_lock); mutex_exit(&pidlock); error = ESRCH; break; } } error = pset_bind_thread(tp, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pp->p_lock); mutex_exit(&pidlock); break; case P_PID: mutex_enter(&pidlock); if (id == P_MYID) { pp = curproc; } else if ((pp = prfind(id)) == NULL) { mutex_exit(&pidlock); error = ESRCH; break; } error = pset_bind_process(pp, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); break; case P_TASKID: mutex_enter(&pidlock); if (id == P_MYID) id = curproc->p_task->tk_tkid; if ((tk = task_hold_by_id(id)) == NULL) { mutex_exit(&pidlock); error = ESRCH; break; } error = pset_bind_task(tk, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); task_rele(tk); break; case P_PROJID: pp = curproc; if (id == P_MYID) id = curprojid(); if ((kpj = project_hold_by_id(id, pp->p_zone, PROJECT_HOLD_FIND)) == NULL) { error = ESRCH; break; } mutex_enter(&pidlock); error = pset_bind_project(kpj, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); project_rele(kpj); break; case P_ZONEID: if (id == P_MYID) id = getzoneid(); if ((zptr = zone_find_by_id(id)) == NULL) { error = ESRCH; break; } mutex_enter(&pidlock); error = pset_bind_zone(zptr, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); zone_rele(zptr); break; case P_CTID: if (id == P_MYID) id = PRCTID(curproc); if ((ct = contract_type_ptr(process_type, id, curproc->p_zone->zone_uniqid)) == NULL) { error = ESRCH; break; } mutex_enter(&pidlock); error = pset_bind_contract(ct->ct_data, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); contract_rele(ct); break; case P_PSETID: if (id == P_MYID || pset != PS_NONE || !INGLOBALZONE(curproc)) { error = EINVAL; break; } error = pset_unbind(id, projbuf, zonebuf, idtype); break; case P_ALL: if (id == P_MYID || pset != PS_NONE || !INGLOBALZONE(curproc)) { error = EINVAL; break; } error = pset_unbind(PS_NONE, projbuf, zonebuf, idtype); break; default: error = EINVAL; break; } fss_freebuf(projbuf, FSS_ALLOC_PROJ); fss_freebuf(zonebuf, FSS_ALLOC_ZONE); mutex_exit(&cpu_lock); pool_unlock(); if (error != 0) return (set_errno(error)); if (opset != NULL) { if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0) return (set_errno(EFAULT)); } return (0); }
void log_sendmsg(mblk_t *mp, zoneid_t zoneid) { log_t *lp; char *src, *dst; mblk_t *mp2 = mp->b_cont; log_ctl_t *lc = (log_ctl_t *)mp->b_rptr; int flags, fac; off_t facility = 0; off_t body = 0; zone_t *zptr = NULL; log_zone_t *lzp; int i; int backlog; /* * Need to special case the global zone here since this may be * called before zone_init. */ if (zoneid == GLOBAL_ZONEID) { lzp = &log_global; } else if ((zptr = zone_find_by_id(zoneid)) == NULL) { /* specified zone doesn't exist, free message and return */ log_freemsg(mp); return; } else { lzp = zone_getspecific(log_zone_key, zptr); } ASSERT(lzp != NULL); if ((lc->flags & lzp->lz_active) == 0) { if (zptr) zone_rele(zptr); log_freemsg(mp); return; } if (panicstr) { /* * Raise the console queue's q_hiwat to ensure that we * capture all panic messages. */ log_consq->q_hiwat = 2 * LOG_HIWAT; log_consq->q_flag &= ~QFULL; /* Message was created while panicking. */ lc->flags |= SL_PANICMSG; } src = (char *)mp2->b_rptr; dst = strstr(src, "FACILITY_AND_PRIORITY] "); if (dst != NULL) { facility = dst - src; body = facility + 23; /* strlen("FACILITY_AND_PRIORITY] ") */ } log_enter(); /* * In the early boot phase hrestime is invalid, then timechanged is 0. * If hrestime is not valid, the ttime is set to 0 here and the correct * ttime is calculated in log_conswitch() later. The log_conswitch() * calculation to determine the correct ttime does not use ttime data * from these log_ctl_t structures; it only uses ttime from log_ctl_t's * that contain good data. * */ lc->ltime = ddi_get_lbolt(); if (timechanged) { lc->ttime = gethrestime_sec(); } else { lc->ttime = 0; } flags = lc->flags & lzp->lz_active; log_seq_no[flags & SL_ERROR]++; log_seq_no[flags & SL_TRACE]++; log_seq_no[flags & SL_CONSOLE]++; /* * If this is in the global zone, start with the backlog, then * walk through the clone logs. If not, just do the clone logs. */ backlog = (zoneid == GLOBAL_ZONEID); i = LOG_LOGMINIDX; while (i <= LOG_LOGMAXIDX) { if (backlog) { /* * Do the backlog this time, then start on the * others. */ backlog = 0; lp = &log_backlog; } else { lp = &lzp->lz_clones[i++]; } if ((lp->log_flags & flags) && lp->log_wanted(lp, lc)) { if (canput(lp->log_q)) { lp->log_overflow = 0; lc->seq_no = log_seq_no[lp->log_flags]; if ((mp2 = copymsg(mp)) == NULL) break; if (facility != 0) { src = (char *)mp2->b_cont->b_rptr; dst = src + facility; fac = (lc->pri & LOG_FACMASK) >> 3; dst += snprintf(dst, LOG_FACSIZE + LOG_PRISIZE, "%s.%s", log_fac[MIN(fac, LOG_NFACILITIES)], log_pri[lc->pri & LOG_PRIMASK]); src += body - 2; /* copy "] " too */ while (*src != '\0') *dst++ = *src++; *dst++ = '\0'; mp2->b_cont->b_wptr = (uchar_t *)dst; } (void) putq(lp->log_q, mp2); } else if (++lp->log_overflow == 1) {