install-vlib-as-libvlib-also-20010712
[openafs.git] / src / vol / xfs_size_check.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 /* Verify that the size of the XFS inode is large enough to hold the XFS
11  * attribute for AFS inode parameters. Check all the mounted /vicep partitions.
12 #include <afsconfig.h>
13
14 RCSID("$Header$");
15
16  */
17 #include <afs/param.h>
18 #ifdef AFS_SGI_XFS_IOPS_ENV
19 #include <errno.h>
20 #include <sys/stat.h>
21 #include <stdio.h>
22 #include <dirent.h>
23 #include <fcntl.h>
24 #include <mntent.h>
25 #include "partition.h"
26 #ifdef AFS_SGI_EFS_IOPS_ENV
27 #include "../sgiefs/efs.h"
28 #endif
29 #include <afs/xfsattrs.h>
30
31 char *prog = "xfs_size_check";
32
33 /* Verify that the on disk XFS inodes on the partition are large enough to
34  * hold the AFS attribute. Returns -1 if the attribute can't be set or is
35  * too small to fit in the inode. Returns 0 if the attribute does fit in
36  * the XFS inode.
37  */
38 #define VERIFY_ERROR   -1
39 #define VERIFY_OK       0
40 #define VERIFY_FIX      1
41 static int VerifyXFSInodeSize(char *part)
42 {
43     afs_xfs_attr_t junk;
44     int length = SIZEOF_XFS_ATTR_T;
45     int fd;
46     int code = VERIFY_ERROR;
47     struct fsxattr fsx;
48
49     if (attr_set(part, AFS_XFS_ATTR, &junk, length, ATTR_ROOT)<0) {
50         if (errno == EPERM) {
51             printf("Must be root to run %s\n", prog);
52             exit(1);
53         }
54         return VERIFY_ERROR;
55     }
56
57     if ((fd=open(part, O_RDONLY, 0))<0)
58         goto done;
59
60     if (fcntl(fd, F_FSGETXATTRA, &fsx)<0)
61         goto done;
62         
63     if (fsx.fsx_nextents == 0)
64         code = VERIFY_OK;
65     else
66         code = VERIFY_FIX;
67
68  done:
69     if (fd>=0)
70         close(fd);
71     (void) attr_remove(part, AFS_XFS_ATTR, ATTR_ROOT);
72
73     return code;
74 }
75
76 #define ALLOC_STEP 256
77 #define NAME_SIZE 64
78 typedef struct {
79     char partName[NAME_SIZE];
80     char devName[NAME_SIZE];
81 } partInfo;
82 partInfo *partList = NULL;
83 int nParts = 0;
84 int nAvail = 0;
85
86 int CheckPartitions()
87     {
88     int i;
89     struct mntent *mntent;
90     FILE *mfd;
91     DIR *dirp;
92     struct dirent *dp;
93     struct stat status;
94     int code;
95
96     if ((mfd = setmntent(MOUNTED, "r")) == NULL) {
97         printf("Problems in getting mount entries(setmntent): %s\n",
98                strerror(errno));
99         exit(-1);
100     }
101     while (mntent = getmntent(mfd)) {
102         char *part = mntent->mnt_dir;
103
104         if (!hasmntopt(mntent, MNTOPT_RW)) continue;
105
106         if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
107             continue;           /* Non /vicepx; ignore */
108         }
109         if (stat(part, &status) == -1) {
110             printf("Couldn't find file system %s; ignored\n", part);
111             continue;
112         }
113         if (!strcmp("xfs", status.st_fstype)) {
114             code = VerifyXFSInodeSize(part);
115             switch (code) {
116             case VERIFY_OK:
117                 break;
118             case VERIFY_ERROR:
119                 printf("%s: Can't check XFS inode size: %s\n", strerror(errno));
120                 break;
121             case VERIFY_FIX:
122                 if (nAvail <= nParts) {
123                     nAvail += ALLOC_STEP; 
124                     if (nAvail == ALLOC_STEP)
125                         partList = (partInfo*)malloc(nAvail*sizeof(partInfo));
126                     else
127                         partList = (partInfo*)realloc((char*)partList,
128                                                       nAvail*sizeof(partInfo));
129                     if (!partList) {
130                         printf("Failed to %salloc %d bytes for partition list.\n",
131                                (nAvail == ALLOC_STEP) ? "m" : "re",
132                                nAvail*sizeof(partInfo));
133                         exit(1);
134                     }
135                 }
136                 (void) strcpy(partList[nParts].partName, part);
137                 (void) strcpy(partList[nParts].devName, mntent->mnt_fsname);
138                 nParts ++;
139                 break;
140             default:
141                 printf("Unknown return code %d from VerifyXFSInodeSize.\n",
142                        code);
143                 abort();
144             }
145         }
146     }
147     return nParts;
148 }
149
150
151 main(int ac, char **av)
152 {
153     int i;
154     int code;
155
156     if (getuid()) {
157         printf("Must be root to run %s.\n", prog);
158         exit(1);
159     }
160
161     code = CheckPartitions();
162     if (code) {
163         printf("Need to remake the following partitions:\n");
164         for (i=0; i<nParts; i++) {
165             printf("%s: mkfs -t xfs -i size=512 -l size=4000b %s\n",
166                    partList[i].partName, partList[i].devName);
167         }
168     }
169     exit (code ? 1 : 0);
170 }
171     
172
173 #else /* AFS_SGI_XFS_IOPS_ENV */
174 main() {printf("%s only runs on XFS platforms.\n, prog"); exit(1); }
175 #endif /* AFS_SGI_XFS_IOPS_ENV */