Control: tags -1 + patch
>From 0ae9d69941b34728c23a1b844fe3006ed7f7cd88 Mon Sep 17 00:00:00 2001
From: Hendrik Brueckner <brueck...@linux.vnet.ibm.com>
Date: Thu, 30 Jun 2016 12:45:19 +0200
Subject: [PATCH] zfcp-config: remove maximum number of FCP devices

Previously, the number of FCP devices was limited to 100 for selection.
In environments with numerous FCP devices, the installer could be limited
with cio_ignore to make the required FCP devices available only.

In case an installation requires more than 100 FCP devices, the
implementation is adjusted to allocate memory to contain the list
of all detected FCP devices.  The limiting factor will then become
the memory available in the installer environment.

Note that a similar change has been also added to the s390-dasd and
s390-netdevice installer modules.

Signed-off-by: Hendrik Brueckner <brueck...@linux.vnet.ibm.com>
Reviewed-by: Benjamin Block <bbl...@linux.vnet.ibm.com>
---
 debian/changelog |  7 +++++++
 zfcp-config.c    | 53 +++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 85ea1a3..fe612fa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+s390-zfcp (1.0.4) UNRELEASED; urgency=medium
+
+  * Improve displaying numereous detected FCP devices by replacing the
+    hard-coded limit with a dynamically allocated solution (Closes: #829562)
+
+ -- Hendrik Brueckner <brueck...@linux.vnet.ibm.com>  Thu, 30 Jun 2016 
11:39:49 +0200
+
 s390-zfcp (1.0.3) unstable; urgency=medium
 
   * Drop useless debian/po directory. Closes: #817206, #821173
diff --git a/zfcp-config.c b/zfcp-config.c
index bed4a32..c0129dc 100644
--- a/zfcp-config.c
+++ b/zfcp-config.c
@@ -36,10 +36,18 @@
 #define PRESEED_DELIM  ","
 #define SCSI_ASYNC_TRIES       15
 #define SCSI_ASYNC_TIMEOUT     250000    /* useconds */
-#define MAX_HOST_LIST_ITEMS    100
-#define MAX_HOST_LIST_SIZE     (MAX_HOST_LIST_ITEMS * (9 + 20 +1))
+#define ZFCP_ENTRY_SIZE                (9 + 20 + 1)
 #define MAX_LUN_LIST_SIZE      2048
 
+/* Memory buffer descriptor for an arbitrary number of
+ * detected FCP devices and their device information.
+ */
+struct dev_list
+{
+       char    *buf;
+       size_t  size;
+};
+
 /* Definition of a zFCP host adapter */
 struct zfcp_host {
        struct ccw_devid devid;       /* CCW device ID */
@@ -342,16 +350,16 @@ static cmdstatus_t debconf_show_error(struct 
debconfclient *client,
 static void build_zfcp_host_list(void *key __unused, void *value, void *data)
 {
        struct zfcp_host *host = value;
-       char *buf = data;
+       struct dev_list *devlist = data;
 
-       if (buf[0])
-               strncat(buf, ",", MAX_HOST_LIST_SIZE);
-       strncat(buf, host->name, MAX_HOST_LIST_SIZE);
+       if (devlist->buf[0])
+               di_snprintfcat (devlist->buf, devlist->size, ", ");
+       di_snprintfcat(devlist->buf, devlist->size, host->name);
 
        if (host->configured)
-               strncat(buf, " (configured)", MAX_HOST_LIST_SIZE);
+               di_snprintfcat (devlist->buf, devlist->size, " (configured)");
        else if (host->online)
-               strncat(buf, " (not configured)", MAX_HOST_LIST_SIZE);
+               di_snprintfcat (devlist->buf, devlist->size, " (not 
configured)");
 }
 
 static void preseed_select_one(void *key, void *value, void *data)
@@ -413,18 +421,33 @@ static enum state_wanted select_zfcp_host(struct 
debconfclient *client,
                                          struct zfcp_host **zfcp_host)
 {
        cmdstatus_t rc;
-       char hostlist[MAX_HOST_LIST_SIZE], *val, *delim;
+       char *val, *delim;
        struct ccw_devid devid;
+       struct dev_list hostlist;
 
-       memset(&hostlist, 0, sizeof(hostlist));
-       di_tree_foreach(zfcp_hosts, build_zfcp_host_list, hostlist);
+       /*
+        * Allocate memory to store the detected FCP devices along
+        * with their state information.
+        */
+       hostlist.size = ZFCP_ENTRY_SIZE * di_tree_size (zfcp_hosts);
+       hostlist.buf = di_malloc0 (hostlist.size);
+       if (hostlist.buf == NULL)
+       {
+               di_warning("Could not allocate memory for FCP device list\n");
+               return WANT_ERROR;
+       }
+       di_tree_foreach(zfcp_hosts, build_zfcp_host_list, &hostlist);
 
-       debconf_subst(client, TEMPLATE_PREFIX "select_zfcp_host", "choices", 
hostlist);
+       debconf_subst(client, TEMPLATE_PREFIX "select_zfcp_host", "choices", 
hostlist.buf);
        rc = debconf_result(client, "critical", TEMPLATE_PREFIX 
"select_zfcp_host", &val);
-       if (rc == CMD_GOBACK)
+       if (rc == CMD_GOBACK) {
+               di_free (hostlist.buf);
                return WANT_BACKUP;
-       if (!strcmp("Finish", val))
+       }
+       if (!strcmp("Finish", val)) {
+               di_free (hostlist.buf);
                return WANT_FINISH;
+       }
 
        /* Remove the trailing "configured" information */
        delim = strchr(val, ' ');
@@ -435,9 +458,11 @@ static enum state_wanted select_zfcp_host(struct 
debconfclient *client,
        *zfcp_host = di_tree_lookup(zfcp_hosts, &devid);
        if (*zfcp_host == NULL) {
                di_debug("Could not find FCP device for devid: %s\n", val);
+               di_free (hostlist.buf);
                return WANT_ERROR;
        }
        di_debug("SELECT: Using FCP device %s\n", val);
+       di_free (hostlist.buf);
 
        return WANT_NEXT;
 }
-- 
1.8.3.1

Reply via email to