/*
* 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.
*/
#define _RDC_
#include <sys/sysmacros.h>
#include <sys/nsc_thread.h>
#ifdef DS_DDICT
#include "../contract.h"
#endif
#include "rdc.h"
#include "rdc_io.h"
#include "rdc_bitmap.h"
#include "rdc_ioctl.h"
#include "rdcsrv.h"
#include "rdc_diskq.h"
int *rvp);
void **result);
#ifdef DEBUG
static int rdc_clrkstat(void *);
#endif
/*
* kstat interface
*/
};
};
nulldev, /* no strategy */
nodev, /* no dump */
nodev, /* no read */
nodev, /* no write */
nodev, /* no devmap */
nodev, /* no mmap */
nodev, /* no segmap */
NULL, /* not STREAMS */
nodev, /* no aread */
nodev, /* no awrite */
};
0,
nulldev, /* identify */
nulldev, /* probe */
nodev, /* no reset */
};
"nws:Remote Mirror:" ISS_VERSION_STR,
};
&rdc_ldrv,
};
static void *rdc_dip;
extern int _rdc_init_dev();
extern void _rdc_deinit_dev();
extern void rdc_link_down_free();
int rdc_bitmap_mode;
int rdc_auto_sync;
int rdc_max_sets;
extern int rdc_health_thres;
static void
{
rdc_sync_event.master[0] = 0;
}
static void
{
}
int
_init(void)
{
return (mod_install(&rdc_modlinkage));
}
int
_fini(void)
{
return (mod_remove(&rdc_modlinkage));
}
int
{
}
static int
{
int instance;
int i;
/*CONSTCOND*/
if (cmd != DDI_ATTACH)
return (DDI_FAILURE);
flags = 0;
/*
* rdc_max_sets must be set before calling _rdc_load().
*/
if (_rdc_init_dev()) {
goto out;
}
if (_rdc_load() != 0) {
goto out;
}
if (_rdc_configure()) {
goto out;
}
!= DDI_SUCCESS) {
goto out;
}
"rdc_bitmap_mode", 0);
switch (rdc_bitmap_mode) {
case RDC_BMP_AUTO: /* 0 */
break;
case RDC_BMP_ALWAYS: /* 1 */
break;
case RDC_BMP_NEVER: /* 2 */
"!SNDR: bitmaps will only be written on shutdown\n");
break;
default: /* unknown */
"!SNDR: unknown bitmap mode %d - autodetecting mode",
break;
}
"rdc_auto_sync", 0);
"rdc_health_thres", RDC_HEALTH_THRESHOLD);
if (i >= RDC_MIN_HEALTH_THRES)
rdc_health_thres = i;
else
"as it is smaller than the min value of %d",
sizeof (sndr_m_stats_t) / sizeof (kstat_named_t),
if (sndr_kstats) {
} else
return (DDI_SUCCESS);
out:
return (DDI_FAILURE);
}
static int
{
int rdcd;
if (cmd != DDI_DETACH) {
return (DDI_FAILURE);
}
goto cleanup;
#ifdef DEBUG
"!rdc: cannot detach, rdcd %d still in use", rdcd);
#endif
return (DDI_FAILURE);
}
}
if (sndr_kstats) {
}
(void) _rdc_deconfigure();
(void) _rdc_unload();
}
return (DDI_SUCCESS);
}
/* ARGSUSED */
static int
{
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
rc = DDI_SUCCESS;
break;
case DDI_INFO_DEVT2INSTANCE:
/* We only have a single instance */
*result = 0;
rc = DDI_SUCCESS;
break;
default:
break;
}
return (rc);
}
/* ARGSUSED */
static int
{
return (0);
}
/* ARGSUSED */
static int
{
return (0);
}
/* ARGSUSED */
static int
{
int instance = 0;
return (0);
}
static int
{
return (EFAULT);
switch (cmd) {
case RDC_CONFIG:
break;
case RDC_STATUS:
break;
case RDC_ENABLE_SVR:
break;
case RDC_VERSION:
break;
case RDC_SYNC_EVENT:
break;
case RDC_LINK_DOWN:
break;
case RDC_POOL_CREATE:
break;
case RDC_POOL_WAIT:
break;
case RDC_POOL_RUN:
break;
default:
return (EINVAL);
}
return (0);
}
/*
* Build a 32bit rdc_set structure and copyout to the user level.
*/
int
{
#ifdef DEBUG
#endif
tailsize = sizeof (struct rdc_addr32) -
/* primary address structure, avoiding netbuf */
/* secondary address structure, avoiding netbuf */
/*
* the rest, avoiding netconfig
* note: the tail must be the same size in both structures
*/
#ifdef DEBUG
/*
* ASSERT is calling for debug reason, and tailsize32 is only declared
* for ASSERT, put them under debug to avoid lint warning.
*/
tailsize32 = sizeof (struct rdc_set32) -
#endif
/* copyout to user level */
}
/*
* Status ioctl.
*/
static int
{
return (EFAULT);
}
} else {
return (EFAULT);
}
}
for (i = 0, j = 0; i < max; i++) {
urdc = &rdc_u_info[i];
krdc = &rdc_k_info[i];
if (!IS_ENABLED(urdc))
continue;
/*
* sneak out qstate in urdc->flags
* this is harmless because it's value is not used
* in urdc->flags. the real qstate is kept in
* group->diskq->disk_hdr.h.state
*/
}
j++;
return (EFAULT);
}
/* copyout rdc_max_sets value */
return (EFAULT);
/* copyout number of sets manipulated */
/*CONSTCOND*/
/*CONSTCOND*/
}
/* ARGSUSED */
static int
{
int error;
int rc = 0;
if (cmd != RDC_STATUS) {
return (error);
}
#ifdef DEBUG
if (cmd == RDC_ASYNC6) {
return (rc);
}
if (cmd == RDC_CLRKSTAT) {
return (rc);
}
if (cmd == RDC_STALL0) {
return (EINVAL);
rdc_stallzero((int)arg);
return (0);
}
if (cmd == RDC_READGEN) {
return (rc);
}
#endif
if (cmd == RDC_BITMAPOP) {
== DDI_MODEL_ILP32) {
mode))
return (EFAULT);
} else {
mode))
return (EFAULT);
}
return (rc);
}
return (rc);
} else {
sizeof (_rdc_ioctl_t), mode)) {
return (EFAULT);
}
}
kstatus = spcs_s_kcreate();
if (!kstatus) {
return (ENOMEM);
}
switch (cmd) {
case RDC_POOL_CREATE: {
struct svcpool_args p;
return (EFAULT);
}
error = svc_pool_create(&p);
break;
}
case RDC_POOL_WAIT: {
int id;
return (EFAULT);
}
break;
}
case RDC_POOL_RUN: {
int id;
return (EFAULT);
}
break;
}
case RDC_ENABLE_SVR:
{
/* Only used by sndrd which does not use unistat */
return (EFAULT);
}
}
break;
case RDC_STATUS:
break;
case RDC_CONFIG:
return (rc);
case RDC_VERSION:
{
return (EFAULT);
}
break;
}
case RDC_LINK_DOWN:
/* char *host from user */
return (rc);
case RDC_SYNC_EVENT:
return (rc);
default:
break;
}
return (rc);
}
int
{
extern int rdc_rpc_tmout;
extern int rdc_health_thres;
extern int rdc_bitmap_delay;
extern long rdc_clnt_count;
extern long rdc_svc_count;
/* no writes currently allowed */
if (rw == KSTAT_WRITE) {
return (EACCES);
}
/* default to READ */
/* clts counters not implemented yet */
return (0);
}
/*
* copy tailsize-1 bytes of tail of s to s1.
*/
void
{
/* To avoid un-terminated string, max size is 16 - 1 */
/* ensure it's null terminated */
}
int
{
/* no writes currently allowed */
if (rw == KSTAT_WRITE) {
return (EACCES);
}
/* default to READ */
} else {
}
}
}
return (0);
}
void
{
int j = index;
if (!krdc->set_kstats) {
sizeof (rdc_info_stats_t) / sizeof (kstat_named_t),
#ifdef DEBUG
if (!krdc->set_kstats)
#endif
if (krdc->set_kstats) {
/* calculate exact size of KSTAT_DATA_STRINGs */
} else {
}
} else
}
}
if (krdc->bmp_kstats) {
}
}
void
{
if (krdc->set_kstats) {
}
}
if (krdc->bmp_kstats) {
}
}
#ifdef DEBUG
/*
* Reset the io_kstat structure of the krdc specified
* by the arg index.
*/
static int
{
int index;
return (EINVAL);
}
} else {
return (EINVAL);
}
} else {
return (EINVAL);
}
/*
* clear the high water marks and throttle.
*/
}
return (0);
}
#endif