/* VAttachPartitions() finds the vice partitions on this server. Calls * VCheckPartition() to do some basic checks on the partition. If the partition * is a valid vice partition, VCheckPartition will add it to the DiskPartition * list. * Returns the number of errors returned by VCheckPartition. An error in * VCheckPartition means that partition is a valid vice partition but the * fileserver should not start because of the error found on that partition. * * AFS_NAMEI_ENV * No specific user space file system checks, since we don't know what * is being used for vice partitions. * * Use partition name as devname. */ int VCheckPartition(char *part, char *devname) { struct afs_stat status; #if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV) char AFSIDatPath[MAXPATHLEN]; #endif /* Only keep track of "/vicepx" partitions since it can get hairy * when NFS mounts are involved.. */ if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) { return 0; } if (afs_stat(part, &status) < 0) { Log("VInitVnodes: Couldn't find file system %s; ignored\n", part); return 0; } #ifndef AFS_AIX32_ENV if (programType == fileServer) { char salvpath[MAXPATHLEN]; strcpy(salvpath, part); strcat(salvpath, "/FORCESALVAGE"); if (afs_stat(salvpath, &status) == 0) { Log("VInitVnodes: Found %s; aborting\n", salvpath); return -1; } } #endif #if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV) strcpy(AFSIDatPath, part); strcat(AFSIDatPath, "/AFSIDat"); #ifdef AFS_NAMEI_ENV if (afs_stat(AFSIDatPath, &status) < 0) { DIR *dirp; struct dirent *dp; dirp = opendir(part); 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); closedir(dirp); return -1; } } closedir(dirp); } #else /* AFS_NAMEI_ENV */ if (afs_stat(AFSIDatPath, &status) == 0) { Log("This program is compiled without AFS_NAMEI_ENV, but partition %s seems to contain volumes which use the namei-interface; aborting\n", part); return -1; } #ifdef AFS_SGI_XFS_IOPS_ENV if (VerifyXFSInodeSize(part, status.st_fstype) < 0) return -1; #endif #endif /* AFS_NAMEI_ENV */ #endif /* !AFS_LINUX20_ENV && !AFS_NT40_ENV */ #if defined(AFS_DUX40_ENV) && !defined(AFS_NAMEI_ENV) if (status.st_ino != ROOTINO) { Log("%s is not a mounted file system; ignored.\n", part); return 0; } #endif VInitPartition(part, devname, status.st_dev); return 0; }
int VAttachPartitions(void) { struct DiskPartition64 *partP, *prevP, *nextP; struct vpt_iter iter; struct vptab entry; if (vpt_Start(&iter) < 0) { Log("No partitions to attach.\n"); return 0; } while (0 == vpt_NextEntry(&iter, &entry)) { if (!VValidVPTEntry(&entry)) { continue; } /* This test for duplicates relies on the fact that the method * of storing the partition names in the NT registry means the same * partition name will never appear twice in the list. */ for (partP = DiskPartitionList; partP; partP = partP->next) { if (*partP->devName == *entry.vp_dev) { Log("Same drive (%s) used for both partition %s and partition %s, ignoring both.\n", entry.vp_dev, partP->name, entry.vp_name); partP->flags = PART_DUPLICATE; break; /* Only one entry will ever be in this list. */ } } if (partP) continue; /* found a duplicate */ if (VCheckPartition(entry.vp_dev) < 0) continue; /* This test allows for manually inserting the FORCESALVAGE flag * and thereby invoking the salvager. scandisk obviously won't be * doing this for us. */ if (programType == fileServer) { struct afs_stat status; char salvpath[MAXPATHLEN]; strcpy(salvpath, entry.vp_dev); strcat(salvpath, "\\FORCESALVAGE"); if (afs_stat(salvpath, &status) == 0) { Log("VAttachPartitions: Found %s; aborting\n", salvpath); exit(1); } } VInitPartition(entry.vp_name, entry.vp_dev, *entry.vp_dev - 'A'); } vpt_Finish(&iter); /* Run through partition list and clear out the dupes. */ prevP = nextP = NULL; for (partP = DiskPartitionList; partP; partP = nextP) { nextP = partP->next; if (partP->flags == PART_DUPLICATE) { if (prevP) prevP->next = partP->next; else DiskPartitionList = partP->next; free(partP); } else prevP = partP; } return 0; }
/* VAttachPartitions() finds the vice partitions on this server. Calls * VCheckPartition() to do some basic checks on the partition. If the partition * is a valid vice partition, VCheckPartition will add it to the DiskPartition * list. * Returns the number of errors returned by VCheckPartition. An error in * VCheckPartition means that partition is a valid vice partition but the * fileserver should not start because of the error found on that partition. * * AFS_NAMEI_ENV * No specific user space file system checks, since we don't know what * is being used for vice partitions. * * Use partition name as devname. */ static int VCheckPartition(char *part, char *devname, int logging) { struct afs_stat_st status; #if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV) char AFSIDatPath[MAXPATHLEN]; #endif /* Only keep track of "/vicepx" partitions since it can get hairy * when NFS mounts are involved.. */ 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; } 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]; strcpy(salvpath, part); strcat(salvpath, "/FORCESALVAGE"); if (afs_stat(salvpath, &status) == 0) { Log("VInitVnodes: Found %s; aborting\n", salvpath); return -1; } } #endif #if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV) strcpy(AFSIDatPath, part); strcat(AFSIDatPath, "/AFSIDat"); #ifdef AFS_NAMEI_ENV if (afs_stat(AFSIDatPath, &status) < 0) { DIR *dirp; struct dirent *dp; dirp = opendir(part); 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); closedir(dirp); return -1; } } closedir(dirp); } #else /* AFS_NAMEI_ENV */ if (afs_stat(AFSIDatPath, &status) == 0) { Log("This program is compiled without AFS_NAMEI_ENV, but partition %s seems to contain volumes which use the namei-interface; aborting\n", part); return -1; } #ifdef AFS_SGI_XFS_IOPS_ENV if (VerifyXFSInodeSize(part, status.st_fstype) < 0) return -1; #endif #endif /* AFS_NAMEI_ENV */ #endif /* !AFS_LINUX20_ENV && !AFS_NT40_ENV */ VInitPartition(part, devname, status.st_dev); return 0; }