Hello community, here is the log from the commit of package target-isns for openSUSE:Factory checked in at 2018-11-10 16:55:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/target-isns (Old) and /work/SRC/openSUSE:Factory/.target-isns.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "target-isns" Sat Nov 10 16:55:26 2018 rev:8 rq:644727 version:0.6.5 Changes: -------- --- /work/SRC/openSUSE:Factory/target-isns/target-isns.changes 2018-06-19 12:04:17.056649089 +0200 +++ /work/SRC/openSUSE:Factory/.target-isns.new/target-isns.changes 2018-11-10 16:55:45.824018932 +0100 @@ -1,0 +2,24 @@ +Thu Oct 25 18:37:03 UTC 2018 - opensuse-packag...@opensuse.org + +- Update to version 0.6.5: + * Update the changelog for release 0.6.5 + * Bump version to 0.6.5 + * Do not rely on asprintf() setting the string to NULL in case of error + * Replace snprintf with asprintf for string handling + * Fix portal registration one more time + * Set the "replace" flag when updating the registration of a target + * Cosmetic change: rename tgt_has_portal() to target_has_portal() + * documentation: describe how Open-iSNS reacts to repetitive portal registrations + * A portal is no longer registered when its refcount reaches zero + * Do not register a TPG if it does not contain a portal + * Remove the portals of a TPG when they no longer exist + * Refactor the data structures of TPGs and portals + * Cosmetic change: fix a comment + * Cosmetic change: move the tag variable closer to where it is used + * Reduce the indentation level in isns_rsp_handle() + * Cosmetic change: rename "name" to "iscsi_name" in isns_rsp_handle() + Replacing target-isns-0.6.4.tar.xz with target-isns-0.6.5.tar.xz, + and removing patch (no longer needed); + * Replace-snprintf-with-asprintf-for-string-handling.patch + +------------------------------------------------------------------- Old: ---- Replace-snprintf-with-asprintf-for-string-handling.patch target-isns-0.6.4.tar.xz New: ---- target-isns-0.6.5.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ target-isns.spec ++++++ --- /var/tmp/diff_new_pack.WHGeEd/_old 2018-11-10 16:55:47.136017325 +0100 +++ /var/tmp/diff_new_pack.WHGeEd/_new 2018-11-10 16:55:47.172017281 +0100 @@ -18,12 +18,11 @@ Name: target-isns Summary: Supplies iSNS support for Linux kernel target -License: GPL-2.0+ +License: GPL-2.0-or-later Group: System/Kernel -Version: 0.6.4 +Version: 0.6.5 Release: 0 Source: %{name}-%{version}.tar.xz -Patch1: Replace-snprintf-with-asprintf-for-string-handling.patch Url: https://github.com/open-iscsi/target-isns BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: cmake @@ -46,7 +45,6 @@ %prep %setup -n %{name}-%{version} -%patch1 -p1 %build %cmake -DSUPPORT_SYSTEMD=ON ++++++ _service ++++++ --- /var/tmp/diff_new_pack.WHGeEd/_old 2018-11-10 16:55:47.508016869 +0100 +++ /var/tmp/diff_new_pack.WHGeEd/_new 2018-11-10 16:55:47.528016845 +0100 @@ -4,8 +4,8 @@ <param name="url">https://github.com/open-iscsi/target-isns.git</param> <param name="subdir"></param> <param name="filename">target-isns</param> - <param name="versionformat">0.6.4</param> - <param name="revision">v0.6.4</param> + <param name="versionformat">0.6.5</param> + <param name="revision">v0.6.5</param> <param name="changesgenerate">enable</param> </service> <service name="recompress" mode="disabled"> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.WHGeEd/_old 2018-11-10 16:55:47.688016649 +0100 +++ /var/tmp/diff_new_pack.WHGeEd/_new 2018-11-10 16:55:47.712016619 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/open-iscsi/target-isns.git</param> - <param name="changesrevision">498a8ffa4a0f584549fdf2175a2675a27fb9ce58</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">a6e0d6c09f1ec7aafd9a2db5f08880b5cfa28e6d</param></service></servicedata> \ No newline at end of file ++++++ target-isns-0.6.4.tar.xz -> target-isns-0.6.5.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/target-isns-0.6.4/CHANGELOG.md new/target-isns-0.6.5/CHANGELOG.md --- old/target-isns-0.6.4/CHANGELOG.md 2018-01-20 21:23:46.000000000 +0100 +++ new/target-isns-0.6.5/CHANGELOG.md 2018-06-20 08:26:56.000000000 +0200 @@ -6,6 +6,15 @@ ## [Unreleased] +## [0.6.5] - 2018-06-20 +### Fixed +- Fix registration of new targets after all existing targets are + removed (issue #38). +- Fix invalid update error returned by the Microsoft iSNS server when + removing a portal (issue #40). +- Fix string truncation and compilation with gcc 8. Contributed by Lee + Duncan. + ## [0.6.4] - 2018-01-20 ### Fixed - Fix segfault caused by large PDUs by generating multiple PDUs for diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/target-isns-0.6.4/CMakeLists.txt new/target-isns-0.6.5/CMakeLists.txt --- old/target-isns-0.6.4/CMakeLists.txt 2018-01-20 21:23:46.000000000 +0100 +++ new/target-isns-0.6.5/CMakeLists.txt 2018-06-20 08:26:56.000000000 +0200 @@ -6,7 +6,7 @@ # project(target-isns "C") -set(TARGET_ISNS_VERSION "0.6.4") +set(TARGET_ISNS_VERSION "0.6.5") cmake_minimum_required(VERSION 2.8) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/target-isns-0.6.4/documentation/iSNS-servers.md new/target-isns-0.6.5/documentation/iSNS-servers.md --- old/target-isns-0.6.4/documentation/iSNS-servers.md 2018-01-20 21:23:46.000000000 +0100 +++ new/target-isns-0.6.5/documentation/iSNS-servers.md 2018-06-20 08:26:56.000000000 +0200 @@ -63,7 +63,11 @@ Moreover, the Microsoft iSNS server returns an "invalid update" error if a DevAttrReg request registers a portal that was already registered by a previous DevAttrReg request. +See [Invalid Update (status code 14)](https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653564(v=vs.85)#invalid-update-status-code-14). The OpenIndiana iSNS server has no problem with duplicate portals in a DevAttrReg message or repetitive registration of a portal by several DevAttrReg messages. + +The Open-iSNS server has no problem with repetitive registrations of a +portal by several DevAttrReg messages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/target-isns-0.6.4/src/configfs.c new/target-isns-0.6.5/src/configfs.c --- old/target-isns-0.6.4/src/configfs.c 2018-01-20 21:23:46.000000000 +0100 +++ new/target-isns-0.6.5/src/configfs.c 2018-06-20 08:26:56.000000000 +0200 @@ -31,6 +31,8 @@ * +-- $IQN N W +-- target N */ +#define _GNU_SOURCE + #include "configfs.h" #include <ccan/list/list.h> @@ -55,18 +57,9 @@ LIST_HEAD(targets); LIST_HEAD(portals); -LIST_HEAD(tpg_portals); static int inotify_fd = -1; -/* Associative entity between a TPG and a portal */ -struct tpg_portal { - struct list_node node; /* Member of the "tpg_portals" list */ - struct tpg *tpg; - struct portal *portal; -}; - - bool configfs_iscsi_path_exists(void) { DIR *dir = opendir(config.configfs_iscsi_path); @@ -115,35 +108,43 @@ static struct target *configfs_target_init(const char *name) { struct target *tgt; - char path[512]; + char *path; if ((tgt = malloc(sizeof(struct target))) == NULL) return NULL; - - snprintf(path, sizeof(path), "%s/%s", config.configfs_iscsi_path, name); + if (asprintf(&path, "%s/%s", config.configfs_iscsi_path, name) < 0) { + free(tgt); + return NULL; + } strncpy(tgt->name, name, ISCSI_NAME_SIZE); tgt->name[ISCSI_NAME_SIZE - 1] = '\0'; tgt->exists = false; + tgt->registered = false; tgt->registration_pending = false; tgt->watch_fd = inotify_add_watch(inotify_fd, path, INOTIFY_MASK); list_head_init(&tgt->tpgs); list_add_tail(&targets, &tgt->node); + free(path); return tgt; } static bool configfs_tpg_enabled(const struct target *tgt, uint16_t tpg_tag) { - int fd; + int fd = -1; ssize_t nr; - char buf[8], path[512]; + char buf[8]; + char *path; bool enabled = false; - snprintf(path, sizeof(path), - "%s/%s/tpgt_%hu/enable", - config.configfs_iscsi_path, tgt->name, tpg_tag); - if ((fd = open(path, O_RDONLY)) == -1) + if (asprintf(&path, "%s/%s/tpgt_%hu/enable", + config.configfs_iscsi_path, tgt->name, tpg_tag) < 0) + return false; + if ((fd = open(path, O_RDONLY)) == -1) { + free(path); return false; + } + free(path); if ((nr = read(fd, buf, sizeof(buf))) != -1) { enabled = buf[0] == '1'; } @@ -154,19 +155,32 @@ static struct tpg *configfs_tpg_init(struct target *tgt, uint16_t tpg_tag) { - struct tpg *tpg = malloc(sizeof(struct tpg)); - char path[512]; - char np_path[512]; - - snprintf(path, sizeof(path), "%s/%s/tpgt_%hu", - config.configfs_iscsi_path, tgt->name, tpg_tag); - snprintf(np_path, sizeof(np_path), "%s/np", path); + struct tpg *tpg; + char *path; + char *np_path; + + if ((tpg = malloc(sizeof(struct tpg))) == NULL) + return NULL; + if (asprintf(&path, "%s/%s/tpgt_%hu", + config.configfs_iscsi_path, tgt->name, tpg_tag) < 0) { + free(tpg); + return NULL; + } + if (asprintf(&np_path, "%s/np", path) < 0) { + free(path); + free(tpg); + return NULL; + } + tpg->watch_fd = inotify_add_watch(inotify_fd, path, INOTIFY_MASK); tpg->np_watch_fd = inotify_add_watch(inotify_fd, np_path, INOTIFY_MASK); tpg->tag = tpg_tag; tpg->enabled = configfs_tpg_enabled(tgt, tpg_tag); tpg->exists = false; + list_head_init(&tpg->portals); list_add(&tgt->tpgs, &tpg->node); + free(path); + free(np_path); return tpg; } @@ -211,34 +225,32 @@ strncpy(portal->ip_addr, ip_addr, INET6_ADDRSTRLEN); portal->ip_addr[INET6_ADDRSTRLEN - 1] = '\0'; portal->port = port; - portal->registered = false; list_add(&portals, &portal->node); return portal; } -static struct tpg_portal *configfs_tpg_portal_init(struct tpg *tpg, - struct portal *portal) +static struct portal_ref *configfs_portal_ref_init(struct tpg *tpg, struct portal *portal) { - struct tpg_portal *tpg_portal = malloc(sizeof(struct tpg_portal)); - if (!tpg_portal) + struct portal_ref *portal_ref = malloc(sizeof(struct portal_ref)); + if (!portal_ref) return NULL; - tpg_portal->tpg = tpg; - tpg_portal->portal = portal; - list_add(&tpg_portals, &tpg_portal->node); + portal_ref->portal = portal; + portal_ref->exists = false; + list_add(&tpg->portals, &portal_ref->node); - return tpg_portal; + return portal_ref; } -static struct tpg_portal *configfs_tpg_portal_find(const struct tpg *tpg, +static struct portal_ref *configfs_portal_ref_find(const struct tpg *tpg, const struct portal *portal) { - struct tpg_portal *tpg_portal; + struct portal_ref *portal_ref; - list_for_each(&tpg_portals, tpg_portal, node) { - if (tpg_portal->tpg == tpg && tpg_portal->portal == portal) - return tpg_portal; + list_for_each(&tpg->portals, portal_ref, node) { + if (portal_ref->portal == portal) + return portal_ref; } return NULL; @@ -248,17 +260,24 @@ { DIR *np_dir; struct dirent *dirent; - char np_path[512]; + char *np_path; + struct portal_ref *portal_ref, *portal_ref_next; + + if (asprintf(&np_path, "%s/%s/tpgt_%hu/np", + config.configfs_iscsi_path, tgt->name, tpg->tag) < 0) + return -ENOMEM; - snprintf(np_path, sizeof(np_path), - "%s/%s/tpgt_%hu/np", - config.configfs_iscsi_path, tgt->name, tpg->tag); np_dir = opendir(np_path); + free(np_path); if (!np_dir) return -ENOENT; tpg->enabled = configfs_tpg_enabled(tgt, tpg->tag); + list_for_each(&tpg->portals, portal_ref, node) { + portal_ref->exists = false; + } + while ((dirent = readdir(np_dir))) { if (streq(dirent->d_name, ".") || streq(dirent->d_name, "..")) continue; @@ -275,14 +294,23 @@ assert(portal); } - struct tpg_portal *tpg_portal = configfs_tpg_portal_find(tpg, portal); - if (!tpg_portal) { - tpg_portal = configfs_tpg_portal_init(tpg, portal); - assert(tpg_portal); + struct portal_ref *portal_ref = configfs_portal_ref_find(tpg, portal); + if (!portal_ref) { + portal_ref = configfs_portal_ref_init(tpg, portal); + assert(portal_ref); } + portal_ref->exists = true; } closedir(np_dir); + list_for_each_safe(&tpg->portals, portal_ref, portal_ref_next, node) { + if (portal_ref->exists) + continue; + + list_del(&portal_ref->node); + free(portal_ref); + } + return 0; } @@ -291,13 +319,14 @@ DIR *tgt_dir; struct dirent *dirent; struct tpg *tpg, *tpg_next; - struct tpg_portal *tpg_portal, *tpg_portal_next; uint16_t tpg_tag; - char tgt_path[512]; + char *tgt_path; - snprintf(tgt_path, sizeof(tgt_path), "%s/%s", - config.configfs_iscsi_path, tgt->name); + if (asprintf(&tgt_path, "%s/%s", + config.configfs_iscsi_path, tgt->name) < 0) + return -ENOMEM; tgt_dir = opendir(tgt_path); + free(tgt_path); if (!tgt_dir) return -ENOENT; @@ -314,20 +343,22 @@ if (!tpg) tpg = configfs_tpg_init(tgt, tpg_tag); + if (!tpg) + return -ENOMEM; configfs_tpg_update(tgt, tpg); tpg->exists = true; } closedir(tgt_dir); list_for_each_safe(&tgt->tpgs, tpg, tpg_next, node) { + struct portal_ref *portal_ref, *portal_ref_next; + if (tpg->exists) continue; - list_for_each_safe(&tpg_portals, tpg_portal, tpg_portal_next, node) { - if (tpg_portal->tpg == tpg) { - list_del(&tpg_portal->node); - free(tpg_portal); - } + list_for_each_safe(&tpg->portals, portal_ref, portal_ref_next, node) { + list_del(&portal_ref->node); + free(portal_ref); } list_del(&tpg->node); @@ -366,6 +397,8 @@ tgt = target_find(dirent->d_name); if (!tgt) tgt = configfs_target_init(dirent->d_name); + if (!tgt) + goto out; configfs_target_update(tgt); } closedir(iscsi_dir); @@ -392,19 +425,15 @@ { struct target *tgt, *tgt_next; struct tpg *tpg, *tpg_next; + struct portal_ref *portal_ref, *portal_ref_next; struct portal *portal, *portal_next; - struct tpg_portal *tpg_portal, *tpg_portal_next; - list_for_each_safe(&tpg_portals, tpg_portal, tpg_portal_next, node) { - list_del(&tpg_portal->node); - free(tpg_portal); - } - list_for_each_safe(&portals, portal, portal_next, node) { - list_del(&portal->node); - free(portal); - } list_for_each_safe(&targets, tgt, tgt_next, node) { list_for_each_safe(&tgt->tpgs, tpg, tpg_next, node) { + list_for_each_safe(&tpg->portals, portal_ref, portal_ref_next, node) { + list_del(&portal_ref->node); + free(portal_ref); + } list_del(&tpg->node); inotify_rm_watch(inotify_fd, tpg->watch_fd); inotify_rm_watch(inotify_fd, tpg->np_watch_fd); @@ -414,6 +443,12 @@ inotify_rm_watch(inotify_fd, tgt->watch_fd); free(tgt); } + + list_for_each_safe(&portals, portal, portal_next, node) { + list_del(&portal->node); + free(portal); + } + close(inotify_fd); } @@ -421,8 +456,7 @@ { struct target *tgt; struct tpg *tpg; - struct tpg_portal *tpg_portal; - struct portal *portal; + struct portal_ref *portal_ref; list_for_each(&targets, tgt, node) { log_print(LOG_DEBUG, "target: name = %s", tgt->name); @@ -430,10 +464,8 @@ log_print(LOG_DEBUG, " tpg: tag = %hu, enabled = %d", tpg->tag, tpg->enabled); - list_for_each(&tpg_portals, tpg_portal, node) { - if (tpg_portal->tpg != tpg) - continue; - portal = tpg_portal->portal; + list_for_each(&tpg->portals, portal_ref, node) { + const struct portal *portal = portal_ref->portal; log_print(LOG_DEBUG, " portal: af = IPv%d, ip_addr = %s, port = %hu", portal->af == AF_INET ? 4 : 6, portal->ip_addr, portal->port); } @@ -488,6 +520,8 @@ if ((event->mask & IN_CREATE) && !tpg) { tpg = configfs_tpg_init(tgt, tpg_tag); + if (!tpg) + return; configfs_tpg_update(tgt, tpg); } else if ((event->mask & IN_DELETE) && tpg) { list_del(&tpg->node); @@ -503,6 +537,8 @@ { struct target *tgt; struct tpg *tpg = NULL; + uint16_t tpg_tag; + struct portal_ref *portal_ref, *portal_ref_next; list_for_each(&targets, tgt, node) { tpg = tpg_find_by_watch(tgt, event->wd); @@ -512,10 +548,22 @@ if (!tpg) return; - configfs_tpg_update(tgt, tpg); + tpg_tag = tpg->tag; + + if (configfs_tpg_update(tgt, tpg) == -ENOENT) { + list_for_each_safe(&tpg->portals, portal_ref, portal_ref_next, node) { + list_del(&portal_ref->node); + free(portal_ref); + } + list_del(&tpg->node); + inotify_rm_watch(inotify_fd, tpg->watch_fd); + inotify_rm_watch(inotify_fd, tpg->np_watch_fd); + free(tpg); + } + isns_target_register_later(tgt); log_print(LOG_DEBUG, "inotify[%c] %s/tpg%hu/%s", - inotify_event_str(event), tgt->name, tpg->tag, event->name); + inotify_event_str(event), tgt->name, tpg_tag, event->name); } void configfs_inotify_events_handle(void) @@ -587,16 +635,10 @@ bool tpg_has_portal(const struct tpg *tpg, const struct portal *portal) { - struct tpg_portal *tpg_portal; - - list_for_each(&tpg_portals, tpg_portal, node) { - if (configfs_tpg_portal_find(tpg, portal)) - return true; - } - return false; + return configfs_portal_ref_find(tpg, portal) != NULL; } -bool tgt_has_portal(const struct target *target, const struct portal *portal) +bool target_has_portal(const struct target *target, const struct portal *portal) { struct tpg *tpg; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/target-isns-0.6.4/src/configfs.h new/target-isns-0.6.5/src/configfs.h --- old/target-isns-0.6.4/src/configfs.h 2018-01-20 21:23:46.000000000 +0100 +++ new/target-isns-0.6.5/src/configfs.h 2018-06-20 08:26:56.000000000 +0200 @@ -19,15 +19,17 @@ char name[ISCSI_NAME_SIZE]; struct list_head tpgs; bool exists; + bool registered; bool registration_pending; int watch_fd; }; struct tpg { - struct list_node node; /* Member of a target->tpg list */ + struct list_node node; /* Member of a target->tpgs list */ uint16_t tag; bool enabled; bool exists; + struct list_head portals; int watch_fd; int np_watch_fd; }; @@ -37,7 +39,12 @@ int af; char ip_addr[INET6_ADDRSTRLEN]; uint16_t port; - bool registered; +}; + +struct portal_ref { + struct list_node node; /* Member of the tpg->portals list */ + struct portal *portal; + bool exists; }; #define ALL_TARGETS ((struct target*) 1) @@ -59,4 +66,4 @@ bool tpg_has_portal(const struct tpg *tpg, const struct portal *portal); -bool tgt_has_portal(const struct target *target, const struct portal *portal); +bool target_has_portal(const struct target *target, const struct portal *portal); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/target-isns-0.6.4/src/isns.c new/target-isns-0.6.5/src/isns.c --- old/target-isns-0.6.4/src/isns.c 2018-01-20 21:23:46.000000000 +0100 +++ new/target-isns-0.6.5/src/isns.c 2018-06-20 08:26:56.000000000 +0200 @@ -441,45 +441,28 @@ inet_pton(AF_INET6, portal->ip_addr, ip_addr); } -static void isns_ip_addr_get(const uint8_t *ip_addr, int *af, char *ip_str) +static void isns_target_set_registered(const char *iscsi_name) { - size_t start; - - start = 12; - *af = AF_INET; - for (size_t i = 0; i < 12; i++) { - if ((i < 10 && ip_addr[i] != 0x00) || - (i >= 10 && ip_addr[i] != 0xFF)) { - start = 0; - *af = AF_INET6; - break; - } - } - inet_ntop(*af, &ip_addr[start], ip_str, INET6_ADDRSTRLEN); + struct target *target = target_find(iscsi_name); + if (target) + target->registered = true; } -static void isns_portals_set_registered(uint8_t *ip_addr, uint32_t port) +static bool portal_is_solely_used(const struct portal *portal, + const struct target *target) { - int af; - char ip_str[INET6_ADDRSTRLEN]; - struct portal *portal; + struct target *tgt; + + assert(target_has_portal(target, portal)); - isns_ip_addr_get(ip_addr, &af, ip_str); - portal = portal_find(af, ip_str, port); - if (portal) - portal->registered = true; - - /* - * If the IP address is the local IP address, also mark the - * default portal as registered. - */ - if (memcmp(ip_addr, ip, 16) == 0) { - strncpy(ip_str, af == AF_INET ? "0.0.0.0" : "::", INET6_ADDRSTRLEN); - ip_str[INET6_ADDRSTRLEN - 1] = '\0'; - portal = portal_find(af, ip_str, port); - if (portal) - portal->registered = true; + list_for_each(&targets, tgt, node) { + if (tgt == target) + continue; + if (tgt->registered && target_has_portal(tgt, portal)) + return false; } + + return true; } #define TGT_REG_BUFSIZE 8192 @@ -547,6 +530,9 @@ bool all_targets = target == ALL_TARGETS; struct isns_query *query; + if (!all_targets && target->registered) + flags |= ISNS_FLAG_REPLACE; + if (all_targets) { if (list_empty(&targets)) return 0; @@ -579,10 +565,18 @@ /* Register the portals. */ list_for_each(&portals, portal, node) { - if (!tgt_has_portal(target, portal) && !all_targets) + if (!target_has_portal(target, portal) && !all_targets) continue; - if (portal->registered) + /* + * The Microsoft iSNS server returns an "invalid + * update" error if "an object specified in a + * DevAttrReg request to update an Entity already + * exists in another Entity". + * + * https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653564(v=vs.85)#invalid-update-status-code-14 + */ + if (!portal_is_solely_used(portal, target)) continue; uint32_t port = htonl(portal->port); @@ -610,7 +604,8 @@ /* Register the TPGs. */ list_for_each(&tgt->tpgs, tpg, node) { - uint32_t tag = htonl(tpg->tag); + if (list_empty(&tpg->portals)) + continue; length += isns_tlv_set_string(&tlv, ISNS_ATTR_PG_ISCSI_NAME, tgt->name); @@ -635,6 +630,7 @@ sizeof(buf), &length, &flags, &sequence); } + uint32_t tag = htonl(tpg->tag); length += isns_tlv_set(&tlv, ISNS_ATTR_PG_TAG, sizeof(tag), &tag); isns_target_register_flush(&tlv, &buf[0], sizeof(buf), @@ -872,9 +868,8 @@ uint16_t transaction = ntohs(hdr->transaction); uint32_t status; struct isns_query *query; - char *name = NULL; + char *iscsi_name = NULL; uint8_t ip_addr[16]; - uint32_t port; uint32_t period; /* Only pop the query from the list if the last PDU is received. */ @@ -933,38 +928,40 @@ case ISNS_ATTR_ENTITY_IDENTIFIER: break; case ISNS_ATTR_REGISTRATION_PERIOD: + if (vlen != 4) + break; period = ntohl(*(tlv->value)); isns_registration_set_period(period); break; case ISNS_ATTR_ISCSI_NAME: - if (vlen) { - size_t slen = vlen - 1; - - if (slen >= ISCSI_NAME_SIZE) - slen = ISCSI_NAME_SIZE - 1; - - *((char *) tlv->value + slen) = 0; - - name = (char *) tlv->value; - } else - name = NULL; + if (vlen == 0) { + iscsi_name = NULL; + break; + } + size_t slen = vlen - 1; + if (slen >= ISCSI_NAME_SIZE) + slen = ISCSI_NAME_SIZE - 1; + *((char *) tlv->value + slen) = '\0'; + iscsi_name = (char *) tlv->value; + isns_target_set_registered(iscsi_name); break; case ISNS_ATTR_ISCSI_NODE_TYPE: - if (vlen == 4 && name) { - uint32_t node_type = ntohl(*(tlv->value)); - switch (node_type) { - case ISNS_NODE_CONTROL: - log_print(LOG_DEBUG, "%s is a control node", name); - break; - case ISNS_NODE_INITIATOR: - log_print(LOG_DEBUG, "%s is an initiator", name); - break; - case ISNS_NODE_TARGET: - log_print(LOG_DEBUG, "%s is a target", name); - break; - } - } else - name = NULL; + if (vlen != 4) + break; + if (!iscsi_name) + break; + uint32_t node_type = ntohl(*(tlv->value)); + switch (node_type) { + case ISNS_NODE_CONTROL: + log_print(LOG_DEBUG, "%s is a control node", iscsi_name); + break; + case ISNS_NODE_INITIATOR: + log_print(LOG_DEBUG, "%s is an initiator", iscsi_name); + break; + case ISNS_NODE_TARGET: + log_print(LOG_DEBUG, "%s is a target", iscsi_name); + break; + } break; case ISNS_ATTR_PORTAL_IP_ADDRESS: if (vlen == 16) @@ -973,13 +970,11 @@ memset(ip_addr, 0, 16); break; case ISNS_ATTR_PORTAL_PORT: - if (vlen == 4) { - port = ntohl(*(tlv->value)); - isns_portals_set_registered(ip_addr, port); - } + if (vlen != 4) + break; break; default: - name = NULL; + iscsi_name = NULL; break; }