diff options
-rw-r--r-- | include/sysfs.h | 1 | ||||
-rw-r--r-- | lib/sysfs.c | 7 | ||||
-rw-r--r-- | shlibs/blkid/src/Makefile.am | 4 | ||||
-rw-r--r-- | shlibs/blkid/src/blkidP.h | 9 | ||||
-rw-r--r-- | shlibs/blkid/src/devname.c | 40 | ||||
-rw-r--r-- | shlibs/blkid/src/devno.c | 101 | ||||
-rw-r--r-- | shlibs/blkid/src/partitions/partitions.c | 11 | ||||
-rw-r--r-- | shlibs/blkid/src/topology/sysfs.c | 69 |
8 files changed, 75 insertions, 167 deletions
diff --git a/include/sysfs.h b/include/sysfs.h index bbb3816c2..ed11a5e19 100644 --- a/include/sysfs.h +++ b/include/sysfs.h @@ -39,6 +39,7 @@ extern void sysfs_deinit(struct sysfs_cxt *cxt); extern DIR *sysfs_opendir(struct sysfs_cxt *cxt, const char *attr); extern int sysfs_stat(struct sysfs_cxt *cxt, const char *attr, struct stat *st); +extern int sysfs_has_attribute(struct sysfs_cxt *cxt, const char *attr); extern int sysfs_scanf(struct sysfs_cxt *cxt, const char *attr, const char *fmt, ...) diff --git a/lib/sysfs.c b/lib/sysfs.c index aba12864e..bc380c030 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -152,6 +152,13 @@ int sysfs_stat(struct sysfs_cxt *cxt, const char *attr, struct stat *st) return rc; } +int sysfs_has_attribute(struct sysfs_cxt *cxt, const char *attr) +{ + struct stat st; + + return sysfs_stat(cxt, attr, &st) == 0; +} + static int sysfs_open(struct sysfs_cxt *cxt, const char *attr) { int fd = open_at(cxt->dir_fd, cxt->dir_path, attr, O_RDONLY); diff --git a/shlibs/blkid/src/Makefile.am b/shlibs/blkid/src/Makefile.am index f385156aa..543f2f629 100644 --- a/shlibs/blkid/src/Makefile.am +++ b/shlibs/blkid/src/Makefile.am @@ -29,7 +29,9 @@ libblkid_la_SOURCES = cache.c dev.c devname.c devno.c getsize.c llseek.c \ $(top_srcdir)/lib/crc32.c \ $(top_srcdir)/include/list.h \ $(top_srcdir)/lib/env.c \ - $(top_srcdir)/lib/strutils.c + $(top_srcdir)/lib/strutils.c \ + $(top_srcdir)/lib/at.c \ + $(top_srcdir)/lib/sysfs.c nodist_libblkid_la_SOURCES = blkid.h diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h index ddd1bb890..b78488f45 100644 --- a/shlibs/blkid/src/blkidP.h +++ b/shlibs/blkid/src/blkidP.h @@ -285,10 +285,6 @@ struct blkid_struct_cache extern char *blkid_strdup(const char *s); extern char *blkid_strndup(const char *s, const int length); extern char *blkid_strconcat(const char *a, const char *b, const char *c); -extern int blkid_fstatat(DIR *dir, const char *dirname, const char *filename, - struct stat *st, int nofollow); -extern int blkid_openat(DIR *dir, const char *dirname, const char *filename, - int flags); #define BLKID_CACHE_FILE "/etc/blkid.tab" #define BLKID_CONFIG_FILE "/etc/blkid.conf" @@ -350,11 +346,6 @@ struct dir_list { }; extern void blkid__scan_dir(char *, dev_t, struct dir_list **, char **); extern int blkid_driver_has_major(const char *drvname, int major); -extern int blkid_devno_has_attribute(dev_t devno, const char *attribute); -extern int blkid_devno_get_u64_attribute(dev_t devno, const char *attribute, - uint64_t *result); -extern int blkid_devno_get_s64_attribute(dev_t devno, const char *attribute, - int64_t *result); /* lseek.c */ extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence); diff --git a/shlibs/blkid/src/devname.c b/shlibs/blkid/src/devname.c index 68e392350..81eac9aa3 100644 --- a/shlibs/blkid/src/devname.c +++ b/shlibs/blkid/src/devname.c @@ -38,6 +38,8 @@ #include "canonicalize.h" /* $(top_srcdir)/include */ #include "pathnames.h" +#include "sysfs.h" +#include "at.h" /* * Find a dev struct in the cache by device name, if available. @@ -400,7 +402,7 @@ ubi_probe_all(blkid_cache cache, int only_if_new) continue; if (!strcmp(name, "ubi_ctrl")) continue; - if (blkid_fstatat(dir, *dirname, name, &st, 0)) + if (fstat_at(dirfd(dir), *dirname, name, &st, 0)) continue; dev = st.st_rdev; @@ -543,7 +545,6 @@ static int probe_all_removable(blkid_cache cache) { DIR *dir; struct dirent *d; - char buf[PATH_MAX]; if (!cache) return -BLKID_ERR_PARAM; @@ -553,7 +554,9 @@ static int probe_all_removable(blkid_cache cache) return -BLKID_ERR_PROC; while((d = readdir(dir))) { - int fd, rc, ma, mi; + struct sysfs_cxt sysfs; + int removable; + dev_t devno; #ifdef _DIRENT_HAVE_D_TYPE if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK) @@ -564,33 +567,16 @@ static int probe_all_removable(blkid_cache cache) ((d->d_name[1] == '.') && (d->d_name[2] == 0)))) continue; - snprintf(buf, sizeof(buf), "%s/removable", d->d_name); - fd = blkid_openat(dir, _PATH_SYS_BLOCK, buf, O_RDONLY); - if (fd < 0) + devno = sysfs_devname_to_devno(d->d_name, NULL); + if (!devno) continue; - rc = read(fd, buf, 1); - close(fd); + sysfs_init(&sysfs, devno, NULL); + removable = sysfs_read_int(&sysfs, "removable"); + sysfs_deinit(&sysfs); - if (rc != 1 || *buf != '1') - continue; /* not removable device */ - - /* get devno */ - snprintf(buf, sizeof(buf), "%s/dev", d->d_name); - fd = blkid_openat(dir, _PATH_SYS_BLOCK, buf, O_RDONLY); - if (fd < 0) - continue; - - rc = read(fd, buf, sizeof(buf)); - close(fd); - - if (rc < 3) - continue; /* M:N */ - buf[rc] = '\0'; - if (sscanf(buf, "%d:%d", &ma, &mi) != 2) - continue; - - probe_one(cache, d->d_name, makedev(ma, mi), 0, 0, 1); + if (removable) + probe_one(cache, d->d_name, devno, 0, 0, 1); } closedir(dir); diff --git a/shlibs/blkid/src/devno.c b/shlibs/blkid/src/devno.c index 33466048f..62192fc6a 100644 --- a/shlibs/blkid/src/devno.c +++ b/shlibs/blkid/src/devno.c @@ -34,6 +34,7 @@ #include "blkidP.h" #include "pathnames.h" +#include "at.h" char *blkid_strndup(const char *s, int length) { @@ -89,40 +90,6 @@ char *blkid_strconcat(const char *a, const char *b, const char *c) return res; } -int blkid_fstatat(DIR *dir, const char *dirname, const char *filename, - struct stat *st, int nofollow) -{ -#ifdef HAVE_FSTATAT - return fstatat(dirfd(dir), filename, st, - nofollow ? AT_SYMLINK_NOFOLLOW : 0); -#else - char path[PATH_MAX]; - int len; - - len = snprintf(path, sizeof(path), "%s/%s", dirname, filename); - if (len < 0 || len + 1 > sizeof(path)) - return -1; - - return nofollow ? lstat(path, st) : stat(path, st); -#endif -} - -int blkid_openat(DIR *dir, const char *dirname, const char *filename, int flags) -{ -#ifdef HAVE_FSTATAT - return openat(dirfd(dir), filename, flags); -#else - char path[PATH_MAX]; - int len; - - len = snprintf(path, sizeof(path), "%s/%s", dirname, filename); - if (len < 0 || len + 1 > sizeof(path)) - return -1; - - return open(path, flags); -#endif -} - /* * This function adds an entry to the directory list */ @@ -180,7 +147,7 @@ void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list, ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) continue; - if (blkid_fstatat(dir, dirname, dp->d_name, &st, 0)) + if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 0)) continue; if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { @@ -201,7 +168,7 @@ void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list, if (dp->d_type == DT_UNKNOWN) #endif { - if (blkid_fstatat(dir, dirname, dp->d_name, &st, 1) || + if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 1) || !S_ISDIR(st.st_mode)) continue; /* symlink or lstat() failed */ } @@ -336,7 +303,6 @@ char *blkid_devno_to_devname(dev_t devno) return devname; } - /** * blkid_devno_to_wholedisk: * @dev: device number @@ -494,67 +460,6 @@ int blkid_driver_has_major(const char *drvname, int major) return match; } -static char *mk_devno_attribute_path(char *buf, size_t buflen, - dev_t devno, const char *attr) -{ - int len = snprintf(buf, buflen, "/sys/dev/block/%d:%d/%s", - major(devno), minor(devno), attr); - - if (len < 0 || len + 1 > buflen) - return NULL; - - return buf; -} - -int blkid_devno_has_attribute(dev_t devno, const char *attribute) -{ - char path[PATH_MAX]; - struct stat info; - - if (!mk_devno_attribute_path(path, sizeof(path), devno, attribute)) - return 0; - - if (stat(path, &info) == 0) - return 1; - - return 0; -} - -int blkid_devno_get_u64_attribute(dev_t devno, const char *attribute, uint64_t *result) -{ - FILE *f; - char path[PATH_MAX]; - int rc = 0; - - if (!mk_devno_attribute_path(path, sizeof(path), devno, attribute)) - return -1; - - f = fopen(path, "r"); - if (f) { - rc = fscanf(f, "%" SCNu64, result); - fclose(f); - } - - return rc == 1 ? 0 : -1; -} - -int blkid_devno_get_s64_attribute(dev_t devno, const char *attribute, int64_t *result) -{ - FILE *f; - char path[PATH_MAX]; - int rc = 0; - - if (!mk_devno_attribute_path(path, sizeof(path), devno, attribute)) - return -1; - - f = fopen(path, "r"); - if (f) { - rc = fscanf(f, "%" SCNd64, result); - fclose(f); - } - - return rc == 1 ? 0 : -1; -} #ifdef TEST_PROGRAM int main(int argc, char** argv) diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c index b3b52f0f1..2ac297a1c 100644 --- a/shlibs/blkid/src/partitions/partitions.c +++ b/shlibs/blkid/src/partitions/partitions.c @@ -21,6 +21,7 @@ #include <stdarg.h> #include "partitions.h" +#include "sysfs.h" /** * SECTION:partitions @@ -889,14 +890,18 @@ blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n) */ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno) { + struct sysfs_cxt sysfs; uint64_t start, size; int i; - if (blkid_devno_get_u64_attribute(devno, "start", &start)) - return NULL; - if (blkid_devno_get_u64_attribute(devno, "size", &size)) + if (sysfs_init(&sysfs, devno, NULL)) return NULL; + start = sysfs_read_u64(&sysfs, "start"); + size = sysfs_read_u64(&sysfs, "size"); + + sysfs_deinit(&sysfs); + for (i = 0; i < ls->nparts; i++) { blkid_partition par = &ls->parts[i]; diff --git a/shlibs/blkid/src/topology/sysfs.c b/shlibs/blkid/src/topology/sysfs.c index d04f0a86e..d5169d02a 100644 --- a/shlibs/blkid/src/topology/sysfs.c +++ b/shlibs/blkid/src/topology/sysfs.c @@ -17,6 +17,7 @@ #include <unistd.h> #include <errno.h> +#include "sysfs.h" #include "topology.h" /* @@ -40,54 +41,64 @@ static struct topology_val { static int probe_sysfs_tp(blkid_probe pr, const struct blkid_idmag *mag) { - dev_t dev, pri_dev = 0; + dev_t dev, disk = 0; int i, count = 0; + struct sysfs_cxt sysfs, parent; + + int rc = 1; /* nothing (default) */ dev = blkid_probe_get_devno(pr); if (!dev) - goto nothing; /* probably not a block device */ + goto done; /* probably not a block device */ + if (sysfs_init(&sysfs, dev, NULL)) + goto done; /* no entry in /sys ? */ for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { struct topology_val *val = &topology_vals[i]; - dev_t attr_dev = dev; - int rc = 1; - - if (!blkid_devno_has_attribute(dev, val->attr)) { - /* get attribute from partition's primary device */ - if (!pri_dev && - blkid_devno_to_wholedisk(dev, NULL, 0, &pri_dev)) - continue; - attr_dev = pri_dev; + int ok = sysfs_has_attribute(&sysfs, val->attr); + + rc = 1; /* nothing */ + + if (!ok) { + if (!disk) { + /* + * Read atrributes from "disk" if the current + * device is a partition. + */ + disk = blkid_probe_get_wholedisk_devno(pr); + if (disk && disk != dev) { + sysfs_init(&parent, disk, NULL); + sysfs.parent = &parent; + + ok = sysfs_has_attribute(&sysfs, val->attr); + } + } + if (!ok) + continue; /* attrinute does not exist */ } if (val->set_ulong) { - uint64_t data = 0; - - if (blkid_devno_get_u64_attribute(attr_dev, - val->attr, &data)) - continue; + uint64_t data = sysfs_read_u64(&sysfs, val->attr); rc = val->set_ulong(pr, (unsigned long) data); } else if (val->set_int) { - int64_t data = 0; - - if (blkid_devno_get_s64_attribute(attr_dev, - val->attr, &data)) - continue; + int64_t data = sysfs_read_s64(&sysfs, val->attr); rc = val->set_int(pr, (int) data); } - if (rc) - goto err; - count++; + if (rc < 0) + goto done; /* error */ + if (rc == 0) + count++; } +done: + sysfs_deinit(&sysfs); + if (disk) + sysfs_deinit(&parent); if (count) - return 0; -nothing: - return 1; -err: - return -1; + return 0; /* success */ + return rc; /* error or nothing */ } const struct blkid_idinfo sysfs_tp_idinfo = |