Whamcloud - gitweb
LU-9137 utils: replace readdir_r with readdir 76/27276/3
authorJames Simmons <uja.ornl@yahoo.com>
Thu, 25 May 2017 17:45:20 +0000 (13:45 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 3 Jun 2017 03:57:33 +0000 (03:57 +0000)
Originally readdir_r was created to handle the case of readdir
not being reentrant. The readdir_r implementation has several
flaws and modern platforms have a glibc version were readdir
is reentrant. Because of this platforms are now marking
readdir_r as obsolete which breaks our lustre build. This
patch migrates us to readdir instead.

Change-Id: I939d5a402e6c73c56615972b2b3c6f0a21b59b55
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/27276
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Tested-by: Jenkins
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/utils/lhsmtool_posix.c
lustre/utils/liblustreapi.c

index 0cb1c4e..79da303 100644 (file)
@@ -1467,7 +1467,7 @@ static int ct_import_fid(const lustre_fid *import_fid)
 static int ct_import_recurse(const char *relpath)
 {
        DIR             *dir;
 static int ct_import_recurse(const char *relpath)
 {
        DIR             *dir;
-       struct dirent    ent, *cookie = NULL;
+       struct dirent   *ent;
        char            *srcpath, *newpath;
        lustre_fid       import_fid;
        int              rc;
        char            *srcpath, *newpath;
        lustre_fid       import_fid;
        int              rc;
@@ -1504,31 +1504,20 @@ static int ct_import_recurse(const char *relpath)
        }
        free(srcpath);
 
        }
        free(srcpath);
 
-       while (1) {
-               rc = readdir_r(dir, &ent, &cookie);
-               if (rc != 0) {
-                       rc = -errno;
-                       CT_ERROR(rc, "cannot readdir_r '%s'", relpath);
-                       err_major++;
-                       goto out;
-               } else if ((rc == 0) && (cookie == NULL)) {
-                       /* end of directory */
-                       break;
-               }
-
-               if (!strcmp(ent.d_name, ".") ||
-                   !strcmp(ent.d_name, ".."))
+       while ((ent = readdir(dir)) != NULL) {
+               if (!strcmp(ent->d_name, ".") ||
+                   !strcmp(ent->d_name, ".."))
                        continue;
 
                /* New relative path */
                        continue;
 
                /* New relative path */
-               newpath = path_concat(relpath, ent.d_name);
+               newpath = path_concat(relpath, ent->d_name);
                if (newpath == NULL) {
                        err_major++;
                        rc = -ENOMEM;
                        goto out;
                }
 
                if (newpath == NULL) {
                        err_major++;
                        rc = -ENOMEM;
                        goto out;
                }
 
-               if (ent.d_type == DT_DIR) {
+               if (ent->d_type == DT_DIR) {
                        rc = ct_import_recurse(newpath);
                } else {
                        char src[PATH_MAX];
                        rc = ct_import_recurse(newpath);
                } else {
                        char src[PATH_MAX];
@@ -1705,7 +1694,7 @@ static int ct_dir_level_max(const char *dirpath, __u16 *sub_seqmax)
        DIR             *dir;
        int              rc;
        __u16            sub_seq;
        DIR             *dir;
        int              rc;
        __u16            sub_seq;
-       struct dirent    ent, *cookie = NULL;
+       struct dirent *ent;
 
        *sub_seqmax = 0;
 
 
        *sub_seqmax = 0;
 
@@ -1716,26 +1705,29 @@ static int ct_dir_level_max(const char *dirpath, __u16 *sub_seqmax)
                return rc;
        }
 
                return rc;
        }
 
-       while ((rc = readdir_r(dir, &ent, &cookie)) == 0) {
-               if (cookie == NULL)
+       do {
+               errno = 0;
+               ent = readdir(dir);
+               if (ent == NULL) {
                        /* end of directory.
                         * rc is 0 and seqmax contains the max value. */
                        /* end of directory.
                         * rc is 0 and seqmax contains the max value. */
+                       rc = -errno;
+                       if (rc)
+                               CT_ERROR(rc, "cannot readdir '%s'", dirpath);
                        goto out;
                        goto out;
+               }
 
 
-               if (!strcmp(ent.d_name, ".") || !strcmp(ent.d_name, ".."))
+               if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
                        continue;
 
                        continue;
 
-               if (sscanf(ent.d_name, "%hx", &sub_seq) != 1) {
+               if (sscanf(ent->d_name, "%hx", &sub_seq) != 1) {
                        CT_TRACE("'%s' has an unexpected dirname format, "
                        CT_TRACE("'%s' has an unexpected dirname format, "
-                                "skip entry", ent.d_name);
+                                "skip entry", ent->d_name);
                        continue;
                }
                if (sub_seq > *sub_seqmax)
                        *sub_seqmax = sub_seq;
                        continue;
                }
                if (sub_seq > *sub_seqmax)
                        *sub_seqmax = sub_seq;
-       }
-       rc = -errno;
-       CT_ERROR(rc, "cannot readdir_r '%s'", dirpath);
-
+       } while (1);
 out:
        closedir(dir);
        return rc;
 out:
        closedir(dir);
        return rc;
index 4194b54..31494a3 100644 (file)
@@ -1235,8 +1235,7 @@ int llapi_get_poollist(const char *name, char **poollist, int list_size,
        char *fsname;
         char *ptr;
         DIR *dir;
        char *fsname;
         char *ptr;
         DIR *dir;
-        struct dirent pool;
-        struct dirent *cookie = NULL;
+       struct dirent *pool;
         int rc = 0;
         unsigned int nb_entries = 0;
         unsigned int used = 0;
         int rc = 0;
         unsigned int nb_entries = 0;
         unsigned int used = 0;
@@ -1288,20 +1287,16 @@ int llapi_get_poollist(const char *name, char **poollist, int list_size,
                goto free_path;
        }
 
                goto free_path;
        }
 
-       while(1) {
-               rc = readdir_r(dir, &pool, &cookie);
-               if (rc != 0) {
+       do {
+               errno = 0;
+               pool = readdir(dir);
+               if (pool == NULL) {
                        rc = -errno;
                        rc = -errno;
-                       llapi_error(LLAPI_MSG_ERROR, rc,
-                                   "Error reading pool list for '%s'", name);
-                       goto free_path;
-               } else if ((rc == 0) && (cookie == NULL)) {
-                       /* end of directory */
-                       break;
+                       goto free_dir;
                }
 
                 /* ignore . and .. */
                }
 
                 /* ignore . and .. */
-                if (!strcmp(pool.d_name, ".") || !strcmp(pool.d_name, ".."))
+               if (!strcmp(pool->d_name, ".") || !strcmp(pool->d_name, ".."))
                         continue;
 
                 /* check output bounds */
                         continue;
 
                 /* check output bounds */
@@ -1311,19 +1306,22 @@ int llapi_get_poollist(const char *name, char **poollist, int list_size,
                }
 
                 /* +2 for '.' and final '\0' */
                }
 
                 /* +2 for '.' and final '\0' */
-               if (used + strlen(pool.d_name) + strlen(fsname) + 2
+               if (used + strlen(pool->d_name) + strlen(fsname) + 2
                    > buffer_size) {
                        rc = -EOVERFLOW;
                        goto free_dir;
                }
 
                    > buffer_size) {
                        rc = -EOVERFLOW;
                        goto free_dir;
                }
 
-                sprintf(buffer + used, "%s.%s", fsname, pool.d_name);
+               sprintf(buffer + used, "%s.%s", fsname, pool->d_name);
                 poollist[nb_entries] = buffer + used;
                 poollist[nb_entries] = buffer + used;
-                used += strlen(pool.d_name) + strlen(fsname) + 2;
+               used += strlen(pool->d_name) + strlen(fsname) + 2;
                 nb_entries++;
                 nb_entries++;
-        }
+       } while (1);
 
 free_dir:
 
 free_dir:
+       if (rc)
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "Error reading pool list for '%s'", name);
        closedir(dir);
 free_path:
        cfs_free_param_data(&pathname);
        closedir(dir);
 free_path:
        cfs_free_param_data(&pathname);