+
+static int print_pool_members(char *fs, char *pool_dir, char *pool_file)
+{
+ char path[PATH_MAX + 1];
+ char buf[1024];
+ FILE *fd;
+
+ llapi_printf(LLAPI_MSG_NORMAL, "Pool: %s.%s\n", fs, pool_file);
+ sprintf(path, "%s/%s", pool_dir, pool_file);
+ if ((fd = fopen(path, "r")) == NULL) {
+ llapi_err(LLAPI_MSG_ERROR, "Cannot open %s\n", path);
+ return -EINVAL;
+ }
+ while (fgets(buf, sizeof(buf), fd) != NULL)
+ llapi_printf(LLAPI_MSG_NORMAL, buf);
+
+ fclose(fd);
+ return 0;
+}
+
+/*
+ * search lustre fsname from pathname
+ *
+ */
+static int search_fsname(char *pathname, char *fsname)
+{
+ char *ptr;
+ FILE *fp;
+ struct mntent *mnt = NULL;
+
+ /* get the mount point */
+ fp = setmntent(MOUNTED, "r");
+ if (fp == NULL) {
+ llapi_err(LLAPI_MSG_ERROR,
+ "setmntent(%s) failed: %s:", MOUNTED,
+ strerror (errno));
+ return -EIO;
+ }
+ mnt = getmntent(fp);
+ while ((feof(fp) == 0) && ferror(fp) == 0) {
+ if (llapi_is_lustre_mnt(mnt)) {
+ /* search by pathname */
+ if (strncmp(mnt->mnt_dir, pathname,
+ strlen(mnt->mnt_dir)) == 0) {
+ ptr = strchr(mnt->mnt_fsname, '/');
+ if (ptr == NULL)
+ return -EINVAL;
+ ptr++;
+ strcpy(fsname, ptr);
+ return 0;
+ }
+ }
+ mnt = getmntent(fp);
+ }
+ endmntent(fp);
+ return -ENOENT;
+
+}
+
+/*
+ * find the pool directory path under /proc
+ * (can be also used to test if a fsname is known)
+ */
+static int poolpath(char *fsname, char *pathname, char *pool_pathname)
+{
+ int rc = 0;
+ glob_t glob_info;
+ char pattern[PATH_MAX + 1];
+ char buffer[PATH_MAX];
+
+ if (fsname == NULL) {
+ rc = search_fsname(pathname, buffer);
+ if (rc != 0)
+ return rc;
+ fsname = buffer;
+ strcpy(pathname, fsname);
+ }
+
+ snprintf(pattern, PATH_MAX,
+ "/proc/fs/lustre/lov/%s-*/pools",
+ fsname);
+ rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
+ if (rc)
+ return -ENOENT;
+
+ if (glob_info.gl_pathc == 0) {
+ globfree(&glob_info);
+ return -ENOENT;
+ }
+
+ /* in fsname test mode, pool_pathname is NULL */
+ if (pool_pathname != NULL)
+ strcpy(pool_pathname, glob_info.gl_pathv[0]);
+
+ return 0;
+}
+
+int llapi_poollist(char *name)
+{
+ char *poolname;
+ char *fsname;
+ char rname[PATH_MAX + 1], pathname[PATH_MAX + 1];
+ char *ptr;
+ int rc = 0;
+
+ /* is name a pathname ? */
+ ptr = strchr(name, '/');
+ if (ptr != NULL) {
+ /* only absolute pathname is supported */
+ if (*name != '/')
+ return -EINVAL;
+ if (!realpath(name, rname)) {
+ rc = -errno;
+ llapi_err(LLAPI_MSG_ERROR,
+ "llapi_poollist: invalid path '%s'",
+ name);
+ return rc;
+ }
+
+ rc = poolpath(NULL, rname, pathname);
+ if (rc != 0) {
+ errno = -rc;
+ llapi_err(LLAPI_MSG_ERROR,
+ "llapi_poollist: '%s' is not"
+ " a Lustre filesystem",
+ name);
+ return rc;
+ }
+ fsname = rname;
+ poolname = NULL;
+ } else {
+ /* name is FSNAME[.POOLNAME] */
+ fsname = name;
+ poolname = strchr(name, '.');
+ if (poolname != NULL) {
+ *poolname = '\0';
+ poolname++;
+ }
+ rc = poolpath(fsname, NULL, pathname);
+ if (rc != 0) {
+ errno = -rc;
+ llapi_err(LLAPI_MSG_ERROR,
+ "llapi_poollist: Lustre filesystem '%s'"
+ " not found", name);
+ return rc;
+ }
+ }
+ if (rc != 0) {
+ errno = -rc;
+ llapi_err(LLAPI_MSG_ERROR,
+ "llapi_poollist: Lustre filesystem '%s' not found",
+ name);
+ return rc;
+ }
+
+ if (poolname != NULL) {
+ rc = print_pool_members(fsname, pathname, poolname);
+ poolname--;
+ *poolname = '.';
+ } else {
+ DIR *dir;
+ struct dirent *pool;
+
+ llapi_printf(LLAPI_MSG_NORMAL, "Pools from %s:\n", fsname);
+ if ((dir = opendir(pathname)) == NULL) {
+ return -EINVAL;
+ }
+ while ((pool = readdir(dir)) != NULL) {
+ if (!((pool->d_name[0] == '.') &&
+ (pool->d_name[1] == '\0')) &&
+ !((pool->d_name[0] == '.') &&
+ (pool->d_name[1] == '.') &&
+ (pool->d_name[2] == '\0')))
+ llapi_printf(LLAPI_MSG_NORMAL, " %s.%s\n",
+ fsname, pool->d_name);
+ }
+ closedir(dir);
+ }
+ return rc;
+}
+