summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sysfs.h2
-rw-r--r--lib/sysfs.c129
-rw-r--r--libblkid/src/devno.c130
3 files changed, 132 insertions, 129 deletions
diff --git a/include/sysfs.h b/include/sysfs.h
index affd2bb76..8604aca5e 100644
--- a/include/sysfs.h
+++ b/include/sysfs.h
@@ -62,4 +62,6 @@ extern char *sysfs_get_slave(struct sysfs_cxt *cxt);
extern int sysfs_is_partition_dirent(DIR *dir, struct dirent *d,
const char *parent_name);
+extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
+ size_t len, dev_t *diskdevno);
#endif /* UTIL_LINUX_SYSFS_H */
diff --git a/lib/sysfs.c b/lib/sysfs.c
index a57c0a6ba..fb03dd999 100644
--- a/lib/sysfs.c
+++ b/lib/sysfs.c
@@ -439,6 +439,135 @@ char *sysfs_get_devname(struct sysfs_cxt *cxt, char *buf, size_t bufsiz)
return buf;
}
+/* returns basename and keeps dirname in the @path */
+static char *stripoff_last_component(char *path)
+{
+ char *p = strrchr(path, '/');
+
+ if (!p)
+ return NULL;
+ *p = '\0';
+ return ++p;
+}
+
+static int get_dm_wholedisk(struct sysfs_cxt *cxt, char *diskname,
+ size_t len, dev_t *diskdevno)
+{
+ int rc = 0;
+ char *name;
+
+ /* Note, sysfs_get_slave() returns the first slave only,
+ * if there is more slaves, then return NULL
+ */
+ name = sysfs_get_slave(cxt);
+ if (!name)
+ return -1;
+
+ if (diskname && len) {
+ strncpy(diskname, name, len);
+ diskname[len - 1] = '\0';
+ }
+
+ if (diskdevno) {
+ *diskdevno = sysfs_devname_to_devno(name, NULL);
+ if (!*diskdevno)
+ rc = -1;
+ }
+
+ free(name);
+ return rc;
+}
+
+int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
+ size_t len, dev_t *diskdevno)
+{
+ struct sysfs_cxt cxt;
+ int is_part = 0;
+
+ if (!dev || sysfs_init(&cxt, dev, NULL) != 0)
+ return -1;
+
+ is_part = sysfs_has_attribute(&cxt, "partition");
+ if (!is_part) {
+ /*
+ * Extra case for partitions mapped by device-mapper.
+ *
+ * All regualar partitions (added by BLKPG ioctl or kernel PT
+ * parser) have the /sys/.../partition file. The partitions
+ * mapped by DM don't have such file, but they have "part"
+ * prefix in DM UUID.
+ */
+ char *uuid = sysfs_strdup(&cxt, "dm/uuid");
+ char *tmp = uuid;
+ char *prefix = uuid ? strsep(&tmp, "-") : NULL;
+
+ if (prefix && strncasecmp(prefix, "part", 4) == 0)
+ is_part = 1;
+ free(uuid);
+
+ if (is_part &&
+ get_dm_wholedisk(&cxt, diskname, len, diskdevno) == 0)
+ /*
+ * partitioned device, mapped by DM
+ */
+ goto done;
+
+ is_part = 0;
+ }
+
+ if (!is_part) {
+ /*
+ * unpartitioned device
+ */
+ if (diskname && len) {
+ if (!sysfs_get_devname(&cxt, diskname, len))
+ goto err;
+ }
+ if (diskdevno)
+ *diskdevno = dev;
+
+ } else {
+ /*
+ * partitioned device
+ * - readlink /sys/dev/block/8:1 = ../../block/sda/sda1
+ * - dirname ../../block/sda/sda1 = ../../block/sda
+ * - basename ../../block/sda = sda
+ */
+ char linkpath[PATH_MAX];
+ char *name;
+ int linklen;
+
+ linklen = sysfs_readlink(&cxt, NULL,
+ linkpath, sizeof(linkpath) - 1);
+ if (linklen < 0)
+ goto err;
+ linkpath[linklen] = '\0';
+
+ stripoff_last_component(linkpath); /* dirname */
+ name = stripoff_last_component(linkpath); /* basename */
+ if (!name)
+ goto err;
+
+ if (diskname && len) {
+ strncpy(diskname, name, len);
+ diskname[len - 1] = '\0';
+ }
+
+ if (diskdevno) {
+ *diskdevno = sysfs_devname_to_devno(name, NULL);
+ if (!*diskdevno)
+ goto err;
+ }
+ }
+
+done:
+ sysfs_deinit(&cxt);
+ return 0;
+err:
+ sysfs_deinit(&cxt);
+ return -1;
+}
+
#ifdef TEST_PROGRAM_SYSFS
#include <errno.h>
#include <err.h>
diff --git a/libblkid/src/devno.c b/libblkid/src/devno.c
index 59edfd85c..2996343a0 100644
--- a/libblkid/src/devno.c
+++ b/libblkid/src/devno.c
@@ -197,16 +197,7 @@ static const char *devdirs[] = { "/devices", "/devfs", "/dev", NULL };
* @short_description: mix of various utils for low-level and high-level API
*/
-/* returns basename and keeps dirname in the @path */
-static char *stripoff_last_component(char *path)
-{
- char *p = strrchr(path, '/');
- if (!p)
- return NULL;
- *p = '\0';
- return ++p;
-}
static char *scandev_devno_to_devpath(dev_t devno)
{
@@ -279,33 +270,6 @@ char *blkid_devno_to_devname(dev_t devno)
return path;
}
-static int get_dm_wholedisk(struct sysfs_cxt *cxt, char *diskname,
- size_t len, dev_t *diskdevno)
-{
- int rc = 0;
- char *name;
-
- /* Note, sysfs_get_slave() returns the first slave only,
- * if there is more slaves, then return NULL
- */
- name = sysfs_get_slave(cxt);
- if (!name)
- return -1;
-
- if (diskname && len) {
- strncpy(diskname, name, len);
- diskname[len - 1] = '\0';
- }
-
- if (diskdevno) {
- *diskdevno = sysfs_devname_to_devno(name, NULL);
- if (!*diskdevno)
- rc = -1;
- }
-
- free(name);
- return rc;
-}
/**
* blkid_devno_to_wholedisk:
@@ -346,99 +310,7 @@ static int get_dm_wholedisk(struct sysfs_cxt *cxt, char *diskname,
int blkid_devno_to_wholedisk(dev_t dev, char *diskname,
size_t len, dev_t *diskdevno)
{
- struct sysfs_cxt cxt = UL_SYSFSCXT_EMPTY;
- int is_part = 0;
-
- if (!dev || sysfs_init(&cxt, dev, NULL) != 0)
- return -1;
-
- is_part = sysfs_has_attribute(&cxt, "partition");
- if (!is_part) {
- /*
- * Extra case for partitions mapped by device-mapper.
- *
- * All regualar partitions (added by BLKPG ioctl or kernel PT
- * parser) have the /sys/.../partition file. The partitions
- * mapped by DM don't have such file, but they have "part"
- * prefix in DM UUID.
- */
- char *uuid = sysfs_strdup(&cxt, "dm/uuid");
- char *tmp = uuid;
- char *prefix = uuid ? strsep(&tmp, "-") : NULL;
-
- if (prefix && strncasecmp(prefix, "part", 4) == 0)
- is_part = 1;
- free(uuid);
-
- if (is_part &&
- get_dm_wholedisk(&cxt, diskname, len, diskdevno) == 0)
- /*
- * partitioned device, mapped by DM
- */
- goto done;
-
- is_part = 0;
- }
-
- if (!is_part) {
- /*
- * unpartitioned device
- */
- if (diskname && len) {
- if (!sysfs_get_devname(&cxt, diskname, len))
- goto err;
- }
- if (diskdevno)
- *diskdevno = dev;
-
- } else {
- /*
- * partitioned device
- * - readlink /sys/dev/block/8:1 = ../../block/sda/sda1
- * - dirname ../../block/sda/sda1 = ../../block/sda
- * - basename ../../block/sda = sda
- */
- char linkpath[PATH_MAX];
- char *name;
- int linklen;
-
- linklen = sysfs_readlink(&cxt, NULL,
- linkpath, sizeof(linkpath) - 1);
- if (linklen < 0)
- goto err;
- linkpath[linklen] = '\0';
-
- stripoff_last_component(linkpath); /* dirname */
- name = stripoff_last_component(linkpath); /* basename */
- if (!name)
- goto err;
-
- if (diskname && len) {
- strncpy(diskname, name, len);
- diskname[len - 1] = '\0';
- }
-
- if (diskdevno) {
- *diskdevno = sysfs_devname_to_devno(name, NULL);
- if (!*diskdevno)
- goto err;
- }
- }
-
-done:
- sysfs_deinit(&cxt);
-
- DBG(DEBUG_DEVNO,
- printf("found entire diskname for devno 0x%04llx %s\n",
- (long long) dev, diskname ? diskname : ""));
- return 0;
-err:
- sysfs_deinit(&cxt);
-
- DBG(DEBUG_DEVNO,
- printf("failed to convert 0x%04llx to wholedisk name, errno=%d\n",
- (long long) dev, errno));
- return -1;
+ return sysfs_devno_to_wholedisk( dev, diskname, len, diskdevno);
}
/*