10 #include <sys/ioctl.h>
11 #include <sys/types.h>
14 #include <liblustre.h>
15 #include <linux/obd.h>
16 #include <linux/lustre_lib.h>
17 #include <linux/lustre_lite.h>
18 #include <linux/obd_lov.h>
20 /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
21 #define MAX_LOV_UUID_COUNT 1000
22 #define OBD_NOT_FOUND (-1)
25 struct option longOpts[] = {
29 {"verbose", 0, 0, 'v'},
34 char shortOpts[] = "ho:qv";
35 char usageMsg[] = "[ --obd <obd uuid> | --query ] <dir|file> ...";
37 int max_ost_count = MAX_LOV_UUID_COUNT;
38 struct obd_uuid *obduuid;
41 struct obd_uuid *uuids;
42 struct obd_ioctl_data data;
46 struct lov_mds_md *lmm;
51 void usage(FILE *stream);
52 void errMsg(char *fmt, ...);
53 void processPath(char *path);
55 int main (int argc, char **argv) {
58 cmd = basename(argv[0]);
60 while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) {
64 printf("obd '%s' already specified: '%s'\n",
65 obduuid->uuid, optarg);
69 obduuid = (struct obd_uuid *)optarg;
84 printf("Internal error. Valid '%s' unrecognized\n",
102 processPath(argv[optind]);
103 } while (++optind < argc);
110 int datalen, desclen;
112 datalen = size_round(sizeof(data));
113 desclen = size_round(sizeof(desc));
114 uuidslen = size_round(max_ost_count * sizeof(*uuids));
115 cfglen = datalen + desclen + uuidslen;
116 lmmlen = lov_mds_md_size(max_ost_count);
122 /* XXX max ioctl buffer size currently hardcoded to 8192 */
124 int nuuids, remaining, nluoinfos;
127 nuuids = (buflen - datalen - desclen) / sizeof(*uuids);
128 uuidslen = size_round(nuuids * sizeof(*uuids));
129 remaining = nuuids * sizeof(*uuids);
130 if (uuidslen > remaining)
132 nluoinfos = (buflen - sizeof(*lmm)) / sizeof(*lmm->lmm_objects);
133 if (nuuids > nluoinfos)
134 max_ost_count = nluoinfos;
136 max_ost_count = nuuids;
138 cfglen = datalen + desclen + uuidslen;
139 lmmlen = lov_mds_md_size(max_ost_count);
142 if ((buf = malloc(buflen)) == NULL) {
143 errMsg("Unable to allocate %d bytes of memory for ioctl's");
147 lmm = (struct lov_mds_md *)buf;
148 uuids = (struct obd_uuid *)buf;
151 void usage(FILE *stream)
153 fprintf(stream, "usage: %s %s\n", cmd, usageMsg);
156 void errMsg(char *fmt, ...)
159 int tmp_errno = errno;
161 fprintf(stderr, "%s: ", cmd);
163 vfprintf(stderr, fmt, args);
165 fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
168 void processPath(char *path)
173 int obdindex = OBD_NOT_FOUND;
175 struct obd_uuid *uuidp;
176 char *fname, *dirname;
178 if ((query || verbose) && !obduuid) {
179 printf("%s\n", path);
182 fname = strrchr(path, '/');
183 if (fname != NULL && fname[1] != '\0') {
187 } else if (fname != NULL && fname[1] == '\0') {
188 printf("need getdents support\n");
195 if ((fd = open(dirname, O_RDONLY)) < 0) {
196 errMsg("open \"%.20s\" failed", dirname);
200 if (!printed_UUIDs) {
201 memset(&data, 0, sizeof(data));
202 data.ioc_inllen1 = sizeof(desc);
203 data.ioc_inlbuf1 = (char *)&desc;
204 data.ioc_inllen2 = uuidslen;
205 data.ioc_inlbuf2 = (char *)uuids;
207 memset(&desc, 0, sizeof(desc));
208 desc.ld_tgt_count = max_ost_count;
210 if (obd_ioctl_pack(&data, &buf, buflen)) {
211 errMsg("internal buffering error");
215 rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
217 if (errno == ENOTTY) {
219 errMsg("error getting LOV config");
223 errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %s");
227 if (obd_ioctl_unpack(&data, buf, buflen)) {
228 errMsg("Invalid reply from ioctl");
232 obdcount = desc.ld_tgt_count;
236 obdindex = OBD_NOT_FOUND;
239 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
240 if (strncmp((char *)obduuid, (char *)uuidp,
241 sizeof(*uuidp)) == 0) {
246 if (obdindex == OBD_NOT_FOUND)
248 } else if (query || verbose) {
250 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
251 printf("%4d: %s\n", i, (char *)uuidp);
256 strcpy((char *)lmm, fname);
257 rc = ioctl(fd, IOC_MDC_GETSTRIPE, (void *)lmm);
259 if (errno == ENODATA) {
261 printf("Has no stripe information.\n");
264 errMsg("IOC_MDC_GETSTRIPE ioctl failed");
271 if (obduuid && lmm->lmm_objects[obdindex].l_object_id)
272 printf("%s\n", path);
275 printf("lmm_magic: 0x%x\n", lmm->lmm_magic);
276 printf("lmm_object_id: "LPX64"\n", lmm->lmm_object_id);
277 printf("lmm_stripe_offset: %u\n", (int)lmm->lmm_stripe_offset);
278 printf("lmm_stripe_count: %u\n", (int)lmm->lmm_stripe_count);
279 printf("lmm_stripe_size: %u\n", (int)lmm->lmm_stripe_size);
280 printf("lmm_ost_count: %u\n", lmm->lmm_ost_count);
281 printf("lmm_stripe_pattern: %d\n", lmm->lmm_magic & 0xf);
284 if (query || verbose) {
286 int ost = lmm->lmm_stripe_offset;
289 for (i = 0; i < lmm->lmm_ost_count; i++, ost++) {
290 ost %= lmm->lmm_ost_count;
291 if ((oid = lmm->lmm_objects[ost].l_object_id)) {
293 printf("\tobdidx\t objid\n");
296 printf("\t%6u\t%8llu%s\n",
297 ost, oid, obdindex == ost ? " *" : "");