chiark / gitweb /
udevtest: add --force mode
authorKay Sievers <kay.sievers@vrfy.org>
Wed, 21 Mar 2007 10:55:26 +0000 (11:55 +0100)
committerKay Sievers <kay.sievers@vrfy.org>
Wed, 21 Mar 2007 10:55:26 +0000 (11:55 +0100)
udev_db.c
udev_device.c
udev_node.c
udevtest.c

index 83d3f9bbf8238d9dbd985c86975d007c8dbc5b22..00d68d6d13f125badb08b8a78eca4de802ee309e 100644 (file)
--- a/udev_db.c
+++ b/udev_db.c
@@ -286,6 +286,9 @@ int udev_db_delete_device(struct udevice *udev)
        char filename[PATH_SIZE];
        struct name_entry *name_loop;
 
+       if (udev->test_run)
+               return 0;
+
        devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
        unlink(filename);
 
index 03514e1d48bbc0c2ed2ff05816d9628a622ac1ec..d50c5ae043ee237ec44168d19814469f9bb27c0b 100644 (file)
@@ -164,6 +164,7 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev)
                /* read current database entry; cleanup, if it is known device */
                udev_old = udev_device_init(NULL);
                if (udev_old != NULL) {
+                       udev_old->test_run = udev->test_run;
                        if (udev_db_get_device(udev_old, udev->dev->devpath) == 0) {
                                info("device '%s' already in database, cleanup", udev->dev->devpath);
                                udev_db_delete_device(udev_old);
index f30ae876ecd5779ecdd6f86484f3ed3b5dabbdc5..b1bbda8369c3e264e86b583015d122e1299f96fe 100644 (file)
@@ -153,7 +153,7 @@ static int update_link(struct udevice *udev, const char *name)
        count = udev_db_get_devices_by_name(name, &name_list);
        info("found %i devices with name '%s'", count, name);
 
-       /* if we don't have any reference, we can delete the link */
+       /* if we don't have a reference, delete it */
        if (count <= 0) {
                info("no reference left, remove '%s'", name);
                if (!udev->test_run) {
@@ -236,11 +236,10 @@ void udev_node_update_symlinks(struct udevice *udev, struct udevice *udev_old)
        if (udev_old != NULL) {
                struct name_entry *link_loop;
                struct name_entry *link_old_loop;
-               struct name_entry *link_old_tmp_loop;
                int found;
 
                /* remove current symlinks from old list */
-               list_for_each_entry_safe(link_old_loop, link_old_tmp_loop, &udev_old->symlink_list, node) {
+               list_for_each_entry(link_old_loop, &udev_old->symlink_list, node) {
                        found = 0;
                        list_for_each_entry(link_loop, &udev->symlink_list, node) {
                                if (strcmp(link_old_loop->name, link_loop->name) == 0) {
@@ -256,8 +255,12 @@ void udev_node_update_symlinks(struct udevice *udev, struct udevice *udev_old)
                        }
                }
 
-               /* the old node is gone, maybe we have a device with a symlink now */
-               update_link(udev, udev_old->name);
+               /*
+                * if the node name has changed, delete the node,
+                * or possibly restore a symlink of another device
+                */
+               if (strcmp(udev->name, udev_old->name) != 0)
+                       update_link(udev, udev_old->name);
        }
 }
 
@@ -345,7 +348,7 @@ int udev_node_remove(struct udevice *udev)
        char filename[PATH_SIZE];
        char partitionname[PATH_SIZE];
        struct stat stats;
-       int retval;
+       int retval = 0;
        int num;
 
        strlcpy(filename, udev_root, sizeof(filename));
@@ -361,7 +364,8 @@ int udev_node_remove(struct udevice *udev)
        }
 
        info("removing device node '%s'", filename);
-       retval = unlink_secure(filename);
+       if (!udev->test_run)
+               retval = unlink_secure(filename);
        if (retval)
                return retval;
 
@@ -376,7 +380,8 @@ int udev_node_remove(struct udevice *udev)
                for (i = 1; i <= num; i++) {
                        snprintf(partitionname, sizeof(partitionname), "%s%d", filename, i);
                        partitionname[sizeof(partitionname)-1] = '\0';
-                       unlink_secure(partitionname);
+                       if (!udev->test_run)
+                               unlink_secure(partitionname);
                }
        }
        delete_path(filename);
index bb889a70fde8eb6b0071c14903aabd2ce48e3eca..8c56dba0f1c7d3cc9e7adb5ed534fff13af244e2 100644 (file)
@@ -26,6 +26,7 @@
 #include <ctype.h>
 #include <signal.h>
 #include <syslog.h>
+#include <getopt.h>
 
 #include "udev.h"
 #include "udev_rules.h"
@@ -49,14 +50,22 @@ void log_message (int priority, const char *format, ...)
 
 int main(int argc, char *argv[], char *envp[])
 {
+       int force = 0;
+       char *action = "add";
        struct udev_rules rules = {};
        char *devpath = NULL;
        struct udevice *udev;
        struct sysfs_device *dev;
-       int i;
        int retval;
        int rc = 0;
 
+       static const struct option options[] = {
+               { "action", 1, NULL, 'a' },
+               { "force", 0, NULL, 'f' },
+               { "help", 0, NULL, 'h' },
+               {}
+       };
+
        info("version %s", UDEV_VERSION);
        udev_config_init();
        if (udev_log_priority < LOG_INFO) {
@@ -67,15 +76,32 @@ int main(int argc, char *argv[], char *envp[])
                setenv("UDEV_LOG", priority, 1);
        }
 
-       for (i = 1 ; i < argc; i++) {
-               char *arg = argv[i];
-
-               if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
-                       printf("Usage: udevtest [--help] <devpath>\n");
-                       goto exit;
-               } else
-                       devpath = arg;
+       while (1) {
+               int option;
+
+               option = getopt_long(argc, argv, "a:fh", options, NULL);
+               if (option == -1)
+                       break;
+
+               dbg("option '%c'", option);
+               switch (option) {
+               case 'a':
+                       action = optarg;
+                       break;
+               case 'f':
+                       force = 1;
+                       break;
+               case 'h':
+                       printf("Usage: udevtest [--action=<string>] [--force] [--help] <devpath>\n"
+                              "  --action=<string>   set action string\n"
+                              "  --force             don't skip node/link creation\n"
+                              "  --help              print this help text\n\n");
+                       exit(0);
+               default:
+                       exit(1);
+               }
        }
+       devpath = argv[optind];
 
        if (devpath == NULL) {
                fprintf(stderr, "devpath parameter missing\n");
@@ -106,19 +132,20 @@ int main(int argc, char *argv[], char *envp[])
 
        /* override built-in sysfs device */
        udev->dev = dev;
-       strcpy(udev->action, "add");
+       strcpy(udev->action, action);
        udev->devt = udev_device_get_devt(udev);
 
        /* simulate node creation with test flag */
-       udev->test_run = 1;
+       if (!force)
+               udev->test_run = 1;
 
        setenv("DEVPATH", udev->dev->devpath, 1);
        setenv("SUBSYSTEM", udev->dev->subsystem, 1);
        setenv("ACTION", "add", 1);
 
-       printf("This program is for debugging only, it does not create any node,\n"
-              "or run any program specified by a RUN key. It may show incorrect results,\n"
-              "if rules match against subsystem specfic kernel event variables.\n"
+       printf("This program is for debugging only, it does not run any program,\n"
+              "specified by a RUN key. It may show incorrect results, if rules\n"
+              "match against subsystem specfic kernel event variables.\n"
               "\n");
 
        info("looking at device '%s' from subsystem '%s'", udev->dev->devpath, udev->dev->subsystem);