Beispiel #1
0
Datei: up7.c Projekt: bradh/LDM
/**
 * Ensures the existence of a client-side transport on the TCP connection.
 *
 * @param[in] xprt      Server-side RPC transport.
 * @retval    true      Success.
 * @retval    false     System error. `log_start()` called.
 */
static bool
up7_ensureClientTransport(
        struct SVCXPRT* const xprt)
{
    bool status;

    if (NULL == clnt) {
        /*
         * Create a client-side RPC transport on the TCP connection.
         */
        do {
            clnt = clnttcp_create(&xprt->xp_raddr, LDMPROG, SEVEN,
                    &xprt->xp_sock, MAX_RPC_BUF_NEEDED, 0);
            /* TODO: adjust sending buffer size in above */
        } while (clnt == NULL && rpc_createerr.cf_stat == RPC_TIMEDOUT);

        if (clnt == NULL ) {
            LOG_START2("Couldn't create client-side transport to downstream LDM-7 on "
                    "%s%s", hostbyaddr(&xprt->xp_raddr), clnt_spcreateerror(""));
            status = false;
        }
        else {
            status = true;
        }
    }

    return status;
}
Beispiel #2
0
/*
 * Sends a data-product to an LDM using the LDM-5 messages COMINGSOON and
 * BLOCKDATA.
 *
 * Arguments:
 *      proxy           Pointer to the LDM proxy data-structure.
 *      info            Pointer to the data-product's metadata.
 *      datap           Pointer to the data-product's data.
 * Returns:
 *      0               Success.
 *      LP_UNWANTED     Data-product was unwanted.
 *      LP_TIMEDOUT     The RPC call timed-out. "log_start()" called.
 *      LP_RPC_ERROR    RPC error. "log_start()" called.
 *      LP_LDM_ERROR    LDM error. "log_start()" called.
 */
static LdmProxyStatus
my_csbd_5(
    LdmProxy* const     proxy,
    product* const      product)
{
    CLIENT* const       clnt = proxy->clnt;
    LdmProxyStatus      status = 0;     /* success */
    ldm_replyt          reply;
    prod_info* const    info = &product->info;

    memset(&reply, 0, sizeof(ldm_replyt));

    status = my_comingsoon_5(proxy, info, DBUFMAX, &reply);

    if (0 == status) {
        if (reply.code != OK) {
            if (reply.code == DONT_SEND) {
               status = LP_UNWANTED;
            }
            else {
               LOG_START2("send_5: %s: %s", info->ident,
                       s_ldm_errt(reply.code));
               status = LP_LDM_ERROR;
            }
        }
        else {
            size_t      unsent = info->sz;
            char*       data = product->data;
            datapkt     pkt;

            pkt.signaturep = &info->signature;
            pkt.pktnum = 0;

            while (unsent > 0) {
                size_t  nsend = DBUFMAX < unsent
                    ? DBUFMAX
                    : unsent;
                pkt.data.dbuf_len = (u_int)nsend;
                pkt.data.dbuf_val = data;
                status = my_blkdata_5(proxy, &pkt, &reply);
                if (0 != status) {
                    getStatus(proxy, "BLOCKDATA_5", info);
                    break;
                }
                else if (reply.code != OK) {
                    LOG_START1("Unexpected reply from LDM: %s",
                            s_ldm_errt(reply.code));
                    status = LP_LDM_ERROR;
                    break;
                }
                pkt.pktnum++;
                data += nsend;
                unsent -= nsend;
            }
        }                                       /* reply.code == OK */
    }                                           /* OK COMINGSOON */

    return status;
}
Beispiel #3
0
/**
 * Notifies the LDM of the class of data-products that will be sent via LDM-5
 * protocols.
 *
 * Arguments:
 *      proxy           Pointer to the LDM proxy data-structure.
 *      offer           Pointer to the data-product class structure which will
 *                      be offered to the LDM.
 *      want            Pointer to a pointer to a data-product class structure.
 *                      "*want" will be set the data-product class structure
 *                      that the LDM wants. The client should call
 *                      "free_prod_class(*want)" when the product-class is no
 *                      longer needed.
 * Returns:
 *      0               Success. "*clsspp" might be modified.
 *      LP_TIMEDOUT     The RPC call timed-out. "log_start()" called.
 *      LP_RPC_ERROR    RPC error. "log_start()" called.
 *      LP_LDM_ERROR    LDM error. "log_start()" called.
 */
static LdmProxyStatus
my_hiya_5(
    LdmProxy* const             proxy,
    prod_class_t* const         offer,
    prod_class_t** const        want)
{
    static ldm_replyt   reply;
    enum clnt_stat      rpc_stat;
    CLIENT* const       clnt = proxy->clnt;

    memset(&reply, 0, sizeof(ldm_replyt));

    rpc_stat = clnt_call(clnt, HIYA, xdr_prod_class, (caddr_t)offer,
            xdr_ldm_replyt, (caddr_t)&reply, proxy->rpcTimeout);

    if (rpc_stat != RPC_SUCCESS) {
        return getStatus(proxy, "HIYA_5", NULL);
    }

    switch (reply.code) {
        case OK:
            *want = (prod_class_t*)PQ_CLASS_ALL;
            break;
        case SHUTTING_DOWN:
            LOG_START1("%s is shutting down", proxy->host);
            return LP_LDM_ERROR;
        case DONT_SEND:
        case RESTART:
        case REDIRECT: /* TODO */
        default:
            LOG_START2("%s: Unexpected reply from LDM: %s", proxy->host,
                    s_ldm_errt(reply.code));
            return LP_LDM_ERROR;
        case RECLASS:
            *want = reply.ldm_replyt_u.newclssp;
            clss_regcomp(*want);
            /* N.B. we use the downstream patterns */
            /* Use of "buf" added to prevent SIGSEGV on 64-bit RHEL 6 */
            (void)s_prod_class(buf, sizeof(buf)-1, *want);
            unotice("%s: reclass: %s", proxy->host, buf);
            break;
    }

    return 0;
}
Beispiel #4
0
/**
 * Returns the pathname of the static, system-specific directory
 *
 * Returns:
 *      Pointer to the pathname.  Might be absolute or relative to the current
 *      working directory.
 */
const char* getSysConfDirPath(void)
{
    static char sysConfDirPath[PATH_MAX];

    if (strlen(sysConfDirPath) == 0) {
        const char*            ldmHome = getLdmHomePath();
        static const char      subdir[] = "/etc";

        if (strlen(ldmHome) + strlen(subdir) >= sizeof(sysConfDirPath)) {
            LOG_START2("System configuration directory pathname too long: "
                    "\"%s%s\"", ldmHome, subdir);
            log_log(LOG_ERR);
            abort();
        }

        (void)strcat(strcpy(sysConfDirPath, ldmHome), subdir);
    }

    return sysConfDirPath;
}