diff options
author | Steve Dickson <steved@redhat.com> | 2021-02-09 14:49:30 -0500 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2021-02-18 17:38:28 -0500 |
commit | bb0d6c1e78b736052173a9c827329f2bc3487046 (patch) | |
tree | c2a2e1fed85811ba77f12dfb849c0673589df01d /support/export | |
parent | 4de39cf12119f4e2c81421d55e5cbface816e3f9 (diff) | |
download | nfs-utils-bb0d6c1e78b736052173a9c827329f2bc3487046.tar.gz |
exportd: Enabled junction support
Moved the junction support from mountd to libexport.a
so both exportd and mountd can use the code.
Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'support/export')
-rw-r--r-- | support/export/Makefile.am | 2 | ||||
-rw-r--r-- | support/export/fsloc.c | 203 |
2 files changed, 204 insertions, 1 deletions
diff --git a/support/export/Makefile.am b/support/export/Makefile.am index 7de82a8..a9e710c 100644 --- a/support/export/Makefile.am +++ b/support/export/Makefile.am @@ -12,7 +12,7 @@ EXTRA_DIST = mount.x noinst_LIBRARIES = libexport.a libexport_a_SOURCES = client.c export.c hostname.c \ xtab.c mount_clnt.c mount_xdr.c \ - cache.c auth.c v4root.c + cache.c auth.c v4root.c fsloc.c BUILT_SOURCES = $(GENFILES) noinst_HEADERS = mount.h diff --git a/support/export/fsloc.c b/support/export/fsloc.c new file mode 100644 index 0000000..1b869b6 --- /dev/null +++ b/support/export/fsloc.c @@ -0,0 +1,203 @@ +/* + * COPYRIGHT (c) 2006 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * Permission is granted to use, copy, create derivative works + * and redistribute this software and such derivative works + * for any purpose, so long as the name of The University of + * Michigan is not used in any advertising or publicity + * pertaining to the use of distribution of this software + * without specific, written prior authorization. If the + * above copyright notice or any other identification of the + * University of Michigan is included in any copy of any + * portion of this software, then the disclaimer below must + * also be included. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +#include <stdlib.h> +#include <string.h> +#include <syslog.h> + +#include "fsloc.h" +#include "exportfs.h" + +/* Debugging tool: prints out @servers info to syslog */ +static void replicas_print(struct servers *sp) +{ + int i; + if (!sp) { + xlog(L_NOTICE, "NULL replicas pointer"); + return; + } + xlog(L_NOTICE, "replicas listsize=%i", sp->h_num); + for (i=0; i<sp->h_num; i++) { + xlog(L_NOTICE, " %s:%s", + sp->h_mp[i]->h_host, sp->h_mp[i]->h_path); + } +} + +#ifdef DEBUG +/* Called by setting 'Method = stub' in config file. Just returns + * some syntactically correct gibberish for testing purposes. + */ +static struct servers *method_stub(char *key) +{ + struct servers *sp; + struct mount_point *mp; + + xlog(L_NOTICE, "called method_stub\n"); + sp = malloc(sizeof(struct servers)); + if (!sp) + return NULL; + mp = calloc(1, sizeof(struct mount_point)); + if (!mp) { + free(sp); + return NULL; + } + sp->h_num = 1; + sp->h_mp[0] = mp; + mp->h_host = strdup("stub_server"); + mp->h_path = strdup("/my/test/path"); + sp->h_referral = 1; + return sp; +} +#endif /* DEBUG */ + +/* Scan @list, which is a NULL-terminated array of strings of the + * form path@host[+host], and return corresponding servers structure. + */ +static struct servers *parse_list(char **list) +{ + int i; + struct servers *res; + struct mount_point *mp; + char *cp; + + res = malloc(sizeof(struct servers)); + if (!res) + return NULL; + res->h_num = 0; + + /* parse each of the answers in sucession. */ + for (i=0; list[i] && i<FSLOC_MAX_LIST; i++) { + mp = calloc(1, sizeof(struct mount_point)); + if (!mp) { + release_replicas(res); + return NULL; + } + cp = strchr(list[i], '@'); + if ((!cp) || list[i][0] != '/') { + xlog(L_WARNING, "invalid entry '%s'", list[i]); + free(mp); + continue; /* XXX Need better error handling */ + } + res->h_mp[i] = mp; + res->h_num++; + mp->h_path = strndup(list[i], cp - list[i]); + cp++; + mp->h_host = strdup(cp); + /* hosts are '+' separated, kernel expects ':' separated */ + while ( (cp = strchr(mp->h_host, '+')) ) + *cp = ':'; + } + return res; +} + +/* @data is a string of form path@host[+host][:path@host[+host]] + */ +static struct servers *method_list(char *data) +{ + char *copy, *ptr=data, *p; + char **list; + int i, listsize; + struct servers *rv=NULL; + bool v6esc = false; + + xlog(L_NOTICE, "method_list(%s)", data); + for (ptr--, listsize=1; ptr; ptr=strchr(ptr, ':'), listsize++) + ptr++; + list = malloc(listsize * sizeof(char *)); + copy = strdup(data); + if (copy) + xlog(L_NOTICE, "converted to %s", copy); + if (list && copy) { + ptr = copy; + for (p = ptr, i = 0; *p && i < listsize; p++) { + if (*p == '[') + v6esc = true; + else if (*p == ']') + v6esc = false; + + if (!v6esc && *p == ':') { + *p = '\0'; + if (*ptr) + list[i++] = ptr; + ptr = p + 1; + } + } + if (*ptr) + list[i++] = ptr; + list[i] = NULL; + rv = parse_list(list); + } + free(copy); + free(list); + replicas_print(rv); + return rv; +} + +/* Returns appropriately filled struct servers, or NULL if had a problem */ +struct servers *replicas_lookup(int method, char *data) +{ + struct servers *sp=NULL; + switch(method) { + case FSLOC_NONE: + break; + case FSLOC_REFER: + sp = method_list(data); + if (sp) + sp->h_referral = 1; + break; + case FSLOC_REPLICA: + sp = method_list(data); + if (sp) + sp->h_referral = 0; + break; +#ifdef DEBUG + case FSLOC_STUB: + sp = method_stub(data); + break; +#endif + default: + xlog(L_WARNING, "Unknown method = %i", method); + } + replicas_print(sp); + return sp; +} + +void release_replicas(struct servers *server) +{ + int i; + + if (!server) return; + for (i = 0; i < server->h_num; i++) { + free(server->h_mp[i]->h_host); + free(server->h_mp[i]->h_path); + free(server->h_mp[i]); + } + free(server); +} |