X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=ndmp-src%2Fndma_ctrl_calls.c;fp=ndmp-src%2Fndma_ctrl_calls.c;h=93fe841e85dc5152ea306eb14efc050502a06215;hb=538ae376635af705ebcd686f3b4b7b72a6652985;hp=0000000000000000000000000000000000000000;hpb=11425c69eb58b6103beb68adc13912735ba36975;p=debian%2Famanda diff --git a/ndmp-src/ndma_ctrl_calls.c b/ndmp-src/ndma_ctrl_calls.c new file mode 100644 index 0000000..93fe841 --- /dev/null +++ b/ndmp-src/ndma_ctrl_calls.c @@ -0,0 +1,649 @@ +/* + * Copyright (c) 1998,1999,2000 + * Traakan, Inc., Los Altos, CA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +/* + * Project: NDMJOB + * Ident: $Id: $ + * + * Description: + * + */ + + +#include "ndmagents.h" + +#ifndef NDMOS_OPTION_NO_CONTROL_AGENT + + +/* + * DATA Agent calls + **************************************************************** + */ + +int +ndmca_data_get_state (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + struct ndmp9_data_get_state_reply *state = &ca->data_state; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_data_get_state, NDMP9VER) + rc = NDMC_CALL(conn); + if (rc) { + NDMOS_MACRO_ZEROFILL (state); + ca->data_state.state = -1; + } else { + *state = *reply; + } + NDMC_ENDWITH + + return rc; +} + +int +ndmca_data_listen (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + + NDMC_WITH(ndmp9_data_listen, NDMP9VER) + if (sess->plumb.tape == sess->plumb.data) { + request->addr_type = NDMP9_ADDR_LOCAL; + } else { + request->addr_type = NDMP9_ADDR_TCP; + } + rc = NDMC_CALL(conn); + if (rc) return rc; + + if (request->addr_type + != reply->data_connection_addr.addr_type) { + ndmalogf (sess, 0, 0, + "DATA_LISTEN addr_type mismatch"); + return -1; + } + + ca->data_addr = reply->data_connection_addr; + NDMC_ENDWITH + + return 0; +} + +int +ndmca_data_connect (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + ndmp9_addr addr; + + if (ca->job.tape_tcp) { + char *host; + char *port; + struct sockaddr_in sin; + + host = ca->job.tape_tcp; + port = strchr(ca->job.tape_tcp, ':'); + *port++ = '\0'; + rc = ndmhost_lookup(host, &sin); + addr.addr_type = NDMP9_ADDR_TCP; + addr.ndmp9_addr_u.tcp_addr.ip_addr = ntohl(sin.sin_addr.s_addr); + addr.ndmp9_addr_u.tcp_addr.port = atoi(port); + } else { + addr = ca->mover_addr; + } + + NDMC_WITH(ndmp9_data_connect, NDMP9VER) + request->addr = addr; + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_data_start_backup (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + unsigned n_env = ca->job.env_tab.n_env; + ndmp9_pval * env = ca->job.env_tab.env; + ndmp9_addr addr; + int rc; + + if (conn->protocol_version > 2) { + if (ca->swap_connect) { + if ( (rc = ndmca_mover_connect (sess)) != 0) { + return rc; + } + } else { + if ( (rc = ndmca_data_connect (sess)) != 0) { + return rc; + } + } + addr.addr_type = NDMP9_ADDR_AS_CONNECTED; + } else { + addr = ca->mover_addr; + } + + NDMC_WITH(ndmp9_data_start_backup, NDMP9VER) + request->addr = addr; + request->bu_type = ca->job.bu_type; + request->env.env_len = n_env; + request->env.env_val = env; + + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_data_start_recover (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + unsigned n_env = ca->job.env_tab.n_env; + ndmp9_pval * env = ca->job.env_tab.env; + unsigned n_nlist = ca->job.nlist_tab.n_nlist; + ndmp9_name * nlist = ca->job.nlist_tab.nlist; + ndmp9_addr addr; + int rc; + + if (conn->protocol_version > 2) { + if (ca->swap_connect) { + if ( (rc = ndmca_mover_connect (sess)) != 0) { + return rc; + } + } else { + if ( (rc = ndmca_data_connect (sess)) != 0) { + return rc; + } + } + addr.addr_type = NDMP9_ADDR_AS_CONNECTED; + } else { + addr = ca->mover_addr; + } + + NDMC_WITH(ndmp9_data_start_recover, NDMP9VER) + request->addr = addr; + request->bu_type = ca->job.bu_type; + request->env.env_len = n_env; + request->env.env_val = env; + request->nlist.nlist_len = n_nlist; + request->nlist.nlist_val = nlist; + + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_data_start_recover_filehist (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + unsigned n_env = ca->job.env_tab.n_env; + ndmp9_pval * env = ca->job.env_tab.env; + unsigned n_nlist = ca->job.nlist_tab.n_nlist; + ndmp9_name * nlist = ca->job.nlist_tab.nlist; + ndmp9_addr addr; + int rc; + + if (conn->protocol_version > 2) { + if (ca->swap_connect) { + if ( (rc = ndmca_mover_connect (sess)) != 0) { + return rc; + } + } else { + if ( (rc = ndmca_data_connect (sess)) != 0) { + return rc; + } + } + addr.addr_type = NDMP9_ADDR_AS_CONNECTED; + } else { + addr = ca->mover_addr; + } + + NDMC_WITH(ndmp9_data_start_recover_filehist, NDMP9VER) + request->addr = addr; + request->bu_type = ca->job.bu_type; + request->env.env_len = n_env; + request->env.env_val = env; + request->nlist.nlist_len = n_nlist; + request->nlist.nlist_val = nlist; + + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_data_abort (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_data_abort, NDMP9VER) + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_data_get_env (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + unsigned int i; + ndmp9_pval * d_pv; + ndmp9_pval * s_pv; + + NDMC_WITH_VOID_REQUEST(ndmp9_data_get_env, NDMP9VER) + rc = NDMC_CALL(conn); + if (rc) return rc; + + for (i = 0; i < reply->env.env_len; i++) { + s_pv = &reply->env.env_val[i]; + d_pv = &ca->job.result_env_tab.env[i]; + d_pv->name = NDMOS_API_STRDUP (s_pv->name); + d_pv->value = NDMOS_API_STRDUP (s_pv->value); + } + ca->job.result_env_tab.n_env = i; + + NDMC_FREE_REPLY(); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_data_stop (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.data; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_data_stop, NDMP9VER) + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + + + + + +/* + * TAPE Agent calls -- TAPE + **************************************************************** + */ + +int +ndmca_tape_open (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + + NDMC_WITH (ndmp9_tape_open, NDMP9VER) + request->device = ca->job.tape_device; + request->mode = ca->tape_mode; + rc = NDMC_CALL(conn); + ca->tape_state.error = reply->error; + NDMC_ENDWITH + + return rc; +} + +int +ndmca_tape_close (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_tape_close, NDMP9VER) + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_tape_get_state (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + struct ndm_control_agent *ca = &sess->control_acb; + struct ndmp9_tape_get_state_reply *state = &ca->tape_state; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER) + rc = NDMC_CALL(conn); + if (rc) { + NDMOS_MACRO_ZEROFILL (state); + /* tape_state.state = -1; */ + state->error = reply->error; + } else { + *state = *reply; + } + NDMC_ENDWITH + + return rc; +} + +int +ndmca_tape_get_state_no_tattle (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + struct ndm_control_agent *ca = &sess->control_acb; + struct ndmp9_tape_get_state_reply *state = &ca->tape_state; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER) + rc = ndma_call_no_tattle (conn, xa); + if (rc) { + NDMOS_MACRO_ZEROFILL (state); + /* tape_state.state = -1; */ + } else { + *state = *reply; + } + if (rc < 0 + || (reply->error != NDMP9_DEV_NOT_OPEN_ERR + && reply->error != NDMP9_NO_ERR)) + ndma_tattle (sess->plumb.tape, xa, rc); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_tape_mtio (struct ndm_session *sess, + ndmp9_tape_mtio_op op, u_long count, u_long *resid) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH(ndmp9_tape_mtio, NDMP9VER) + request->tape_op = op; + request->count = count; + + rc = NDMC_CALL(conn); + if (!rc) { + if (resid) { + *resid = reply->resid_count; + } else if (reply->resid_count != 0) { + return -1; + } + } + NDMC_ENDWITH + + return rc; +} + +int +ndmca_tape_write (struct ndm_session *sess, char *buf, unsigned count) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH(ndmp9_tape_write, NDMP9VER) + request->data_out.data_out_len = count; + request->data_out.data_out_val = buf; + rc = NDMC_CALL(conn); + if (rc == 0) { + if (reply->count != count) + rc = -1; + } + NDMC_ENDWITH + + return rc; +} + +int +ndmca_tape_read (struct ndm_session *sess, char *buf, unsigned count) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH(ndmp9_tape_read, NDMP9VER) + request->count = count; + rc = NDMC_CALL(conn); + if (rc == 0) { + if (reply->data_in.data_in_len == count) { + bcopy (reply->data_in.data_in_val, + buf, count); + } else { + rc = -1; + } + } + NDMC_FREE_REPLY(); + NDMC_ENDWITH + + return rc; +} + + +int +ndmca_tape_read_partial (struct ndm_session *sess, char *buf, unsigned count, int *read_count) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH(ndmp9_tape_read, NDMP9VER) + request->count = count; + rc = NDMC_CALL(conn); + if (rc == 0) { + *read_count = reply->data_in.data_in_len; + bcopy (reply->data_in.data_in_val, buf, *read_count); + } else { + rc = reply->error; + } + NDMC_FREE_REPLY(); + NDMC_ENDWITH + + return rc; +} + + +/* + * TAPE Agent calls -- MOVER + **************************************************************** + */ + +int +ndmca_mover_get_state (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + struct ndm_control_agent *ca = &sess->control_acb; + struct ndmp9_mover_get_state_reply *state = &ca->mover_state; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_mover_get_state, NDMP9VER) + rc = NDMC_CALL(conn); + if (rc) { + NDMOS_MACRO_ZEROFILL (state); + ca->mover_state.state = -1; + } else { + *state = *reply; + } + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_listen (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + + NDMC_WITH(ndmp9_mover_listen, NDMP9VER) + request->mode = ca->mover_mode; + + if (sess->plumb.tape == sess->plumb.data) { + request->addr_type = NDMP9_ADDR_LOCAL; + } else { + request->addr_type = NDMP9_ADDR_TCP; + } + rc = NDMC_CALL(conn); + if (rc) return rc; + + if (request->addr_type + != reply->data_connection_addr.addr_type) { + ndmalogf (sess, 0, 0, + "MOVER_LISTEN addr_type mismatch"); + return -1; + } + + ca->mover_addr = reply->data_connection_addr; + NDMC_ENDWITH + + return 0; +} + +int +ndmca_mover_connect (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + + NDMC_WITH(ndmp9_mover_connect, NDMP9VER) + request->mode = ca->mover_mode; + request->addr = ca->data_addr; + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_continue (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_mover_continue, NDMP9VER) + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_abort (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_mover_abort, NDMP9VER) + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_stop (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_mover_stop, NDMP9VER) + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_set_window (struct ndm_session *sess, + unsigned long long offset, unsigned long long length) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH(ndmp9_mover_set_window, NDMP9VER) + request->offset = offset; + request->length = length; + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_read (struct ndm_session *sess, + unsigned long long offset, unsigned long long length) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH(ndmp9_mover_read, NDMP9VER) + request->offset = offset; + request->length = length; + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_close (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + int rc; + + NDMC_WITH_VOID_REQUEST(ndmp9_mover_close, NDMP9VER) + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} + +int +ndmca_mover_set_record_size (struct ndm_session *sess) +{ + struct ndmconn * conn = sess->plumb.tape; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + + NDMC_WITH(ndmp9_mover_set_record_size, NDMP9VER) + request->record_size = ca->job.record_size; + rc = NDMC_CALL(conn); + NDMC_ENDWITH + + return rc; +} +#endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */