Fileserver: Add the /vicepXX/NeverAttach flag to skip mounting a partition
[openafs.git] / src / vol / partition.c
index bc7fe76..95bb8a8 100644 (file)
 #include <afsconfig.h>
 #include <afs/param.h>
 
+#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>
@@ -63,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>
@@ -73,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>
 #include <jfs/filsys.h>
 #endif
 
-#ifdef O_LARGEFILE
-
-#define afs_stat       stat64
-#define afs_open       open64
-#define afs_fopen      fopen64
-#ifndef AFS_NT40_ENV
-#if AFS_HAVE_STATVFS64
-# define afs_statvfs   statvfs64
-#else
-# if AFS_HAVE_STATFS64
-#  define afs_statfs   statfs64
-#else
-#  if AFS_HAVE_STATVFS
-#   define afs_statvfs statvfs
-#  else
-#   define afs_statfs  statfs
-#  endif /* !AFS_HAVE_STATVFS */
-# endif        /* !AFS_HAVE_STATFS64 */
-#endif /* !AFS_HAVE_STATVFS64 */
-#endif /* !AFS_NT40_ENV */
-
-#else /* !O_LARGEFILE */
-
-#define afs_stat       stat
-#define afs_open       open
-#define afs_fopen      fopen
-#ifndef AFS_NT40_ENV
-#if AFS_HAVE_STATVFS
-#define afs_statvfs    statvfs
-#else /* !AFS_HAVE_STATVFS */
-#define afs_statfs     statfs
-#endif /* !AFS_HAVE_STATVFS */
-#endif /* !AFS_NT40_ENV */
-
-#endif /* !O_LARGEFILE */
-
 int aixlow_water = 8;          /* default 8% */
 struct DiskPartition64 *DiskPartitionList;
 
@@ -229,9 +182,9 @@ VerifyXFSInodeSize(char *part, char *fstype)
 int
 VInitPartitionPackage(void)
 {
-#ifdef AFS_DEMAND_ATTACH_ENV
+#ifdef AFS_DEMAND_ATTACH_FS
     memset(&DiskPartitionTable, 0, sizeof(DiskPartitionTable));
-#endif /* AFS_DEMAND_ATTACH_ENV */
+#endif /* AFS_DEMAND_ATTACH_FS */
     return 0;
 }
 
@@ -258,7 +211,7 @@ VInitPartition_r(char *path, char *devname, Device dev)
     /* Create a lockfile for the partition, of the form /vicepa/Lock/vicepa */
     dp->devName = (char *)malloc(2 * strlen(path) + 6);
     strcpy(dp->devName, path);
-    strcat(dp->devName, "/");
+    strcat(dp->devName, OS_DIRSEP);
     strcat(dp->devName, "Lock");
     mkdir(dp->devName, 0700);
     strcat(dp->devName, path);
@@ -285,11 +238,11 @@ VInitPartition_r(char *path, char *devname, Device dev)
     dp->vol_list.busy = 0;
     {
        char lockpath[MAXPATHLEN+1];
-       afs_snprintf(lockpath, MAXPATHLEN, "%s/" AFS_PARTLOCK_FILE, dp->name);
+       snprintf(lockpath, MAXPATHLEN, "%s/" AFS_PARTLOCK_FILE, dp->name);
        lockpath[MAXPATHLEN] = '\0';
        VLockFileInit(&dp->headerLockFile, lockpath);
 
-       afs_snprintf(lockpath, MAXPATHLEN, "%s/" AFS_VOLUMELOCK_FILE, dp->name);
+       snprintf(lockpath, MAXPATHLEN, "%s/" AFS_VOLUMELOCK_FILE, dp->name);
        lockpath[MAXPATHLEN] = '\0';
        VLockFileInit(&dp->volLockFile, lockpath);
     }
@@ -321,9 +274,9 @@ 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 status;
+    struct afs_stat_st status;
 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV)
     char AFSIDatPath[MAXPATHLEN];
 #endif
@@ -337,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];
@@ -408,7 +370,7 @@ static int
 VIsAlwaysAttach(char *part, int *awouldattach)
 {
 #ifdef AFS_NAMEI_ENV
-    struct afs_stat st;
+    struct afs_stat_st st;
     char checkfile[256];
     int ret;
 #endif /* AFS_NAMEI_ENV */
@@ -426,7 +388,7 @@ VIsAlwaysAttach(char *part, int *awouldattach)
     }
 
     strncpy(checkfile, part, 100);
-    strcat(checkfile, "/");
+    strcat(checkfile, OS_DIRSEP);
     strcat(checkfile, VICE_ALWAYSATTACH_FILE);
 
     ret = afs_stat(checkfile, &st);
@@ -436,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
@@ -450,18 +434,18 @@ VAttachPartitions2(void)
     char pname[32];
     int wouldattach;
 
-    dirp = opendir("/");
+    dirp = opendir(OS_DIRSEP);
     while ((de = readdir(dirp))) {
-       strcpy(pname, "/");
+       strcpy(pname, OS_DIRSEP);
        strncat(pname, de->d_name, 20);
        pname[sizeof(pname) - 1] = '\0';
 
        /* 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;
+           struct afs_stat_st st;
            if (wouldattach && VGetPartition(pname, 0) == NULL &&
                afs_stat(pname, &st) == 0 && S_ISDIR(st.st_mode)) {
 
@@ -503,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 (
@@ -515,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++;
     }
 
@@ -560,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++;
     }
 
@@ -663,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++;
     }
 
@@ -693,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();
@@ -831,7 +826,7 @@ VAttachPartitions(void)
         * doing this for us.
         */
        if (programType == fileServer) {
-           struct afs_stat status;
+           struct afs_stat_st status;
            char salvpath[MAXPATHLEN];
            strcpy(salvpath, entry.vp_dev);
            strcat(salvpath, "\\FORCESALVAGE");
@@ -877,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);
@@ -1128,14 +1127,14 @@ VPrintDiskStats_r(void)
     struct DiskPartition64 *dp;
     for (dp = DiskPartitionList; dp; dp = dp->next) {
        if (dp->free < 0) {
-           Log("Partition %s: %"AFS_INT64_FMT
-               " available 1K blocks (minfree=%"AFS_INT64_FMT"), "
-               "overallocated by %"AFS_INT64_FMT" blocks\n", dp->name,
+           Log("Partition %s: %lld "
+               " available 1K blocks (minfree=%lld), "
+               "overallocated by %lld blocks\n", dp->name,
                dp->totalUsable, dp->minFree, -dp->free);
        } else {
-           Log("Partition %s: %"AFS_INT64_FMT
-               " available 1K blocks (minfree=%"AFS_INT64_FMT"), "
-               "%"AFS_INT64_FMT" free blocks\n", dp->name,
+           Log("Partition %s: %lld"
+               " available 1K blocks (minfree=%lld), "
+               "%lld free blocks\n", dp->name,
                dp->totalUsable, dp->minFree, dp->free);
        }
     }