[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH 1/3] 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.
---
 isys/Makefile  |    4 +-
 isys/devices.c |  165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 isys/devices.h |   42 ++++++++++++++
 3 files changed, 209 insertions(+), 2 deletions(-)

diff --git a/isys/Makefile b/isys/Makefile
index aaeaa80..0ccc15f 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 0000000..47b4a82
--- /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 0000000..9428a77
--- /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
-- 
1.5.3.7


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]