rdc_clnt.c revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Network data replicator Client side */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * define enum_t here as it is all we need from rpc/types.h
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anyway and make it look like we included it. Yuck.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SunOS_2_6 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void rdc_clnt_free(struct chtab *, CLIENT *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint rdc_diskq_enqueue(rdc_k_info_t *krdc, rdc_aio_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid rdc_init_diskq_header(rdc_group_t *grp, dqheader *hd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_aio_t *rdc_dequeue(rdc_k_info_t *krdc, int *rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid rdc_clr_iohdr(rdc_k_info_t *krdc, nsc_off_t qpos);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern void rdc_fail_diskq(rdc_k_info_t *krdc, int wait, int flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_getsize: null intf for index %d", index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_int, (char *)&remote_index,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte err = rdc_clnt_call(krdc->lsrv, RDCPROC_GETSIZE6,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_int, (char *)&remote_index,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned short *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(urdc->primary.addr.buf, s4.netaddr, s4.netaddrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(urdc->secondary.addr.buf, s4.rnetaddr, s4.rnetaddrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(s4.pfile, urdc->primary.file, RDC_MAXNAMLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(s4.sfile, urdc->secondary.file, RDC_MAXNAMLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_set_state4, (char *)&s4, xdr_int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)&remote_index, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(urdc->primary.addr.buf, s.netaddr.buf, s.netaddrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(urdc->secondary.addr.buf, s.rnetaddr.buf, s.rnetaddrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_set_state, (char *)&s, xdr_int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)&remote_index, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_net_getbmap
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * gets the bitmaps from remote side and or's them with remote bitmap
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_getbmap: null intf for index %d", index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_bmap, (char *)&b, xdr_int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)&err, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_bmap6, (char *)&b6, xdr_int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)&err, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return state corresponding to rdc_host
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_net_getstate(rdc_k_info_t *krdc, int *serial_mode, int *use_mirror,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned short *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *setp = (char *)&s;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (krdc->lsrv && (krdc->intf == NULL || krdc->intf->if_down) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(urdc->primary.addr.buf, s.netaddr.buf, s.netaddrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(urdc->secondary.addr.buf, s.rnetaddr.buf, s.rnetaddrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte err = rdc_clnt_call(krdc->lsrv, RDCPROC_GETSTATE4, krdc->rpc_version,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (err == RPC_PROGVERSMISMATCH && (krdc->rpc_version !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* set_state struct changed with v7 of protocol */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* x64 can not use protocols < 7 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "sndr get_state: Protocol ver %d", krdc->rpc_version);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reply from remote read (client side)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (xdr_union(xdrs, (enum_t *)&(rr->rr_status),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&(rr->rr_ok), rdres_discrim, xdr_void));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_net_read(int local_index, int remote_index, nsc_buf_t *handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!RDC_HANDLE_LIMITS(handle, fba_pos, fba_len)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (krdc->remote_fd && !(rdc_get_vflags(urdc) & RDC_FCAL_FAILED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = nsc_alloc_buf(krdc->remote_fd, fba_pos, fba_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = nsc_copy(remote_h, handle, fba_pos, fba_pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_read: null intf for index %d", local_index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * switch on proto version.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rr.rr_bufsize = 0; /* rpc data buffer length (bytes) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte transflag = rpc_flag | RDC_RREAD_START; /* setup rpc */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list.pos = (int)fba_pos; /* fba position of start of chunk */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* send setup rpc */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_rread, (char *)&list, xdr_int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)&ret, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list6.pos = fba_pos; /* fba position of start of chunk */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* send setup rpc */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->rpc_version, xdr_rread6, (char *)&list6, xdr_int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)&ret, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "rdc_net_read: setup err %d", err);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0) { /* No valid index from r_net_read */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_read: no valid index from r_net_read");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list.idx = ret; /* save idx to return to server */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* move onto to data xfer rpcs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list6.idx = ret; /* save idx to return to server */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* find starting position in handle */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_addr = vec->sv_addr + FBA_SIZE(fba_pos); /* data in vector */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_len = vec->sv_len - FBA_SIZE(fba_pos); /* bytes in vector */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* last data xfer rpc - tell server to cleanup */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rr.rr_data = kmem_alloc(rr.rr_bufsize, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "rdc_net_read: kmem_alloc failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get data from remote end */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_read: null intf for index %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*CONSTCOND*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "rdc_net_read: rpc err %d", err);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy into handle */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(rr.rr_data, sv_addr, (size_t)rr.rr_bufsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update counters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_IO_PTR(krdc->io_kstats)->nread += rr.rr_bufsize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* goto next vector */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_net_write
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Main remote write client side
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handles protocol selection as well as requests for remote allocation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and data transfer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Does local IO for FCAL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * caller must clear bitmap on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_net_write(int local_index, int remote_index, nsc_buf_t *handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t fba_pos, nsc_size_t fba_len, uint_t aseq, int qpos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if not a diskq buffer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((qpos == -1) && (!RDC_HANDLE_LIMITS(handle, fba_pos, fba_len))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "rdc_net_write: handle bounds");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FCAL IO */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (krdc->remote_fd && !(rdc_get_vflags(urdc) & RDC_FCAL_FAILED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = nsc_alloc_buf(krdc->remote_fd, fba_pos, fba_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = nsc_copy(handle, remote_h, fba_pos, fba_pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * At this point we must decide which protocol we are using and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * do the right thing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_write: null intf for index %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * find starting position in vector
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((qpos == -1) || (handle->sb_user == RDC_NULLBUFREAD))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_len = vec->sv_len - FBA_SIZE(fpos); /* bytes in vector */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte transptr = (char *)vec->sv_addr + FBA_SIZE(fpos);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlist5.sfba = (int)fba_pos; /* starting fba for this xfer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlist6.sfba = fba_pos; /* starting fba for this xfer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_write: walked off end of handle!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* last data xfer - tell server to commit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_write: null intf for index %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)&ret, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)netresptr, &t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_write(5): cd %d err %d ret %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Error from r_net_write5 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_write: r_net_write(5) "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "returned: %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_net_write: no valid index from "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "r_net_write(5)");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update counters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* goto next vector */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this can't happen.....
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_dump_alloc_bufs_cd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dump allocated buffers (rdc_net_hnd's) for the specified cd.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this could be the flusher failing, if so, don't do the delay forever
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns: 0 (success), EAGAIN (caller needs to try again).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* cannot do anything! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_dump_alloc_bufs_cd(%d): c_fd NULL",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now dump the async queue anonymous buffers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if we are a diskq, the we are using the diskq mutex.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * However, we are flushing from diskq to memory queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we now need to grab the memory lock also
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "dumpalloccd sending diskq->memq flusher to sleep");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (q->qfill_sleeping == RDC_QFILL_AWAKE && tries--)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmpkrdc->io_kstats && !RDC_IS_DISKQ(krdc->group)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_waitq_exit(KSTAT_IO_PTR(tmpkrdc->io_kstats));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_dump_alloc_bufs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have an error on the link
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try to dump all of the allocated bufs so we can cleanly recover
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and not hang
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns 1 if the the throttle should throttle, 0 if not.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ---T----H----N--- */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Throttle entries on queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Need to take the 1-many case into account, checking all sets */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ADD HANDY HUERISTIC HERE TO SLOW DOWN IO */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (krdc = this; /* CSTYLED */; krdc = krdc->many_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this may be the last set standing in a one to many setup.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we may also be stuck in unintercept, after marking
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the volume as not enabled, but have not removed it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from the many list resulting in an endless loop if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we just continue here. Lets jump over this stuff
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and check to see if we are the only dude here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_ASYNC(urdc) && RDC_IS_MEMQ(krdc->group)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((q->blocks + q->inflbls) > urdc->maxqfbas ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* do a much more aggressive delay, get disk flush going */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_ASYNC(urdc) && RDC_IS_DISKQ(krdc->group)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " disk queue %s full",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "SNDR: disk queue %s full and not flushing. giving up",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "SNDR: %s:%s entering logging mode",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdc_joins = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_aio_coalesce(rdc_aio_t *queued, rdc_aio_t *new)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0); /* don't even try */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0); /* existing queue is empty */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (queued->index != new->index || queued->len + new->len >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0); /* I/O to big */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_abuf(queued->pos, queued->len + new->len, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0); /* couldn't do coalesce */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_copy(queued->handle, h, queued->pos, queued->pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0); /* couldn't do coalesce */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_copy(new->handle, h, new->pos, new->pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0); /* couldn't do coalesce */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte RDC_SET_BITMASK(queued->pos, queued->len, &bitmask);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bump the ref count back up
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte RDC_SET_BITMAP(krdc, queued->pos, queued->len, &bitmask);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1); /* new I/O succeeds last I/O queued */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_memq_enqueue(rdc_k_info_t *krdc, rdc_aio_t *aio)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* adding to empty q */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc enqueue: q %p, qhead 0, q blocks %" NSC_SZFMT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* discontiguous, add aio to q tail */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_waitq_enter(KSTAT_IO_PTR(krdc->io_kstats));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* sum the q and check for sanity */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (qblocks != q->blocks || nitems != q->nitems) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NSC_SZFMT "), nitems %" NSC_SZFMT " (%" NSC_SZFMT ")",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_rdc_enqueue_write(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len, int flag,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Async Network RDC flusher
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't allow any new writer threads to start if a member of the set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is disable pending
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_writer -- spawn new writer if not running already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called after enqueing the dirty blocks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((group->rdc_writer) || is_disable_pending(krdc)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((group->rdc_thrnum >= 1) && (group->seqack == RDC_NEWSEQ)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We also need to check if we are starting a new
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sequence, and if so don't create a new thread,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as we must ensure that the start of new sequence
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * requests arrives first to re-init the server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For version 6,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * see if we can fit in another thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (krdc->intf && (krdc->intf->rpc_version >= RDC_VERSION6)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we got here, we know that we have not exceeded the allowed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * number of async threads for our group. If we run out of threads
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in _rdc_flset, we add a new thread to the set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* first try to grab a thread from the free list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t = nst_create(_rdc_flset, rdc_flusher_thread,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* that failed; add a thread to the set and try again */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_writer index %d nst_add_thread "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_writer: index %d nst_create error", index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((group->count == 0) && (group->rdc_thrnum == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Race with remove_from_group while write thread was
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failing to be created.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_writer: group being destroyed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Either we need to flush the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kmem (net_queue) queue or the disk (disk_queue)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * determine which, and do it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* uh-oh, big time */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "flusher trying to flush unknown queue type");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_memq: no group left!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_memq: DISABLE PENDING!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Need to continue as we may be trying to flush IO
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * while trying to disable or suspend
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_memq: no group left!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (q->nitems != 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_flush_memq(1): q %p, q blocks %"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ", qhead %p qtail %p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* aio remove from q */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in flight numbers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (q->nitems != 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_flush_memq(2): q %p, q blocks %"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ", qhead %p qtail %p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *) q->net_qtail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (q->blocks < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ", nitems %d, qhead %p, qtail %p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* blocks and nitems are unsigned for NSC_MULTI_TERABYTE */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We are an old thread, and the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * queue sequence has been reset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * during the network write above.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * As such we mustn't pull another
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * job from the queue until the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * first sequence message has been ack'ed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Just die instead. Unless this thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is the first sequence that has just
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * been ack'ed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((aio->iostatus != RDC_IO_DONE) && (group->count)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "memq flush aio status not RDC_IO_DONE");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (krdc->remote_index < 0 || !krdc->lsrv || !krdc->intf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * all threads must be dead.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((group->count == 0) && (group->rdc_thrnum == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Group now empty, so destroy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Race with remove_from_group while write thread was running
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_memq: group being destroyed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_flush_diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * disk queue flusher
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_diskq: no group left!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_diskq: DISABLE PENDING!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Need to continue as we may be trying to flush IO
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * while trying to disable or suspend
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_QSTATE(q, RDC_QDISABLEPEND) || IS_STATE(urdc, RDC_LOGGING)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "flusher thread death 1 %x", QSTATE(q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_diskq: no group left!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We are an old thread, and the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * queue sequence has been reset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * during the network write above.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * As such we mustn't pull another
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * job from the queue until the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * first sequence message has been ack'ed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Just die instead. Unless of course,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this thread is the first sequence that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has just been ack'ed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((aio->iostatus != RDC_IO_DONE) && (group->count)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "diskq flush aio status not RDC_IO_DONE");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_flush_diskq: DISABLE PENDING after IO!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (krdc->remote_index < 0 || !krdc->lsrv || !krdc->intf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((group->count == 0) && (group->rdc_thrnum == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Group now empty, so destroy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Race with remove_from_group while write thread was running
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_flush_diskq: group being destroyed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _rdc_remote_flush
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Flush a single block ANON block
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function will flush from either the disk queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or the memory queue. The appropriate locks must be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * taken out etc, etc ...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Where did we get this aio from anyway? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * quench transmission if we are too far ahead of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * server Q, or it will overflow.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Must fail all requests while asyncdis is set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It will be cleared when the last thread to be discarded
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sets the asyncstall counter to zero.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note the thread within rdc_net_write
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * also bumps the asyncstall counter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* don't go to sleep if we have gone logging! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vflags & (RDC_BMP_FAILED|RDC_VOL_FAILED|RDC_LOGGING))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vflags & RDC_LOGGING) && RDC_IS_DISKQ(group))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (maxseq = group->seqack + RDC_MAXPENDQ + 1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maxseq = (maxseq < group->seqack) ? maxseq + RDC_NEWSEQ + 1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if we have gone into logging mode
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * since sleeping.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vflags & (RDC_BMP_FAILED|RDC_VOL_FAILED|RDC_LOGGING)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vflags & RDC_LOGGING) && RDC_IS_DISKQ(group))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((krdc->io_kstats) && (!RDC_IS_DISKQ(krdc->group))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "_rdc_remote_flush: reserve, index %d, rc %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Case where we are multihop and calling with no ANON bufs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Need to do the read to fill the buf.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_buf(RDC_U_FD(krdc), aio->pos, aio->len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "_rdc_remote_flush: alloc_buf, index %d, pos %"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this should be ok, we are flushing, not rev syncing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remote_index could be -1 if we lost a race with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * resume and the flusher trys to flush an io from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * another set that has not resumed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->remote_index = rdc_net_state(krdc->index, CCIO_SLAVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * double check for logging, no check in net_write()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * skip the write if you can, otherwise, if logging
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * avoid clearing the bit .. you don't know whose bit it may
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = rdc_net_write(krdc->index, krdc->remote_index,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte aio->handle, aio->pos, aio->len, aio->seq, aio->qpos, &netret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "_rdc_remote_flush: write, index %d, pos %" NSC_SZFMT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rc %d seq %u group seq %u seqack %u qpos %" NSC_SZFMT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Hard timeout detected (%d sec) "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "on SNDR set %s:%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free locally alloc'd handle */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(vflags & (RDC_BMP_FAILED|RDC_VOL_FAILED|RDC_LOGGING))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* tell queue data has been flushed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* throw away queue, logging */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check to see if the reply has arrived out of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * order, if so don't update seqack.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * see if we have any pending async requests we can mark
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vecpe = netret.vecdata.vecdata_val + netret.vecdata.vecdata_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we must always still be in the same group.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update queue info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* we've gone logging */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * see if we can re-start transmission
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netret.vecdata.vecdata_len * sizeof (net_pendvec_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* perhaps we have a few threads stuck .. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netret.vecdata.vecdata_len * sizeof (net_pendvec_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free locally alloc'd hanlde */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((waitq && krdc->io_kstats) && (!RDC_IS_DISKQ(krdc->group))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* make sure that the bit is still set */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_drain_disk_queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * drain the async network queue for the whole group. Bail out if nothing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * happens in 20 sec
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns -1 if it bails before the queues are drained.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NUM_RETRIES 15 /* Number of retries to wait if no progress */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Sanity checking */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there is no group or diskq configured, we can leave now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(group = krdc->group) || !(diskq = &group->diskq))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No need to wait if EMPTY and threads are gone
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Capture counters to determine if progress is being made
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Has the group or disk queue gone away while delayed?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(group = krdc->group) || !(diskq = &group->diskq))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Are we still seeing progress?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (blocks == QBLOCKS(diskq) && threads == group->rdc_thrnum) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No progress seen, increment retry counter
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset counter, as we've made progress
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * decide what needs to be drained, disk or core
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and drain it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* oops.. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "rdc_drain_queue: attempting drain of unknown Q type");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_drain_net_queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * drain the async network queue for the whole group. Bail out if nothing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * happens in 20 sec
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns -1 if it bails before the queues are drained.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Sanity checking */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((volatile rdc_aio_t *)q->net_qhead == NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte q = (volatile net_queue *)&krdc->group->ra_queue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_dump_queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We want to release all the blocks currently on the network flushing queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We already have them logged in the bitmap.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * gotta have both locks here for diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "dumpq sending diskq->memq flusher to sleep");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (q->qfill_sleeping == RDC_QFILL_AWAKE && tries--)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte group->seq = RDC_NEWSEQ; /* reset the sequence number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if the q is on disk, dump the q->iohdr chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* back up the nxtio pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmpkrdc->io_kstats && !RDC_IS_DISKQ(group)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_waitq_exit(KSTAT_IO_PTR(tmpkrdc->io_kstats));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if we have stalled threads.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_clnt_get
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get a CLIENT handle and cache it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_clnt_get(rdc_srv_t *svp, rpcvers_t vers, struct chtab **rch, CLIENT **clp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retries = 6; /* Never used for COTS in Solaris */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* find the right ch_list chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ch = rdc_chtable; ch != NULL; ch = ch->ch_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* found the correct chain to walk */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* walk the ch_list and try and find a free client */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (num_clnts = 0; ch != NULL; ch = ch->ch_list, num_clnts++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* suitable handle to reuse */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* alloc a temporary handle and return */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = clnt_tli_kcreate(svp->ri_knconf, &(svp->ri_addr),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) CLNT_CONTROL(client, CLSET_PROGRESS, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* reuse a cached handle */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = clnt_tli_kcreate(svp->ri_knconf, &(svp->ri_addr),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) CLNT_CONTROL(ch->ch_client, CLSET_PROGRESS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Consecutive calls to CLNT_CALL() on the same client handle
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get the same transaction ID. We want a new xid per call,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we first reinitialise the handle.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) clnt_tli_kinit(ch->ch_client, svp->ri_knconf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* create new handle and cache it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ch = (struct chtab *)kmem_zalloc(sizeof (*ch), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(svp->ri_knconf->knc_protofmly)+1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = clnt_tli_kcreate(svp->ri_knconf, &(svp->ri_addr),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "rdc_call: tli_kcreate failed %d", ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_clnt_call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Arguments:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_srv_t *svp - rdc servinfo
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rpcproc_t proc; - rpcid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rpcvers_t vers; - protocol version
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * xdrproc_t xargs;- xdr function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * caddr_t argsp;- args to xdr function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * xdrproc_t xres;- xdr function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * caddr_t resp;- args to xdr function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * struct timeval timeout;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs RPC client call using specific protocol and version
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_clnt_call(rdc_srv_t *svp, rpcproc_t proc, rpcvers_t vers,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xdrproc_t xres, caddr_t resp, struct timeval *timeout)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte err = cl_call_sig(rh, proc, xargs, argsp, xres, resp, *timeout);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fall thru */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Delay here to err on side of caution */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fall thru */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The call is in progress (over COTS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try the CLNT_CALL again, but don't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * print a noisy error message
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call an rpc from the client side, not caring which protocol is used.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_clnt_call_any(rdc_srv_t *svp, rdc_if_t *ip, rpcproc_t proc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xdrproc_t xres, caddr_t resp, struct timeval *timeout)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = rdc_clnt_call(svp, proc, vers, xargs, argsp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Downgrade and try again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while ((vers >= RDC_VERS_MIN) && (rc == RPC_PROGVERSMISMATCH));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc == 0) && (ip != NULL) && (vers != ip->rpc_version)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call an rpc from the client side, starting with protocol specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_clnt_call_walk(rdc_k_info_t *krdc, rpcproc_t proc, xdrproc_t xargs,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = rdc_clnt_call(svp, proc, vers, xargs, argsp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Downgrade and try again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while ((vers >= RDC_VERS_MIN) && (rc == RPC_PROGVERSMISMATCH));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc == 0) && (ip != NULL) && (vers != ip->rpc_version)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_clnt_free
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free a client structure into the cache, or if this was a temporary
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle allocated above MAXCLIENTS, destroy it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* cached client, just clear inuse flag and return */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* temporary handle allocated above MAXCLIENTS, so destroy it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _rdc_clnt_destroy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free a chain (ch_list or ch_next) of cached clients
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_rdc_clnt_destroy(struct chtab **p, const int list)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (*p != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unlink from the chain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - this leaks the client if it was inuse
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* unused client - destroy it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* remember client leak */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_clnt_destroy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free client caching table on unconfigure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* destroy each ch_list chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* destroy the main ch_next chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we are about to leak clients */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_clnt_destroy: leaking %d inuse clients", leak);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function to send an asynchronous net_data6 request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * direct to a server to allow the generation of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * out of order requests for ZatoIchi tests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copyin the user's arguments.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(arg, &async6, sizeof (async6), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * search by the secondary host and file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((strncmp(urdc->secondary.intf, async6.sechost,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "start %d length %d sub start %d sub length %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte async6.pos, async6.len, async6.spos, async6.slen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill in the net databuffer prior to transmission.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = rdc_clnt_call(krdc->lsrv, RDCPROC_WRITE6, krdc->rpc_version,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xdr_net_data6, (char *)&data6, xdr_netwriteres, (char *)&netret,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "async6: seq %u result %d index %d "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pendcnt %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < netret.vecdata.vecdata_len; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "async6: rpc call failed %d", rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function to send an net_read6 request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * direct to a server to allow the generation of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * read requests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rr.rr_bufsize = 0; /* rpc data buffer length (bytes) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(arg, &readgen32, sizeof (readgen32), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(readgen.sechost, readgen32.sechost,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(readgen.secfile, readgen32.secfile, NSC_MAXPATH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte readgen.data = (void *)(unsigned long)readgen32.data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(arg, &readgen, sizeof (readgen), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = rdc_lookup_byhostdev(readgen.sechost, readgen.secfile);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we should really call setbusy here.