/*
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "libzfs_jni_diskmgt.h"
#include "libzfs_jni_util.h"
#include <strings.h>
#include <libzfs.h>
/*
* Function prototypes
*/
static dmgt_slice_t *get_slice(
static void handle_error(const char *format, ...);
/*
* Static data
*/
/*
* Static functions
*/
static char *
{
char *dup;
char *name;
*error = 0;
if (*error) {
handle_error("could not determine name of device");
} else {
handle_error("out of memory");
*error = -1;
}
}
return (dup);
}
/*
* Gets a dmgt_disk_t for the given disk dm_descriptor_t.
*
* Results:
*
* 1. Success: error is set to 0 and a dmgt_disk_t is returned
*
* 2. Failure: error is set to -1 and NULL is returned
*/
static dmgt_disk_t *
{
*error = 0;
handle_error("out of memory");
*error = -1;
} else {
/* Get name */
if (!*error) {
/* Get aliases */
if (!*error) {
/* Get media */
"could not get media from disk %s",
*error = -1;
} else {
/* Get size */
error);
if (!*error) {
/* Get free slices */
}
}
}
}
}
if (*error) {
/* Normalize error */
*error = -1;
}
}
return (dp);
}
static char **
{
*error = 0;
*error = -1;
} else {
int j;
/* Count aliases */
*error = -1;
handle_error("out of memory");
} else {
/* For each alias... */
if (*error) {
handle_error("could not get alias %d "
} else {
*error = -1;
handle_error("out of memory");
}
}
}
}
}
/* Free previously-allocated names */
}
return (names);
}
static int
{
*error = 0;
if (*error) {
handle_error("could not get disk attributes for disk");
} else {
/* Try to get the status */
handle_error("could not get status of disk");
*error = 1;
}
}
return (status != 0);
}
/*
* Gets the slices for the given disk.
*
* Results:
*
* 1. Success: error is set to 0 and slices are returned
*
* 2. Failure: error is set to -1 and NULL is returned
*/
static dmgt_slice_t **
int *error)
{
*error = 0;
if (*error != 0) {
} else {
int j;
int nslices = 0;
/* For each slice... */
for (j = 0; *error == 0 &&
/* Get slice */
if (!*error) {
handle_error("out of memory");
*error = -1;
} else {
/* NULL-terminated array */
nslices++;
}
}
}
}
if (*error) {
/* Normalize error */
*error = -1;
zjni_free_array((void **)sap,
}
}
return (sap);
}
static void
{
int i;
}
}
static int
{
#ifdef DEBUG
if (overlap) {
}
#endif
return (overlap);
}
/*
* Gets the slices for the given disk.
*
* Results:
*
* 1. Success: error is set to 0 and slices are returned
*
* 2. Failure: error is set to -1 and NULL is returned
*/
static dmgt_slice_t **
{
if (*error) {
}
*in_use = 0;
int i, nslices;
/* Prune slices based on use */
for (i = nslices - 1; i >= 0; i--) {
int s_in_use;
/*
* Slice at this index could be NULL if
* removed in earlier iteration
*/
continue;
}
if (*error) {
break;
}
if (s_in_use) {
int j;
/* Disk is in use */
*in_use = 1;
/*
* Remove any slice that overlaps with this
* in-use slice
*/
for (j = nslices - 1; j >= 0; j--) {
j);
}
}
} else if (slice_too_small(slice)) {
}
}
}
if (*error) {
/* Normalize error */
*error = -1;
zjni_free_array((void **)slices,
}
}
return (slices);
}
static void
{
*size = 0;
*error = 0;
if (*error) {
handle_error("could not get media attributes from disk: %s",
name);
} else {
/* Try to get the number of accessible blocks */
/* Disk is probably not labeled, get raw size instead */
handle_error("could not get size of disk: %s",
name);
*error = 1;
}
}
if (*error == 0) {
handle_error("could not get "
"block size of disk: %s", name);
*error = 1;
} else {
}
}
}
}
static void
{
/* Get slice use statistics */
if (*error != 0) {
} else {
char *tmp;
/* Get the type of usage for this slice */
*error = -1;
handle_error("out of memory");
} else {
/* Get the object using this slice */
match =
NULL);
0) {
*error = -1;
"out of memory");
}
}
}
}
}
}
}
static dmgt_slice_t *
{
*error = 0;
*error = -1;
handle_error("out of memory");
} else {
/* Get name */
if (!*error) {
if (*error) {
handle_error("could not get "
} else {
/* Get the size in blocks */
handle_error("could not get "
*error = 1;
} else {
/* Convert to bytes */
/* Get the starting block */
NULL);
&start_blocks)) {
"could not get "
"start block of slice: %s",
*error = 1;
} else {
/* Convert to bytes */
/* Set slice use */
}
}
}
}
}
}
return (sp);
}
static void
{
if (error_func != NULL) {
}
}
/* Should go away once 6285992 is fixed */
static int
{
/* Check size */
#ifdef DEBUG
#endif
return (1);
}
return (0);
}
static int
{
int in_use;
/* Determine whether this slice could be passed to "zpool -f" */
if (*error) {
}
#ifdef DEBUG
if (in_use) {
"can't use %s: used name: %s: used by: %s\n message: %s\n",
}
#endif
}
return (in_use);
}
/*
* Extern functions
*/
/*
* Iterates through each available disk on the system. For each free
* dmgt_disk_t *, runs the given function with the dmgt_disk_t * as
* the first arg and the given void * as the second arg.
*/
int
{
int error = 0;
/* Search for fixed disks */
if (error) {
handle_error("unable to communicate with libdiskmgt");
} else {
int i;
/* For each disk... */
int online;
/* Reset error flag for each disk */
error = 0;
/* Is this disk online? */
/* Get a dmgt_disk_t for this dm_descriptor_t */
if (!error) {
/*
* If this disk or any of its
* slices is usable...
*/
/* Run the given function */
error = -1;
}
#ifdef DEBUG
} else {
"has no available slices: "
#endif
}
}
}
}
}
return (error);
}
void
{
}
}
void
{
}
}
/*
* For clients that need to capture error output.
*/
void
{
error_func = func;
}