summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>2005-02-10 18:26:09 +0100
committerGreg KH <gregkh@suse.de>2005-04-26 23:31:07 -0700
commitf22e9686fd4f8e602e8dc11a4b06765206f26edf (patch)
tree3d99beeb2bd964051aff5b6f6c6fe7d938b3a479
parent27753a3cf74f9d665728e0e2c483435b1d72721f (diff)
[PATCH] udevstart: simplify "dev" file searching
Just stat() the "dev" file in the device directory instead of opening the directory and iterating over all entries. Make udevstart work with the settings in with udev.conf so we can run a test program. Add a test for udevstart. Remove changelog stuff from code. We should never start with this silly thing.
-rw-r--r--test/udev-test.pl8
-rw-r--r--test/udevstart-test.pl58
-rw-r--r--udev_start.c143
3 files changed, 126 insertions, 83 deletions
diff --git a/test/udev-test.pl b/test/udev-test.pl
index 5a519ef13b..992fc0019a 100644
--- a/test/udev-test.pl
+++ b/test/udev-test.pl
@@ -14,14 +14,8 @@
# After creation and removal the result is checked against the
# expected value and the result is printed.
#
-# happy testing,
# Kay Sievers <kay.sievers@vrfy.org>, 2003
-#
-# Modified April 9, 2004 by Leann Ogasawara <ogasawara@osdl.org>
-# - expanded @tests array to add more symlinks and permissions tests
-# - some of the symlinks tests also test lack of node creation
-# - added symlink_test() function
-# - moved permissions and major_minor tests into their own functions
+# Leann Ogasawara <ogasawara@osdl.org>, 2004
use warnings;
use strict;
diff --git a/test/udevstart-test.pl b/test/udevstart-test.pl
new file mode 100644
index 0000000000..b6f85bb38c
--- /dev/null
+++ b/test/udevstart-test.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+# udevstart-test
+#
+# runs udevstart in a temporary directory with our test sysfs-tree
+# and counts the created nodes to compare it with the expected numbers.
+#
+# Kay Sievers <kay.sievers@vrfy.org>, 2005
+#
+
+use warnings;
+use strict;
+
+my $PWD = $ENV{PWD};
+my $sysfs = "sys/";
+my $udev_bin = "../udev";
+my $udev_root = "udev-root/"; # !!! directory will be removed !!!
+my $udev_db = ".udevdb";
+my $main_conf = "udev-test.conf";
+my $conf_tmp = "udev-test.rules";
+
+# set env
+$ENV{UDEV_TEST} = "yes";
+$ENV{SYSFS_PATH} = $sysfs;
+$ENV{UDEV_CONFIG_FILE} = $main_conf;
+$ENV{UDEV_NO_DEVD} = "yes";
+$ENV{UDEV_NO_HOTPLUGD} = "yes";
+
+# due to mknod restrictions
+if (!($<==0)) {
+ print "Must have root permissions to run properly.\n";
+ exit;
+}
+
+# prepare
+system("rm -rf $udev_root");
+mkdir($udev_root) || die "unable to create udev_root: $udev_root\n";
+
+# create initial config file
+open CONF, ">$main_conf" || die "unable to create config file: $main_conf";
+print CONF "udev_root=\"$udev_root\"\n";
+print CONF "udev_db=\"$udev_db\"\n";
+print CONF "udev_rules=\"$conf_tmp\"\n";
+close CONF;
+
+system("$udev_bin udevstart");
+my $block = int( `find $udev_root -type b -print | wc -l`);
+my $char = int( `find $udev_root -type c -print | wc -l`);
+
+print "block devices: $block/10\n";
+print "char devices: $char/91\n";
+
+# cleanup
+system("rm -rf $udev_db");
+system("rm -rf $udev_root");
+unlink($conf_tmp);
+unlink($main_conf);
+
diff --git a/udev_start.c b/udev_start.c
index 8c7a06b5af..dcb4293345 100644
--- a/udev_start.c
+++ b/udev_start.c
@@ -30,6 +30,7 @@
#include <ctype.h>
#include <dirent.h>
#include <sys/wait.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -40,22 +41,22 @@
#include "udev.h"
-#define MAX_PATHLEN 1024
-#define SYSBLOCK "/sys/block"
-#define SYSCLASS "/sys/class"
+#define MAX_PATH_SIZE 512
struct device {
struct list_head list;
- char path[MAX_PATHLEN];
- char subsys[MAX_PATHLEN];
+ char path[MAX_PATH_SIZE];
+ char subsys[MAX_PATH_SIZE];
};
/* sort files in lexical order */
-static int device_list_insert(char *path, char *subsystem, struct list_head *device_list)
+static int device_list_insert(const char *path, char *subsystem, struct list_head *device_list)
{
struct device *loop_device;
struct device *new_device;
+ dbg("insert: '%s'\n", path);
+
list_for_each_entry(loop_device, device_list, list) {
if (strcmp(loop_device->path, path) > 0) {
break;
@@ -87,18 +88,20 @@ static char *first_list[] = {
NULL,
};
-static int add_device(char *devpath, char *subsystem)
+static int add_device(const char *path, const char *subsystem)
{
struct udevice udev;
- char path[SYSFS_PATH_MAX];
struct sysfs_class_device *class_dev;
+ const char *devpath;
+
+ devpath = &path[strlen(sysfs_path)];
/* set environment for callouts and dev.d/ */
setenv("DEVPATH", devpath, 1);
setenv("SUBSYSTEM", subsystem, 1);
- snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath);
- path[SYSFS_PATH_MAX-1] = '\0';
+ dbg("exec : '%s' (%s)\n", devpath, path);
+
class_dev = sysfs_open_class_device_path(path);
if (class_dev == NULL) {
dbg ("sysfs_open_class_device_path failed");
@@ -127,7 +130,7 @@ static void exec_list(struct list_head *device_list)
/* handle the "first" type devices first */
list_for_each_entry_safe(loop_device, tmp_device, device_list, list) {
- for (i=0; first_list[i] != NULL; i++) {
+ for (i = 0; first_list[i] != NULL; i++) {
if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) {
add_device(loop_device->path, loop_device->subsys);
list_del(&loop_device->list);
@@ -140,7 +143,7 @@ static void exec_list(struct list_head *device_list)
/* handle the devices we are allowed to, excluding the "last" type devices */
list_for_each_entry_safe(loop_device, tmp_device, device_list, list) {
int found = 0;
- for (i=0; last_list[i] != NULL; i++) {
+ for (i = 0; last_list[i] != NULL; i++) {
if (strncmp(loop_device->path, last_list[i], strlen(last_list[i])) == 0) {
found = 1;
break;
@@ -162,56 +165,61 @@ static void exec_list(struct list_head *device_list)
}
}
+static int has_devt(const char *directory)
+{
+ char filename[MAX_PATH_SIZE];
+ struct stat statbuf;
+
+ snprintf(filename, MAX_PATH_SIZE, "%s/dev", directory);
+ filename[MAX_PATH_SIZE-1] = '\0';
+
+ if (stat(filename, &statbuf) == 0)
+ return 1;
+
+ return 0;
+}
+
static void udev_scan_block(void)
{
+ char base[MAX_PATH_SIZE];
DIR *dir;
struct dirent *dent;
LIST_HEAD(device_list);
- dir = opendir(SYSBLOCK);
+ snprintf(base, MAX_PATH_SIZE, "%s/block", sysfs_path);
+ base[MAX_PATH_SIZE-1] = '\0';
+
+ dir = opendir(base);
if (dir != NULL) {
for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
- char dirname[MAX_PATHLEN];
+ char dirname[MAX_PATH_SIZE];
DIR *dir2;
struct dirent *dent2;
- if ((strcmp(dent->d_name, ".") == 0) ||
- (strcmp(dent->d_name, "..") == 0))
+ if (dent->d_name[0] == '.')
continue;
- snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name);
- dirname[MAX_PATHLEN-1] = '\0';
- device_list_insert(dirname, "block", &device_list);
+ snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name);
+ dirname[MAX_PATH_SIZE-1] = '\0';
+ if (has_devt(dirname))
+ device_list_insert(dirname, "block", &device_list);
+ else
+ continue;
- snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name);
+ snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name);
dir2 = opendir(dirname);
if (dir2 != NULL) {
for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) {
- char dirname2[MAX_PATHLEN];
- DIR *dir3;
- struct dirent *dent3;
+ char dirname2[MAX_PATH_SIZE];
- if ((strcmp(dent2->d_name, ".") == 0) ||
- (strcmp(dent2->d_name, "..") == 0))
+ if (dent2->d_name[0] == '.')
continue;
- snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name);
- dirname2[MAX_PATHLEN-1] = '\0';
-
- dir3 = opendir(dirname2);
- if (dir3 != NULL) {
- for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) {
- char filename[MAX_PATHLEN];
-
- if (strcmp(dent3->d_name, "dev") == 0) {
- snprintf(filename, MAX_PATHLEN, "/block/%s/%s",
- dent->d_name, dent2->d_name);
- filename[MAX_PATHLEN-1] = '\0';
- device_list_insert(filename, "block", &device_list);
- }
- }
- closedir(dir3);
- }
+ snprintf(dirname2, MAX_PATH_SIZE, "%s/%s", dirname, dent2->d_name);
+ dirname2[MAX_PATH_SIZE-1] = '\0';
+
+ if (has_devt(dirname2))
+ device_list_insert(dirname2, "block", &device_list);
}
closedir(dir2);
}
@@ -224,59 +232,42 @@ static void udev_scan_block(void)
static void udev_scan_class(void)
{
+ char base[MAX_PATH_SIZE];
DIR *dir;
struct dirent *dent;
LIST_HEAD(device_list);
- dir = opendir(SYSCLASS);
+ snprintf(base, MAX_PATH_SIZE, "%s/class", sysfs_path);
+ base[MAX_PATH_SIZE-1] = '\0';
+
+ dir = opendir(base);
if (dir != NULL) {
for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
- char dirname[MAX_PATHLEN];
+ char dirname[MAX_PATH_SIZE];
DIR *dir2;
struct dirent *dent2;
- if ((strcmp(dent->d_name, ".") == 0) ||
- (strcmp(dent->d_name, "..") == 0))
+ if (dent->d_name[0] == '.')
continue;
- snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name);
- dirname[MAX_PATHLEN-1] = '\0';
+ snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name);
+ dirname[MAX_PATH_SIZE-1] = '\0';
dir2 = opendir(dirname);
if (dir2 != NULL) {
for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) {
- char dirname2[MAX_PATHLEN];
- DIR *dir3;
- struct dirent *dent3;
+ char dirname2[MAX_PATH_SIZE];
- if ((strcmp(dent2->d_name, ".") == 0) ||
- (strcmp(dent2->d_name, "..") == 0))
+ if (dent2->d_name[0] == '.')
continue;
+ snprintf(dirname2, MAX_PATH_SIZE, "%s/%s", dirname, dent2->d_name);
+ dirname2[MAX_PATH_SIZE-1] = '\0';
+
/* pass the net class as it is */
- if (strcmp(dent->d_name, "net") == 0) {
- snprintf(dirname2, MAX_PATHLEN, "/class/net/%s", dent2->d_name);
+ if (strcmp(dent->d_name, "net") == 0)
device_list_insert(dirname2, "net", &device_list);
- continue;
- }
-
- snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name);
- dirname2[MAX_PATHLEN-1] = '\0';
- dir3 = opendir(dirname2);
- if (dir3 != NULL) {
- for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) {
- char filename[MAX_PATHLEN];
-
- /* pass devices with a "dev" file */
- if (strcmp(dent3->d_name, "dev") == 0) {
- snprintf(filename, MAX_PATHLEN, "/class/%s/%s",
- dent->d_name, dent2->d_name);
- filename[MAX_PATHLEN-1] = '\0';
- device_list_insert(filename, dent->d_name, &device_list);
- break;
- }
- }
- closedir(dir3);
- }
+ else if (has_devt(dirname2))
+ device_list_insert(dirname2, dent->d_name, &device_list);
}
closedir(dir2);
}