Ejemplo n.º 1
0
/*
 * called at exit
 */
static void
cleanup(void)
{
        log_notice("Exiting");
        if(!intr)
        {
                /* We are not in the interrupt context */

                if(md5ctxp != NULL)
                {
                        free_MD5_CTX(md5ctxp);  
                }

                if(pq != NULL)
                {
                        off_t highwater = 0;
                        size_t maxregions = 0;
                        (void) pq_highwater(pq, &highwater, &maxregions);
                        (void) pq_close(pq);
                        pq = NULL;

                        if(feed_close)
                                (*feed_close)(ifd);
                        ifd = -1;
                        log_notice("  Queue usage (bytes):%8ld",
                                                (long)highwater);
                        log_notice("           (nregions):%8ld",
                                                (long)maxregions);
                        log_notice("  Duplicates rejected:%8lu", ndups);
                }
                (*prod_stats)();
                (*feed_stats)();
        }
        log_fini();
}
Ejemplo n.º 2
0
static int
sender_start(
    const feedtypet feedtype)
{
    // The following ensures that the first product-index will be 0
    int status = pim_delete(NULL, feedtype);
    if (status) {
        LOG_ADD1("Couldn't delete product-index map for feedtype %#lx",
                 feedtype);
    }
    else {
        status = createEmptyProductQueue(UP7_PQ_PATHNAME);
        if (status) {
            LOG_ADD1("Couldn't create empty product queue \"%s\"",
                     UP7_PQ_PATHNAME);
        }
        else {
            // Thread-safe because 2 threads: upstream LDM-7 & product insertion.
            status = pq_open(getQueuePath(), PQ_READONLY | PQ_THREADSAFE, &pq);
            if (status) {
                LOG_ADD1("Couldn't open product-queue \"%s\"", getQueuePath());
            }
            else {
                McastInfo* mcastInfo;

                status = setMcastInfo(&mcastInfo, feedtype);
                if (status) {
                    LOG_ADD0("Couldn't set multicast information");
                }
                else {
                    status = mlsm_clear();
                    status = mlsm_addPotentialSender(mcastInfo, 2, LOCAL_HOST,
                                                     UP7_PQ_PATHNAME);
                    if (status) {
                        LOG_ADD0("mlsm_addPotentialSender() failure");
                    }
                    else {
                        // Starts the sender on a new thread
                        status = sender_spawn();
                        if (status) {
                            LOG_ADD0("Couldn't spawn sender");
                        }
                        else {
                            done = 0;
                        }
                    }
                    mi_free(mcastInfo);
                } // `mcastInfo` allocated

                if (status)
                    (void)pq_close(pq);
            } // Product-queue open

            if (status)
                (void)deleteProductQueue(UP7_PQ_PATHNAME);
        } // empty product-queue created
    } // product-index map deleted

    return status;
}
Ejemplo n.º 3
0
static void
sender_insertProducts(void)
{
    pqueue* pq;
    int     status = pq_open(UP7_PQ_PATHNAME, 0, &pq);

    CU_ASSERT_EQUAL_FATAL(status, 0);

    product        prod;
    prod_info*     info = &prod.info;
    char           ident[80];
    void*          data = NULL;
    unsigned short xsubi[3] = {(unsigned short)1234567890,
                               (unsigned short)9876543210,
                               (unsigned short)1029384756
                              };
    info->feedtype = EXP;
    info->ident = ident;
    info->origin = "localhost";
    (void)memset(info->signature, 0, sizeof(info->signature));

    for (int i = 0; i < NUM_PRODS; i++) {
        const unsigned size = MAX_PROD_SIZE*erand48(xsubi) + 0.5;
        const ssize_t  nbytes = snprintf(ident, sizeof(ident), "%d", i);

        CU_ASSERT_TRUE_FATAL(nbytes >= 0 && nbytes < sizeof(ident));
        status = set_timestamp(&info->arrival);
        CU_ASSERT_EQUAL_FATAL(status, 0);
        info->seqno = i;
        uint32_t signet = htonl(i);
        (void)memcpy(info->signature+sizeof(signaturet)-sizeof(signet), &signet,
                     sizeof(signet));
        info->sz = size;

        data = realloc(data, size);
        CU_ASSERT_PTR_NOT_NULL(data);
        prod.data = data;

        status = pq_insert(pq, &prod);
        CU_ASSERT_EQUAL_FATAL(status, 0);
        char buf[LDM_INFO_MAX];
        LOG_ADD1("Inserted: prodInfo=\"%s\"",
                 s_prod_info(buf, sizeof(buf), info, 1));
        log_log(LOG_INFO);

        struct timespec duration;
        duration.tv_sec = 0;
        duration.tv_nsec = 5000000; // 5 ms
        status = nanosleep(&duration, NULL);
        CU_ASSERT_EQUAL_FATAL(status, 0);
    }

    free(data);
    status = pq_close(pq);
    CU_ASSERT_EQUAL_FATAL(status, 0);
}
Ejemplo n.º 4
0
void
cleanup(void)
{
        unotice("Exiting"); 

        if(pq && !intr) 
                (void)pq_close(pq);

        (void) closeulog();
}
Ejemplo n.º 5
0
void
cleanup (void)
{
  if (pq)
    {
      (void) pq_close (pq);
      pq = NULL;
    }
  log_fini();
}
Ejemplo n.º 6
0
static void pti_fini(void)
{
    if (pq) {
        (void)pq_close(pq);
        pq = NULL;
    }
    if (prod.data) {
        free(prod.data);
        prod.data = NULL;
    }
}
Ejemplo n.º 7
0
static void cleanup(void){
  /*
   * If malloc() was used for prod.data, we leave it to the OS to free
   * the memory allocated.
   */
  if(g.pq != NULL) {
    pq_close(g.pq);
    g.pq = NULL;
  }  
  
  if((g.fd != -1) && (g.fd != STDIN_FILENO)){
    close(g.fd);
    g.fd = -1;
  }
}
Ejemplo n.º 8
0
static void
cleanup(void)
{
        log_notice("Exiting");

        dump_stats(&stats);

        if(pq != NULL)  
        {
                (void)pq_close(pq);
                pq = NULL;
        }

        log_fini();
}
Ejemplo n.º 9
0
void
cleanup(void)
{
    if (pq) {
#if !USE_MMAP
        if (!pqeIsNone(pqeIndex))
            (void)pqe_discard(pq, pqeIndex);
#endif

        (void) pq_close(pq);
        pq = NULL;
    }

    (void)closeulog();
}
Ejemplo n.º 10
0
void
cleanup(void)
{
        unotice("Exiting"); 

        if(act_pid != -1)
        {
                (void)signal(SIGCHLD, SIG_IGN);
                kill(act_pid, SIGTERM);
                (void) reap_act(0);
        }

        if(opq != NULL)
        {
                off_t highwater = 0;
                size_t maxregions = 0;
                (void) pq_highwater(opq, &highwater, &maxregions);
                (void) pq_close(opq);
                opq = NULL;

                unotice("  Queue usage (bytes):%8ld",
                                        (long)highwater);
                unotice("           (nregions):%8ld",
                                        (long)maxregions);
        }

        if(pq != NULL)
        {
                (void) pq_close(pq);
                pq = NULL;
        }

        dump_stats();

        (void) closeulog();
}
Ejemplo n.º 11
0
static int
createEmptyProductQueue(
    const char* const pathname)
{
    pqueue* pq;
    int     status = pq_create(pathname, 0666, PQ_DEFAULT, 0, PQ_SIZE,
                               NUM_PQ_SLOTS, &pq); // PQ_DEFAULT => clobber existing

    if (status == 0) {
        status = pq_close(pq);
        if (status) {
            LOG_ADD1("Couldn't close product-queue \"%s\"", pathname);
        }
    }
    return status;
}
Ejemplo n.º 12
0
/*
 * called at exit
 */
static void
cleanup(void)
{
    log_notice("Exiting");

    if (done) {
        /*
         * We are not in the interrupt context, so these can be performed
         * safely.
         */
        fl_closeAll();

        if (pq)
            (void)pq_close(pq);

        if (!tvEqual(palt_last_insertion, TS_ZERO)) {
            timestampt  now;

            (void)set_timestamp(&now);
            log_notice("Behind by %g s",
                    d_diff_timestamp(&now, &palt_last_insertion));

            if (stateWrite(&palt_last_insertion) < 0) {
                log_error("Couldn't save insertion-time of last processed "
                    "data-product");
            }
        }

        while (reap(-1, WNOHANG) > 0)
            /*EMPTY*/;
    }

    if(shmid != -1) {
        log_notice("Deleting shared segment.");
        shmctl(shmid, IPC_RMID, NULL);
    }
    if(semid != -1) {
        semctl(semid, 0, IPC_RMID);
    }

    log_fini();
}
Ejemplo n.º 13
0
static void cleanup(void){
  /*
   * If malloc() was used for prod.data, we leave it to the OS to free
   * the memory allocated (g.dynamic_pool).
   */
  if(g.pq != NULL) {
    pq_close(g.pq);
    g.pq = NULL;
  }  
  
  if(g.strp != NULL) {
    strsplit_delete(g.strp);
    g.strp = NULL;
  }

  if((g.fd != -1) && (g.fd != STDIN_FILENO)){
    close(g.fd);
    g.fd = -1;
  }
}
Ejemplo n.º 14
0
hiya_reply_t*
hiya_6_svc(
        prod_class_t *offered,
        struct svc_req *rqstp)
{
    const char* const pqfname = getQueuePath();
    static hiya_reply_t reply;
    SVCXPRT * const xprt = rqstp->rq_xprt;
    struct sockaddr_in *upAddr = (struct sockaddr_in*) svc_getcaller(xprt);
    const char *upName = hostbyaddr(upAddr);
    int error;
    int isPrimary;
    unsigned int maxHereis;
    static prod_class_t *accept;

    /*
     * Open the product-queue for writing.  It will be closed by cleanup()
     * during process termination.
     */
    if (pq) {
        (void) pq_close(pq);
        pq = NULL;
    }
    error = pq_open(pqfname, PQ_DEFAULT, &pq);
    if (error) {
        err_log_and_free(ERR_NEW2(error, NULL,
                "Couldn't open product-queue \"%s\" for writing: %s",
                pqfname,
                PQ_CORRUPT == error
                ? "The product-queue is inconsistent"
                : strerror(error)), ERR_FAILURE);
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }

    /* else */

    error = down6_init(upName, upAddr, pqfname, pq);
    if (error) {
        uerror("Couldn't initialize downstream LDM");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        uinfo("Downstream LDM initialized");
    }

    /*
     * The previous "accept" is freed here -- rather than freeing the
     * soon-to-be-allocated "accept" at the end of its block -- because it can
     * be used in the reply.
     */
    if (accept) {
        free_prod_class(accept); /* NULL safe */
        accept = NULL;
    }

    error = lcf_reduceToAcceptable(upName, inet_ntoa(upAddr->sin_addr), offered,
            &accept, &isPrimary);

    maxHereis = isPrimary ? UINT_MAX : 0;

    if (error) {
        serror("Couldn't validate HIYA");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        if (ulogIsDebug())
            udebug("intersection: %s", s_prod_class(NULL, 0, accept));

        if (accept->psa.psa_len == 0) {
            uwarn("Empty intersection of HIYA offer from %s (%s) and ACCEPT "
                    "entries", upName, s_prod_class(NULL, 0, offered));
            svcerr_weakauth(xprt);
            svc_destroy(xprt);
            exit(0);
        }
        else {
            error = down6_set_prod_class(accept);

            if (error) {
                if (DOWN6_SYSTEM_ERROR == error) {
                    serror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }
                else {
                    uerror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }

                svcerr_systemerr(xprt);
                svc_destroy(xprt);
                exit(EXIT_FAILURE);
            }

            /* else */

            if (clss_eq(offered, accept)) {
                unotice("hiya6: %s", s_prod_class(NULL, 0, offered));

                reply.code = OK;
                reply.hiya_reply_t_u.max_hereis = maxHereis;
            }
            else {
                if (ulogIsVerbose()) {
                    char off[512];
                    char acc[512];

                    (void) s_prod_class(off, sizeof(off), offered), (void) s_prod_class(
                            acc, sizeof(acc), accept);

                    uinfo("hiya6: RECLASS: %s -> %s", off, acc);
                }

                reply.code = RECLASS;
                reply.hiya_reply_t_u.feedPar.prod_class = accept;
                reply.hiya_reply_t_u.feedPar.max_hereis = maxHereis;
            }
        } /* product-intersection != empty set */
    } /* successful acl_check_hiya() */

    return &reply;
}
Ejemplo n.º 15
0
int main(int ac, char *av[])
{
        int pflags = PQ_NOCLOBBER;
        off_t initialsz = 0;
        size_t nproducts = 0;
        pqueue *pq = NULL;
        int errnum = 0;

        /*
         * initialize logger
         */
        (void)log_init(av[0]);

        int ch;
        char *qopt = NULL;
        char *sopt = NULL;
        char *Sopt = NULL;
        extern char     *optarg;
        extern int       optind;
        const char* pqfname = getQueuePath();

        while ((ch = getopt(ac, av, "xvcfq:s:S:l:")) != EOF)
                switch (ch) {
                case 'v':
                        if (!log_is_enabled_info)
                            (void)log_set_level(LOG_LEVEL_INFO);
                        break;
                case 'c':
                        pflags &= ~PQ_NOCLOBBER;
                        break;
                case 'f':
                        pflags |= PQ_SPARSE;
                        break;
                case 's':
                        sopt = optarg;
                        break;
                case 'S':
                        Sopt = optarg;
                        break;
                case 'q':
                        qopt = optarg;
                        break;
                case 'x':
                        (void)log_set_level(LOG_LEVEL_DEBUG);
                        break;
                case 'l':
                        (void)log_set_destination(optarg);
                        break;
                case '?':
                        usage(av[0]);
                        break;
                }
        
        if(ac - optind > 1)
        {
                if(sopt)
                        usage(av[0]);
                sopt = av[ac - 2];
        }
        if(ac - optind > 0)
        {
                if(qopt)        
                        usage(av[0]);
                qopt =  av[ac - 1];
        }

        if(qopt) {
                pqfname = qopt ;
                setQueuePath(qopt);
        }

        if (sopt) {
            char*       cp;
            int         exponent = 0;

            errno = 0;
            initialsz = strtol(sopt, &cp, 0);

            if (0 != errno) {
                initialsz = 0; /* trigger error below */
            }
            else {
                switch (*cp) {
                    case 0:
                        break;
                    case 'k':
                    case 'K':
                        exponent = 1;
                        break;
                    case 'm':
                    case 'M':
                        exponent = 2;
                        break;
                    case 'g':
                    case 'G':
                        exponent = 3;
                        break;
                    default:
                        initialsz = 0; /* trigger error below */
                        break;
                }

                if (0 < initialsz) {
                    int     i;

                    for (i = 0; i < exponent; i++) {
                        initialsz *= 1000;
                        
                        if (0 >= initialsz) {
                            fprintf(stderr, "Size \"%s\" too big\n", sopt);
                            usage(av[0]);
                        }
                    }
                }
            }
        }
        if(initialsz <= 0)
        {
                if(sopt)
                        fprintf(stderr, "Illegal size \"%s\"\n", sopt);
                else
                        fprintf(stderr, "No size specified\n");
                usage(av[0]);
        }

        if(Sopt != NULL)
        {
                nproducts = (size_t)atol(Sopt);
                if(nproducts == 0)
                {
                        fprintf(stderr, "Illegal nproducts \"%s\"\n", Sopt);
                }
        }
        else
        {
#define PQ_AVG_PRODUCT_SIZE 51000 // approximate mean size on 2014-08-21
                /* For default number of product slots, use average product size estimate */
                nproducts = initialsz/PQ_AVG_PRODUCT_SIZE;
        }


        log_info_q("Creating %s, %ld bytes, %ld products.\n",
                pqfname, (long)initialsz, (long)nproducts);

        errnum = pq_create(pqfname, 0666, pflags,
                0, initialsz, nproducts, &pq);
        if(errnum)
        {
                fprintf(stderr, "%s: create \"%s\" failed: %s\n",
                        av[0], pqfname, strerror(errnum));
                exit(1);
        }

        (void)pq_close(pq);

        return(0);
}
Ejemplo n.º 16
0
int main(
        int ac,
        char* av[])
{
    const char* pqfname = getQueuePath();
    int sock = -1;
    int status;
    int doSomething = 1;
    in_addr_t locIpAddr = (in_addr_t) htonl(INADDR_ANY );
    unsigned ldmPort = LDM_PORT;

    ensureDumpable();

    /*
     * deal with the command line, set options
     */
    {
        extern int optind;
        extern int opterr;
        extern char *optarg;
        int ch;
        int logmask = LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING)
                | LOG_MASK(LOG_NOTICE);

        opterr = 1;

        while ((ch = getopt(ac, av, "I:vxl:nq:o:P:M:m:t:")) != EOF) {
            switch (ch) {
            case 'I': {
                in_addr_t ipAddr = inet_addr(optarg);

                if ((in_addr_t) -1 == ipAddr) {
                    (void) fprintf(stderr, "Interface specification \"%s\" "
                            "isn't an IP address\n", optarg);
                    exit(1);
                }

                locIpAddr = ipAddr;

                break;
            }
            case 'v':
                logmask |= LOG_MASK(LOG_INFO);
                break;
            case 'x':
                logmask |= LOG_MASK(LOG_DEBUG);
                break;
            case 'l':
                logfname = optarg;
                break;
            case 'q':
                pqfname = optarg;
                setQueuePath(optarg);
                break;
            case 'o':
                toffset = atoi(optarg);
                if (toffset == 0 && *optarg != '0') {
                    (void) fprintf(stderr, "%s: invalid offset %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case 'P': {
                char* suffix = "";
                long port;

                errno = 0;
                port = strtol(optarg, &suffix, 0);

                if (0 != errno || 0 != *suffix || 0 >= port || 0xffff < port) {

                    (void) fprintf(stderr, "%s: invalid port %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }

                ldmPort = (unsigned) port;

                break;
            }
            case 'M': {
                int max = atoi(optarg);
                if (max < 0) {
                    (void) fprintf(stderr,
                            "%s: invalid maximum number of clients %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                maxClients = max;
                break;
            }
            case 'm':
                max_latency = atoi(optarg);
                if (max_latency <= 0) {
                    (void) fprintf(stderr, "%s: invalid max_latency %s\n",
                            av[0], optarg);
                    usage(av[0]);
                }
                break;
            case 'n':
                doSomething = 0;
                break;
            case 't':
                rpctimeo = (unsigned) atoi(optarg);
                if (rpctimeo == 0 || rpctimeo > 32767) {
                    (void) fprintf(stderr, "%s: invalid timeout %s", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case '?':
                usage(av[0]);
                break;
            } /* "switch" statement */
        } /* argument loop */

        if (ac - optind == 1)
            setLdmdConfigPath(av[optind]);
        (void) setulogmask(logmask);

        if (toffset != TOFFSET_NONE && toffset > max_latency) {
            (void) fprintf(stderr,
                    "%s: invalid toffset (%d) > max_latency (%d)\n", av[0],
                    toffset, max_latency);
            usage(av[0]);
        }
    } /* command-line argument decoding */

#ifndef DONTFORK
    /* 
     * daemon behavior
     *
     * Background the process unless we are logging to stderr, in which
     * case we assume interactive.
     */
    if (logfname == NULL || *logfname != '-') {
        /* detach */
        pid_t pid;
        pid = ldmfork();
        if (pid == -1) {
            log_add("Couldn't fork LDM daemon");
            log_log(LOG_ERR);
            exit(2);
        }

        if (pid > 0) {
            /* parent */
            (void) printf("%ld\n", (long) pid);
            exit(0);
        }

        /* detach the child from parents process group ?? */
        (void) setsid();
    }
#endif

    /*
     * Initialize logger.
     * (Close fd 2 to remap stderr to the logfile, when
     * appropriate. I know, this is anal.)
     */
    if (logfname == NULL )
        (void) fclose(stderr);
    else if (!(logfname[0] == '-' && logfname[1] == 0))
        (void) close(2);
    (void) openulog(ubasename(av[0]), (LOG_CONS | LOG_PID), LOG_LDM, logfname);
    unotice("Starting Up (version: %s; built: %s %s)", PACKAGE_VERSION,
            __DATE__, __TIME__);

    /*
     * register exit handler
     */
    if (atexit(cleanup) != 0) {
        serror("atexit");
        unotice("Exiting");
        exit(1);
    }

    /*
     * set up signal handlers
     */
    set_sigactions();

    /*
     * Close the standard input and standard output streams because they won't
     * be used (more anality :-)
     */
    (void) fclose(stdout);
    (void) fclose(stdin);

    if (!doSomething) {
        /*
         * Vet the configuration file.
         */
        udebug("main(): Vetting configuration-file");
        if (read_conf(getLdmdConfigPath(), doSomething, ldmPort) != 0) {
            log_log(LOG_ERR);
            exit(1);
        }
    }
    else {
        /*
         * Create a service portal. This should be done before anything is
         * created because this is the function that relinquishes superuser
         * privileges.
         */
        udebug("main(): Creating service portal");
        if (create_ldm_tcp_svc(&sock, locIpAddr, ldmPort) != ENOERR) {
            /* error reports are emitted from create_ldm_tcp_svc() */
            exit(1);
        }
        udebug("tcp sock: %d", sock);

        /*
         * Verify that the product-queue can be open for writing.
         */
        udebug("main(): Opening product-queue");
        if (status = pq_open(pqfname, PQ_DEFAULT, &pq)) {
            if (PQ_CORRUPT == status) {
                uerror("The product-queue \"%s\" is inconsistent", pqfname);
            }
            else {
                uerror("pq_open failed: %s: %s", pqfname, strerror(status));
            }
            exit(1);
        }
        (void) pq_close(pq);
        pq = NULL;

        /*
         * Create the sharable database of upstream LDM metadata.
         */
        udebug("main(): Creating shared upstream LDM database");
        if (status = uldb_delete(NULL)) {
            if (ULDB_EXIST == status) {
                log_clear();
            }
            else {
                LOG_ADD0(
                        "Couldn't delete existing shared upstream LDM database");
                log_log(LOG_ERR);
                exit(1);
            }
        }
        if (uldb_create(NULL, maxClients * 1024)) {
            LOG_ADD0("Couldn't create shared upstream LDM database");
            log_log(LOG_ERR);
            exit(1);
        }

        /*
         * Read the configuration file (downstream LDM-s are started).
         */
        udebug("main(): Reading configuration-file");
        if (read_conf(getLdmdConfigPath(), doSomething, ldmPort) != 0) {
            log_log(LOG_ERR);
            exit(1);
        }

        /*
         * Serve
         */
        udebug("main(): Serving socket");
        sock_svc(sock);
    } /* "doSomething" is true */

    return (0);
}
Ejemplo n.º 17
0
int main(int argc, char** argv){
	CONFIG cfg;

	cfg_init(&cfg);

	//read commandline args
	if(!arg_parse(&cfg, argc-1, argv+1)){
		return -1;
	}

	//read config file
	if(!cfg.cfg_file){
		fprintf(stderr, "No config file supplied\n");
		return -1;
	}
	if(!cfg_read(&cfg, cfg.cfg_file)){
		cfg_free(&cfg);
		return -1;
	}

	//if not using pgpass, ask for database password
	if(!cfg.db.use_pgpass){
		cfg.db.pass=calloc(sizeof(char),MAX_PASSWORD_LENGTH+1);
		if(!cfg.db.pass){
			fprintf(stderr, "Failed to allocate memory\n");
			cfg_free(&cfg);
			return -1;
		}
		fprintf(stderr, "DB Password: "******"\fWaiting...");
		ask_password(cfg.db.pass, MAX_PASSWORD_LENGTH);
	}

	//check for sane config
	if(!cfg_sane(&cfg)){
		cfg_free(&cfg);
		return -1;
	}

	//connect to database if persistent
	if(cfg.db.persist_connection){
		if(!pq_connect(&(cfg.db))){
			cfg_free(&cfg);
			return -1;
		}
		if(cfg.verbosity>2){
			fprintf(stderr, "Database connection established\n");	
		}
	}

	//connect to remote devices
	if(!comms_open(&cfg)){
		comms_close(&cfg);
		pq_close(&(cfg.db));
		cfg_free(&cfg);
		return -1;
	}
	
	//set up signal handlers
	signal(SIGINT, sig_interrupt);
	signal(SIGTERM, sig_terminate);

	//run the state machine
	garfield_pos(&cfg);

	comms_close(&cfg);
	pq_close(&(cfg.db));
	cfg_free(&cfg);
	return 0;
}
Ejemplo n.º 18
0
/**
 * @retval LDM7_INVAL  No multicast sender child process exists.
 */
static int
sender_terminate(void)
{
    int retval = 0;
    int status;

#if CANCEL_SENDER
    udebug("Canceling sender thread");
    status = pthread_cancel(sender.thread);
    if (status) {
        LOG_ERRNUM0(status, "Couldn't cancel sender thread");
        retval = status;
    }
#else
    udebug("Writing to termination pipe");
    status = write(sender.fds[1], &status, sizeof(int));
    if (status == -1) {
        LOG_SERROR0("Couldn't write to termination pipe");
        retval = status;
    }
#endif

    void* statusPtr;

    udebug("Joining sender thread");
    status = pthread_join(sender.thread, &statusPtr);
    if (status) {
        LOG_ERRNUM0(status, "Couldn't join sender thread");
        retval = status;
    }

    if (statusPtr != PTHREAD_CANCELED) {
        status = *(int*)statusPtr;
        if (status) {
            LOG_START1("Sender task exit-status was %d", status);
            retval = status;
        }
    }

    (void)close(sender.sock);

    udebug("Terminating multicast sender");
    status = terminateMcastSender();
    if (status) {
        LOG_ADD0("Couldn't terminate multicast sender process");
        retval = status;
    }

    udebug("Clearing multicast LDM sender manager");
    status = mlsm_clear();
    if (status) {
        LOG_ADD0("mlsm_clear() failure");
        retval = status;
    }

    status = pq_close(pq);
    if (status) {
        LOG_ADD0("pq_close() failure");
        retval = status;
    }

    status = deleteProductQueue(UP7_PQ_PATHNAME);
    if (status) {
        LOG_ADD0("deleteProductQueue() failure");
        retval = status;
    }

    return retval;
}
Ejemplo n.º 19
0
/*ARGSUSED*/
static int
exec_prodput(
     const product*     prod,
     int                argc,
     char**             argv,
     const void*        xprod,
     size_t             xlen)
{
    pid_t       pid = 0;

    if (NULL == execMap) {
        execMap = cm_new();

        if (NULL == execMap) {
            LOG_ADD0("Couldn't create child-process map for EXEC entries");
            log_log(LOG_ERR);
            pid = -1;
        }
    }                                   /* child-process map not allocated */

    if (0 == pid) {
        int     waitOnChild = 0;        /* default is not to wait */

        if (strcmp(argv[0], "-wait") == 0) {
            waitOnChild = 1;            /* => wait for child */
            argc--; argv++;
        }

        pid = ldmfork();
        if (-1 == pid) {
            LOG_SERROR0("Couldn't fork EXEC process");
            log_log(LOG_ERR);
        }
        else {
            if (0 == pid) {
                /*
                 * Child process.
                 *
                 * Detach the child process from the parents process group??
                 *
                 * (void) setpgid(0,0);
                 */
                const unsigned  ulogOptions = ulog_get_options();
                const char*     ulogIdent = getulogident();
                const unsigned  ulogFacility = getulogfacility();
                const char*     ulogPath = getulogpath();

                (void)signal(SIGTERM, SIG_DFL);
                (void)pq_close(pq);

                /*
                 * It is assumed that the standard input, output, and error
                 * streams are correctly established and should not be
                 * modified.
                 */

                /*
                 * Don't let the child process get any inappropriate privileges.
                 */
                endpriv();

                (void) execvp(argv[0], argv);
                openulog(ulogIdent, ulogOptions, ulogFacility, ulogPath);
                LOG_SERROR1("Couldn't execute command \"%s\"", argv[0]);
                log_log(LOG_ERR);
                exit(EXIT_FAILURE);
            }                           /* child process */
            else {
                /*
                 * Parent process.
                 */
                (void)cm_add_argv(execMap, pid, argv);

                if (!waitOnChild) {
                    udebug("    exec %s[%d]", argv[0], pid);
                }
                else {
                    udebug("    exec -wait %s[%d]", argv[0], pid);
                    (void)reap(pid, 0);
                }
            }
        }                               /* child-process forked */
    }                                   /* child-process map allocated */

    return -1 == pid ? -1 : 1;
}
Ejemplo n.º 20
0
Archivo: ldmd.c Proyecto: dgaer/LDM
/*
 * Called at exit.
 * This callback routine registered by atexit().
 */
static void cleanup(
        void)
{
    const char* const pqfname = getQueuePath();

    unotice("Exiting");

    lcf_savePreviousProdInfo();

    free_remote_clss();

    /*
     * Ensure release of COMINGSOON-reserved space in product-queue.
     */
    clr_pip_5();
    down6_destroy();

    /*
     * Close product-queue.
     */
    if (pq) {
        (void) pq_close(pq);
        pq = NULL;
    }

    /*
     * Ensure that this process has no entry in the upstream LDM database and
     * that the database is closed.
     */
    (void) uldb_remove(getpid());
    (void) uldb_close();
    log_clear();

    if (getpid() == getpgrp()) {
        /*
         * This process is the process group leader (i.e., the top-level
         * LDM server).
         */
        if (portIsMapped) {
            int vers;

            /*
             * Superuser privileges might be required to unmap the
             * port on which the LDM is listening.
             */
            rootpriv();

            for (vers = MIN_LDM_VERSION; vers <= MAX_LDM_VERSION; vers++) {
                if (!pmap_unset(LDMPROG, vers))
                    uerror("pmap_unset(LDMPROG %lu, LDMVERS %lu) "
                            "failed", LDMPROG, vers);
                else
                    portIsMapped = 0;
            }

            unpriv();
        }

        /*
         * Terminate all child processes.
         */
        {
            /*
             * Ignore the signal I'm about to send my process group.
             */
            struct sigaction sigact;

            (void) sigemptyset(&sigact.sa_mask);
            sigact.sa_flags = 0;
            sigact.sa_handler = SIG_IGN;
            (void) sigaction(SIGTERM, &sigact, NULL );
        }

        /*
         * Signal my process group.
         */
        unotice("Terminating process group");
        (void) kill(0, SIGTERM);

        while (reap(-1, 0) > 0)
            ; /*empty*/

        /*
         * Delete the upstream LDM database.
         */
        (void) uldb_delete(NULL);

#if WANT_MULTICAST
        /*
         * Destroy the multicast LDM sender map.
         */
        msm_destroy();
#endif
    }

    /*
     * Free access-control-list resources.
     */
    lcf_free();

    /*
     * Close registry.
     */
    if (reg_close())
        log_log(LOG_ERR);

    /*
     * Terminate logging.
     */
    (void) closeulog();
}
Ejemplo n.º 21
0
Archivo: ldmd.c Proyecto: dgaer/LDM
int main(
        int ac,
        char* av[])
{
    const char* pqfname = getQueuePath();
    int status;
    int doSomething = 1;
    in_addr_t ldmIpAddr = (in_addr_t) htonl(INADDR_ANY );
    unsigned ldmPort = LDM_PORT;

    ensureDumpable();

    /*
     * deal with the command line, set options
     */
    {
        extern int optind;
        extern int opterr;
        extern char *optarg;
        int ch;
        int logmask = LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING)
                | LOG_MASK(LOG_NOTICE);

        opterr = 1;

        while ((ch = getopt(ac, av, "I:vxl:nq:o:P:M:m:t:")) != EOF) {
            switch (ch) {
            case 'I': {
                in_addr_t ipAddr = inet_addr(optarg);

                if ((in_addr_t) -1 == ipAddr) {
                    (void) fprintf(stderr, "Interface specification \"%s\" "
                            "isn't an IP address\n", optarg);
                    exit(1);
                }

                ldmIpAddr = ipAddr;

                break;
            }
            case 'v':
                logmask |= LOG_MASK(LOG_INFO);
                break;
            case 'x':
                logmask |= LOG_MASK(LOG_DEBUG);
                break;
            case 'l':
                logfname = optarg;
                break;
            case 'q':
                pqfname = optarg;
                setQueuePath(optarg);
                break;
            case 'o':
                toffset = atoi(optarg);
                if (toffset == 0 && *optarg != '0') {
                    (void) fprintf(stderr, "%s: invalid offset %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case 'P': {
                unsigned port;
                int      nbytes;
                if (sscanf(optarg, "%5u %n", &port, &nbytes) != 1 ||
                        0 != optarg[nbytes] || port > 0xffff) {
                    (void)fprintf(stderr, "%s: invalid port number: %s\n",
                            av[0], optarg);
                    usage(av[0]);
                }
                ldmPort = port;
                break;
            }
            case 'M': {
                int max = atoi(optarg);
                if (max < 0) {
                    (void) fprintf(stderr,
                            "%s: invalid maximum number of clients %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                maxClients = max;
                break;
            }
            case 'm':
                max_latency = atoi(optarg);
                if (max_latency <= 0) {
                    (void) fprintf(stderr, "%s: invalid max_latency %s\n",
                            av[0], optarg);
                    usage(av[0]);
                }
                break;
            case 'n':
                doSomething = 0;
                break;
            case 't':
                rpctimeo = (unsigned) atoi(optarg);
                if (rpctimeo == 0 || rpctimeo > 32767) {
                    (void) fprintf(stderr, "%s: invalid timeout %s", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case '?':
                usage(av[0]);
                break;
            } /* "switch" statement */
        } /* argument loop */

        if (ac - optind == 1)
            setLdmdConfigPath(av[optind]);
        (void) setulogmask(logmask);

        if (toffset != TOFFSET_NONE && toffset > max_latency) {
            (void) fprintf(stderr,
                    "%s: invalid toffset (%d) > max_latency (%d)\n", av[0],
                    toffset, max_latency);
            usage(av[0]);
        }
    } /* command-line argument decoding */

    if (logfname != NULL && *logfname == '-') {
        /*
         * Logging to standard error stream. Assume interactive.
         *
         * Make this process a process group leader so that all child processes
         * (e.g., upstream LDM, downstream LDM, pqact(1)s) will be signaled by
         * `cleanup()`.
         */
        (void)setpgid(0, 0); // can't fail
    }
#ifndef DONTFORK
    else {
        /*
         * Logging to system logging daemon or file. Make this process a daemon.
         */
        pid_t pid;
        pid = ldmfork();
        if (pid == -1) {
            log_add("Couldn't fork LDM daemon");
            log_log(LOG_ERR);
            exit(2);
        }

        if (pid > 0) {
            /* parent */
            (void) printf("%ld\n", (long) pid);
            exit(0);
        }

        /* detach the child from parents process group ?? */
        (void) setsid(); // also makes this process a process group leader
    }
#endif

    /*
     * Initialize logger.
     * (Close fd 2 to remap stderr to the logfile, when
     * appropriate. I know, this is anal.)
     */
    if (logfname == NULL )
        (void) fclose(stderr);
    else if (!(logfname[0] == '-' && logfname[1] == 0))
        (void) close(2);
    (void) openulog(ubasename(av[0]), (LOG_CONS | LOG_PID), LOG_LDM, logfname);
    unotice("Starting Up (version: %s; built: %s %s)", PACKAGE_VERSION,
            __DATE__, __TIME__);

    /*
     * register exit handler
     */
    if (atexit(cleanup) != 0) {
        serror("atexit");
        unotice("Exiting");
        exit(1);
    }

    /*
     * set up signal handlers
     */
    set_sigactions();

    /*
     * Close the standard input and standard output streams because they won't
     * be used (more anality :-)
     */
    (void) fclose(stdout);
    (void) fclose(stdin);

    /*
     * Vet the configuration file.
     */
    udebug("main(): Vetting configuration-file");
    if (read_conf(getLdmdConfigPath(), 0, ldmIpAddr, ldmPort) != 0) {
        log_log(LOG_ERR);
        exit(1);
    }

    if (doSomething) {
        int sock = -1;

        if (lcf_isServerNeeded()) {
            /*
             * Create a service portal. This should be done before anything is
             * created because this is the function that relinquishes superuser
             * privileges.
             */
            udebug("main(): Creating service portal");
            if (create_ldm_tcp_svc(&sock, ldmIpAddr, ldmPort) != ENOERR) {
                /* error reports are emitted from create_ldm_tcp_svc() */
                exit(1);
            }
            udebug("tcp sock: %d", sock);
        }

        /*
         * Verify that the product-queue can be open for writing.
         */
        udebug("main(): Opening product-queue");
        if ((status = pq_open(pqfname, PQ_DEFAULT, &pq))) {
            if (PQ_CORRUPT == status) {
                uerror("The product-queue \"%s\" is inconsistent", pqfname);
            }
            else {
                uerror("pq_open failed: %s: %s", pqfname, strerror(status));
            }
            exit(1);
        }
        (void) pq_close(pq);
        pq = NULL;

        /*
         * Create the sharable database of upstream LDM metadata.
         */
        udebug("main(): Creating shared upstream LDM database");
        if ((status = uldb_delete(NULL))) {
            if (ULDB_EXIST == status) {
                log_clear();
            }
            else {
                LOG_ADD0(
                        "Couldn't delete existing shared upstream LDM database");
                log_log(LOG_ERR);
                exit(1);
            }
        }
        if (uldb_create(NULL, maxClients * 1024)) {
            LOG_ADD0("Couldn't create shared upstream LDM database");
            log_log(LOG_ERR);
            exit(1);
        }

        /*
         * Initialize the multicast sender map.
         */
#if WANT_MULTICAST
        if (msm_init()) {
            LOG_ADD0("Couldn't initialize multicast LDM sender map");
            log_log(LOG_ERR);
            exit(1);
        }
#endif

        /*
         * Re-read (and execute) the configuration file (downstream LDM-s are
         * started).
         */
        lcf_free(); // Start with a clean slate to prevent duplicates
        udebug("main(): Reading configuration-file");
        if (read_conf(getLdmdConfigPath(), 1, ldmIpAddr, ldmPort) != 0) {
            log_log(LOG_ERR);
            exit(1);
        }

        if (lcf_isServerNeeded()) {
            /*
             * Serve
             */
            udebug("main(): Serving socket");
            sock_svc(sock);
        }
        else {
            /*
             * Wait until all child processes have terminated.
             */
            while (reap(-1, 0) > 0)
                /* empty */;
        }
    }   // configuration-file will be executed

    return (0);
}
Ejemplo n.º 22
0
/*----------------------------------------*/ int main(int argc, char **argv) {
int rc;
int ssmcr_tries=0;
infolog_SetFacility("CTP"); infolog_SetStream("",0);
#ifdef PQWAY
printf("main_ctp: opening rec/send queues...\n");
mq_rec= pq_open();
if(mq_rec==(mqd_t)-1) {
  infolog_trgboth(LOG_FATAL, "posix mq_rec not created");
  exit(8);
}
mq_sendmsg= pq_connect();
if(mq_sendmsg==(mqd_t)-1) {
  infolog_trgboth(LOG_FATAL, "posix mq_sendmsg not connected");
  exit(8);
}
#endif
signal(SIGUSR1, gotsignal); siginterrupt(SIGUSR1, 0);
signal(SIGQUIT, gotsignal); siginterrupt(SIGQUIT, 0);
signal(SIGKILL, gotsignal); siginterrupt(SIGKILL, 0); // -9
signal(SIGTERM, gotsignal); siginterrupt(SIGTERM, 0); // kill pid
signal(SIGINT, gotsignal); siginterrupt(SIGINT, 0);   // CTRL C   2
partmode[0]='\0';
printf("cshmInit i.e. initBakery(swtriggers/ccread/ssmcr ONLY once, when shm allocated)...\n");
/*printf("initBakery(swtriggers,4): 0:SOD/EOD 1:gcalib 2:ctp.exe 3:dims\n");
printf("initBakery(ccread,5): 0:proxy 1:dims 2:ctp+busytool 3:smaq 4:inputs\n");
*/
cshmInit();
setglobalflags(argc, argv);

/* changed in aug2016 (initBakery only once from now, when shm allocated)
printf("initBakery(swtriggers,4): 0:SOD/EOD 1:gcalib 2:ctp.exe 3:dims\n");
initBakery(&ctpshmbase->swtriggers, "swtriggers", swtriggers_N);
printf("initBakery(ccread,6): 0:proxy 1:dims 2:ctp+busytool 3:smaq 4:inputs 5:orbitddl2\n");
initBakery(&ctpshmbase->ccread, "ccread", ccread_N);
printf("initBakery(ssmcr,4): 0:smaq 1:orbitddl2 2:ctp 3:inputs\n");
initBakery(&ctpshmbase->ssmcr, "ssmcr", ssmcr_N);
*/
printBakery(&ctpshmbase->swtriggers);
printBakery(&ctpshmbase->ccread);
printBakery(&ctpshmbase->ssmcr);
unlockBakery(&ctpshmbase->swtriggers,swtriggers_ctpproxy);
unlockBakery(&ctpshmbase->ccread,ccread_ctpproxy);
unlockBakery(&ctpshmbase->ssmcr,ssmcr_ctpproxy);

/* Let' synchronise with smcr only, i.e. 
- ccread_dims,... can go in parallel with ctp_Initproxy, 
  orbitddl2: should use ccread_orbitddl2 customer when reading counters
  
- swtriggers_gcalib/_dims cannot appear (no global runs becasue ctpproxy being restarted)
*/
while(1) { // do not allow SSM usage (smaq) because ctp_Initproxy is initialising it
  char msg[100];
  rc= lockBakeryTimeout(&ctpshmbase->ssmcr,ssmcr_ctpproxy, 10);
  if(rc==1) {
    if(ssmcr_tries>0) {
      sprintf(msg, "Got ssmcr resource after %d attempts", ssmcr_tries);
      infolog_trgboth(LOG_INFO, msg);
    };
    break;  // ssmcr reserved for me now
  };
  ssmcr_tries++;
  sprintf(msg,"%d secs Waiting for ssmcr resource. Is smaq stopped?", ssmcr_tries*10);
  infolog_trgboth(LOG_WARNING, msg);
};
if(isArg(argc, argv, "configrunset")) {
  /* do we need before orbitddl2.py INT/L2 orbit in SYNC (automatic with L2a)?
  */
  int rc, reslen;
  char cmd[200];
  char result[1000]="";   // ~ 10 lines
  char orbchanged[]="Warning: orbitoffset changed:";
  if(envcmp("VMESITE", "PRIVATE")==0) {
    strcpy(cmd, "who");
  } else {
    strcpy(cmd, "orbitddl2.py configrunset");
  };
  infolog_trgboth(LOG_INFO, "Starting L0 orbit calibration (30s...)");
  rc= popenread(cmd, result, 1000);   // opens vme...
  reslen= strlen(result);
  if((rc==EXIT_FAILURE) || (reslen<=1)) { 
    infolog_trgboth(LOG_ERROR, "L0 orbit calibration problem");
  } else {
    int ixr= reslen;
    if(result[ixr-1]=='\n') {   //remove last NL character if present
      result[ixr-1]='\0';
      ixr= reslen-2;
    } else {
      ixr= reslen-1;   // pointer to the last non-NEWLINE character
    };
    while(ixr>=0) {    // find last line
      if(result[ixr]=='\n') {
        ixr++; break;
      };
      ixr--;
    };
    sprintf(cmd, "L0 orbit calibration: %s", &result[ixr]);
    if((strcmp(&result[ixr], "Everything ok")==0) ||
       (strncmp(&result[ixr], orbchanged, strlen(orbchanged))==0)
      ) {
      infolog_trgboth(LOG_INFO, cmd);
    } else {
      infolog_trgboth(LOG_ERROR, cmd);
      infolog_trgboth(LOG_ERROR, "ctpproxy not started"); 
      unlockBakery(&ctpshmbase->ssmcr,ssmcr_ctpproxy);
      rc=8; goto STP;
    };
  };
};
// init CTP after calibration (e.g. to repair modifications done by orbitddl2.py)
rc=ctp_Initproxy();
unlockBakery(&ctpshmbase->ssmcr,ssmcr_ctpproxy);
if(rc!=0) goto STP;

// DIM services not registered here (see ctpdims.c), they run in separae task:
// ds_register();
strcpy(obj,argv[1]);
smi_attach(obj, SMI_handle_command);
printf("CTP attached to: %s\n",obj);
/* if smi_volatile: stops the ctp_proxy in case TRIGGER domain is down
smi_volatile();   
*/
strcpy(errorReason,"not set"); smi_set_parER();
strcpy(ORBIT_NUMBER,""); smi_set_par("ORBIT_NUMBER",ORBIT_NUMBER,STRING);
smi_setState("RUNNING");
while(1) {
#ifdef PQWAY
  executectp("wait");
#else
  usleep(1000000);
#endif
  if(quit>9) break;
};
rc= ctp_Endproxy();
STP:
#ifdef PQWAY
pq_close(mq_sendmsg, 0);
pq_close(mq_rec, 1);
#endif
printf("Calling cshmDetach()...\n"); cshmDetach();
return (rc);
}