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