chiark / gitweb /
[PATCH] big cleanup of internal udev api
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Tue, 19 Oct 2004 02:11:51 +0000 (19:11 -0700)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 05:02:46 +0000 (22:02 -0700)
Here is the first patch to cleanup the internal processing of the
various stages of an udev event. It should not change any behavior,
but if your system depends on udev, please always test it before reboot :)

We pass only one generic structure around between add, remove,
namedev, db and dev_d handling and make all relevant data available
to all internal stages. All udev structures are renamed to "udev".

We replace the fake parameter by a flag in the udev structure.

We open the class device in the main binaries and not in udev_add, to
make it possible to use libsysfs for udevstart directory crawling.

The last sleep parameters are removed.

16 files changed:
dev_d.c
extras/start_udev
namedev.c
namedev.h
test/udev-test.pl
udev.c
udev.h
udev_add.c
udev_lib.c
udev_lib.h
udev_remove.c
udevdb.c
udevdb.h
udevinfo.c
udevstart.c
udevtest.c

diff --git a/dev_d.c b/dev_d.c
index eaf9b1dc12c7ecef5364a373041f380f5d964d89..5580b5a3627ea09ee59ed9acd47000cc0190d750 100644 (file)
--- a/dev_d.c
+++ b/dev_d.c
@@ -80,7 +80,7 @@ static int run_program(char *name)
  *     subsystem/
  *     default/
  */
-void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath)
+void dev_d_send(struct udevice *udev)
 {
        char dirname[256];
        char env_devname[NAME_SIZE];
@@ -91,17 +91,17 @@ void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath)
                return;
 
        memset(env_devname, 0x00, sizeof(env_devname));
-       if (dev->type == 'b' || dev->type == 'c') {
+       if (udev->type == 'b' || udev->type == 'c') {
                strfieldcpy(env_devname, udev_root);
-               strfieldcat(env_devname, dev->name);
-       } else if (dev->type == 'n') {
-               strfieldcpy(env_devname, dev->name);
-               setenv("DEVPATH", devpath, 1);
+               strfieldcat(env_devname, udev->name);
+       } else if (udev->type == 'n') {
+               strfieldcpy(env_devname, udev->name);
+               setenv("DEVPATH", udev->devpath, 1);
        }
        setenv("DEVNAME", env_devname, 1);
        dbg("DEVNAME='%s'", env_devname);
 
-       devname = strdup(dev->name);
+       devname = strdup(udev->name);
        if (!devname) {
                dbg("out of memory");
                return;
@@ -121,11 +121,11 @@ void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath)
        }
 
        strcpy(dirname, DEVD_DIR);
-       strfieldcat(dirname, dev->name);
+       strfieldcat(dirname, udev->name);
        call_foreach_file(run_program, dirname, DEVD_SUFFIX);
 
        strcpy(dirname, DEVD_DIR);
-       strfieldcat(dirname, subsystem);
+       strfieldcat(dirname, udev->subsystem);
        call_foreach_file(run_program, dirname, DEVD_SUFFIX);
 
        strcpy(dirname, DEVD_DIR "default");
index bbf32a1bb9befb81940c2481d4f76503e9527737..c2518761e316d42a6b1f7da54a3479b4ae2cba90 100644 (file)
@@ -30,7 +30,6 @@ udevd=/sbin/udevd
 
 run_udev () {
        export ACTION=add
-       export UDEV_NO_SLEEP=1
 
        # handle block devices and their partitions
        for i in ${sysfs_dir}/block/*; do
index 39f033726c5cdc554e0a641aee77b5845f259c96..03fc41d2346f3e174956cb828a255ec567097cb7 100644 (file)
--- a/namedev.c
+++ b/namedev.c
@@ -692,7 +692,7 @@ try_parent:
 
 }
 
-int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev)
+int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev)
 {
        struct sysfs_class_device *class_dev_parent;
        struct sysfs_device *sysfs_device = NULL;
@@ -718,9 +718,10 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud
        }
 
        if (sysfs_device) {
-               dbg("found /device-device: path='%s', bus_id='%s', bus='%s'",
+               dbg("found devices device: path='%s', bus_id='%s', bus='%s'",
                    sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus);
                strfieldcpy(udev->bus_id, sysfs_device->bus_id);
+               strfieldcpy(udev->bus, sysfs_device->bus);
        }
 
        strfieldcpy(udev->kernel_name, class_dev->name);
index fa924b14d96dd12e4076a0ddb8e518d6c863d5e8..f1e0082241e8f611aeb9a637bd54e6cb90f05267 100644 (file)
--- a/namedev.h
+++ b/namedev.h
@@ -102,7 +102,7 @@ extern struct list_head config_device_list;
 extern struct list_head perm_device_list;
 
 extern int namedev_init(void);
-extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev);
+extern int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev);
 extern int namedev_init_permissions(void);
 extern int namedev_init_rules(void);
 
index 9e4e192c51230f3465cd8e59bea774d7df2a2065..a7becf99df36bed2c976c8226822fb6b6a1f35ef 100644 (file)
@@ -1100,7 +1100,6 @@ EOF
 $ENV{UDEV_TEST} = "yes";
 $ENV{SYSFS_PATH} = $sysfs;
 $ENV{UDEV_CONFIG_FILE} = $main_conf;
-$ENV{UDEV_NO_SLEEP} = "yes";
 $ENV{UDEV_NO_DEVD} = "yes";
 
 
diff --git a/udev.c b/udev.c
index 10a937e4724f54bc69d609960b8799916f7dc182..8d5be0542e8d3edff7fabc74f388eaeecb01ade2 100644 (file)
--- a/udev.c
+++ b/udev.c
@@ -107,9 +107,9 @@ static int subsystem_without_dev(const char *subsystem)
 int main(int argc, char *argv[], char *envp[])
 {
        struct sigaction act;
-       char *action;
-       char *devpath = "";
-       char *subsystem = "";
+       struct sysfs_class_device *class_dev;
+       struct udevice udev;
+       char path[SYSFS_PATH_MAX];
        int retval = -EINVAL;
        enum {
                ADD,
@@ -129,7 +129,10 @@ int main(int argc, char *argv[], char *envp[])
        if (strstr(argv[0], "udevstart")) {
                act_type = UDEVSTART;
        } else {
-               action = get_action();
+               const char *action = get_action();
+               const char *devpath = get_devpath();
+               const char *subsystem = get_subsystem(main_argv[1]);
+
                if (!action) {
                        dbg("no action?");
                        goto exit;
@@ -139,16 +142,15 @@ int main(int argc, char *argv[], char *envp[])
                } else if (strcmp(action, "remove") == 0) {
                        act_type = REMOVE;
                } else {
-                       dbg("unknown action '%s'", action);
+                       dbg("no action '%s' for us", action);
                        goto exit;
                }
 
-               devpath = get_devpath();
                if (!devpath) {
                        dbg("no devpath?");
                        goto exit;
                }
-               dbg("looking at '%s'", devpath);
+               dbg("looking at '%s'", udev.devpath);
 
                /* we only care about class devices and block stuff */
                if (!strstr(devpath, "class") && !strstr(devpath, "block")) {
@@ -156,17 +158,18 @@ int main(int argc, char *argv[], char *envp[])
                        goto exit;
                }
 
-               subsystem = get_subsystem(main_argv[1]);
                if (!subsystem) {
-                       dbg("no subsystem?");
+                       dbg("no subsystem");
                        goto exit;
                }
 
                /* skip blacklisted subsystems */
                if (subsystem_without_dev(subsystem)) {
                        dbg("don't care about '%s' devices", subsystem);
-                       exit(0);
+                       goto exit;
                };
+
+               udev_set_values(&udev, devpath, subsystem);
        }
 
        /* set signal handlers */
@@ -192,12 +195,25 @@ int main(int argc, char *argv[], char *envp[])
                break;
        case ADD:
                dbg("udev add");
+
+               /* init rules */
                namedev_init();
-               retval = udev_add_device(devpath, subsystem, NOFAKE);
+
+               /* open the device */
+               snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath);
+               class_dev = sysfs_open_class_device_path(path);
+               if (class_dev == NULL) {
+                       dbg ("sysfs_open_class_device_path failed");
+                       break;
+               }
+               dbg("opened class_dev->name='%s'", class_dev->name);
+
+               /* name, create node, store in db */
+               retval = udev_add_device(&udev, class_dev);
                break;
        case REMOVE:
                dbg("udev remove");
-               retval = udev_remove_device(devpath, subsystem);
+               retval = udev_remove_device(&udev);
        }
 
        udevdb_exit();
diff --git a/udev.h b/udev.h
index 642b30b517f4a76f503caf5d07011abfb9608647..70de729f30033c7a92f94013e343011703f96f64 100644 (file)
--- a/udev.h
+++ b/udev.h
 
 #define LINE_SIZE                      256
 
-#define FAKE                           1
-#define NOFAKE                         0
-
 /* length of public data to store in udevdb */
-#define UDEVICE_LEN (offsetof(struct udevice, bus_id))
+#define UDEVICE_DB_LEN (offsetof(struct udevice, devpath))
 
 struct udevice {
        char name[NAME_SIZE];
@@ -61,20 +58,23 @@ struct udevice {
        char config_file[NAME_SIZE];
        long config_uptime;
 
-       /* private data that help us in building strings */
+       /* private data, not stored in udevdb */
+       char devpath[DEVPATH_SIZE];
+       char subsystem[SUBSYSTEM_SIZE];
        char bus_id[SYSFS_NAME_LEN];
+       char bus[SYSFS_NAME_LEN];
        char program_result[NAME_SIZE];
        char kernel_number[NAME_SIZE];
        char kernel_name[NAME_SIZE];
+       int test_run;
 };
 
-extern int udev_add_device(const char *path, const char *subsystem, int fake);
-extern int udev_remove_device(const char *path, const char *subsystem);
+extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev);
+extern int udev_remove_device(struct udevice *udev);
 extern void udev_init_config(void);
 extern int udev_start(void);
 extern int parse_get_pair(char **orig_string, char **left, char **right);
-extern void dev_d_send(struct udevice *dev, const char *subsystem,
-       const char *devpath);
+extern void dev_d_send(struct udevice *udev);
 
 extern char **main_argv;
 extern char **main_envp;
index 08257609adcc5c7c7d97c577b7cddd714dd6e30c..d07120de62a14103b443c36a11076a669f6fab07 100644 (file)
@@ -186,7 +186,7 @@ static void set_to_local_user(char *user)
        endutent();
 }
 
-static int create_node(struct udevice *dev, int fake)
+static int create_node(struct udevice *udev)
 {
        char filename[NAME_SIZE];
        char linkname[NAME_SIZE];
@@ -200,90 +200,89 @@ static int create_node(struct udevice *dev, int fake)
        int len;
 
        strfieldcpy(filename, udev_root);
-       strfieldcat(filename, dev->name);
+       strfieldcat(filename, udev->name);
 
-       switch (dev->type) {
+       switch (udev->type) {
        case 'b':
-               dev->mode |= S_IFBLK;
+               udev->mode |= S_IFBLK;
                break;
        case 'c':
        case 'u':
-               dev->mode |= S_IFCHR;
+               udev->mode |= S_IFCHR;
                break;
        case 'p':
-               dev->mode |= S_IFIFO;
+               udev->mode |= S_IFIFO;
                break;
        default:
-               dbg("unknown node type %c\n", dev->type);
+               dbg("unknown node type %c\n", udev->type);
                return -EINVAL;
        }
 
        /* create parent directories if needed */
-       if (strrchr(dev->name, '/'))
+       if (strrchr(udev->name, '/'))
                create_path(filename);
 
-       if (dev->owner[0] != '\0') {
+       if (udev->owner[0] != '\0') {
                char *endptr;
-               unsigned long id = strtoul(dev->owner, &endptr, 10);
+               unsigned long id = strtoul(udev->owner, &endptr, 10);
                if (endptr[0] == '\0')
                        uid = (uid_t) id;
                else {
                        struct passwd *pw;
-                       if (strncmp(dev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0)
-                               set_to_local_user(dev->owner);
+                       if (strncmp(udev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0)
+                               set_to_local_user(udev->owner);
 
-                       pw = getpwnam(dev->owner);
+                       pw = getpwnam(udev->owner);
                        if (pw == NULL)
-                               dbg("specified user unknown '%s'", dev->owner);
+                               dbg("specified user unknown '%s'", udev->owner);
                        else
                                uid = pw->pw_uid;
                }
        }
 
-       if (dev->group[0] != '\0') {
+       if (udev->group[0] != '\0') {
                char *endptr;
-               unsigned long id = strtoul(dev->group, &endptr, 10);
+               unsigned long id = strtoul(udev->group, &endptr, 10);
                if (endptr[0] == '\0')
                        gid = (gid_t) id;
                else {
-                       struct group *gr = getgrnam(dev->group);
+                       struct group *gr = getgrnam(udev->group);
                        if (gr == NULL)
-                               dbg("specified group unknown '%s'", dev->group);
+                               dbg("specified group unknown '%s'", udev->group);
                        else
                                gid = gr->gr_gid;
                }
        }
 
-       if (!fake) {
+       if (!udev->test_run) {
                info("creating device node '%s'", filename);
-               if (make_node(filename, dev->major, dev->minor, dev->mode, uid, gid) != 0)
+               if (make_node(filename, udev->major, udev->minor, udev->mode, uid, gid) != 0)
                        goto error;
        } else {
                info("creating device node '%s', major = '%d', minor = '%d', "
                     "mode = '%#o', uid = '%d', gid = '%d'", filename,
-                    dev->major, dev->minor, (mode_t)dev->mode, uid, gid);
+                    udev->major, udev->minor, (mode_t)udev->mode, uid, gid);
        }
 
        /* create all_partitions if requested */
-       if (dev->partitions > 0) {
-               info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions);
-               if (!fake) {
-                       for (i = 1; i <= dev->partitions; i++) {
+       if (udev->partitions > 0) {
+               info("creating device partition nodes '%s[1-%i]'", filename, udev->partitions);
+               if (!udev->test_run) {
+                       for (i = 1; i <= udev->partitions; i++) {
                                strfieldcpy(partitionname, filename);
                                strintcat(partitionname, i);
-                               make_node(partitionname, dev->major,
-                                         dev->minor + i, dev->mode, uid, gid);
+                               make_node(partitionname, udev->major, udev->minor + i, udev->mode, uid, gid);
                        }
                }
        }
 
        /* create symlink(s) if requested */
-       foreach_strpart(dev->symlink, " ", pos, len) {
+       foreach_strpart(udev->symlink, " ", pos, len) {
                strfieldcpymax(linkname, pos, len+1);
                strfieldcpy(filename, udev_root);
                strfieldcat(filename, linkname);
-               dbg("symlink '%s' to node '%s' requested", filename, dev->name);
-               if (!fake)
+               dbg("symlink '%s' to node '%s' requested", filename, udev->name);
+               if (!udev->test_run)
                        if (strrchr(linkname, '/'))
                                create_path(filename);
 
@@ -291,8 +290,8 @@ static int create_node(struct udevice *dev, int fake)
                linktarget[0] = '\0';
                i = 0;
                tail = 0;
-               while ((dev->name[i] == linkname[i]) && dev->name[i]) {
-                       if (dev->name[i] == '/')
+               while ((udev->name[i] == linkname[i]) && udev->name[i]) {
+                       if (udev->name[i] == '/')
                                tail = i+1;
                        i++;
                }
@@ -302,10 +301,10 @@ static int create_node(struct udevice *dev, int fake)
                        i++;
                }
 
-               strfieldcat(linktarget, &dev->name[tail]);
+               strfieldcat(linktarget, &udev->name[tail]);
 
                dbg("symlink(%s, %s)", linktarget, filename);
-               if (!fake) {
+               if (!udev->test_run) {
                        selinux_setfscreatecon(filename, S_IFLNK);
                        unlink(filename);
                        if (symlink(linktarget, filename) != 0)
@@ -319,35 +318,14 @@ error:
        return -1;
 }
 
-static struct sysfs_class_device *get_class_dev(const char *device_name)
-{
-       char dev_path[SYSFS_PATH_MAX];
-       struct sysfs_class_device *class_dev = NULL;
-
-       strfieldcpy(dev_path, sysfs_path);
-       strfieldcat(dev_path, device_name);
-       dbg("looking at '%s'", dev_path);
-
-       /* open up the sysfs class device for this thing... */
-       class_dev = sysfs_open_class_device_path(dev_path);
-       if (class_dev == NULL) {
-               dbg ("sysfs_open_class_device_path failed");
-               goto exit;
-       }
-       dbg("class_dev->name='%s'", class_dev->name);
-
-exit:
-       return class_dev;
-}
-
-static int rename_net_if(struct udevice *dev, int fake)
+static int rename_net_if(struct udevice *udev)
 {
        int sk;
        struct ifreq ifr;
        int retval;
 
-       dbg("changing net interface name from '%s' to '%s'", dev->kernel_name, dev->name);
-       if (fake)
+       dbg("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name);
+       if (udev->test_run)
                return 0;
 
        sk = socket(PF_INET, SOCK_DGRAM, 0);
@@ -357,8 +335,8 @@ static int rename_net_if(struct udevice *dev, int fake)
        }
 
        memset(&ifr, 0x00, sizeof(struct ifreq));
-       strfieldcpy(ifr.ifr_name, dev->kernel_name);
-       strfieldcpy(ifr.ifr_newname, dev->name);
+       strfieldcpy(ifr.ifr_name, udev->kernel_name);
+       strfieldcpy(ifr.ifr_newname, udev->name);
 
        retval = ioctl(sk, SIOCSIFNAME, &ifr);
        if (retval != 0)
@@ -368,69 +346,57 @@ static int rename_net_if(struct udevice *dev, int fake)
        return retval;
 }
 
-int udev_add_device(const char *path, const char *subsystem, int fake)
+int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev)
 {
-       struct sysfs_class_device *class_dev;
-       struct udevice dev;
-       char devpath[DEVPATH_SIZE];
        char *pos;
        int retval = 0;
 
-       memset(&dev, 0x00, sizeof(dev));
-
-       dev.type = get_device_type(path, subsystem);
-
-       class_dev = get_class_dev(path);
-       if (class_dev == NULL)
-               return -1;
-
-       if (dev.type == 'b' || dev.type == 'c') {
-               retval = get_major_minor(class_dev, &dev);
+       if (udev->type == 'b' || udev->type == 'c') {
+               retval = get_major_minor(class_dev, udev);
                if (retval != 0) {
                        dbg("no dev-file found, do nothing");
                        goto close;
                }
        }
 
-       if (namedev_name_device(class_dev, &dev) != 0)
+       if (namedev_name_device(udev, class_dev) != 0)
                goto exit;
 
-       dbg("name='%s'", dev.name);
+       dbg("adding name='%s'", udev->name);
 
        selinux_init();
-       switch (dev.type) {
+       switch (udev->type) {
        case 'b':
        case 'c':
-               retval = create_node(&dev, fake);
+               retval = create_node(udev);
                if (retval != 0)
                        goto exit;
-               if ((!fake) && (udevdb_add_dev(path, &dev) != 0))
+               if ((!udev->test_run) && (udevdb_add_dev(udev) != 0))
                        dbg("udevdb_add_dev failed, but we are going to try "
                            "to create the node anyway. But remove might not "
                            "work properly for this device.");
 
-               dev_d_send(&dev, subsystem, path);
+               dev_d_send(udev);
                break;
 
        case 'n':
-               strfieldcpy(devpath, path);
-               if (strcmp(dev.name, dev.kernel_name) != 0) {
-                       retval = rename_net_if(&dev, fake);
+               if (strcmp(udev->name, udev->kernel_name) != 0) {
+                       retval = rename_net_if(udev);
                        if (retval != 0)
                                goto exit;
                        /* netif's are keyed with the configured name, cause
                         * the original kernel name sleeps with the fishes
                         */
-                       pos = strrchr(devpath, '/');
+                       pos = strrchr(udev->devpath, '/');
                        if (pos != NULL) {
                                pos[1] = '\0';
-                               strfieldcat(devpath, dev.name);
+                               strfieldcat(udev->devpath, udev->name);
                        }
                }
-               if ((!fake) && (udevdb_add_dev(devpath, &dev) != 0))
+               if ((!udev->test_run) && (udevdb_add_dev(udev) != 0))
                        dbg("udevdb_add_dev failed");
 
-               dev_d_send(&dev, subsystem, devpath);
+               dev_d_send(udev);
                break;
        }
 
index 4991ec3acb4447699b34e2a643c76429a5d04833..bd3eeba661184957d2f6401012922411cc109b59 100644 (file)
@@ -29,7 +29,6 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
 #include "udev.h"
 #include "logging.h"
 #include "udev_lib.h"
@@ -113,6 +112,14 @@ char get_device_type(const char *path, const char *subsystem)
        return '\0';
 }
 
+void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem)
+{
+       memset(udev, 0x00, sizeof(struct udevice));
+       strfieldcpy(udev->devpath, devpath);
+       strfieldcpy(udev->subsystem, subsystem);
+       udev->type = get_device_type(devpath, subsystem);
+}
+
 int file_map(const char *filename, char **buf, size_t *bufsize)
 {
        struct stat stats;
index e9ff379fc6665fda1a5e70f2d60808882f09f458..8a14ef00b6cf6607661f35a758d2bf560997285a 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef _UDEV_LIB_H_
 #define _UDEV_LIB_H_
 
+#include "udev.h"
 
 #define strfieldcpy(to, from) \
 do { \
@@ -81,6 +82,7 @@ extern char *get_devname(void);
 extern char *get_seqnum(void);
 extern char *get_subsystem(char *subsystem);
 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);
 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);
index d4be8bd6f9cd6c8e5ed214964339e21032df90df..d97a2411f4d7fe587d8a330e4b5a8e656be9f93e 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -161,35 +162,37 @@ static int delete_node(struct udevice *dev)
 }
 
 /*
- * Look up the sysfs path in the database to see if we have named this device
- * something different from the kernel name.  If we have, us it.  If not, use
- * the default kernel name for lack of anything else to know to do.
+ * look up the sysfs path in the database to get the node name to remove
+ * If we can't find it, use kernel name for lack of anything else to know to do
  */
-int udev_remove_device(const char *path, const char *subsystem)
+int udev_remove_device(struct udevice *udev)
 {
-       struct udevice dev;
+       struct udevice db_dev;
        char *temp;
        int retval;
 
-       memset(&dev, 0x00, sizeof(dev));
+       memset(&db_dev, 0x00, sizeof(struct udevice));
 
-       retval = udevdb_get_dev(path, &dev);
-       if (retval != 0) {
-               dbg("'%s' not found in database, falling back on default name", path);
-               temp = strrchr(path, '/');
+       retval = udevdb_get_dev(udev->devpath, &db_dev);
+       if (retval == 0) {
+               /* get stored values in our device */
+               memcpy(udev, &db_dev, UDEVICE_DB_LEN);
+       } else {
+               /* fall back to kernel name */
+               temp = strrchr(udev->devpath, '/');
                if (temp == NULL)
                        return -ENODEV;
-               strfieldcpy(dev.name, &temp[1]);
+               strfieldcpy(udev->name, &temp[1]);
+               dbg("'%s' not found in database, falling back on default name", udev->name);
        }
-       dbg("name='%s'", dev.name);
+       dbg("remove name='%s'", udev->name);
 
-       dev.type = get_device_type(path, subsystem);
-       dev_d_send(&dev, subsystem, path);
-       udevdb_delete_dev(path);
+       dev_d_send(udev);
+       udevdb_delete_dev(udev->devpath);
 
-       if (dev.type == 'b' || dev.type == 'c')
-               retval = delete_node(&dev);
-       else if (dev.type == 'n')
+       if (udev->type == 'b' || udev->type == 'c')
+               retval = delete_node(udev);
+       else
                retval = 0;
 
        return retval;
index a218b66179319f7f48b0db7f8df941f0f6af51d1..3d0a9ea3c2b6cc2a646ebe6b3bf7f5fc88ffd7bc 100644 (file)
--- a/udevdb.c
+++ b/udevdb.c
@@ -44,7 +44,7 @@
 static TDB_CONTEXT *udevdb;
 sig_atomic_t gotalarm;
 
-int udevdb_add_dev(const char *path, const struct udevice *dev)
+int udevdb_add_dev(struct udevice *udev)
 {
        TDB_DATA key, data;
        char keystr[SYSFS_PATH_MAX];
@@ -52,22 +52,19 @@ int udevdb_add_dev(const char *path, const struct udevice *dev)
        if (udevdb == NULL)
                return -1;
 
-       if ((path == NULL) || (dev == NULL))
-               return -ENODEV;
-
-       memset(keystr, 0, SYSFS_PATH_MAX);
-       strfieldcpy(keystr, path);
+       memset(keystr, 0x00, SYSFS_PATH_MAX);
+       strfieldcpy(keystr, udev->devpath);
        key.dptr = keystr;
        key.dsize = strlen(keystr) + 1;
 
-       data.dptr = (void *)dev;
-       data.dsize = UDEVICE_LEN;
-       dbg("store key '%s' for device '%s'", path, dev->name);
+       data.dptr = (void *) udev;
+       data.dsize = UDEVICE_DB_LEN;
+       dbg("store key '%s' for device '%s'", keystr, udev->name);
 
        return tdb_store(udevdb, key, data, TDB_REPLACE); 
 }
 
-int udevdb_get_dev(const char *path, struct udevice *dev)
+int udevdb_get_dev(const char *path, struct udevice *udev)
 {
        TDB_DATA key, data;
 
@@ -84,8 +81,9 @@ int udevdb_get_dev(const char *path, struct udevice *dev)
        if (data.dptr == NULL || data.dsize == 0)
                return -ENODEV;
 
-       memset(dev, 0, sizeof(struct udevice));
-       memcpy(dev, data.dptr, UDEVICE_LEN);
+       memset(udev, 0x00, sizeof(struct udevice));
+       memcpy(udev, data.dptr, UDEVICE_DB_LEN);
+
        return 0;
 }
 
@@ -156,7 +154,7 @@ int udevdb_open_ro(void)
        return 0;
 }
 
-static int (*user_record_callback) (char *path, struct udevice *dev);
+static int (*user_record_callback) (const char *path, struct udevice *dev);
 
 static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
 {
@@ -167,7 +165,7 @@ static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void
  * udevdb_call_foreach: dumps whole database by passing record data to user function
  * @user_record_handler: user function called for every record in the database
  */
-int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev))
+int udevdb_call_foreach(int (*user_record_handler) (const char *path, struct udevice *dev))
 {
        int retval = 0;
 
@@ -191,27 +189,27 @@ static char *find_path;
 static const char *find_name;
 static int find_found;
 
-static int find_device_by_name(char *path, struct udevice *dev)
+static int find_device_by_name(const char *path, struct udevice *udev)
 {
        char *pos;
        int len;
 
-       if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) {
-               memcpy(find_dev, dev, sizeof(struct udevice));
+       if (strncmp(udev->name, find_name, sizeof(udev->name)) == 0) {
+               memcpy(find_dev, udev, sizeof(struct udevice));
                strfieldcpymax(find_path, path, NAME_SIZE);
                find_found = 1;
                /* stop search */
                return 1;
        }
        /* look for matching symlink*/
-       foreach_strpart(dev->symlink, " ", pos, len) {
+       foreach_strpart(udev->symlink, " ", pos, len) {
                if (strncmp(pos, find_name, len) != 0)
                        continue;
 
                if (len != strlen(find_name))
                        continue;
 
-               memcpy(find_dev, dev, sizeof(struct udevice));
+               memcpy(find_dev, udev, sizeof(struct udevice));
                strfieldcpymax(find_path, path, NAME_SIZE);
                find_found = 1;
                return 1;
index 6eaeb25668f6a17a92e57ba6c234e3a8fb39a4db..6986a0a1136ef66bb26604d4fbf58bd4839e399d 100644 (file)
--- a/udevdb.h
+++ b/udevdb.h
@@ -12,9 +12,9 @@
 extern void udevdb_exit(void);
 extern int udevdb_init(int init_flag);
 extern int udevdb_open_ro(void);
-extern int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev));
+extern int udevdb_call_foreach(int (*user_record_handler) (const char *path, struct udevice *dev));
 
-extern int udevdb_add_dev(const char *path, const struct udevice *dev);
+extern int udevdb_add_dev(struct udevice *dev);
 extern int udevdb_get_dev(const char *path, struct udevice *dev);
 extern int udevdb_delete_dev(const char *path);
 extern int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev);
index 763cfd139f76636286a9b76a8b41ec7ebca1a4d6..af2346c8f566e8e9fad54868a98ec0e2446cff28 100644 (file)
@@ -104,7 +104,7 @@ exit:
 }
 
 /* callback for database dump */
-static int print_record(char *path, struct udevice *dev)
+static int print_record(const char *path, struct udevice *dev)
 {
        printf("P: %s\n", path);
        printf("N: %s\n", dev->name);
index cabafb0abc76689064131e41d87ebdcb90276d19..c4ec0f7b7abd132399d7fc77f73e2f46d5db7c20 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "libsysfs/sysfs/libsysfs.h"
 #include "logging.h"
 #include "udev_lib.h"
 #include "list.h"
@@ -86,19 +87,32 @@ static char *first_list[] = {
        NULL,
 };
 
-static void add_device(char *path, char *subsys, int fake)
+static int add_device(char *devpath, char *subsystem)
 {
+       struct udevice udev;
+       char path[SYSFS_PATH_MAX];
+       struct sysfs_class_device *class_dev;
        char *argv[3];
 
        /* fake argument vector and environment for callouts and dev.d/ */
        argv[0] = "udev";
-       argv[1] = subsys;
+       argv[1] = subsystem;
        argv[2] = NULL;
 
        main_argv = argv;
-       setenv("DEVPATH", path, 1);
+       setenv("DEVPATH", devpath, 1);
        setenv("ACTION", "add", 1);
-       udev_add_device(path, subsys, fake);
+
+       snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath);
+       class_dev = sysfs_open_class_device_path(path);
+       if (class_dev == NULL) {
+               dbg ("sysfs_open_class_device_path failed");
+               return -ENODEV;
+       }
+
+       udev_set_values(&udev, devpath, subsystem);
+
+       return udev_add_device(&udev, class_dev);
 }
 
 static void exec_list(struct list_head *device_list)
@@ -111,7 +125,7 @@ static void exec_list(struct list_head *device_list)
        list_for_each_entry_safe(loop_device, tmp_device, device_list, list) {
                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, NOFAKE);
+                               add_device(loop_device->path, loop_device->subsys);
                                list_del(&loop_device->list);
                                free(loop_device);
                                break;
@@ -131,14 +145,14 @@ static void exec_list(struct list_head *device_list)
                if (found)
                        continue;
 
-               add_device(loop_device->path, loop_device->subsys, NOFAKE);
+               add_device(loop_device->path, loop_device->subsys);
                list_del(&loop_device->list);
                free(loop_device);
        }
 
        /* handle the rest of the devices left over, if any */
        list_for_each_entry_safe(loop_device, tmp_device, device_list, list) {
-               add_device(loop_device->path, loop_device->subsys, NOFAKE);
+               add_device(loop_device->path, loop_device->subsys);
                list_del(&loop_device->list);
                free(loop_device);
        }
index df882d2d8cde6858c8f93f1c3b366bc0b7dbe636..fa1629af2552197023f35b5facb51613082b4a37 100644 (file)
@@ -55,9 +55,12 @@ void log_message (int level, const char *format, ...)
 
 int main(int argc, char *argv[], char *envp[])
 {
+       struct sysfs_class_device *class_dev;
        char *devpath;
+       char path[SYSFS_PATH_MAX];
        char temp[NAME_SIZE];
        char *subsystem = "";
+       struct udevice udev;
 
        main_argv = argv;
        main_envp = envp;
@@ -88,9 +91,8 @@ int main(int argc, char *argv[], char *envp[])
        info("looking at '%s'", devpath);
 
        /* we only care about class devices and block stuff */
-       if (!strstr(devpath, "class") &&
-           !strstr(devpath, "block")) {
-               info("not a block or class device");
+       if (!strstr(devpath, "class") && !strstr(devpath, "block")) {
+               dbg("not a block or class device");
                goto exit;
        }
 
@@ -100,8 +102,20 @@ int main(int argc, char *argv[], char *envp[])
        if (argv[2] != NULL)
                subsystem = argv[2];
 
+       /* fill in values and test_run flag*/
+       udev_set_values(&udev, devpath, subsystem);
+       udev.test_run = 1;
+
+       /* open the device */
+       snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath);
+       class_dev = sysfs_open_class_device_path(path);
+       if (class_dev == NULL)
+               dbg ("sysfs_open_class_device_path failed");
+       else
+               dbg("opened class_dev->name='%s'", class_dev->name);
+
        /* simulate node creation with fake flag */
-       udev_add_device(devpath, subsystem, FAKE);
+       udev_add_device(&udev, class_dev);
 
 exit:
        return 0;