📄 iscsi-config.c
字号:
if (s1->iscsi_bus != s2->iscsi_bus) return 0; if (s1->target_id != s2->target_id) return 0; if (memcmp(s1->isid, s2->isid, sizeof (s1->isid))) return 0; if (s1->path_number != s2->path_number) return 0; if (!same_portal_config(s1->portal, s2->portal)) return 0; return 1;}intsame_target_config(struct iscsi_target_config *t1, struct iscsi_target_config *t2){ /* Note: this needs to be updated whenever fields are * added to struct iscsi_target_config */ if (!t1 && !t2) return 1; if (t1 && !t2) return 0; if (!t1 && t2) return 0; if (t1->enabled != t2->enabled) return 0; if (memcmp (&t1->auth_options, &t2->auth_options, sizeof (t1->auth_options))) return 0; /* we don't recursively compare session configs */ return 1;}voidfree_portal_descriptors(struct iscsi_portal_descriptor *portals){ struct iscsi_portal_descriptor *portal; while ((portal = portals)) { portals = portal->next; if (portal->address) { debugmsg(6, "freeing portal descriptor address %p", portal->address); free(portal->address); } debugmsg(6, "freeing portal descriptor %p", portal); free(portal); }}voidfree_session_config(struct iscsi_session_config *config){ /* free the portal config */ /* * we assume something else (the daemon's struct iscsi_target) * is managing the lifetime of the descriptors, so we * don't free them here. */ debugmsg(6, "freeing portal config %p of session config %p", config->portal, config); free(config->portal); /* and the config itself */ debugmsg(6, "freeing session config %p of target config %p", config, config->target); free(config);}voidfree_target_config(struct iscsi_target_config *config){ struct iscsi_session_config *session; /* free the session configs */ while ((session = config->sessions)) { config->sessions = session->next; free_session_config(session); } /* we assume something else (the daemon's struct iscsi_target) * is managing the lifetime of the TargetName, so we dont * free it here. */ config->TargetName = NULL; /* don't leave passwords in memory */ memset(&config->auth_options, 0, sizeof (config->auth_options)); /* free the config itself */ debugmsg(6, "freeing target config %p", config); free(config);}intparse_boolean(char *str){ char *end = str; int value = -1; int c; /* stop at the first whitespace */ while (*end && !isspace(c = *end)) end++; *end = '\0'; if (strncasecmp(str, "yes", 3) == 0) { value = 1; } else if (strncasecmp(str, "no", 2) == 0) { value = 0; } else { value = strtol(str, &end, 0); /* check for invalid input */ if (*str && (*end != '\0')) value = -1; } return value;}intparse_number(char *str){ char *end = str; int number = -1; int c; /* stop at the first whitespace */ while (*end && !isspace(c = *end)) end++; *end = '\0'; number = strtol(str, &end, 0); if (*str && (*end == '\0')) return number; /* it was all valid */ else return -1; /* something was invalid */}/* FIXME: accept suffixes for seconds, minutes, hours */intparse_time(char *str){ char *end = str; int number = -1; int c; int units = 1; /* stop at the first whitespace */ while (*end && !isspace(c = *end)) end++; *end = '\0'; end--; switch (*end) { case 's': units = 1; /* seconds */ *end = '\0'; break; case 'm': units = 60; /* minutes */ *end = '\0'; break; case 'h': units = 60 * 60; /* hours */ *end = '\0'; break; default: /* let strtol flag it as invalid */ break; } end++; /* FIXME: check for overflow */ number = strtol(str, &end, 0) * units; if (*str && (*end == '\0')) return number; /* it was all valid */ else return -1; /* something was invalid */}/* * If string is quoted, terminate it at the end quote * - else terminate at first whitespace. * Return pointer after leading quote. */char *parse_quoted_string(char *strp){ char *cp, *retp = strp; int c; if (*strp == '"') { cp = ++strp; retp = cp; /* find the end quote and NUL it */ while ((*cp != '\0') && (*cp != '"')) { cp++; } *cp = '\0'; } else { /* not quoted - terminate it at first whitespace */ cp = strp; while ((*cp != '\0') && (!isspace(c = *cp))) { cp++; } *cp = '\0'; } return retp;}/* * update the existing config so that it matches * what's currently in the config file * FIXME: use a real parser. */intupdate_iscsi_config(const char *pathname, struct iscsi_config *config){ FILE *f = NULL; char *line, *nl, buffer[2048]; int c; struct iscsi_config_entry *entry = NULL, *current_entry = NULL, *slp_entry = NULL; int indent = 0, entry_indent = 0; int line_number = 1; int slp_multicast_seen = 0; if (!config) return 0; f = fopen(pathname, "r"); if (!f) { errormsg("Cannot open configuration file %s", pathname); return 0; } debugmsg(5, "updating config %p from %s", config, pathname); /* clear out any existing config */ while ((entry = config->head)) { remove_config_entry(config, entry); free_config_entry(entry); } memset(config, 0, sizeof (*config)); config->head = config->tail = NULL; /* reset to the platform's usual defaults */ iscsi_init_config_defaults(&config->defaults); /* process the config file */ do { line = fgets(buffer, sizeof (buffer), f); line_number++; if (!line) continue; /* skip but record leading whitespace */ indent = 0; while (isspace(c = *line)) { if (*line == '\t') indent += 8; else indent++; line++; } /* strip trailing whitespace, including the newline. * anything that needs the whitespace must be quoted. */ nl = line + strlen(line) - 1; if (*nl == '\n') { do { *nl = '\0'; nl--; } while (isspace(c = *nl)); } else { logmsg(AS_ERROR, "config file line %d too long", line_number); return 0; } /* process any non-empty, non-comment lines */ if (*line && (*line != '#')) { debugmsg(7, "config indent %d, line %s", indent, line); /* if this line isn't indented farther than * the current entry, it's unrelated. */ if (indent <= entry_indent) current_entry = NULL; if ((strncasecmp(line, "TargetIpAddr=", 13) == 0) || (strncasecmp(line, "DiscoveryAddress=", 17) == 0)) { char *addr = NULL, *port = NULL; char *sep = line; struct iscsi_sendtargets_config *sendtargets_config = NULL; /* find the start of the address */ while (*sep && *sep != '=') sep++; addr = ++sep; if (*addr) { /* look for a port number */ /* FIXME: ought to handle the * IPv6 syntax in the iSCSI spec */ while (*sep && !isspace(c = *sep) && *sep != ':') sep++; if (*sep == ':') { *sep = '\0'; port = ++sep; while (*sep && isdigit(c = *sep)) sep++; *sep = '\0'; } else *sep = '\0'; /* create a new sendtargets config entry */ entry = calloc(1, sizeof (*entry)); if (entry == NULL) { logmsg(AS_ERROR, "failed to allocate " "config entry"); return 0; } entry->line_number = line_number; sendtargets_config = calloc(1, sizeof (*sendtargets_config)); if (sendtargets_config == NULL) { free(entry); entry = NULL; logmsg(AS_ERROR, "failed to allocate " "sendtargets config"); return 0; } entry->type = CONFIG_TYPE_SENDTARGETS; entry->config.sendtargets = sendtargets_config; /* capture the current global defaults */ memcpy(&sendtargets_config-> auth_options, &config->defaults.auth_options, sizeof (sendtargets_config-> auth_options)); memcpy(&sendtargets_config-> connection_timeout_options, &config->defaults. connection_timeout_options, sizeof (sendtargets_config-> connection_timeout_options)); sendtargets_config->continuous = config->defaults. continuous_sendtargets; sendtargets_config->send_async_text = config->defaults.send_async_text; /* record the address and port */ sendtargets_config->address = strdup(addr); if (port && *port && atoi(port) > 0) sendtargets_config->port = atoi(port); else sendtargets_config->port = ISCSI_DEFAULT_PORT; /* append it to the list of all * config entries */ add_config_entry(config, entry); debugmsg(5, "config entry %p " "sendtargets %p = %s:%d", entry, sendtargets_config, addr, sendtargets_config->port); /* indented settings in the config file * may modify this entry */ current_entry = entry; entry_indent = indent; } else { logmsg(AS_ERROR, "error on line %d of %s, an " "address is required", line_number, pathname); } } else if (strncasecmp(line, "DiscoveryFile=", 14) == 0) { char *filename = line + 14; struct iscsi_discovery_file_config *file_config; if (strlen(filename)) { /* create a new sendtargets config entry */ entry = calloc(1, sizeof (*entry)); if (entry == NULL) { logmsg(AS_ERROR, "failed to allocate " "config entry"); return 0; } entry->line_number = line_number; file_config = calloc(1, sizeof (*file_config)); if (file_config == NULL) { free(entry); entry = NULL; logmsg(AS_ERROR, "failed to allocate " "discovery file config"); return 0; } entry->type = CONFIG_TYPE_DISCOVERY_FILE; entry->config.file = file_config; /* capture the current global defaults */ file_config->read_size = 512; /* FIXME: make this configurable */ file_config->continuous = config->defaults. continuous_sendtargets; memcpy(&file_config->auth_options, &config->defaults.auth_options, sizeof (file_config-> auth_options)); /* record the filename */ file_config->filename = strdup(filename); /* append it to the list of all * config entries */ add_config_entry(config, entry); debugmsg(5, "config entry %p discovery " "file %p = %s", entry, file_config, filename); /* indented settings in the config file * may modify this entry */ current_entry = entry; entry_indent = indent; } else { logmsg(AS_ERROR, "error on line %d of %s, " "DiscoveryFile entry requires " "a filename", line_number, pathname); } } else if (strncasecmp(line, "Continuous=", 11) == 0) { int value = parse_boolean(line + 11); if (value < 0) { logmsg(AS_ERROR, "error on line %d of %s, " "invalid value %s", line_number, pathname, line + 11); } else if (current_entry && current_entry->type == CONFIG_TYPE_SENDTARGETS) { struct iscsi_sendtargets_config *sendtargets = current_entry->config.sendtargets; sendtargets->continuous = value; debugmsg(5, "config entry %p sendtargets " "config %p continuous %d", current_entry, sendtargets, value); } else if (current_entry && current_entry->type == CONFIG_TYPE_DISCOVERY_FILE) { struct iscsi_discovery_file_config *file_config = current_entry->config.file; file_config->continuous = value; debugmsg(5, "config entry %p discovery " "file config %p continuous %d", current_entry, file_config, value); } else { config->defaults. continuous_sendtargets = value; debugmsg(5, "config global continuous " "discovery %d", value); } } else if (strncasecmp(line, "SendAsyncText=", 14) == 0) { char *str = &line[14]; int value = parse_boolean(str);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -