📄 iscsi-config.c
字号:
/* * iSCSI driver for Linux * Copyright (C) 2002 Cisco Systems, Inc. * maintained by linux-iscsi-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * See the file COPYING included with this distribution for more details. * * $Id: iscsi-config.c,v 1.13 2005/01/11 03:47:08 mikenc Exp $ * */#include "iscsi-sfnet.h"#include "iscsi-hooks.h"char *get_iscsi_initiatorname(char *pathname){ FILE *f = NULL; int c; char *line, buffer[1024]; char *name = NULL; if (!pathname) { logmsg(AS_ERROR, "No pathname to load InitiatorName from"); return NULL; } /* get the InitiatorName */ if ((f = fopen(pathname, "r"))) { while ((line = fgets(buffer, sizeof (buffer), f))) { while (line && isspace(c = *line)) line++; if (strncmp(line, "InitiatorName=", 14) == 0) { char *end = line + 14; /* the name is everything up to the first * bit of whitespace */ while (*end && (!isspace(c = *end))) end++; if (isspace(c = *end)) *end = '\0'; if (end > line + 14) name = strdup(line + 14); } } fclose(f); if (!name) { logmsg(AS_ERROR, "an InitiatorName is required, but " "was not found in %s", pathname); return NULL; } else { debugmsg(5, "InitiatorName=%s\n", name); } return name; } else { errormsg("cannot open InitiatorName configuration file %s", pathname); return NULL; }}intadd_config_entry(struct iscsi_config *config, struct iscsi_config_entry *entry){ if (config == NULL || entry == NULL) return 0; if (config->head) { entry->prev = config->tail; entry->next = NULL; config->tail->next = entry; config->tail = entry; } else { entry->next = entry->prev = NULL; config->head = config->tail = entry; } return 1;}intremove_config_entry(struct iscsi_config *config, struct iscsi_config_entry *entry){ if (config == NULL || entry == NULL) return 0; if (entry == config->head) { config->head = entry->next; if (config->head == NULL) config->tail = NULL; entry->next = entry->prev = NULL; return 1; } else if (entry == config->tail) { entry->prev->next = NULL; config->tail = entry->prev; entry->next = entry->prev = NULL; return 1; } else if (entry->prev && entry->next) { entry->prev->next = entry->next; entry->next->prev = entry->prev; entry->next = entry->prev = NULL; return 1; } else { return 0; }}voidfree_config_entry(struct iscsi_config_entry *entry){ if (entry == NULL) return; switch (entry->type) { case CONFIG_TYPE_SENDTARGETS:{ struct iscsi_sendtargets_config *sendtargets = entry->config.sendtargets; if (sendtargets->address) { free(sendtargets->address); sendtargets->address = NULL; } free(sendtargets); entry->config.sendtargets = NULL; break; } case CONFIG_TYPE_SLP:{ struct iscsi_slp_config *slp = entry->config.slp; if (slp->interfaces) { free(slp->interfaces); slp->interfaces = NULL; } if (slp->address) { free(slp->address); slp->address = NULL; } if (slp->scopes) { free(slp->scopes); slp->scopes = NULL; } free(slp); entry->config.slp = NULL; break; } case CONFIG_TYPE_DISCOVERY_FILE:{ struct iscsi_discovery_file_config *file = entry->config.file; if (file->filename) { free(file->filename); file->filename = NULL; } if (file->address) { free(file->address); file->address = NULL; } if (file->port) { free(file->port); file->port = NULL; } free(file); entry->config.file = NULL; break; } case CONFIG_TYPE_TARGETNAME:{ struct iscsi_targetname_config *targetname = entry->config.targetname; if (targetname->TargetName) free(targetname->TargetName); free(targetname); entry->config.targetname = NULL; break; } case CONFIG_TYPE_SUBNET:{ struct iscsi_subnet_config *subnet = entry->config.subnet; if (subnet->address) free(subnet->address); free(subnet); entry->config.subnet = NULL; break; } default: logmsg(AS_ERROR, "can't free unknown config entry %p type %u\n", entry, entry->type); break; } free(entry);}struct iscsi_auth_config *entry_auth_options(struct iscsi_config_entry *entry){ if (entry == NULL) return NULL; switch (entry->type) { case CONFIG_TYPE_SENDTARGETS:{ struct iscsi_sendtargets_config *sendtargets = entry->config.sendtargets; return &sendtargets->auth_options; } case CONFIG_TYPE_SLP:{ struct iscsi_slp_config *slp = entry->config.slp; return &slp->auth_options; } case CONFIG_TYPE_DISCOVERY_FILE:{ struct iscsi_discovery_file_config *file = entry->config.file; return &file->auth_options; } case CONFIG_TYPE_TARGETNAME:{#ifdef PER_TARGETNAME_AUTH struct iscsi_targetname_config *targetname = entry->config.targetname; return &targetname->auth_options;#else /* disable configuring auth by TargetName for now, * and always get the auth options at run-time * from discovery */ return NULL;#endif } case CONFIG_TYPE_SUBNET:{ return NULL; } default: return NULL; }}struct iscsi_connection_timeout_config *entry_connection_timeout_options(struct iscsi_config_entry *entry){ if (entry == NULL) return NULL; switch (entry->type) { case CONFIG_TYPE_SENDTARGETS:{ struct iscsi_sendtargets_config *sendtargets = entry->config.sendtargets; return &sendtargets->connection_timeout_options; } case CONFIG_TYPE_SLP:{ return NULL; } case CONFIG_TYPE_TARGETNAME:{ struct iscsi_targetname_config *targetname = entry->config.targetname; return &targetname->connection_timeout_options; } case CONFIG_TYPE_SUBNET:{ struct iscsi_subnet_config *subnet = entry->config.subnet; return &subnet->connection_timeout_options; } default: return NULL; }}struct iscsi_session_timeout_config *entry_session_timeout_options(struct iscsi_config_entry *entry){ if (entry == NULL) return NULL; switch (entry->type) { case CONFIG_TYPE_SENDTARGETS:{ return NULL; } case CONFIG_TYPE_SLP:{ return NULL; } case CONFIG_TYPE_TARGETNAME:{ struct iscsi_targetname_config *targetname = entry->config.targetname; return &targetname->session_timeout_options; } case CONFIG_TYPE_SUBNET:{ return NULL; } default: return NULL; }}struct iscsi_error_timeout_config *entry_error_timeout_options(struct iscsi_config_entry *entry){ if (entry == NULL) return NULL; switch (entry->type) { case CONFIG_TYPE_SENDTARGETS:{ return NULL; } case CONFIG_TYPE_SLP:{ return NULL; } case CONFIG_TYPE_TARGETNAME:{ struct iscsi_targetname_config *targetname = entry->config.targetname; return &targetname->error_timeout_options; } case CONFIG_TYPE_SUBNET:{ struct iscsi_subnet_config *subnet = entry->config.subnet; return &subnet->error_timeout_options; } default: return NULL; }}struct iscsi_tcp_config *entry_tcp_options(struct iscsi_config_entry *entry){ if (entry == NULL) return NULL; switch (entry->type) { case CONFIG_TYPE_SENDTARGETS:{ return NULL; } case CONFIG_TYPE_SLP:{ return NULL; } case CONFIG_TYPE_TARGETNAME:{ struct iscsi_targetname_config *targetname = entry->config.targetname; return &targetname->tcp_options; } case CONFIG_TYPE_SUBNET:{ struct iscsi_subnet_config *subnet = entry->config.subnet; return &subnet->tcp_options; } default: return NULL; }}struct iscsi_operational_config *entry_iscsi_options(struct iscsi_config_entry *entry){ if (entry == NULL) return NULL; switch (entry->type) { case CONFIG_TYPE_SENDTARGETS:{ return NULL; } case CONFIG_TYPE_SLP:{ return NULL; } case CONFIG_TYPE_TARGETNAME:{ struct iscsi_targetname_config *targetname = entry->config.targetname; return &targetname->iscsi_options; } case CONFIG_TYPE_SUBNET:{ return NULL; } default: return NULL; }}intsame_portal_descriptor(struct iscsi_portal_descriptor *p1, struct iscsi_portal_descriptor *p2){ if (p1->port != p2->port) return 0; if (p1->tag != p2->tag) return 0; if (p1->ip_length != p2->ip_length) return 0; if (memcmp(p1->ip, p2->ip, p1->ip_length)) return 0; return 1;}intsame_portal_descriptors(struct iscsi_portal_descriptor *portals1, struct iscsi_portal_descriptor *portals2){ struct iscsi_portal_descriptor *p1, *p2; if (portals1 && !portals2) return 0; if (!portals1 && portals2) return 0; /* same when p1 is a subset of p2 and p2 is a subset of p1 */ for (p1 = portals1; p1; p1 = p1->next) { int same = 0; for (p2 = portals2; p2; p2 = p2->next) { if (same_portal_descriptor(p1, p2)) { same = 1; break; } } if (!same) return 0; } for (p2 = portals2; p2; p2 = p2->next) { int same = 0; for (p1 = portals1; p1; p1 = p1->next) { if (same_portal_descriptor(p1, p2)) { same = 1; break; } } if (!same) return 0; } return 1;}intsame_portal_config(struct iscsi_portal_config *p1, struct iscsi_portal_config *p2){ /* Note: this needs to be updated whenever new structures are * added to the portal config */ if (memcmp (&p1->connection_timeout_options, &p2->connection_timeout_options, sizeof (p1->connection_timeout_options))) return 0; if (memcmp(&p1->session_timeout_options, &p2->session_timeout_options, sizeof (p1->session_timeout_options))) return 0; if (memcmp(&p1->error_timeout_options, &p2->error_timeout_options, sizeof (p1->error_timeout_options))) return 0; if (memcmp(&p1->tcp_options, &p2->tcp_options, sizeof (p1->tcp_options))) return 0; if (memcmp(&p1->iscsi_options, &p2->iscsi_options, sizeof (p1->iscsi_options))) return 0; if (!same_portal_descriptor(p1->descriptor, p2->descriptor)) return 0; return 1;}intsame_portal_configs(struct iscsi_portal_config *p1, struct iscsi_portal_config *p2){ /* FIXME: ordering currently matters, but perhaps shouldn't */ while (p1 || p2) { if (p1 && !p2) return 0; if (!p1 && p2) return 0; if (!same_portal_config(p1, p2)) return 0; p1 = p1->next; p2 = p2->next; } return 1;}intsame_session_config(struct iscsi_session_config *s1, struct iscsi_session_config *s2){ /* Note: this needs to be updated whenever fields are * added to struct iscsi_session_config */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -