Exemple #1
0
/* start clc main work socket */
int ly_epoll_work_start(int port)
{
    if (g_efd == -1)
        return -1;

    int listener, ret = 0;
    char portstr[10];
    sprintf(portstr, "%d", port);

    listener = lyutil_create_and_bind(portstr);
    if (listener < 0) {
        logerror(_("failed create/bind port %d\n"), port);
        return -1;
    }

    ret = lyutil_make_socket_nonblocking(listener);
    if (ret < 0) {
        logerror(_("failed make port %d nonblocking\n"), port);
        goto out;
    }

    ret = listen(listener, SOMAXCONN);
    if (ret < 0) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        goto out;
    }

    int id = ly_entity_new(listener);
    if (id < 0) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        goto out;
    }
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = id;
    ret = epoll_ctl(g_efd, EPOLL_CTL_ADD, listener, &ev);
    if (ret < 0) {
        logerror(_("add socket to epoll error in %s.\n"), __func__);
        ly_entity_release(id);
        /* close(listener); closed in ly_entity_release */
        return -1;
    }
    ly_entity_init(id, LY_ENTITY_CLC);

out:
    if (ret != 0)
        close(listener);
    return ret;
}
Exemple #2
0
int main(int argc, char *argv[])
{
    int ret, keeppidfile = 1;

    setlocale(LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);

    lyxml_init();
    lyauth_init();

    /* start initializeing g_c */
    CLCConfig *c = malloc(sizeof(CLCConfig));
    if (c == NULL) {
        printf(_("malloc for g_c have a error.\n"));
        return -255;
    }
    g_c = c;

    /* parse command line option and configuration file */
    ret = clc_config(argc, argv, c);
    if (ret == CLC_CONFIG_RET_HELP)
        usage();
    else if (ret == CLC_CONFIG_RET_VER)
        printf(_("%s : Version %s\n"), PROGRAM_NAME, PROGRAM_VERSION);
    else if (ret == CLC_CONFIG_RET_ERR_CMD)
        printf(_
               ("command line parsing error, use -h option to display usage\n"));
    else if (ret == CLC_CONFIG_RET_ERR_NOCONF) {
        printf(_
               ("missing lyclc config file, default build-in settings are used.\n"));
        ret = 0;
    }
    else if (ret == CLC_CONFIG_RET_ERR_ERRCONF)
        printf(_("can not find %s.\n"), c->conf_path);
    else if (ret == CLC_CONFIG_RET_ERR_CONF)
        printf(_("reading config file %s returned error\n"), c->conf_path);
    else if (ret == CLC_CONFIG_RET_ERR_UNKNOWN)
        printf(_("internal error\n"));

    /* exit if ret is not zero */
    if (ret != 0)
        goto out;

    /* node cpu/mem factors */
    if (c->node_cpu_factor == 0)
        c->node_cpu_factor = DEFAULT_NODE_CPU_FACTOR;
    if (c->node_mem_factor == 0)
        c->node_mem_factor = DEFAULT_NODE_MEM_FACTOR;

    /* for debuuging */
    if (c->debug)
        __print_config(c);

    /* make sure data directory exists */
    if (lyutil_create_dir(c->clc_data_dir)) {
        printf(_("%s is not accessible\n"), c->clc_data_dir);
        ret = -255;
        goto out;
    }

    /* check whether program is started already */
    ret = lyutil_check_pid_file(c->pid_path, PROGRAM_NAME);
    if (ret == 1) {
        printf(_("%s is running already.\n"), PROGRAM_NAME);
        goto out;
    }
    else if (ret != 0) {
        printf(_("error checking pid file.\n"));
        goto out;
    }

    /* check DB */
    if (ly_db_check() < 0) {
        printf(_("failed connecting DB\n"));
        ret = -255;
        goto out;
    }

    /* get clc ip */
    if (c->clc_ip == NULL && ly_clc_ip_get() < 0) {
        logerror(_("CLC no proper network interface to use.\n"));
        goto out;
    }

    /* Daemonize the progress */
    if (c->daemon) {
        if (c->debug == LYDEBUG)
            printf(_("Run as daemon, log to %s.\n"), c->log_path);
        lyutil_daemonize(__main_clean, keeppidfile);
        logfile(c->log_path, c->debug ? LYDEBUG : c->verbose ? LYINFO : LYWARN);
    }
    else
        logfile(NULL, c->debug ? LYDEBUG : c->verbose ? LYINFO : LYWARN);

    /* create lock file */
    ret = lyutil_create_pid_file(c->pid_path, PROGRAM_NAME);
    if (ret == 1) {
        logsimple(_("%s is running already.\n"), PROGRAM_NAME);
        ret = 0;
        goto out;
    }
    else if (ret != 0) {
        logsimple(_("error creating pid file.\n"));
        goto out;
    }
    keeppidfile = 0;

    /* init db connection */
    if (ly_db_init() < 0) {
        logsimple(_("ly_db_init failed.\n"));
        ret = -255;
        goto out;
    }

    /* initialize entity store */
    if (ly_entity_store_init() < 0) {
        logsimple(_("ly_entity_init failed.\n"));
        ret = -255;
        goto out;
    }

    /* init job queue */
    if (job_init() < 0 || job_internal_init() < 0) {
        logsimple(_("job_init failed.\n"));
        ret = -255;
        goto out;
    }
    if (c->debug)
        job_print_queue();

    /* set up signal handler */
    lyutil_signal_init();

    /* handle specific signal */
    struct sigaction sa;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = __sig_handler;
    if (sigaction(SIGTERM, &sa, NULL)) {
        logsimple(_("Setting signal handler error.\n"));
        ret = -255;
        goto out;
    }

    /* initialize g_c->efd */
    if (ly_epoll_init(EPOLL_EVENTS_MAX) != 0) {
        logsimple(_("ly_epoll_init failed.\n"));
        ret = -255;
        goto out;
    }

    if (ly_epoll_work_start(g_c->clc_port) != 0) {
        ret = -1;
        logsimple(_("ly_epoll_init failed.\n"));
        goto out;
    }

    /* init timeout values */
    time_t mcast_join_time, job_dispatch_time, job_internal_time;
    mcast_join_time = 0;
    time(&job_dispatch_time);
    job_internal_time = job_dispatch_time + (CLC_MCAST_JOIN_INTERVAL<<1);
    job_dispatch_time = job_dispatch_time + (CLC_MCAST_JOIN_INTERVAL<<2);

    /* start main event driven loop */
    if (c->clc_ip)
        loginfo(_("clc uses IP %s\n"), c->clc_ip);
    else
        loginfo(_("clc uses IP automatically detected\n"));
    loginfo(_("start event loop, waiting for events ...\n"));
    int i, n = 0;
    struct epoll_event events[EPOLL_EVENTS_MAX];
    while (1) {
        time_t time_now;
        time(&time_now);

        /* send mcast request */
        if (time_now - mcast_join_time > CLC_MCAST_JOIN_INTERVAL) {
            if (ly_mcast_send_join() < 0)
                logerror(_("failed sending mcast request.\n"));
            mcast_join_time = time_now;
        }
        else if (time_now < mcast_join_time)
            mcast_join_time = time_now;

        /* job dispatch */
        if (time_now - job_dispatch_time > CLC_JOB_DISPATCH_INTERVAL) {
            if (job_dispatch() < 0)
                logerror(_("job_dispatch failed.\n"));
            job_dispatch_time = time_now;
        }
        else if (time_now < job_dispatch_time)
            job_dispatch_time = time_now;

        /* internal job dispatch */
        if (time_now - job_internal_time > CLC_JOB_INTERNAL_INTERVAL) {
            if (job_internal_dispatch() < 0)
                logerror(_("job_internal failed.\n"));
            job_internal_time = time_now;
        }
        else if (time_now < job_internal_time)
            job_internal_time = time_now;

        n = epoll_wait(g_efd, events, EPOLL_EVENTS_MAX,
                       CLC_EPOLL_TIMEOUT);
        if (n != 0)
            logdebug(_("waiting ... got %d events\n"), n);
        for (i = 0; i < n; i++) {
            int id = events[i].data.fd;
            if (events[i].events & EPOLLIN) {
                ret = ly_epoll_entity_recv(id);
                if (ret < 0) {
                    logerror(_("epoll_data_recv error\n"));
                }
                else if (ret > 0) {
                    loginfo(_("release entity %d\n"), id);
                    ly_entity_release(id);
                }
            }
            else if (events[i].events & EPOLLRDHUP) {
                loginfo(_("epoll entity(%d) got rdhup. close.\n"), id);
                ly_entity_release(id);
            }
            else if (events[i].events & EPOLLHUP) {
                loginfo(_("epoll entity(%d) got hup. close.\n"), id);
                ly_entity_release(id);
            }
            else {
                logerror(_("unexpected event(%d, %d). ignore.\n"),
                         events[i].events, id);
            }
        }
    }

out:
    __main_clean(keeppidfile);
    if (ret <= 0)
        loginfo(_("%s exits\n"), PROGRAM_NAME);
    return ret;
}
Exemple #3
0
/* process node register request */
static int __node_xml_register(xmlDoc * doc, xmlNode * node, int ent_id)
{
    if (ly_entity_is_registered(ent_id)) {
        logwarn(_("received node register request again, ignored\n"));
        return -1;
    }

    LYNodeData * nd = ly_entity_data(ent_id);
    if (nd == NULL ) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        return -1;
    }
    NodeInfo * nf = &nd->node;

    /* Create xpath evaluation context */
    xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
    if (xpathCtx == NULL) {
        logerror(_("unable to create new XPath context %s, %d\n"),
                 __func__, __LINE__);
        return -1;
    }
    int ret = -1;

    char *str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/status");
    if (str == NULL)
        goto xml_err;
    nf->status = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/hypervisor");
    if (str == NULL)
        goto xml_err;
    nf->hypervisor = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/host/tag");
    int tag = -1;
    if (str) {
        tag = atoi(str); /* NULL str is allowed for new node */
        free(str);
    }
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/host/name");
    if (str == NULL)
        goto xml_err;
    nf->host_name = str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/host/ip");
    if (str == NULL)
        goto xml_err;
    nf->host_ip = str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/arch");
    if (str == NULL)
        goto xml_err;
    nf->cpu_arch = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/model");
    if (str == NULL)
        goto xml_err;
    nf->cpu_model = str;
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/mhz");
    if (str == NULL)
        goto xml_err;
    nf->cpu_mhz = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/max");
    if (str == NULL)
        goto xml_err;
    nf->cpu_max = atoi(str);
    nf->cpu_vlimit = NODE_SCHEDULE_CPU_LIMIT(nf->cpu_max);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/cpu/commit");
    if (str == NULL)
        goto xml_err;
    nf->cpu_commit = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/memory/total");
    if (str == NULL)
        goto xml_err;
    nf->mem_max = atoi(str);
    nf->mem_vlimit = NODE_SCHEDULE_MEM_LIMIT(nf->mem_max);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/memory/free");
    if (str == NULL)
        goto xml_err;
    nf->mem_free = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/memory/commit");
    if (str == NULL)
        goto xml_err;
    nf->mem_commit = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/storage/total");
    if (str == NULL)
        goto xml_err;
    nf->storage_total = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                         "/" LYXML_ROOT "/request/parameters/storage/free");
    if (str == NULL)
        goto xml_err;
    nf->storage_free = atoi(str);
    free(str);
    str = xml_xpath_text_from_ctx(xpathCtx,
                          "/" LYXML_ROOT "/request/parameters/load/average");
    if (str == NULL)
        goto xml_err;
    nf->load_average = atoi(str);
    free(str);

    if (nf->status >= NODE_STATUS_REGISTERED) {
        logwarn(_("node(%d, %s) tries to register from wrong status(%d)\n"),
                 nf->host_tag, nf->host_ip, nf->status);
        ly_entity_release(ent_id);
        ret = 0; /* no need to continue node registration */
        goto done;
    }
        
    if (ly_entity_node_active(nf->host_ip)) {
        logwarn(_("duplicate node ip received. something is wrong...\n"));
        ly_entity_release(ent_id);
        ret = 0; /* no need to continue node registration */
        goto done;
    }
   
    if (tag > 0) {
        /* check authentication result */
        if (nf->host_tag > 0 && tag != nf->host_tag) {
            logerror(_("node tag changed, %d -> %d. something is wrong.\n"),
                       nf->host_tag, tag);
            goto done;
        }
        nf->host_tag = tag;
        ret = __node_register_auth(nf, ent_id);
        if (ret == LY_S_REGISTERING_DONE_SUCCESS) {
            AuthConfig * ac = ly_entity_auth(ent_id);
            if (db_node_update_secret(DB_NODE_FIND_BY_ID, &tag,
                                      ac->secret) < 0 ||
                db_node_update_status(DB_NODE_FIND_BY_ID, &tag,
                                      NODE_STATUS_REGISTERED) < 0) {
                logerror(_("error in %s(%d)\n"), __func__, __LINE__);
                ret = -1;
                goto done;
            }
            loginfo(_("node(tag:%d) registered\n"), tag);
            ly_entity_update(ent_id, tag, LY_ENTITY_FLAG_STATUS_REGISTERED);
        }
        goto done;
    }

    /* new node */
    DBNodeRegInfo db_nf;
    bzero(&db_nf, sizeof(DBNodeRegInfo));
    ret = db_node_find(DB_NODE_FIND_BY_IP, nf->host_ip, &db_nf);
    if (ret < 0 || ret > 1) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        ret = -1;
        goto done;
    }

    if (ret == 0 || db_nf.secret) {
        /* new node */
        logdebug(_("new node\n"));
        if (nf->status != NODE_STATUS_UNINITIALIZED) {
            logwarn(_("node(%d, %s) tries to register from unexpected status(%d)\n"),
                       nf->host_tag, nf->host_ip, nf->status);
            nf->status = NODE_STATUS_UNINITIALIZED;
        }
        if (db_nf.secret) {
            logwarn(_("new node takes ip(%s) used by tagged node\n"), nf->host_ip);
            db_node_reginfo_free(&db_nf);
            bzero(&db_nf, sizeof(DBNodeRegInfo));
        }
            
        ret = db_node_insert(nf);
        if (ret < 0) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            goto new_done;
        }
        db_nf.id = ret;
        loginfo(_("new node %s added in db(%d)\n"), nf->host_ip, ret);

        /* enable node if node is control server */
        if (ly_is_clc_ip(nf->host_ip)) {
            if (db_node_enable(ret, 1) != 0 ||
                db_node_find(DB_NODE_FIND_BY_ID, &ret, &db_nf) != 1) {
                logerror(_("error in %s(%d)\n"), __func__, __LINE__);
                ret = -1;
                goto new_done;
            }
        }
    }
    else
        logdebug(_("untagged node for ip(%s) found in db\n"), nf->host_ip);

    ly_entity_update(ent_id, db_nf.id, LY_ENTITY_FLAG_STATUS_ONLINE);
    if (db_nf.enabled) {
        AuthConfig * ac = ly_entity_auth(ent_id);
        ret = -1;
        if (ac->secret) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            goto new_done;
        }
        ac->secret = lyauth_secret();
        if (ac->secret == NULL) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            goto new_done;
        }
        nf->host_tag = db_nf.id;
        ret = LY_S_REGISTERING_CONFIG;
    }
    else {
        logdebug(_("register request done, node %s not enabled\n"), nf->host_ip);
        ret = LY_S_REGISTERING_INIT;
    }
    nf->status = NODE_STATUS_ONLINE;
    if (db_node_update(DB_NODE_FIND_BY_ID, &db_nf.id, nf) < 0) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        ret = -1;
    }

new_done:
    db_node_reginfo_free(&db_nf);
    goto done;
xml_err:
    logerror(_("invalid node xml register request\n"));
done:
    xmlXPathFreeContext(xpathCtx);
    logdebug(_("end of %s, node status %d\n"), __func__, nf->status);
    return ret;
}
Exemple #4
0
/* process xml response */
static int __process_node_xml_response(xmlDoc * doc, xmlNode * node,
                                       int ent_id)
{
    logdebug(_("node response for entity %d\n"), ent_id);
    char * str = (char *) xmlGetProp(node, (const xmlChar *) "id");
    if (str)
        logdebug("node response id(job id) = %s\n", str);
    else {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        return -1;
    }
    int id = atoi(str);
    free(str);

    str = (char *) xmlGetProp(node, (const xmlChar *) "status");
    if (str)
        logdebug("node response status = %s\n", str);
    else {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        return -1;
    }
    int status = atoi(str);
    free(str);

    int data_type = -1;
    node = node->children;
    for (; node; node = node->next) {
        if (node->type == XML_ELEMENT_NODE) {
            if (strcmp((char *)node->name, "result") == 0) {
                xmlNode * n = node->children;
                if (n && n->type == XML_TEXT_NODE && n->content)
                    loginfo(_("response result: %s\n"), n->content);
                else
                    loginfo(_("response no result message\n"));
            }
            else if (strcmp((char *)node->name, "data") == 0) {
                str = (char *) xmlGetProp(node, (const xmlChar *) "type");
                if (str) {
                    logdebug("node response data type = %s\n", str);
                    data_type = atoi(str);
                    free(str);
                }
                else
                    logwarn(_("response data no type\n"));
            }
        }
    }

    if (id != 0) {
        LYJobInfo * job = job_find(id);
        if (job == NULL) {
            logwarn(_("job(%d) not found waiting for node reply\n"), id);
            return 0;
        }
        if (job_update_status(job, status)) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            return -1;
        }
        /* hack to release entity during instance shutting down */
        if (((job->j_action == LY_A_NODE_STOP_INSTANCE) ||
            (job->j_action == LY_A_NODE_FULLREBOOT_INSTANCE) ||
            (job->j_action == LY_A_NODE_ACPIREBOOT_INSTANCE)) && 
            status == LY_S_RUNNING_STOPPED) {
                int ins_id = ly_entity_find_by_db(LY_ENTITY_OSM, job->j_target_id);
                if (ins_id > 0)
                    ly_entity_release(ins_id);
            }
         /* continue processing for data */
    }

    int ent_type = ly_entity_type(ent_id);
    if (ent_type == LY_ENTITY_NODE && data_type == DATA_INSTANCE_INFO) { 
        if ( __instance_info_update(doc, node)) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            return -1;
        }
    }
   
    if (ent_type == LY_ENTITY_NODE && data_type == DATA_NODE_INFO) { 
        if ( __node_info_update(doc, node, ent_id, &status)) {
            logerror(_("error in %s(%d)\n"), __func__, __LINE__);
            return -1;
        }
    }
 
    return 0;
}
Exemple #5
0
/* clc work socket receives connection */
static int __epoll_work_recv(int ent_id)
{
    int fd = ly_entity_fd(ent_id);
    if (fd == -1)
        return -255;

    struct sockaddr in_addr;
    socklen_t in_len;
    int infd;

    in_len = sizeof(in_addr);
    infd = accept(fd, &in_addr, &in_len);
    if (infd == -1) {
        if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
            /* We have processed all incoming connections. */
            logdebug(_("accept error(%d) ignored\n"), errno);
            return 0;
        }
        else {
            logerror(_("unexpected accept error(%d) in %s"), errno,
                     __func__);
            return -1;
        }
    }

    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
    int ret = getnameinfo(&in_addr, in_len, hbuf, sizeof(hbuf),
                          sbuf, sizeof(sbuf),
                          NI_NUMERICHOST | NI_NUMERICSERV);
    if (ret)
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
    else
        loginfo(_("accepted connection from %s:%s. open socket %d\n"),
                  hbuf, sbuf, infd);

    /* keep alive */
    if (lyutil_set_keepalive(infd, CLC_SOCKET_KEEPALIVE_INTVL,
                                   CLC_SOCKET_KEEPALIVE_INTVL,
                                   CLC_SOCKET_KEEPALIVE_PROBES) < 0) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        close(infd);
        return -1;
    }

    int id = ly_entity_new(infd);
    if (id < 0) {
        logerror(_("error in %s(%d)\n"), __func__, __LINE__);
        close(infd);
        return -1;
    }
    struct epoll_event ev;
    ev.data.fd = id;
    ev.events = EPOLLIN;
    ret = epoll_ctl(g_efd, EPOLL_CTL_ADD, infd, &ev);
    if (ret == -1) {
        logerror(_("add socket to epoll error in %s.\n"), __func__);
        ly_entity_release(id);
        /* close(infd); closed in ly_entity_release */
        return -1;
    }
    loginfo(_("entity %d registered in epoll.\n"), id);

    return 0;
}