DAFS: Avoid unnecessary preattach on FSYNC_VOL_ON
[openafs.git] / src / vol / devname.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #include <ctype.h>
16
17 #include <rx/xdr.h>
18 #include <afs/afsint.h>
19
20 #if !defined(AFS_SGI_ENV)
21 #ifdef  AFS_OSF_ENV
22 #include <ufs/fs.h>
23 #else /* AFS_OSF_ENV */
24 #ifdef AFS_VFSINCL_ENV
25 #define VFS
26 #ifdef  AFS_SUN5_ENV
27 #include <sys/fs/ufs_fs.h>
28 #else
29 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
30 #include <ufs/ufs/dinode.h>
31 #include <ufs/ffs/fs.h>
32 #else
33 #include <ufs/fs.h>
34 #endif
35 #endif
36 #else /* AFS_VFSINCL_ENV */
37 #if !defined(AFS_AIX_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_DARWIN_ENV)
38 #include <sys/fs.h>
39 #endif
40 #endif /* AFS_VFSINCL_ENV */
41 #endif /* AFS_OSF_ENV */
42 #endif /* AFS_SGI_ENV */
43 #include <sys/file.h>
44 #ifdef  AFS_AIX_ENV
45 #include <sys/vfs.h>
46 #else
47 #ifdef  AFS_HPUX_ENV
48 #include <mntent.h>
49 #else
50 #if     defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
51 #ifdef  AFS_SUN5_ENV
52 #include <sys/mnttab.h>
53 #include <sys/mntent.h>
54 #else
55 #include <mntent.h>
56 #endif
57 #else
58 #if defined(AFS_SGI_ENV)
59 #include <mntent.h>
60 #else
61 #ifdef AFS_LINUX22_ENV
62 #include <mntent.h>
63 #else
64 #include <fstab.h>
65 #endif
66 #endif
67 #endif /* AFS_SGI_ENV */
68 #endif /* AFS_HPUX_ENV */
69 #endif
70 #include <sys/wait.h>
71 #include <setjmp.h>
72
73 #include "ihandle.h"
74 #include "partition.h"
75
76 /* ensure that we don't have a "/" instead of a "/dev/rxd0a" type of device.
77  * returns pointer to static storage; copy it out quickly!
78  */
79 char *
80 vol_DevName(dev_t adev, char *wpath)
81 {
82     static char pbuffer[128];
83     char pbuf[128], *ptr;
84 #ifdef  AFS_SUN5_ENV
85     struct mnttab mnt;
86     FILE *mntfile;
87 #else
88 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
89     struct mntent *mntent;
90     FILE *mfd;
91 #else
92     struct fstab *fsent;
93 #endif
94 #endif
95 #ifdef  AFS_AIX_ENV
96     int nmounts;
97     struct vmount *vmountp;
98 #endif
99
100 #ifdef  AFS_AIX_ENV
101     if ((nmounts = getmount(&vmountp)) <= 0) {
102         return NULL;
103     }
104     for (; nmounts;
105          nmounts--, vmountp =
106          (struct vmount *)((int)vmountp + vmountp->vmt_length)) {
107         char *part = vmt2dataptr(vmountp, VMT_STUB);
108 #else
109 #ifdef  AFS_SUN5_ENV
110     if (!(mntfile = fopen(MNTTAB, "r"))) {
111         return NULL;
112     }
113     while (!getmntent(mntfile, &mnt)) {
114         char *part = mnt.mnt_mountp;
115 #else
116 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
117 #ifdef AFS_LINUX22_ENV
118     if ((mfd = setmntent("/proc/mounts", "r")) == NULL) {
119         if ((mfd = setmntent("/etc/mtab", "r")) == NULL) {
120             return NULL;
121         }
122     }
123 #else
124     if ((mfd = setmntent(MOUNTED /*MNTTAB*/, "r")) == NULL) {
125         return NULL;
126     }
127 #endif
128     while ((mntent = getmntent(mfd))) {
129         char *part = mntent->mnt_dir;
130 #else
131     setfsent();
132     while ((fsent = getfsent())) {
133         char *part = fsent->fs_file;
134 #endif
135 #endif /* AFS_SGI_ENV */
136 #endif
137         struct stat status;
138 #ifdef  AFS_AIX_ENV
139         if (vmountp->vmt_flags & (MNT_READONLY | MNT_REMOVABLE | MNT_REMOTE))
140             continue;           /* Ignore any "special" partitions */
141 #else
142 #ifdef  AFS_SUN5_ENV
143         /* Ignore non ufs or non read/write partitions */
144         if ((strcmp(mnt.mnt_fstype, "ufs") != 0)
145             || (strncmp(mnt.mnt_mntopts, "ro,ignore", 9) == 0))
146             continue;
147 #else
148 #if defined(AFS_LINUX22_ENV)
149         if (strcmp(mntent->mnt_type, "ext2"))
150             continue;
151 #else
152 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV)
153         if (!hasmntopt(mntent, MNTOPT_RW))
154             continue;
155 #else
156         if (strcmp(fsent->fs_type, "rw") != 0)
157             continue;           /* Ignore non read/write partitions */
158 #endif /* AFS_LINUX22_ENV */
159 #endif /* AFS_SGI_ENV */
160 #endif
161 #endif
162         /* Only keep track of "/vicepx" partitions since it can get hairy when NFS mounts are involved.. */
163         if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
164             continue;           /* Non /vicepx; ignore */
165         }
166         if (stat(part, &status) == -1) {
167             continue;
168         }
169 #if !defined(AFS_SGI_XFS_IOPS_ENV) && !defined(AFS_LINUX22_ENV) && !defined(AFS_DARWIN_ENV)
170         if ((status.st_ino !=
171              ROOTINO) /*|| ((status.st_mode & S_IFMT) != S_IFBLK) */ ) {
172             continue;
173         }
174 #endif
175         if (status.st_dev == adev) {
176 #ifdef  AFS_AIX_ENV
177             strcpy(pbuffer, vmt2dataptr(vmountp, VMT_OBJECT));
178 #else
179 #ifdef  AFS_SUN5_ENV
180             strcpy(pbuffer, mnt.mnt_special);
181 #else
182 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
183             strcpy(pbuffer, mntent->mnt_fsname);
184 #else
185             strcpy(pbuffer, fsent->fs_spec);
186 #endif
187 #endif /* AFS_SGI_ENV */
188 #endif
189             if (wpath) {
190                 strcpy(pbuf, pbuffer);
191                 ptr = (char *)strrchr(pbuf, OS_DIRSEPC);
192                 if (ptr) {
193                     *ptr = '\0';
194                     strcpy(wpath, pbuf);
195                 } else
196                     return NULL;
197             }
198             ptr = (char *)strrchr(pbuffer, OS_DIRSEPC);
199             if (ptr) {
200                 strcpy(pbuffer, ptr + 1);
201                 return pbuffer;
202             } else
203                 return NULL;
204         }
205     }
206 #ifdef  AFS_SUN5_ENV
207     (void)fclose(mntfile);
208 #else
209 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
210     endmntent(mfd);
211 #else
212 #ifndef AFS_AIX_ENV
213     endfsent();
214 #endif
215 #endif
216 #endif /* AFS_SGI_ENV */
217     return NULL;
218 }
219
220 /* Search for the raw device name. Will put an "r" in front of each
221  * directory and file entry of the pathname until we find a character
222  * device.
223  */
224 char *
225 afs_rawname(char *devfile)
226 {
227     static char rawname[100];
228     struct stat statbuf;
229     int code, i;
230
231     i = strlen(devfile);
232     while (i >= 0) {
233         strcpy(rawname, devfile);
234         if (devfile[i] == OS_DIRSEPC) {
235             rawname[i + 1] = 'r';
236             rawname[i + 2] = 0;
237             strcat(rawname, &devfile[i + 1]);
238         }
239
240         code = stat(rawname, &statbuf);
241         if (!code && S_ISCHR(statbuf.st_mode))
242             return rawname;
243
244         while ((--i >= 0) && (devfile[i] != OS_DIRSEPC));
245     }
246
247     return NULL;
248 }