diff options
author | Karel Zak <kzak@redhat.com> | 2009-09-18 10:19:59 +0200 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2009-09-18 10:19:59 +0200 |
commit | bf539f48f37da7a3609350ce4e9839921527de23 (patch) | |
tree | 227aef378716086655953734854695e8994d6380 /shlibs/blkid/src/topology/topology.c | |
parent | 38fb0905a6105f0dafe2db1beef8a92271c68f35 (diff) | |
download | util-linux-old-bf539f48f37da7a3609350ce4e9839921527de23.tar.gz |
libblkid: allows more probing methods for topology chain
This patch moves the current topology code to the separate sysfs.c
file.
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs/blkid/src/topology/topology.c')
-rw-r--r-- | shlibs/blkid/src/topology/topology.c | 177 |
1 files changed, 39 insertions, 138 deletions
diff --git a/shlibs/blkid/src/topology/topology.c b/shlibs/blkid/src/topology/topology.c index b4240543..26930cfa 100644 --- a/shlibs/blkid/src/topology/topology.c +++ b/shlibs/blkid/src/topology/topology.c @@ -5,25 +5,13 @@ * * This file may be redistributed under the terms of the * GNU Lesser General Public License. - * - * NOTE: this chain supports one probing method only, so it's implemented - * without array of probing functions (idinfos array). - * - * This chain does not support probing functions filtering. The chain - * could be enable or disabled only. */ #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#include "blkdev.h" -#include "blkidP.h" +#include "topology.h" /** * SECTION:topology @@ -55,26 +43,28 @@ static int topology_probe(blkid_probe pr, struct blkid_chain *chn); static void topology_free(blkid_probe pr, void *data); /* + * Topology chain probing functions + */ +static const struct blkid_idinfo *idinfos[] = +{ + &sysfs_tp_idinfo +}; + + +/* * Driver definition */ const struct blkid_chaindrv topology_drv = { .id = BLKID_CHAIN_TOPLGY, .name = "topology", .dflt_enabled = FALSE, + .idinfos = idinfos, + .nidinfos = ARRAY_SIZE(idinfos), .probe = topology_probe, .safeprobe = topology_probe, .free_data = topology_free }; -/* - * Binary interface - */ -struct blkid_struct_topology { - unsigned long alignment_offset; - unsigned long minimum_io_size; - unsigned long optimal_io_size; -}; - /** * blkid_probe_enable_topology: * @pr: probe @@ -110,109 +100,17 @@ blkid_topology blkid_probe_get_topology(blkid_probe pr) &pr->chains[BLKID_CHAIN_TOPLGY]); } -static unsigned long -dev_topology_attribute(const char *attribute, dev_t dev, dev_t *primary) -{ - const char *sysfs_fmt_str = "/sys/dev/block/%d:%d/%s"; - char path[PATH_MAX]; - int len; - FILE *fp = NULL; - struct stat info; - unsigned long result = 0UL; - - len = snprintf(path, sizeof(path), sysfs_fmt_str, - major(dev), minor(dev), attribute); - if (len < 0 || len + 1 > sizeof(path)) - goto err; - - /* - * check if the desired sysfs attribute exists - * - if not: either the kernel doesn't have topology support or the - * device could be a partition - */ - if (stat(path, &info) < 0) { - if (!*primary && - blkid_devno_to_wholedisk(dev, NULL, 0, primary)) - goto err; - - /* get attribute from partition's primary device */ - len = snprintf(path, sizeof(path), sysfs_fmt_str, - major(*primary), minor(*primary), attribute); - if (len < 0 || len + 1 > sizeof(path)) - goto err; - } - - fp = fopen(path, "r"); - if (!fp) { - DBG(DEBUG_LOWPROBE, printf( - "topology: %s: fopen failed, errno=%d\n", path, errno)); - goto err; - } - - if (fscanf(fp, "%lu", &result) != 1) { - DBG(DEBUG_LOWPROBE, printf( - "topology: %s: unexpected file format\n", path)); - goto err; - } - - fclose(fp); - - DBG(DEBUG_LOWPROBE, - printf("topology: attribute %s = %lu (sectors)\n", attribute, result)); - - return result; -err: - if (fp) - fclose(fp); - DBG(DEBUG_LOWPROBE, - printf("topology: failed to read %s attribute\n", attribute)); - return 0; -} - -/* - * Topology values - */ -static struct topology_val { - const char *val_name; /* NAME=value */ - const char *sysfs_name; /* /sys/dev/block/<maj>:<min>/NAME */ - const size_t bin_offset; /* blkid_struct_topology member */ -} topology_vals[] = { - { "ALIGNMENT_OFFSET", "alignment_offset", - offsetof(struct blkid_struct_topology, alignment_offset) }, - { "MINIMUM_IO_SIZE", "queue/minimum_io_size", - offsetof(struct blkid_struct_topology, minimum_io_size) }, - {"OPTIMAL_IO_SIZE", "queue/optimal_io_size", - offsetof(struct blkid_struct_topology, optimal_io_size) } -}; - -static int topology_set_value(blkid_probe pr, struct blkid_chain *chn, - struct topology_val *val, unsigned long data) -{ - if (chn->binary) { - unsigned long *v = - (unsigned long *) (chn->data + val->bin_offset); - *v = data; - return 0; - } - return blkid_probe_sprintf_value(pr, val->val_name, "%llu", data); -} - /* * The blkid_do_probe() backend. */ static int topology_probe(blkid_probe pr, struct blkid_chain *chn) { - dev_t dev, pri_dev = 0; - int i, rc = 0, count = 0; + int i = 0; - if (!pr) + if (!pr || chn->idx < -1) + return -1; + if (chn->idx < -1) return -1; - - blkid_probe_chain_reset_vals(pr, chn); - - dev = blkid_probe_get_devno(pr); - if (!dev) - return 1; /* no result */ if (chn->binary) { DBG(DEBUG_LOWPROBE, printf("initialize topology binary data\n")); @@ -229,33 +127,36 @@ static int topology_probe(blkid_probe pr, struct blkid_chain *chn) } } - DBG(DEBUG_LOWPROBE, printf("--> starting probing loop [TOPOLOGY]\n")); + blkid_probe_chain_reset_vals(pr, chn); + + DBG(DEBUG_LOWPROBE, + printf("--> starting probing loop [TOPOLOGY idx=%d]\n", + chn->idx)); - for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { - struct topology_val *val = &topology_vals[i]; - unsigned long data; + i = chn->idx + 1; - /* - * Don't bother reporting any of the topology information - * if it's zero. - */ - data = dev_topology_attribute(val->sysfs_name, dev, &pri_dev); - if (!data) - continue; + for ( ; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id = idinfos[i]; - rc = topology_set_value(pr, chn, val, data); - if (rc) - break; /* error */ - count++; - } + chn->idx = i; + if (id->probefunc) { + DBG(DEBUG_LOWPROBE, printf( + "%s: call probefunc()\n", id->name)); + if (id->probefunc(pr, NULL) != 0) + continue; + } - if (rc == 0 && count == 0) - rc = 1; /* no result */ + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (type=%s) [TOPOLOGY idx=%d]\n", + id->name, chn->idx)); + return 0; + } DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop [TOPOLOGY, rc=%d]\n", rc)); - return rc; + printf("<-- leaving probing loop (failed) [TOPOLOGY idx=%d]\n", + chn->idx)); + return 1; } static void topology_free(blkid_probe pr, void *data) |