Fileserver: Add the /vicepXX/NeverAttach flag to skip mounting a partition
[openafs.git] / src / vol / partition.c
index 2fec1bb..95bb8a8 100644 (file)
 #include <roken.h>
 
 #include <ctype.h>
-#include <string.h>
+
 #ifdef AFS_NT40_ENV
 #include <windows.h>
 #include <winbase.h>
 #include <winioctl.h>
 #else
-#include <sys/param.h>
-#include <sys/types.h>
-#include <unistd.h>
 
 #if AFS_HAVE_STATVFS || AFS_HAVE_STATVFS64
 #include <sys/statvfs.h>
@@ -64,9 +61,6 @@
 #endif
 #endif /* AFS_VFSINCL_ENV */
 #endif /* AFS_OSF_ENV */
-#include <errno.h>
-#include <sys/stat.h>
-#include <stdio.h>
 #include <sys/file.h>
 #ifdef AFS_AIX_ENV
 #include <sys/vfs.h>
@@ -74,8 +68,6 @@
 #else
 #ifdef AFS_HPUX_ENV
 #include <sys/vfs.h>
-#include <unistd.h>
-#include <fcntl.h>
 #include <checklist.h>
 #else
 #if    defined(AFS_SUN_ENV)
 #endif /* AFS_SGI_ENV */
 #endif /* AFS_NT40_ENV */
 #if defined(AFS_SGI_ENV)
-#include <sys/errno.h>
-#include <sys/stat.h>
-#include <stdio.h>
 #include <sys/file.h>
 #include <mntent.h>
 #endif
 #include "vnode.h"
 #include "volume.h"
 #include "partition.h"
-#include <afs/afs_assert.h>
 
 #if defined(AFS_HPUX_ENV)
 #include <sys/types.h>
@@ -286,7 +274,7 @@ VInitPartition(char *path, char *devname, Device dev)
  * Use partition name as devname.
  */
 int
-VCheckPartition(char *part, char *devname)
+VCheckPartition(char *part, char *devname, int logging)
 {
     struct afs_stat_st status;
 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV)
@@ -302,6 +290,15 @@ VCheckPartition(char *part, char *devname)
        Log("VInitVnodes: Couldn't find file system %s; ignored\n", part);
        return 0;
     }
+    if (logging) {
+       Log("This program is compiled without AFS_NAMEI_ENV, and "
+           "partition %s is mounted with the 'logging' option. "
+           "Using the inode fileserver backend with 'logging' UFS "
+           "partitions causes volume corruption, so please either "
+           "mount the partition without logging, or use the namei "
+           "fileserver backend. Aborting...\n", part);
+       return -1;
+    }
 #ifndef AFS_AIX32_ENV
     if (programType == fileServer) {
        char salvpath[MAXPATHLEN];
@@ -401,6 +398,28 @@ VIsAlwaysAttach(char *part, int *awouldattach)
 #endif /* AFS_NAMEI_ENV */
 }
 
+/* VIsNeverAttach() checks whether a /vicepX directory should never be
+ * attached (return value 1), or follow the normal mounting logic. The
+ * Always Attach flag may override the NeverAttach flag.
+ */
+static int
+VIsNeverAttach(char *part)
+{
+    struct afs_stat_st st;
+    char checkfile[256];
+    int ret;
+
+    if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE))
+       return 0;
+
+    strncpy(checkfile, part, 100);
+    strcat(checkfile, OS_DIRSEP);
+    strcat(checkfile, VICE_NEVERATTACH_FILE);
+
+    ret = afs_stat(checkfile, &st);
+    return (ret < 0) ? 0 : 1;
+}
+
 /* VAttachPartitions2() looks for and attaches /vicepX partitions
  * where a special file (VICE_ALWAYSATTACH_FILE) exists.  This is
  * used to attach /vicepX directories which aren't on dedicated
@@ -424,7 +443,7 @@ VAttachPartitions2(void)
        /* Only keep track of "/vicepx" partitions since automounter
         * may hose us */
        if (VIsAlwaysAttach(pname, &wouldattach)) {
-           VCheckPartition(pname, "");
+           VCheckPartition(pname, "", 0);
        } else {
            struct afs_stat_st st;
            if (wouldattach && VGetPartition(pname, 0) == NULL &&
@@ -468,6 +487,7 @@ VAttachPartitions(void)
        exit(-1);
     }
     while (!getmntent(mntfile, &mnt)) {
+       int logging = 0;
        /* Ignore non ufs or non read/write partitions */
        /* but allow zfs too if we're in the NAMEI environment */
        if (
@@ -480,23 +500,21 @@ VAttachPartitions(void)
            || (strncmp(mnt.mnt_mntopts, "ro,ignore", 9) == 0))
            continue;
 
+       /* Skip this Partition? */
+       if (VIsNeverAttach(mntent->mnt_dir))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(mnt.mnt_mountp, NULL))
            continue;
 
 #ifndef AFS_NAMEI_ENV
        if (hasmntopt(&mnt, "logging") != NULL) {
-           Log("This program is compiled without AFS_NAMEI_ENV, and "
-               "partition %s is mounted with the 'logging' option. "
-               "Using the inode fileserver backend with 'logging' UFS "
-               "partitions causes volume corruption, so please either "
-               "mount the partition without logging, or use the namei "
-               "fileserver backend. Aborting...\n", mnt.mnt_mountp);
-           errors++;
+           logging = 1;
        }
 #endif /* !AFS_NAMEI_ENV */
 
-       if (VCheckPartition(mnt.mnt_mountp, mnt.mnt_special) < 0)
+       if (VCheckPartition(mnt.mnt_mountp, mnt.mnt_special, logging) < 0)
            errors++;
     }
 
@@ -525,11 +543,15 @@ VAttachPartitions(void)
        if (!hasmntopt(mntent, MNTOPT_RW))
            continue;
 
+       /* Skip this Partition? */
+       if (VIsNeverAttach(mntent->mnt_dir))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(mntent->mnt_dir, NULL))
            continue;
 
-       if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname) < 0)
+       if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname, 0) < 0)
            errors++;
     }
 
@@ -628,11 +650,15 @@ VAttachPartitions(void)
 #endif
 #endif
 
+       /* Skip this Partition? */
+       if (VIsNeverAttach(mntent->mnt_dir))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(part, NULL))
            continue;
 
-       if (VCheckPartition(part, vmt2dataptr(vmountp, VMT_OBJECT)) < 0)
+       if (VCheckPartition(part, vmt2dataptr(vmountp, VMT_OBJECT), 0) < 0)
            errors++;
     }
 
@@ -658,11 +684,15 @@ VAttachPartitions(void)
        if (strcmp(fsent->fs_type, "rw") != 0)
            continue;
 
+       /* Skip this Partition? */
+       if (VIsNeverAttach(mntent->mnt_dir))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(fsent->fs_file, NULL))
            continue;
 
-       if (VCheckPartition(fsent->fs_file, fsent->fs_spec) < 0)
+       if (VCheckPartition(fsent->fs_file, fsent->fs_spec, 0) < 0)
            errors++;
     }
     endfsent();
@@ -842,11 +872,15 @@ VAttachPartitions(void)
        }
     }
     while ((mntent = getmntent(mfd))) {
+       /* Skip this Partition? */
+       if (VIsNeverAttach(mntent->mnt_dir))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(mntent->mnt_dir, NULL))
            continue;
 
-       if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname) < 0)
+       if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname, 0) < 0)
            errors++;
     }
     endmntent(mfd);