1 #define _XOPEN_SOURCE 500
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
15 #include <linux/lustre_lib.h>
16 #include <linux/lustre_lite.h>
17 #include <linux/obd_lov.h>
19 /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
20 #define MAX_LOV_UUID_COUNT 1000
21 #define OBD_NOT_FOUND ((__u32)-1)
24 struct option longOpts[] = {
28 {"verbose", 0, 0, 'v'},
33 char * shortOpts = "ho:qv";
34 char * usageMsg = "[ --obd <obd uuid> | --query ] <dir|file> ...";
36 int max_ost_count = MAX_LOV_UUID_COUNT;
42 struct obd_ioctl_data data;
47 struct lov_mds_md *lmm;
51 void usage(FILE *stream);
52 void errMsg(char *fmt, ...);
53 void processPath(char *path);
56 const struct stat *sp,
60 __u32 getobdindex(const char *path);
63 main (int argc, char **argv) {
66 cmd = basename(argv[0]);
68 while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) {
72 errMsg("obd '%s' already specified: '%s'.",
77 obduuid = (obd_uuid_t *)optarg;
92 errMsg("Internal error. Valid '%s' unrecognized.",
110 processPath(argv[optind]);
111 } while (++optind < argc);
119 int datalen, desclen;
121 datalen = size_round(sizeof(data));
122 desclen = size_round(sizeof(desc));
123 uuidslen = size_round(max_ost_count * sizeof(*uuids));
124 cfglen = datalen + desclen + uuidslen;
125 lmmlen = lov_mds_md_size(max_ost_count);
131 /* XXX max ioctl buffer size currently hardcoded to 8192 */
133 int nuuids, remaining, nluoinfos;
136 nuuids = (buflen - datalen - desclen) / sizeof(*uuids);
137 uuidslen = size_round(nuuids * sizeof(*uuids));
138 remaining = nuuids * sizeof(*uuids);
139 if (uuidslen > remaining)
141 nluoinfos = (buflen - sizeof(*lmm)) / sizeof(*lmm->lmm_objects);
142 if (nuuids > nluoinfos)
143 max_ost_count = nluoinfos;
145 max_ost_count = nuuids;
147 cfglen = datalen + desclen + uuidslen;
148 lmmlen = lov_mds_md_size(max_ost_count);
151 if ((buf = malloc(buflen)) == NULL) {
152 errMsg("Unable to allocate %d bytes of memory for ioctl's.",
157 lmm = (struct lov_mds_md *)buf;
158 uuids = (obd_uuid_t *)buf;
164 fprintf(stream, "usage: %s %s\n", cmd, usageMsg);
168 errMsg(char *fmt, ...)
172 fprintf(stderr, "%s: ", cmd);
174 vfprintf(stderr, fmt, args);
176 fprintf(stderr, "\n");
180 processPath(char *path)
182 obdindex = OBD_NOT_FOUND;
183 nftw((const char *)path, processFile, 128, FTW_PHYS|FTW_MOUNT);
187 processFile(const char *path, const struct stat *sp, int flag, struct FTW *ftwp)
197 if (getobdindex(path) == OBD_NOT_FOUND && obdcount == 0) {
198 /* terminate nftw walking this tree */
202 if ((fd = open(path, O_RDONLY | O_LOV_DELAY_CREATE)) < 0) {
203 errMsg("open \"%.20s\" failed.", path);
208 memset((void *)buf, 0, buflen);
209 lmm->lmm_magic = LOV_MAGIC;
210 lmm->lmm_ost_count = max_ost_count;
212 if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lmm)) < 0) {
213 errMsg("LL_IOC_LOV_GETSTRIPE ioctl failed.");
220 if (query || verbose ||
221 (obdindex != OBD_NOT_FOUND &&
222 lmm->lmm_objects[obdindex].l_object_id))
223 printf("%s\n", path);
226 printf("lmm_magic: 0x%x\n", lmm->lmm_magic);
227 printf("lmm_object_id: "LPX64"\n", lmm->lmm_object_id);
228 printf("lmm_stripe_offset: %u\n", (int)lmm->lmm_stripe_offset);
229 printf("lmm_stripe_count: %u\n", (int)lmm->lmm_stripe_count);
230 printf("lmm_stripe_size: %u\n", (int)lmm->lmm_stripe_size);
231 printf("lmm_ost_count: %u\n", lmm->lmm_ost_count);
232 printf("lmm_stripe_pattern: %d\n", lmm->lmm_magic & 0xf);
235 count = lmm->lmm_ost_count;
237 if (query || verbose) {
239 int ost = lmm->lmm_stripe_offset;
242 for (i = 0; i < count; i++, ost++) {
243 ost %= lmm->lmm_ost_count;
244 if ((oid = lmm->lmm_objects[ost].l_object_id)) {
246 printf("\tobdidx\t objid\n");
249 printf("\t%6u\t%8llu%s\n",
250 ost, oid, obdindex == ost ? " *" : "");
262 getobdindex(const char *path)
269 if ((fd = open(path, O_RDONLY)) < 0) {
270 errMsg("open \"%.20s\" failed.", path);
275 data.ioc_inllen1 = sizeof(desc);
276 data.ioc_inlbuf1 = (char *)&desc;
277 data.ioc_inllen2 = uuidslen;
278 data.ioc_inlbuf2 = (char *)uuids;
279 data.ioc_inllen3 = 0;
281 memset(&desc, 0, sizeof(desc));
282 desc.ld_tgt_count = max_ost_count;
284 if (obd_ioctl_pack(&data, &buf, buflen)) {
285 errMsg("internal buffering error.");
289 rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
291 errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %d.", errno);
296 if (obd_ioctl_unpack(&data, buf, buflen)) {
297 errMsg("Invalid reply from ioctl.");
303 obdcount = desc.ld_tgt_count;
305 if (query || verbose) {
307 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
308 printf("%4d: %s\n", i, (char *)uuidp);
313 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
314 rc = strncmp((const char *)obduuid, (const char *)uuidp,
322 if (obdindex == OBD_NOT_FOUND) {
323 errMsg("obd UUID '%s' not found.", obduuid);
324 return(OBD_NOT_FOUND);