예제 #1
0
void fsa_node_addr_free(fsa_node_addr *na)
{
    if (na == NULL) {
        return;
    }

    free(na->host);
    fsa_node_addr_free(na->next);
    free(na);
}
예제 #2
0
파일: admin.c 프로젝트: davechallis/4store
/* get single node_addr based on matching host name in config file */
static fsa_node_addr *node_name_to_node_addr(char *name)
{
    GKeyFile *config = fsa_get_config();
    int default_port = fsa_get_admind_port(config);
    fsa_node_addr *nodes = NULL;

    /* use localhost if no config file found */
    if (config == NULL) {
        if (strcmp(name, "localhost") == 0) {
            nodes = fsa_node_addr_new("localhost");
            nodes->port = default_port;
            return nodes;
        }
        else {
            return NULL;
        }
    }

    nodes = fsa_get_node_list(config);

    /* done with config */
    fsa_config_free(config);

    /* if no nodes found in config file, use localhost */
    if (nodes == NULL) {
        if (strcmp(name, "localhost") == 0) {
            nodes = fsa_node_addr_new("localhost");
            nodes->port = default_port;
            return nodes;
        }
        else {
            return NULL;
        }
    }

    /* count through node list to get node node_num in */
    fsa_node_addr *cur = nodes;
    fsa_node_addr *tmp = NULL;
    while (cur != NULL) {
        if (strcmp(name, cur->host) == 0) {
            /* free rest of node list, then return the current */
            fsa_node_addr_free(cur->next);
            cur->next = NULL;
            return cur;
        }

        /* free current node then move to next */
        tmp = cur;
        cur = cur->next;
        fsa_node_addr_free_one(tmp);
    }

    return NULL;
}
예제 #3
0
fsa_node_addr *fsa_node_addr_new(const char *host)
{
    fsa_node_addr *na = (fsa_node_addr *)malloc(sizeof(fsa_node_addr));
    if (na == NULL) {
        errno = ENOMEM;
        return NULL;
    }

    na->port = 0;
    na->next = NULL;
    na->host = (char *)malloc(strlen(host) + 1);
    if (na->host == NULL) {
        errno = ENOMEM;
        fsa_node_addr_free(na);
        return NULL;
    }

    strcpy(na->host, host);

    return na;
}
예제 #4
0
/* Get info on a kb from any number of nodes. For all kbs, or all nodes,
   set the corresponding argument to NULL */
fsa_kb_info *fsaf_fetch_kb_info(const unsigned char *kb_name,
                                fsa_node_addr *nodes)
{
    fsa_node_addr *cur_node;
    int free_nodes = 0; /* free nodes if they werem't passed to function */

    /* if no nodes given, get all nodes from config */
    if (nodes == NULL) {
        fsa_error(LOG_DEBUG, "fetching kb info for all nodes");
        GKeyFile *conf = fsa_get_config();
        nodes = fsa_get_node_list(conf);
        fsa_config_free(conf);
        free_nodes = 1;
    }

    unsigned char *buf;
    unsigned char header_buf[ADM_HEADER_LEN]; /* store single header packet */
    int nbytes, sock_fd, rv;

    struct addrinfo hints;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    /* command to be sent to all stores */
    int cmd_len; /* length of command packet */
    unsigned char *cmd_pkt; /* command packet itself */
    fsa_kb_info *ki_list = NULL;
    uint8_t cmdval;
    uint16_t datasize;
    char ipaddr[INET6_ADDRSTRLEN]; /* large enough to hold a v4 or v6 addr */

    if (kb_name == NULL) {
        /* get info on all kbs */
        fsa_error(LOG_DEBUG, "fetching info for all kbs");
        cmd_pkt = fsap_encode_cmd_get_kb_info_all(&cmd_len);
    }
    else {
        /* request info on named kb */
        fsa_error(LOG_DEBUG, "fetching info for kb '%s'", kb_name);
        cmd_pkt = fsap_encode_cmd_get_kb_info(kb_name, &cmd_len);
    }

    fsa_error(LOG_DEBUG, "admin command length is %d bytes", cmd_len);

    /* connect to each storage node */
    for (cur_node = nodes; cur_node != NULL; cur_node = cur_node->next) {
        sock_fd = fsaf_connect_to_admind(cur_node->host, cur_node->port,
                                         &hints, ipaddr);
        if (sock_fd == -1) {
            fsa_error(LOG_ERR, "failed to connect to %s:%d, skipping node",
                      cur_node->host, cur_node->port);
            continue;
        }

        /* send command to node */
        nbytes = cmd_len;
        rv = fsa_sendall(sock_fd, cmd_pkt, &nbytes);
        if (rv == -1) {
            fsa_error(LOG_ERR, "failed to send command to %s:%d, skipping node",
                      cur_node->host, cur_node->port);
            continue;
        }

        fsa_error(LOG_DEBUG,
                  "header (%d bytes) sent to %s:%d, waiting for response",
                  nbytes, cur_node->host, cur_node->port);

        /* get response header from node */
        rv = fsa_fetch_header(sock_fd, header_buf);
        if (rv == -1) {
            fsa_error(LOG_ERR,
                      "failed to get response from %s:%d, skipping node",
                      cur_node->host, cur_node->port);
            continue;
        }

        fsa_error(LOG_DEBUG, "response received from %s:%d",
                  cur_node->host, cur_node->port);

        /* server sent us data */
        rv = fsap_decode_header(header_buf, &cmdval, &datasize);
        if (rv == -1) {
            fsa_error(LOG_ERR, "unable to decode header from %s:%d",
                      cur_node->host, cur_node->port);
            close(sock_fd);
            continue;
        }

        /* alloc buffer for receiving further data into */
        buf = (unsigned char *)malloc(datasize);
        if (buf == NULL) {
            errno = ENOMEM;
            free(cmd_pkt);
            return NULL;
        }

        fsa_error(LOG_DEBUG, "response header from %s:%d decoded",
                  cur_node->host, cur_node->port);

        /* handle response from client */
        if (cmdval == ADM_RSP_GET_KB_INFO_ALL) {
            fsa_error(LOG_DEBUG, "ADM_RSP_GET_KB_INFO_ALL received");
            fsa_error(LOG_DEBUG, "fetching data from client");

            nbytes = fsaf_recv_from_admind(sock_fd, buf, datasize);
            if (nbytes <= 0) {
                /* error already handled */
                free(buf);
                continue;
            }

            /* local list of kb info for a single node */
            fsa_kb_info *kid = fsap_decode_rsp_get_kb_info_all(buf);
            free(buf);
            fsa_kb_info *tmp_ki = NULL;
            fsa_kb_info *cur_ki = NULL;

            /* add kb info to list of info across nodes */
            if (kid != NULL) {
                tmp_ki = kid; /* pointer to start of list */
                cur_ki = kid;
                int done = 0;

                while (!done) {
                    cur_ki->ipaddr = (unsigned char *)strdup(ipaddr);
                    if (cur_ki->next == NULL) {
                        /* if last item in list */
                        cur_ki->next = ki_list; /* append existing vals */
                        ki_list = tmp_ki; /* point to new head */
                        done = 1;
                    }
                    else {
                        cur_ki = cur_ki->next;
                    }
                }
            }
        }
        else if (cmdval == ADM_RSP_GET_KB_INFO) {
            fsa_error(LOG_DEBUG, "ADM_RSP_GET_KB_INFO_ALL received");
            fsa_error(LOG_DEBUG, "fetching data from client");

            nbytes = fsaf_recv_from_admind(sock_fd, buf, datasize);
            if (nbytes <= 0) {
                /* error already handled */
                free(buf);
                continue;
            }

            fsa_kb_info *kid = fsap_decode_rsp_get_kb_info(buf);
            free(buf);

            if (kid != NULL) {
                /* copy ip addr to struct */
                kid->ipaddr = (unsigned char *)strdup(ipaddr);
                kid->next = ki_list;
                ki_list = kid;
            }
        }

        close(sock_fd);
    }

    free(cmd_pkt);
    if (free_nodes) {
        fsa_node_addr_free(nodes);
    }

    return ki_list;
}
예제 #5
0
파일: admin.c 프로젝트: davechallis/4store
/* gets host info from config file based on node number (starting at 0) */
static fsa_node_addr *node_num_to_node_addr(int node_num)
{
    /* sanity check node number */
    if (node_num < 0 || node_num >= FS_MAX_SEGMENTS) {
        return NULL;
    }

    GKeyFile *config = fsa_get_config();
    fsa_node_addr *nodes = NULL;
    int default_port = fsa_get_admind_port(config);

    /* assume localhost if no config file found */
    if (config == NULL) {
        if (node_num == 0) {
            nodes = fsa_node_addr_new("localhost");
            nodes->port = default_port;
            return nodes;
        }
        else {
            return NULL;
        }
    }

    /* if no nodes found in config file, use localhost */
    nodes = fsa_get_node_list(config);

    /* done with config */
    fsa_config_free(config);

    if (nodes == NULL) {
        if (node_num == 0) {
            nodes = fsa_node_addr_new("localhost");
            nodes->port = default_port;
            return nodes;
        }
        else {
            return NULL;
        }
    }

    /* count through node list to get node node_num in */
    int i = 0;
    fsa_node_addr *cur = nodes;
    fsa_node_addr *tmp = NULL;
    while (cur != NULL) {
        if (i == node_num) {
            /* free rest of node list, then return the current */
            fsa_node_addr_free(cur->next);
            cur->next = NULL;
            return cur;
        }

        /* free current node then move to next */
        tmp = cur;
        cur = cur->next;
        fsa_node_addr_free_one(tmp);
        i += 1;
    }

    return NULL;
}
예제 #6
0
파일: admin.c 프로젝트: davechallis/4store
/* Check whether admin daemon on all nodes is reachable */
static int cmd_list_nodes(void)
{
    /* this command has no arguments, exit if any are found */
    if (args_index >= 0) {
        print_invalid_arg();
        return 1;
    }

    /* network related vars */
    struct addrinfo hints;
    int default_port = FS_ADMIND_PORT;
    fsa_node_addr *nodes = NULL;
    fsa_node_addr *p;
    int sock_fd;
    char ipaddr[INET6_ADDRSTRLEN];

    /* printing/output related vars */
    int all_nodes_ok = 0;
    int hostlen = 13;
    int len;
    int node_num = 0;
    int n_nodes = 0;

    /* Setup hints information */
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    /* attempt to read /etc/4store.conf */
    GKeyFile *config = fsa_get_config();

    if (config == NULL) {
        /* assume localhost if no config file found */
        fsa_error(LOG_WARNING,
                  "Unable to read config file at '%s', assuming localhost\n",
                  fs_get_config_file()); 
    }
    else {
        nodes = fsa_get_node_list(config);
        if (nodes == NULL) {
            fsa_error(LOG_WARNING,
                      "No nodes found in '%s', assuming localhost\n",
                      fs_get_config_file()); 
            default_port = fsa_get_admind_port(config);
        }
    }

    if (nodes == NULL) {
        /* Use localhost and default port */
        nodes = fsa_node_addr_new("localhost");
        nodes->port = default_port;
    }


    /* loop through once to get lengths of various fields */
    for (p = nodes; p != NULL; p = p->next) {
        len = strlen(p->host) + 1;
        if (len > hostlen) {
            hostlen = len;
        }

        n_nodes += 1;
    }

    int n_nodes_len = int_len(n_nodes);
    if (n_nodes_len < 11) {
        n_nodes_len = 11;
    }

    /* print column headers */
    if (colour_flag) {
        printf(ANSI_COLOUR_BLUE);
    }

    printf("%-*s %-*s port  status      ip_address\n",
           n_nodes_len, "node_number", hostlen, "hostname");

    if (colour_flag) {
        printf(ANSI_COLOUR_RESET);
    }

    /* loop through all nodes and attempt to connect admin daemon on each */
    for (p = nodes; p != NULL; p = p->next) {
        /* set default output for IP address */
        strcpy(ipaddr, "unknown");

        /* check if we can open conn to admin daemon */
        sock_fd = fsaf_connect_to_admind(p->host, p->port, &hints, ipaddr);

        /* print result of attempted connection */
        printf("%-*d %-*s %-5d ",
               n_nodes_len, node_num, hostlen, p->host, p->port);
        if (sock_fd == -1) {
            print_colour("unreachable", ANSI_COLOUR_RED);
            all_nodes_ok = 2;
        }
        else {
            print_colour("ok         ", ANSI_COLOUR_GREEN);
            close(sock_fd);
        }
        printf(" %s\n", ipaddr);

        node_num += 1;
    }

    fsa_node_addr_free(nodes);
    fsa_config_free(config);

    return all_nodes_ok;
}
예제 #7
0
파일: admin.c 프로젝트: davechallis/4store
static int cmd_list_stores(void)
{
    /* verbose listing moved to separate function for clarity */
    if (verbosity >= V_VERBOSE) {
        return cmd_list_stores_verbose();
    }

    fsa_node_addr *nodes = get_nodes_from_cmd_line();
    if (nodes == NULL) {
        /* error messages already printed */
        return 1;
    }

    GHashTable *kb_hash = g_hash_table_new(g_str_hash, g_str_equal);

    fsa_node_addr *node = nodes;
    fsa_node_addr *tmp_node = NULL;
    fsa_kb_info *kis;
    fsa_kb_info *ki;
    fsa_kb_info *next_ki;
    int node_num = 0;
    int name_len;
    int max_name_len = 10; /* track lengths of kb names */

    /* connect to each node separately */
    while (node != NULL) {
        /* only pass a single node to fetch_kb_info, so break linked list  */
        tmp_node = node->next;
        node->next = NULL;

        kis = fsaf_fetch_kb_info(NULL, node);

        /* restore next item in list */
        node->next = tmp_node;

        if (kis != NULL) {
            /* insert each kb info record into hash table */
            ki = kis;
            while (ki != NULL) {
                /* will be breaking the linked list, so track next */
                next_ki = ki->next;

                /* will return NULL if key not found */
                ki->next = g_hash_table_lookup(kb_hash, ki->name);
                g_hash_table_insert(kb_hash, ki->name, ki);

                /* used to align columns when printing */
                name_len = strlen((char *)ki->name);
                if (name_len > max_name_len) {
                    max_name_len = name_len;
                }

                ki = next_ki;
            }
        }

        node_num += 1;
        node = node->next;
    }

    /* sort hash keys, print info for each kb in turn */
    GList *kb_name_list = g_hash_table_get_keys(kb_hash);
    kb_name_list = g_list_sort(kb_name_list, (GCompareFunc)strcmp);

    char *kb_name;
    int n_total, n_running, n_stopped, n_unknown;
    int comma = 0;
    int print_store_header = 1;

    if (kb_name_list == NULL) {
        printf("No stores found\n");
    }

    while (kb_name_list != NULL) {
        if (print_store_header) {
            if (colour_flag) {
                printf(ANSI_COLOUR_BLUE);
            }

            printf("%-*s store_status backend_status\n",
                   max_name_len, "store_name");

            if (colour_flag) {
                printf(ANSI_COLOUR_RESET);
            }
            print_store_header = 0;
        }

        n_running = n_stopped = n_unknown = 0;
        kb_name = kb_name_list->data;

        kis = g_hash_table_lookup(kb_hash, kb_name);
        for (ki = kis; ki != NULL; ki = ki->next) {
            switch (ki->status) {
                case KB_STATUS_RUNNING:
                    n_running += 1;
                    break;
                case KB_STATUS_STOPPED:
                    n_stopped += 1;
                    break;
                case KB_STATUS_UNKNOWN:
                    n_unknown += 1;
                    break;
                default:
                    break;
            }
        }

        n_total = n_running + n_stopped + n_unknown;

        /* output info for this kb */
        printf("%-*s ", max_name_len, kb_name);

        if (n_running == n_total) {
            print_colour("available    ", ANSI_COLOUR_GREEN);
        }
        else {
            print_colour("unavailable  ", ANSI_COLOUR_RED);
        }

        comma = 0;
        if (n_running > 0) {
            printf("%d/%d ", n_running, n_total);
            print_colour("running", ANSI_COLOUR_GREEN);
            comma = 1;
        }

        if (n_stopped > 0) {
            if (comma) {
                printf(", ");
            }
            printf("%d/%d ", n_stopped, n_total);
            print_colour("stopped", ANSI_COLOUR_RED);
            comma = 1;
        }

        if (n_unknown > 0) {
            if (comma) {
                printf(", ");
            }
            printf("%d/%d ", n_unknown, n_total);
            print_colour("unknown", ANSI_COLOUR_YELLOW);
        }

        printf("\n");


        /* done with data in hash entry now */
        fsa_kb_info_free(kis);

        kb_name_list = g_list_next(kb_name_list);
    }

    kb_name_list = g_list_first(kb_name_list);
    g_list_free(kb_name_list);

    fsa_node_addr_free(nodes);
    g_hash_table_destroy(kb_hash);

    return 0;
}
예제 #8
0
파일: admin.c 프로젝트: davechallis/4store
static int cmd_list_stores_verbose(void)
{
    fsa_node_addr *nodes = get_nodes_from_cmd_line();
    if (nodes == NULL) {
        /* error messages already printed */
        return 1;
    }

    fsa_node_addr *node = nodes;
    fsa_node_addr *tmp_node = NULL;
    fsa_kb_info *ki;
    fsa_kb_info *kis;
    int node_num = 0;
    int info_header_printed = 0;
    int print_node_header = 1;

    /* connect to each node separately */
    while (node != NULL) {
        print_node_line(node_num, node->host, print_node_header);
        print_node_header = 0;

        /* only pass a single node to fetch_kb_info, so break linked list  */
        tmp_node = node->next;
        node->next = NULL;

        kis = fsaf_fetch_kb_info(NULL, node);

        /* restore next item in list */
        node->next = tmp_node;

        /* TODO: better error handling, differentiate between err and no
         * stores */
        if (kis != NULL) {
            /* get column widths */
            int max_name = 10;
            int max_segs = 10;
            int curlen;

            for (ki = kis; ki != NULL; ki = ki->next) {
                curlen = strlen((char *)ki->name);
                if (curlen > max_name) {
                    max_name = curlen;
                }

                curlen = ki->p_segments_len * 3;
                if (curlen > max_segs) {
                    max_segs = curlen;
                }
            }

            /* print header */
            if (!info_header_printed) {
                if (colour_flag) {
                    printf(ANSI_COLOUR_BLUE);
                }

                printf("  %-*s status  port  number_of_segments\n",
                       max_name, "store_name");

                if (colour_flag) {
                    printf(ANSI_COLOUR_RESET);
                }

                info_header_printed = 1;
            }

            /* print kb info */
            for (ki = kis; ki != NULL; ki = ki->next) {
                printf("  %-*s ", max_name, ki->name);

                const char *kistat = fsa_kb_info_status_to_string(ki->status);

                if (ki->status == KB_STATUS_RUNNING) {
                    print_colour(kistat, ANSI_COLOUR_GREEN);
                }
                else if (ki->status == KB_STATUS_STOPPED) {
                    print_colour(kistat, ANSI_COLOUR_RED);
                }
                else {
                    print_colour(kistat, ANSI_COLOUR_YELLOW);
                }
                printf(" ");

                if (ki->port > 0) {
                    printf("%-5d ", ki->port);
                }
                else {
                    printf("      ");
                }

                if (ki->p_segments_len > 0) {
                    if (verbosity == V_VERBOSE) {
                        for (int i = 0; i < ki->p_segments_len; i++) {
                            printf("%d", ki->p_segments_data[i]);
                            if (i == ki->p_segments_len-1) {
                                printf(" of %d", ki->num_segments);
                            }
                            else {
                                printf(",");
                            }
                        }
                    }
                    else {
                        /* print summary of segments */
                        printf("%d of %d",
                               ki->p_segments_len, ki->num_segments);
                    }
                }
                printf("\n");
            }
        }

        fsa_kb_info_free(kis);
        node_num += 1;
        node = node->next;
    }

    fsa_node_addr_free(nodes);

    return 0;
}