1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-28 17:57:25 +03:00

[PATCH] don't wait for sysfs if the kernel(2.6.10-rc2) tells us what not to expect

Newer kernels will tell us if we should wait for the "device" or
the "bus" link. So don't waste the time with our lists or wait
for the timeout.
This commit is contained in:
kay.sievers@vrfy.org 2004-11-13 12:36:47 +01:00 committed by Greg KH
parent 2092fbcdeb
commit d402af7d71
5 changed files with 77 additions and 35 deletions

View File

@ -28,6 +28,7 @@
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include "udev.h"
#include "logging.h"
@ -72,6 +73,29 @@ void udev_set_values(struct udevice *udev, const char* devpath,
udev->type = get_device_type(devpath, subsystem);
}
int kernel_release_satisfactory(int version, int patchlevel, int sublevel)
{
static struct utsname uts;
static int kversion = 0;
static int kpatchlevel;
static int ksublevel;
if (kversion == 0) {
if (uname(&uts) != 0)
return -1;
if (sscanf (uts.release, "%u.%u.%u", &kversion, &kpatchlevel, &ksublevel) != 3) {
kversion = 0;
return -1;
}
}
if (kversion >= version && kpatchlevel >= patchlevel && ksublevel >= sublevel)
return 1;
else
return 0;
}
int create_path(const char *path)
{
char p[NAME_SIZE];

View File

@ -79,12 +79,12 @@ do { \
extern char get_device_type(const char *path, const char *subsystem);
extern void udev_set_values(struct udevice *udev, const char* devpath,
const char *subsystem, const char* action);
extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel);
extern int create_path(const char *path);
extern int file_map(const char *filename, char **buf, size_t *bufsize);
extern void file_unmap(char *buf, size_t bufsize);
extern size_t buf_get_line(char *buf, size_t buflen, size_t cur);
extern void no_trailing_slash(char *path);
typedef int (*file_fnct_t)(const char *filename, void *data);
extern int call_foreach_file(file_fnct_t fnct, const char *dirname,
const char *suffix, void *data);

View File

@ -28,14 +28,13 @@
#include <errno.h>
#include <sys/stat.h>
#include "logging.h"
#include "libsysfs/sysfs/libsysfs.h"
#include "udev_version.h"
#include "udev_sysfs.h"
#include "libsysfs/sysfs/libsysfs.h"
#include "udev_lib.h"
#include "logging.h"
/* list of subsystem specific files
* NULL if there is no file to wait for
*/
/* list of subsystem specific files, NULL if there is no file to wait for */
static struct subsystem_file {
char *subsystem;
char *file;
@ -204,6 +203,13 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d
struct class_device *classdevice;
int len;
/* the kernel may tell us what to wait for */
if (kernel_release_satisfactory(2,6,10) > 0)
if (getenv("PHYSDEVPATH") == NULL) {
dbg("the kernel says, that there is no physical device for '%s'", class_dev->path);
return 1;
}
for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) {
if (strcmp(class_dev->classname, classdevice->subsystem) == 0) {
/* see if no device in this class is expected to have a device-link */
@ -229,7 +235,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d
return 0;
}
/* skip waiting for the bus */
/* skip waiting for the bus of the devices device */
static int class_device_expect_no_bus(struct sysfs_class_device *class_dev)
{
static char *devices_without_bus[] = {
@ -250,14 +256,14 @@ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev)
return 0;
}
/* wait for the bus and for a bus specific file to show up */
int wait_for_bus_device(struct sysfs_device *devices_dev,
/* wait for a devices device specific file to show up */
int wait_for_devices_device(struct sysfs_device *devices_dev,
const char **error)
{
static struct bus_file {
static struct device_file {
char *bus;
char *file;
} bus_files[] = {
} device_files[] = {
{ .bus = "scsi", .file = "vendor" },
{ .bus = "usb", .file = "idVendor" },
{ .bus = "usb", .file = "iInterface" },
@ -272,9 +278,16 @@ int wait_for_bus_device(struct sysfs_device *devices_dev,
{ .bus = "ieee1394", .file = "address" },
{ NULL, NULL }
};
struct bus_file *busfile;
struct device_file *devicefile;
int loop;
/* the kernel may tell us what to wait for */
if (kernel_release_satisfactory(2,6,10) > 0)
if (getenv("PHYSDEVBUS") == NULL) {
dbg("the kernel says, that there is no bus for '%s'", devices_dev->path);
return 0;
}
/* wait for the bus device link to the devices device */
loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND;
while (--loop) {
@ -291,22 +304,22 @@ int wait_for_bus_device(struct sysfs_device *devices_dev,
}
dbg("bus device link found for bus '%s'", devices_dev->bus);
/* wait for a bus specific file to show up */
/* wait for a bus device specific file to show up */
loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND;
while (--loop) {
int found_bus_type = 0;
for (busfile = bus_files; busfile->bus != NULL; busfile++) {
if (strcmp(devices_dev->bus, busfile->bus) == 0) {
for (devicefile = device_files; devicefile->bus != NULL; devicefile++) {
if (strcmp(devices_dev->bus, devicefile->bus) == 0) {
char filename[SYSFS_PATH_MAX];
struct stat stats;
found_bus_type = 1;
snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, busfile->file);
dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, filename);
snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, devicefile->file);
dbg("looking at bus '%s' device for specific file '%s'", devices_dev->bus, filename);
if (stat(filename, &stats) == 0) {
dbg("bus '%s' specific file '%s' found", devices_dev->bus, busfile->file);
dbg("bus '%s' device specific file '%s' found", devices_dev->bus, devicefile->file);
return 0;
}
}
@ -321,14 +334,14 @@ int wait_for_bus_device(struct sysfs_device *devices_dev,
usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
}
dbg("error: getting bus '%s' specific file '%s'", devices_dev->bus, busfile->file);
dbg("error: getting '%s' device specific file '%s'", devices_dev->bus, devicefile->file);
if (error)
*error = "bus specific file unavailable";
*error = "bus device specific file unavailable";
return -1;
}
struct sysfs_class_device *open_class_device_wait(const char *path)
struct sysfs_class_device *wait_class_device_open(const char *path)
{
struct sysfs_class_device *class_dev;
int loop;
@ -358,7 +371,7 @@ int wait_for_class_device(struct sysfs_class_device *class_dev,
/* skip devices without devices-link */
if (class_device_expect_no_device_link(class_dev)) {
dbg("no device symlink expected for '%s', ", class_dev->name);
return -ENODEV;
return 0;
}
/* the symlink may be on the parent device */
@ -388,16 +401,16 @@ int wait_for_class_device(struct sysfs_class_device *class_dev,
}
dbg("device symlink found pointing to '%s'", devices_dev->path);
/* wait for the bus value */
/* wait for the devices device */
if (class_device_expect_no_bus(class_dev)) {
dbg("no bus device expected for '%s', ", class_dev->classname);
return 0;
} else {
return wait_for_bus_device(devices_dev, error);
}
return wait_for_devices_device(devices_dev, error);
}
struct sysfs_device *open_devices_device_wait(const char *path)
struct sysfs_device *wait_devices_device_open(const char *path)
{
struct sysfs_device *devices_dev;
int loop;

View File

@ -28,9 +28,13 @@
#define WAIT_LOOP_PER_SECOND 20
extern int subsystem_expect_no_dev(const char *subsystem);
extern int wait_for_bus_device(struct sysfs_device *devices_dev, const char **error);
/* /sys/class /sys/block devices */
extern struct sysfs_class_device *wait_class_device_open(const char *path);
extern int wait_for_class_device(struct sysfs_class_device *class_dev, const char **error);
extern struct sysfs_class_device *open_class_device_wait(const char *path);
extern struct sysfs_device *open_devices_device_wait(const char *path);
/* /sys/devices devices */
extern struct sysfs_device *wait_devices_device_open(const char *path);
extern int wait_for_devices_device(struct sysfs_device *devices_dev, const char **error);
#endif /* _UDEV_SYSFS_H_ */

View File

@ -32,10 +32,11 @@
#include <errno.h>
#include <sys/stat.h>
#include "logging.h"
#include "libsysfs/sysfs/libsysfs.h"
#include "udev_lib.h"
#include "udev_version.h"
#include "udev_sysfs.h"
#include "libsysfs/sysfs/libsysfs.h"
#include "logging.h"
#ifdef LOG
unsigned char logname[LOGNAME_SIZE];
@ -106,7 +107,7 @@ int main(int argc, char *argv[], char *envp[])
}
/* open the class device we are called for */
class_dev = open_class_device_wait(filename);
class_dev = wait_class_device_open(filename);
if (!class_dev) {
dbg("error: class device unavailable (probably remove has beaten us)");
goto exit;
@ -132,15 +133,15 @@ int main(int argc, char *argv[], char *envp[])
filename[SYSFS_PATH_MAX-1] = '\0';
/* open the path we are called for */
devices_dev = open_devices_device_wait(filename);
devices_dev = wait_devices_device_open(filename);
if (!devices_dev) {
dbg("error: devices device unavailable (probably remove has beaten us)");
goto exit;
}
dbg("devices device opened '%s'", filename);
/* wait for the bus value */
wait_for_bus_device(devices_dev, &error);
/* wait for the devices device */
wait_for_devices_device(devices_dev, &error);
sysfs_close_device(devices_dev);