Diff for /embedaddon/istgt/src/istgt.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 16:42:02 version 1.1.1.2, 2012/10/09 09:13:23
Line 1 Line 1
 /*  /*
 * Copyright (C) 2008-2011 Daisuke Aoyama <aoyama@peach.ne.jp>. * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 67 Line 67
 #include <sys/time.h>  #include <sys/time.h>
 #endif  #endif
   
#define POLLWAIT 3000#if !defined(__GNUC__)
 #undef __attribute__
 #define __attribute__(x)
 #endif
 
 #define POLLWAIT 5000
 #define PORTNUMLEN 32  #define PORTNUMLEN 32
   
 ISTGT g_istgt;  ISTGT g_istgt;
   
 #if 0  
 void  
 fatal(const char *msg, ...)  
 {  
         va_list ap;  
         va_start(ap, msg);  
         vfprintf(stderr, msg, ap);  
         va_end(ap);  
         exit(EXIT_FAILURE);  
 }  
 #endif  
   
 static int  static int
 istgt_parse_portal(const char *portal, char **host, char **port)  istgt_parse_portal(const char *portal, char **host, char **port)
 {  {
Line 102  istgt_parse_portal(const char *portal, char **host, ch Line 95  istgt_parse_portal(const char *portal, char **host, ch
                         ISTGT_ERRLOG("portal error\n");                          ISTGT_ERRLOG("portal error\n");
                         return -1;                          return -1;
                 }                  }
 #if 0  
                 n = p - (portal + 1);  
                 *host = xmalloc(n + 1);  
                 memcpy(*host, portal + 1, n);  
                 (*host)[n] = '\0';  
                 p++;                  p++;
 #else  
                 p++;  
                 n = p - portal;                  n = p - portal;
                *host = xmalloc(n + 1);                if (host != NULL) {
                memcpy(*host, portal, n);                        *host = xmalloc(n + 1);
                (*host)[n] = '\0';                        memcpy(*host, portal, n);
#endif                        (*host)[n] = '\0';
                 }
                 if (p[0] == '\0') {                  if (p[0] == '\0') {
                        *port = xmalloc(PORTNUMLEN);                        if (port != NULL) {
                        snprintf(*port, PORTNUMLEN, "%d", DEFAULT_PORT);                                *port = xmalloc(PORTNUMLEN);
                                 snprintf(*port, PORTNUMLEN, "%d", DEFAULT_PORT);
                         }
                 } else {                  } else {
                         if (p[0] != ':') {                          if (p[0] != ':') {
                                 ISTGT_ERRLOG("portal error\n");                                  ISTGT_ERRLOG("portal error\n");
                                xfree(*host);                                if (host != NULL)
                                         xfree(*host);
                                 return -1;                                  return -1;
                         }                          }
                        *port = xstrdup(p + 1);                        if (port != NULL)
                                 *port = xstrdup(p + 1);
                 }                  }
         } else {          } else {
                 /* IPv4 */                  /* IPv4 */
Line 133  istgt_parse_portal(const char *portal, char **host, ch Line 124  istgt_parse_portal(const char *portal, char **host, ch
                         p = portal + strlen(portal);                          p = portal + strlen(portal);
                 }                  }
                 n = p - portal;                  n = p - portal;
                *host = xmalloc(n + 1);                if (host != NULL) {
                memcpy(*host, portal, n);                        *host = xmalloc(n + 1);
                (*host)[n] = '\0';                        memcpy(*host, portal, n);
                         (*host)[n] = '\0';
                 }
                 if (p[0] == '\0') {                  if (p[0] == '\0') {
                        *port = xmalloc(PORTNUMLEN);                        if (port != NULL) {
                        snprintf(*port, PORTNUMLEN, "%d", DEFAULT_PORT);                                *port = xmalloc(PORTNUMLEN);
                                 snprintf(*port, PORTNUMLEN, "%d", DEFAULT_PORT);
                         }
                 } else {                  } else {
                         if (p[0] != ':') {                          if (p[0] != ':') {
                                 ISTGT_ERRLOG("portal error\n");                                  ISTGT_ERRLOG("portal error\n");
                                xfree(*host);                                if (host != NULL)
                                         xfree(*host);
                                 return -1;                                  return -1;
                         }                          }
                        *port = xstrdup(p + 1);                        if (port != NULL)
                                 *port = xstrdup(p + 1);
                 }                  }
         }          }
         return 0;          return 0;
 }  }
   
 static int  static int
istgt_add_portal(ISTGT_Ptr istgt, CF_SECTION *sp, int idx1)istgt_add_portal_group(ISTGT_Ptr istgt, CF_SECTION *sp, int *pgp_idx)
 {  {
           const char *val;
         char *label, *portal, *host, *port;          char *label, *portal, *host, *port;
        int idx;        int alloc_len;
         int idx, free_idx;
         int portals;
         int rc;          int rc;
           int i;
   
        label = istgt_get_nmval(sp, "Portal", idx1, 0);        ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "add portal group %d\n", sp->num);
        portal = istgt_get_nmval(sp, "Portal", idx1, 1);
        if (label == NULL || portal == NULL) {        val = istgt_get_val(sp, "Comment");
                ISTGT_ERRLOG("portal error\n");        if (val != NULL) {
                return -1;                ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
         }          }
   
        rc = istgt_parse_portal(portal, &host, &port);        /* counts number of definition */
        if (rc < 0) {        for (i = 0; ; i++) {
                ISTGT_ERRLOG("parse portal error\n");                label = istgt_get_nmval(sp, "Portal", i, 0);
                 portal = istgt_get_nmval(sp, "Portal", i, 1);
                 if (label == NULL || portal == NULL)
                         break;
                 rc = istgt_parse_portal(portal, NULL, NULL);
                 if (rc < 0) {
                         ISTGT_ERRLOG("parse portal error (%s)\n", portal);
                         return -1;
                 }
         }
         portals = i;
         if (portals > MAX_PORTAL) {
                 ISTGT_ERRLOG("%d > MAX_PORTAL\n", portals);
                 return -1;                  return -1;
         }          }
   
        idx = istgt->nportal;        MTX_LOCK(&istgt->mutex);
         idx = istgt->nportal_group;
         free_idx = -1;
         for (i = 0; i < istgt->nportal_group; i++) {
                 if (istgt->portal_group[i].tag != 0)
                         continue;
                 if (istgt->portal_group[i].nportals == portals) {
                         free_idx = i;
                         break;
                 }
         }
         if (free_idx >= 0)
                 idx = free_idx;
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
            "Index=%d, Host=%s, Port=%s, Tag=%d\n",            "Index=%d, Tag=%d, Portals=%d\n",
            idx, host, port, sp->num);            idx, sp->num, portals);
        if (idx < MAX_PORTAL) {        if (idx < MAX_PORTAL_GROUP) {
                istgt->portal[idx].label = xstrdup(label);                if (free_idx < 0) {
                istgt->portal[idx].host = host;                        istgt->portal_group[idx].nportals = portals;
                istgt->portal[idx].port = port;                        alloc_len = sizeof (PORTAL *) * portals;
                istgt->portal[idx].idx = idx;                        istgt->portal_group[idx].portals = xmalloc(alloc_len);
                istgt->portal[idx].tag = sp->num;                }
                istgt->portal[idx].sock = -1;                istgt->portal_group[idx].ref = 0;
                idx++;                istgt->portal_group[idx].idx = idx;
                istgt->nportal = idx;                istgt->portal_group[idx].tag = sp->num;
 
                 for (i = 0; i < portals; i++) {
                         label = istgt_get_nmval(sp, "Portal", i, 0);
                         portal = istgt_get_nmval(sp, "Portal", i, 1);
                         if (label == NULL || portal == NULL) {
                                 if (free_idx < 0) {
                                         xfree(istgt->portal_group[idx].portals);
                                         istgt->portal_group[idx].nportals = 0;
                                 }
                                 istgt->portal_group[idx].tag = 0;
                                 MTX_UNLOCK(&istgt->mutex);
                                 ISTGT_ERRLOG("portal error\n");
                                 return -1;
                         }
                         rc = istgt_parse_portal(portal, &host, &port);
                         if (rc < 0) {
                                 if (free_idx < 0) {
                                         xfree(istgt->portal_group[idx].portals);
                                         istgt->portal_group[idx].nportals = 0;
                                 }
                                 istgt->portal_group[idx].tag = 0;
                                 MTX_UNLOCK(&istgt->mutex);
                                 ISTGT_ERRLOG("parse portal error (%s)\n", portal);
                                 return -1;
                         }
                         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                             "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
                             i, host, port, sp->num);
 
                         if (free_idx < 0) {
                                 istgt->portal_group[idx].portals[i] = xmalloc(sizeof (PORTAL));
                         } else {
                                 xfree(istgt->portal_group[idx].portals[i]->label);
                                 xfree(istgt->portal_group[idx].portals[i]->host);
                                 xfree(istgt->portal_group[idx].portals[i]->port);
                         }
                         istgt->portal_group[idx].portals[i]->label = xstrdup(label);
                         istgt->portal_group[idx].portals[i]->host = host;
                         istgt->portal_group[idx].portals[i]->port = port;
                         istgt->portal_group[idx].portals[i]->ref = 0;
                         istgt->portal_group[idx].portals[i]->idx = i;
                         istgt->portal_group[idx].portals[i]->tag = sp->num;
                         istgt->portal_group[idx].portals[i]->sock = -1;
                 }
 
                 if (pgp_idx != NULL)
                         *pgp_idx = idx;
                 if (free_idx < 0) {
                         idx++;
                         istgt->nportal_group = idx;
                 }
         } else {          } else {
                ISTGT_ERRLOG("nportal(%d) >= MAX_PORTAL\n", idx);                MTX_UNLOCK(&istgt->mutex);
                xfree(host);                ISTGT_ERRLOG("nportal_group(%d) >= MAX_PORTAL_GROUP\n", idx);
                xfree(port); 
                 return -1;                  return -1;
         }          }
           MTX_UNLOCK(&istgt->mutex);
         return 0;          return 0;
 }  }
   
 static int  static int
istgt_build_portal_array(ISTGT_Ptr istgt)istgt_pg_match_all(PORTAL_GROUP *pgp, CF_SECTION *sp)
 {  {
        CF_SECTION *sp;        char *label, *portal, *host, *port;
         int rc;
         int i;
 
         for (i = 0; i < pgp->nportals; i++) {
                 label = istgt_get_nmval(sp, "Portal", i, 0);
                 portal = istgt_get_nmval(sp, "Portal", i, 1);
                 if (label == NULL || portal == NULL)
                         return 0;
                 rc = istgt_parse_portal(portal, &host, &port);
                 if (rc < 0)
                         return 0;
                 if (strcmp(pgp->portals[i]->label, label) != 0)
                         return 0;
                 if (strcmp(pgp->portals[i]->host, host) != 0)
                         return 0;
                 if (strcmp(pgp->portals[i]->port, port) != 0)
                         return 0;
         }
         label = istgt_get_nmval(sp, "Portal", i, 0);
         portal = istgt_get_nmval(sp, "Portal", i, 1);
         if (label != NULL || portal != NULL)
                 return 0;
         return 1;
 }
 
 static int
 istgt_update_portal_group(ISTGT_Ptr istgt, CF_SECTION *sp, int *pgp_idx)
 {
         const char *val;          const char *val;
           char *label, *portal, *host, *port;
           int alloc_len;
           int idx, free_idx;
           int portals;
         int rc;          int rc;
         int i;          int i;
   
        sp = istgt->config->section;        ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "update portal group %d\n", sp->num);
        while (sp != NULL) {
                if (sp->type == ST_PORTALGROUP) {        val = istgt_get_val(sp, "Comment");
                        if (sp->num == 0) {        if (val != NULL) {
                                ISTGT_ERRLOG("Group 0 is invalid\n");                ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
         }
 
         /* counts number of definition */
         for (i = 0; ; i++) {
                 label = istgt_get_nmval(sp, "Portal", i, 0);
                 portal = istgt_get_nmval(sp, "Portal", i, 1);
                 if (label == NULL || portal == NULL)
                         break;
                 rc = istgt_parse_portal(portal, NULL, NULL);
                 if (rc < 0) {
                         ISTGT_ERRLOG("parse portal error (%s)\n", portal);
                         return -1;
                 }
         }
         portals = i;
         if (portals > MAX_PORTAL) {
                 ISTGT_ERRLOG("%d > MAX_PORTAL\n", portals);
                 return -1;
         }
 
         MTX_LOCK(&istgt->mutex);
         idx = -1;
         for (i = 0; i < istgt->nportal_group; i++) {
                 if (istgt->portal_group[i].tag == sp->num) {
                         idx = i;
                         break;
                 }
         }
         if (idx < 0) {
                 MTX_UNLOCK(&istgt->mutex);
                 ISTGT_ERRLOG("can't find PG%d\n", sp->num);
                 return -1;
         }
         if (istgt_pg_match_all(&istgt->portal_group[i], sp)) {
                 MTX_UNLOCK(&istgt->mutex);
                 ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "skip for PG%d\n", sp->num);
                 return 0;
         }
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
             "Index=%d, Tag=%d, Portals=%d\n",
             idx, sp->num, portals);
         if (istgt->portal_group[idx].nportals == portals) {
                 /* udpate PG */
                 for (i = 0; i < portals; i++) {
                         label = istgt_get_nmval(sp, "Portal", i, 0);
                         portal = istgt_get_nmval(sp, "Portal", i, 1);
                         if (label == NULL || portal == NULL) {
                                 xfree(istgt->portal_group[idx].portals);
                                 istgt->portal_group[idx].nportals = 0;
                                 istgt->portal_group[idx].tag = 0;
                                 MTX_UNLOCK(&istgt->mutex);
                                 ISTGT_ERRLOG("portal error\n");
                                 return -1;                                  return -1;
                         }                          }
                        if (sp->num > ISTGT_PG_TAG_MAX) {                        rc = istgt_parse_portal(portal, &host, &port);
                                ISTGT_ERRLOG("tag %d is invalid\n", sp->num);                        if (rc < 0) {
                                 xfree(istgt->portal_group[idx].portals);
                                 istgt->portal_group[idx].nportals = 0;
                                 istgt->portal_group[idx].tag = 0;
                                 MTX_UNLOCK(&istgt->mutex);
                                 ISTGT_ERRLOG("parse portal error (%s)\n", portal);
                                 return -1;                                  return -1;
                         }                          }
                           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                               "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
                               i, host, port, sp->num);
   
                        val = istgt_get_val(sp, "Comment");                        /* free old PG */
                        if (val != NULL) {                        xfree(istgt->portal_group[idx].portals[i]->label);
                                ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,                        xfree(istgt->portal_group[idx].portals[i]->host);
                                    "Comment %s\n", val);                        xfree(istgt->portal_group[idx].portals[i]->port);
 
                         /* allocate new PG */
                         istgt->portal_group[idx].portals[i]->label = xstrdup(label);
                         istgt->portal_group[idx].portals[i]->host = host;
                         istgt->portal_group[idx].portals[i]->port = port;
                         //istgt->portal_group[idx].portals[i]->ref = 0;
                         //istgt->portal_group[idx].portals[i]->idx = i;
                         //istgt->portal_group[idx].portals[i]->tag = sp->num;
                         //istgt->portal_group[idx].portals[i]->sock = -1;
                 }
                 if (pgp_idx != NULL)
                         *pgp_idx = idx;
         } else {
                 /* mark as free */
                 istgt->portal_group[*pgp_idx].tag = 0;
 
                 /* allocate new PG */
                 idx = istgt->nportal_group;
                 free_idx = -1;
                 for (i = 0; i < istgt->nportal_group; i++) {
                         if (istgt->portal_group[i].tag != 0)
                                 continue;
                         if (istgt->portal_group[i].nportals == portals) {
                                 free_idx = i;
                                 break;
                         }                          }
                        for (i = 0; ; i++) {                }
                                val = istgt_get_nval(sp, "Portal", i);                if (free_idx >= 0)
                                if (val == NULL)                        idx = free_idx;
                                        break;                ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                                rc = istgt_add_portal(istgt, sp, i);                    "Index=%d, Tag=%d, Portals=%d -> %d\n",
                     idx, sp->num, istgt->portal_group[*pgp_idx].nportals, portals);
                 if (idx < MAX_PORTAL_GROUP) {
                         if (free_idx < 0) {
                                 istgt->portal_group[idx].nportals = portals;
                                 alloc_len = sizeof (PORTAL *) * portals;
                                 istgt->portal_group[idx].portals = xmalloc(alloc_len);
                         }
                         istgt->portal_group[idx].ref = istgt->portal_group[*pgp_idx].ref;
                         istgt->portal_group[idx].idx = idx;
                         istgt->portal_group[idx].tag = sp->num;
 
                         for (i = 0; i < portals; i++) {
                                 label = istgt_get_nmval(sp, "Portal", i, 0);
                                 portal = istgt_get_nmval(sp, "Portal", i, 1);
                                 if (label == NULL || portal == NULL) {
                                         if (free_idx < 0) {
                                                 xfree(istgt->portal_group[idx].portals);
                                                 istgt->portal_group[idx].nportals = 0;
                                         }
                                         istgt->portal_group[idx].tag = 0;
                                         MTX_UNLOCK(&istgt->mutex);
                                         ISTGT_ERRLOG("portal error\n");
                                         return -1;
                                 }
                                 rc = istgt_parse_portal(portal, &host, &port);
                                 if (rc < 0) {                                  if (rc < 0) {
                                        ISTGT_ERRLOG("add_portal() failed\n");                                        if (free_idx < 0) {
                                                 xfree(istgt->portal_group[idx].portals);
                                                 istgt->portal_group[idx].nportals = 0;
                                         }
                                         istgt->portal_group[idx].tag = 0;
                                         MTX_UNLOCK(&istgt->mutex);
                                         ISTGT_ERRLOG("parse portal error (%s)\n", portal);
                                         return -1;                                          return -1;
                                 }                                  }
                                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                                       "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
                                       i, host, port, sp->num);
   
                                   if (free_idx < 0) {
                                           istgt->portal_group[idx].portals[i] = xmalloc(sizeof (PORTAL));
                                   } else {
                                           xfree(istgt->portal_group[idx].portals[i]->label);
                                           xfree(istgt->portal_group[idx].portals[i]->host);
                                           xfree(istgt->portal_group[idx].portals[i]->port);
                                   }
                                   istgt->portal_group[idx].portals[i]->label = xstrdup(label);
                                   istgt->portal_group[idx].portals[i]->host = host;
                                   istgt->portal_group[idx].portals[i]->port = port;
                                   istgt->portal_group[idx].portals[i]->ref = 0;
                                   istgt->portal_group[idx].portals[i]->idx = i;
                                   istgt->portal_group[idx].portals[i]->tag = sp->num;
                                   istgt->portal_group[idx].portals[i]->sock = -1;
                         }                          }
   
                           if (pgp_idx != NULL)
                                   *pgp_idx = idx;
                           if (free_idx < 0) {
                                   idx++;
                                   istgt->nportal_group = idx;
                           }
                   } else {
                           MTX_UNLOCK(&istgt->mutex);
                           ISTGT_ERRLOG("nportal_group(%d) >= MAX_PORTAL_GROUP\n", idx);
                           return -1;
                 }                  }
           }
           MTX_UNLOCK(&istgt->mutex);
           return 1;
   }
   
   static int
   istgt_build_portal_group_array(ISTGT_Ptr istgt)
   {
           CF_SECTION *sp;
           int rc;
   
           sp = istgt->config->section;
           while (sp != NULL) {
                   if (sp->type == ST_PORTALGROUP) {
                           if (sp->num == 0) {
                                   ISTGT_ERRLOG("Group 0 is invalid\n");
                                   return -1;
                           }
                           rc = istgt_add_portal_group(istgt, sp, NULL);
                           if (rc < 0) {
                                   ISTGT_ERRLOG("add_portal_group() failed\n");
                                   return -1;
                           }
                   }
                 sp = sp->next;                  sp = sp->next;
         }          }
         return 0;          return 0;
 }  }
   
 static void  static void
istgt_destroy_portal_array(ISTGT_Ptr istgt)istgt_destroy_portal_group_array(ISTGT_Ptr istgt)
 {  {
        int i;        int i, j;
   
        ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destroy_portal_array\n");        ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destory_portal_group_array\n");
        for (i = 0; i < istgt->nportal; i++) {        MTX_LOCK(&istgt->mutex);
                xfree(istgt->portal[i].label);        for (i = 0; i < istgt->nportal_group; i++) {
                xfree(istgt->portal[i].host);                for (j = 0; j < istgt->portal_group[i].nportals; j++) {
                xfree(istgt->portal[i].port);                        xfree(istgt->portal_group[i].portals[j]->label);
                         xfree(istgt->portal_group[i].portals[j]->host);
                         xfree(istgt->portal_group[i].portals[j]->port);
                         xfree(istgt->portal_group[i].portals[j]);
                 }
                 xfree(istgt->portal_group[i].portals);
   
                istgt->portal[i].label = NULL;                istgt->portal_group[i].nportals = 0;
                istgt->portal[i].host = NULL;                istgt->portal_group[i].portals = NULL;
                istgt->portal[i].port = NULL;                istgt->portal_group[i].ref = 0;
                istgt->portal[i].idx = i;                istgt->portal_group[i].idx = i;
                istgt->portal[i].tag = 0;                istgt->portal_group[i].tag = 0;
         }          }
        istgt->nportal = 0;        istgt->nportal_group = 0;
         MTX_UNLOCK(&istgt->mutex);
 }  }
   
 static int  static int
istgt_open_portal(ISTGT_Ptr istgt)istgt_open_portal_group(PORTAL_GROUP *pgp)
 {  {
         int port;          int port;
         int sock;          int sock;
         int i;          int i;
   
        ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_open_portal\n");        for (i = 0; i < pgp->nportals; i++) {
        for (i = 0; i < istgt->nportal; i++) {                if (pgp->portals[i]->sock < 0) {
                if (istgt->portal[i].sock < 0) {                        ISTGT_TRACELOG(ISTGT_TRACE_NET, "open host %s, port %s, tag %d\n",
                        ISTGT_TRACELOG(ISTGT_TRACE_NET,                            pgp->portals[i]->host, pgp->portals[i]->port,
                            "open host %s, port %s, tag %d\n",                            pgp->portals[i]->tag);
                            istgt->portal[i].host, istgt->portal[i].port,                        port = (int)strtol(pgp->portals[i]->port, NULL, 0);
                            istgt->portal[i].tag);                        sock = istgt_listen(pgp->portals[i]->host, port);
                        port = (int)strtol(istgt->portal[i].port, NULL, 0); 
                        sock = istgt_listen(istgt->portal[i].host, port); 
                         if (sock < 0) {                          if (sock < 0) {
                                 ISTGT_ERRLOG("listen error %.64s:%d\n",                                  ISTGT_ERRLOG("listen error %.64s:%d\n",
                                    istgt->portal[i].host, port);                                    pgp->portals[i]->host, port);
                                 return -1;                                  return -1;
                         }                          }
                        istgt->portal[i].sock = sock;                        pgp->portals[i]->sock = sock;
                 }                  }
         }          }
         return 0;          return 0;
 }  }
   
 static int  static int
istgt_close_portal(ISTGT_Ptr istgt)istgt_open_all_portals(ISTGT_Ptr istgt)
 {  {
           int rc;
         int i;          int i;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_open_portal\n");
           MTX_LOCK(&istgt->mutex);
           for (i = 0; i < istgt->nportal_group; i++) {
                   rc = istgt_open_portal_group(&istgt->portal_group[i]);
                   if (rc < 0) {
                           MTX_UNLOCK(&istgt->mutex);
                           return -1;
                   }
           }
           MTX_UNLOCK(&istgt->mutex);
           return 0;
   }
   
   static int
   istgt_close_portal_group(PORTAL_GROUP *pgp)
   {
           int i;
   
           for (i = 0; i < pgp->nportals; i++) {
                   if (pgp->portals[i]->sock >= 0) {
                           ISTGT_TRACELOG(ISTGT_TRACE_NET, "close host %s, port %s, tag %d\n",
                               pgp->portals[i]->host, pgp->portals[i]->port,
                               pgp->portals[i]->tag);
                           close(pgp->portals[i]->sock);
                           pgp->portals[i]->sock = -1;
                   }
           }
           return 0;
   }
   
   static int
   istgt_close_all_portals(ISTGT_Ptr istgt)
   {
           int rc;
           int i;
   
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_close_portal\n");          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_close_portal\n");
        for (i = 0; i < istgt->nportal; i++) {        MTX_LOCK(&istgt->mutex);
                if (istgt->portal[i].sock >= 0) {        for (i = 0; i < istgt->nportal_group; i++) {
                        ISTGT_TRACELOG(ISTGT_TRACE_NET,                rc = istgt_close_portal_group(&istgt->portal_group[i]);
                            "close host %s, port %s, tag %d\n",                if (rc < 0) {
                            istgt->portal[i].host, istgt->portal[i].port,                        MTX_UNLOCK(&istgt->mutex);
                            istgt->portal[i].tag);                        return -1;
                        close(istgt->portal[i].sock); 
                        istgt->portal[i].sock = -1; 
                 }                  }
         }          }
           MTX_UNLOCK(&istgt->mutex);
         return 0;          return 0;
 }  }
   
Line 339  istgt_add_initiator_group(ISTGT_Ptr istgt, CF_SECTION  Line 656  istgt_add_initiator_group(ISTGT_Ptr istgt, CF_SECTION 
                 return -1;                  return -1;
         }          }
   
           MTX_LOCK(&istgt->mutex);
         idx = istgt->ninitiator_group;          idx = istgt->ninitiator_group;
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
             "Index=%d, Tag=%d, Names=%d, Masks=%d\n",              "Index=%d, Tag=%d, Names=%d, Masks=%d\n",
Line 350  istgt_add_initiator_group(ISTGT_Ptr istgt, CF_SECTION  Line 668  istgt_add_initiator_group(ISTGT_Ptr istgt, CF_SECTION 
                 istgt->initiator_group[idx].nnetmasks = masks;                  istgt->initiator_group[idx].nnetmasks = masks;
                 alloc_len = sizeof (char *) * masks;                  alloc_len = sizeof (char *) * masks;
                 istgt->initiator_group[idx].netmasks = xmalloc(alloc_len);                  istgt->initiator_group[idx].netmasks = xmalloc(alloc_len);
                   istgt->initiator_group[idx].ref = 0;
                 istgt->initiator_group[idx].idx = idx;                  istgt->initiator_group[idx].idx = idx;
                 istgt->initiator_group[idx].tag = sp->num;                  istgt->initiator_group[idx].tag = sp->num;
   
Line 368  istgt_add_initiator_group(ISTGT_Ptr istgt, CF_SECTION  Line 687  istgt_add_initiator_group(ISTGT_Ptr istgt, CF_SECTION 
                 idx++;                  idx++;
                 istgt->ninitiator_group = idx;                  istgt->ninitiator_group = idx;
         } else {          } else {
                   MTX_UNLOCK(&istgt->mutex);
                 ISTGT_ERRLOG("ninitiator_group(%d) >= MAX_INITIATOR_GROUP\n", idx);                  ISTGT_ERRLOG("ninitiator_group(%d) >= MAX_INITIATOR_GROUP\n", idx);
                 return -1;                  return -1;
         }          }
           MTX_UNLOCK(&istgt->mutex);
         return 0;          return 0;
 }  }
   
 static int  static int
   istgt_ig_match_all(INITIATOR_GROUP *igp, CF_SECTION *sp)
   {
           const char *val;
           int i;
   
           for (i = 0; i < igp->ninitiators; i++) {
                   val = istgt_get_nval(sp, "InitiatorName", i);
                   if (val == NULL)
                           return 0;
                   if (strcmp(igp->initiators[i], val) != 0)
                           return 0;
           }
           val = istgt_get_nval(sp, "InitiatorName", i);
           if (val != NULL)
                   return 0;
           for (i = 0; i < igp->nnetmasks; i++) {
                   val = istgt_get_nval(sp, "Netmask", i);
                   if (val == NULL)
                           return 0;
                   if (strcmp(igp->netmasks[i], val) != 0)
                           return 0;
           }
           val = istgt_get_nval(sp, "Netmask", i);
           if (val != NULL)
                   return 0;
           return 1;
   }
   
   static int
   istgt_update_initiator_group(ISTGT_Ptr istgt, CF_SECTION *sp)
   {
           const char *val;
           int alloc_len;
           int idx;
           int names;
           int masks;
           int i;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "update initiator group %d\n", sp->num);
   
           val = istgt_get_val(sp, "Comment");
           if (val != NULL) {
                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
           }
   
           /* counts number of definition */
           for (i = 0; ; i++) {
                   val = istgt_get_nval(sp, "InitiatorName", i);
                   if (val == NULL)
                           break;
           }
           names = i;
           if (names > MAX_INITIATOR) {
                   ISTGT_ERRLOG("%d > MAX_INITIATOR\n", names);
                   return -1;
           }
           for (i = 0; ; i++) {
                   val = istgt_get_nval(sp, "Netmask", i);
                   if (val == NULL)
                           break;
           }
           masks = i;
           if (masks > MAX_NETMASK) {
                   ISTGT_ERRLOG("%d > MAX_NETMASK\n", masks);
                   return -1;
           }
   
           MTX_LOCK(&istgt->mutex);
           idx = -1;
           for (i = 0; i < istgt->ninitiator_group; i++) {
                   if (istgt->initiator_group[i].tag == sp->num) {
                           idx = i;
                           break;
                   }
           }
           if (idx < 0) {
                   MTX_UNLOCK(&istgt->mutex);
                   ISTGT_ERRLOG("can't find IG%d\n", sp->num);
                   return -1;
           }
           if (istgt_ig_match_all(&istgt->initiator_group[i], sp)) {
                   MTX_UNLOCK(&istgt->mutex);
                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "skip for IG%d\n", sp->num);
                   return 0;
           }
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
               "Index=%d, Tag=%d, Names=%d, Masks=%d\n",
               idx, sp->num, names, masks);
   
           /* free old IG */
           for (i = 0; i < istgt->initiator_group[idx].ninitiators; i++) {
                   xfree(istgt->initiator_group[idx].initiators[i]);
           }
           xfree(istgt->initiator_group[idx].initiators);
           for (i = 0; i < istgt->initiator_group[idx].nnetmasks; i++) {
                   xfree(istgt->initiator_group[idx].netmasks[i]);
           }
           xfree(istgt->initiator_group[idx].netmasks);
   
           /* allocate new IG */
           istgt->initiator_group[idx].ninitiators = names;
           alloc_len = sizeof (char *) * names;
           istgt->initiator_group[idx].initiators = xmalloc(alloc_len);
           istgt->initiator_group[idx].nnetmasks = masks;
           alloc_len = sizeof (char *) * masks;
           istgt->initiator_group[idx].netmasks = xmalloc(alloc_len);
           //istgt->initiator_group[idx].ref = 0;
           //istgt->initiator_group[idx].idx = idx;
           //istgt->initiator_group[idx].tag = sp->num;
   
           /* copy new strings */
           for (i = 0; i < names; i++) {
                   val = istgt_get_nval(sp, "InitiatorName", i);
                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                       "InitiatorName %s\n", val);
                   istgt->initiator_group[idx].initiators[i] = xstrdup(val);
           }
           for (i = 0; i < masks; i++) {
                   val = istgt_get_nval(sp, "Netmask", i);
                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Netmask %s\n", val);
                   istgt->initiator_group[idx].netmasks[i] = xstrdup(val);
           }
           MTX_UNLOCK(&istgt->mutex);
           return 1;
   }
   
   static int
 istgt_build_initiator_group_array(ISTGT_Ptr istgt)  istgt_build_initiator_group_array(ISTGT_Ptr istgt)
 {  {
         CF_SECTION *sp;          CF_SECTION *sp;
Line 404  istgt_destory_initiator_group_array(ISTGT_Ptr istgt) Line 852  istgt_destory_initiator_group_array(ISTGT_Ptr istgt)
         int i, j;          int i, j;
   
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destory_initiator_group_array\n");          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destory_initiator_group_array\n");
           MTX_LOCK(&istgt->mutex);
         for (i = 0; i < istgt->ninitiator_group; i++) {          for (i = 0; i < istgt->ninitiator_group; i++) {
                 for (j = 0; j < istgt->initiator_group[i].ninitiators; j++) {                  for (j = 0; j < istgt->initiator_group[i].ninitiators; j++) {
                         xfree(istgt->initiator_group[i].initiators[j]);                          xfree(istgt->initiator_group[i].initiators[j]);
Line 418  istgt_destory_initiator_group_array(ISTGT_Ptr istgt) Line 867  istgt_destory_initiator_group_array(ISTGT_Ptr istgt)
                 istgt->initiator_group[i].initiators = NULL;                  istgt->initiator_group[i].initiators = NULL;
                 istgt->initiator_group[i].nnetmasks = 0;                  istgt->initiator_group[i].nnetmasks = 0;
                 istgt->initiator_group[i].netmasks = NULL;                  istgt->initiator_group[i].netmasks = NULL;
                   istgt->initiator_group[i].ref = 0;
                 istgt->initiator_group[i].idx = i;                  istgt->initiator_group[i].idx = i;
                 istgt->initiator_group[i].tag = 0;                  istgt->initiator_group[i].tag = 0;
         }          }
         istgt->ninitiator_group = 0;          istgt->ninitiator_group = 0;
           MTX_UNLOCK(&istgt->mutex);
 }  }
   
 static int  static int
Line 470  istgt_build_uctl_portal(ISTGT_Ptr istgt) Line 921  istgt_build_uctl_portal(ISTGT_Ptr istgt)
                         istgt->uctl_portal[idx].label = xstrdup(label);                          istgt->uctl_portal[idx].label = xstrdup(label);
                         istgt->uctl_portal[idx].host = host;                          istgt->uctl_portal[idx].host = host;
                         istgt->uctl_portal[idx].port = port;                          istgt->uctl_portal[idx].port = port;
                           istgt->uctl_portal[idx].ref = 0;
                         istgt->uctl_portal[idx].idx = idx;                          istgt->uctl_portal[idx].idx = idx;
                         istgt->uctl_portal[idx].tag = tag;                          istgt->uctl_portal[idx].tag = tag;
                         istgt->uctl_portal[idx].sock = -1;                          istgt->uctl_portal[idx].sock = -1;
Line 492  istgt_destroy_uctl_portal(ISTGT_Ptr istgt) Line 944  istgt_destroy_uctl_portal(ISTGT_Ptr istgt)
         int i;          int i;
   
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destroy_uctl_portal\n");          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destroy_uctl_portal\n");
        for (i = 0; i < istgt->nportal; i++) {        for (i = 0; i < istgt->nuctl_portal; i++) {
                 xfree(istgt->uctl_portal[i].label);                  xfree(istgt->uctl_portal[i].label);
                 xfree(istgt->uctl_portal[i].host);                  xfree(istgt->uctl_portal[i].host);
                 xfree(istgt->uctl_portal[i].port);                  xfree(istgt->uctl_portal[i].port);
Line 500  istgt_destroy_uctl_portal(ISTGT_Ptr istgt) Line 952  istgt_destroy_uctl_portal(ISTGT_Ptr istgt)
                 istgt->uctl_portal[i].label = NULL;                  istgt->uctl_portal[i].label = NULL;
                 istgt->uctl_portal[i].host = NULL;                  istgt->uctl_portal[i].host = NULL;
                 istgt->uctl_portal[i].port = NULL;                  istgt->uctl_portal[i].port = NULL;
                   istgt->uctl_portal[i].ref = 0;
                 istgt->uctl_portal[i].idx = i;                  istgt->uctl_portal[i].idx = i;
                 istgt->uctl_portal[i].tag = 0;                  istgt->uctl_portal[i].tag = 0;
         }          }
Line 1099  istgt_init(ISTGT_Ptr istgt) Line 1552  istgt_init(ISTGT_Ptr istgt)
                     istgt->discovery_auth_group);                      istgt->discovery_auth_group);
         }          }
   
        rc = istgt_init_uctl(istgt);        rc = istgt_uctl_init(istgt);
         if (rc < 0) {          if (rc < 0) {
                ISTGT_ERRLOG("istgt_init_uctl() failed\n");                ISTGT_ERRLOG("istgt_uctl_init() failed\n");
                 return -1;                  return -1;
         }          }
         rc = istgt_build_uctl_portal(istgt);          rc = istgt_build_uctl_portal(istgt);
Line 1109  istgt_init(ISTGT_Ptr istgt) Line 1562  istgt_init(ISTGT_Ptr istgt)
                 ISTGT_ERRLOG("istgt_build_uctl_portal() failed\n");                  ISTGT_ERRLOG("istgt_build_uctl_portal() failed\n");
                 return -1;                  return -1;
         }          }
        rc = istgt_build_portal_array(istgt);        rc = istgt_build_portal_group_array(istgt);
         if (rc < 0) {          if (rc < 0) {
                 ISTGT_ERRLOG("istgt_build_portal_array() failed\n");                  ISTGT_ERRLOG("istgt_build_portal_array() failed\n");
                 return -1;                  return -1;
Line 1141  istgt_init(ISTGT_Ptr istgt) Line 1594  istgt_init(ISTGT_Ptr istgt)
                 }                  }
         }          }
   
           rc = pthread_mutexattr_init(&istgt->mutex_attr);
           if (rc != 0) {
                   ISTGT_ERRLOG("mutexattr_init() failed\n");
                   return -1;
           }
   #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
           rc = pthread_mutexattr_settype(&istgt->mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
   #else
           rc = pthread_mutexattr_settype(&istgt->mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
   #endif
           if (rc != 0) {
                   ISTGT_ERRLOG("mutexattr_settype() failed\n");
                   return -1;
           }
         rc = pthread_mutex_init(&istgt->mutex, NULL);          rc = pthread_mutex_init(&istgt->mutex, NULL);
         if (rc != 0) {          if (rc != 0) {
                 ISTGT_ERRLOG("mutex_init() failed\n");                  ISTGT_ERRLOG("mutex_init() failed\n");
                 return -1;                  return -1;
         }          }
           rc = pthread_mutex_init(&istgt->state_mutex, &istgt->mutex_attr);
           if (rc != 0) {
                   ISTGT_ERRLOG("mutex_init() failed\n");
                   return -1;
           }
           rc = pthread_mutex_init(&istgt->reload_mutex, &istgt->mutex_attr);
           if (rc != 0) {
                   ISTGT_ERRLOG("mutex_init() failed\n");
                   return -1;
           }
           rc = pthread_cond_init(&istgt->reload_cond, NULL);
           if (rc != 0) {
                   ISTGT_ERRLOG("cond_init() failed\n");
                   return -1;
           }
   
           rc = pipe(istgt->sig_pipe);
           if (rc != 0) {
                   ISTGT_ERRLOG("pipe() failed\n");
                   istgt->sig_pipe[0] = -1;
                   istgt->sig_pipe[1] = -1;
                   return -1;
           }
   
         /* XXX TODO: add initializer */          /* XXX TODO: add initializer */
   
         istgt_set_state(istgt, ISTGT_STATE_INITIALIZED);          istgt_set_state(istgt, ISTGT_STATE_INITIALIZED);
Line 1154  istgt_init(ISTGT_Ptr istgt) Line 1644  istgt_init(ISTGT_Ptr istgt)
         return 0;          return 0;
 }  }
   
   static void
   istgt_shutdown(ISTGT_Ptr istgt)
   {
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_shutdown\n");
   
           istgt_destory_initiator_group_array(istgt);
           istgt_destroy_portal_group_array(istgt);
           istgt_destroy_uctl_portal(istgt);
           istgt_uctl_shutdown(istgt);
           istgt_remove_pidfile(istgt);
           xfree(istgt->pidfile);
           xfree(istgt->authfile);
   #if 0
           xfree(istgt->mediafile);
           xfree(istgt->livefile);
   #endif
           xfree(istgt->mediadirectory);
           xfree(istgt->nodebase);
   
           if (istgt->sig_pipe[0] != -1)
               close(istgt->sig_pipe[0]);
           if (istgt->sig_pipe[1] != -1)
               close(istgt->sig_pipe[1]);
   
           (void) pthread_cond_destroy(&istgt->reload_cond);
           (void) pthread_mutex_destroy(&istgt->reload_mutex);
           (void) pthread_mutex_destroy(&istgt->state_mutex);
           (void) pthread_mutex_destroy(&istgt->mutex);
           (void) pthread_attr_destroy(&istgt->attr);
   }
   
   static int
   istgt_pg_exist_num(CONFIG *config, int num)
   {
           CF_SECTION *sp;
   
           sp = config->section;
           while (sp != NULL) {
                   if (sp->type == ST_PORTALGROUP) {
                           if (sp->num == num) {
                                   return 1;
                           }
                   }
                   sp = sp->next;
           }
           return -1;
   }
   
   static PORTAL_GROUP *
   istgt_get_tag_portal(ISTGT_Ptr istgt, int tag)
   {
           int i;
   
           if (tag == 0)
                   return NULL;
           MTX_LOCK(&istgt->mutex);
           for (i = 0; i < istgt->nportal_group; i++) {
                   if (istgt->portal_group[i].tag == tag) {
                           MTX_UNLOCK(&istgt->mutex);
                           return &istgt->portal_group[i];
                   }
           }
           MTX_UNLOCK(&istgt->mutex);
           return NULL;
   }
   
   #if 0
   static int
   istgt_get_num_of_portals(CF_SECTION *sp)
   {
           char *label, *portal;
           int portals;
           int rc;
           int i;
   
           for (i = 0; ; i++) {
                   label = istgt_get_nmval(sp, "Portal", i, 0);
                   portal = istgt_get_nmval(sp, "Portal", i, 1);
                   if (label == NULL || portal == NULL)
                           break;
                   rc = istgt_parse_portal(portal, NULL, NULL);
                   if (rc < 0) {
                           ISTGT_ERRLOG("parse portal error (%s)\n", portal);
                           return -1;
                   }
           }
           portals = i;
           if (portals > MAX_PORTAL) {
                   ISTGT_ERRLOG("%d > MAX_PORTAL\n", portals);
                   return -1;
           }
           return portals;
   }
   #endif
   
   #define RELOAD_CMD_LENGTH 5
   static int
   istgt_pg_reload_delete(ISTGT_Ptr istgt)
   {
           char tmp[RELOAD_CMD_LENGTH];
           int rc;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_pg_reload_delete\n");
   
           istgt->pg_reload = 0;
           /* request delete */
           tmp[0] = 'D';
           DSET32(&tmp[1], 0);
           rc = write(istgt->sig_pipe[1], tmp, RELOAD_CMD_LENGTH);
           if (rc < 0 || rc != RELOAD_CMD_LENGTH) {
                   ISTGT_ERRLOG("write() failed\n");
                   return -1;
           }
           /* wait for completion */
           MTX_LOCK(&istgt->reload_mutex);
           while (istgt->pg_reload == 0) {
                   pthread_cond_wait(&istgt->reload_cond, &istgt->reload_mutex);
           }
           rc = istgt->pg_reload;
           MTX_UNLOCK(&istgt->reload_mutex);
           if (rc < 0) {
                   if (istgt_get_state(istgt) != ISTGT_STATE_RUNNING) {
                           ISTGT_WARNLOG("pg_reload abort\n");
                           return -1;
                   }
           }
           return 0;
   }
   
   static int
   istgt_pg_reload_update(ISTGT_Ptr istgt)
   {
           char tmp[RELOAD_CMD_LENGTH];
           int rc;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_pg_reload_update\n");
   
           istgt->pg_reload = 0;
           /* request update */
           tmp[0] = 'U';
           DSET32(&tmp[1], 0);
           rc = write(istgt->sig_pipe[1], tmp, RELOAD_CMD_LENGTH);
           if (rc < 0 || rc != RELOAD_CMD_LENGTH) {
                   ISTGT_ERRLOG("write() failed\n");
                   return -1;
           }
           /* wait for completion */
           MTX_LOCK(&istgt->reload_mutex);
           while (istgt->pg_reload == 0) {
                   pthread_cond_wait(&istgt->reload_cond, &istgt->reload_mutex);
           }
           rc = istgt->pg_reload;
           MTX_UNLOCK(&istgt->reload_mutex);
           if (rc < 0) {
                   if (istgt_get_state(istgt) != ISTGT_STATE_RUNNING) {
                           ISTGT_WARNLOG("pg_reload abort\n");
                           return -1;
                   }
           }
           return 0;
   }
   
   static int
   istgt_ig_exist_num(CONFIG *config, int num)
   {
           CF_SECTION *sp;
   
           sp = config->section;
           while (sp != NULL) {
                   if (sp->type == ST_INITIATORGROUP) {
                           if (sp->num == num) {
                                   return 1;
                           }
                   }
                   sp = sp->next;
           }
           return -1;
   }
   
   static int
   istgt_ig_reload_delete(ISTGT_Ptr istgt)
   {
           INITIATOR_GROUP *igp;
           int rc;
           int i, j;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_ig_reload_delete\n");
           MTX_LOCK(&istgt->mutex);
           for (i = 0; i < istgt->ninitiator_group; i++) {
                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "IG reload idx=%d, (%d)\n",
                       i, istgt->ninitiator_group);
                   igp = &istgt->initiator_group[i];
                   rc = istgt_ig_exist_num(istgt->config, igp->tag);
                   if (rc < 0) {
                           if (igp->ref != 0) {
                                   ISTGT_ERRLOG("delete request for referenced IG%d\n",
                                       igp->tag);
                           } else {
                                   ISTGT_NOTICELOG("delete IG%d\n", igp->tag);
                                   /* free old IG */
                                   for (j = 0; j < istgt->initiator_group[i].ninitiators; j++) {
                                           xfree(istgt->initiator_group[i].initiators[j]);
                                   }
                                   xfree(istgt->initiator_group[i].initiators);
                                   for (j = 0; j < istgt->initiator_group[i].nnetmasks; j++) {
                                           xfree(istgt->initiator_group[i].netmasks[j]);
                                   }
                                   xfree(istgt->initiator_group[i].netmasks);
   
                                   /* move from beyond the IG */
                                   for (j = i; j < istgt->ninitiator_group - 1; j++) {
                                           istgt->initiator_group[j].ninitiators
                                                   = istgt->initiator_group[j+1].ninitiators;
                                           istgt->initiator_group[j].initiators
                                                   = istgt->initiator_group[j+1].initiators;
                                           istgt->initiator_group[j].nnetmasks
                                                   = istgt->initiator_group[j+1].nnetmasks;
                                           istgt->initiator_group[j].netmasks
                                                   = istgt->initiator_group[j+1].netmasks;
                                           istgt->initiator_group[j].ref
                                                   = istgt->initiator_group[j+1].ref;
                                           istgt->initiator_group[j].idx
                                                   = istgt->initiator_group[j+1].idx;
                                           istgt->initiator_group[j].tag
                                                   = istgt->initiator_group[j+1].tag;
                                   }
                                   istgt->ninitiator_group--;
                           }
                   }
           }
           MTX_UNLOCK(&istgt->mutex);
           return 0;
   }
   
   static int
   istgt_ig_reload_update(ISTGT_Ptr istgt)
   {
           CF_SECTION *sp;
           int rc;
           int i;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_ig_reload_update\n");
           sp = istgt->config->section;
           while (sp != NULL) {
                   if (sp->type == ST_INITIATORGROUP) {
                           if (sp->num == 0) {
                                   ISTGT_ERRLOG("Group 0 is invalid\n");
                                   goto skip_ig;
                           }
                           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "IG reload tag=%d\n", sp->num);
   #if 0
                           rc = istgt_ig_exist_num(istgt->config_old, sp->num);
   #else
                           rc = -1;
                           MTX_LOCK(&istgt->mutex);
                           for (i = 0; i < istgt->ninitiator_group; i++) {
                                   if (istgt->initiator_group[i].tag == sp->num) {
                                           rc = 1;
                                           break;
                                   }
                           }
                           MTX_UNLOCK(&istgt->mutex);
   #endif
                           if (rc < 0) {
                                   rc = istgt_add_initiator_group(istgt, sp);
                                   if (rc < 0) {
                                           ISTGT_ERRLOG("add_initiator_group() failed\n");
                                           goto skip_ig;
                                   }
                                   ISTGT_NOTICELOG("add IG%d\n", sp->num);
                           } else {
                                   rc = istgt_update_initiator_group(istgt, sp);
                                   if (rc < 0) {
                                           ISTGT_ERRLOG("update_initiator_group() failed\n");
                                           goto skip_ig;
                                   } else if (rc == 0) {
                                           // not modified
                                   } else if (rc > 0) {
                                           ISTGT_NOTICELOG("update IG%d\n", sp->num);
                                   }
                           }
                   }
           skip_ig:
                   sp = sp->next;
           }
           return 0;
   }
   
   static int
   istgt_reload(ISTGT_Ptr istgt)
   {
           CONFIG *config_new, *config_old;
           char *config_file;
           int rc;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_reload\n");
           /* prepare config structure */
           config_new = istgt_allocate_config();
           config_old = istgt->config;
           config_file = config_old->file;
           rc = istgt_read_config(config_new, config_file);
           if (rc < 0) {
                   ISTGT_ERRLOG("config error\n");
                   return -1;
           }
           if (config_new->section == NULL) {
                   ISTGT_ERRLOG("empty config\n");
                   istgt_free_config(config_new);
                   return -1;
           }
           istgt->config = config_new;
           istgt->config_old = config_old;
           istgt->generation++;
   
           /* reload sub groups */
           ISTGT_NOTICELOG("reload configuration #%"PRIu32"\n", istgt->generation);
           rc = istgt_lu_reload_delete(istgt);
           if (rc < 0) {
                   ISTGT_ERRLOG("LU reload del error\n");
                   return -1;
           }
           rc = istgt_ig_reload_delete(istgt);
           if (rc < 0) {
                   ISTGT_ERRLOG("IG reload del error\n");
                   return -1;
           }
           rc = istgt_pg_reload_delete(istgt);
           if (rc < 0) {
                   ISTGT_ERRLOG("PG reload del error\n");
                   return -1;
           }
   
           rc = istgt_pg_reload_update(istgt);
           if (rc < 0) {
                   ISTGT_ERRLOG("PG reload add error\n");
                   return -1;
           }
           rc = istgt_ig_reload_update(istgt);
           if (rc < 0) {
                   ISTGT_ERRLOG("IG reload add error\n");
                   return -1;
           }
           rc = istgt_lu_reload_update(istgt);
           if (rc < 0) {
                   ISTGT_ERRLOG("LU reload add error\n");
                   return -1;
           }
   
           istgt->config_old = NULL;
           istgt_free_config(config_old);
           return 0;
   }
   
   static int
   istgt_stop_loop(ISTGT_Ptr istgt)
   {
           char tmp[RELOAD_CMD_LENGTH];
           int rc;
   
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_stop_loop\n");
           tmp[0] = 'E';
           DSET32(&tmp[1], 0);
           rc = write(istgt->sig_pipe[1], tmp, RELOAD_CMD_LENGTH);
           if (rc < 0 || rc != RELOAD_CMD_LENGTH) {
                   ISTGT_ERRLOG("write() failed\n");
                   /* ignore error */
           }
           return 0;
   }
   
   
   static void
   istgt_sigint(int signo __attribute__((__unused__)))
   {
   }
   
   static void
   istgt_sigterm(int signo __attribute__((__unused__)))
   {
   }
   
   static void
   istgt_sighup(int signo __attribute__((__unused__)))
   {
   }
   
 #ifdef SIGINFO  #ifdef SIGINFO
 static void  static void
istgt_siginfo(int signo)istgt_siginfo(int signo __attribute__((__unused__)))
 {  {
         /* nothing */          /* nothing */
 }  }
 #endif  #endif
   
 static void  static void
istgt_sigwakeup(int signo)istgt_sigwakeup(int signo __attribute__((__unused__)))
 {  {
 }  }
   
 #ifdef SIGIO  #ifdef SIGIO
 static void  static void
istgt_sigio(int signo)istgt_sigio(int signo __attribute__((__unused__)))
 {  {
 }  }
 #endif  #endif
Line 1205  istgt_sighandler(void *arg) Line 2081  istgt_sighandler(void *arg)
                 switch (signo) {                  switch (signo) {
                 case SIGINT:                  case SIGINT:
                         printf("SIGINT catch\n");                          printf("SIGINT catch\n");
                           istgt_stop_loop(istgt);
                         istgt_set_state(istgt, ISTGT_STATE_EXITING);                          istgt_set_state(istgt, ISTGT_STATE_EXITING);
                         istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);                          istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);
                         break;                          break;
                 case SIGTERM:                  case SIGTERM:
                         printf("SIGTERM catch\n");                          printf("SIGTERM catch\n");
                           istgt_stop_loop(istgt);
                         istgt_set_state(istgt, ISTGT_STATE_EXITING);                          istgt_set_state(istgt, ISTGT_STATE_EXITING);
                         istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);                          istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);
                         break;                          break;
Line 1219  istgt_sighandler(void *arg) Line 2097  istgt_sighandler(void *arg)
                         break;                          break;
                 case SIGHUP:                  case SIGHUP:
                         printf("SIGHUP catch\n");                          printf("SIGHUP catch\n");
                           istgt_reload(istgt);
                         break;                          break;
 #ifdef SIGINFO  #ifdef SIGINFO
                 case SIGINFO:                  case SIGINFO:
Line 1249  istgt_sighandler(void *arg) Line 2128  istgt_sighandler(void *arg)
         return NULL;          return NULL;
 }  }
   
   static PORTAL *
   istgt_get_sock_portal(ISTGT_Ptr istgt, int sock)
   {
           int i, j;
   
           if (sock < 0)
                   return NULL;
           MTX_LOCK(&istgt->mutex);
           for (i = 0; i < istgt->nportal_group; i++) {
                   for (j = 0; j < istgt->portal_group[i].nportals; j++) {
                           if (istgt->portal_group[i].portals[j]->sock == sock) {
                                   MTX_UNLOCK(&istgt->mutex);
                                   return istgt->portal_group[i].portals[j];
                           }
                   }
           }
           MTX_UNLOCK(&istgt->mutex);
           return NULL;
   }
   
 static int  static int
   istgt_pg_delete(ISTGT_Ptr istgt)
   {
           PORTAL_GROUP *pgp;
           int rc;
           int i;
   
           MTX_LOCK(&istgt->mutex);
           for (i = 0; i < istgt->nportal_group; i++) {
                   pgp = &istgt->portal_group[i];
                   if (pgp->tag == 0)
                           continue;
                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "PG reload idx=%d, tag=%d, (%d)\n",
                       i, pgp->tag, istgt->nportal_group);
                   rc = istgt_pg_exist_num(istgt->config, pgp->tag);
                   if (rc < 0) {
                           if (pgp->ref != 0) {
                                   ISTGT_ERRLOG("delete request for referenced PG%d\n",
                                       pgp->tag);
                           } else {
                                   ISTGT_NOTICELOG("delete PG%d\n", pgp->tag);
                                   pgp->tag = 0;
                                   (void) istgt_close_portal_group(pgp);
                           }
                   }
           }
           MTX_UNLOCK(&istgt->mutex);
           return 0;
   }
   
   static int
   istgt_pg_update(ISTGT_Ptr istgt)
   {
           PORTAL_GROUP *pgp;
           CF_SECTION *sp;
           int pgp_idx;
           int rc;
           int i;
   
           sp = istgt->config->section;
           while (sp != NULL) {
                   if (sp->type == ST_PORTALGROUP) {
                           if (sp->num == 0) {
                                   ISTGT_ERRLOG("Group 0 is invalid\n");
                                   goto skip_pg;
                           }
                           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "PG reload tag=%d\n", sp->num);
   #if 0
                           rc = istgt_pg_exist_num(istgt->config_old, sp->num);
   #else
                           rc = -1;
                           MTX_LOCK(&istgt->mutex);
                           for (i = 0; i < istgt->nportal_group; i++) {
                                   if (istgt->portal_group[i].tag == sp->num) {
                                           rc = 1;
                                           break;
                                   }
                           }
                           MTX_UNLOCK(&istgt->mutex);
   #endif
                           if (rc < 0) {
                                   rc = istgt_add_portal_group(istgt, sp, &pgp_idx);
                                   if (rc < 0) {
                                           ISTGT_ERRLOG("add_portal_group() failed\n");
                                           goto skip_pg;
                                   }
                                   MTX_LOCK(&istgt->mutex);
                                   pgp = &istgt->portal_group[pgp_idx];
                                   (void) istgt_open_portal_group(pgp);
                                   MTX_UNLOCK(&istgt->mutex);
                                   ISTGT_NOTICELOG("add PG%d\n", sp->num);
                           } else {
                                   //portals = istgt_get_num_of_portals(sp);
                                   pgp = istgt_get_tag_portal(istgt, sp->num);
                                   if (istgt_pg_match_all(pgp, sp)) {
                                           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                                               "skip for PG%d\n", sp->num);
                                   } else if (pgp->ref != 0) {
                                           ISTGT_ERRLOG("update request for referenced PG%d\n",
                                               pgp->tag);
                                   } else {
                                           /* delete old sock */
                                           MTX_LOCK(&istgt->mutex);
                                           pgp_idx = pgp->idx;
                                           (void) istgt_close_portal_group(pgp);
                                           MTX_UNLOCK(&istgt->mutex);
                                           rc = istgt_update_portal_group(istgt, sp, &pgp_idx);
                                           if (rc < 0) {
                                                   ISTGT_ERRLOG("update_portal_group() failed\n");
                                                   goto skip_pg;
                                           } else if (rc == 0) {
                                                   // not modified
                                           } else if (rc > 0) {
                                                   /* add new sock */
                                                   MTX_LOCK(&istgt->mutex);
                                                   pgp = &istgt->portal_group[pgp_idx];
                                                   (void) istgt_open_portal_group(pgp);
                                                   MTX_UNLOCK(&istgt->mutex);
                                                   ISTGT_NOTICELOG("update PG%d\n", sp->num);
                                           }
                                   }
                           }
                   }
           skip_pg:
                   sp = sp->next;
           }
           return 0;
   }
   
   static int
 istgt_acceptor(ISTGT_Ptr istgt)  istgt_acceptor(ISTGT_Ptr istgt)
 {  {
           PORTAL *pp;
 #ifdef ISTGT_USE_KQUEUE  #ifdef ISTGT_USE_KQUEUE
         int kq;          int kq;
         struct kevent kev;          struct kevent kev;
         struct timespec kev_timeout;          struct timespec kev_timeout;
           int kqsocks[MAX_PORTAL_GROUP + MAX_UCPORTAL];
 #else  #else
        struct pollfd fds[MAX_PORTAL + MAX_UCPORTAL];        struct pollfd fds[MAX_PORTAL_GROUP + MAX_UCPORTAL];
 #endif /* ISTGT_USE_KQUEUE */  #endif /* ISTGT_USE_KQUEUE */
         struct sockaddr_storage sa;          struct sockaddr_storage sa;
         socklen_t salen;          socklen_t salen;
Line 1265  istgt_acceptor(ISTGT_Ptr istgt) Line 2275  istgt_acceptor(ISTGT_Ptr istgt)
         int rc, n;          int rc, n;
         int ucidx;          int ucidx;
         int nidx;          int nidx;
        int i;        int i, j;
   
         if (istgt_get_state(istgt) != ISTGT_STATE_INITIALIZED) {          if (istgt_get_state(istgt) != ISTGT_STATE_INITIALIZED) {
                 ISTGT_ERRLOG("not initialized\n");                  ISTGT_ERRLOG("not initialized\n");
Line 1274  istgt_acceptor(ISTGT_Ptr istgt) Line 2284  istgt_acceptor(ISTGT_Ptr istgt)
         /* now running main thread */          /* now running main thread */
         istgt_set_state(istgt, ISTGT_STATE_RUNNING);          istgt_set_state(istgt, ISTGT_STATE_RUNNING);
   
   reload:
           nidx = 0;
 #ifdef ISTGT_USE_KQUEUE  #ifdef ISTGT_USE_KQUEUE
         kq = kqueue();          kq = kqueue();
         if (kq == -1) {          if (kq == -1) {
                 ISTGT_ERRLOG("kqueue() failed\n");                  ISTGT_ERRLOG("kqueue() failed\n");
                 return -1;                  return -1;
         }          }
        for (i = 0; i < istgt->nportal; i++) {        for (i = 0; i < (int)(sizeof kqsocks / sizeof *kqsocks); i++) {
                EV_SET(&kev, istgt->portal[i].sock,                kqsocks[i] = -1;
                    EVFILT_READ, EV_ADD, 0, 0, NULL);        }
                rc = kevent(kq, &kev, 1, NULL, 0, NULL);        MTX_LOCK(&istgt->mutex);
                if (rc == -1) {        for (i = 0; i < istgt->nportal_group; i++) {
                        ISTGT_ERRLOG("kevent() failed\n");                for (j = 0; j < istgt->portal_group[i].nportals; j++) {
                        close(kq);                        if (istgt->portal_group[i].portals[j]->sock >= 0) {
                        return -1;                                ISTGT_EV_SET(&kev, istgt->portal_group[i].portals[j]->sock,
                                     EVFILT_READ, EV_ADD, 0, 0, NULL);
                                 rc = kevent(kq, &kev, 1, NULL, 0, NULL);
                                 if (rc == -1) {
                                         MTX_UNLOCK(&istgt->mutex);
                                         ISTGT_ERRLOG("kevent() failed\n");
                                         close(kq);
                                         return -1;
                                 }
                                 kqsocks[nidx] = istgt->portal_group[i].portals[j]->sock;
                                 nidx++;
                         }
                 }                  }
         }          }
        ucidx = istgt->nportal;        MTX_UNLOCK(&istgt->mutex);
         ucidx = nidx;
         for (i = 0; i < istgt->nuctl_portal; i++) {          for (i = 0; i < istgt->nuctl_portal; i++) {
                EV_SET(&kev, istgt->uctl_portal[i].sock,                ISTGT_EV_SET(&kev, istgt->uctl_portal[i].sock,
                     EVFILT_READ, EV_ADD, 0, 0, NULL);                      EVFILT_READ, EV_ADD, 0, 0, NULL);
                 rc = kevent(kq, &kev, 1, NULL, 0, NULL);                  rc = kevent(kq, &kev, 1, NULL, 0, NULL);
                 if (rc == -1) {                  if (rc == -1) {
Line 1300  istgt_acceptor(ISTGT_Ptr istgt) Line 2324  istgt_acceptor(ISTGT_Ptr istgt)
                         close(kq);                          close(kq);
                         return -1;                          return -1;
                 }                  }
                   kqsocks[nidx] = istgt->uctl_portal[i].sock;
                   nidx++;
         }          }
        nidx = istgt->nportal + istgt->nuctl_portal;        ISTGT_EV_SET(&kev, istgt->sig_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
 
        EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); 
         rc = kevent(kq, &kev, 1, NULL, 0, NULL);          rc = kevent(kq, &kev, 1, NULL, 0, NULL);
         if (rc == -1) {          if (rc == -1) {
                 ISTGT_ERRLOG("kevent() failed\n");                  ISTGT_ERRLOG("kevent() failed\n");
                 close(kq);                  close(kq);
                 return -1;                  return -1;
         }          }
        EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);        kqsocks[nidx] = istgt->sig_pipe[0];
        rc = kevent(kq, &kev, 1, NULL, 0, NULL);        nidx++;
        if (rc == -1) {
                ISTGT_ERRLOG("kevent() failed\n");        if (!istgt->daemon) {
                close(kq);                ISTGT_EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
                return -1;                rc = kevent(kq, &kev, 1, NULL, 0, NULL);
                 if (rc == -1) {
                         ISTGT_ERRLOG("kevent() failed\n");
                         close(kq);
                         return -1;
                 }
                 ISTGT_EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
                 rc = kevent(kq, &kev, 1, NULL, 0, NULL);
                 if (rc == -1) {
                         ISTGT_ERRLOG("kevent() failed\n");
                         close(kq);
                         return -1;
                 }
         }          }
 #else  #else
         memset(&fds, 0, sizeof fds);          memset(&fds, 0, sizeof fds);
        for (i = 0; i < istgt->nportal; i++) {        MTX_LOCK(&istgt->mutex);
                fds[i].fd = istgt->portal[i].sock;        for (i = 0; i < istgt->nportal_group; i++) {
                fds[i].events = POLLIN;                for (j = 0; j < istgt->portal_group[i].nportals; j++) {
                         if (istgt->portal_group[i].portals[j]->sock >= 0) {
                                 fds[i].fd = istgt->portal_group[i].portals[j]->sock;
                                 fds[i].events = POLLIN;
                                 nidx++;
                         }
                 }
         }          }
        ucidx = istgt->nportal;        MTX_UNLOCK(&istgt->mutex);
         ucidx = nidx;
         for (i = 0; i < istgt->nuctl_portal; i++) {          for (i = 0; i < istgt->nuctl_portal; i++) {
                 fds[ucidx + i].fd = istgt->uctl_portal[i].sock;                  fds[ucidx + i].fd = istgt->uctl_portal[i].sock;
                 fds[ucidx + i].events = POLLIN;                  fds[ucidx + i].events = POLLIN;
                   nidx++;
         }          }
        nidx = istgt->nportal + istgt->nuctl_portal;        fds[nidx].fd = istgt->sig_pipe[0];
         fds[nidx].events = POLLIN;
         nidx++;
 #endif /* ISTGT_USE_KQUEUE */  #endif /* ISTGT_USE_KQUEUE */
   
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop start\n");          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop start\n");
Line 1350  istgt_acceptor(ISTGT_Ptr istgt) Line 2396  istgt_acceptor(ISTGT_Ptr istgt)
                 }                  }
                 if (rc == 0) {                  if (rc == 0) {
                         /* idle timeout */                          /* idle timeout */
                           //ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "kevent TIMEOUT\n");
                         continue;                          continue;
                 }                  }
                 if (kev.filter == EVFILT_SIGNAL) {                  if (kev.filter == EVFILT_SIGNAL) {
Line 1373  istgt_acceptor(ISTGT_Ptr istgt) Line 2420  istgt_acceptor(ISTGT_Ptr istgt)
                 }                  }
                 if (rc == 0) {                  if (rc == 0) {
                         /* no fds */                          /* no fds */
                           //ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "poll TIMEOUT\n");
                         continue;                          continue;
                 }                  }
 #endif /* ISTGT_USE_KQUEUE */  #endif /* ISTGT_USE_KQUEUE */
   
                 n = rc;                  n = rc;
                for (i = 0; n != 0 && i < istgt->nportal; i++) {                for (i = 0; n != 0 && i < ucidx; i++) {
 #ifdef ISTGT_USE_KQUEUE  #ifdef ISTGT_USE_KQUEUE
                        if (kev.ident == istgt->portal[i].sock) {                        if (kev.ident == (uintptr_t)kqsocks[i]) {
                                 if (kev.flags) {                                  if (kev.flags) {
                                         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,                                          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                                             "flags %x\n",                                              "flags %x\n",
Line 1398  istgt_acceptor(ISTGT_Ptr istgt) Line 2446  istgt_acceptor(ISTGT_Ptr istgt)
                                 memset(&sa, 0, sizeof(sa));                                  memset(&sa, 0, sizeof(sa));
                                 salen = sizeof(sa);                                  salen = sizeof(sa);
 #ifdef ISTGT_USE_KQUEUE  #ifdef ISTGT_USE_KQUEUE
                                ISTGT_TRACELOG(ISTGT_TRACE_NET, "accept %d\n",                                ISTGT_TRACELOG(ISTGT_TRACE_NET, "accept %ld\n",
                                    kev.ident);                                    (unsigned long)kev.ident);
                                 pp = istgt_get_sock_portal(istgt, kev.ident);
                                 rc = accept(kev.ident, (struct sockaddr *) &sa, &salen);                                  rc = accept(kev.ident, (struct sockaddr *) &sa, &salen);
 #else  #else
                                 ISTGT_TRACELOG(ISTGT_TRACE_NET, "accept %d\n",                                  ISTGT_TRACELOG(ISTGT_TRACE_NET, "accept %d\n",
                                     fds[i].fd);                                      fds[i].fd);
                                   pp = istgt_get_sock_portal(istgt, fds[i].fd);
                                 rc = accept(fds[i].fd, (struct sockaddr *) &sa, &salen);                                  rc = accept(fds[i].fd, (struct sockaddr *) &sa, &salen);
 #endif /* ISTGT_USE_KQUEUE */  #endif /* ISTGT_USE_KQUEUE */
                                 if (rc < 0) {                                  if (rc < 0) {
Line 1423  istgt_acceptor(ISTGT_Ptr istgt) Line 2473  istgt_acceptor(ISTGT_Ptr istgt)
                                         continue;                                          continue;
                                 }                                  }
 #endif  #endif
                                rc = istgt_create_conn(istgt,                                rc = istgt_create_conn(istgt, pp, sock,
                                    &istgt->portal[i], sock, 
                                     (struct sockaddr *) &sa, salen);                                      (struct sockaddr *) &sa, salen);
                                 if (rc < 0) {                                  if (rc < 0) {
                                         close(sock);                                          close(sock);
Line 1437  istgt_acceptor(ISTGT_Ptr istgt) Line 2486  istgt_acceptor(ISTGT_Ptr istgt)
                 /* check for control */                  /* check for control */
                 for (i = 0; n != 0 && i < istgt->nuctl_portal; i++) {                  for (i = 0; n != 0 && i < istgt->nuctl_portal; i++) {
 #ifdef ISTGT_USE_KQUEUE  #ifdef ISTGT_USE_KQUEUE
                        if (kev.ident == istgt->uctl_portal[i].sock) {                        if (kev.ident == (uintptr_t)istgt->uctl_portal[i].sock) {
                                 if (kev.flags) {                                  if (kev.flags) {
                                         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,                                          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                                             "flags %x\n",                                              "flags %x\n",
Line 1456  istgt_acceptor(ISTGT_Ptr istgt) Line 2505  istgt_acceptor(ISTGT_Ptr istgt)
                                 salen = sizeof(sa);                                  salen = sizeof(sa);
 #ifdef ISTGT_USE_KQUEUE  #ifdef ISTGT_USE_KQUEUE
                                 ISTGT_TRACELOG(ISTGT_TRACE_NET,                                  ISTGT_TRACELOG(ISTGT_TRACE_NET,
                                    "accept %d\n", kev.ident);                                    "accept %ld\n", (unsigned long)kev.ident);
                                 rc = accept(kev.ident,                                  rc = accept(kev.ident,
                                     (struct sockaddr *) &sa, &salen);                                      (struct sockaddr *) &sa, &salen);
 #else  #else
Line 1480  istgt_acceptor(ISTGT_Ptr istgt) Line 2529  istgt_acceptor(ISTGT_Ptr istgt)
                                 }                                  }
                         }                          }
                 }                  }
   
                   /* check for signal thread */
   #ifdef ISTGT_USE_KQUEUE
                   if (kev.ident == (uintptr_t)istgt->sig_pipe[0]) {
                           if (kev.flags & (EV_EOF|EV_ERROR)) {
                                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                                       "kevent EOF/ERROR\n");
                                   break;
                           }
   #else
                   if (fds[nidx - 1].revents & POLLHUP) {
                           break;
                   }
                   if (fds[nidx - 1].revents & POLLIN) {
   #endif /* ISTGT_USE_KQUEUE */
                           char tmp[RELOAD_CMD_LENGTH];
                           //int pgp_idx;
                           int rc2;
   
                           rc = read(istgt->sig_pipe[0], tmp, RELOAD_CMD_LENGTH);
                           if (rc < 0 || rc == 0 || rc != RELOAD_CMD_LENGTH) {
                                   ISTGT_ERRLOG("read() failed\n");
                                   break;
                           }
                           //pgp_idx = (int)DGET32(&tmp[1]);
   
                           if (tmp[0] == 'E') {
                                   ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
                                       "exit request (main loop)\n");
                                   break;
                           }
                           if (tmp[0] == 'D') {
                                   rc = istgt_pg_delete(istgt);
                                   MTX_LOCK(&istgt->reload_mutex);
                                   istgt->pg_reload = rc < 0 ? -1 : 1;
                                   rc2 = pthread_cond_broadcast(&istgt->reload_cond);
                                   if (rc2 != 0) {
                                           ISTGT_ERRLOG("cond_broadcast() failed\n");
                                   }
                                   MTX_UNLOCK(&istgt->reload_mutex);
                                   if (rc < 0) {
                                           ISTGT_ERRLOG("pg_delete() failed\n");
                                           //break;
                                   }
                           }
                           if (tmp[0] == 'U') {
                                   rc = istgt_pg_update(istgt);
                                   MTX_LOCK(&istgt->reload_mutex);
                                   istgt->pg_reload = rc < 0 ? -1 : 1;
                                   rc2 = pthread_cond_broadcast(&istgt->reload_cond);
                                   if (rc2 != 0) {
                                           ISTGT_ERRLOG("cond_broadcast() failed\n");
                                   }
                                   MTX_UNLOCK(&istgt->reload_mutex);
                                   if (rc < 0) {
                                           ISTGT_ERRLOG("pg_update() failed\n");
                                           //break;
                                   }
                           }
   #ifdef ISTGT_USE_KQUEUE
                           close(kq);
   #endif /* ISTGT_USE_KQUEUE */
                           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "reload accept loop\n");
                           goto reload;
                   }
         }          }
 #ifdef ISTGT_USE_KQUEUE  #ifdef ISTGT_USE_KQUEUE
         close(kq);          close(kq);
 #endif /* ISTGT_USE_KQUEUE */  #endif /* ISTGT_USE_KQUEUE */
         ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop ended\n");          ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop ended\n");
         istgt_set_state(istgt, ISTGT_STATE_EXITING);          istgt_set_state(istgt, ISTGT_STATE_EXITING);
           istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);
   
         return 0;          return 0;
 }  }
Line 1518  main(int argc, char **argv) Line 2633  main(int argc, char **argv)
         const char *logpriority = NULL;          const char *logpriority = NULL;
         CONFIG *config;          CONFIG *config;
         pthread_t sigthread;          pthread_t sigthread;
        struct sigaction sigact, sigoldact_pipe, sigoldact_info;        struct sigaction sigact, sigoldact_pipe, sigoldact_int, sigoldact_term;
         struct sigaction sigoldact_hup, sigoldact_info;
         struct sigaction sigoldact_wakeup, sigoldact_io;          struct sigaction sigoldact_wakeup, sigoldact_io;
         sigset_t signew, sigold;          sigset_t signew, sigold;
         int retry = 10;          int retry = 10;
Line 1534  main(int argc, char **argv) Line 2650  main(int argc, char **argv)
   
         memset(&g_istgt, 0, sizeof g_istgt);          memset(&g_istgt, 0, sizeof g_istgt);
         istgt = &g_istgt;          istgt = &g_istgt;
        istgt_set_state(istgt, ISTGT_STATE_INVALID);        istgt->state = ISTGT_STATE_INVALID;
         istgt->swmode = DEFAULT_ISTGT_SWMODE;          istgt->swmode = DEFAULT_ISTGT_SWMODE;
           istgt->sig_pipe[0] = istgt->sig_pipe[1] = -1;
           istgt->daemon = 0;
           istgt->generation = 0;
   
         while ((ch = getopt(argc, argv, "c:p:l:m:t:qDHV")) != -1) {          while ((ch = getopt(argc, argv, "c:p:l:m:t:qDHV")) != -1) {
                 switch (ch) {                  switch (ch) {
Line 1609  main(int argc, char **argv) Line 2728  main(int argc, char **argv)
                 exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
         }          }
         istgt->config = config;          istgt->config = config;
           istgt->config_old = NULL;
         //istgt_print_config(config);          //istgt_print_config(config);
   
         /* open log files */          /* open log files */
Line 1647  main(int argc, char **argv) Line 2767  main(int argc, char **argv)
         default:          default:
                 break;                  break;
         }          }
   #ifdef ISTGT_USE_KQUEUE
           ISTGT_NOTICELOG("using kqueue\n");
   #else
           ISTGT_NOTICELOG("using poll\n");
   #endif /* ISTGT_USE_KQUEUE */
   #ifdef USE_ATOMIC
           ISTGT_NOTICELOG("using host atomic\n");
   #elif defined (USE_GCC_ATOMIC)
           ISTGT_NOTICELOG("using gcc atomic\n");
   #else
           ISTGT_NOTICELOG("using generic atomic\n");
   #endif /* USE_ATOMIC */
   
 #ifdef ISTGT_USE_CRC32C_TABLE  #ifdef ISTGT_USE_CRC32C_TABLE
         /* build crc32c table */          /* build crc32c table */
Line 1682  main(int argc, char **argv) Line 2814  main(int argc, char **argv)
         /* detach from tty and run background */          /* detach from tty and run background */
         fflush(stdout);          fflush(stdout);
         if (detach) {          if (detach) {
                   istgt->daemon = 1;
                 rc = daemon(0, 0);                  rc = daemon(0, 0);
                 if (rc < 0) {                  if (rc < 0) {
                         ISTGT_ERRLOG("daemon() failed\n");                          ISTGT_ERRLOG("daemon() failed\n");
Line 1690  main(int argc, char **argv) Line 2823  main(int argc, char **argv)
         }          }
   
         /* setup signal handler thread */          /* setup signal handler thread */
           ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "setup signal handler\n");
         memset(&sigact, 0, sizeof sigact);          memset(&sigact, 0, sizeof sigact);
         memset(&sigoldact_pipe, 0, sizeof sigoldact_pipe);          memset(&sigoldact_pipe, 0, sizeof sigoldact_pipe);
           memset(&sigoldact_int, 0, sizeof sigoldact_int);
           memset(&sigoldact_term, 0, sizeof sigoldact_term);
           memset(&sigoldact_hup, 0, sizeof sigoldact_hup);
         memset(&sigoldact_info, 0, sizeof sigoldact_info);          memset(&sigoldact_info, 0, sizeof sigoldact_info);
         memset(&sigoldact_wakeup, 0, sizeof sigoldact_wakeup);          memset(&sigoldact_wakeup, 0, sizeof sigoldact_wakeup);
         memset(&sigoldact_io, 0, sizeof sigoldact_io);          memset(&sigoldact_io, 0, sizeof sigoldact_io);
Line 1702  main(int argc, char **argv) Line 2839  main(int argc, char **argv)
                 ISTGT_ERRLOG("sigaction(SIGPIPE) failed\n");                  ISTGT_ERRLOG("sigaction(SIGPIPE) failed\n");
                 goto initialize_error;                  goto initialize_error;
         }          }
           sigact.sa_handler = istgt_sigint;
           sigemptyset(&sigact.sa_mask);
           rc = sigaction(SIGINT, &sigact, &sigoldact_int);
           if (rc < 0) {
                   ISTGT_ERRLOG("sigaction(SIGINT) failed\n");
                   goto initialize_error;
           }
           sigact.sa_handler = istgt_sigterm;
           sigemptyset(&sigact.sa_mask);
           rc = sigaction(SIGTERM, &sigact, &sigoldact_term);
           if (rc < 0) {
                   ISTGT_ERRLOG("sigaction(SIGTERM) failed\n");
                   goto initialize_error;
           }
           sigact.sa_handler = istgt_sighup;
           sigemptyset(&sigact.sa_mask);
           rc = sigaction(SIGHUP, &sigact, &sigoldact_hup);
           if (rc < 0) {
                   ISTGT_ERRLOG("sigaction(SIGHUP) failed\n");
                   goto initialize_error;
           }
 #ifdef SIGINFO  #ifdef SIGINFO
         sigact.sa_handler = istgt_siginfo;          sigact.sa_handler = istgt_siginfo;
         sigemptyset(&sigact.sa_mask);          sigemptyset(&sigact.sa_mask);
Line 1713  main(int argc, char **argv) Line 2871  main(int argc, char **argv)
 #endif  #endif
 #ifdef ISTGT_USE_SIGRT  #ifdef ISTGT_USE_SIGRT
         if (ISTGT_SIGWAKEUP < SIGRTMIN          if (ISTGT_SIGWAKEUP < SIGRTMIN
                || ISTGT_SIGWAKEUP > SIGRTMAX) {            || ISTGT_SIGWAKEUP > SIGRTMAX) {
                 ISTGT_ERRLOG("SIGRT error\n");                  ISTGT_ERRLOG("SIGRT error\n");
                 goto initialize_error;                  goto initialize_error;
         }          }
Line 1751  main(int argc, char **argv) Line 2909  main(int argc, char **argv)
         pthread_sigmask(SIG_SETMASK, &signew, &sigold);          pthread_sigmask(SIG_SETMASK, &signew, &sigold);
 #ifdef ISTGT_STACKSIZE  #ifdef ISTGT_STACKSIZE
         rc = pthread_create(&sigthread, &istgt->attr, &istgt_sighandler,          rc = pthread_create(&sigthread, &istgt->attr, &istgt_sighandler,
               (void *) istgt);
 #else  #else
         rc = pthread_create(&sigthread, NULL, &istgt_sighandler,          rc = pthread_create(&sigthread, NULL, &istgt_sighandler,
 #endif  
             (void *) istgt);              (void *) istgt);
   #endif
         if (rc != 0) {          if (rc != 0) {
                 ISTGT_ERRLOG("pthread_create() failed\n");                  ISTGT_ERRLOG("pthread_create() failed\n");
                 goto initialize_error;                  goto initialize_error;
Line 1789  main(int argc, char **argv) Line 2948  main(int argc, char **argv)
                 ISTGT_ERRLOG("istgt_open_uctl_portal() failed\n");                  ISTGT_ERRLOG("istgt_open_uctl_portal() failed\n");
                 goto initialize_error;                  goto initialize_error;
         }          }
        rc = istgt_open_portal(istgt);        rc = istgt_open_all_portals(istgt);
         if (rc < 0) {          if (rc < 0) {
                ISTGT_ERRLOG("istgt_open_portal() failed\n");                ISTGT_ERRLOG("istgt_open_all_portals() failed\n");
                 goto initialize_error;                  goto initialize_error;
         }          }
   
Line 1806  main(int argc, char **argv) Line 2965  main(int argc, char **argv)
         rc = istgt_acceptor(istgt);          rc = istgt_acceptor(istgt);
         if (rc < 0) {          if (rc < 0) {
                 ISTGT_ERRLOG("istgt_acceptor() failed\n");                  ISTGT_ERRLOG("istgt_acceptor() failed\n");
                istgt_close_portal(istgt);                istgt_close_all_portals(istgt);
                 istgt_close_uctl_portal(istgt);                  istgt_close_uctl_portal(istgt);
                 istgt_iscsi_shutdown(istgt);                  istgt_iscsi_shutdown(istgt);
                 istgt_lu_shutdown(istgt);                  istgt_lu_shutdown(istgt);
                istgt_destory_initiator_group_array(istgt);                istgt_shutdown(istgt);
                istgt_destroy_portal_array(istgt); 
                istgt_destroy_uctl_portal(istgt); 
                istgt_remove_pidfile(istgt); 
                 istgt_close_log();                  istgt_close_log();
                   config = istgt->config;
                 istgt->config = NULL;                  istgt->config = NULL;
                 istgt_free_config(config);                  istgt_free_config(config);
                 exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
         }          }
   
         /* wait threads */          /* wait threads */
           istgt_stop_conns();
         while (retry > 0) {          while (retry > 0) {
                 if (istgt_get_active_conns() == 0) {                  if (istgt_get_active_conns() == 0) {
                         break;                          break;
Line 1833  main(int argc, char **argv) Line 2991  main(int argc, char **argv)
         ISTGT_NOTICELOG("istgt version %s (%s) exiting\n", ISTGT_VERSION,          ISTGT_NOTICELOG("istgt version %s (%s) exiting\n", ISTGT_VERSION,
             ISTGT_EXTRA_VERSION);              ISTGT_EXTRA_VERSION);
   
           /* stop signal thread */
           rc = pthread_join(sigthread, NULL);
           if (rc != 0) {
                   ISTGT_ERRLOG("pthread_join() failed\n");
                   exit (EXIT_FAILURE);
           }
   
         /* cleanup */          /* cleanup */
        istgt_close_portal(istgt);        istgt_close_all_portals(istgt);
         istgt_close_uctl_portal(istgt);          istgt_close_uctl_portal(istgt);
         istgt_iscsi_shutdown(istgt);          istgt_iscsi_shutdown(istgt);
         istgt_lu_shutdown(istgt);          istgt_lu_shutdown(istgt);
        istgt_destory_initiator_group_array(istgt);        istgt_shutdown(istgt);
        istgt_destroy_portal_array(istgt); 
        istgt_destroy_uctl_portal(istgt); 
        istgt_remove_pidfile(istgt); 
         istgt_close_log();          istgt_close_log();
           config = istgt->config;
         istgt->config = NULL;          istgt->config = NULL;
         istgt_free_config(config);          istgt_free_config(config);
        istgt_set_state(istgt, ISTGT_STATE_SHUTDOWN);        istgt->state = ISTGT_STATE_SHUTDOWN;
 
        /* stop signal thread */ 
        rc = pthread_join(sigthread, NULL); 
        if (rc != 0) { 
                ISTGT_ERRLOG("pthread_join() failed\n"); 
                exit (EXIT_FAILURE); 
        } 
   
         return 0;          return 0;
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>