1 #define _XOPEN_SOURCE 500
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
14 #include <linux/lustre_lib.h>
15 #include <linux/lustre_lite.h>
16 #include <linux/obd_lov.h>
18 /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
19 #define MAX_LOV_UUID_COUNT 1000
20 #define OBD_NOT_FOUND ((__u32)-1)
23 struct option longOpts[] = {
27 {"verbose", 0, 0, 'v'},
32 char * shortOpts = "ho:qv";
33 char * usageMsg = "[ --obd <obd uuid> | --query ] <dir|file> ...";
35 int max_ost_count = MAX_LOV_UUID_COUNT;
36 struct obd_uuid * obduuid;
41 struct obd_ioctl_data data;
43 struct obd_uuid * uuids;
46 struct lov_mds_md *lmm;
50 void usage(FILE *stream);
51 void errMsg(char *fmt, ...);
52 void processPath(char *path);
55 const struct stat *sp,
59 __u32 getobdindex(const char *path);
62 main (int argc, char **argv) {
65 cmd = basename(argv[0]);
67 while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) {
71 errMsg("obd '%s' already specified: '%s'.",
76 obduuid = (struct obd_uuid *)optarg;
91 errMsg("Internal error. Valid '%s' unrecognized.",
109 processPath(argv[optind]);
110 } while (++optind < argc);
118 int datalen, desclen;
120 datalen = size_round(sizeof(data));
121 desclen = size_round(sizeof(desc));
122 uuidslen = size_round(max_ost_count * sizeof(*uuids));
123 cfglen = datalen + desclen + uuidslen;
124 lmmlen = lov_mds_md_size(max_ost_count);
130 /* XXX max ioctl buffer size currently hardcoded to 8192 */
132 int nuuids, remaining, nluoinfos;
135 nuuids = (buflen - datalen - desclen) / sizeof(*uuids);
136 uuidslen = size_round(nuuids * sizeof(*uuids));
137 remaining = nuuids * sizeof(*uuids);
138 if (uuidslen > remaining)
140 nluoinfos = (buflen - sizeof(*lmm)) / sizeof(*lmm->lmm_objects);
141 if (nuuids > nluoinfos)
142 max_ost_count = nluoinfos;
144 max_ost_count = nuuids;
146 cfglen = datalen + desclen + uuidslen;
147 lmmlen = lov_mds_md_size(max_ost_count);
150 if ((buf = malloc(buflen)) == NULL) {
151 errMsg("Unable to allocate %d bytes of memory for ioctl's.",
156 lmm = (struct lov_mds_md *)buf;
157 uuids = (struct obd_uuid *)buf;
163 fprintf(stream, "usage: %s %s\n", cmd, usageMsg);
167 errMsg(char *fmt, ...)
171 fprintf(stderr, "%s: ", cmd);
173 vfprintf(stderr, fmt, args);
175 fprintf(stderr, "\n");
179 processPath(char *path)
181 obdindex = OBD_NOT_FOUND;
182 nftw((const char *)path, processFile, 128, FTW_PHYS|FTW_MOUNT);
186 processFile(const char *path, const struct stat *sp, int flag, struct FTW *ftwp)
196 if (getobdindex(path) == OBD_NOT_FOUND && obdcount == 0) {
197 /* terminate nftw walking this tree */
201 if ((fd = open(path, O_RDONLY | O_LOV_DELAY_CREATE)) < 0) {
202 errMsg("open \"%.20s\" failed.", path);
207 memset((void *)buf, 0, buflen);
208 lmm->lmm_magic = LOV_MAGIC;
209 lmm->lmm_ost_count = max_ost_count;
211 if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lmm)) < 0) {
212 errMsg("LL_IOC_LOV_GETSTRIPE ioctl failed.");
219 if (query || verbose ||
220 (obdindex != OBD_NOT_FOUND &&
221 lmm->lmm_objects[obdindex].l_object_id))
222 printf("%s\n", path);
225 printf("lmm_magic: 0x%x\n", lmm->lmm_magic);
226 printf("lmm_object_id: "LPX64"\n", lmm->lmm_object_id);
227 printf("lmm_stripe_offset: %u\n", (int)lmm->lmm_stripe_offset);
228 printf("lmm_stripe_count: %u\n", (int)lmm->lmm_stripe_count);
229 printf("lmm_stripe_size: %u\n", (int)lmm->lmm_stripe_size);
230 printf("lmm_ost_count: %u\n", lmm->lmm_ost_count);
231 printf("lmm_stripe_pattern: %d\n", lmm->lmm_magic & 0xf);
234 count = lmm->lmm_ost_count;
236 if (query || verbose) {
238 int ost = lmm->lmm_stripe_offset;
241 for (i = 0; i < count; i++, ost++) {
242 ost %= lmm->lmm_ost_count;
243 if ((oid = lmm->lmm_objects[ost].l_object_id)) {
245 printf("\tobdidx\t objid\n");
248 printf("\t%6u\t%8llu%s\n",
249 ost, oid, obdindex == ost ? " *" : "");
261 getobdindex(const char *path)
263 struct obd_uuid *uuidp;
268 if ((fd = open(path, O_RDONLY)) < 0) {
269 errMsg("open \"%.20s\" failed.", path);
274 data.ioc_inllen1 = sizeof(desc);
275 data.ioc_inlbuf1 = (char *)&desc;
276 data.ioc_inllen2 = uuidslen;
277 data.ioc_inlbuf2 = (char *)uuids;
278 data.ioc_inllen3 = 0;
280 memset(&desc, 0, sizeof(desc));
281 desc.ld_tgt_count = max_ost_count;
283 if (obd_ioctl_pack(&data, &buf, buflen)) {
284 errMsg("internal buffering error.");
288 rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
290 errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %d.", errno);
295 if (obd_ioctl_unpack(&data, buf, buflen)) {
296 errMsg("Invalid reply from ioctl.");
302 obdcount = desc.ld_tgt_count;
304 if (query || verbose) {
306 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
307 printf("%4d: %s\n", i, (char *)uuidp);
312 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
313 rc = strncmp((const char *)obduuid, (const char *)uuidp,
321 if (obdindex == OBD_NOT_FOUND) {
322 errMsg("obd UUID '%s' not found.", obduuid);
323 return(OBD_NOT_FOUND);