]> www.infradead.org Git - mtd-utils.git/commitdiff
Fix libmtd behaviour if MTD is not present on the system
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>
Wed, 15 Mar 2017 10:26:38 +0000 (11:26 +0100)
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>
Wed, 15 Mar 2017 11:10:34 +0000 (12:10 +0100)
The documentation of libmtd_open says, if it returns NULL and errno is
zero, MTD is not present. However, the current version always returns
a libmtd_t object. The function internally checks, if it can access the
MTD sysfs files and, if not, sets a flag to use the procfs fallback.

This patch adds an additional check to libmtd_open, to test if the
MTD procfs file can be read and fails with errno cleared if it does
not exist.

Furhtermore, mtd_get_info is documented to fail with errno set to ENODEV
if MTD is not present. First of all, this was broken in the original
version. It was implemented to specification for the sysfs code path,
but if MTD is not present, that won't be executed, because of the flag
set by libmtd_open. This makes the check not only redundant, but masks
an actual error (the sysfs paths suddenly not being readable anymore).
The legacy path that was used if the sysfs files are not avaible fails
with ENOENT if it cannot read the procfs file. With the above changes
in addition, we don't have a libmtd_t object if neither sysfs nor
procfs is readable, so this error status no longer makes sense.

This patch removes the documentation on the ENODEV errno, and
makes sure that mtd_get_info always returns with apropriate errno
on failure.

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
include/libmtd.h
lib/libmtd.c
lib/libmtd_int.h
lib/libmtd_legacy.c
ubi-utils/mtdinfo.c
ubi-utils/ubiformat.c

index f9f31643634208d2f0a46b606f12d452c6ea6931..db85fb4a28802e0ebdcae778cbaed0859d94932a 100644 (file)
@@ -120,8 +120,7 @@ int mtd_dev_present(libmtd_t desc, int mtd_num);
  * @info: the MTD device information is returned here
  *
  * This function fills the passed @info object with general MTD information and
- * returns %0 in case of success and %-1 in case of failure. If MTD subsystem is
- * not present in the system, errno is set to @ENODEV.
+ * returns %0 in case of success and %-1 in case of failure.
  */
 int mtd_get_info(libmtd_t desc, struct mtd_info *info);
 
index 8bc532fc2f7df667410da1e695ae741490516a88..a50f18af00782e7cbca340b45bd6ef08b92bf1e9 100644 (file)
@@ -578,6 +578,11 @@ libmtd_t libmtd_open(void)
                free(lib->sysfs_mtd);
                free(lib->mtd_name);
                lib->mtd_name = lib->mtd = lib->sysfs_mtd = NULL;
+
+               if (!legacy_procfs_is_supported()) {
+                       free(lib);
+                       lib = NULL;
+               }
                return lib;
        }
 
@@ -676,13 +681,8 @@ int mtd_get_info(libmtd_t desc, struct mtd_info *info)
         * devices are present.
         */
        sysfs_mtd = opendir(lib->sysfs_mtd);
-       if (!sysfs_mtd) {
-               if (errno == ENOENT) {
-                       errno = ENODEV;
-                       return -1;
-               }
+       if (!sysfs_mtd)
                return sys_errmsg("cannot open \"%s\"", lib->sysfs_mtd);
-       }
 
        info->lowest_mtd_num = INT_MAX;
        while (1) {
index db2f1cf9f920c3148b1ac6c7edc8b3aa3f7f6bf3..03b086356879efbd88eef4f6d08a52a0f39f3a1a 100644 (file)
@@ -98,6 +98,7 @@ struct libmtd
        unsigned int offs64_ioctls:2;
 };
 
+int legacy_procfs_is_supported(void);
 int legacy_dev_present(int mtd_num);
 int legacy_mtd_get_info(struct mtd_info *info);
 int legacy_get_dev_info(const char *node, struct mtd_dev_info *mtd);
index ba8eade402e1a87ea2e772fc7491199c2b78b249..46f51fda3dd51eb0f74b5e7d8faa91c3bfa33f89 100644 (file)
@@ -145,6 +145,24 @@ static int proc_parse_next(struct proc_parse_info *pi)
        return 1;
 }
 
+/**
+ * legacy_procfs_is_supported - legacy version of 'sysfs_is_supported()'.
+ *
+ * Check if we can access the procfs files for the MTD subsystem.
+ */
+int legacy_procfs_is_supported(void)
+{
+       if (access(MTD_PROC_FILE, R_OK) != 0) {
+               if (errno == ENOENT) {
+                       errno = 0;
+               } else {
+                       sys_errmsg("cannot read \"%s\"", MTD_PROC_FILE);
+               }
+               return 0;
+       }
+       return 1;
+}
+
 /**
  * legacy_dev_presentl - legacy version of 'mtd_dev_present()'.
  * @info: the MTD device information is returned here
index 11e59c1c61ca6c2ed327cc58fd4981c2ec469412..0606ab07837d01073508847a2a5179ca988db8e4 100644 (file)
@@ -407,11 +407,8 @@ int main(int argc, char * const argv[])
        }
 
        err = mtd_get_info(libmtd, &mtd_info);
-       if (err) {
-               if (errno == ENODEV)
-                       return errmsg("MTD is not present");
+       if (err)
                return sys_errmsg("cannot get MTD information");
-       }
 
        if (!args.all && args.node) {
                int mtdn;
index 68906f241ee042e5be00ee6f8e18fc0e4e3de88e..896fe20cc6a4c02b076461cd08e7a9f9f05bf22d 100644 (file)
@@ -698,8 +698,6 @@ int main(int argc, char * const argv[])
 
        err = mtd_get_info(libmtd, &mtd_info);
        if (err) {
-               if (errno == ENODEV)
-                       errmsg("MTD is not present");
                sys_errmsg("cannot get MTD information");
                goto out_close_mtd;
        }