Exemplo n.º 1
0
/* create a single kb */
static void handle_cmd_create_kb(int client_fd, uint16_t datasize)
{
    int rv, err;
    unsigned char *msg = NULL;
    int exit_val; /* exit value from 4s-backend-setup */

    /* unpack client data into buffer */
    unsigned char *buf = (unsigned char *)malloc(datasize);
    rv = recv_from_client(client_fd, buf, datasize);
    if (rv <= 0) {
        /* errors already logged/handled */
        free(buf);
        return;
    }

    /* parse buffer into kb setup args struct */
    fsa_kb_setup_args *ksargs = fsap_decode_cmd_create_kb(buf);
    fsa_error(LOG_DEBUG, "ksargs->name: %s", ksargs->name);
    fsa_error(LOG_DEBUG, "ksargs->node_id: %d", ksargs->node_id);
    fsa_error(LOG_DEBUG, "ksargs->cluster_size: %d", ksargs->cluster_size);
    fsa_error(LOG_DEBUG, "ksargs->num_segments: %d", ksargs->num_segments);
    fsa_error(LOG_DEBUG, "ksargs->mirror_segments: %d",ksargs->mirror_segments);
    fsa_error(LOG_DEBUG, "ksargs->model_files: %d", ksargs->model_files);
    fsa_error(LOG_DEBUG, "ksargs->delete_existing: %d",ksargs->delete_existing);

    /* should already have been checked by client */
    if (!fsa_is_valid_kb_name((const char *)ksargs->name)) {
        fsa_error(LOG_CRIT, "Invalid store name received from client");
        send_error_message(client_fd, "store name invalid");
        fsa_kb_setup_args_free(ksargs);
    }

    rv = fsab_create_local_kb(ksargs, &exit_val, &msg, &err);

    /* encode message for client */
    int len;
    unsigned char *response =
        fsap_encode_rsp_create_kb(err, ksargs->name, msg, &len);

    fsa_error(LOG_DEBUG, "sending err: %d, kb_name: %s, msg: %s",
              err, ksargs->name, msg);

    fsa_kb_setup_args_free(ksargs);
    free(msg);

    fsa_error(LOG_DEBUG, "response size is %d bytes", len);

    /* send entire response back to client */
    rv = fsa_sendall(client_fd, response, &len);
    free(response);
    if (rv == -1) {
        fsa_error(LOG_ERR, "failed to send response to client: %s",
                  strerror(errno));
        return;
    }

    fsa_error(LOG_DEBUG, "%d bytes sent to client", len);
}
Exemplo n.º 2
0
/* get all information about a specific kb on this host, send to client */
static void handle_cmd_get_kb_info(int client_fd, uint16_t datasize)
{
    int rv, len, err;
    fsa_kb_info *ki;
    unsigned char *response;
    unsigned char *kb_name;

    kb_name = get_string_from_client(client_fd, datasize);
    if (kb_name == NULL) {
        /* errors already logged/handled */
        return;
    }

    /* should already have been checked by client */
    if (!fsa_is_valid_kb_name((const char *)kb_name)) {
        fsa_error(LOG_CRIT, "Invalid kb name received from client");
        send_error_message(client_fd, "kb name invalid");
        free(kb_name);
        return;
    }

    ki = fsab_get_local_kb_info(kb_name, &err);
    free(kb_name); /* done with kb_name */
    if (ki == NULL || err == ADM_ERR_KB_NOT_EXISTS) {
        send_error_message(client_fd, "failed to get local kb info");
        return;
    }

    /* encode message for client */
    response = fsap_encode_rsp_get_kb_info(ki, &len);
    fsa_kb_info_free(ki);
    if (response == NULL) {
        send_error_message(client_fd, "failed to encode kb info");
        return;
    }

    fsa_error(LOG_DEBUG, "response size is %d bytes", len);

    /* send entire response back to client */
    rv = fsa_sendall(client_fd, response, &len);
    free(response); /* done with response buffer */
    if (rv == -1) {
        fsa_error(LOG_ERR, "failed to send response to client: %s",
                  strerror(errno));
        return;
    }

    fsa_error(LOG_DEBUG, "%d bytes sent to client", len);
}
Exemplo n.º 3
0
/* delete a single kb */
static void handle_cmd_delete_kb(int client_fd, uint16_t datasize)
{
    int rv, err;
    unsigned char *msg = NULL;
    int exit_val; /* exit value from 4s-backend-delete */

    /* datasize = num chars in kb name */
    unsigned char *kb_name = get_string_from_client(client_fd, datasize);
    if (kb_name == NULL) {
        /* errors already logged/handled */
        return;
    }

    /* should already have been checked by client */
    if (!fsa_is_valid_kb_name((const char *)kb_name)) {
        fsa_error(LOG_CRIT, "Invalid kb name received from client");
        send_error_message(client_fd, "kb name invalid");
        free(kb_name);
        return;
    }

    rv = fsab_delete_local_kb(kb_name, &exit_val, &msg, &err);

    /* encode message for client */
    int len;
    unsigned char *response =
        fsap_encode_rsp_delete_kb(err, kb_name, msg, &len);

    fsa_error(LOG_DEBUG, "sending err: %d, kb_name: %s, msg: %s",
              err, kb_name, msg);

    free(msg);
    free(kb_name);

    fsa_error(LOG_DEBUG, "response size is %d bytes", len);

    /* send entire response back to client */
    rv = fsa_sendall(client_fd, response, &len);
    free(response); /* done with response buffer */
    if (rv == -1) {
        fsa_error(LOG_ERR, "failed to send response to client: %s",
                  strerror(errno));
        return;
    }

    fsa_error(LOG_DEBUG, "%d bytes sent to client", len);
}
Exemplo n.º 4
0
static int cmd_delete_stores(void)
{
    if (args_index < 0) {
        /* no argument given, display help text */
        fsa_error(
            LOG_ERR,
            "No store name(s) given. Use `%s help %s' for details",
            program_invocation_short_name, argv[cmd_index]
        );
        return 1;
    }

    /* check for invalid store names */
    int store_name_len = 11;
    for (int i = args_index; i < argc; i++) {
        if (!fsa_is_valid_kb_name(argv[i])) {
            fsa_error(LOG_ERR, "'%s' is not a valid store name", argv[i]);
            return 1;
        }

        int len = strlen(argv[i]);
        if (len > store_name_len) {
            store_name_len = len;
        }
    }
    
    /* get list of all storage nodes */
    fsa_node_addr *node;
    fsa_node_addr *nodes = get_storage_nodes();
    int n_nodes = 0;
    int node_name_len = 9;
    for (node = nodes; node != NULL; node = node->next) {
        int len = strlen(node->host);
        if (len > node_name_len) {
            node_name_len = len;
        }
        
        n_nodes += 1;
    }

    /* connections to each node */
    int *sock_fds = init_sock_fds(n_nodes);

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

    char ipaddr[INET6_ADDRSTRLEN];
    int cur_node = 0;
    int print_node_header = 1;
    int node_status;

    printf("Checking cluster status:\n");

    for (fsa_node_addr *n = nodes; n != NULL; n = n->next) {
        sock_fds[cur_node] =
            fsaf_connect_to_admind(n->host, n->port, &hints, ipaddr);

        if (sock_fds[cur_node] == -1) {
            node_status = -1;
        }
        else {
            node_status = 0;
        }

        print_node_status_line(cur_node, n->host, node_status,
                               node_name_len, print_node_header);
        print_node_header = 0;

        cur_node += 1;
    }

    /* check that we've got a connection to all nodes */
    for (int i = 0; i < n_nodes; i++) {
        if (sock_fds[i] == -1) {
            cleanup_sock_fds(sock_fds, n_nodes);
            printf("Failed to connect to all nodes, aborting.\n");
            return 1;
        }
    }
    printf("\n");

    int response, bufsize, err, len;
    int n_errors = 0;
    int n_deleted;
    unsigned char *cmd;
    unsigned char *buf;
    int print_store_header = 1;

    /* delete one kb at a time across all nodes */
    for (int i = args_index; i < argc; i++) {
        cur_node = 0;
        n_deleted = 0;
        cmd = fsap_encode_cmd_delete_kb((unsigned char *)argv[i], &len);
        if (cmd == NULL) {
            fsa_error(LOG_CRIT, "failed to encode %s command",
                      argv[cmd_index]);
            n_errors += 1;
            break;
        }

        for (node = nodes; node != NULL; node = node->next) {
            fsa_error(LOG_DEBUG, "sending %s '%s' command to %s:%d",
                      argv[cmd_index], argv[i], node->host, node->port);

            buf = fsaf_send_recv_cmd(node, sock_fds[cur_node], cmd, len,
                                     &response, &bufsize, &err);

            /* usually a network error */
            if (buf == NULL) {
                /* error already handled */
                n_errors += 1;
                break;
            }

            if (response == ADM_RSP_DELETE_KB) {
                fsa_kb_response *kbr = fsap_decode_rsp_delete_kb(buf);

                switch (kbr->return_val) {
                    case ADM_ERR_OK:
                        fsa_error(
                            LOG_DEBUG,
                            "kb '%s' deleted on node %s",
                            kbr->kb_name, node->host
                        );
                        n_deleted += 1;
                        break;
                    case ADM_ERR_KB_STATUS_UNKNOWN:
                        /* kb deleted, but runtime status not confirmed */
                        fsa_error(
                            LOG_DEBUG,
                            "kb '%s' deleted on node %s, but runtime status "
                            "not confirmed",
                            kbr->kb_name, node->host
                        );
                        n_deleted += 1;
                        break;
                    case ADM_ERR_KB_NOT_EXISTS:
                        fsa_error(
                            LOG_DEBUG,
                            "kb '%s' does not exist on node %s",
                            kbr->kb_name, node->host
                        );
                        break;
                    case ADM_ERR_KB_GET_INFO:
                        fsa_error(
                            LOG_ERR,
                            "failed to get info for kb '%s' on node %s",
                            kbr->kb_name, node->host
                        );
                        n_errors += 1;
                        break;
                    case ADM_ERR_POPEN:
                    case ADM_ERR_GENERIC:
                    default:
                        fsa_error(
                            LOG_ERR,
                            "failed to delete kb '%s' on node %s",
                            kbr->kb_name, node->host
                        );
                        n_errors += 1;
                        break;
                }

                fsa_kb_response_free(kbr);
            }
            else if (response == ADM_RSP_ERROR) {
                unsigned char *errmsg = fsap_decode_rsp_error(buf, bufsize);
                fsa_error(LOG_ERR, "server error: %s", errmsg);
                free(errmsg);
                free(buf);
                n_errors += 1;
                break;
            }
            else {
                fsa_error(LOG_CRIT, "unknown response from server");
                free(buf);
                n_errors += 1;
                break;
            }

            free(buf);

            if (n_errors > 0) {
                break;
            }
            cur_node += 1;
        }

        free(cmd);

        if (n_errors > 0) {
            break;
        }

        if (print_store_header) {
            if (colour_flag) {
                printf(ANSI_COLOUR_BLUE);
            }

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

            if (colour_flag) {
                printf(ANSI_COLOUR_RESET);
            }

            print_store_header = 0;
        }

        printf("%-*s ", store_name_len, argv[i]);

        /* else kb deleted on all nodes */
        if (n_deleted == 0) {
            print_colour("store_not_found\n", ANSI_COLOUR_YELLOW);
        }
        else {
            print_colour("deleted\n", ANSI_COLOUR_GREEN);
        }
    }

    /* cleanup */
    cleanup_sock_fds(sock_fds, n_nodes);

    if (n_errors > 0) {
        printf(
          "An error occurred while deleting stores, check status manually\n"
        );
        return 1;
    }
    return 0;
}
Exemplo n.º 5
0
/* Used to handle store starting/stopping, interface is mostly identical */
static int start_or_stop_stores(int action)
{
    int all = 0; /* if -a flag, then start/stop all, instead of kb name */
    int kb_name_len = 11;

    if (args_index < 0) {
        /* no argument given, display help text */
        fsa_error(
            LOG_ERR,
            "No store name(s) given. Use `%s help %s' for details",
            program_invocation_short_name, argv[cmd_index]
        );
        return 1;
    }

    if (strcmp("-a", argv[args_index]) == 0
        || strcmp("--all", argv[args_index]) == 0) {
        all = 1; /* all stores */
    }
    else {
        /* check for invalid store names */
        for (int i = args_index; i < argc; i++) {
            if (!fsa_is_valid_kb_name(argv[i])) {
                fsa_error(LOG_ERR, "'%s' is not a valid store name", argv[i]);
                return 1;
            }

            int len = strlen(argv[i]);
            if (len > kb_name_len) {
                kb_name_len = len;
            }
        }
    }
    
    /* get list of all storage nodes */
    fsa_node_addr *nodes = get_storage_nodes();

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

    int sock_fd, len;
    char ipaddr[INET6_ADDRSTRLEN];
    unsigned char *buf;

    int node_num = 0;
    unsigned char *cmd = NULL;
    int n_errors = 0;

    /* to be set by fsa_send_recv_cmd */
    int response, bufsize, err;

    int print_node_header = 1;
    int print_store_header = 1;

    for (fsa_node_addr *n = nodes; n != NULL; n = n->next) {
        sock_fd = fsaf_connect_to_admind(n->host, n->port, &hints, ipaddr);

        print_node_line(node_num, n->host, print_node_header);
        print_node_header = 0;

        node_num += 1;

        if (sock_fd == -1) {
            print_colour("unreachable\n", ANSI_COLOUR_RED);
            continue;
        }
        
        if (all) {
            /* start/stop all kbs */
            if (action == STOP_STORE) {
                cmd = fsap_encode_cmd_stop_kb_all(&len);
            }
            else if (action == START_STORE) {
                cmd = fsap_encode_cmd_start_kb_all(&len);
            }

            if (cmd == NULL) {
                fsa_error(LOG_CRIT, "failed to encode %s command",
                          argv[cmd_index]);
                n_errors += 1;
                break;
            }

            fsa_error(LOG_DEBUG, "sending '%s' command to %s:%d",
                      argv[cmd_index], n->host, n->port);

            /* send command and get reply */
            buf = fsaf_send_recv_cmd(n, sock_fd, cmd, len,
                                     &response, &bufsize, &err);

            /* usually a network error */
            if (buf == NULL) {
                /* error already handled */
                n_errors += 1;
                break;
            }

            /* should get this if all went well */
            if (response == ADM_RSP_EXPECT_N_KB) {
                int rv;
                uint8_t rspval;
                uint16_t datasize;
                unsigned char header_buf[ADM_HEADER_LEN];
                fsa_kb_response *kbr = NULL;

                int max_kb_len;
                int expected_responses =
                    fsap_decode_rsp_expect_n_kb(buf, &max_kb_len);
                free(buf);

                fsa_error(LOG_DEBUG, "expecting %d responses from server",
                          expected_responses);

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

                    printf("  %-*s status\n", max_kb_len, "store_name");

                    if (colour_flag) {
                        printf(ANSI_COLOUR_RESET);
                    }
                }

                /* get packet from server for each kb started/stopped */
                for (int i = 0; i < expected_responses; i++) {
                    rv = fsa_fetch_header(sock_fd, header_buf);
                    if (rv == -1) {
                        fsa_error(LOG_ERR,
                                  "failed to get response from %s:%d",
                                  n->host, n->port);
                        break;
                    }

                    fsa_error(LOG_DEBUG, "got header %d/%d",
                              i+1, expected_responses);

                    rv = fsap_decode_header(header_buf, &rspval, &datasize);
                    if (rv == -1) {
                        fsa_error(LOG_CRIT,
                                  "unable to decode header from %s:%d",
                                  n->host, n->port);
                        break;
                    }

                    if (rspval == ADM_RSP_ABORT_EXPECT) {
                        fsa_error(LOG_ERR, "operation aborted by server");
                        break;
                    }

                    buf = (unsigned char *)malloc(datasize);
                    rv = fsaf_recv_from_admind(sock_fd, buf, datasize);
                    if (rv < 0) {
                        /* error already handled/logged */
                        free(buf);
                        break;
                    }

                    if (rspval == ADM_RSP_STOP_KB) {
                        kbr = fsap_decode_rsp_stop_kb(buf);
                        printf("  %-*s ", max_kb_len, kbr->kb_name);
                        switch (kbr->return_val) {
                            case ADM_ERR_OK:
                            case ADM_ERR_KB_STATUS_STOPPED:
                                print_colour("stopped", ANSI_COLOUR_GREEN);
                                break;
                            case ADM_ERR_KB_STATUS_UNKNOWN:
                                print_colour("unknown", ANSI_COLOUR_RED);
                                break;
                            default:
                                fsa_error(
                                    LOG_CRIT,
                                    "Unknown server response: %d",
                                    kbr->return_val
                                );
                                print_colour("unknown", ANSI_COLOUR_RED);
                                break;
                        }
                    }
                    else if (rspval == ADM_RSP_START_KB) {
                        kbr = fsap_decode_rsp_start_kb(buf);
                        printf("  %-*s ", max_kb_len, kbr->kb_name);
                        switch (kbr->return_val) {
                            case ADM_ERR_OK:
                            case ADM_ERR_KB_STATUS_RUNNING:
                                print_colour("running", ANSI_COLOUR_GREEN);
                                break;
                            case ADM_ERR_KB_STATUS_STOPPED:
                                print_colour("stopped", ANSI_COLOUR_YELLOW);
                                break;
                            case ADM_ERR_KB_STATUS_UNKNOWN:
                                print_colour("unknown", ANSI_COLOUR_RED);
                                break;
                            default:
                                fsa_error(
                                    LOG_CRIT,
                                    "Unknown server response: %d",
                                    kbr->return_val
                                );
                                print_colour("unknown", ANSI_COLOUR_RED);
                                break;
                        }
                    }
                    printf("\n");

                    free(buf);
                    buf = NULL;
                    fsa_kb_response_free(kbr);
                    kbr = NULL;
                }
            }
            else if (response == ADM_RSP_ERROR) {
                unsigned char *errmsg = fsap_decode_rsp_error(buf, bufsize);
                fsa_error(LOG_ERR, "server error: %s", errmsg);
                free(errmsg);
                free(buf);
            }
            else {
                fsa_error(LOG_ERR, "unexpected response from server: %d",
                          response);
                free(buf);
            }
        }
        else {
            /* print header */
            if (print_store_header) {
                if (colour_flag) {
                    printf(ANSI_COLOUR_BLUE);
                }

                printf("  %-*s status\n", kb_name_len, "store_name");

                if (colour_flag) {
                    printf(ANSI_COLOUR_RESET);
                }

                print_store_header = 0;
            }

            /* stop kbs given on command line */
            for (int i = args_index; i < argc; i++) {
                /* send start/stop command for each kb */
                if (action == STOP_STORE) {
                    cmd = fsap_encode_cmd_stop_kb((unsigned char *)argv[i],
                                                  &len);
                }
                else if (action == START_STORE) {
                    cmd = fsap_encode_cmd_start_kb((unsigned char *)argv[i],
                                                   &len);
                }

                if (cmd == NULL) {
                    fsa_error(LOG_CRIT, "failed to encode %s command",
                            argv[cmd_index]);
                    n_errors += 1;
                    break;
                }

                fsa_error(LOG_DEBUG, "sending %s '%s' command to %s:%d",
                          argv[cmd_index], argv[i], n->host, n->port);

                buf = fsaf_send_recv_cmd(n, sock_fd, cmd, len,
                                         &response, &bufsize, &err);
                free(cmd);
                cmd = NULL;

                /* usually a network error */
                if (buf == NULL) {
                    /* error already handled */
                    n_errors += 1;
                    break;
                }

                printf("  %-*s ", kb_name_len, argv[i]);

                fsa_kb_response *kbr = NULL;

                if (response == ADM_RSP_STOP_KB) {
                    kbr = fsap_decode_rsp_stop_kb(buf);
                    switch (kbr->return_val) {
                        case ADM_ERR_OK:
                        case ADM_ERR_KB_STATUS_STOPPED:
                            print_colour("stopped", ANSI_COLOUR_GREEN);
                            break;
                        case ADM_ERR_KB_NOT_EXISTS:
                            print_colour("store_not_found", ANSI_COLOUR_RED);
                            break;
                        default:
                            print_colour("unknown", ANSI_COLOUR_RED);
                            break;
                    }
                    printf("\n");
                    fsa_kb_response_free(kbr);
                }
                else if (response == ADM_RSP_START_KB) {
                    kbr = fsap_decode_rsp_start_kb(buf);
                    switch (kbr->return_val) {
                        case ADM_ERR_OK:
                        case ADM_ERR_KB_STATUS_RUNNING:
                            print_colour("running", ANSI_COLOUR_GREEN);
                            break;
                        case ADM_ERR_KB_STATUS_STOPPED:
                            print_colour("stopped", ANSI_COLOUR_YELLOW);
                            break;
                        case ADM_ERR_KB_NOT_EXISTS:
                            print_colour("store_not_found", ANSI_COLOUR_RED);
                            break;
                        default:
                            print_colour("unknown", ANSI_COLOUR_RED);
                            break;
                    }
                    printf("\n");
                    fsa_kb_response_free(kbr);
                }
                else if (response == ADM_RSP_ERROR) {
                    unsigned char *msg = fsap_decode_rsp_error(buf, bufsize);
                    printf("unknown: %s\n", msg);
                    free(msg);
                    n_errors += 1;
                }
                else {
                    fsa_error(LOG_CRIT, "unknown response from server");
                    n_errors += 1;
                }
                
                free(buf);
            }
        }

        /* done with current server */
        close(sock_fd);
    }

    if (n_errors > 0) {
        return 1;
    }
    return 0;
}