/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <libintl.h>
#include <string.h>
#include <rcm_module.h>
#include <pool.h>
/*
* RCM module ops.
*/
static int pool_register(rcm_handle_t *);
static int pool_unregister(rcm_handle_t *);
char **, nvlist_t *, rcm_info_t **);
rcm_info_t **);
char **, rcm_info_t **);
char **, rcm_info_t **);
rcm_info_t **);
nvlist_t *, char **, rcm_info_t **);
nvlist_t *, char **, rcm_info_t **);
/*
* Pool-specific callback functions.
*/
static int pset_validate_remove(nvlist_t *, char **);
static struct {
const char *rsrc;
} registrations[] = {
{ "SUNW_cpu", pset_validate_remove },
};
static int registered = 0;
};
struct rcm_mod_ops *
rcm_mod_init(void)
{
return (&pool_ops);
}
int
rcm_mod_fini(void)
{
return (RCM_SUCCESS);
}
const char *
rcm_mod_info(void)
{
return ("Pools RCM module 1.4");
}
static int
{
int i, j;
return (-1);
gettext("POOL: cannot find property 'pset.min' in pset\n"));
return (-1);
}
return (-1);
}
return (-1);
}
return (-1);
}
return (-1);
}
for (i = 0; del_cpus[i] != -1; i++)
for (j = 0; j < num_cpus; j++)
num_found++;
int len;
char *errval;
const char *errfmt =
gettext("POOL: processor set (%1$d) would go "
"below its minimum value of %2$u\n");
/*
* We would go below the min value. Fail this request.
*/
}
return (-1);
}
return (0);
}
/*
* pset_validate_remove()
* Check to see if the requested cpu removal would be acceptable.
* Returns RCM_FAILURE if not.
*/
static int
{
int i, j;
return (RCM_FAILURE);
"POOL: failed to parse config file: '%s'\n",
return (RCM_SUCCESS);
}
(void) pool_conf_close(conf);
gettext("POOL: unable to find 'old_total' in nvlist: %s\n"),
return (RCM_FAILURE);
}
(void) pool_conf_close(conf);
gettext("POOL: unable to find 'new_total' in nvlist: %s\n"),
return (RCM_FAILURE);
}
(void) pool_conf_close(conf);
/*
* This doesn't look like a cpu removal.
*/
gettext("POOL: 'old_total' (%d) is less than 'new_total' "
return (RCM_SUCCESS);
}
== NULL) {
error = RCM_FAILURE;
goto out;
}
&old_cpu_list, &nelem)) != 0) {
gettext("POOL: 'old_cpu_list' not found in nvlist: %s\n"),
error = RCM_FAILURE;
goto out;
}
gettext("POOL: 'old_cpu_list' size mismatch: %1$d vs "
error = RCM_FAILURE;
goto out;
}
&new_cpu_list, &nelem)) != 0) {
gettext("POOL: 'new_cpu_list' not found in nvlist: %s\n"),
error = RCM_FAILURE;
goto out;
}
gettext("POOL: 'new_cpu_list' size mismatch: %1$d vs "
error = RCM_FAILURE;
goto out;
}
for (i = 0, removed_total = 0; i < old_total; i++) {
for (j = 0; j < new_total; j++)
if (old_cpu_list[i] == new_cpu_list[j])
break;
if (j == new_total) /* not found in new_cpu_list */
}
gettext("POOL: error finding removed cpu list\n"));
error = RCM_FAILURE;
goto out;
}
error = RCM_FAILURE;
goto out;
}
/*
* Look for resources with "'type' = 'pset'"
*/
gettext("POOL: No psets found in configuration\n"));
pool_value_free(pvals[0]);
error = RCM_FAILURE;
goto out;
}
pool_value_free(pvals[0]);
/*
* Ask each pset if removing these cpus would cause it to go
* below it's minimum value.
*/
error = RCM_FAILURE;
break;
}
out:
if (removed_list)
if (conf) {
(void) pool_conf_close(conf);
}
/*
* Set the error string if not already set.
*/
return (error);
}
/*
* Returns RCM_SUCCESS in a number of error cases, since RCM_FAILURE would
* mean that the capacity change would be disallowed by this module,
* which is not what we mean.
*/
static int
{
int i;
"POOL: requesting capacity change for: %s (flag: %d)\n",
"POOL: Allowing forced operation to pass through...\n");
return (RCM_SUCCESS);
}
errorp));
}
}
return (RCM_SUCCESS);
}
static int
{
"POOL: notifying capacity change for: %s (flags: %d)\n",
return (RCM_SUCCESS);
}
static int
{
int i;
if (registered)
return (RCM_SUCCESS);
registered++;
0, NULL) != RCM_SUCCESS) {
gettext("POOL: failed to register capacity "
"change for '%s'\n"),
registrations[i].rsrc);
}
}
return (RCM_SUCCESS);
}
static int
{
int i;
if (registered) {
registered--;
gettext("POOL: unregister capacity failed "
}
}
return (RCM_SUCCESS);
}
static int
{
== NULL) {
"failure\n"), rsrcname);
return (RCM_FAILURE);
}
return (RCM_SUCCESS);
}
static int
{
"POOL: requesting suspend for: %s\n", rsrcname);
return (RCM_SUCCESS);
}
static int
{
"POOL: notifying resume of: %s\n", rsrcname);
return (RCM_SUCCESS);
}
static int
{
"POOL: requesting offline for: %s\n", rsrcname);
return (RCM_SUCCESS);
}
static int
{
"POOL: notifying online for: %s\n", rsrcname);
return (RCM_SUCCESS);
}
static int
{
"POOL: notifying removal of: %s\n", rsrcname);
return (RCM_SUCCESS);
}