summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Nottingham <notting@redhat.com>2007-12-20 16:32:44 -0500
committerBill Nottingham <notting@redhat.com>2007-12-20 18:11:47 -0500
commit2e6cb0d664b17c98ad6d2a6a094d99b65415be11 (patch)
tree1f387cbb194e55f72c2cbef5cfb671b5a0321cb5
parentdaf5c641ddfd2345aaacfe77958f4c25ecbf7d78 (diff)
downloadanaconda-2e6cb0d664b17c98ad6d2a6a094d99b65415be11.tar.gz
anaconda-2e6cb0d664b17c98ad6d2a6a094d99b65415be11.tar.xz
anaconda-2e6cb0d664b17c98ad6d2a6a094d99b65415be11.zip
Add some simple hardware probing code that uses sysfs.
This is in isys because the EDD code needs it. Otherwise it would just be in the loader.
-rw-r--r--isys/Makefile4
-rw-r--r--isys/devices.c165
-rw-r--r--isys/devices.h42
3 files changed, 209 insertions, 2 deletions
diff --git a/isys/Makefile b/isys/Makefile
index aaeaa80a4..0ccc15f71 100644
--- a/isys/Makefile
+++ b/isys/Makefile
@@ -21,13 +21,13 @@ include ../Makefile.inc
CFLAGS += -I$(PYTHONINCLUDE) -I.. -DHAVE_NFS
-OBJECTS = nfsmount.o nfsmount_clnt.o nfsmount_xdr.o imount.o \
+OBJECTS = nfsmount.o nfsmount_clnt.o nfsmount_xdr.o devices.o imount.o \
smp.o cpio.o uncpio.o dasd.o \
lang.o isofs.o dns.o linkdetect.o vio.o \
ethtool.o wireless.o eddsupport.o nl.o str.o auditd.o
SOBJECTS = $(patsubst %.o,%.lo,$(OBJECTS))
SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) isys.c
-LOADLIBES = -lresolv -lpci -lpopt -lext2fs -lz -lkudzu -lpci -ldevmapper -lblkid
+LOADLIBES = -lresolv -lpci -lpopt -lext2fs -lz -ldevmapper -lblkid
LOADLIBES += $(SELINUXLIBES)
ifeq ($(USESELINUX),1)
LOADLIBES += -laudit
diff --git a/isys/devices.c b/isys/devices.c
new file mode 100644
index 000000000..47b4a8263
--- /dev/null
+++ b/isys/devices.c
@@ -0,0 +1,165 @@
+/*
+ * devices.c - various hardware probing functionality
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Bill Nottingham <notting@redhat.com>
+ */
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "devices.h"
+
+/* for 'disks', to filter out weird stuff */
+#define MINIMUM_INTERESTING_SIZE 32*1048576 /* 32MB */
+
+/* from genhd.h, kernel side */
+#define GENHD_FL_REMOVABLE 1
+#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
+#define GENHD_FL_CD 8
+#define GENHD_FL_UP 16
+#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
+#define GENHD_FL_FAIL 64
+
+
+struct device **getDevices(enum deviceType type) {
+ struct device **ret = NULL;
+ struct device *new;
+ int numdevices = 0;
+ int rc;
+
+ if (type & (DEVICE_DISK | DEVICE_CDROM)) {
+ DIR *dir;
+ struct dirent *ent;
+
+ dir = opendir("/sys/block");
+
+ if (!dir) goto storagedone;
+
+ while ((ent = readdir(dir))) {
+ char path[64];
+ char buf[64];
+ int fd, caps, devtype;
+
+ snprintf(path, 64, "/sys/block/%s/capability", ent->d_name);
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ continue;
+ if (read(fd, buf, 64) <= 0) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+ caps = strtol(buf, NULL, 16);
+ if (caps & GENHD_FL_CD)
+ devtype = DEVICE_CDROM;
+ else
+ devtype = DEVICE_DISK;
+ if (!(devtype & type))
+ continue;
+
+ if (devtype == DEVICE_DISK && !(caps & GENHD_FL_REMOVABLE)) {
+ int size;
+
+ snprintf(path, 64, "/sys/block/%s/size", ent->d_name);
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ continue;
+ if (read(fd, buf, 64) <= 0) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+ size = atoi(buf);
+ if (size < MINIMUM_INTERESTING_SIZE)
+ continue;
+ }
+
+ new = calloc(1, sizeof(struct device));
+ new->device = strdup(ent->d_name);
+ /* FIXME */
+ rc = asprintf(&new->description,"Storage device %s",new->device);
+ new->type = devtype;
+ if (caps & GENHD_FL_REMOVABLE) {
+ new->priv.removable = 1;
+ }
+ ret = realloc(ret, (numdevices+2) * sizeof(struct device));
+ ret[numdevices] = new;
+ ret[numdevices+1] = NULL;
+ numdevices++;
+ }
+ }
+storagedone:
+
+ if (type & DEVICE_NETWORK) {
+ DIR *dir;
+ struct dirent *ent;
+
+ dir = opendir("/sys/class/net");
+
+ if (!dir) goto netdone;
+
+ while ((ent = readdir(dir))) {
+ char path[64];
+ int fd, type;
+ char buf[64];
+
+ snprintf(path, 64, "/sys/class/net/%s/type", ent->d_name);
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ continue;
+ if (read(fd, buf, 64) <= 0) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+ type = atoi(buf);
+ if (type != 1)
+ continue;
+
+ new = calloc(1, sizeof(struct device));
+ new->device = strdup(ent->d_name);
+ /* FIXME */
+ rc = asprintf(&new->description,"Ethernet device %s",new->device);
+ snprintf(path, 64, "/sys/class/net/%s/address", ent->d_name);
+ fd = open(path, O_RDONLY);
+ if (fd != -1) {
+ if (read(fd, buf, 64) > 0) {
+ int i;
+ for (i = (strlen(buf)-1); isspace(buf[i]); i--) buf[i] = '\0';
+ new->priv.hwaddr = strdup(buf);
+ }
+ }
+ ret = realloc(ret, (numdevices+2) * sizeof(struct device));
+ ret[numdevices] = new;
+ ret[numdevices+1] = NULL;
+ numdevices++;
+ }
+ }
+netdone:
+ return ret;
+}
+
diff --git a/isys/devices.h b/isys/devices.h
new file mode 100644
index 000000000..9428a7725
--- /dev/null
+++ b/isys/devices.h
@@ -0,0 +1,42 @@
+/*
+ * devices.h
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DEVICES_H
+#define DEVICES_H
+
+enum deviceType {
+ DEVICE_ANY = ~0,
+ DEVICE_NETWORK = (1 << 0),
+ DEVICE_DISK = (1 << 1),
+ DEVICE_CDROM = (1 << 2)
+};
+
+struct device {
+ char *device;
+ char *description;
+ enum deviceType type;
+ union {
+ char *hwaddr;
+ int removable;
+ } priv;
+};
+
+struct device **getDevices(enum deviceType type);
+
+#endif