/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/sysmacros.h>
/*
* Core File Settings
* ------------------
*
* A process's core file path and content live in separate reference-counted
* structures. The corectl_content_t structure is fairly straightforward --
* the only subtlety is that we only really _need_ the mutex on architectures
* on which 64-bit memory operations are not atomic. The corectl_path_t
* structure is slightly trickier in that it contains a refstr_t rather than
* just a char * string. This is to allow consumers of the data in that
* structure (the core dumping sub-system for example) to safely use the
* string without holding any locks on it in light of updates.
*
* At system and zone boot, init_core() sets init(1M)'s core file path and
* content to the same value as the fields core_default_path and
* core_default_content respectively (for the global zone). All subsequent
* children of init(1M) reference those same settings. During boot coreadm(1M)
* is invoked with the -u option to update the system settings from
* /etc/coreadm.conf. This has the effect of also changing the values in
* core_default_path and core_default_content which updates the core file
* settings for all processes in the zone. Each zone has different default
* settings; when processes enter a non-global zone, their core file path and
* content are set to the zone's default path and content.
*
* Processes that have their core file settings explicitly overridden using
* coreadm(1M) no longer reference core_default_path or core_default_content
* so subsequent changes to the default will not affect them.
*/
static corectl_content_t *
{
return (ccp);
}
{
return (content);
}
static void
{
}
void
{
}
void
{
}
static corectl_path_t *
{
return (ccp);
}
refstr_t *
{
return (path);
}
static void
{
}
void
{
}
void
{
}
}
/*
* Constructor routine to be called when a zone is created.
*/
/*ARGSUSED*/
static void *
{
return (cg);
}
/*
* Destructor routine to be called when a zone is destroyed.
*/
/*ARGSUSED*/
static void
{
return;
}
/*
* Called from start_init_common(), to set init's core file path and content.
*/
void
init_core(void)
{
/*
* The first time we hit this, in the global zone, we have to
* initialize the zsd key.
*/
if (INGLOBALZONE(curproc)) {
}
/*
* zone_key_create will have called core_init_zone for the
* global zone, which sets up the default path and content
* variables.
*/
}
int
{
int error = 0;
proc_t *p;
char *path;
switch (subcode) {
case CC_SET_OPTIONS:
if (arg1 & ~CC_OPTIONS)
else
}
break;
case CC_GET_OPTIONS:
return (cg->core_options);
case CC_GET_GLOBAL_PATH:
case CC_GET_DEFAULT_PATH:
case CC_GET_PROCESS_PATH:
if (subcode == CC_GET_GLOBAL_PATH) {
} else if (subcode == CC_GET_DEFAULT_PATH) {
} else {
} else {
mutex_enter(&p->p_lock);
mutex_enter(&p->p_crlock);
else if (p->p_corefile != NULL)
mutex_exit(&p->p_crlock);
mutex_exit(&p->p_lock);
}
}
} else {
}
break;
case CC_SET_GLOBAL_PATH:
case CC_SET_DEFAULT_PATH:
break;
/* FALLTHROUGH */
case CC_SET_PROCESS_PATH:
break;
}
if (error == 0) {
if (subcode == CC_SET_PROCESS_PATH) {
} else if (subcode == CC_SET_DEFAULT_PATH) {
} else {
if (*path == '\0')
else
}
}
break;
case CC_SET_GLOBAL_CONTENT:
case CC_SET_DEFAULT_CONTENT:
break;
/* FALLTHROUGH */
case CC_SET_PROCESS_CONTENT:
if (error != 0)
break;
/*
* If any unknown bits are set, don't let this charade
* continue.
*/
if (content & ~CC_CONTENT_ALL) {
break;
}
if (subcode == CC_SET_PROCESS_CONTENT) {
} else if (subcode == CC_SET_DEFAULT_CONTENT) {
} else {
}
break;
case CC_GET_GLOBAL_CONTENT:
break;
case CC_GET_DEFAULT_CONTENT:
break;
case CC_GET_PROCESS_CONTENT:
break;
}
mutex_enter(&p->p_lock);
mutex_enter(&p->p_crlock);
else
mutex_exit(&p->p_crlock);
mutex_exit(&p->p_lock);
if (error == 0)
sizeof (content));
break;
default:
break;
}
if (error)
return (0);
}
typedef struct {
int cc_count;
} counter_t;
static int
{
mutex_enter(&p->p_crlock);
mutex_exit(&p->p_crlock);
mutex_enter(&p->p_lock);
corefile = p->p_corefile;
mutex_exit(&p->p_lock);
} else {
mutex_enter(&p->p_lock);
mutex_exit(&p->p_lock);
}
} else {
mutex_exit(&p->p_crlock);
}
return (0);
}
static int
{
proc_t *p;
int error = 0;
/*
* Only one of the core file path or content can be set at a time.
*/
} else {
}
if (pid == -1) {
} else if (pid > 0) {
} else {
(void) set_one_proc_info(p, &counter);
}
} else {
int nfound = 0;
if (pid == 0)
else
nfound++;
(void) set_one_proc_info(p, &counter);
}
}
if (nfound == 0)
}
else
if (error)
return (0);
}
/*
* Give current process the default core settings for its current zone;
* used for processes entering a zone via zone_enter.
*/
void
set_core_defaults(void)
{
/* make local copies of default values to protect against change */
mutex_enter(&p->p_lock);
oldpath = p->p_corefile;
p->p_corefile = newpath;
oldcontent = p->p_content;
p->p_content = newcontent;
mutex_exit(&p->p_lock);
if (oldcontent != NULL)
}