libuafs: Allow -mountdir to override uafs_Setup
authorAndrew Deason <adeason@sinenomine.net>
Fri, 28 Jan 2011 17:11:20 +0000 (11:11 -0600)
committerDerrick Brashear <shadow@dementia.org>
Wed, 16 Feb 2011 16:57:43 +0000 (08:57 -0800)
For some reason, uafs_Setup accepts a parameter specifying the AFS mount
point, and we effectively ignore any -mountdir option specified in the
string arguments. Allow -mountdir to override the mount point specified
in uafs_Setup, by changing afs_mountDir &co during afsd_mount_afs().

Change-Id: I4ea88923c0a8392d280c1a8f0ca4d3adf741f7f6
Reviewed-on: http://gerrit.openafs.org/3897
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/afs/UKERNEL/afs_usrops.c
src/afs/UKERNEL/afs_usrops.h
src/afs/UKERNEL/afsd_uafs.c

index f647133..4d0e843 100644 (file)
@@ -1213,6 +1213,63 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
     usr_assert(code == 0);
 }
 
+/**
+ * Calculate the cacheMountDir used for a specified dir.
+ *
+ * @param[in]  dir      Desired mount dir
+ * @param[out] mountdir On success, contains the literal string that should
+ *                      be used as the cache mount dir.
+ * @param[in]  size     The number of bytes allocated in mountdir
+ *
+ * @post On success, mountdir begins with a slash, and does not contain two
+ * slashes adjacent to each other
+ *
+ * @return operation status
+ *  @retval 0 success
+ *  @retval ENAMETOOLONG the specified dir is too long to fix in the given
+ *                       mountdir buffer
+ *  @retval EINVAL the specified dir does not actually specify any meaningful
+ *                 mount directory
+ */
+static int
+calcMountDir(const char *dir, char *mountdir, size_t size)
+{
+    char buf[1024];
+    char lastchar;
+    char *p;
+    int len;
+
+    if (dir && strlen(dir) > size-1) {
+       return ENAMETOOLONG;
+    }
+
+    /*
+     * Initialize the AFS mount point, default is '/afs'.
+     * Strip duplicate/trailing slashes from mount point string.
+     * afs_mountDirLen is set to strlen(afs_mountDir).
+     */
+    if (!dir) {
+       dir = "afs";
+    }
+    sprintf(buf, "%s", dir);
+
+    mountdir[0] = '/';
+    len = 1;
+    for (lastchar = '/', p = &buf[0]; *p != '\0'; p++) {
+        if (lastchar != '/' || *p != '/') {
+            mountdir[len++] = lastchar = *p;
+        }
+    }
+    if (lastchar == '/' && len > 1)
+        len--;
+    mountdir[len] = '\0';
+    if (len <= 1) {
+       return EINVAL;
+    }
+
+    return 0;
+}
+
 void
 uafs_mount(void) {
     int rc;
@@ -1236,6 +1293,28 @@ uafs_mount(void) {
     return;
 }
 
+void
+uafs_mountWithDir(const char *dir)
+{
+    if (dir) {
+       int rc;
+       char tmp_mountDir[1024];
+
+       rc = calcMountDir(dir, tmp_mountDir, sizeof(tmp_mountDir));
+       if (rc) {
+           afs_warn("Invalid mount dir specification (error %d): %s\n", rc, dir);
+       } else {
+           if (strcmp(tmp_mountDir, afs_mountDir) != 0) {
+               /* mount dir changed */
+               strcpy(afs_mountDir, tmp_mountDir);
+               afs_mountDirLen = strlen(afs_mountDir);
+           }
+       }
+    }
+
+    uafs_mount();
+}
+
 int
 uafs_statvfs(struct statvfs *buf)
 {
@@ -1395,9 +1474,7 @@ call_syscall(long syscall, long afscall, long param1, long param2,
 int
 uafs_Setup(const char *mount)
 {
-    char buf[1024];
-    char lastchar;
-    char *p;
+    int rc;
     static int inited = 0;
 
     if (inited) {
@@ -1405,33 +1482,11 @@ uafs_Setup(const char *mount)
     }
     inited = 1;
 
-    if (mount && strlen(mount) > 1023) {
-       return ENAMETOOLONG;
-    }
-
-    /*
-     * Initialize the AFS mount point, default is '/afs'.
-     * Strip duplicate/trailing slashes from mount point string.
-     * afs_mountDirLen is set to strlen(afs_mountDir).
-     */
-    if (!mount) {
-       mount = "afs";
-    }
-    sprintf(buf, "%s", mount);
-
-    afs_mountDir[0] = '/';
-    afs_mountDirLen = 1;
-    for (lastchar = '/', p = &buf[0]; *p != '\0'; p++) {
-        if (lastchar != '/' || *p != '/') {
-            afs_mountDir[afs_mountDirLen++] = lastchar = *p;
-        }
-    }
-    if (lastchar == '/' && afs_mountDirLen > 1)
-        afs_mountDirLen--;
-    afs_mountDir[afs_mountDirLen] = '\0';
-    if (afs_mountDirLen <= 1) {
-       return EINVAL;
+    rc = calcMountDir(mount, afs_mountDir, sizeof(afs_mountDir));
+    if (rc) {
+       return rc;
     }
+    afs_mountDirLen = strlen(afs_mountDir);
 
     /* initialize global vars and such */
     osi_Init();
index 6ba738d..b468b89 100644 (file)
@@ -149,6 +149,7 @@ extern int uafs_statmountpoint_r(char *path);
 extern int uafs_statvfs(struct statvfs *buf);
 extern void uafs_Shutdown(void);
 extern void uafs_mount(void);
+extern void uafs_mountWithDir(const char *dir);
 extern int uafs_fork(int wait, void* (*cbf) (void *), void *rock);
 
 #endif /* __AFS_USROPS_H__ */
index 06c61df..afd193c 100644 (file)
@@ -28,7 +28,7 @@ extern int call_syscall(long, long, long, long, long, long);
 void
 afsd_mount_afs(const char *rn, const char *mountdir)
 {
-    uafs_mount();
+    uafs_mountWithDir(mountdir);
 }
 
 void