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;
                }
 


Reply via email to