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 <[email protected]>
---

 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(-)

diff --git a/src/libjunction/fedfs.c b/src/libjunction/fedfs.c
index 5acd58e..a39925b 100644
--- a/src/libjunction/fedfs.c
+++ b/src/libjunction/fedfs.c
@@ -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);
 }
 
diff --git a/src/libjunction/junction-internal.h 
b/src/libjunction/junction-internal.h
index e80edf0..8279ad1 100644
--- a/src/libjunction/junction-internal.h
+++ b/src/libjunction/junction-internal.h
@@ -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);
 
diff --git a/src/libjunction/junction.c b/src/libjunction/junction.c
index cd53744..9d9a266 100644
--- a/src/libjunction/junction.c
+++ b/src/libjunction/junction.c
@@ -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)
diff --git a/src/libjunction/nfs.c b/src/libjunction/nfs.c
index 67c434c..b141392 100644
--- a/src/libjunction/nfs.c
+++ b/src/libjunction/nfs.c
@@ -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);
 }
 


_______________________________________________
fedfs-utils-devel mailing list
[email protected]
https://oss.oracle.com/mailman/listinfo/fedfs-utils-devel

Reply via email to