/*
*/
/*
* BSD 3 Clause License
*
* Copyright (c) 2007, The Storage Networking Industry Association.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* - Neither the name of The Storage Networking Industry Association (SNIA)
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <locale.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <door.h>
#include <thread.h>
#include <ndmpd_door.h>
#include <libndmp.h>
static int door_buf_size = 0;
static int ndmp_door_setup(int opcode);
static int ndmp_door_call(ndmp_door_err_t *);
static int ndmp_door_fini(void);
/* ndmp library APIs */
int
{
int i;
(void) mutex_lock(&ndmp_lock);
/*
* the first door call is to get the device count
* which will be used to calculate the door buffer size
*/
if (ndmp_door_setup(NDMP_GET_DEV_CNT) ||
ndmp_door_call(&derr)) {
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
/* number of devices */
if (ndmp_door_fini() ||
ndmp_door_call(&derr)) {
ndmp_num_dev = 0;
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
/* get the number of devices available */
/* calloc to ensure NULL pointers in allocated struct */
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
/* Free all allocations if any failed */
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
}
if (ndmp_door_fini()) {
/* Free all allocations if anything failed */
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
(void) mutex_unlock(&ndmp_lock);
return (0);
}
void
{
int i;
}
}
}
int
{
int ret;
(void) mutex_lock(&ndmp_lock);
if (ndmp_door_setup(opcode))
goto err;
if (ndmp_door_call(&derr))
goto err;
if (ndmp_door_fini())
goto err;
(void) mutex_unlock(&ndmp_lock);
return (ret);
err:
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
int
{
int status;
int i, j;
int prev_num_conn = 0;
int attempts = 0;
(void) mutex_lock(&ndmp_lock);
goto err;
if (ndmp_door_call(&derr))
goto err;
/* number of sessions */
if (ndmp_door_fini())
goto err;
/*
* Now setup the door again, this time
* with the intention of getting the session
* specific info.
*/
if (ndmp_door_setup(NDMP_SHOW))
goto err;
if (ndmp_door_call(&derr)) {
/*
* If we failed because of space constraints
* then reevaluate and give it another try,
* but only if the number of sessions actually changed
* between our previous call and now. If they are
* equal, then retrying is fruitless.
*/
(prev_num_conn < ndmp_num_conn)) {
continue;
} else {
goto err;
}
} else {
/*
* If the door call was successful then
* no need to continue to retry. Break out
* of the loop now.
*/
break;
}
}
/* number of sessions */
/* calloc to ensure NULL pointers in allocated struct */
goto err;
}
if (status == NDMP_SESSION_NODATA)
continue;
/* connection common info */
/*
* scsi and tape data are same for all version,
* so keep reading
*/
/* connection common scsi info. */
}
/* connection common tape info. */
}
}
/* connection common data info */
/* calloc to ensure NULL pointers in allocated struct */
goto err;
}
}
/* Read V2 data info */
/* calloc to ensure NULL pointers in allocated struct */
sizeof (ndmp_dt_name_t));
goto err;
}
}
/* calloc to ensure NULL pointers in allocated struct */
sizeof (ndmp_dt_name_v3_t));
goto err;
}
j++, npv3++) {
npv3->nn3_fh_info =
}
}
}
if (ndmp_door_fini()) {
goto err;
}
(void) mutex_unlock(&ndmp_lock);
return (0);
err:
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
void
{
int i, j;
/*
* Protect against dereferencing a null pointer in any of the following code.
* If *sinfopp == NULL, assume that everything was already freed previously.
*/
return;
}
}
}
}
j++, npv3++) {
}
}
}
}
/* ARGSUSED */
int
{
(void) mutex_lock(&ndmp_lock);
if (!statp) {
goto err;
}
if (ndmp_door_setup(opcode))
goto err;
if (ndmp_door_call(&derr))
goto err;
if (ndmp_door_fini())
goto err;
(void) mutex_unlock(&ndmp_lock);
return (0);
err:
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
int
ndmp_door_status(void)
{
(void) mutex_lock(&ndmp_lock);
if (ndmp_door_setup(opcode))
goto err;
if (ndmp_door_call(&derr))
goto err;
if (ndmp_door_fini())
goto err;
(void) mutex_unlock(&ndmp_lock);
return (0);
err:
(void) mutex_unlock(&ndmp_lock);
return (-1);
}
static int
{
/* Open channel to NDMP service */
if ((ndmp_door_fildes == -1) &&
return (-1);
}
switch (opcode) {
case NDMP_SHOW:
break;
case NDMP_DEVICES_GET_INFO:
break;
default:
}
/*
* No matter what, we don't allow our
* door size to be less than NDMP_DOOR_SIZE
*/
if (door_buf_size < NDMP_DOOR_SIZE)
return (-1);
}
if (enc_ctx == 0) {
return (-1);
}
/*
* If it is an opcode that can elicit a variant
* response in size, tell the door callee
* how much memory to alloc when forming the
* response.
*/
switch (opcode) {
case NDMP_SHOW:
case NDMP_DEVICES_GET_INFO:
break;
}
return (0);
}
static int
{
int rc;
return (-1);
}
(void) close(ndmp_door_fildes);
ndmp_door_fildes = -1;
return (-1);
}
if (rc != NDMP_DOOR_SRV_SUCCESS) {
return (-1);
}
return (0);
}
static int
ndmp_door_fini(void)
{
if ((ndmp_door_decode_finish(dec_ctx)) != 0) {
return (-1);
}
return (0);
}