From acedaf0ec3e2cfed966d7d0c48fa760c12807169 Mon Sep 17 00:00:00 2001 From: Stephen Lane-Walsh Date: Mon, 30 Jan 2023 18:52:16 -0500 Subject: [PATCH 1/2] Fix failure to get/set shot id with :: at end of path When getting/setting the current shot with a multi-part tree path that ends with ::, we currently fail to traverse the list of paths. For example: ``` $ export "cmod_path=/tmp;alcdata-new::" $ mdstcl show current cmod Connect failed to host: /tmp;alcdata-new Failed to get shotid. ``` This commit allows traversal of the list of paths, so this now works: ``` $ export "cmod_path=/tmp;alcdata-new::" $ mdstcl show current cmod Current shot is 1170112002 ``` If there is a more standard way to traverse the list of paths, I would love to use it. --- treeshr/TreeGetSetShotId.c | 248 ++++++++++++++++++++----------------- treeshr/treeshrp.h | 1 + 2 files changed, 138 insertions(+), 111 deletions(-) diff --git a/treeshr/TreeGetSetShotId.c b/treeshr/TreeGetSetShotId.c index 2e45aa4009..8552631eec 100644 --- a/treeshr/TreeGetSetShotId.c +++ b/treeshr/TreeGetSetShotId.c @@ -56,6 +56,7 @@ int TreeGetCurrentShotId(experiment,shot) #include #include #include +#include #include #include #include @@ -65,81 +66,74 @@ extern char *MaskReplace(); extern char *TreePath(); -static char *GetFileName(char *experiment, char **ctx) +static char * PathToFileName(const char * experiment, char * path) { - char *ans = 0; - static char pathname[1024]; - static char *path; - char *semi = 0; - char *part; - if (*ctx == NULL) + static char filename[1024]; + char * tmp = MaskReplace(path, experiment, 0); + strcpy(filename, tmp); + free(tmp); + + if (filename[strlen(filename) - 1] == '+') { - if (path != NULL) - free(path); - path = TreePath(experiment, NULL); - part = path; + size_t i; + for (i = strlen(filename); (i > 0) && (filename[i - 1] != TREE_PATH_DELIM[0]); i--) + ; + if (i > 0) + filename[i] = 0; } - else if (*ctx == pathname) - return NULL; else - part = *ctx; - if (part != NULL) { - char *delim = TREE_PATH_DELIM; - char *tmp; - if ((semi = strchr(part, ';')) != 0) - *semi = '\0'; - strncpy(pathname, part, 500); - if (semi == 0) - *ctx = pathname; - else - *ctx = part + strlen(part) + 1; - tmp = MaskReplace(pathname, experiment, 0); - strcpy(pathname, tmp); - free(tmp); - if (pathname[strlen(pathname) - 1] == '+') - { - size_t i; - for (i = strlen(pathname); (i > 0) && (pathname[i - 1] != delim[0]); i--) - ; - if (i > 0) - pathname[i] = 0; - } - else - { - if (pathname[strlen(pathname) - 1] != delim[0]) - strcat(pathname, TREE_PATH_DELIM); - } - strcat(pathname, "shotid.sys"); - ans = pathname; + if (filename[strlen(filename) - 1] != TREE_PATH_DELIM[0]) + strcat(filename, TREE_PATH_DELIM); } - return ans; + strcat(filename, "shotid.sys"); + + return filename; } -static int CreateShotIdFile(char *experiment) +int ReadShotId(int fd, int * shot) { - int fd = -1; - char *ctx = 0; - char *filename; - while ((fd == -1) && (filename = GetFileName(experiment, &ctx))) - fd = MDS_IO_OPEN(filename, O_RDWR | O_CREAT | O_TRUNC, 0664); - return fd; + int status = TreeFAILURE; + + if (fd != -1) + { + status = MDS_IO_READ(fd, shot, sizeof(*shot)) == sizeof(*shot); + MDS_IO_CLOSE(fd); +#ifdef WORDS_BIGENDIAN + if (STATUS_OK) + { + int lshot = shot; + int i; + char *optr = (char *)shot; + char *iptr = (char *)lshot; + for (i = 0; i < 4; i++) + optr[i] = iptr[3 - i]; + } +#endif + } + + return status; } -static int OpenShotIdFile(char *experiment, int mode) +int WriteShotId(int fd, int shot) { - int fd = -1; - char *ctx = 0; - char *filename; - int found = 0; - while ((filename = GetFileName(experiment, &ctx)) && - !(found = (MDS_IO_EXISTS(filename)))) - ; - if (found) - fd = MDS_IO_OPEN(filename, mode, 0); - else if (mode == O_WRONLY) - fd = CreateShotIdFile(experiment); - return fd; + int status = TreeFAILURE; + + if (fd != -1) + { + int lshot = shot; +#ifdef WORDS_BIGENDIAN + int i; + char *optr = (char *)&lshot; + char *iptr = (char *)&shot; + for (i = 0; i < 4; i++) + optr[i] = iptr[3 - i]; +#endif + status = MDS_IO_WRITE(fd, &lshot, sizeof(shot)) == sizeof(shot); + MDS_IO_CLOSE(fd); + } + + return status; } int TreeGetCurrentShotId(char const *experiment) @@ -147,36 +141,36 @@ int TreeGetCurrentShotId(char const *experiment) int shot = 0; int status = TreeFAILURE; char exp[16] = {0}; - char *path = TreePath(experiment, exp); size_t slen; - if (path && ((slen = strlen(path)) > 2) && (path[slen - 1] == ':') && - (path[slen - 2] == ':')) - { - path[slen - 2] = 0; - status = TreeGetCurrentShotIdRemote(exp, path, &shot); - } - else - { - int fd = OpenShotIdFile(exp, O_RDONLY); - if (fd != -1) + char * pathlist = TreePath(experiment, exp); + char * filename; + char * saveptr = NULL; + char * path = strtok_r(pathlist, TREE_PATH_LIST_DELIM, &saveptr); + while (path) { + slen = strlen(path); + bool thick = (slen > 2) && (path[slen - 1] == ':') && (path[slen - 2] == ':'); + if (thick) { - status = MDS_IO_READ(fd, &shot, sizeof(shot)) == sizeof(shot); - MDS_IO_CLOSE(fd); -#ifdef WORDS_BIGENDIAN - if (STATUS_OK) - { - int lshot = shot; - int i; - char *optr = (char *)&shot; - char *iptr = (char *)&lshot; - for (i = 0; i < 4; i++) - optr[i] = iptr[3 - i]; + path[slen - 2] = 0; + status = TreeGetCurrentShotIdRemote(exp, path, &shot); + } + else + { + filename = PathToFileName(experiment, path); + + if (MDS_IO_EXISTS(filename)) { + int fd = MDS_IO_OPEN(filename, O_RDONLY, 0); + status = ReadShotId(fd, &shot); } -#endif } + + if (STATUS_OK) { + break; + } + + path = strtok_r(NULL, TREE_PATH_LIST_DELIM, &saveptr); } - if (path) - free(path); + free(pathlist); return STATUS_OK ? shot : 0; } @@ -184,32 +178,64 @@ int TreeSetCurrentShotId(char const *experiment, int shot) { int status = TreeFAILURE; char exp[16] = {0}; - char *path = TreePath(experiment, exp); size_t slen; - if (path && ((slen = strlen(path)) > 2) && (path[slen - 1] == ':') && - (path[slen - 2] == ':')) - { - path[slen - 2] = 0; - status = TreeSetCurrentShotIdRemote(exp, path, shot); - } - else - { - int fd = OpenShotIdFile(exp, O_WRONLY); - if (fd != -1) + char * pathlist = TreePath(experiment, exp); + char * filename; + char * saveptr = NULL; + char * path = strtok_r(pathlist, TREE_PATH_LIST_DELIM, &saveptr); + while (path) { + slen = strlen(path); + bool thick = (slen > 2) && (path[slen - 1] == ':') && (path[slen - 2] == ':'); + if (thick) { - int lshot = shot; -#ifdef WORDS_BIGENDIAN - int i; - char *optr = (char *)&lshot; - char *iptr = (char *)&shot; - for (i = 0; i < 4; i++) - optr[i] = iptr[3 - i]; -#endif - status = MDS_IO_WRITE(fd, &lshot, sizeof(shot)) == sizeof(shot); - MDS_IO_CLOSE(fd); + path[slen - 2] = 0; + status = TreeSetCurrentShotIdRemote(exp, path, shot); + } + else + { + filename = PathToFileName(experiment, path); + + if (MDS_IO_EXISTS(filename)) { + int fd = MDS_IO_OPEN(filename, O_WRONLY, 0); + status = WriteShotId(fd, shot); + } + } + + if (STATUS_OK) { + break; } + + path = strtok_r(NULL, TREE_PATH_LIST_DELIM, &saveptr); } - if (path) - free(path); + free(pathlist); + + // (slw) NOTE: This will potentially create a shotid.sys on a remote host even if + // there is one further down the path, recommend only putting thick client at the end + // of tree paths + if (STATUS_NOT_OK) { + pathlist = TreePath(experiment, exp); + saveptr = NULL; + path = strtok_r(pathlist, TREE_PATH_LIST_DELIM, &saveptr); + while (path) { + status = TreeFAILURE; + + slen = strlen(path); + bool thick = (slen > 2) && (path[slen - 1] == ':') && (path[slen - 2] == ':'); + if (!thick) { + filename = PathToFileName(experiment, path); + + int fd = MDS_IO_OPEN(filename, O_RDWR | O_CREAT | O_TRUNC, 0664); + status = WriteShotId(fd, shot); + } + + if (STATUS_OK) { + break; + } + + path = strtok_r(NULL, TREE_PATH_LIST_DELIM, &saveptr); + } + free(pathlist); + } + return status; } diff --git a/treeshr/treeshrp.h b/treeshr/treeshrp.h index 79c52e2951..80573017b3 100644 --- a/treeshr/treeshrp.h +++ b/treeshr/treeshrp.h @@ -839,6 +839,7 @@ to databases #define TREE_PATH_SUFFIX "_path" #define TREE_DEFAULT_PATH "default_tree_path" #define TREE_PATH_DELIM "/" +#define TREE_PATH_LIST_DELIM ";" /************* Prototypes for internal functions *************/ extern int ConnectTreeRemote(PINO_DATABASE *dblist, char const *tree, From 084d687a11fb3746784d538f52e75ebb5f45f9da Mon Sep 17 00:00:00 2001 From: Stephen Lane-Walsh Date: Wed, 1 Feb 2023 16:25:32 -0500 Subject: [PATCH 2/2] Feedback from Josh --- treeshr/TreeGetSetShotId.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/treeshr/TreeGetSetShotId.c b/treeshr/TreeGetSetShotId.c index 8552631eec..722006c8ec 100644 --- a/treeshr/TreeGetSetShotId.c +++ b/treeshr/TreeGetSetShotId.c @@ -73,6 +73,7 @@ static char * PathToFileName(const char * experiment, char * path) strcpy(filename, tmp); free(tmp); + // (slwalsh, jas, fsantoro) NOTE: We have no idea if this is even used anymore, possibly remove? if (filename[strlen(filename) - 1] == '+') { size_t i; @@ -91,15 +92,15 @@ static char * PathToFileName(const char * experiment, char * path) return filename; } -int ReadShotId(int fd, int * shot) +int ReadShotId(char * filename, int * shot) { int status = TreeFAILURE; - - if (fd != -1) - { + + int fd = MDS_IO_OPEN(filename, O_RDONLY, 0); + if (fd != -1) { status = MDS_IO_READ(fd, shot, sizeof(*shot)) == sizeof(*shot); MDS_IO_CLOSE(fd); -#ifdef WORDS_BIGENDIAN + #ifdef WORDS_BIGENDIAN if (STATUS_OK) { int lshot = shot; @@ -109,26 +110,26 @@ int ReadShotId(int fd, int * shot) for (i = 0; i < 4; i++) optr[i] = iptr[3 - i]; } -#endif + #endif } return status; } -int WriteShotId(int fd, int shot) +int WriteShotId(char * filename, int shot, int mode) { int status = TreeFAILURE; - - if (fd != -1) - { + + int fd = MDS_IO_OPEN(filename, mode, 0664); + if (fd != -1) { int lshot = shot; -#ifdef WORDS_BIGENDIAN + #ifdef WORDS_BIGENDIAN int i; char *optr = (char *)&lshot; char *iptr = (char *)&shot; for (i = 0; i < 4; i++) optr[i] = iptr[3 - i]; -#endif + #endif status = MDS_IO_WRITE(fd, &lshot, sizeof(shot)) == sizeof(shot); MDS_IO_CLOSE(fd); } @@ -159,8 +160,7 @@ int TreeGetCurrentShotId(char const *experiment) filename = PathToFileName(experiment, path); if (MDS_IO_EXISTS(filename)) { - int fd = MDS_IO_OPEN(filename, O_RDONLY, 0); - status = ReadShotId(fd, &shot); + status = ReadShotId(filename, &shot); } } @@ -196,8 +196,7 @@ int TreeSetCurrentShotId(char const *experiment, int shot) filename = PathToFileName(experiment, path); if (MDS_IO_EXISTS(filename)) { - int fd = MDS_IO_OPEN(filename, O_WRONLY, 0); - status = WriteShotId(fd, shot); + status = WriteShotId(filename, shot, O_WRONLY); } } @@ -209,9 +208,9 @@ int TreeSetCurrentShotId(char const *experiment, int shot) } free(pathlist); - // (slw) NOTE: This will potentially create a shotid.sys on a remote host even if + // (slwalsh) NOTE: This will potentially create a shotid.sys on a remote host even if // there is one further down the path, recommend only putting thick client at the end - // of tree paths + // of tree paths. if (STATUS_NOT_OK) { pathlist = TreePath(experiment, exp); saveptr = NULL; @@ -224,8 +223,7 @@ int TreeSetCurrentShotId(char const *experiment, int shot) if (!thick) { filename = PathToFileName(experiment, path); - int fd = MDS_IO_OPEN(filename, O_RDWR | O_CREAT | O_TRUNC, 0664); - status = WriteShotId(fd, shot); + status = WriteShotId(filename, shot, O_RDWR | O_CREAT | O_TRUNC); } if (STATUS_OK) {