chiark / gitweb /
Merge gregkh@ehlo.org:/home/kay/public_html/pub/scm/linux/hotplug/udev-kay
authorGreg KH <greg@press.(none)>
Thu, 14 Jul 2005 21:13:34 +0000 (14:13 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 14 Jul 2005 21:13:34 +0000 (14:13 -0700)
19 files changed:
docs/writing_udev_rules/index.html
etc/udev/redhat/udev.rules
extras/ata_id/ata_id.c
extras/dasd_id/Makefile [new file with mode: 0644]
extras/dasd_id/dasd_id.c [moved from extras/volume_id/volume_id/dasd.c with 72% similarity]
extras/scsi_id/scsi_id.c
extras/scsi_id/scsi_serial.c
extras/usb_id/usb_id.c
extras/volume_id/README
extras/volume_id/vol_id.c
extras/volume_id/volume_id/Makefile.inc
extras/volume_id/volume_id/dasd.h [deleted file]
extras/volume_id/volume_id/volume_id.h
test/simple-build-check.sh
test/udev-test.pl
udev_rules.c
udev_rules.h
udev_rules_parse.c
udevd.c

index 1ba43678c0ecf08e851ba329dec14a66aa938160..c2ccdc3663f1878a1bbc5fe9bbf8295904057f2e 100644 (file)
@@ -321,7 +321,7 @@ Building on the style mentioned above, you can do even more flashy things. The u
 
 This prevents the need to excessively provide a <i>GROUP="audio"</i> key on every following rule which names sound devices.<br /><br />
 
-udev defaults to creating nodes with unix permissions of 0660 (read/write to owner and group), which is configured by the <b>default_mode</b> setting inside <i>/etc/udev/udev.conf</i>. There may be some situations where you do not want to use the default permissions on your device node. Fortunately, you can easily override the permissions in your rules using the <i>MODE</i> assignment key. As an example, the following rule defines that the inotify node shall be readable and writable to everyone:
+udev defaults to creating nodes with unix permissions of 0660 (read/write to owner and group). There may be some situations where you do not want to use the default permissions on your device node. Fortunately, you can easily override the permissions in your rules using the <i>MODE</i> assignment key. As an example, the following rule defines that the inotify node shall be readable and writable to everyone:
 
 <blockquote><pre>KERNEL="inotify", NAME="misc/%k", SYMLINK="%k", MODE="0666"</pre></blockquote>
 
index 2d4819f8c36ae6eeb37e8e16da6ae0ab6bf074f5..5bed78228091bcf4086fd8e1d16376d84133a0f3 100644 (file)
@@ -1,7 +1,7 @@
 # There are a number of modifiers that are allowed to be used in some of the
 # fields.  See the udev man page for a full description of them.
 #
-# default is OWNER="root" GROUP="root", MODE="0600"
+# default is OWNER="root" GROUP="root", MODE="0660"
 #
 
 # all block devices
index 34b1ccdff1203be22f444626ef9ad63879fab7a4..9df0fdb10763107a78d38a742fc1ad6aeec600ce 100644 (file)
@@ -107,6 +107,8 @@ int main(int argc, char *argv[])
        int fd;
        int rc = 0;
 
+       logging_init("ata_id");
+
        for (i = 1 ; i < argc; i++) {
                char *arg = argv[i];
 
@@ -167,8 +169,12 @@ int main(int argc, char *argv[])
                printf("ID_MODEL=%s\n", model);
                printf("ID_SERIAL=%s\n", serial);
                printf("ID_REVISION=%s\n", revision);
-       } else
-               printf("%s_%s\n", model, serial);
+       } else {
+               if (serial[0] != '\0')
+                       printf("%s_%s\n", model, serial);
+               else
+                       printf("%s\n", model);
+       }
 
 close:
        close(fd);
diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile
new file mode 100644 (file)
index 0000000..33bb696
--- /dev/null
@@ -0,0 +1,52 @@
+# Makefile for dasd_id
+#
+# Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+#
+# 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; version 2 of the License.
+#
+
+PROG = dasd_id
+
+all:   $(PROG)
+
+prefix =
+exec_prefix =  ${prefix}
+etcdir =       ${prefix}/etc
+sbindir =      ${exec_prefix}/sbin
+usrbindir =    ${exec_prefix}/usr/bin
+usrsbindir =   ${exec_prefix}/usr/sbin
+mandir =       ${prefix}/usr/share/man
+devddir =      ${etcdir}/dev.d/default
+configdir =    ${etcdir}/udev/
+initdir =      ${etcdir}/init.d/
+srcdir = .
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+CFLAGS+=-D_FILE_OFFSET_BITS=64
+
+OBJS = dasd_id.o ../../udev.a
+
+$(OBJS): $(HEADERS)
+
+.c.o:
+       $(QUIET) $(CC) $(CFLAGS) -c -o $@ $<
+
+$(PROG): $(OBJS) $(HEADERS)
+       $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS)
+
+clean:
+       rm -f $(PROG) $(OBJS)
+
+spotless: clean
+
+install: all
+       $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+
+uninstall:
+       - rm $(DESTDIR)$(sbindir)/$(PROG)
similarity index 72%
rename from extras/volume_id/volume_id/dasd.c
rename to extras/dasd_id/dasd_id.c
index 6f403cb9283d66c9c2e30961d9fe919fdf0a7b58..5c2143f45d5c3a98c44822051e48aca6137e01a3 100644 (file)
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <errno.h>
 #include <sys/ioctl.h>
 #include <asm/types.h>
 
-#include "volume_id.h"
-#include "logging.h"
-#include "util.h"
-#include "dasd.h"
+#include "../../logging.h"
+#include "../../udev_utils.h"
+
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
+{
+       va_list args;
+       static int udev_log = -1;
+
+       if (udev_log == -1) {
+               const char *value;
+
+               value = getenv("UDEV_LOG");
+               if (value)
+                       udev_log = log_priority(value);
+               else
+                       udev_log = LOG_ERR;
+       }
+
+       if (priority > udev_log)
+               return;
+
+       va_start(args, format);
+       vsyslog(priority, format, args);
+       va_end(args);
+}
+#endif
+
+/*
+ * Only compile this on S/390. Doesn't make any sense
+ * for other architectures.
+ */
 
 static unsigned char EBCtoASC[256] =
 {
@@ -55,7 +84,7 @@ static unsigned char EBCtoASC[256] =
                                 -INP                   */
        0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
 /* 0x28  -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                     -SW                               */ 
+                     -SW                               */
        0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
 /* 0x30 ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
        0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
@@ -71,7 +100,7 @@ static unsigned char EBCtoASC[256] =
        0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
 /* 0x60    -     /  ----     Ä  ----  ----  ----       */
        0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
-/* 0x68             ----     ,     %     _     >     ? */ 
+/* 0x68             ----     ,     %     _     >     ? */
        0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
 /* 0x70  ---        ----  ----  ----  ----  ----  ---- */
        0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
@@ -111,15 +140,15 @@ static unsigned char EBCtoASC[256] =
        0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
 };
 
-static void vtoc_ebcdic_dec (const unsigned char *source, unsigned char *target, int l) 
+static void vtoc_ebcdic_dec (const unsigned char *source, char *target, int l) 
 {
        int i;
 
        for (i = 0; i < l; i++) 
-               target[i]=EBCtoASC[(unsigned char)(source[i])];
+               target[i]=(char)EBCtoASC[(unsigned char)(source[i])];
 }
 
-/* 
+/*
  * struct dasd_information_t
  * represents any data about the data, which is visible to userspace
  */
@@ -144,54 +173,101 @@ typedef struct dasd_information_t {
        char configuration_data[256];   /* from read_configuration_data */
 } dasd_information_t;
 
-#define _IOC_NRBITS            8
-#define _IOC_TYPEBITS          8
-#define _IOC_SIZEBITS          14
-#define _IOC_DIRBITS           2
-#define _IOC_NRMASK            ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK          ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK          ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK           ((1 << _IOC_DIRBITS)-1)
-#define _IOC_NRSHIFT           0
-#define _IOC_TYPESHIFT         (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT         (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT          (_IOC_SIZESHIFT+_IOC_SIZEBITS)
 #define DASD_IOCTL_LETTER       'D'
-
 #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t)
 #define BLKSSZGET _IO(0x12,104)
 
-int volume_id_probe_dasd(struct volume_id *id)
+unsigned char serial[8];
+
+static int dasd_id(int fd)
 {
        int blocksize;
        dasd_information_t info;
        __u8 *data;
        __u8 *label_raw;
-       unsigned char name[7];
-
-       dbg("probing");
 
-       if (ioctl(id->fd, BIODASDINFO, &info) != 0)
+       if (ioctl(fd, BIODASDINFO, &info) != 0) {
+               dbg("not a dasd");
                return -1;
+       }
 
-       if (ioctl(id->fd, BLKSSZGET, &blocksize) != 0)
-               return -1;
+               if (ioctl(fd, BLKSSZGET, &blocksize) != 0) {
+                       err("failed to get blocksize");
+                       return -1;
+               }
 
-       data = volume_id_get_buffer(id, info.label_block * blocksize, 16);
-       if (data == NULL)
-               return -1;
+               if (lseek(fd,info.label_block * blocksize, SEEK_SET) == -1) {
+                       err("seek failed on dasd");
+                       return -1;
+               }
+
+               data = malloc(blocksize);
+               if (data == NULL)
+                       return -1;
+
+               if (read(fd, data, blocksize) == -1) {
+                       err("read disklabel failed");
+                       free(data);
+                       return -1;
+               }
 
-       if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD")))
-               label_raw = &data[8];
-       else
-               label_raw = &data[4];
+               if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD")))
+                       label_raw = &data[8];
+               else
+                       label_raw = &data[4];
+               serial[6] = '\0';
 
-       name[6] = '\0';
-       volume_id_set_usage(id, VOLUME_ID_DISKLABEL);
-       id->type = "dasd";
-       volume_id_set_label_raw(id, label_raw, 6);
-       vtoc_ebcdic_dec(label_raw, name, 6);
-       volume_id_set_label_string(id, name, 6);
+               vtoc_ebcdic_dec(label_raw, serial, 6);
+               free(data);
+
+               return 0;
+       }
+
+int main(int argc, char *argv[])
+{
+       const char *node = NULL;
+       int i;
+       int export = 0;
+       int fd;
+       int rc = 0;
 
-       return 0;
+       logging_init("dasd_id");
+
+       for (i = 1; i < argc; i++) {
+               char *arg = argv[i];
+
+               if (strcmp(arg, "--export") == 0) {
+                       export = 1;
+               } else
+                       node = arg;
+       }
+       if (!node) {
+               err("no node specified");
+               rc = 1;
+               goto exit;
+       }
+
+       fd = open(node, O_RDONLY);
+       if (fd < 0) {
+               err("unable to open '%s'", node);
+               rc = 1;
+               goto exit;
+       }
+
+       if (dasd_id(fd) < 0) {
+               err("dasd_id failed: %s", strerror(errno));
+               rc = 1;
+       }
+
+       if (export) {
+               printf("ID_TYPE=disk\n");
+               printf("ID_SERIAL=%s\n",serial);
+       } else
+               printf("%s\n", serial);
+
+       close(fd);
+exit:
+       logging_close();
+       return rc;
 }
+
index 4003ee6af5a66dcaf436cf06a7097eb144856240..cbefb445dffe1cbbf3992b9be814aeba522e9136 100644 (file)
@@ -52,7 +52,7 @@
  * options are not supported, but other code is still left in place for
  * now.
  */
-static const char short_options[] = "bd:f:gip:s:uvVx";
+static const char short_options[] = "abd:f:gip:s:uvVx";
 /*
  * Just duplicate per dev options.
  */
@@ -61,6 +61,7 @@ static const char dev_short_options[] = "bgp:";
 char sysfs_mnt_path[SYSFS_PATH_MAX];
 
 static int all_good;
+static int always_info;
 static char *default_callout;
 static int dev_specified;
 static int sys_specified;
@@ -485,6 +486,9 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        dprintf("option '%c'\n", option);
 
                switch (option) {
+               case 'a':
+                       always_info = 1;
+                       break;
                case 'b':
                        all_good = 0;
                        break;
@@ -810,7 +814,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev)
                retval = 1;
        } else if (scsi_get_serial(scsi_dev, maj_min_dev, page_code,
                                   serial, MAX_SERIAL_LEN)) {
-               retval = 1;
+               retval = always_info?0:1;
        } else {
                retval = 0;
        }
index 20a7928553eb6a0d14c8b363962820eacfd2a5bd..7bfa9d18128c5b7223e5a0e36561b5970b613ddd 100644 (file)
@@ -89,6 +89,7 @@ static const char hex_str[]="0123456789abcdef";
 #define SG_ERR_CAT_RESET       2      /* interpreted from sense buffer */
 #define SG_ERR_CAT_TIMEOUT     3
 #define SG_ERR_CAT_RECOVERED   4  /* Successful command after recovered err */
+#define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */
 #define SG_ERR_CAT_SENSE       98     /* Something else in the sense buffer */
 #define SG_ERR_CAT_OTHER       99     /* Some other error/warning */
 
@@ -130,6 +131,8 @@ static int sg_err_category_new(int scsi_status, int msg_status, int
                                        return SG_ERR_CAT_MEDIA_CHANGED;
                                if (0x29 == asc)
                                        return SG_ERR_CAT_RESET;
+                       } else if (sense_key == ILLEGAL_REQUEST) {
+                               return SG_ERR_CAT_NOTSUPPORTED;
                        }
                }
                return SG_ERR_CAT_SENSE;
@@ -331,6 +334,9 @@ resend:
        retval = sg_err_category3(&io_hdr);
 
        switch (retval) {
+               case SG_ERR_CAT_NOTSUPPORTED:
+                       buf[1] = 0;
+                       /* Fallthrough */
                case SG_ERR_CAT_CLEAN:
                case SG_ERR_CAT_RECOVERED:
                        retval = 0;
index bca80f8de10b332a1da62e3eead06819a1062871..f4011ee8992b06dec55ed707d9d2a9fdc44976a2 100644 (file)
@@ -72,7 +72,9 @@ static char revision_str[16];
 static char type_str[16];
 
 static int use_usb_info;
+static int use_num_info;
 static int export;
+static int debug;
 
 static void set_str(char *to, const unsigned char *from, int count)
 {
@@ -259,7 +261,7 @@ static int usb_id(const char *target_path)
        struct sysfs_device *target_dev;
        struct sysfs_device *host_dev, *interface_dev, *usb_dev;
        struct sysfs_attribute *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev;
-       struct sysfs_attribute *usb_model, *usb_vendor, *usb_rev, *usb_serial;
+       struct sysfs_attribute *usb_model = NULL, *usb_vendor = NULL, *usb_rev, *usb_serial;
        struct sysfs_attribute *if_class, *if_subclass;
        int if_class_num;
        int protocol = 0;
@@ -322,11 +324,12 @@ static int usb_id(const char *target_path)
        if_class = sysfs_get_device_attr(interface_dev, "bInterfaceClass");
        if (!if_class) {
                info("%s: cannot get bInterfaceClass attribute", interface_dev->name);
-               return -1;
+               return 1;
        }
        if_class_num = strtoul(if_class->value, NULL, 16);
        if (if_class_num != 8) {
                set_usb_iftype(type_str, if_class->value, sizeof(type_str) - 1);
+               protocol = 0;
        } else {
                if_subclass = sysfs_get_device_attr(interface_dev, 
                                                    "bInterfaceSubClass");
@@ -338,29 +341,29 @@ static int usb_id(const char *target_path)
                /* Generic SPC-2 device */
                scsi_vendor = sysfs_get_device_attr(scsi_dev, "vendor");
                if (!scsi_vendor) {
-                       info("%s: cannot get vendor attribute", scsi_dev->name);
-                       return -1;
+                       info("%s: cannot get SCSI vendor attribute", scsi_dev->name);
+                       return 1;
                }
                set_str(vendor_str, scsi_vendor->value, sizeof(vendor_str)-1);
 
                scsi_model = sysfs_get_device_attr(scsi_dev, "model");
                if (!scsi_model) {
-                       info("%s: cannot get model attribute", scsi_dev->name);
-                       return -1;
+                       info("%s: cannot get SCSI model attribute", scsi_dev->name);
+                       return 1;
                }
                set_str(model_str, scsi_model->value, sizeof(model_str)-1);
 
                scsi_type = sysfs_get_device_attr(scsi_dev, "type");
                if (!scsi_type) {
-                       info("%s: cannot get type attribute", scsi_dev->name);
-                       return -1;
+                       info("%s: cannot get SCSI type attribute", scsi_dev->name);
+                       return 1;
                }
                set_scsi_type(type_str, scsi_type->value, sizeof(type_str)-1);
 
                scsi_rev = sysfs_get_device_attr(scsi_dev, "rev");
                if (!scsi_rev) {
-                       info("%s: cannot get type attribute", scsi_dev->name);
-                       return -1;
+                       info("%s: cannot get SCSI revision attribute", scsi_dev->name);
+                       return 1;
                }
                set_str(revision_str, scsi_rev->value, sizeof(revision_str)-1);
 
@@ -368,19 +371,29 @@ static int usb_id(const char *target_path)
 
        /* Fallback to USB vendor & device */
        if (vendor_str[0] == '\0') {
-               usb_vendor = sysfs_get_device_attr(usb_dev, "manufacturer");
+               if (!use_num_info)
+                       if (!(usb_vendor = sysfs_get_device_attr(usb_dev, "manufacturer")))
+                               dbg("No USB vendor string found, using idVendor");
+
                if (!usb_vendor) {
-                       dbg("No USB vendor string found, using idVendor");
-                       usb_vendor = sysfs_get_device_attr(usb_dev, "idVendor");
+                       if (!(usb_vendor = sysfs_get_device_attr(usb_dev, "idVendor"))) {
+                               dbg("No USB vendor information available\n");
+                               sprintf(vendor_str,"0000");
+                       }
                }
                set_str(vendor_str,usb_vendor->value, sizeof(vendor_str) - 1);
        }
        
        if (model_str[0] == '\0') {
-               usb_model = sysfs_get_device_attr(usb_dev, "product");
+               if (!use_num_info)
+                       if (!(usb_model = sysfs_get_device_attr(usb_dev, "product")))
+                               dbg("No USB model string found, using idProduct");
+               
                if (!usb_model) {
-                       dbg("No USB model string found, using idProduct");
-                       usb_model = sysfs_get_device_attr(usb_dev, "idProduct");
+                       if (!(usb_model = sysfs_get_device_attr(usb_dev, "idProduct"))) {
+                               dbg("No USB model information available\n");
+                               sprintf(model_str,"0000");
+                       }
                }
                set_str(model_str, usb_model->value, sizeof(model_str) - 1);
        }
@@ -417,13 +430,20 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       while ((option = getopt(argc, argv, "ux")) != -1 ) {
+       while ((option = getopt(argc, argv, "dnux")) != -1 ) {
                if (optarg)
                        dbg("option '%c' arg '%s'", option, optarg);
                else
                        dbg("option '%c'", option);
 
                switch (option) {
+               case 'd':
+                       debug = 1;
+                       break;
+               case 'n':
+                       use_num_info=1;
+                       use_usb_info=1;
+                       break;
                case 'u':
                        use_usb_info=1;
                        break;
@@ -432,7 +452,7 @@ int main(int argc, char **argv)
                        break;
                default:
                        info("Unknown or bad option '%c' (0x%x)", option, option);
-                       retval = -1;
+                       retval = 1;
                        break;
                }
        }
@@ -452,25 +472,27 @@ int main(int argc, char **argv)
 
        retval = usb_id(target_path);
 
-       if (export) {
-               printf("ID_VENDOR=%s\n", vendor_str);
-               printf("ID_MODEL=%s\n", model_str);
-               printf("ID_REVISION=%s\n", revision_str);
-               if (serial_str[0] == '\0') {
-                       printf("ID_SERIAL=%s_%s\n", 
-                              vendor_str, model_str);
-               } else {
-                       printf("ID_SERIAL=%s_%s_%s\n", 
-                              vendor_str, model_str, serial_str);
-               }
-               printf("ID_TYPE=%s\n", type_str);
-       } else {
-               if (serial_str[0] == '\0') {
-                       printf("%s_%s\n", 
-                              vendor_str, model_str);
+       if (retval == 0) {
+               if (export) {
+                       printf("ID_VENDOR=%s\n", vendor_str);
+                       printf("ID_MODEL=%s\n", model_str);
+                       printf("ID_REVISION=%s\n", revision_str);
+                       if (serial_str[0] == '\0') {
+                               printf("ID_SERIAL=%s_%s\n", 
+                                      vendor_str, model_str);
+                       } else {
+                               printf("ID_SERIAL=%s_%s_%s\n", 
+                                      vendor_str, model_str, serial_str);
+                       }
+                       printf("ID_TYPE=%s\n", type_str);
                } else {
-                       printf("%s_%s_%s\n", 
-                              vendor_str, model_str, serial_str);
+                       if (serial_str[0] == '\0') {
+                               printf("%s_%s\n", 
+                                      vendor_str, model_str);
+                       } else {
+                               printf("%s_%s_%s\n", 
+                                      vendor_str, model_str, serial_str);
+                       }
                }
        }
        exit(retval);
index a7635ff612f3cc385f6ae41ea3a72eb516b5e189..974a5016d9e1f5cdafd781cf3c08eb722d325337 100644 (file)
@@ -37,7 +37,6 @@ luks                   *      -      *     -
 hpfs                   *      -      -     -
 romfs                  *
 minix                  *
-dasd                   *
 highpoint              *
 isw_raid               *
 lsi_raid               *
index 451fd355c1ad10cbe5714fadfcce14ee55818ea5..a4a866cfcf6d040e952fd6c0bc6ab8d77ba6fe09 100644 (file)
@@ -32,7 +32,6 @@
 #include "../../udev_utils.h"
 #include "../../logging.h"
 #include "volume_id/volume_id.h"
-#include "volume_id/dasd.h"
 
 #define BLKGETSIZE64 _IOR(0x12,114,size_t)
 
@@ -136,7 +135,7 @@ int main(int argc, char *argv[])
 
        vid = volume_id_open_node(node);
        if (vid == NULL) {
-               fprintf(stderr, "error open volume\n");
+               fprintf(stderr, "%s: error open volume\n", node);
                rc = 2;
                goto exit;
        }
@@ -147,10 +146,8 @@ int main(int argc, char *argv[])
        if (volume_id_probe_all(vid, 0, size) == 0)
                goto print;
 
-       if (volume_id_probe_dasd(vid) == 0)
-               goto print;
-
-       fprintf(stderr, "unknown volume type\n");
+       if (print != PRINT_EXPORT)
+               fprintf(stderr, "%s: unknown volume type\n", node);
        rc = 3;
        goto exit;
 
index acd26ff101a68b39b57c6121fd6616dcc9a70e0f..266d1e4872617fd5b86845c0106732d35d9fbd2e 100644 (file)
@@ -26,7 +26,6 @@ VOLUME_ID_OBJS=                                       \
        $(VOLUME_ID_BASE)/romfs.o               \
        $(VOLUME_ID_BASE)/sysv.o                \
        $(VOLUME_ID_BASE)/minix.o               \
-       $(VOLUME_ID_BASE)/dasd.o                \
        $(VOLUME_ID_BASE)/luks.o                \
        $(VOLUME_ID_BASE)/volume_id.o           \
        $(VOLUME_ID_BASE)/util.o
@@ -58,7 +57,6 @@ VOLUME_ID_HEADERS=                            \
        $(VOLUME_ID_BASE)/romfs.h               \
        $(VOLUME_ID_BASE)/sysv.h                \
        $(VOLUME_ID_BASE)/minix.h               \
-       $(VOLUME_ID_BASE)/dasd.h                \
        $(VOLUME_ID_BASE)/luks.h                \
        $(VOLUME_ID_BASE)/volume_id.h           \
        $(VOLUME_ID_BASE)/util.h
diff --git a/extras/volume_id/volume_id/dasd.h b/extras/volume_id/volume_id/dasd.h
deleted file mode 100644 (file)
index 751b9fd..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * dasdlabel - read label from s390 block device
- *
- * Copyright (C) 2004 Arnd Bergmann <arnd@arndb.de>
- *
- *     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 version 2 of the License.
- * 
- *     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, write to the Free Software Foundation, Inc.,
- *     675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef _VOLUME_ID_DASDLABEL_
-#define _VOLUME_ID_DASDLABEL_
-
-extern int volume_id_probe_dasd(struct volume_id *id);
-
-#endif
index 2266694f5e292833378f632dd07cea5b5f4aba84..c6aef508760a50fd8b7e19dc5f497d91d769b178 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef _VOLUME_ID_H_
 #define _VOLUME_ID_H_
 
-#define VOLUME_ID_VERSION              44
+#define VOLUME_ID_VERSION              45
 
 #define VOLUME_ID_LABEL_SIZE           64
 #define VOLUME_ID_UUID_SIZE            36
index c5b429d98d67340abc74fca078227e3f6ffc000b..7e9a940f859c1f706e3f4e1f807da81162e8fa8c 100755 (executable)
@@ -6,6 +6,7 @@ EXTRAS="\
        extras/ata_id \
        extras/volume_id \
        extras/usb_id \
+       extras/dasd_id \
        extras/run_directory"
 
 [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build
index 873780d70af521552850c7eeae893026a5546914..1bb60bb76e522f57929bf0b818885afbdbb48cb4 100755 (executable)
@@ -1450,6 +1450,48 @@ EOF
 KERNEL=="ttyUSB[0-9]*", NAME="right"
 KERNEL=="ttyUSB[0-9]*", NAME=""
 KERNEL=="ttyUSB[0-9]*", NAME="wrong"
+EOF
+       },
+       {
+               desc            => "test multi matches",
+               subsys          => "tty",
+               devpath         => "/class/tty/ttyUSB0",
+               exp_name        => "right",
+               rules           => <<EOF
+KERNEL=="ttyUSB*|nothing", NAME="right"
+KERNEL=="ttyUSB*", NAME="wrong"
+EOF
+       },
+       {
+               desc            => "test multi matches 2",
+               subsys          => "tty",
+               devpath         => "/class/tty/ttyUSB0",
+               exp_name        => "right",
+               rules           => <<EOF
+KERNEL=="dontknow*|*nothing", NAME="nomatch"
+KERNEL=="dontknow*|ttyUSB*|nothing*", NAME="right"
+KERNEL=="ttyUSB*", NAME="wrong"
+EOF
+       },
+       {
+               desc            => "IMPORT parent test sequence 1/2 (keep)",
+               subsys          => "block",
+               devpath         => "/block/sda",
+               exp_name        => "parent",
+               option          => "keep",
+               rules           => <<EOF
+KERNEL=="sda", IMPORT="/bin/echo -e \'PARENT_KEY=parent_right\\nWRONG_PARENT_KEY=parent_wrong'"
+KERNEL=="sda", NAME="parent"
+EOF
+       },
+       {
+               desc            => "IMPORT parent test sequence 2/2 (keep)",
+               subsys          => "block",
+               devpath         => "/block/sda/sda1",
+               exp_name        => "parentenv-parent_right",
+               option          => "clean",
+               rules           => <<EOF
+KERNEL=="sda1", IMPORT{parent}="PARENT*", NAME="parentenv-\$env{PARENT_KEY}\$env{WRONG_PARENT_KEY}"
 EOF
        },
 );
index a25c2e90a8bc196b6f3a44a219b339a01505c74b..5669a8593ede14c05c1449ebcbe66086cc01bc91 100644 (file)
@@ -281,6 +281,46 @@ static int import_program_into_env(struct udevice *udev, const char *program)
        return import_keys_into_env(udev, result, reslen);
 }
 
+static int import_parent_into_env(struct udevice *udev, struct sysfs_class_device *class_dev, const char *filter)
+{
+       struct sysfs_class_device *parent = sysfs_get_classdev_parent(class_dev);
+       int rc = -1;
+
+       if (parent != NULL) {
+               struct udevice udev_parent;
+               struct name_entry *name_loop;
+
+               dbg("found parent '%s', get the node name", parent->path);
+               udev_init_device(&udev_parent, NULL, NULL, NULL);
+               /* import the udev_db of the parent */
+               if (udev_db_get_device(&udev_parent, &parent->path[strlen(sysfs_path)]) == 0) {
+                       dbg("import stored parent env '%s'", udev_parent.name);
+                       list_for_each_entry(name_loop, &udev_parent.env_list, node) {
+                               char name[NAME_SIZE];
+                               char *pos;
+
+                               strlcpy(name, name_loop->name, sizeof(name));
+                               pos = strchr(name, '=');
+                               if (pos) {
+                                       pos[0] = '\0';
+                                       pos++;
+                                       if (strcmp_pattern(filter, name) == 0) {
+                                               dbg("import key '%s'", name_loop->name);
+                                               name_list_add(&udev->env_list, name_loop->name, 0);
+                                               setenv(name, pos, 1);
+                                       } else
+                                               dbg("skip key '%s'", name_loop->name);
+                               }
+                       }
+                       rc = 0;
+               } else
+                       dbg("parent not found in database");
+               udev_cleanup_device(&udev_parent);
+       }
+
+       return rc;
+}
+
 /* finds the lowest positive N such that <name>N isn't present in the udevdb
  * if <name> doesn't exist, 0 is returned, N otherwise
  */
@@ -604,10 +644,12 @@ found:
                                break;
                        }
                        pos = getenv(attr);
-                       if (pos == NULL)
+                       if (pos == NULL) {
+                               dbg("env '%s' not avialable", attr);
                                break;
-                       strlcat(string, pos, maxsize);
+                       }
                        dbg("substitute env '%s=%s'", attr, pos);
+                       strlcat(string, pos, maxsize);
                        break;
                default:
                        err("unknown substitution type=%i", type);
@@ -635,25 +677,36 @@ static char *key_pair_name(struct udev_rule *rule, struct key_pair *pair)
 static int match_key(const char *key_name, struct udev_rule *rule, struct key *key, const char *val)
 {
        int match;
+       char value[PATH_SIZE];
        char *key_value;
+       char *pos;
 
        if (key->operation == KEY_OP_UNSET)
                return 0;
 
-       key_value = rule->buf + key->val_off;
+       strlcpy(value, rule->buf + key->val_off, sizeof(value));
+       key_value = value;
 
-       dbg("check for %s '%s' <-> '%s'", key_name, key_value, val);
-       match = (strcmp_pattern(key_value, val) == 0);
-       if (match && (key->operation != KEY_OP_NOMATCH)) {
-               dbg("%s is matching (matching value)", key_name);
-               return 0;
-       }
-       if (!match && (key->operation == KEY_OP_NOMATCH)) {
-               dbg("%s is matching, (non matching value)", key_name);
-               return 0;
+       dbg("key %s value='%s'", key_name, key_value);
+       while (key_value) {
+               pos = strchr(key_value, '|');
+               if (pos) {
+                       pos[0] = '\0';
+                       pos++;
+               }
+               dbg("match %s '%s' <-> '%s'", key_name, key_value, val);
+               match = (strcmp_pattern(key_value, val) == 0);
+               if (match && (key->operation != KEY_OP_NOMATCH)) {
+                       dbg("%s is true (matching value)", key_name);
+                       return 0;
+               }
+               if (!match && (key->operation == KEY_OP_NOMATCH)) {
+                       dbg("%s is true (non-matching value)", key_name);
+                       return 0;
+               }
+               key_value = pos;
        }
-
-       dbg("%s is not matching", key_name);
+       dbg("%s is false", key_name);
        return -1;
 }
 
@@ -709,14 +762,14 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
 
                match = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0);
                if (match && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) {
-                       dbg("WAIT_FOR_SYSFS is matching (matching value)");
+                       dbg("WAIT_FOR_SYSFS is true (matching value)");
                        return 0;
                }
                if (!match && (rule->wait_for_sysfs.operation == KEY_OP_NOMATCH)) {
-                       dbg("WAIT_FOR_SYSFS is matching, (non matching value)");
+                       dbg("WAIT_FOR_SYSFS is true, (non matching value)");
                        return 0;
                }
-               dbg("WAIT_FOR_SYSFS is not matching");
+               dbg("WAIT_FOR_SYSFS is false");
                return -1;
        }
 
@@ -801,12 +854,15 @@ try_parent:
                strlcpy(import, key_val(rule, &rule->import), sizeof(import));
                apply_format(udev, import, sizeof(import), class_dev, sysfs_device);
                dbg("check for IMPORT import='%s'", import);
-               if (rule->import_exec) {
+               if (rule->import_type == IMPORT_PROGRAM) {
                        dbg("run executable file import='%s'", import);
                        rc = import_program_into_env(udev, import);
-               } else {
+               } else if (rule->import_type == IMPORT_FILE) {
                        dbg("import file import='%s'", import);
                        rc = import_file_into_env(udev, import);
+               } else if (rule->import_type == IMPORT_PARENT && class_dev) {
+                       dbg("import parent import='%s'", import);
+                       rc = import_parent_into_env(udev, class_dev, import);
                }
                if (rc) {
                        dbg("IMPORT failed");
@@ -826,7 +882,7 @@ try_parent:
                apply_format(udev, program, sizeof(program), class_dev, sysfs_device);
                dbg("check for PROGRAM program='%s", program);
                if (execute_program(program, udev->subsystem, result, sizeof(result), NULL) != 0) {
-                       dbg("PROGRAM is not matching");
+                       dbg("PROGRAM is false");
                        if (rule->program.operation != KEY_OP_NOMATCH)
                                goto exit;
                } else {
@@ -931,7 +987,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
                                if (rule->group.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->group_final = 1;
                                strlcpy(udev->group, key_val(rule, &rule->group), sizeof(udev->group));
-                               apply_format(udev, key_val(rule, &rule->group), sizeof(udev->group), class_dev, sysfs_device);
+                               apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device);
                                dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name);
                        }
 
index 959524a802fc48bdd7ac8fc5fb8835857822a72c..3f37d4b0b4d3345089dda3ebe512d9015d5daa3e 100644 (file)
@@ -54,6 +54,13 @@ struct key_pairs {
        struct key_pair keys[PAIRS_MAX];
 };
 
+enum import_type {
+       IMPORT_UNSET,
+       IMPORT_PROGRAM,
+       IMPORT_FILE,
+       IMPORT_PARENT,
+};
+
 struct udev_rule {
        struct key kernel_name;
        struct key subsystem;
@@ -66,6 +73,7 @@ struct udev_rule {
        struct key result;
        struct key modalias;
        struct key import;
+       enum import_type import_type;
        struct key wait_for_sysfs;
        struct key_pairs sysfs;
        struct key_pairs env;
@@ -81,8 +89,7 @@ struct udev_rule {
        unsigned int partitions;
        unsigned int last_rule:1,
                     ignore_device:1,
-                    ignore_remove:1,
-                    import_exec:1;
+                    ignore_remove:1;
 
        size_t bufsize;
        char buf[];
index a2f2f1804b2279470b5a0e786c3764e1967382d9..7c3c2e7fc252698aed9bb4be6c3d0c551a588b14 100644 (file)
@@ -311,9 +311,13 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                        attr = get_key_attribute(key + sizeof("IMPORT")-1);
                        if (attr && strstr(attr, "program")) {
                                dbg("IMPORT will be executed");
-                               rule->import_exec = 1;
+                               rule->import_type  = IMPORT_PROGRAM;
                        } else if (attr && strstr(attr, "file")) {
                                dbg("IMPORT will be included as file");
+                               rule->import_type  = IMPORT_FILE;
+                       } else if (attr && strstr(attr, "parent")) {
+                               dbg("IMPORT will include the parent values");
+                               rule->import_type = IMPORT_PARENT;
                        } else {
                                /* figure it out if it is executable */
                                char file[PATH_SIZE];
@@ -326,8 +330,11 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                                        pos[0] = '\0';
                                dbg("IMPORT auto mode for '%s'", file);
                                if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) {
-                                               dbg("IMPORT is executable, will be executed");
-                                               rule->import_exec = 1;
+                                       dbg("IMPORT is executable, will be executed (autotype)");
+                                       rule->import_type  = IMPORT_PROGRAM;
+                               } else {
+                                       dbg("IMPORT is not executable, will be included as file (autotype)");
+                                       rule->import_type  = IMPORT_FILE;
                                }
                        }
                        add_rule_key(rule, &rule->import, operation, value);
@@ -548,6 +555,7 @@ static int rules_map(struct udev_rules *rules, const char *filename)
                rules->buf = NULL;
                return -1;
        }
+       rules->mapped = 1;
 
        return 0;
 }
diff --git a/udevd.c b/udevd.c
index 8782c615e325878bb7a7701a2f480209c82a7840..110d8e7c4d3a3fe90f547f76e252dbba63f0a0e8 100644 (file)
--- a/udevd.c
+++ b/udevd.c
@@ -167,7 +167,7 @@ static void msg_queue_insert(struct uevent_msg *msg)
 }
 
 /* forks event and removes event from run queue when finished */
-static void execute_udev(struct uevent_msg *msg)
+static void udev_event_fork(struct uevent_msg *msg)
 {
        char *const argv[] = { "udev", msg->subsystem, NULL };
        pid_t pid;
@@ -181,12 +181,10 @@ static void execute_udev(struct uevent_msg *msg)
                        close(uevent_netlink_sock);
                close(udevd_sock);
                logging_close();
-
                setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY);
                execve(udev_bin, argv, msg->envp);
                err("exec of child failed");
                _exit(1);
-               break;
        case -1:
                err("fork of child failed");
                msg_queue_delete(msg);
@@ -389,7 +387,7 @@ static void exec_queue_manager(void)
                if (running_with_devpath(loop_msg, max_childs) == 0) {
                        /* move event to run list */
                        list_move_tail(&loop_msg->node, &running_list);
-                       execute_udev(loop_msg);
+                       udev_event_fork(loop_msg);
                        running++;
                        dbg("moved seq %llu to running list", loop_msg->seqnum);
                } else
@@ -722,6 +720,7 @@ static void user_sighandler(void)
 static int init_udevd_socket(void)
 {
        struct sockaddr_un saddr;
+       const int buffersize = 1024 * 1024;
        socklen_t addrlen;
        const int feature_on = 1;
        int retval;
@@ -738,6 +737,9 @@ static int init_udevd_socket(void)
                return -1;
        }
 
+       /* set receive buffersize */
+       setsockopt(udevd_sock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
+
        /* the bind takes care of ensuring only one copy running */
        retval = bind(udevd_sock, (struct sockaddr *) &saddr, addrlen);
        if (retval < 0) {
@@ -755,6 +757,7 @@ static int init_udevd_socket(void)
 static int init_uevent_netlink_sock(void)
 {
        struct sockaddr_nl snl;
+       const int buffersize = 1024 * 1024;
        int retval;
 
        memset(&snl, 0x00, sizeof(struct sockaddr_nl));
@@ -768,6 +771,9 @@ static int init_uevent_netlink_sock(void)
                return -1;
        }
 
+       /* set receive buffersize */
+       setsockopt(uevent_netlink_sock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
+
        retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl,
                      sizeof(struct sockaddr_nl));
        if (retval < 0) {