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