/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#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>
#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>
#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"
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
#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;
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;
}
/* 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);
#ifdef AFS_DEMAND_ATTACH_FS
AddPartitionToTable_r(dp);
queue_Init(&dp->vol_list.head);
- assert(pthread_cond_init(&dp->vol_list.cv, NULL) == 0);
+ CV_INIT(&dp->vol_list.cv, "vol list", CV_DEFAULT, 0);
dp->vol_list.len = 0;
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);
}
* 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
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];
struct dirent *dp;
dirp = opendir(part);
- assert(dirp);
+ osi_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);
* attached (return value 1), or only attached when it is a separately
* mounted partition (return value 0). For non-NAMEI environments, it
* always returns 0.
+ *
+ * *awouldattach will be set to 1 if the given path at least looks like a vice
+ * partition (that is, if we return 0, the only thing preventing this partition
+ * from being attached is the existence of the AlwaysAttach file), or to 0
+ * otherwise. *awouldattach is set regardless of whether or not the partition
+ * should always be attached or not.
*/
static int
-VIsAlwaysAttach(char *part)
+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 */
+
+ if (awouldattach) {
+ *awouldattach = 0;
+ }
+#ifdef AFS_NAMEI_ENV
if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE))
return 0;
+ if (awouldattach) {
+ *awouldattach = 1;
+ }
+
strncpy(checkfile, part, 100);
- strcat(checkfile, "/");
+ strcat(checkfile, OS_DIRSEP);
strcat(checkfile, VICE_ALWAYSATTACH_FILE);
ret = afs_stat(checkfile, &st);
#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
DIR *dirp;
struct dirent *de;
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))
- VCheckPartition(pname, "");
+ if (VIsAlwaysAttach(pname, &wouldattach)) {
+ VCheckPartition(pname, "", 0);
+ } else {
+ struct afs_stat_st st;
+ if (wouldattach && VGetPartition(pname, 0) == NULL &&
+ afs_stat(pname, &st) == 0 && S_ISDIR(st.st_mode)) {
+
+ /* This is a /vicep* dir, and it has not been attached as a
+ * partition. This probably means that this is a /vicep* dir
+ * that is not a separate partition, so just give a notice so
+ * admins are not confused as to why their /vicep* dirs are not
+ * being attached.
+ *
+ * It is possible that the dir _is_ a separate partition and we
+ * failed to attach it earlier, making this message a bit
+ * confusing. But that should be rare, and an error message
+ * about the failure will already be logged right before this,
+ * so it should be clear enough. */
+
+ Log("VAttachPartitions: not attaching %s; either it is not a "
+ "separate partition, or it failed to attach (create the "
+ "file %s/" VICE_ALWAYSATTACH_FILE " to force attachment)\n",
+ pname, pname);
+ }
+ }
}
closedir(dirp);
#endif /* AFS_NAMEI_ENV */
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 (
#endif
|| (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))
+ 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++;
}
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))
+ 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++;
}
#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))
+ if (VIsAlwaysAttach(part, NULL))
continue;
- if (VCheckPartition(part, vmt2dataptr(vmountp, VMT_OBJECT)) < 0)
+ if (VCheckPartition(part, vmt2dataptr(vmountp, VMT_OBJECT), 0) < 0)
errors++;
}
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))
+ 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();
* 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");
}
}
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))
+ 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);
}
#endif /* AFS_DEMAND_ATTACH_FS */
if (abortp)
- assert(dp != NULL);
+ osi_Assert(dp != NULL);
return dp;
}
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);
}
}
(FD_t)CreateFile(path, GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
- assert(dp->lock_fd != INVALID_FD);
+ osi_Assert(dp->lock_fd != INVALID_FD);
memset(&lap, 0, sizeof(lap));
rc = LockFileEx((HANDLE) dp->lock_fd, LOCKFILE_EXCLUSIVE_LOCK, 0, 1,
0, &lap);
- assert(rc);
+ osi_Assert(rc);
}
}
if (!dp)
return; /* no partition, will fail later */
- if (dp->lock_fd != -1)
+ if (dp->lock_fd != INVALID_FD)
return;
#if defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV)
else
dp->lock_fd = afs_open(partitionName, code);
- if (dp->lock_fd != -1)
+ if (dp->lock_fd != INVALID_FD)
break;
if (errno == ENOENT)
code |= O_CREAT;
pausing.tv_usec = 500000;
select(0, NULL, NULL, NULL, &pausing);
}
- assert(retries != 0);
+ osi_Assert(retries != 0);
#if defined (AFS_HPUX_ENV)
- assert(getprivgrp(privGrpList) == 0);
+ osi_Assert(getprivgrp(privGrpList) == 0);
/*
* In general, it will difficult and time-consuming ,if not impossible,
if (((*globalMask) & privmask(PRIV_LOCKRDONLY)) == 0) {
/* allow everybody to set a lock on a read-only file descriptor */
(*globalMask) |= privmask(PRIV_LOCKRDONLY);
- assert(setprivgrp(PRIV_GLOBAL, privGrpList[globalMaskIndex].priv_mask)
+ osi_Assert(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));
- assert(setprivgrp(PRIV_GLOBAL, privGrpList[globalMaskIndex].priv_mask)
+ osi_Assert(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);
}
- assert(lockfRtn != -1);
+ osi_Assert(lockfRtn != -1);
#else
#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
- assert(lockf(dp->lock_fd, F_LOCK, 0) != -1);
+ osi_Assert(lockf(dp->lock_fd, F_LOCK, 0) != -1);
#else
- assert(flock(dp->lock_fd, LOCK_EX) == 0);
+ osi_Assert(flock(dp->lock_fd, LOCK_EX) == 0);
#endif /* defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) */
#endif
}
if (!dp)
return; /* no partition, will fail later */
close(dp->lock_fd);
- dp->lock_fd = -1;
+ dp->lock_fd = INVALID_FD;
}
#endif /* AFS_NT40_ENV */
* @internal volume package internal use only
*/
-struct DiskPartition64 *
+struct DiskPartition64 *
VGetPartitionById_r(afs_int32 id, int abortp)
{
struct DiskPartition64 *dp = NULL;
}
if (abortp) {
- assert(dp != NULL);
+ osi_Assert(dp != NULL);
}
return dp;
}
return dp;
}
-static struct DiskPartition64 *
+static struct DiskPartition64 *
VLookupPartition_r(char * path)
{
afs_int32 id = volutil_GetPartitionID(path);
return DiskPartitionTable[id];
}
-static void
+static void
AddPartitionToTable_r(struct DiskPartition64 *dp)
{
- assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
+ osi_Assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
DiskPartitionTable[dp->index] = dp;
}
#if 0
-static void
+static void
DeletePartitionFromTable_r(struct DiskPartition64 *dp)
{
- assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
+ osi_Assert(dp->index >= 0 && dp->index <= VOLMAXPARTS);
DiskPartitionTable[dp->index] = NULL;
}
#endif