@@ -262,7 +262,7 @@ dn: fedfsFslUuid=323c5068-7c11-11e0-8d38-000c297fd679,
.br
FSL UUID: 323c5068-7c11-11e0-8d38-000c297fd679
.br
- FSL host: fileserver.example.net
+ NFS fls_server: fileserver.example.net
.sp
NFS fli_rootpath: /path
.br
@@ -695,9 +695,11 @@ fedfsd_fill_in_fedfsfsl(const struct fedfs_fsl *fsl, FedFsFsl *new)
}
memcpy(new->FedFsFsl_u.nfsFsl.fslUuid, &uu, sizeof(uu));
- new->FedFsFsl_u.nfsFsl.port = fsl->fl_fslport;
- new->FedFsFsl_u.nfsFsl.hostname.utf8string_len = strlen(fsl->fl_fslhost);
- new->FedFsFsl_u.nfsFsl.hostname.utf8string_val = strdup(fsl->fl_fslhost);
+ new->FedFsFsl_u.nfsFsl.port = fsl->fl_u.fl_nfsfsl.fn_fslport;
+ new->FedFsFsl_u.nfsFsl.hostname.utf8string_len =
+ strlen(fsl->fl_u.fl_nfsfsl.fn_fslhost);
+ new->FedFsFsl_u.nfsFsl.hostname.utf8string_val =
+ strdup(fsl->fl_u.fl_nfsfsl.fn_fslhost);
if (new->FedFsFsl_u.nfsFsl.hostname.utf8string_val == NULL) {
xlog(D_GENERAL, "%s: Failed to allocate hostname", __func__);
goto out_free;
@@ -80,6 +80,8 @@ void nsdb_free_fedfs_fsn(struct fedfs_fsn *fsn);
* the NSDB protocol draft, chapter 4, section 2.2.4
*/
struct fedfs_nfs_fsl {
+ char fn_fslhost[NI_MAXHOST + 1];
+ int fn_fslport;
char **fn_nfspath;
int fn_currency;
_Bool fn_gen_writable;
@@ -112,8 +114,6 @@ struct fedfs_fsl {
char fl_fsluuid[FEDFS_UUID_STRLEN];
char fl_fsnuuid[FEDFS_UUID_STRLEN];
- char fl_fslhost[NI_MAXHOST + 1];
- int fl_fslport;
char **fl_annotations;
char **fl_description;
@@ -613,6 +613,85 @@ nsdb_construct_fsl_dn(const char *nce, const char *fsn_uuid, const char *fsl_uui
return dn;
}
+/**
+ * Build a UriUriA for the location information in "nfsfsl"
+ *
+ * @param nfsfsl an initialized struct fedfs_nfs_fsl
+ * @param uri OUT: a filled-in UriUriA object
+ * @return a FedFsStatus code
+ *
+ * Caller must free the members of the UriUriA object with
+ * uriFreeUriMembersA().
+ */
+static FedFsStatus
+nsdb_nfsfsl_to_uri(const struct fedfs_nfs_fsl *nfsfsl, UriUriA *uri)
+{
+ memset(uri, 0, sizeof(*uri));
+
+ nsdb_assign_textrange(&uri->scheme, "nfs");
+ nsdb_assign_textrange(&uri->hostText, nfsfsl->fn_fslhost);
+ if (nfsfsl->fn_fslport != 2049 && nfsfsl->fn_fslport != 0) {
+ char portbuf[8];
+ sprintf(portbuf, "%u", nfsfsl->fn_fslport);
+ nsdb_assign_textrange(&uri->portText, portbuf);
+ }
+
+ return nsdb_path_array_to_uri_pathname(nfsfsl->fn_nfspath, uri);
+}
+
+/**
+ * Construct an NFS URI for this location
+ *
+ * @param nfsfsl an initialized struct fedfs_nfs_fsl
+ * @param nfsuri OUT: a NUL-terminated C string containing an NFS URI
+ * @return a FedFsStatus code
+ *
+ * Caller must free "nfsuri" with free(3).
+ */
+static FedFsStatus
+nsdb_construct_nfsuri(const struct fedfs_nfs_fsl *nfsfsl, char **nfsuri)
+{
+ FedFsStatus retval;
+ char *result;
+ int len, err;
+ UriUriA uri;
+
+ retval = nsdb_nfsfsl_to_uri(nfsfsl, &uri);
+ if (retval != FEDFS_OK)
+ return retval;
+
+ retval = FEDFS_ERR_SVRFAULT;
+ err = uriToStringCharsRequiredA(&uri, &len);
+ if (err != URI_SUCCESS) {
+ xlog(D_GENERAL, "%s: uriToStringCharsRequired failed: %d",
+ __func__, err);
+ goto out;
+ }
+ len++;
+
+ result = (char *)calloc(len, sizeof(char));
+ if (result == NULL) {
+ xlog(D_GENERAL, "%s calloc failed", __func__);
+ goto out;
+ }
+
+ err = uriToStringA(result, &uri, len, NULL);
+ if (err != URI_SUCCESS) {
+ xlog(D_GENERAL, "%s uriToStringA failed: %d",
+ __func__, err);
+ free(result);
+ goto out;
+ }
+
+ xlog(D_CALL, "%s: NFS URI: %s", __func__, result);
+ *nfsuri = result;
+ retval = FEDFS_OK;
+
+out:
+ uriFreeUriMembersA(&uri);
+ return retval;
+}
+
static const char *nsdb_ldap_true = "TRUE";
static const char *nsdb_ldap_false = "FALSE";
@@ -671,12 +750,11 @@ nsdb_create_nfs_fsl_entry_s(LDAP *ld, const char *nce, struct fedfs_fsl *fsl,
{
struct fedfs_nfs_fsl *nfsfsl = &fsl->fl_u.fl_nfsfsl;
char *ocvals[3], *fsluuidvals[2], *fsnuuidvals[2];
- char *servernamevals[2], *serverportvals[2], serverportbuf[12];
/* XXX: variables for encoding annotations and description
* attributes would go here */
- struct berval *xdrpathvals[2], xdr_path;
+ char *nfsurivals[2], *nfsuri = NULL;
char *currvals[2], currbuf[12];
char *flagwvals[2], *flaggvals[2], *flagsvals[2],
*flagrvals[2], *varsubvals[2];
@@ -710,22 +788,11 @@ nsdb_create_nfs_fsl_entry_s(LDAP *ld, const char *nce, struct fedfs_fsl *fsl,
fsluuidvals, fsl->fl_fsluuid);
nsdb_init_add_attribute(attrs[i++], "fedfsFsnUuid",
fsnuuidvals, fsl->fl_fsnuuid);
- nsdb_init_add_attribute(attrs[i++], "fedfsFslHost",
- servernamevals, fsl->fl_fslhost);
- if (fsl->fl_fslport != 0) {
- sprintf(serverportbuf, "%d", fsl->fl_fslport);
- nsdb_init_add_attribute(attrs[i++], "fedfsFslPort",
- serverportvals, serverportbuf);
- }
-
- retval = nsdb_path_array_to_xdr(nfsfsl->fn_nfspath, &xdr_path);
+ retval = nsdb_construct_nfsuri(nfsfsl, &nfsuri);
if (retval != FEDFS_OK)
- return retval;
- xdrpathvals[0] = &xdr_path;
- xdrpathvals[1] = NULL;
- attr[i].mod_op = LDAP_MOD_BVALUES;
- attr[i].mod_type = "fedfsNfsPath";
- attr[i++].mod_bvalues = xdrpathvals;
+ goto out;
+ nsdb_init_add_attribute(attrs[i++], "fedfsNfsURI",
+ nfsurivals, nfsuri);
sprintf(currbuf, "%d", nfsfsl->fn_currency);
nsdb_init_add_attribute(attrs[i++], "fedfsNfsCurrency",
@@ -802,7 +869,7 @@ nsdb_create_nfs_fsl_entry_s(LDAP *ld, const char *nce, struct fedfs_fsl *fsl,
retval = FEDFS_OK;
out:
- ber_memfree(xdr_path.bv_val);
+ free(nfsuri);
return retval;
}
@@ -1093,21 +1160,13 @@ nsdb_update_fsl_update_attribute_s(LDAP *ld, const char *dn,
struct berval newval;
FedFsStatus retval;
- if (strcasecmp(attribute, "fedfsNfsPath") == 0) {
- retval = nsdb_path_array_to_xdr((char * const *)value, &newval);
- if (retval != FEDFS_OK)
- return retval;
- } else {
- newval.bv_val = (char *)value;
- newval.bv_len = 0;
- if (value != NULL)
- newval.bv_len = (ber_len_t)strlen(value);
- }
+ newval.bv_val = (char *)value;
+ newval.bv_len = 0;
+ if (value != NULL)
+ newval.bv_len = (ber_len_t)strlen(value);
retval = nsdb_modify_attribute_s(ld, dn, attribute,
&newval, ldap_err);
- if (strcasecmp(attribute, "fedfsNfsPath") == 0)
- ber_memfree(newval.bv_val);
if (retval != FEDFS_OK)
return retval;
@@ -39,6 +39,8 @@
#include <unistd.h>
#include <netdb.h>
+#include <uriparser/Uri.h>
+
#include "nsdb.h"
#include "nsdb-internal.h"
#include "xlog.h"
@@ -720,6 +722,128 @@ nsdb_parse_annotations(struct berval **values, char ***annotations)
}
/**
+ * Unmarshal a parsed NFS URI object into an NFS FSL
+ *
+ * @param attr NUL-terminated C string containing LDAP attribute name
+ * @param uri a filled-in UriUriA structure
+ * @param nfsl OUT: fedfs_nfs_fsl structure to fill in
+ * @return a FedFsStatus code
+ *
+ * @todo i18n hostname
+ */
+static FedFsStatus
+nsdb_parse_nfs_uri_fsl(const char *attr, UriUriA *uri,
+ struct fedfs_nfs_fsl *nfsl)
+{
+ unsigned short port;
+ FedFsStatus retval;
+ char **pathname;
+ size_t len;
+
+ retval = FEDFS_ERR_NSDB_RESPONSE;
+
+ if ((uri->scheme.first == NULL) ||
+ (uri->scheme.afterLast != uri->scheme.first + 3) ||
+ (strncmp(uri->scheme.first, "nfs", 3) != 0)) {
+ xlog(L_ERROR, "%s: Attribute %s does not contain an NFS URI",
+ __func__, attr);
+ goto out;
+ }
+
+ if ((uri->hostText.first == NULL) ||
+ (uri->hostText.afterLast <= uri->hostText.first)) {
+ xlog(L_ERROR, "%s: NFS URI has no hostname",
+ __func__);
+ goto out;
+ }
+ len = uri->hostText.afterLast - uri->hostText.first;
+ if (len > sizeof(nfsl->fn_fslhost)) {
+ xlog(L_ERROR, "%s: NFS URI hostname too large",
+ __func__);
+ goto out;
+ }
+
+ port = 0;
+ if ((uri->portText.first != NULL) &&
+ (uri->portText.afterLast > uri->portText.first)) {
+ char string[16];
+ size_t portlen;
+
+ portlen = uri->portText.afterLast - uri->portText.first;
+ if (portlen > sizeof(string)) {
+ xlog(L_ERROR, "%s: NFS URI has invalid port",
+ __func__, attr);
+ goto out;
+ }
+ string[0] = '\0';
+ strncat(string, uri->portText.first, portlen);
+ if (!nsdb_parse_port_string(string, &port)) {
+ xlog(L_ERROR, "%s: NFS URI has invalid port",
+ __func__, attr);
+ goto out;
+ }
+ }
+
+ retval = nsdb_uri_pathname_to_path_array(uri, &pathname);
+ if (retval != FEDFS_OK)
+ goto out;
+
+ xlog(D_CALL, "%s: NFS URI successfully parsed", __func__);
+
+ strncpy(nfsl->fn_fslhost, uri->hostText.first, len);
+ nfsl->fn_fslport = port;
+ nfsl->fn_nfspath = pathname;
+ retval = FEDFS_OK;
+
+out:
+ return retval;
+}
+
+/**
+ * Parse an NFS URI into a hostname and pathname
+ *
+ * @param attr NUL-terminated C string containing LDAP attribute name
+ * @param values URI string value returned from LDAP server
+ * @param nfsl OUT: fedfs_nfs_fsl structure to fill in
+ * @return a FedFsStatus code
+ */
+static FedFsStatus
+nsdb_parse_nfs_uri(const char *attr, struct berval **values,
+ struct fedfs_nfs_fsl *nfsl)
+{
+ UriUriA uri;
+ UriParserStateA state = {
+ .uri = &uri,
+ };
+ FedFsStatus retval;
+
+ retval = FEDFS_ERR_NSDB_RESPONSE;
+
+ if (values[0] == NULL) {
+ xlog(L_ERROR, "%s: NULL value for attribute %s",
+ __func__, attr);
+ return retval;
+ }
+ if (values[1] != NULL) {
+ xlog(L_ERROR, "%s: Expecting only one value for attribute %s",
+ __func__, attr);
+ return retval;
+ }
+
+ if (uriParseUriA(&state, (char *)values[0]->bv_val) != URI_SUCCESS) {
+ xlog(L_ERROR, "%s: Failed to parse NFS URI", __func__);
+ goto out;
+ }
+
+ xlog(D_CALL, "%s: parsing '%s'", __func__, (char *)values[0]->bv_val);
+ retval = nsdb_parse_nfs_uri_fsl(attr, &uri, nfsl);
+
+out:
+ uriFreeUriMembersA(&uri);
+ return retval;
+}
+
+/**
* Parse the values of each attribute in a fedfsFsl object
*
* @param ld an initialized LDAP server descriptor
@@ -751,12 +875,6 @@ nsdb_resolve_fsn_parse_attribute(LDAP *ld, LDAPMessage *entry, char *attr,
else if (strcasecmp(attr, "fedfsFsnUuid") == 0)
retval = nsdb_parse_singlevalue_str(attr, values,
fsl->fl_fsnuuid, sizeof(fsl->fl_fsnuuid));
- else if (strcasecmp(attr, "fedfsFslHost") == 0)
- retval = nsdb_parse_singlevalue_str(attr, values,
- fsl->fl_fslhost, sizeof(fsl->fl_fslhost));
- else if (strcasecmp(attr, "fedfsFslPort") == 0)
- retval = nsdb_parse_singlevalue_int(attr, values,
- &fsl->fl_fslport);
else if (strcasecmp(attr, "fedfsAnnotation") == 0)
retval = nsdb_parse_annotations(values, &fsl->fl_annotations);
else if (strcasecmp(attr, "fedfsDescr") == 0)
@@ -765,9 +883,8 @@ nsdb_resolve_fsn_parse_attribute(LDAP *ld, LDAPMessage *entry, char *attr,
/* fedfsNfsFsl attributes */
- else if (strcasecmp(attr, "fedfsNfsPath") == 0)
- retval = nsdb_parse_singlevalue_xdrpath(attr, values,
- &nfsl->fn_nfspath);
+ else if (strcasecmp(attr, "fedfsNfsURI") == 0)
+ retval = nsdb_parse_nfs_uri(attr, values, nfsl);
else if (strcasecmp(attr, "fedfsNfsCurrency") == 0)
retval = nsdb_parse_singlevalue_int(attr, values,
&nfsl->fn_currency);
@@ -267,16 +267,22 @@ nfsref_add_create_fedfs_fsn(nsdb_t host, const char *nce, char **fsn_uuid)
/**
* Fill in default settings for NFSv4.0 fs_locations4
*
+ * @param server NUL-terminated C string containing fileserver hostname
* @param rootpath NUL-terminated C string containing POSIX-style export path
* @param new fedfs_fsl object to fill in
*
* See section 5.1.3.2 of the NSDB protocol draft.
*/
static FedFsStatus
-nfsref_add_nfs_fsl_defaults(const char *rootpath, struct fedfs_nfs_fsl *new)
+nfsref_add_nfs_fsl_defaults(const char *server, const char *rootpath,
+ struct fedfs_nfs_fsl *new)
{
FedFsStatus retval;
+ /* XXX: check the server hostname length */
+ strcpy(new->fn_fslhost, server);
+ new->fn_fslport = 0;
+
retval = nsdb_posix_to_path_array(rootpath, &new->fn_nfspath);
if (retval != FEDFS_OK)
return retval;
@@ -334,10 +340,8 @@ nfsref_add_build_fsl(const char *fsn_uuid, const char *server,
uuid_generate_random(uu);
uuid_unparse(uu, new->fl_fsluuid);
strncpy(new->fl_fsnuuid, fsn_uuid, sizeof(new->fl_fsnuuid));
- strncpy(new->fl_fslhost, server, sizeof(new->fl_fslhost));
- new->fl_fslport = 0;
- retval = nfsref_add_nfs_fsl_defaults(rootpath, &new->fl_u.fl_nfsfsl);
+ retval = nfsref_add_nfs_fsl_defaults(server, rootpath, &new->fl_u.fl_nfsfsl);
if (retval != FEDFS_OK)
return retval;
@@ -169,11 +169,14 @@ nfsref_lookup_display_fedfs_nfs_fsl(struct fedfs_nfs_fsl *nfsl)
{
char *rootpath;
+ printf("\tFileserver name:\t\t\t%s\n", nfsl->fn_fslhost);
+ printf("\tFileserver port:\t\t\t%u\n", nfsl->fn_fslport);
+
if (nsdb_path_array_to_posix(nfsl->fn_nfspath, &rootpath) == FEDFS_OK) {
- printf("\tfedfsNfsPath:\t\t\t%s\n", rootpath);
+ printf("\tExport path:\t\t\t%s\n", rootpath);
free(rootpath);
} else
- printf("\tfedfsNfsPath:\t\t\tInvalid\n");
+ printf("\tExport path:\t\t\tInvalid\n");
printf("\tfedfsNfsCurrency:\t\t%d\n", nfsl->fn_currency);
printf("\tfedfsNfsGenFlagWritable:\t%s\n",
@@ -213,8 +216,6 @@ nfsref_lookup_display_fedfs_fsl(struct fedfs_fsl *fsl)
printf("\tfedfsFslUuid:\t\t\t%s\n", fsl->fl_fsluuid);
printf("\tfedfsFsnUuid:\t\t\t%s\n", fsl->fl_fsnuuid);
- printf("\tfedfsFslHost:\t\t\t%s\n", fsl->fl_fslhost);
- printf("\tfedfsFslPort:\t\t\t%u\n", fsl->fl_fslport);
if (fsl->fl_annotations != NULL) {
for (i = 0; fsl->fl_annotations[i] != NULL; i++)
@@ -208,14 +208,21 @@ main(int argc, char **argv)
}
strcpy(fsl->fl_fsluuid, fsl_uuid);
strcpy(fsl->fl_fsnuuid, fsn_uuid);
- strcpy(fsl->fl_fslhost, servername);
+
+ retval = FEDFS_ERR_NAMETOOLONG;
+ if (strlen(servername) >= sizeof(fsl->fl_u.fl_nfsfsl.fn_fslhost)) {
+ fprintf(stderr, "Fileserver hostname too large\n");
+ goto out;
+ }
+ strcpy(fsl->fl_u.fl_nfsfsl.fn_fslhost, servername);
+
+ fsl->fl_u.fl_nfsfsl.fn_fslport = serverport;
retval = nsdb_posix_to_path_array(serverpath,
&fsl->fl_u.fl_nfsfsl.fn_nfspath);
if (retval != FEDFS_OK) {
fprintf(stderr, "Failed to encode serverpath\n");
goto out;
}
- fsl->fl_fslport = serverport;
retval = nsdb_lookup_nsdb(nsdbname, nsdbport, &host, NULL);
switch (retval) {
@@ -114,8 +114,16 @@ nsdb_resolve_fsn_display_nfs_fsl(struct fedfs_nfs_fsl *nfsl)
status = nsdb_path_array_to_posix(nfsl->fn_nfspath, &rootpath);
if (status != FEDFS_OK)
return;
+
+ if (nfsl->fn_fslport == 0)
+ printf(" NFS fls_server:\t\t%s\n", nfsl->fn_fslhost);
+ else
+ printf(" NFS fls_server:\t\t%s:%u\n", nfsl->fn_fslhost,
+ nfsl->fn_fslport);
+
printf(" NFS fli_rootpath:\t\t%s\n", rootpath);
free(rootpath);
+
printf(" NFS fls_currency:\t\t%d\n", nfsl->fn_currency);
printf(" NFS FSLI4GF_WRITABLE:\t\t%s\n", _display_bool(nfsl->fn_gen_writable));
printf(" NFS FSLI4GF_GOING:\t\t%s\n", _display_bool(nfsl->fn_gen_going));
@@ -152,10 +160,6 @@ nsdb_resolve_fsn_display_fsl(struct fedfs_fsl *fsl)
printf(" FSN UUID:\t\t%s\n", fsl->fl_fsnuuid);
printf(" FSL UUID:\t\t%s\n", fsl->fl_fsluuid);
- if (fsl->fl_fslport == 0)
- printf(" FSL host:\t\t%s\n", fsl->fl_fslhost);
- else
- printf(" FSL host:\t\t%s:%u\n", fsl->fl_fslhost, fsl->fl_fslport);
if (fsl->fl_annotations != NULL) {
for (i = 0; fsl->fl_annotations[i] != NULL; i++)
@@ -253,7 +253,8 @@ nfs_jp_convert_fedfs_fsl(struct fedfs_fsl *fsl, struct nfs_fsloc **fsloc)
return JP_MEMORY;
}
- new->nfl_hostname = strdup(fsl->fl_fslhost);
+ new->nfl_hostname = strdup(nfs_fsl->fn_fslhost);
+ new->nfl_hostport = nfs_fsl->fn_fslport;
new->nfl_rootpath = nfs_dup_string_array(nfs_fsl->fn_nfspath);
if (new->nfl_hostname == NULL || new->nfl_rootpath == NULL) {
nfs_free_location(new);
@@ -261,8 +262,6 @@ nfs_jp_convert_fedfs_fsl(struct fedfs_fsl *fsl, struct nfs_fsloc **fsloc)
return JP_MEMORY;
}
- new->nfl_hostport = fsl->fl_fslport;
-
new->nfl_flags.nfl_varsub = nfs_fsl->fn_varsub;
new->nfl_currency = nfs_fsl->fn_currency;
new->nfl_validfor = nfs_fsl->fn_validfor;
The latest NSDB schema moves the name and port of the fileserver host (fedfsFslHost and fedfsFslPort) to the NFS-specific section of the FSL, and combines them with the export pathname. The result is stored in a single labeledURI type attribute. We'll need to replace the logic that stores the pathname as an XDR blob on the NSDB with one that constructs an NFS URI. The logic that reads an XDR-encoded pathname and unmarshals it will have to read the URI and break it into its constituent components. Note: this commit adds a new library dependency to fedfs-utils: URI parsing is done via the open liburiparser library. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- doc/man/nsdb-resolve-fsn.8 | 2 - src/fedfsd/svc.c | 8 ++ src/include/nsdb.h | 4 + src/libnsdb/administrator.c | 119 ++++++++++++++++++++++++++++--------- src/libnsdb/fileserver.c | 135 +++++++++++++++++++++++++++++++++++++++--- src/nfsref/add.c | 12 ++-- src/nfsref/lookup.c | 9 ++- src/nsdbc/nsdb-create-fsl.c | 11 +++ src/nsdbc/nsdb-resolve-fsn.c | 12 ++-- src/plug-ins/nfs-plugin.c | 5 +- 10 files changed, 255 insertions(+), 62 deletions(-)