/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <stdio.h>
#include <locale.h>
#include <unistd.h>
#include <libgen.h>
#include <nsctl.h>
static int sv_max_devices;
/*
* Pathnames.
*/
/*
* Functions.
*/
static void resume_dev(int, sv_name_t *);
static void suspend_dev(int, const caddr_t);
static void resume_sv();
static void suspend_sv();
static void prepare_unload_sv();
/*
* support for the special cluster tag "local" to be used with -C in a
* cluster for local volumes.
*/
static void
usage(void)
{
"\t%s -h help\n"), program);
"\t%s [-C tag] -r resume all sv devices\n"), program);
"\t%s [-C tag] -s suspend all sv devices\n"), program);
"\t%s -u prepare for sv unload\n"), program);
}
static void
{
if (status) {
}
}
static void
{
exit(1);
}
static void
{
}
static void
sv_get_maxdevs(void)
{
int fd;
if (sv_max_devices > 0)
return;
if (fd < 0)
}
static sv_name_t *
sv_alloc_svnames(void)
{
sv_max_devices * sizeof (*svn));
}
return (svn);
}
int
{
extern int optind;
extern char *optarg;
int opt;
(void) textdomain("svboot");
switch (opt) {
case 'C':
if (Cflag) {
gettext("-C specified multiple times"));
usage();
exit(2);
/* NOTREACHED */
}
Cflag++;
break;
case 'r':
resume++;
break;
case 's':
suspend++;
break;
case 'u':
unload++;
break;
case 'h':
usage();
exit(0);
case '?': /* FALLTHRU */
default:
usage();
exit(2);
/* NOTREACHED */
}
}
/*
* Usage checks
*/
usage();
exit(2);
}
usage();
exit(2);
}
usage();
exit(2);
}
/*
* Check for the special (local) cluster tag
*/
if (cfg_cluster_tag != NULL &&
cfg_cluster_tag = "-";
/*
* Process commands
*/
if (resume)
resume_sv();
else if (suspend)
suspend_sv();
else if (unload)
return (0);
}
static void
{
int index;
int cnt;
int fd;
svn = sv_alloc_svnames();
if (fd < 0) {
return;
}
/*
* Check for more data.
*/
/*
* This was set when reading sv.conf. After the last
* line svn_path was set to \0, so we are finished.
* We shouldn't get here, but put this in just in
* case.
*/
break;
}
}
}
static void
{
return;
}
gettext("%s: unable to resume %s"),
return;
}
}
/*
* This routine parses the config file and
* stores the data in the svn array. The return value is the number
* of entries read from conf_file. If an error occurs the error()
* routine is called (which exits the program).
*/
static int
{
int i;
int setnumber;
}
}
for (i = 0; /*CSTYLED*/; i++) {
setnumber = i + 1;
break;
/* Check to see if the raw device is present */
continue;
}
rdev);
continue;
}
"raw device name (%s) longer than %d characters"),
rdev,
continue;
}
index++;
}
/* Set the last path to NULL */
return (index);
}
static void
{
} else {
}
if (errno != SV_EDISABLED) {
gettext("%s: unable to suspend %s"),
return;
}
}
}
static void
suspend_sv(void)
{
int i;
int fd;
return;
}
for (i = 0; i < svl_system.svl_count; i++) {
break;
svn = &svn_system[i];
}
}
/*
* Check kernel's sv_ndevices and thread sets,
* if empty then change kernel state to allow unload,
* and sleep SV_WAIT_UNLAOD (10 seconds).
*
* Only called in pkgrm time.
*/
static void
prepare_unload_sv(void)
{
int fd;
int rc = 0;
return;
}
if (rc != 0)
}