/* * util_parse_add_remote_replica -- (internal) add a new remote replica * to the pool set info */ static int util_parse_add_remote_replica(struct pool_set **setp, char *node_addr, char *pool_desc) { LOG(3, "setp %p node_addr %s pool_desc %s", setp, node_addr, pool_desc); ASSERTne(setp, NULL); ASSERTne(node_addr, NULL); ASSERTne(pool_desc, NULL); int ret = util_parse_add_replica(setp); if (ret != 0) return ret; /* a remote replica has one 'fake' part */ ret = util_parse_add_part(*setp, NULL, 0); if (ret != 0) return ret; struct pool_set *set = *setp; struct pool_replica *rep = set->replica[set->nreplicas - 1]; ASSERTne(rep, NULL); rep->remote = Zalloc(sizeof(struct remote_replica)); if (rep->remote == NULL) { ERR("!Malloc"); return -1; } rep->remote->node_addr = node_addr; rep->remote->pool_desc = pool_desc; set->remote = 1; return 0; }
/* * util_poolset_parse -- (internal) parse pool set config file * * Returns 1 if the file is a valid pool set config file, 0 if the file * is not a pool set header, and -1 in case of any error. * * XXX: use memory mapped file */ int util_poolset_parse(const char *path, int fd, struct pool_set **setp) { LOG(3, "path %s fd %d setp %p", path, fd, setp); struct pool_set *set; enum parser_codes result; char line[PARSER_MAX_LINE]; char *s; char *ppath; char *cp; size_t psize; FILE *fs; if (lseek(fd, 0, SEEK_SET) != 0) { ERR("!lseek %d", fd); return -1; } fd = dup(fd); if (fd < 0) { ERR("!dup"); return -1; } /* associate a stream with the file descriptor */ if ((fs = fdopen(fd, "r")) == NULL) { ERR("!fdopen %d", fd); close(fd); return -1; } unsigned nlines = 0; unsigned nparts = 0; /* number of parts in current replica */ /* read the first line */ s = fgets(line, PARSER_MAX_LINE, fs); nlines++; set = Malloc(sizeof (struct pool_set)); if (set == NULL) { ERR("!Malloc for pool set"); goto err; } set->nreplicas = 0; set->poolsize = 0; /* check also if the last character is '\n' */ if (s && strncmp(line, POOLSET_HDR_SIG, POOLSET_HDR_SIG_LEN) == 0 && line[POOLSET_HDR_SIG_LEN] == '\n') { /* 'PMEMPOOLSET' signature detected */ LOG(10, "PMEMPOOLSET"); int ret = util_parse_add_replica(&set); if (ret != 0) goto err; nparts = 0; result = PARSER_CONTINUE; } else { result = PARSER_PMEMPOOLSET; } while (result == PARSER_CONTINUE) { /* read next line */ s = fgets(line, PARSER_MAX_LINE, fs); nlines++; if (s) { /* chop off newline and comments */ if ((cp = strchr(line, '\n')) != NULL) *cp = '\0'; if (cp != s && (cp = strchr(line, '#')) != NULL) *cp = '\0'; /* skip comments and blank lines */ if (cp == s) continue; } if (!s) { if (nparts >= 1) { result = PARSER_FORMAT_OK; } else { if (set->nreplicas == 1) result = PARSER_SET_NO_PARTS; else result = PARSER_REP_NO_PARTS; } } else if (strncmp(line, POOLSET_REPLICA_SIG, POOLSET_REPLICA_SIG_LEN) == 0) { if (line[POOLSET_REPLICA_SIG_LEN] != '\0') { /* something more than 'REPLICA' */ result = PARSER_REPLICA; } else if (nparts >= 1) { /* 'REPLICA' signature detected */ LOG(10, "REPLICA"); int ret = util_parse_add_replica(&set); if (ret != 0) goto err; nparts = 0; result = PARSER_CONTINUE; } else { if (set->nreplicas == 1) result = PARSER_SET_NO_PARTS; else result = PARSER_REP_NO_PARTS; } } else { /* read size and path */ result = parser_read_line(line, &psize, &ppath); if (result == PARSER_CONTINUE) { /* add a new pool's part to the list */ int ret = util_parse_add_part(set, ppath, psize); if (ret != 0) goto err; nparts++; } } } if (result == PARSER_FORMAT_OK) { LOG(4, "set file format correct (%s)", path); (void) fclose(fs); *setp = set; return 0; } else { ERR("%s [%s:%d]", path, parser_errstr[result], nlines); } err: (void) fclose(fs); if (set) util_poolset_free(set); return -1; }