Skip to content

Commit

Permalink
[#191] Use GT.CM GNP server for @<hostname>:<filepath> syntax even if…
Browse files Browse the repository at this point in the history
… <hostname> is local host

When <hostname>:<filepath> is specified as the file name in the segment definition in the gld,
at runtime, YottaDB checks if <hostname> is a local host and if so does not go to GT.CM GNP.
Instead avoids using a GNP server, accesses the database locally and avoids network communication
overhead (aka short-circuiting). If not a local host, it goes to the GT.CM GNP server.

But with the @ prefix (i.e. @<hostname>:<filepath>), YottaDB now goes to the GT.CM GNP server
even if <hostname> is a local host.
  • Loading branch information
nars1 committed Oct 18, 2018
1 parent e906530 commit d2d3557
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 56 deletions.
12 changes: 10 additions & 2 deletions sr_unix/gvcst_init_sysops.c
Expand Up @@ -443,6 +443,7 @@ gd_region *dbfilopn(gd_region *reg)
sgmnt_data_ptr_t tsd;
file_control *fc;
unsigned char cstatus;
char *ptr;
boolean_t ftok_counter_halted;
ZOS_ONLY(int realfiletag;)
DCL_THREADGBL_ACCESS;
Expand Down Expand Up @@ -488,8 +489,15 @@ gd_region *dbfilopn(gd_region *reg)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(reg), status);
}
assert(((int)pblk.b_esl + 1) <= SIZEOF(seg->fname));
memcpy(seg->fname, pblk.buffer, pblk.b_esl);
pblk.buffer[pblk.b_esl] = 0;
/* If a remote nodename has been specified with the @ syntax, pblk.l_node points to the character past the '@'
* whereas pblk.buffer points to the '@' so use pblk.l_node in that case. In case a remote nodename has
* been specified without the '@' syntax, pblk.l_node points to the same character as pblk.buffer.
* In case no remote nodename is specified, pblk.l_node is uninitialized and pblk.buffer should be used.
* So in case a remote nodename is specified, use pblk.l_node and use pblk.buffer otherwise.
*/
ptr = !(pblk.fnb & F_HAS_NODE) ? pblk.buffer : pblk.l_node;
memcpy(seg->fname, ptr, pblk.b_esl);
ptr[pblk.b_esl] = 0;
seg->fname[pblk.b_esl] = 0;
seg->fname_len = pblk.b_esl;
if (pblk.fnb & F_HAS_NODE)
Expand Down
133 changes: 79 additions & 54 deletions sr_unix/parse_file.c
Expand Up @@ -70,6 +70,7 @@ int4 parse_file(mstr *file, parse_blk *pblk)
struct sockaddr localhost_sa, *localhost_sa_ptr;
mval def_trans;
int errcode;
boolean_t donot_short_circuit;

pblk->fnb = 0;
ai_ptr = localhost_ai_ptr = temp_ai_ptr = NULL;
Expand Down Expand Up @@ -112,6 +113,24 @@ int4 parse_file(mstr *file, parse_blk *pblk)
if (pblk->fop & F_PARNODE)
{ /* What we have could be a nodename */
assert(pblk->fop & F_SYNTAXO);
/* A file specification could be any of the the following forms
* <filepath>
* <hostname>:<filepath>
* @<hostname>:<filepath>
* where <hostname> is a host name that does not contain either '@' or ':'.
* In case '@' is not specified, we will check <hostname> to see if it is a local host
* and if so short-circuit the remote access and not go through GTCM GNP.
* In case '@' is specified, we will go through GTCM GNP even if it is a local host (#191).
*/
if ('@' == *node)
{
donot_short_circuit = TRUE;
/* Now that we have seen the '@', remove it from the nodename */
ptr++;
node = base = trans.addr = ptr;
trans.len--;
} else
donot_short_circuit = FALSE;
while (node < top)
{
ch = *node++;
Expand All @@ -125,75 +144,81 @@ int4 parse_file(mstr *file, parse_blk *pblk)
}
if (node < top)
{
assert(':' == ch);
hasnode = TRUE;
ptr = base = node; /* Update pointers past node name */
base = node; /* Update pointers past node name */
/* See if the desired (query) node is the local node */
node_name_len = (int)(node - trans.addr); /* Scanned node including ':' */
query_node_len = node_name_len - 1; /* Pure name length, no ':' on end */
assert(MAX_HOST_NAME_LEN >= query_node_len);
assert(0 < query_node_len);
assert(':' == *(trans.addr + query_node_len));
memcpy(query_node_name, trans.addr, query_node_len);
query_node_name[query_node_len] = 0;
localhost_sa_ptr = NULL; /* Null value needed if not find query node (remote default) */
CLIENT_HINTS(hints);
errcode = getaddrinfo(query_node_name, NULL, &hints, &ai_ptr);
if (0 == errcode)
if (!donot_short_circuit)
{
memcpy((sockaddr_ptr)&query_sas, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
query_node_len = node_name_len - 1; /* Pure name length, no ':' on end */
assert(MAX_HOST_NAME_LEN >= query_node_len);
assert(0 < query_node_len);
assert(':' == *(trans.addr + query_node_len));
memcpy(query_node_name, trans.addr, query_node_len);
query_node_name[query_node_len] = 0;
localhost_sa_ptr = NULL; /* Null value needed if not find query node (remote default) */
CLIENT_HINTS(hints);
if (0 == (errcode = getaddrinfo(LOCALHOSTNAME, NULL, &hints, &localhost_ai_ptr))
&& (0 == memcmp(localhost_ai_ptr->ai_addr, (sockaddr_ptr)&query_sas,
localhost_ai_ptr->ai_addrlen)))
errcode = getaddrinfo(query_node_name, NULL, &hints, &ai_ptr);
if (0 == errcode)
{
localhost_sa_ptr = localhost_ai_ptr->ai_addr;
}
FREEADDRINFO(localhost_ai_ptr);
if (!localhost_sa_ptr)
{ /* Have not yet established this is not a local node -- check further */
GETHOSTNAME(local_node_name, MAX_HOST_NAME_LEN, status);
if (-1 == status)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
LEN_AND_LIT("gethostname"), CALLFROM, errno);
memcpy((sockaddr_ptr)&query_sas, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
CLIENT_HINTS(hints);
if (0 != (errcode = getaddrinfo(local_node_name, NULL, &hints, &localhost_ai_ptr)))
localhost_ai_ptr = NULL; /* Empty address list */
for (temp_ai_ptr = localhost_ai_ptr; temp_ai_ptr!= NULL;
temp_ai_ptr = temp_ai_ptr->ai_next)
if (0 == (errcode = getaddrinfo(LOCALHOSTNAME, NULL, &hints, &localhost_ai_ptr))
&& (0 == memcmp(localhost_ai_ptr->ai_addr, (sockaddr_ptr)&query_sas,
localhost_ai_ptr->ai_addrlen)))
{
if (0 == memcmp((sockaddr_ptr)&query_sas, temp_ai_ptr->ai_addr,
temp_ai_ptr->ai_addrlen))
localhost_sa_ptr = localhost_ai_ptr->ai_addr;
}
FREEADDRINFO(localhost_ai_ptr);
if (!localhost_sa_ptr)
{ /* Have not yet established this is not a local node -- check further */
GETHOSTNAME(local_node_name, MAX_HOST_NAME_LEN, status);
if (-1 == status)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
LEN_AND_LIT("gethostname"), CALLFROM, errno);
CLIENT_HINTS(hints);
errcode = getaddrinfo(local_node_name, NULL, &hints, &localhost_ai_ptr);
if (0 != errcode)
localhost_ai_ptr = NULL; /* Empty address list */
for (temp_ai_ptr = localhost_ai_ptr; temp_ai_ptr!= NULL;
temp_ai_ptr = temp_ai_ptr->ai_next)
{
localhost_sa_ptr = temp_ai_ptr->ai_addr;
break; /* Tiz truly a local node */
if (0 == memcmp((sockaddr_ptr)&query_sas, temp_ai_ptr->ai_addr,
temp_ai_ptr->ai_addrlen))
{
localhost_sa_ptr = temp_ai_ptr->ai_addr;
break; /* Tiz truly a local node */
}
}
FREEADDRINFO(localhost_ai_ptr);
}
FREEADDRINFO(localhost_ai_ptr);
}
if (!localhost_sa_ptr)
{
CLIENT_HINTS(hints);
if (0 != (errcode = getaddrinfo(LOCALHOSTNAME6, NULL, &hints, &localhost_ai_ptr)))
localhost_ai_ptr = NULL; /* Empty address list */
for (temp_ai_ptr = localhost_ai_ptr; temp_ai_ptr!= NULL;
temp_ai_ptr = temp_ai_ptr->ai_next)
if (!localhost_sa_ptr)
{
if (0 == memcmp((sockaddr_ptr)&query_sas, temp_ai_ptr->ai_addr,
temp_ai_ptr->ai_addrlen))
CLIENT_HINTS(hints);
errcode = getaddrinfo(LOCALHOSTNAME6, NULL, &hints, &localhost_ai_ptr);
if (0 != errcode)
localhost_ai_ptr = NULL; /* Empty address list */
for (temp_ai_ptr = localhost_ai_ptr; temp_ai_ptr!= NULL;
temp_ai_ptr = temp_ai_ptr->ai_next)
{
localhost_sa_ptr = temp_ai_ptr->ai_addr;
break; /* Tiz truly a local node */
if (0 == memcmp((sockaddr_ptr)&query_sas, temp_ai_ptr->ai_addr,
temp_ai_ptr->ai_addrlen))
{
localhost_sa_ptr = temp_ai_ptr->ai_addr;
break; /* Tiz truly a local node */
}
}
FREEADDRINFO(localhost_ai_ptr);
}
FREEADDRINFO(localhost_ai_ptr);
FREEADDRINFO(ai_ptr);
/* At this point, if "localhost_sa_ptr" is NULL, a hostname that is not local
* (or an unknown hostname) is given. If it is non-NULL, a local hostname is given.
* Set "hasnode" to TRUE only for the non-local case.
* Treat local host as if node was not specified.
*/
hasnode = (NULL == localhost_sa_ptr);
}
FREEADDRINFO(ai_ptr);
/* At this point, if "localhost_sa_ptr" is NULL, a hostname that is not local
* (or an unknown hostname) is given. If it is non-NULL, a local hostname is given.
* Set "hasnode" to TRUE only for the non-local case.
* Treat local host as if node was not specified.
*/
hasnode = (NULL == localhost_sa_ptr);
}
if (hasnode)
{ /* Remote node specified -- don't apply any defaults */
Expand All @@ -204,7 +229,7 @@ int4 parse_file(mstr *file, parse_blk *pblk)
pblk->l_name = pblk->l_ext = base + pblk->b_dir;
pblk->b_esl = pblk->b_node + pblk->b_dir;
pblk->b_name = pblk->b_ext = 0;
pblk->fnb |= (hasnode << V_HAS_NODE);
pblk->fnb |= (1 << V_HAS_NODE);
return ERR_PARNORMAL;
}
/* Remove local node name from filename buffer */
Expand Down

0 comments on commit d2d3557

Please sign in to comment.