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