Created
July 9, 2014 19:06
-
-
Save nedbass/f5eb28da0f0886dffa55 to your computer and use it in GitHub Desktop.
llapi: get OST count from /proc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 6df9cc253cbcde4a912dd42f106015fdd74ca695 | |
Author: Ned Bass <bass6@llnl.gov> | |
Date: Wed Nov 6 11:17:12 2013 -0800 | |
LLNL-0000 llapi: get OST count from proc | |
Add a fallback method to llapi_get_obd_count() for getting the number | |
of OSTs in the filesystem. If the ioctl() method fails, try to count | |
the OSTs by examining the target_obd file under /proc. This method | |
requires inferring the Lustre filesystem name by comparing the | |
user-supplied path to the mount points in the system table of mounted | |
file systems. This is neither efficient nor robust, but it provides a | |
workaround for applications requiring this functionality on systems | |
where the ioctl() method is not supported (i.e. BGQ). | |
Signed-off-by: Ned Bass <bass6@llnl.gov> | |
Change-Id: I68d82be7f83dd16e61db16edb0a630325df52e11 | |
diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c | |
index cc747d0..5cb58ad 100644 | |
--- a/lustre/utils/liblustreapi.c | |
+++ b/lustre/utils/liblustreapi.c | |
@@ -1702,6 +1702,117 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) | |
return llapi_get_target_uuids(fd, uuidp, ost_count, LOV_TYPE); | |
} | |
+/* | |
+ * Given a path, determines the Lustre filesystem name by examining | |
+ * entries in the mounted filesystem table. On success, stores up to | |
+ * \a n bytes of the filesystem name in \a fsname and returns 0. On | |
+ * failure, the contents of \a fsname are undefined and -1 is returned. | |
+ */ | |
+static int llapi_fsname_from_path(const char *path, char *fsname, size_t n) | |
+{ | |
+ char resolved[PATH_MAX]; | |
+ struct mntent *mnt; | |
+ FILE *fp; | |
+ char *p; | |
+ int rc = -1; | |
+ | |
+ if (realpath(path, resolved) == NULL) | |
+ return -1; | |
+ | |
+ fp = setmntent(MOUNTED, "r"); | |
+ if (fp == NULL) | |
+ return -1; | |
+ | |
+ while ((mnt = getmntent(fp)) != NULL) { | |
+ if (!llapi_is_lustre_mnt(mnt)) | |
+ continue; | |
+ p = strstr(resolved, mnt->mnt_dir); | |
+ if (p != resolved) | |
+ continue; | |
+ | |
+ /* The mount point is a prefix of path. The Lustre fsname is | |
+ * the string following '/' in the mount fsname. */ | |
+ p = strrchr(mnt->mnt_fsname, '/'); | |
+ if (p == NULL) | |
+ break; | |
+ p = p + 1; | |
+ strncpy(fsname, p, n); | |
+ rc = 0; | |
+ break; | |
+ } | |
+ endmntent(fp); | |
+ return rc; | |
+} | |
+ | |
+/* | |
+ * Given a Lustre filesystem name, determines the path to the LMV | |
+ * target_obd file in /proc. This is a helper function for use in | |
+ * determining the number of OSTs in a Lustre fileysstem. On success, | |
+ * stores up to \a n bytes of the target_obd path in \a target_obd and | |
+ * returns 0. On failure, the contents of \a target_obd are undefined | |
+ * and -1 is returned. | |
+ */ | |
+static int llapi_target_obd_from_fsname(const char *fsname, char *target_obd, | |
+ size_t n) | |
+{ | |
+ char clilov[PATH_MAX]; | |
+ const char *lovdir = "/proc/fs/lustre/lov"; | |
+ char *p; | |
+ DIR *dir; | |
+ struct dirent *dp; | |
+ int rc = -1; | |
+ | |
+ dir = opendir(lovdir); | |
+ if (dir == NULL) | |
+ return rc; | |
+ | |
+ snprintf(clilov, sizeof(clilov), "%s-clilov-", fsname); | |
+ while ((dp = readdir(dir)) != NULL) { | |
+ p = strstr(dp->d_name, clilov); | |
+ if (p == dp->d_name) | |
+ break; | |
+ } | |
+ | |
+ if (dp == NULL) | |
+ return -1; | |
+ | |
+ snprintf(target_obd, n, "/proc/fs/lustre/lov/%s/target_obd", | |
+ dp->d_name); | |
+ return 0; | |
+} | |
+ | |
+static int llapi_get_ost_count_from_proc(const char *path, int *count) | |
+{ | |
+ int rc; | |
+ char fsname[PATH_MAX]; | |
+ char target_obd[PATH_MAX]; | |
+ char *line; | |
+ FILE *fp; | |
+ size_t n = LINE_MAX; | |
+ | |
+ rc = llapi_fsname_from_path(path, fsname, sizeof(fsname)); | |
+ if (rc < 0) | |
+ return rc; | |
+ | |
+ rc = llapi_target_obd_from_fsname(fsname, target_obd, | |
+ sizeof(target_obd)); | |
+ if (rc < 0) | |
+ return rc; | |
+ | |
+ fp = fopen(target_obd, "r"); | |
+ if (fp == NULL) | |
+ return -1; | |
+ | |
+ *count = 0; | |
+ line = malloc(n); | |
+ while (getline(&line, &n, fp) >= 0) | |
+ (*count)++; | |
+ free(line); | |
+ | |
+ fclose(fp); | |
+ return 0; | |
+} | |
+ | |
int llapi_get_obd_count(char *mnt, int *count, int is_mdt) | |
{ | |
DIR *root; | |
@@ -1718,8 +1829,11 @@ int llapi_get_obd_count(char *mnt, int *count, int is_mdt) | |
rc = ioctl(dirfd(root), LL_IOC_GETOBDCOUNT, count); | |
if (rc < 0) | |
rc = -errno; | |
- | |
closedir(root); | |
+ | |
+ if (rc == -EINVAL && is_mdt == 0) | |
+ rc = llapi_get_ost_count_from_proc(mnt, count); | |
+ | |
return rc; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment