@@ -28,6 +28,7 @@
*
* <?xml version="1.0" encoding="UTF-8"?>
* <junction>
+ * <savedmode bits="1777" />
* <fileset>
* <name fsnuuid="d2b09895-98ff-415e-ac73-565fad7b429b"
* nsdbname="nsdb.example.net"
@@ -175,6 +176,38 @@ fedfs_fileset_xml(const char *pathname, xmlNodePtr root,
}
/**
+ * Construct a "savedmode" element
+ *
+ * @param pathname NUL-terminated C string containing pathname of a junction
+ * @param root root element of XML document tree
+ * @return a FedFsStatus code
+ */
+static FedFsStatus
+fedfs_savedmode_xml(const char *pathname, xmlNodePtr root)
+{
+ xmlNodePtr savedmode;
+ FedFsStatus retval;
+ mode_t mode;
+ char buf[8];
+
+ retval = junction_get_mode(pathname, &mode);
+ if (retval != FEDFS_OK)
+ return retval;
+
+ savedmode = xmlNewTextChild(root, NULL, JUNCTION_XML_SAVEDMODE_TAG, NULL);
+ if (savedmode == NULL) {
+ xlog(D_GENERAL, "%s: Failed to add savedmode element for %s\n",
+ __func__, pathname);
+ return FEDFS_ERR_SVRFAULT;
+ }
+
+ (void)snprintf(buf, sizeof(buf), "%o", ALLPERMS & mode);
+ xmlSetProp(savedmode, JUNCTION_XML_MODEBITS_ATTR, (const xmlChar *)buf);
+
+ return FEDFS_OK;
+}
+
+/**
* Construct FedFS junction XML document
*
* @param pathname NUL-terminated C string containing pathname of a junction
@@ -189,6 +222,7 @@ fedfs_build_xml(const char *pathname, xmlDocPtr doc,
const char *fsn_uuid, const char *nsdb_name,
unsigned short nsdb_port)
{
+ FedFsStatus retval;
xmlNodePtr root;
root = xmlNewNode(NULL, JUNCTION_XML_ROOT_TAG);
@@ -199,6 +233,10 @@ fedfs_build_xml(const char *pathname, xmlDocPtr doc,
}
(void)xmlDocSetRootElement(doc, root);
+ retval = fedfs_savedmode_xml(pathname, root);
+ if (retval != FEDFS_OK)
+ return retval;
+
return fedfs_fileset_xml(pathname, root, fsn_uuid, nsdb_name, nsdb_port);
}
@@ -58,6 +58,15 @@
*/
#define JUNCTION_XML_FILESET_TAG (const xmlChar *)"fileset"
+/**
+ * Tag name of savedmode element of a junction XML document
+ */
+#define JUNCTION_XML_SAVEDMODE_TAG (const xmlChar *)"savedmode"
+
+/**
+ * Name of mode bits attribute on a savedmode element
+ */
+#define JUNCTION_XML_MODEBITS_ATTR (const xmlChar *)"bits"
/**
** Junction helper functions
@@ -77,6 +86,7 @@ FedFsStatus junction_set_xattr(int fd, const char *path, const char *name,
const void *contents, const size_t contentlen);
FedFsStatus junction_remove_xattr(int fd, const char *pathname,
const char *name);
+FedFsStatus junction_get_mode(const char *pathname, mode_t *mode);
FedFsStatus junction_save_mode(const char *pathname);
FedFsStatus junction_restore_mode(const char *pathname);
@@ -374,18 +374,17 @@ junction_remove_xattr(int fd, const char *pathname, const char *name)
}
/**
- * Save the object's mode in an xattr. Saved mode is human-readable.
+ * Retrieve object's mode bits.
*
* @param pathname NUL-terminated C string containing pathname of a directory
+ * @param mode OUT: mode bits
* @return a FedFsStatus code
*/
FedFsStatus
-junction_save_mode(const char *pathname)
+junction_get_mode(const char *pathname, mode_t *mode)
{
FedFsStatus retval;
- unsigned int mode;
struct stat stb;
- char buf[16];
int fd;
retval = junction_open_path(pathname, &fd);
@@ -398,8 +397,38 @@ junction_save_mode(const char *pathname)
return FEDFS_ERR_ACCESS;
}
- mode = ALLPERMS & stb.st_mode;
- (void)snprintf(buf, sizeof(buf), "%o", mode);
+ (void)close(fd);
+
+ xlog(D_CALL, "%s: pathname %s has mode %o",
+ __func__, pathname, stb.st_mode);
+ *mode = stb.st_mode;
+ return FEDFS_OK;
+
+}
+
+/**
+ * Save the object's mode in an xattr. Saved mode is human-readable.
+ *
+ * @param pathname NUL-terminated C string containing pathname of a directory
+ * @return a FedFsStatus code
+ */
+FedFsStatus
+junction_save_mode(const char *pathname)
+{
+ FedFsStatus retval;
+ mode_t mode;
+ char buf[8];
+ int fd;
+
+ retval = junction_get_mode(pathname, &mode);
+ if (retval != FEDFS_OK)
+ return retval;
+ (void)snprintf(buf, sizeof(buf), "%o", ALLPERMS & mode);
+
+ retval = junction_open_path(pathname, &fd);
+ if (retval != FEDFS_OK)
+ return retval;
+
retval = junction_set_xattr(fd, pathname, JUNCTION_XATTR_NAME_MODE,
buf, strlen(buf));
if (retval != FEDFS_OK)
@@ -29,6 +29,7 @@
*
* <?xml version="1.0" encoding="UTF-8"?>
* <junction>
+ * <savedmode bits="1777" />
* <fileset>
* <location>
* <host name="fileserver.example.net" port="2049" />
@@ -708,6 +709,38 @@ nfs_fileset_xml(const char *pathname, xmlNodePtr root,
}
/**
+ * Construct a "savedmode" element
+ *
+ * @param pathname NUL-terminated C string containing pathname of a junction
+ * @param root root element of XML document tree
+ * @return a FedFsStatus code
+ */
+static FedFsStatus
+nfs_savedmode_xml(const char *pathname, xmlNodePtr root)
+{
+ xmlNodePtr savedmode;
+ FedFsStatus retval;
+ mode_t mode;
+ char buf[8];
+
+ retval = junction_get_mode(pathname, &mode);
+ if (retval != FEDFS_OK)
+ return retval;
+
+ savedmode = xmlNewTextChild(root, NULL, JUNCTION_XML_SAVEDMODE_TAG, NULL);
+ if (savedmode == NULL) {
+ xlog(D_GENERAL, "%s: Failed to add savedmode element for %s\n",
+ __func__, pathname);
+ return FEDFS_ERR_SVRFAULT;
+ }
+
+ (void)snprintf(buf, sizeof(buf), "%o", ALLPERMS & mode);
+ xmlSetProp(savedmode, JUNCTION_XML_MODEBITS_ATTR, (const xmlChar *)buf);
+
+ return FEDFS_OK;
+}
+
+/**
* Construct NFS junction XML document from list of NFS locations
*
* @param pathname NUL-terminated C string containing pathname of a junction
@@ -719,6 +752,7 @@ static FedFsStatus
nfs_junction_xml(const char *pathname, xmlDocPtr doc,
struct nfs_fsloc *fslocs)
{
+ FedFsStatus retval;
xmlNodePtr root;
root = xmlNewNode(NULL, JUNCTION_XML_ROOT_TAG);
@@ -729,6 +763,10 @@ nfs_junction_xml(const char *pathname, xmlDocPtr doc,
}
(void)xmlDocSetRootElement(doc, root);
+ retval = nfs_savedmode_xml(pathname, root);
+ if (retval != FEDFS_OK)
+ return retval;
+
return nfs_fileset_xml(pathname, root, fslocs);
}
Today, when we convert a directory into a junction, we save the directory's mode bits in an extended attribute, and then set them to a known weird value, which the kernel can detect. As an experiment, save the directory mode in the junction XML as well. If this works out, we can avoid using a separate extended attribute for the saved mode. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- src/libjunction/fedfs.c | 38 ++++++++++++++++++++++++++++++++ src/libjunction/junction-internal.h | 10 +++++++++ src/libjunction/junction.c | 41 ++++++++++++++++++++++++++++++----- src/libjunction/nfs.c | 38 ++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 6 deletions(-)