vol: check for bad partition names
[openafs.git] / src / vol / partition.c
index 0e3e448..4bd0344 100644 (file)
@@ -77,7 +77,6 @@
 #endif
 #endif
 #ifdef AFS_SUN5_ENV
-#include <unistd.h>
 #include <sys/mnttab.h>
 #include <sys/mntent.h>
 #else
 #include <mntent.h>
 #endif
 
-#include <rx/xdr.h>
+#include <afs/opr.h>
+#ifdef AFS_PTHREAD_ENV
+# include <opr/lock.h>
+#endif
 #include <afs/afsint.h>
+#include <rx/rx_queue.h>
 #include "nfs.h"
 #include <afs/errors.h>
 #include "lock.h"
 #include "ntops.h"
 #else
 #include "namei_ops.h"
-#include <dirent.h>
 #endif /* AFS_NT40_ENV */
 #endif /* AFS_NAMEI_ENV */
 #include "vnode.h"
 #include "partition.h"
 
 #if defined(AFS_HPUX_ENV)
-#include <sys/types.h>
 #include <sys/privgrp.h>
 #endif /* defined(AFS_HPUX_ENV) */
 
 #include <jfs/filsys.h>
 #endif
 
+#ifdef AFS_NT40_ENV
+extern int VValidVPTEntry(struct vptab *vptp);
+#endif
+
 int aixlow_water = 8;          /* default 8% */
 struct DiskPartition64 *DiskPartitionList;
 
@@ -193,7 +198,7 @@ VInitPartition_r(char *path, char *devname, Device dev)
 {
     struct DiskPartition64 *dp, *op;
 
-    dp = (struct DiskPartition64 *)malloc(sizeof(struct DiskPartition64));
+    dp = malloc(sizeof(struct DiskPartition64));
     /* Add it to the end, to preserve order when we print statistics */
     for (op = DiskPartitionList; op; op = op->next) {
        if (!op->next)
@@ -204,12 +209,11 @@ VInitPartition_r(char *path, char *devname, Device dev)
     else
        DiskPartitionList = dp;
     dp->next = 0;
-    dp->name = (char *)malloc(strlen(path) + 1);
-    strncpy(dp->name, path, strlen(path) + 1);
+    dp->name = strdup(path);
     dp->index = volutil_GetPartitionID(path);
 #if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
     /* Create a lockfile for the partition, of the form /vicepa/Lock/vicepa */
-    dp->devName = (char *)malloc(2 * strlen(path) + 6);
+    dp->devName = malloc(2 * strlen(path) + 6);
     strcpy(dp->devName, path);
     strcat(dp->devName, OS_DIRSEP);
     strcat(dp->devName, "Lock");
@@ -218,8 +222,7 @@ VInitPartition_r(char *path, char *devname, Device dev)
     close(afs_open(dp->devName, O_RDWR | O_CREAT, 0600));
     dp->device = dp->index;
 #else
-    dp->devName = (char *)malloc(strlen(devname) + 1);
-    strncpy(dp->devName, devname, strlen(devname) + 1);
+    dp->devName = strdup(devname);
     dp->device = dev;
 #endif
     dp->lock_fd = INVALID_FD;
@@ -273,7 +276,7 @@ VInitPartition(char *path, char *devname, Device dev)
  *
  * Use partition name as devname.
  */
-int
+static int
 VCheckPartition(char *part, char *devname, int logging)
 {
     struct afs_stat_st status;
@@ -286,6 +289,10 @@ VCheckPartition(char *part, char *devname, int logging)
     if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
        return 0;
     }
+    if (volutil_GetPartitionID(part) == -1) {
+       Log("Warning: %s is a bad partition name; ignored.\n", part);
+       return 0;
+    }
     if (afs_stat(part, &status) < 0) {
        Log("VInitVnodes: Couldn't find file system %s; ignored\n", part);
        return 0;
@@ -320,7 +327,7 @@ VCheckPartition(char *part, char *devname, int logging)
        struct dirent *dp;
 
        dirp = opendir(part);
-       osi_Assert(dirp);
+       opr_Assert(dirp);
        while ((dp = readdir(dirp))) {
            if (dp->d_name[0] == 'V') {
                Log("This program is compiled with AFS_NAMEI_ENV, but partition %s seems to contain volumes which don't use the namei-interface; aborting\n", part);
@@ -398,12 +405,34 @@ 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
  * partitions, in the NAMEI fileserver.
  */
-void
+static void
 VAttachPartitions2(void)
 {
 #ifdef AFS_NAMEI_ENV
@@ -478,6 +507,10 @@ VAttachPartitions(void)
            || (strncmp(mnt.mnt_mntopts, "ro,ignore", 9) == 0))
            continue;
 
+       /* Skip this Partition? */
+       if (VIsNeverAttach(mnt.mnt_mountp))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(mnt.mnt_mountp, NULL))
            continue;
@@ -517,6 +550,10 @@ 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;
@@ -549,7 +586,7 @@ getmount(struct vmount **vmountpp)
 
     /* try the operation until ok or a fatal error */
     while (1) {
-       if ((vm = (struct vmount *)malloc(size)) == NULL) {
+       if ((vm = malloc(size)) == NULL) {
            /* failed getting memory for mount status buf */
            perror("FATAL ERROR: get_stat malloc failed\n");
            exit(-1);
@@ -620,6 +657,10 @@ VAttachPartitions(void)
 #endif
 #endif
 
+       /* Skip this Partition? */
+       if (VIsNeverAttach(part))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(part, NULL))
            continue;
@@ -650,6 +691,10 @@ VAttachPartitions(void)
        if (strcmp(fsent->fs_type, "rw") != 0)
            continue;
 
+       /* Skip this Partition? */
+       if (VIsNeverAttach(fsent->fs_file))
+           continue;
+
        /* If we're going to always attach this partition, do it later. */
        if (VIsAlwaysAttach(fsent->fs_file, NULL))
            continue;
@@ -667,8 +712,6 @@ VAttachPartitions(void)
 #endif
 
 #ifdef AFS_NT40_ENV
-#include <string.h>
-#include <sys/stat.h>
 /* VValidVPTEntry
  *
  * validate names in vptab.
@@ -678,7 +721,7 @@ VAttachPartitions(void)
  * 0 invalid entry
  */
 
-int
+static int
 VValidVPTEntry(struct vptab *vpe)
 {
     int len = strlen(vpe->vp_name);
@@ -717,7 +760,7 @@ VValidVPTEntry(struct vptab *vpe)
     return 1;
 }
 
-int
+static int
 VCheckPartition(char *partName)
 {
     char volRoot[4];
@@ -834,6 +877,10 @@ 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;
@@ -877,7 +924,7 @@ VGetPartition_r(char *name, int abortp)
     }
 #endif /* AFS_DEMAND_ATTACH_FS */
     if (abortp)
-       osi_Assert(dp != NULL);
+       opr_Assert(dp != NULL);
     return dp;
 }
 
@@ -1125,12 +1172,12 @@ VLockPartition_r(char *name)
            (FD_t)CreateFile(path, GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                            CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
-       osi_Assert(dp->lock_fd != INVALID_FD);
+       opr_Assert(dp->lock_fd != INVALID_FD);
 
        memset(&lap, 0, sizeof(lap));
        rc = LockFileEx((HANDLE) dp->lock_fd, LOCKFILE_EXCLUSIVE_LOCK, 0, 1,
                        0, &lap);
-       osi_Assert(rc);
+       opr_Assert(rc);
     }
 }
 
@@ -1215,11 +1262,11 @@ VLockPartition_r(char *name)
        pausing.tv_usec = 500000;
        select(0, NULL, NULL, NULL, &pausing);
     }
-    osi_Assert(retries != 0);
+    opr_Assert(retries != 0);
 
 #if defined (AFS_HPUX_ENV)
 
-    osi_Assert(getprivgrp(privGrpList) == 0);
+    opr_Verify(getprivgrp(privGrpList) == 0);
 
     /*
      * In general, it will difficult and time-consuming ,if not impossible,
@@ -1240,26 +1287,26 @@ VLockPartition_r(char *name)
     if (((*globalMask) & privmask(PRIV_LOCKRDONLY)) == 0) {
        /* allow everybody to set a lock on a read-only file descriptor */
        (*globalMask) |= privmask(PRIV_LOCKRDONLY);
-       osi_Assert(setprivgrp(PRIV_GLOBAL, privGrpList[globalMaskIndex].priv_mask)
-              == 0);
+       opr_Verify(setprivgrp(PRIV_GLOBAL,
+                             privGrpList[globalMaskIndex].priv_mask) == 0);
 
        lockfRtn = lockf(dp->lock_fd, F_LOCK, 0);
 
        /* remove the privilege granted to everybody to lock a read-only fd */
        (*globalMask) &= ~(privmask(PRIV_LOCKRDONLY));
-       osi_Assert(setprivgrp(PRIV_GLOBAL, privGrpList[globalMaskIndex].priv_mask)
-              == 0);
+       opr_Verify(setprivgrp(PRIV_GLOBAL,
+                             privGrpList[globalMaskIndex].priv_mask) == 0);
     } else {
        /* in this case, we should be able to do this with impunity, anyway */
        lockfRtn = lockf(dp->lock_fd, F_LOCK, 0);
     }
 
-    osi_Assert(lockfRtn != -1);
+    opr_Assert(lockfRtn != -1);
 #else
 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
-    osi_Assert(lockf(dp->lock_fd, F_LOCK, 0) != -1);
+    opr_Verify(lockf(dp->lock_fd, F_LOCK, 0) != -1);
 #else
-    osi_Assert(flock(dp->lock_fd, LOCK_EX) == 0);
+    opr_Verify(flock(dp->lock_fd, LOCK_EX) == 0);
 #endif /* defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) */
 #endif
 }
@@ -1366,7 +1413,7 @@ VGetPartitionById_r(afs_int32 id, int abortp)
     }
 
     if (abortp) {
-       osi_Assert(dp != NULL);
+       opr_Assert(dp != NULL);
     }
     return dp;
 }
@@ -1410,7 +1457,7 @@ VLookupPartition_r(char * path)
 static void
 AddPartitionToTable_r(struct DiskPartition64 *dp)
 {
-    osi_Assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
+    opr_Assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
     DiskPartitionTable[dp->index] = dp;
 }
 
@@ -1418,7 +1465,7 @@ AddPartitionToTable_r(struct DiskPartition64 *dp)
 static void
 DeletePartitionFromTable_r(struct DiskPartition64 *dp)
 {
-    osi_Assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
+    opr_Assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
     DiskPartitionTable[dp->index] = NULL;
 }
 #endif