summaryrefslogtreecommitdiff
path: root/shlibs/blkid/src/topology/topology.c
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2009-09-18 10:19:59 +0200
committerKarel Zak <kzak@redhat.com>2009-09-18 10:19:59 +0200
commitbf539f48f37da7a3609350ce4e9839921527de23 (patch)
tree227aef378716086655953734854695e8994d6380 /shlibs/blkid/src/topology/topology.c
parent38fb0905a6105f0dafe2db1beef8a92271c68f35 (diff)
downloadutil-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.c177
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)