Salvager: Don't use garbage vnodes when Testing
[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 =
124                             (partInfo *) malloc(nAvail * sizeof(partInfo));
125                     else
126                         partList =
127                             (partInfo *) realloc((char *)partList,
128                                                  nAvail * sizeof(partInfo));
129                     if (!partList) {
130                         printf
131                             ("Failed to %salloc %d bytes for partition list.\n",
132                              (nAvail == ALLOC_STEP) ? "m" : "re",
133                              nAvail * sizeof(partInfo));
134                         exit(1);
135                     }
136                 }
137                 (void)strcpy(partList[nParts].partName, part);
138                 (void)strcpy(partList[nParts].devName, mntent->mnt_fsname);
139                 nParts++;
140                 break;
141             default:
142                 printf("Unknown return code %d from VerifyXFSInodeSize.\n",
143                        code);
144                 abort();
145             }
146         }
147     }
148     return nParts;
149 }
150
151
152 main(int ac, char **av)
153 {
154     int i;
155     int code;
156
157     if (getuid()) {
158         printf("Must be root to run %s.\n", prog);
159         exit(1);
160     }
161
162     code = CheckPartitions();
163     if (code) {
164         printf("Need to remake the following partitions:\n");
165         for (i = 0; i < nParts; i++) {
166             printf("%s: mkfs -t xfs -i size=512 -l size=4000b %s\n",
167                    partList[i].partName, partList[i].devName);
168         }
169     }
170     exit(code ? 1 : 0);
171 }
172
173
174 #else /* AFS_SGI_XFS_IOPS_ENV */
175 main()
176 {
177     printf("%s only runs on XFS platforms.\n, prog");
178     exit(1);
179 }
180 #endif /* AFS_SGI_XFS_IOPS_ENV */