allow-namei-fileservers-to-use-directories-instead-of-partitions-for-vicep-20010924
authorNickolai Zeldovich <kolya@mit.edu>
Wed, 26 Sep 2001 01:02:46 +0000 (01:02 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 26 Sep 2001 01:02:46 +0000 (01:02 +0000)
 -- /vicepX/AFSIDat/README is created the first time the fileserver
    is started, rather than the second time.

 -- For the namei fileserver, /vicepa/Lock/vicepa is created as
    the lockfile.  Previously, on Solaris, the raw device was
    was being used for LockPartition(), and that breaks when
    there isn't a corresponding device.

 -- The VolPartitions and XVolPartitions volserver calls now return
    the list of attached (rather than mounted) partitions.  This is
    consistent with the NT fileserver and removes duplicate code.

The actual magic for allowing the fileserver to attach non-mounted
partitions is to create /vicepX/AlwaysAttach.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

carefully avoid non vicep directories and/or partitions as it may get upset at
automounters or running cachemanagers!

====================

more carefully avoid non-vicepX partitions

src/vol/namei_ops.c
src/vol/partition.c
src/vol/partition.h
src/volser/volprocs.c

index e540587..e1cb1f6 100644 (file)
@@ -204,6 +204,10 @@ int namei_ViceREADME(char *partition)
    char filename[32];
    int fd;
 
+   /* Create the inode directory if we're starting for the first time */
+   sprintf(filename, "%s/%s", partition, INODEDIR);
+   mkdir(filename, 0700);
+
    sprintf(filename, "%s/%s/README", partition, INODEDIR);
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0444);
    if (fd >= 0) {
index 2717722..cb16224 100644 (file)
@@ -196,11 +196,13 @@ static void VInitPartition_r(char *path, char *devname, Device dev)
     dp->next = 0;
     strcpy(dp->name, path);
 #if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
-#ifdef AFS_SUN5_ENV
-    strcpy(dp->devName, devname);
-#else /* AFS_SUN5_ENV */
+    /* Create a lockfile for the partition, of the form /vicepa/Lock/vicepa */
     strcpy(dp->devName, path);
-#endif
+    strcat(dp->devName, "/");
+    strcat(dp->devName, "Lock");
+    mkdir(dp->devName, 0700);
+    strcat(dp->devName, path);
+    close(open(dp->devName, O_RDWR | O_CREAT, 0600));
     dp->device = volutil_GetPartitionID(path);
 #else
     strcpy(dp->devName, devname);
@@ -312,6 +314,59 @@ int VCheckPartition(part, devname)
 
     return 0;
 }
+
+/* VIsAlwaysAttach() checks whether a /vicepX directory should always be
+ * 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.
+ */
+static int VIsAlwaysAttach(part)
+    char *part;
+{
+#ifdef AFS_NAMEI_ENV
+    struct stat st;
+    char checkfile[256];
+    int ret;
+
+    if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE))
+       return 0;
+
+    strncpy(checkfile, part, 100);
+    strcat(checkfile, "/");
+    strcat(checkfile, VICE_ALWAYSATTACH_FILE);
+
+    ret = stat(checkfile, &st);
+    return (ret < 0) ? 0 : 1;
+#else  /* AFS_NAMEI_ENV */
+    return 0;
+#endif /* AFS_NAMEI_ENV */
+}
+
+/* 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 VAttachPartitions2() {
+#ifdef AFS_NAMEI_ENV
+    DIR *dirp;
+    struct dirent *de;
+    char pname[32];
+
+    dirp = opendir("/");
+    while (de = readdir(dirp)) {
+       strcpy(pname, "/");
+       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, "");
+    }
+    closedir(dirp);
+#endif /* AFS_NAMEI_ENV */
+}
 #endif /* AFS_NT40_ENV */
 
 #ifdef AFS_SUN5_ENV
@@ -332,11 +387,18 @@ int VAttachPartitions(void)
            (strncmp(mnt.mnt_mntopts, "ro,ignore",9) ==0)) 
            continue; 
 
+       /* If we're going to always attach this partition, do it later. */
+       if (VIsAlwaysAttach(mnt.mnt_mountp))
+           continue;
+
        if (VCheckPartition(mnt.mnt_mountp, mnt.mnt_special) < 0 )
            errors ++;
     }
 
-   (void) fclose(mntfile);
+    (void) fclose(mntfile);
+
+    /* Process the always-attach partitions, if any. */
+    VAttachPartitions2();
 
     return errors ;
 }
@@ -356,12 +418,19 @@ int VAttachPartitions(void)
     while (mntent = getmntent(mfd)) {
        if (!hasmntopt(mntent, MNTOPT_RW)) continue;
        
+       /* If we're going to always attach this partition, do it later. */
+       if (VIsAlwaysAttach(mntent->mnt_dir))
+           continue;
+
        if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname) < 0 )
            errors ++;
     }
 
     endmntent(mfd);
 
+    /* Process the always-attach partitions, if any. */
+    VAttachPartitions2();
+
     return errors ;
 }
 #endif
@@ -449,11 +518,18 @@ int VAttachPartitions(void)
        }
 #endif
 
+       /* If we're going to always attach this partition, do it later. */
+       if (VIsAlwaysAttach(part))
+           continue;
+
        if (VCheckPartition(part, vmt2dataptr(vmountp, VMT_OBJECT)) < 0 )
            errors ++;
     }
-    return errors ;
 
+    /* Process the always-attach partitions, if any. */
+    VAttachPartitions2();
+
+    return errors ;
 }
 #endif
 #if defined(AFS_DUX40_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
@@ -470,11 +546,18 @@ int VAttachPartitions(void)
     while (fsent = getfsent()) {
        if (strcmp(fsent->fs_type, "rw") != 0) continue;
 
+       /* If we're going to always attach this partition, do it later. */
+       if (VIsAlwaysAttach(fsent->fs_file))
+           continue;
+
        if (VCheckPartition(fsent->fs_file, fsent->fs_spec) < 0 )
            errors ++;
     }
     endfsent();
     
+    /* Process the always-attach partitions, if any. */
+    VAttachPartitions2();
+
     return errors ;
 }
 #endif
@@ -644,11 +727,18 @@ int VAttachPartitions(void)
        }
     }
     while (mntent = getmntent(mfd)) {
+       /* If we're going to always attach this partition, do it later. */
+       if (VIsAlwaysAttach(mntent->mnt_dir))
+           continue;
+
        if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname) < 0 )
            errors ++;
     }
     endmntent(mfd);
 
+    /* Process the always-attach partitions, if any. */
+    VAttachPartitions2();
+
     return errors ;
 }
 #endif /* AFS_LINUX22_ENV */
@@ -1001,7 +1091,7 @@ void VLockPartition_r(char *name)
        assert (lockf(dp->lock_fd, F_LOCK, 0) != -1); 
 #else
        assert (flock(dp->lock_fd, LOCK_EX) == 0);
-#endif /* defined(AFS_AIX_ENV) */
+#endif /* defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) */
 #endif
 }
 
index c641403..c583bd0 100644 (file)
 #define VICE_PARTITION_PREFIX  "/vicep"
 #define VICE_PREFIX_SIZE       (sizeof(VICE_PARTITION_PREFIX)-1)
 
+/* If a file by this name exists in a /vicepX directory, it means that
+ * this directory should be used as an AFS partition even if it's not
+ * on a separate partition (for instance if it's part of a large /).
+ * This feature only works with the NAMEI fileserver.
+ */
+#ifdef AFS_NAMEI_ENV
+#define VICE_ALWAYSATTACH_FILE "AlwaysAttach"
+#endif
+
 /* For NT, the roles of "name" and "devName" are reversed. That is, "name"
  * refers to the drive letter name and "devName" refers to the /vicep style
  * or name. The reason for this is that a lot of places assume that "name"
index 93bce59..048eeed 100644 (file)
@@ -1585,13 +1585,11 @@ struct rx_call *acid;
 struct pIDs *partIds;
 {   
     char namehead[9];
-    struct stat rbuf, pbuf;
     int code;
     char i;
 
     strcpy(namehead, "/vicep");        /*7 including null terminator*/
 
-#ifdef AFS_NT40_ENV
     /* Just return attached partitions. */
     namehead[7] = '\0';
     for (i=0; i<26; i++) {
@@ -1599,23 +1597,7 @@ struct pIDs *partIds;
        if (VGetPartition(namehead, 0))
            partIds->partIds[i] = VGetPartition(namehead, 0) ? i : -1;
     }
-#else
-    
-    (void) stat("/",&rbuf);    /*interested in buf->st_dev*/
-   
-    for(i = 0 ; i < 26 ; i++){
-       
-       namehead[6] = i + 'a';
-       namehead[7] = '\0';
-       code = stat(namehead,&pbuf);
-       if(!code){
-           if(rbuf.st_dev != pbuf.st_dev) /*the partition is mounted */
-               partIds->partIds[i] = i ;
-           else  partIds->partIds[i ] = -1;
-       }
-       else partIds->partIds[i ] = -1;
-    }
-#endif   
+
     return 0;
 }
 
@@ -1642,7 +1624,8 @@ struct partEntries *pEntries;
     int code, i, j=0, k;
 
     strcpy(namehead, "/vicep");        /*7 including null terminator*/
-#ifdef AFS_NT40_ENV
+
+    /* Only report attached partitions */
     for(i = 0 ; i < VOLMAXPARTS; i++){
        if (i < 26) {
            namehead[6] = i + 'a';
@@ -1660,28 +1643,6 @@ struct partEntries *pEntries;
     pEntries->partEntries_val = (afs_int32 *) malloc(j * sizeof(int));
     memcpy((char *)pEntries->partEntries_val, (char *)&partList, j * sizeof(int));
     pEntries->partEntries_len = j;
-#else
-    code = stat("/",&rbuf);    /*interested in buf->st_dev*/
-    for(i = 0 ; i < VOLMAXPARTS; i++){
-       if (i < 26) {
-           namehead[6] = i + 'a';
-           namehead[7] = '\0';
-       } else {
-           k = i - 26;
-           namehead[6] = 'a' + (k/26);
-           namehead[7] = 'a' + (k%26);
-           namehead[8] = '\0';
-       }
-       code = stat(namehead,&pbuf);
-       if(!code){
-           if(rbuf.st_dev != pbuf.st_dev) /*the partition is mounted */
-               partList.partId[j++] = i;
-       }
-    } 
-    pEntries->partEntries_val = (afs_int32 *) malloc(j * sizeof(int));
-    memcpy((char *)pEntries->partEntries_val, (char *)&partList, j * sizeof(int));
-    pEntries->partEntries_len = j;
-#endif
     return 0;
 
 }