/* convenience function to return all nodes, or default node if none found */ static fsa_node_addr *get_storage_nodes(void) { 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) { fsa_error(LOG_WARNING, "Unable to read config file at '%s', assuming localhost\n", fs_get_config_file()); nodes = fsa_node_addr_new("localhost"); nodes->port = default_port; return nodes; } 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) { fsa_error(LOG_WARNING, "No nodes found in '%s', assuming localhost\n", fs_get_config_file()); nodes = fsa_node_addr_new("localhost"); nodes->port = default_port; return nodes; } return nodes; }
/* check command line opts and config file to set server_port global */ static int init_server_port(void) { int port; /* no port given on command line */ if (cport == NULL) { /* get default or config file port */ GKeyFile *config = fsa_get_config(); port = fsa_get_admind_port(config); fsa_config_free(config); if (port == -1) { if (errno == ADM_ERR_BAD_CONFIG) { fprintf( stderr, "%s: non-numeric port specified in %s", program_invocation_short_name, fs_get_config_file() ); } else if (errno == ERANGE) { fprintf( stderr, "%s: port number out of range 0-65535 in %s", program_invocation_short_name, fs_get_config_file() ); } else { fprintf( stderr, "%s: unknown error reading port from config file at %s\n", program_invocation_short_name, fs_get_config_file() ); } return -1; } } else { /* cport has been specified on command line */ if (!fsa_is_int(cport)) { fprintf(stderr, "%s: non-numeric port specified on command line\n", program_invocation_short_name); return -1; } port = atoi(cport); if (port < 0 || port > 65535) { fprintf(stderr, "%s: port number %d out of range 0-65535\n", program_invocation_short_name, port); return -1; } } /* have a port 0-65535 if we got here */ sprintf(server_port, "%d", port); return 0; }
/* 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; }
/* Get list of storage nodes admind host/ports from /etc/4store.conf, default to localhost */ fsa_node_addr *fsa_get_node_list(GKeyFile *config_file) { fsa_node_addr *first_na = NULL; fsa_node_addr *na = NULL; int default_port = fsa_get_admind_port(config_file); gsize len; GError *err = NULL; gchar **nodes = g_key_file_get_string_list(config_file, "4s-boss", "nodes", &len, &err); if (nodes == NULL) { g_error_free(err); first_na = fsa_node_addr_new("localhost"); first_na->port = default_port; return first_na; } gchar *cur; char *tok; /* build list in reverse order to keep string order from conf */ for (int i = len-1; i >= 0; i--) { cur = nodes[i]; if (cur[0] == '[') { int cur_len = strlen(cur); int start = 1; int end = 1; while (cur[end] != ']' && end < cur_len) { end += 1; } char *v6addr = (char *)malloc(end - start + 1); strncpy(v6addr, &cur[start], end - start); v6addr[end - start] = '\0'; na = fsa_node_addr_new(v6addr); free(v6addr); end += 1; if (end >= cur_len || cur[end] != ':') { na->port = default_port; } else { na->port = atoi(&cur[end+1]); } } else { /* treat as v4 addr or hostname */ tok = strtok(cur, ":"); na = fsa_node_addr_new(tok); tok = strtok(NULL, ":"); if (tok != NULL) { na->port = atoi(tok); } else { na->port = default_port; } } na->next = first_na; first_na = na; } g_strfreev(nodes); return first_na; }
/* 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; }
/* 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; }