修改globalfifo...

This commit is contained in:
gatieme
2016-03-31 17:04:31 +08:00
parent 8caed16e1d
commit b3f625002f
451 changed files with 34423 additions and 412 deletions
@@ -0,0 +1,14 @@
*.o
*.a
udevd
udevcontrol
udevtrigger
udevsettle
udevsend
udevinfo
udevmonitor
udevstart
udevtest
udev_version.h
test-udev
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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; either version 2 of the License, or
(at your option) any later version.
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
File diff suppressed because it is too large Load Diff
+111
View File
@@ -0,0 +1,111 @@
Frequently Asked Questions about udev
Q: What's this udev thing, and what is it trying to do?
A: Read the OLS 2003 paper about udev, available in the docs/ directory,
and at:
<http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf>
There is also a udev presentation given at OLS 2003 available at:
<http://www.kroah.com/linux/talks/ols_2003_udev_talk/>
Q: How is udev related to devfs?
A: udev works entirely in userspace, using hotplug events the kernel sends
whenever a device is added or removed from the kernel. Details about
the devices are exported by the kernel to the sysfs filesystem at /sys
All device naming policy permission control and event handling is done in
userspace. devfs is operated from within the kernel.
Q: Why was devfs removed if udev can't do everthing devfs did?
A: To quote Al Viro (Linux VFS kernel maintainer):
- it was determined that the same thing could be done in userspace
- devfs had been shoved into the tree in hope that its quality will
catch up
- devfs was found to have fixable and unfixable bugs
- the former had stayed around for many months with maintainer
claiming that everything works fine
- the latter had stayed, period.
- the devfs maintainer/author disappeared and stopped maintaining
the code.
Q: But udev will not automatically load a driver if a /dev node is opened
when it is not present like devfs will do.
A: Right, but Linux is supposed to load a module when a device is discovered
not to load a module when it's accessed.
Q: Oh come on, pretty please. It can't be that hard to do.
A: Such a functionality isn't needed on a properly configured system. All
devices present on the system should generate hotplug events, loading
the appropriate driver, and udev will notice and create the
appropriate device node. If you don't want to keep all drivers for your
hardware in memory, then use something else to manage your modules
(scripts, modules.conf, etc.) This is not a task for udev.
Q: But I love that feature of devfs, please?
A: The devfs approach caused a lot of spurious modprobe attempts as
programs probed to see if devices were present or not. Every probe
attempt created a process to run modprobe, almost all of which were
spurious.
Q: I really like the devfs naming scheme, will udev do that?
A: Yes, udev can create /dev nodes using the devfs naming policy. But you
will need a custom configuration and scripts that enumerate your devices
sequentially while events run in parallel, without a predictable order.
The devfs scheme is not recommended or supported because it is a stupid
idea to simply enumerate devices in a world where devices can come and go
at any time. These numbers give you nothing but problems, and are not
useful to identify a device. Have a look at the persistent rules for
examples how to create persistent device names in userspace without any
device enumeration depending on the device probing order.
Q: What kinds of devices does udev create nodes for?
A: All devices that are shown in the kernel's sysfs tree will work with udev.
Q: Will udev remove the limit on the number of anonymous devices?
A: udev is entirely in userspace. If the kernel supports a greater number
of anonymous devices, udev will support it.
Q: Does udev support symlinks?
A: Yes, multiple symlinks per device node are supported.
Q: How will udev handle the /dev filesystem?
A: /dev is recomended to be a tmpfs filesystem that is recreated on every reboot.
Although, udev does not care what kind of filesystem it runs on.
Q: How will udev handle devices found before init runs?
A: udev can be placed in initramfs and run for every device that is found.
udev can also populate an initial /dev directory from the content of /sys
after the real root is mounted.
Q: Can I use udev to automount a USB device when I connect it?
A: Technically, yes, but udev is not intended for this. All major distributions
use HAL (http://freedesktop.org/wiki/Software_2fhal) for this, which also
watches devices with removable media and integrates the Desktop environment.
Alternatively, it is easy to add the following to fstab:
/dev/disk/by-label/PENDRIVE /media/PENDRIVE vfat user,noauto 0 0
This means that users can access the device with:
$mount /media/PENDRIVE
and doen't have to be root, but will get full permissions on the device.
Using the persistent disk links (label, uuid) will always catch the
same device regardless of the actual kernel name.
Q: Are there any security issues that I should be aware of?
A: When using dynamic device numbers, a given pair of major/minor numbers may
point to different hardware over time. If a user has permission to access a
specific device node directly and is able to create hard links to this node,
he or she can do so to create a copy of the device node. When the device is
unplugged and udev removes the device node, the user's copy remains.
If the device node is later recreated with different permissions the hard
link can still be used to access the device using the old permissions.
(The same problem exists when using PAM to change permissions on login.)
The simplest solution is to prevent the creation of hard links by putting
/dev on a separate filesystem like tmpfs.
Q: I have other questions about udev, where do I ask them?
A: The linux-hotplug-devel mailing list is the proper place for it. The
address for it is:
linux-hotplug-devel@lists.sourceforge.net
Information on joining can be found at:
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
@@ -0,0 +1,379 @@
#
# Copyright (C) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
# Copyright (C) 2004-2006 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.
#
# 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
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
VERSION = 114
# set this to make use of syslog
USE_LOG = true
# compile-in development debug messages
# (export UDEV_LOG="debug" or set udev_log="debug" in udev.conf
# to print the debug messages to syslog)
DEBUG = false
# compile with gcc's code coverage option
USE_GCOV = false
# include Security-Enhanced Linux support
USE_SELINUX = false
# set this to create statically linked binaries
USE_STATIC = false
# to build any of the extras programs pass:
# make EXTRAS="extras/<extra1> extras/<extra2>"
EXTRAS =
# make the build silent
V =
PROGRAMS = \
udevd \
udevtrigger \
udevsettle \
udevcontrol \
udevmonitor \
udevinfo \
udevtest \
test-udev \
udevstart
HEADERS = \
udev.h \
udevd.h \
udev_rules.h \
logging.h \
udev_sysdeps.h \
udev_selinux.h \
list.h
UDEV_OBJS = \
udev_device.o \
udev_config.o \
udev_node.o \
udev_db.o \
udev_sysfs.o \
udev_rules.o \
udev_rules_parse.o \
udev_utils.o \
udev_utils_string.o \
udev_utils_file.o \
udev_sysdeps.o
LIBUDEV = libudev.a
MAN_PAGES = \
udev.7 \
udevmonitor.8 \
udevd.8 \
udevtrigger.8 \
udevsettle.8 \
udevtest.8 \
udevinfo.8 \
udevstart.8
GEN_HEADERS = \
udev_version.h
prefix ?=
etcdir = ${prefix}/etc
sbindir = ${prefix}/sbin
usrbindir = ${prefix}/usr/bin
usrsbindir = ${prefix}/usr/sbin
libudevdir = ${prefix}/lib/udev
mandir = ${prefix}/usr/share/man
configdir = ${etcdir}/udev
udevdir = /dev
DESTDIR =
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
PWD = $(shell pwd)
CROSS_COMPILE ?=
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib
CFLAGS += -g -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
WARNINGS = -Wstrict-prototypes -Wsign-compare -Wshadow \
-Wchar-subscripts -Wmissing-declarations -Wnested-externs \
-Wpointer-arith -Wcast-align -Wsign-compare -Wmissing-prototypes
CFLAGS += $(WARNINGS)
LDFLAGS += -Wl,-warn-common,--as-needed
OPTFLAGS = -Os
CFLAGS += $(OPTFLAGS)
ifeq ($(strip $(USE_LOG)),true)
CFLAGS += -DUSE_LOG
endif
# if DEBUG is enabled, then we do not strip
ifeq ($(strip $(DEBUG)),true)
CFLAGS += -DDEBUG
endif
ifeq ($(strip $(USE_GCOV)),true)
CFLAGS += -fprofile-arcs -ftest-coverage
LDFLAGS += -fprofile-arcs
endif
ifeq ($(strip $(USE_SELINUX)),true)
UDEV_OBJS += udev_selinux.o
LIB_OBJS += -lselinux -lsepol
CFLAGS += -DUSE_SELINUX
endif
ifeq ($(strip $(USE_STATIC)),true)
CFLAGS += -DUSE_STATIC
LDFLAGS += -static
endif
ifeq ($(strip $(V)),)
E = @echo
Q = @
else
E = @\#
Q =
endif
export E Q
all: $(PROGRAMS) $(MAN_PAGES)
$(Q) extras="$(EXTRAS)"; for target in $$extras; do \
$(MAKE) CC="$(CC)" \
CFLAGS="$(CFLAGS)" \
LD="$(LD)" \
LDFLAGS="$(LDFLAGS)" \
AR="$(AR)" \
RANLIB="$(RANLIB)" \
LIB_OBJS="$(LIB_OBJS)" \
LIBUDEV="$(PWD)/$(LIBUDEV)" \
-C $$target $@ || exit 1; \
done;
.PHONY: all
.DEFAULT: all
# clear implicit rules
.SUFFIXES:
# build the objects
%.o: %.c $(HEADERS) $(GEN_HEADERS)
$(E) " CC " $@
$(Q) $(CC) -c $(CFLAGS) $< -o $@
# "Static Pattern Rule" to build all programs
$(PROGRAMS): %: $(HEADERS) $(GEN_HEADERS) $(LIBUDEV) %.o
$(E) " LD " $@
$(Q) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIB_OBJS)
$(LIBUDEV): $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS)
$(Q) rm -f $@
$(E) " AR " $@
$(Q) $(AR) cq $@ $(UDEV_OBJS)
$(E) " RANLIB " $@
$(Q) $(RANLIB) $@
udev_version.h:
$(E) " GENHDR " $@
$(Q) echo "/* Generated by make. */" > $@
$(Q) echo \#define UDEV_VERSION \"$(VERSION)\" >> $@
$(Q) echo \#define UDEV_ROOT \"$(udevdir)\" >> $@
$(Q) echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@
$(Q) echo \#define UDEV_RULES_DIR \"$(configdir)/rules.d\" >> $@
# man pages
%.8 %.7: %.xml
$(E) " XMLTO " $@
$(Q) xmlto man $?
.PRECIOUS: %.8
clean:
$(E) " CLEAN "
$(Q) - find . -type f -name '*.orig' -print0 | xargs -0r rm -f
$(Q) - find . -type f -name '*.rej' -print0 | xargs -0r rm -f
$(Q) - find . -type f -name '*~' -print0 | xargs -0r rm -f
$(Q) - find . -type f -name '*.[oas]' -print0 | xargs -0r rm -f
$(Q) - find . -type f -name "*.gcno" -print0 | xargs -0r rm -f
$(Q) - find . -type f -name "*.gcda" -print0 | xargs -0r rm -f
$(Q) - find . -type f -name "*.gcov" -print0 | xargs -0r rm -f
$(Q) - rm -f udev_gcov.txt
$(Q) - rm -f core $(PROGRAMS) $(GEN_HEADERS)
$(Q) - rm -f udev-$(VERSION).tar.gz
$(Q) - rm -f udev-$(VERSION).tar.bz2
$(Q) - rm -f udev-git-HEAD.patch
@ extras="$(EXTRAS)"; for target in $$extras; do \
$(MAKE) -C $$target $@ || exit 1; \
done;
.PHONY: clean
install-config:
$(INSTALL) -d $(DESTDIR)$(configdir)/rules.d
@ if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \
$(INSTALL_DATA) etc/udev/udev.conf $(DESTDIR)$(configdir); \
fi
@ if [ ! -r $(DESTDIR)$(configdir)/rules.d/50-udev.rules ]; then \
echo; \
echo "pick a udev rules file from the etc/udev directory that matches your distribution"; \
echo; \
fi
@ extras="$(EXTRAS)"; for target in $$extras; do \
$(MAKE) -C $$target $@ || exit 1; \
done;
.PHONY: install-config
install-man:
$(INSTALL_DATA) -D udev.7 $(DESTDIR)$(mandir)/man7/udev.7
$(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8
$(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8
$(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8
$(INSTALL_DATA) -D udevtrigger.8 $(DESTDIR)$(mandir)/man8/udevtrigger.8
$(INSTALL_DATA) -D udevsettle.8 $(DESTDIR)$(mandir)/man8/udevsettle.8
$(INSTALL_DATA) -D udevmonitor.8 $(DESTDIR)$(mandir)/man8/udevmonitor.8
- ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8
@extras="$(EXTRAS)"; for target in $$extras; do \
$(MAKE) -C $$target $@ || exit 1; \
done;
.PHONY: install-man
uninstall-man:
- rm -f $(DESTDIR)$(mandir)/man7/udev.7
- rm -f $(DESTDIR)$(mandir)/man8/udevinfo.8
- rm -f $(DESTDIR)$(mandir)/man8/udevtest.8
- rm -f $(DESTDIR)$(mandir)/man8/udevd.8
- rm -f $(DESTDIR)$(mandir)/man8/udevtrigger.8
- rm -f $(DESTDIR)$(mandir)/man8/udevsettle.8
- rm -f $(DESTDIR)$(mandir)/man8/udevmonitor.8
- rm -f $(DESTDIR)$(mandir)/man8/udevcontrol.8
@ extras="$(EXTRAS)"; for target in $$extras; do \
$(MAKE) -C $$target $@ || exit 1; \
done;
.PHONY: uninstall-man
install-bin:
$(INSTALL) -d $(DESTDIR)$(udevdir)
$(INSTALL_PROGRAM) -D udevd $(DESTDIR)$(sbindir)/udevd
$(INSTALL_PROGRAM) -D udevtrigger $(DESTDIR)$(sbindir)/udevtrigger
$(INSTALL_PROGRAM) -D udevsettle $(DESTDIR)$(sbindir)/udevsettle
$(INSTALL_PROGRAM) -D udevcontrol $(DESTDIR)$(sbindir)/udevcontrol
$(INSTALL_PROGRAM) -D udevmonitor $(DESTDIR)$(usrsbindir)/udevmonitor
$(INSTALL_PROGRAM) -D udevinfo $(DESTDIR)$(usrbindir)/udevinfo
$(INSTALL_PROGRAM) -D udevtest $(DESTDIR)$(usrbindir)/udevtest
@extras="$(EXTRAS)"; for target in $$extras; do \
$(MAKE) -C $$target $@ || exit 1; \
done;
ifndef DESTDIR
- killall udevd
- rm -rf /dev/.udev
- $(sbindir)/udevd --daemon
endif
.PHONY: install-bin
uninstall-bin:
- rm -f $(DESTDIR)$(sbindir)/udevd
- rm -f $(DESTDIR)$(sbindir)/udevtrigger
- rm -f $(DESTDIR)$(sbindir)/udevsettle
- rm -f $(DESTDIR)$(sbindir)/udevcontrol
- rm -f $(DESTDIR)$(usrsbindir)/udevmonitor
- rm -f $(DESTDIR)$(usrbindir)/udevinfo
- rm -f $(DESTDIR)$(usrbindir)/udevtest
ifndef DESTDIR
- killall udevd
- rm -rf /dev/.udev
endif
@extras="$(EXTRAS)"; for target in $$extras; do \
$(MAKE) -C $$target $@ || exit 1; \
done;
.PHONY: uninstall-bin
install: all install-bin install-config install-man
.PHONY: install
uninstall: uninstall-bin uninstall-man
.PHONY: uninstall
test tests: all
@ cd test && ./udev-test.pl
@ cd test && ./udevstart-test.pl
.PHONY: test tests
buildtest:
test/simple-build-check.sh
.PHONY: buildtest
ChangeLog:
head -1 $@ | grep -q "to v$(shell echo $$(($(VERSION) - 1)))"
@ mv $@ $@.tmp
@ echo "Summary of changes from v$(shell echo $$(($(VERSION) - 1))) to v$(VERSION)" >> $@
@ echo "============================================" >> $@
@ echo >> $@
@ git log --pretty=short $(shell echo $$(($(VERSION) - 1)))..HEAD | git shortlog >> $@
@ echo >> $@
@ cat $@
@ cat $@.tmp >> $@
@ rm $@.tmp
head -1 $@ | grep -q "to v$(VERSION)"
.PHONY: ChangeLog
.PRECIOUS: ChangeLog
release:
$(Q) - rm -f udev-$(VERSION).tar.gz
$(Q) - rm -f udev-$(VERSION).tar.bz2
head -1 ChangeLog | grep -q "to v$(VERSION)"
head -1 RELEASE-NOTES | grep -q "udev $(VERSION)"
git commit -a -m "release $(VERSION)"
cat .git/refs/heads/master > .git/refs/tags/$(VERSION)
@ echo
git-archive --format=tar --prefix=udev-$(VERSION)/ HEAD | gzip -9v > udev-$(VERSION).tar.gz
git-archive --format=tar --prefix=udev-$(VERSION)/ HEAD | bzip2 -9v > udev-$(VERSION).tar.bz2
.PHONY: release
dist:
git-archive --format=tar --prefix=udev-$(VERSION)/ HEAD | gzip -9v > udev-$(VERSION).tar.gz
git-archive --format=tar --prefix=udev-$(VERSION)/ HEAD | bzip2 -9v > udev-$(VERSION).tar.bz2
.PHONY: dist
patch:
git diff $(shell echo $$(($(VERSION) - 1))) HEAD > udev-git-HEAD.patch
.PHONY: patch
gcov-all:
$(MAKE) clean all USE_GCOV=true
@ echo
@ echo "binaries built with gcov support."
@ echo "run the tests and analyze with 'make udev_gcov.txt'"
.PHONY: gcov-all
# see docs/README-gcov_for_udev
udev_gcov.txt: $(wildcard *.gcda) $(wildcard *.gcno)
for file in `find -maxdepth 1 -name "*.gcno"`; do \
name=`basename $$file .gcno`; \
echo "################" >> $@; \
echo "$$name.c" >> $@; \
echo "################" >> $@; \
if [ -e "$$name.gcda" ]; then \
gcov -l "$$name.c" >> $@ 2>&1; \
else \
echo "code for $$name.c was never executed" >> $@ 2>&1; \
fi; \
echo >> $@; \
done; \
echo "view $@ for the result"
@@ -0,0 +1,97 @@
udev - userspace device management
For more information see the files in the docs/ directory.
Important Note:
Integrating udev in the system is a whole lot of work, has complex dependencies
and differs a lot from distro to distro. All major distros depend on udev these
days and the system may not work without a proper installed version. The upstream
udev project does not support or recommend to replace a distro's udev installation
with the upstream version. The installation of a unmodified upstream version may
render your system unusable. Until now, there is no "default" setup or a set of
"default" rules provided by the upstream udev version.
Requirements:
- Version 2.6.15 of the Linux kernel for reliable operation of this release of
udev. The kernel may have a requirement on udev too, see Documentation/Changes
in the kernel source tree for the actual dependency.
- The kernel must have sysfs, unix domain sockets and networking enabled.
(unix domain sockets (CONFIG_UNIX) as a loadable kernel module may work,
but it is completely silly - don't complain if anything goes wrong.)
- The proc filesystem must be mounted on /proc, the sysfs filesystem must
be mounted at /sys. No other location will be supported by udev.
Operation:
Udev creates and removes device nodes in /dev, based on events the kernel
sends out on device discovery or removal.
- Very early in the boot process, the /dev directory should get a 'tmpfs'
filesystem mounted, which is populated from scratch by udev. Created nodes
or changed permissions will not survive a reboot, which is intentional.
- The content of /lib/udev/devices directory which contains the nodes,
symlinks and directories, which are always expected to be in /dev, should
be copied over to the tmpfs mounted /dev, to provide the required nodes
to initialize udev and continue booting.
- The old hotplug helper /sbin/hotplug should be disabled on bootup, before
actions like loading kernel modules are taken, which may cause a lot of
events.
- The udevd daemon must be started on bootup to receive netlink uevents
from the kernel driver core.
- All kernel events are matched against a set of specified rules in
/etc/udev/rules.d/ which make it possible to hook into the event
processing to load required kernel modules and setup devices. For all
devices the kernel exports a major/minor number, udev will create a
device node with the default kernel name or the one specified by a
matching udev rule.
Compile Options:
DESTDIR
Prefix of install target, used for package building.
USE_LOG
If set to 'true', udev is able to pass errors or debug information
to syslog. This is very useful to see what udev is doing or not doing.
It is enabled by default, don't expect any useful answer, if you
need to hunt a bug, but you can't enable syslog.
DEBUG
If set to 'true', very verbose debugging messages will be compiled
into the udev binaries. The actual level of debugging is specified
in the udev config file.
USE_SELINUX
If set to 'true', udev will be built with SELinux support
enabled. This is disabled by default.
EXTRAS
list of helper programs in extras/ to build.
make EXTRAS="extras/cdrom_id extras/scsi_id extras/volume_id"
Installation:
- The install target intalls the udev binaries in the default locations,
All at boot time reqired binaries will be installed in /lib/udev or /sbin.
- The default location for scripts and binaries that are called from
rules is /lib/udev. Other packages who install udev rules, should use
that directory too.
- It is recommended to use the /lib/udev/devices directory to place
device nodes and symlinks in, which are copied to /dev at every boot.
That way, nodes for broken subsystems or devices which can't be
detected automatically by the kernel, will always be available.
- Copies of the rules files for the major distros are provided as examples
in the etc/udev directory.
- The persistent device naming links in /dev/disk/ are required by other
software that depends on the data udev has collected from the devices
and should be installed by default with every udev installation.
Please direct any comment/question/concern to the linux-hotplug-devel mailing list at:
linux-hotplug-devel@lists.sourceforge.net
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,13 @@
These things would be nice to have:
These things will change in future udev versions:
o warn if BUS, ID, SYSFS are used as keys
(they are SUBSYSTEMS, KERNELS, ATTRS now)
These things are deprecated and scheduled for removal in a future
udev version:
o remove udevstart
(we rely on the kernel "uevent"-triggers of kernel 2.6.15 and no longer
want to guess event-properties from sysfs like udevstart is doing it)
@@ -0,0 +1,90 @@
################################################
Using GCC's code coverage tool, gcov, with udev
Leann Ogasawara <ogasawara@osdl.org>, April 2004
################################################
For more information on using gcov please see:
http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
With that said, here is how to get code coverage analysis for udev files.
Note that this was developed with udev version 024.
- Make sure you've installed udev and that it is working properly.
If you are having problems, refer to the README and HOWTO-udev_for_dev
documents in udev tarball.
- execute make_gcov.sh from udev top level directory
make gcov-all
This will compile udev with gcov support. Basically make_gcov.sh will
run make but override the CFLAGS. It strips any optimization from
CFLAGS in order for gcov to get correct code coverage analysis. It will
also add the -fprofile-arcs and -ftest-coverage options which are the
necessary flags needed to use gcov.
If you look into your udev directory and see that it has been polluted with
a bunch of *.gcno, *.gcda and *.gcov files. gcov creates and uses these files
to extract the code coverage info.
- After running make_gcov.sh you need to install udev again. So basically,
su to root
make install
- Then execute some udev tasks. You can run some udev tests, reboot, or
do anything your little udev heart desires. Once you are satisfied, you
can now see how much udev code was covered. I personally recommend just
running test/udev-test.pl for starters.
- To get the udev code coverage analysis, execute run_gcov.sh from udev top
level directory. You need to be root to do this.
su to root
make udev_gcov.txt
- This creates udev_gcov.txt in the udev top level directory which holds all
the code coverage information. To see an example of the code coverage info
after executing the udev-test.pl test, please see:
http://developer.osdl.org/ogasawara/gcov_for_udev/udev_gcov.txt
- Also, after having executed gcov on udev (ie executing run_gcov.sh) a
*.gcov file is created for every file which contained code that was
used. Looking at the *.gcov files, one will see what lines of code
were hit, and what lines were missed. For, example if code in udev-add.c
were executed, gcov then created a file called udev-add.c.gcov. And a
portion of udev-add.c.gov might look like:
static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev)
95 {
95 struct sysfs_attribute *attr = NULL;
95 attr = sysfs_get_classdev_attr(class_dev, "dev");
95 if (attr == NULL)
###### goto error;
dbg("dev='%s'", attr->value);
95 if (sscanf(attr->value, "%u:%u", &udev->major, &udev->minor) != 2)
###### goto error;
dbg("found major=%d, minor=%d", udev->major, udev->minor);
95 return 0;
error:
###### return -1;
}
Any line of code that is preceded by a "######" implies that the code
was never hit during execution.
- Once you are done with using gcov for udev and want to return to your
normal use of udev, run a regular 'make clean' on your udev directory.
Then just run a regular make and make install and you are back to normal:
make clean all
su to root
make install
@@ -0,0 +1,102 @@
-------------------------------------------------------------------------
This is a proposal from the early days of udev. A lot of the things
mentioned here are implemented differently and most of the features
implemented in udev are not part of that document.
This document is only kept in the tree for sentimental reasons.
-------------------------------------------------------------------------
We've got a couple of goals for udev:
1) dynamic replacement for /dev
2) device naming
3) API to access info about current system devices
Splitting these goals into separate subsystems:
1) udev - dynamic replacement for /dev
2) namedev - device naming
3) libsysfs - a standard library for accessing device information on the
system.
Udev
------
Udev will be responsible for responding to /sbin/hotplug on device
events. It will receive the device class information along with
device's sysfs directory. Udev will call the name_device function from
the naming device subsystem with that information and receive a unique
device name in return. Udev will then query sysfs through the libsysfs
for specific device information required for creating the /dev node like
major and minor number. Once it has the important information, udev
will create a /dev entry for the device, add the device to the in memory
table of current devices, and send notification of the successful event
through a D-BUS message. On a remove call, udev will remove the /dev
entry, remove the device from the in memory table, and send
notification.
Udev will consist of a command udev - to be called from /sbin/hotplug.
It will require the in memory dynamic database/table for keeping track
of current system devices, and a library of routines for accessing that
database/table. Udev will not care about "how" devices are named, that
will be separated into the device naming subsystem. It's presented a
common device naming API by the device naming subsystem to use for
naming devices.
namedev
----------
From comments people have made, the device naming part of udev has been
pushed into its own "subsystem". The reason is to make this as flexible
and pluggable as possible. The device naming subsystem, or namedev, will
present a standard interface for udev to call for naming a particular
device. Under that interface, system administrators can plug in their
own methods for device naming.
We would provide a default naming scheme. The first prototype
implementation could simply take the sysfs directory passed in with the
device name function, query sysfs for the major and minor numbers, and
then look up in a static device name mapping file the name of the
device. The static device naming file could look just like devices.txt
in the Linux kernel's Documentation directory. Obviously, this isn't a
great implementation because eventually we'd like major an minor numbers
to be dynamic.
The default naming scheme in the future would have a set of policies to
go through in order to determine the name of the device. The device
naming subsystem would get the sysfs directory of the to be named device
and would use the following information in order to map the device's
name:
1) Label info - like SCSI's UUID
2) Bus Device Number
3) Topology on Bus
4) Kernel Name - DEFAULT
System administrators could use the default naming system or enterprise
computing environments could plug in their Universal Unique Identifier
(UUID) policies. The idea is to make the device naming as flexible and
pluggable as possible.
The device naming subsystem would require accessing sysfs for device
information. It will receive the device's sysfs directory in the call
from udev and use it to get more information to determine naming. The
namedev subsystem will include a standard naming API for udev to use.
The default naming scheme will include a set of functions and a static
device naming file, which will reside in /etc or /var.
libsysfs
--------
There is a need for a common API to access device information in sysfs.
The device naming subsystem and the udev subsystem need to take the
sysfs directory path and query device information. Instead of copying
code so each one will have to readdir, etc., splitting this logic of
sysfs calls into a separate library that will sit atop sysfs makes more
sense. Sysfs callbacks aren't standard across devices, so this is
another reason for creating a common and standard library interface for
querying device information.
@@ -0,0 +1,192 @@
udev and devfs - The final word
December 30, 2003
Greg Kroah-Hartman
<greg@kroah.com>
Executive summary for those too lazy to read this whole thing:
I don't care about devfs, and I don't want to talk about it at
all anymore. If you love devfs, fine, I'm not trying to tell
anyone what to do. But you really should be looking into using
udev instead. All further email messages sent to me about devfs
will be gladly ignored.
First off, some background. For a description of udev, and what its
original design goals were, please see the OLS 2003 paper on udev,
available at:
<http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf>
and the slides for the talk, available at:
<http://www.kroah.com/linux/talks/ols_2003_udev_talk/>
The OLS paper can also be found in the docs/ directory of the udev
tarball, available on kernel.org in the /pub/linux/utils/kernel/hotplug/
directory.
In that OLS paper, I described the current situation of a static /dev
and the current problems that a number of people have with it. I also
detailed how devfs tries to solve a number of these problems. In
hindsight, I should have never mentioned the word "devfs" when talking
about udev. I did so only because it seemed like a good place to start
with. Most people understood what devfs is, and what it does. To
compare udev against it, showing how udev was more powerful, and a more
complete solution to the problems people were having, seemed like a
natural comparison to me.
But no more. I hereby never want to compare devfs and udev again. With
the exception of this message...
The Problems:
1) A static /dev is unwieldy and big. It would be nice to only show
the /dev entries for the devices we actually have running in the
system.
2) We are (well, were) running out of major and minor numbers for
devices.
3) Users want a way to name devices in a persistent fashion (i.e. "This
disk here, must _always_ be called "boot_disk" no matter where in
the scsi tree I put it", or "This USB camera must always be called
"camera" no matter if I have other USB scsi devices plugged in or
not.")
4) Userspace programs want to know when devices are created or removed,
and what /dev entry is associated with them.
The constraints:
1) No policy in the kernel!
2) Follow standards (like the LSB)
3) must be small so embedded devices will use it.
So, how does devfs stack up to the above problems and constraints:
Problems:
1) devfs only shows the dev entries for the devices in the system.
2) devfs does not handle the need for dynamic major/minor numbers
3) devfs does not provide a way to name devices in a persistent
fashion.
4) devfs does provide a deamon that userspace programs can hook into
to listen to see what devices are being created or removed.
Constraints:
1) devfs forces the devfs naming policy into the kernel. If you
don't like this naming scheme, tough.
2) devfs does not follow the LSB device naming standard.
3) devfs is small, and embedded devices use it. However it is
implemented in non-pagable memory.
Oh yeah, and there are the insolvable race conditions with the devfs
implementation in the kernel, but I'm not going to talk about them right
now, sorry. See the linux-kernel archives if you care about them (and
if you use devfs, you should care...)
So devfs is 2 for 7, ignoring the kernel races.
And now for udev:
Problems:
1) using udev, the /dev tree only is populated for the devices that
are currently present in the system.
2) udev does not care about the major/minor number schemes. If the
kernel tomorrow switches to randomly assign major and minor numbers
to different devices, it would work just fine (this is exactly
what I am proposing to do in 2.7...)
3) This is the main reason udev is around. It provides the ability
to name devices in a persistent manner. More on that below.
4) udev emits D-BUS messages so that any other userspace program
(like HAL) can listen to see what devices are created or removed.
It also allows userspace programs to query its database to see
what devices are present and what they are currently named as
(providing a pointer into the sysfs tree for that specific device
node.)
Constraints:
1) udev moves _all_ naming policies out of the kernel and into
userspace.
2) udev defaults to using the LSB device naming standard. If users
want to deviate away from this standard (for example when naming
some devices in a persistent manner), it is easily possible to do
so.
3) udev is small and is entirely in userspace, which
is swapable, and doesn't have to be running at all times.
Nice, 7 out of 7 for udev. Makes you think the problems and constraints
were picked by a udev developer, right? No, the problems and
constraints are ones I've seen over the years and so udev, along with
the kernel driver model and sysfs, were created to solve these real
problems. I also have had the luxury to see the problems that the
current devfs implementation has, and have taken the time to work out
something that does not have those same problems.
So by just looking at the above descriptions, everyone should instantly
realize that udev is far better than devfs and start helping out udev
development, right? Oh, you want more info, ok...
Back in May 2003 I released a very tiny version of udev that implemented
everything that devfs currently does, in about 6Kb of userspace code:
http://marc.theaimsgroup.com/?l=linux-kernel&m=105003185331553
Yes, that's right, 6Kb. So, you are asking, why are you still working
on udev if it did everything devfs did back in May 2003? That's because
just managing static device nodes based on what the kernel calls the
devices is _not_ the primary goal of udev. It's just a tiny side effect
of its primary goal, the ability to never worry about major/minor
number assignments and provide the ability to achieve persistent device
names if wanted.
All the people wanting to bring up the udev vs. devfs argument go back
and read the previous paragraph. Yes, all Gentoo users who keep filling
up my inbox with smoking emails, I mean you.
So, how well does udev solve its goals:
Prevent users from ever worrying about major/minor numbers
And here you were, not knowing you ever needed to worry about
major/minor numbers in the first place, right? Ah, I see you
haven't plugged in 2 USB printers and tried to figure out which
printer was which /dev entry? Or plugged in 4000 SCSI disks and
tried to figure out how to access that 3642nd disk and what it was
called in /dev. Or plugged in a USB camera and a USB flash drive
and then tried to download the pictures off of the flash drive by
accident?
As the above scenarios show, both desktop users and big iron users
both need to not worry about which device is assigned to what
major/minor device.
udev doesn't care what major/minor number is assigned to a device.
It merely takes the numbers that the kernel says it assigned to the
device and creates a device node based on it, which the user can
then use (if you don't understand the whole major/minor to device
node issue, or even what a device node is, trust me, you don't
really want to, go install udev and don't worry about it...) As
stated above, if the kernel decides to start randomly assigning
major numbers to all devices, then udev will still work just fine.
Provide a persistent device naming solution:
Lots of people want to assign a specific name that they can talk to
a device to, no matter where it is in the system, or what order they
plugged the device in. USB printers, SCSI disks, PCI sound cards,
Firewire disks, USB mice, and lots of other devices all need to be
assigned a name in a consistent manner (udev doesn't handle network
devices, naming them is already a solved solution, using nameif).
udev allows users to create simple rules to describe what device to
name. If users want to call a program running a large database
half-way around the world, asking it what to name this device, it
can. We don't put the naming database into the kernel (like other
Unix variants have), everything is in userspace, and easily
accessible. You can even run a perl script to name your device if
you are that crazy...
For more information on how to create udev rules to name devices,
please see the udev man page, and look at the example udev rules
that ship with the tarball.
So, convinced already why you should use udev instead of devfs? No.
Ok, fine, I'm not forcing you to abandon your bloated, stifling policy,
nonextensible, end of life feature if you don't want to. But please
don't bother me about it either, I don't care about devfs, only about
udev.
This is my last posting about this topic, all further emails sent to me
about why devfs is wonderful, and why are you making fun of this
wonderful, stable gift from the gods, will be gleefully ignored and
possibly posted in a public place where others can see.
thanks,
greg k-h
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,37 @@
# compatibility links for a devfs-style /dev
KERNEL=="md[0-9]*", SYMLINK+="%k"
#KERNEL=="loop[0-9]*", SYMLINK+="%k"
#KERNEL=="tty[0-9]*", SYMLINK+="%k"
#KERNEL=="ttyS[0-9]*", SYMLINK+="%k"
#KERNEL=="ttyUSB[0-9]*", SYMLINK+="%k"
#KERNEL=="vcs", SYMLINK+="%k"
#KERNEL=="vcs[0-9]*", SYMLINK+="%k"
#KERNEL=="vcsa", SYMLINK+="%k"
#KERNEL=="vcsa[0-9]*", SYMLINK+="%k"
KERNEL=="video*", SYMLINK+="%k"
KERNEL=="radio*", SYMLINK+="%k"
KERNEL=="vbi*", SYMLINK+="%k"
KERNEL=="vtx*", SYMLINK+="%k"
KERNEL=="apm_bios", SYMLINK+="%k"
KERNEL=="agpgart", SYMLINK+="%k"
#KERNEL=="psaux", SYMLINK+="%k"
#KERNEL=="nvram", SYMLINK+="%k"
KERNEL=="rtc", SYMLINK+="%k"
#KERNEL=="ram[0-9]*", SYMLINK+="%k"
#KERNEL=="i2c-[0-9]*", SYMLINK+="%k"
#KERNEL=="lp[0-9]*", SYMLINK+="%k"
KERNEL=="audio*", SYMLINK+="%k"
KERNEL=="dsp*", SYMLINK+="%k"
KERNEL=="mixer*", SYMLINK+="%k"
#KERNEL=="fb[0-9]*", SYMLINK+="%k"
#KERNEL=="fd[0-9]*", SYMLINK+="%k"
#KERNEL=="js[0-9]*", SYMLINK+="%k"
@@ -0,0 +1,152 @@
# There are a number of modifiers that are allowed to be used in some
# of the different fields. They provide the following subsitutions:
#
# %n the "kernel number" of the device.
# For example, 'sda3' has a "kernel number" of '3'
# %k the kernel name for the device
# %M the kernel major number for the device
# %m the kernel minor number for the device
# %b the bus id for the device
# %c the string returned by the PROGRAM
# %s{filename} the content of a sysfs attribute
# %% the '%' char itself
#
# workaround for devices which do not report media changes
SUBSYSTEMS=="ide", KERNEL=="hd[a-z]", ATTR{removable}=="1", \
ENV{ID_MODEL}=="IOMEGA_ZIP*", NAME="%k", OPTIONS+="all_partitions"
SUBSYSTEMS=="ide", KERNEL=="hd[a-z]", ATTRS{media}=="floppy", \
OPTIONS+="all_partitions"
# IDE devices
SUBSYSTEMS=="ide", KERNEL=="hd[a-z]*", PROGRAM="ide-devfs.sh %k %b %n", \
ACTION=="add", \
NAME="%c{1}", SYMLINK+="%k %c{2}"
# SCSI devices
SUBSYSTEMS=="scsi", PROGRAM="scsi-devfs.sh %k %b %n", ACTION=="add", \
NAME="%c{1}", SYMLINK+="%k %c{2}"
# RAID controllers
KERNEL=="cciss!*|ida!*|rd!*", PROGRAM="raid-devfs.sh %k", ACTION=="add", \
NAME="%c{1}", SYMLINK+="%k"
# other block devices
KERNEL=="md[0-9]*", NAME="md/%n",
KERNEL=="loop[0-9]*", NAME="loop/%n"
KERNEL=="ram[0-9]*", NAME="rd/%n"
# USB devices
SUBSYSTEMS=="usb", KERNEL=="auer[0-9]*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="cpad[0-9]*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="dabusb*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="hiddev*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="legousbtower*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", \
ATTRS{product}=="Palm Handheld*|Handspring Visor|palmOne Handheld", \
SYMLINK+="pilot"
# usbfs-like devices
SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", ACTION=="add", \
NAME="%c"
# serial devices
KERNEL=="ttyS[0-9]*", NAME="tts/%n"
KERNEL=="ttyUSB[0-9]*", NAME="tts/USB%n"
KERNEL=="rfcomm[0-9]*", NAME="bluetooth/rfcomm/%n",
KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20"
KERNEL=="capi[0-9]*", NAME="capi/%n"
# vc devices
KERNEL=="tty[0-9]*", NAME="vc/%n"
KERNEL=="vcs", NAME="vcc/0"
KERNEL=="vcs[0-9]*", NAME="vcc/%n"
KERNEL=="vcsa", NAME="vcc/a0"
KERNEL=="vcsa[0-9]*", NAME="vcc/a%n"
# video devices
KERNEL=="video[0-9]*", NAME="v4l/%k"
KERNEL=="radio[0-9]*", NAME="v4l/%k"
KERNEL=="vbi[0-9]*", NAME="v4l/%k"
KERNEL=="vtx[0-9]*", NAME="v4l/%k"
KERNEL=="dvb*", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%s $${K%%%%.*} $${K#*.}", ACTION=="add", \
NAME="%c"
KERNEL=="fb[0-9]*", NAME="fb/%n"
KERNEL=="card[0-9]*", NAME="dri/%k"
# misc devices
KERNEL=="apm_bios", NAME="misc/%k",
KERNEL=="agpgart", NAME="misc/%k"
KERNEL=="hw_random", NAME="hwrng"
KERNEL=="nvram", NAME="misc/%k"
KERNEL=="psaux", NAME="misc/%k"
KERNEL=="rtc", NAME="misc/%k"
KERNEL=="tun", NAME="net/%k"
KERNEL=="evtchn", NAME="xen/%k"
# printers and parallel devices
KERNEL=="lp[0-9]*", NAME="printers/%n"
KERNEL=="parport[0-9]*", NAME="parports/%n"
KERNEL=="i2c-[0-9]*", NAME="i2c/%n"
KERNEL=="fd[0-9]*", NAME="floppy/%n"
KERNEL=="cdemu[0-9]*", NAME="cdemu/%n"
KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%n"
KERNEL=="pktcdvd", NAME="pktcdvd/control"
KERNEL=="cpu[0-9]*", NAME="cpu/%n/cpuid"
KERNEL=="msr[0-9]*", NAME="cpu/%n/msr"
KERNEL=="microcode", NAME="cpu/microcode"
KERNEL=="umad*", NAME="infiniband/%k"
KERNEL=="issm*", NAME="infiniband/%k"
KERNEL=="uverbs*", NAME="infiniband/%k"
KERNEL=="ucm*", NAME="infiniband/%k"
# sound devices
KERNEL=="controlC[0-9]*", NAME="snd/%k"
KERNEL=="hwC[D0-9]*", NAME="snd/%k"
KERNEL=="pcmC[D0-9cp]*", NAME="snd/%k"
KERNEL=="midiC[D0-9]*", NAME="snd/%k"
KERNEL=="timer", NAME="snd/%k"
KERNEL=="seq", NAME="snd/%k"
KERNEL=="audio*", NAME="sound/%k"
KERNEL=="dsp*", NAME="sound/%k"
KERNEL=="adsp*", NAME="sound/%k"
KERNEL=="midi*", NAME="sound/%k"
KERNEL=="mixer*", NAME="sound/%k"
KERNEL=="sequencer*", NAME="sound/%k"
KERNEL=="amidi*", NAME="sound/%k"
KERNEL=="dmmidi*", NAME="sound/%k"
KERNEL=="admmidi*", NAME="sound/%k"
# ieee1394 devices
KERNEL=="dv1394*", NAME="dv1394/%n"
KERNEL=="video1394*", NAME="video1394/%n"
# input devices
KERNEL=="mice", NAME="input/%k"
KERNEL=="mouse[0-9]*", NAME="input/%k"
KERNEL=="event[0-9]*", NAME="input/%k"
KERNEL=="js[0-9]*", NAME="input/%k"
KERNEL=="ts[0-9]*", NAME="input/%k"
KERNEL=="uinput", NAME="input/%k"
# Zaptel
KERNEL=="zapctl", NAME="zap/ctl"
KERNEL=="zaptimer", NAME="zap/timer"
KERNEL=="zapchannel", NAME="zap/channel"
KERNEL=="zappseudo", NAME="zap/pseudo"
KERNEL=="zap[0-9]*", NAME="zap/%n"
# AOE character devices
SUBSYSTEM=="aoe", KERNEL=="discover", NAME="etherd/%k"
SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k"
SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k"
SUBSYSTEM=="aoe", KERNEL=="revalidate", NAME="etherd/%k"
# device mapper creates its own device nodes, so ignore these
KERNEL=="device-mapper", NAME="mapper/control"
@@ -0,0 +1,49 @@
ACTION!="add", GOTO="hotplug_not_add_event"
# check if the device has already been claimed by a driver
ENV{DRIVER}=="?*", SUBSYSTEM!="input", GOTO="hotplug_driver_loaded"
# this driver is broken and should not be loaded automatically (see #398962)
SUBSYSTEM=="platform", ENV{MODALIAS}=="i82365", GOTO="hotplug_driver_loaded"
# load the drivers
ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe --use-blacklist $env{MODALIAS}"
SUBSYSTEM=="ide", ENV{MODALIAS}!="?*", RUN+="ide.agent"
SUBSYSTEM=="pnp", ENV{MODALIAS}!="?*", RUN+="/bin/sh -c 'while read id; do /sbin/modprobe --use-blacklist pnp:d$$id; done < /sys$devpath/id'"
SUBSYSTEM=="pcmcia_socket", RUN+="/sbin/modprobe pcmcia"
# rules for subsystems which lack proper hotplug support
SUBSYSTEM=="i2o", RUN+="/sbin/modprobe i2o_block"
SUBSYSTEM=="mmc", RUN+="/sbin/modprobe mmc_block"
SUBSYSTEM=="scsi_device", ATTRS{type}=="0|7|14", RUN+="/sbin/modprobe sd_mod"
SUBSYSTEM=="scsi_device", ATTRS{type}=="1", RUN+="/sbin/modprobe osst", \
ATTRS{vendor}=="Onstream", ATTRS{model}!="ADR*"
SUBSYSTEM=="scsi_device", ATTRS{type}=="1", RUN+="/sbin/modprobe st", \
ATTRS{vendor}=="Onstream", ATTRS{model}=="ADR*"
SUBSYSTEM=="scsi_device", ATTRS{type}=="1", RUN+="/sbin/modprobe st", \
ATTRS{vendor}!="Onstream"
SUBSYSTEM=="scsi_device", ATTRS{type}=="[45]", RUN+="/sbin/modprobe sr_mod"
SUBSYSTEM=="scsi_device", ATTRS{type}=="8", RUN+="/sbin/modprobe ch"
SUBSYSTEM=="scsi_device", ATTRS{type}=="[235689]", RUN+="/sbin/modprobe sg"
SUBSYSTEM=="ide", ATTR{media}=="tape", RUN+="/sbin/modprobe ide-scsi"
# From here on follows the hotplug agents which do not load modules
LABEL="hotplug_driver_loaded"
# FIXME: does a sane default exist?
#SUBSYSTEM=="scsi_device", ATTRS{idVendor}=="...", \
# RUN+="scsi-re-add"
SUBSYSTEM=="firmware", RUN+="firmware.agent"
LABEL="hotplug_not_add_event"
SUBSYSTEM=="net", RUN+="net.agent"
# Log every event to /dev/hotplug.log (for debugging).
#RUN+="logger.agent"
@@ -0,0 +1,8 @@
# do not call hotplug.d and dev.d for "drivers" and "module" events
SUBSYSTEM=="drivers", OPTIONS="last_rule"
SUBSYSTEM=="module", OPTIONS="last_rule"
# compatibility support for the obsolete hotplug.d and dev.d directories
RUN+="udev_run_hotplugd $env{SUBSYSTEM}"
RUN+="udev_run_devd $env{SUBSYSTEM}"
@@ -0,0 +1,123 @@
ACTION!="add", GOTO="permissions_end"
# workarounds needed to synchronize with sysfs
# only needed for kernels < v2.6.18-rc1
ENV{PHYSDEVPATH}!="?*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus"
SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt"
# only needed for kernels < 2.6.16
SUBSYSTEM=="net", WAIT_FOR_SYSFS="address"
# only needed for kernels < 2.6.17
SUBSYSTEM=="net", ENV{DRIVER}=="?*", WAIT_FOR_SYSFS="device/driver"
# default permissions for block devices
SUBSYSTEM=="block", GROUP="disk"
# the aacraid driver is broken and reports that disks removable (see #404927)
SUBSYSTEM=="block", ATTRS{removable}=="1", \
DRIVERS!="aacraid", GROUP="floppy"
# all block devices on these buses are "removable"
SUBSYSTEM=="block", SUBSYSTEMS=="usb|ieee1394|mmc|pcmcia", GROUP="floppy"
# IDE devices
KERNEL=="hd[a-z]|pcd[0-9]*", DRIVERS=="ide-cdrom|pcd", \
IMPORT{program}="cdrom_id --export $tempnode"
ENV{ID_CDROM}=="?*", GROUP="cdrom"
KERNEL=="ht[0-9]*", GROUP="tape"
KERNEL=="nht[0-9]*", GROUP="tape"
# SCSI devices
KERNEL=="sr[0-9]*", IMPORT{program}="cdrom_id --export $tempnode"
SUBSYSTEMS=="scsi", ATTRS{type}=="1", GROUP="tape"
SUBSYSTEMS=="scsi", ATTRS{type}=="3", ATTRS{vendor}=="HP", GROUP="scanner"
SUBSYSTEMS=="scsi", ATTRS{type}=="3", ATTRS{vendor}=="Epson", GROUP="scanner"
SUBSYSTEMS=="scsi", ATTRS{type}=="3", ATTRS{vendor}=="EPSON", GROUP="scanner"
SUBSYSTEMS=="scsi", ATTRS{type}=="5", GROUP="cdrom"
SUBSYSTEMS=="scsi", ATTRS{type}=="6", GROUP="scanner"
SUBSYSTEMS=="scsi", ATTRS{type}=="8", GROUP="tape"
# USB devices
KERNEL=="legousbtower*", MODE="0666"
KERNEL=="lp[0-9]*", SUBSYSTEMS=="usb", GROUP="lp"
# usbfs-like devices
SUBSYSTEM=="usb_device", MODE="0664"
# iRiver music players
SUBSYSTEM=="usb_device", GROUP="plugdev", \
ATTRS{idVendor}=="4102", ATTRS{idProduct}=="10[01][135789]"
# serial devices
SUBSYSTEM=="tty", GROUP="dialout"
SUBSYSTEM=="capi", GROUP="dialout"
SUBSYSTEM=="slamr", GROUP="dialout"
SUBSYSTEM=="zaptel", GROUP="dialout"
# vc devices (all members of the tty subsystem)
KERNEL=="ptmx", MODE="0666", GROUP="root"
KERNEL=="console", MODE="0600", GROUP="root"
KERNEL=="tty", MODE="0666", GROUP="root"
KERNEL=="tty[0-9]*", GROUP="root"
KERNEL=="pty*", MODE="0666", GROUP="tty"
# video devices
SUBSYSTEM=="video4linux", GROUP="video"
SUBSYSTEM=="drm", GROUP="video"
SUBSYSTEM=="dvb", GROUP="video"
SUBSYSTEM=="em8300", GROUP="video"
SUBSYSTEM=="graphics", GROUP="video"
SUBSYSTEM=="nvidia", GROUP="video"
# misc devices
KERNEL=="random", MODE="0666"
KERNEL=="urandom", MODE="0666"
KERNEL=="mem", MODE="0640", GROUP="kmem"
KERNEL=="kmem", MODE="0640", GROUP="kmem"
KERNEL=="port", MODE="0640", GROUP="kmem"
KERNEL=="full", MODE="0666"
KERNEL=="null", MODE="0666"
KERNEL=="zero", MODE="0666"
KERNEL=="inotify", MODE="0666"
KERNEL=="sgi_fetchop", MODE="0666"
KERNEL=="sonypi", MODE="0666"
KERNEL=="agpgart", GROUP="video"
KERNEL=="nvram", GROUP="nvram"
KERNEL=="rtc|rtc[0-9]*", GROUP="audio"
KERNEL=="tpm*", MODE="0600", OWNER="tss", GROUP="tss"
KERNEL=="fuse", GROUP="fuse"
KERNEL=="kqemu", MODE="0666"
KERNEL=="kvm", GROUP="kvm"
KERNEL=="tun", MODE="0666"
KERNEL=="cdemu[0-9]*", GROUP="cdrom"
KERNEL=="pktcdvd[0-9]*", GROUP="cdrom"
KERNEL=="pktcdvd", MODE="0644"
KERNEL=="uverbs*", GROUP="rdma"
KERNEL=="ucm*", GROUP="rdma"
# printers and parallel devices
SUBSYSTEM=="printer", GROUP="lp"
SUBSYSTEM=="ppdev", GROUP="lp"
KERNEL=="irlpt*", GROUP="lp"
KERNEL=="pt[0-9]*", GROUP="tape"
KERNEL=="pht[0-9]*", GROUP="tape"
# sound devices
SUBSYSTEM=="sound", GROUP="audio"
# ieee1394 devices
KERNEL=="raw1394", GROUP="disk"
KERNEL=="dv1394*", GROUP="video"
KERNEL=="video1394*", GROUP="video"
# input devices
KERNEL=="event[0-9]*", ATTRS{name}=="*dvb*|*DVB*|* IR *" \
MODE="0664", GROUP="video"
KERNEL=="js[0-9]*", MODE="0664"
KERNEL=="lirc[0-9]*", GROUP="video"
# AOE character devices
SUBSYSTEM=="aoe", MODE="0220", GROUP="disk"
SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440"
LABEL="permissions_end"
@@ -0,0 +1,41 @@
SUBSYSTEM!="input", GOTO="persistent_input_end"
ACTION!="add", GOTO="persistent_input_end"
# ignore the mid-level drivers
KERNEL=="input[0-9]*", GOTO="persistent_input_end"
# usb devices
SUBSYSTEMS=="usb", IMPORT{program}="usb_id -x"
SUBSYSTEMS=="usb", \
ATTRS{bInterfaceClass}=="03", ATTRS{bInterfaceProtocol}=="01", \
ENV{ID_CLASS}="kbd"
SUBSYSTEMS=="usb", \
ATTRS{bInterfaceClass}=="03", ATTRS{bInterfaceProtocol}=="02", \
ENV{ID_CLASS}="mouse"
# other devices
DRIVERS=="pcspkr", ENV{ID_CLASS}="spkr"
DRIVERS=="atkbd", ENV{ID_CLASS}="kbd"
DRIVERS=="psmouse", ENV{ID_CLASS}="mouse"
ATTRS{name}=="*dvb*|*DVB*|* IR *", ENV{ID_CLASS}="ir"
# this means (ABS_X || ABS_WHEEL || ABS_THROTTLE) && !BTN_TOUCH
ATTRS{modalias}=="input:*-*a[068],*|input:*-*a*,[68],*m*", \
ATTRS{modalias}!="input:*-*k*14A,*r*", \
ENV{ID_CLASS}="joystick"
ENV{ID_SERIAL}=="", ENV{ID_SERIAL}="noserial"
# by-id links, generic and for the event devices
KERNEL=="mouse*", ENV{ID_BUS}=="?*", ENV{ID_CLASS}=="?*", \
SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_CLASS}"
KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{ID_CLASS}=="?*", \
SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-$env{ID_CLASS}"
# by-path links
IMPORT{program}="path_id %p"
KERNEL=="mouse*", ENV{ID_PATH}=="?*", \
SYMLINK+="input/by-path/$env{ID_PATH}-$env{ID_CLASS}"
KERNEL=="event*", ENV{ID_PATH}=="?*", \
SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{ID_CLASS}"
LABEL="persistent_input_end"
@@ -0,0 +1,102 @@
# This file contains the rules needed to create persistent device names.
# we are only interested in add actions for block devices
SUBSYSTEM!="block", GOTO="no_volume_id"
ACTION!="add", GOTO="no_volume_id"
# and we can safely ignore these kinds of devices
KERNEL=="ram*|loop*|fd*|nbd*|gnbd*|dm-*|md*", GOTO="no_volume_id"
# skip removable ide devices, because open(2) on them causes an events loop
KERNEL=="hd*[!0-9]", ATTR{removable}=="1", DRIVERS=="ide-cs|ide-floppy", \
GOTO="no_volume_id"
KERNEL=="hd*[0-9]", ATTRS{removable}=="1", \
GOTO="no_volume_id"
# skip xen virtual hard disks
DRIVERS=="vbd", GOTO="no_hardware_id"
# look for different kinds of unique identificators
KERNEL=="hd*[!0-9]", \
IMPORT{program}="ata_id --export $tempnode"
KERNEL=="sd*[!0-9]|sr*|st*|nst*", ATTRS{ieee1394_id}=="?*", \
ENV{ID_BUS}="ieee1394", ENV{ID_SERIAL}="$attr{ieee1394_id}"
KERNEL=="sd*[!0-9]|sr*|st*|nst*", ENV{ID_SERIAL}=="", \
IMPORT{program}="usb_id -x"
KERNEL=="sd*[!0-9]|sr*|st*|nst*", ENV{ID_SERIAL}=="", \
IMPORT{program}="scsi_id -g -x -s $devpath -d $tempnode"
KERNEL=="sd*[!0-9]|sr*|st*|nst*", ENV{ID_SERIAL}=="", \
IMPORT{program}="scsi_id -g -x -a -s $devpath -d $tempnode"
KERNEL=="sg*", ATTRS{type}=="8", ENV{ID_SERIAL}=="", \
IMPORT{program}="scsi_id -g -x -s $devpath -d $tempnode"
KERNEL=="sg*", ATTRS{type}=="8", ENV{ID_SERIAL}=="", \
IMPORT{program}="scsi_id -g -x -a -s $devpath -d $tempnode"
KERNEL=="dasd*[!0-9]", \
IMPORT{program}="dasd_id --export $tempnode"
KERNEL=="*[!0-9]", \
IMPORT{program}="edd_id --export $tempnode"
# find the physical path of the device
KERNEL=="*[!0-9]|sr*|st*", IMPORT{program}="path_id $devpath"
LABEL="no_hardware_id"
# import the variables of partitions from the parent disks
KERNEL=="*[0-9]", IMPORT{parent}="ID_*"
KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", \
SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}"
KERNEL=="hd*[0-9]", ENV{ID_SERIAL}=="?*", \
SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n"
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL_SHORT}=="?*", \
ENV{ID_VENDOR}=="ATA", \
SYMLINK+="disk/by-id/ata-$env{ID_MODEL}-$env{ID_SERIAL_SHORT}"
KERNEL=="sd*[0-9]", ENV{ID_SERIAL_SHORT}=="?*", \
ENV{ID_VENDOR}=="ATA", \
SYMLINK+="disk/by-id/ata-$env{ID_MODEL}-$env{ID_SERIAL_SHORT}-part%n"
KERNEL=="mmcblk[0-9]", ATTR{name}=="?*", ATTR{serial}=="?*", \
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", \
SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
KERNEL=="mmcblk[0-9]p[0-9]", ATTR{name}=="?*", ATTR{serial}=="?*", \
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", \
SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
KERNEL=="*[!0-9]", ENV{ID_EDD}=="?*", \
SYMLINK+="disk/by-id/edd-$env{ID_EDD}"
KERNEL=="*[0-9]", ENV{ID_EDD}=="?*", \
SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part%n"
KERNEL=="sd*[!0-9]|dasd[!0-9]*|sr*", ENV{ID_SERIAL}=="?*", \
SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", \
SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
KERNEL=="st*", ENV{ID_SERIAL}=="?*", \
SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="nst*", ENV{ID_SERIAL}=="?*", \
SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}-nst"
KERNEL=="sg*", ATTRS{type}=="8", ENV{ID_SERIAL}=="?*", \
SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="*[!0-9]|sr*", ENV{ID_PATH}=="?*", \
SYMLINK+="disk/by-path/$env{ID_PATH}"
KERNEL=="st*", ENV{ID_PATH}=="?*", \
SYMLINK+="tape/by-path/$env{ID_PATH}"
KERNEL=="sr*|st*", GOTO="no_volume_id"
KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", \
SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
# UUID and volume label
KERNEL=="*[!0-9]", ATTR{removable}=="1", GOTO="no_volume_id"
IMPORT{program}="vol_id --export $tempnode"
ENV{ID_FS_UUID}=="?*", ENV{ID_FS_USAGE}=="filesystem|other|crypto", \
SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}"
ENV{ID_FS_LABEL_SAFE}=="?*", ENV{ID_FS_USAGE}=="filesystem|other", \
SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}"
# end of processing
LABEL="no_volume_id"
@@ -0,0 +1,14 @@
# debugging monitor
RUN+="socket:/org/kernel/udev/monitor"
# run a command on remove events
ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"
# ignore the events generated by virtual consoles
KERNEL=="ptmx", OPTIONS+="last_rule"
KERNEL=="console", OPTIONS+="last_rule"
KERNEL=="tty" , OPTIONS+="last_rule"
KERNEL=="tty[0-9]*", OPTIONS+="last_rule"
KERNEL=="pty*", OPTIONS+="last_rule"
SUBSYSTEM=="vc", OPTIONS+="last_rule"
@@ -0,0 +1,101 @@
# There are a number of modifiers that are allowed to be used in some
# of the different fields. They provide the following subsitutions:
#
# %n the "kernel number" of the device.
# For example, 'sda3' has a "kernel number" of '3'
# %k the kernel name for the device
# %M the kernel major number for the device
# %m the kernel minor number for the device
# %b the bus id for the device
# %c the string returned by the PROGRAM
# %s{filename} the content of a sysfs attribute
# %% the '%' char itself
#
# workaround for devices which do not report media changes
SUBSYSTEMS=="ide", KERNEL=="hd[a-z]", ATTR{removable}=="1", \
ENV{ID_MODEL}=="IOMEGA_ZIP*", NAME="%k", OPTIONS+="all_partitions"
SUBSYSTEMS=="ide", KERNEL=="hd[a-z]", ATTRS{media}=="floppy", \
OPTIONS+="all_partitions"
# SCSI devices
SUBSYSTEMS=="scsi", KERNEL=="sr[0-9]*", NAME="scd%n", SYMLINK+="sr%n"
# USB devices
SUBSYSTEMS=="usb", KERNEL=="auer[0-9]*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="cpad[0-9]*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="dabusb*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="hiddev*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="legousbtower*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", \
ATTRS{product}=="Palm Handheld*|Handspring Visor|palmOne Handheld", \
SYMLINK+="pilot"
# usbfs-like devices
SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", ACTION=="add", \
NAME="%c"
# serial devices
KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20"
KERNEL=="capi[0-9]*", NAME="capi/%n"
# video devices
KERNEL=="dvb*", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%s $${K%%%%.*} $${K#*.}", ACTION=="add", \
NAME="%c"
KERNEL=="card[0-9]*", NAME="dri/%k"
# misc devices
KERNEL=="hw_random", NAME="hwrng"
KERNEL=="tun", NAME="net/%k"
KERNEL=="evtchn", NAME="xen/%k"
KERNEL=="cdemu[0-9]*", NAME="cdemu/%n"
KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%n"
KERNEL=="pktcdvd", NAME="pktcdvd/control"
KERNEL=="cpu[0-9]*", NAME="cpu/%n/cpuid"
KERNEL=="msr[0-9]*", NAME="cpu/%n/msr"
KERNEL=="microcode", NAME="cpu/microcode"
KERNEL=="umad*", NAME="infiniband/%k"
KERNEL=="issm*", NAME="infiniband/%k"
KERNEL=="uverbs*", NAME="infiniband/%k"
KERNEL=="ucm*", NAME="infiniband/%k"
# ALSA devices
KERNEL=="controlC[0-9]*", NAME="snd/%k"
KERNEL=="hwC[D0-9]*", NAME="snd/%k"
KERNEL=="pcmC[D0-9cp]*", NAME="snd/%k"
KERNEL=="midiC[D0-9]*", NAME="snd/%k"
KERNEL=="timer", NAME="snd/%k"
KERNEL=="seq", NAME="snd/%k"
# ieee1394 devices
KERNEL=="dv1394*", NAME="dv1394/%n"
KERNEL=="video1394*", NAME="video1394/%n"
# input devices
KERNEL=="mice", NAME="input/%k"
KERNEL=="mouse[0-9]*", NAME="input/%k"
KERNEL=="event[0-9]*", NAME="input/%k"
KERNEL=="js[0-9]*", NAME="input/%k"
KERNEL=="ts[0-9]*", NAME="input/%k"
KERNEL=="uinput", NAME="input/%k"
# Zaptel
KERNEL=="zapctl", NAME="zap/ctl"
KERNEL=="zaptimer", NAME="zap/timer"
KERNEL=="zapchannel", NAME="zap/channel"
KERNEL=="zappseudo", NAME="zap/pseudo"
KERNEL=="zap[0-9]*", NAME="zap/%n"
# AOE character devices
SUBSYSTEM=="aoe", KERNEL=="discover", NAME="etherd/%k"
SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k"
SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k"
SUBSYSTEM=="aoe", KERNEL=="revalidate", NAME="etherd/%k"
# device mapper creates its own device nodes, so ignore these
KERNEL=="device-mapper", NAME="mapper/control"
@@ -0,0 +1,198 @@
# 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.
#
# See the udev.rules.examples file for more examples of how to create rules
#
# permissions for IDE CD devices
SUBSYSTEMS=="ide", KERNEL=="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom*", NAME="%k", GROUP="cdrom", MODE="0660"
# permissions for SCSI cd/sg/tape devices
SUBSYSTEMS=="scsi", KERNEL=="s[grt][0-9]*", ATTRS{type}=="5", NAME="%k", GROUP="cdrom", MODE="0660"
# USB devices
KERNEL=="hiddev*", NAME="usb/%k"
KERNEL=="auer*", NAME="usb/%k"
KERNEL=="legousbtower*", NAME="usb/%k"
KERNEL=="dabusb*", NAME="usb/%k"
SUBSYSTEMS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k", GROUP="lp"
# CAPI devices
KERNEL=="capi", NAME="capi20", SYMLINK="isdn/capi20"
KERNEL=="capi*", NAME="capi/%n"
# Network devices
KERNEL=="tun", NAME="net/%k"
# permissions
KERNEL=="pl2303", NAME="%k", OWNER="500", GROUP="500", MODE="0666"
KERNEL=="visor", NAME="%k", OWNER="root", GROUP="uucp", MODE="0666"
KERNEL=="camera*" NAME="%k", OWNER="root", GROUP="camera", MODE="0666"
# console devices
KERNEL=="console" NAME="%k", OWNER="root", GROUP="tty", MODE="0600"
KERNEL=="tty", NAME="%k", OWNER="root", GROUP="tty", MODE="0666"
KERNEL=="tty[0-9]*", NAME="%k", OWNER="root", GROUP="tty", MODE="0660"
KERNEL=="vcs*", NAME="%k", OWNER="root", GROUP="tty", MODE="0620"
KERNEL=="tty[CIS]*", NAME="%k", OWNER="root", GROUP="uucp", MODE="0660"
KERNEL=="ttyUB[0-9]", NAME="%k", OWNER="root", GROUP="uucp", MODE="0660"
KERNEL=="ttyUSB0", NAME="%k", OWNER="root", GROUP="uucp", MODE="0660"
KERNEL=="ttyUSB1", NAME="%k", OWNER="root" GROUP="uucp", MODE="0666"
# pty devices
KERNEL=="ptmx" NAME="%k", OWNER="root", GROUP="tty", MODE="0666"
KERNEL=="pty[p-za-e][0-9a-f]*" NAME="%k", OWNER="root", GROUP="tty", MODE="0666"
KERNEL=="tty[p-za-e][0-9a-f]*" NAME="%k", OWNER="root", GROUP="tty", MODE="0666"
KERNEL=="cu[abiu]*" NAME="%k", OWNER="root", GROUP="uucp", MODE="0660"
# sound devices
KERNEL=="audio*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="beep" NAME="%k", OWNER="root", GROUP="audio", MODE="0644"
KERNEL=="dsp*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="midi*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="mixer*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="music" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="sequencer*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="controlC[0-9]*", NAME="snd/%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="hw[CD0-9]*", NAME="snd/%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="pcm[CD0-9cp]*", NAME="snd/%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="midiC[D0-9]*", NAME="snd/%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="timer", NAME="snd/%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="seq", NAME="snd/%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="sndstat" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="speaker" NAME="%k", OWNER="root", GROUP="audio", MODE="0644"
KERNEL=="sound/*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="admmidi*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="adsp*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="aload*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="amidi*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
KERNEL=="amixer*" NAME="%k", OWNER="root", GROUP="audio", MODE="0666"
# input devices (mouse, joystick, etc)
KERNEL=="mice", NAME="input/%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="mouse*", NAME="input/%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="event*", NAME="input/%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="js*", NAME="input/%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="ts*", NAME="input/%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="input/js*" NAME="%k", OWNER="root", GROUP="games",0 MODE="0666"
KERNEL=="djs[0-3]" NAME="%k", OWNER="root", GROUP="games", MODE="0660"
KERNEL=="psaux" NAME="%k", OWNER="root", GROUP="sys", MODE="0660"
KERNEL=="crash" NAME="%k", OWNER="root", GROUP="root", MODE="0660"
KERNEL=="logibm" NAME="%k", OWNER="root", GROUP="sys", MODE="0660"
KERNEL=="jbm" NAME="%k", OWNER="root", GROUP="sys", MODE="0660"
KERNEL=="hwtrap" NAME="%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="inportbm" NAME="%k", OWNER="root", GROUP="sys", MODE="0660"
KERNEL=="sexec" NAME="%k", OWNER="root", GROUP="root", MODE="0660"
KERNEL=="jsflash" NAME="%k", OWNER="root", GROUP="root", MODE="0660"
# power manager device
KERNEL=="apm_bios" NAME="%k", OWNER="root", GROUP="root", MODE="0644"
# printer device
KERNEL=="lp[0-9]" NAME="%k", OWNER="root", GROUP="lp", MODE="0660"
KERNEL=="parport*" NAME="%k", OWNER="root", GROUP="lp", MODE="0660"
# video devices
KERNEL=="card*" NAME="dri/card%n", OWNER="root", GROUP="video", MODE="0666"
KERNEL=="fb[0-9]" NAME="%k", OWNER="root", GROUP="video", MODE="0660"
KERNEL=="agpgart" NAME="%k", OWNER="root", GROUP="video", MODE="0660"
KERNEL=="nvidia*" NAME="%k", OWNER="root", GROUP="video", MODE="0666"
KERNEL=="video*" NAME="%k", OWNER="root", GROUP="video", MODE="0660"
KERNEL=="vbi*" NAME="%k", OWNER="root", GROUP="video", MODE="0660"
KERNEL=="dvb*", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; A=$${K%%%%.*}; D=$${K#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video", MODE="0660"
# DISK devices
KERNEL=="ed[ab]*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="gscd0" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="initrd" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="lmscd" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="mcd*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="md*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="mtd*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="userdma" NAME="%k", OWNER="root", GROUP="root", MODE="0660"
# floppy devices
KERNEL=="fd[0-3]*" NAME="%k", OWNER="root", GROUP="floppy", MODE="0660"
KERNEL=="fd0" SYMLINK="floppy"
# permissions for removable devices like cardreaders or sticks
KERNEL=="sd*", ATTRS{scsi_level}=="3", ATTRS{type}=="0", NAME="%k", GROUP="storage"
# permissions for firewire external drives
KERNEL=="sd*", ATTRS{scsi_level}=="5", NAME="%k", GROUP="storage"
# permissions for usb to scsi external adapters
KERNEL=="sd*", ATTRS{scsi_level}=="3", ATTRS{type}=="7", NAME="%k", GROUP="storage"
# IDE devices (hd, cdrom)
KERNEL=="hd*" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
KERNEL=="ht0" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
# RAID IDE
KERNEL=="ataraid[0-9]*" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
KERNEL=="ataraid/*" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
# SCSI devices
KERNEL=="scsi/*/cd" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
KERNEL=="scsi/*" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
KERNEL=="sd[a-h]*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="s[rt][0-9]*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="scd*" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
# generic scsi devices
KERNEL=="sg*" NAME="%k", OWNER="root", GROUP="root", MODE="0600"
# old CD-ROM
KERNEL=="sbpcd*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
# loop devices
KERNEL=="loop[0-9]*" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
# network block devices
KERNEL=="nb[0-7]" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
KERNEL=="nht0" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="npt[0-3]" NAME="%k", OWNER="root", GROUP="disk", MODE="0660"
KERNEL=="n[qrs]*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
# memory access devices
KERNEL=="kmem" NAME="%k", OWNER="root", GROUP="kmem", MODE="0640"
KERNEL=="mem" NAME="%k", OWNER="root", GROUP="kmem", MODE="0640"
KERNEL=="null" NAME="%k", OWNER="root", GROUP="sys", MODE="0666"
KERNEL=="nvram" NAME="%k", OWNER="root", GROUP="root", MODE="0640"
KERNEL=="port" NAME="%k", OWNER="root", GROUP="kmem", MODE="0640"
KERNEL=="ram[0-9]*" NAME="%k", OWNER="root", GROUP="disk", MODE="0640"
KERNEL=="random" NAME="%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="rtc" NAME="%k", OWNER="root", GROUP="root", MODE="0444"
KERNEL=="urandom" NAME="%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="full" NAME="%k", OWNER="root", GROUP="sys", MODE="0666"
KERNEL=="zero" NAME="%k", OWNER="root", GROUP="root", MODE="0666"
KERNEL=="raw[0-9]*" NAME="raw/%k", OWNER="root", GROUP="disk", MODE="0660"
KERNEL=="modreq" NAME="%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="msr" NAME="%k", OWNER="root", GROUP="root", MODE="0660"
KERNEL=="profile*" NAME="%k", OWNER="root", GROUP="root", MODE="0640"
# ISDN devices
KERNEL=="isdn*" NAME="%k", OWNER="root", GROUP="tty", MODE="0660"
# net devices
KERNEL=="ippp*" NAME="%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="ipstate*" NAME="%k", OWNER="root", GROUP="root", MODE="0660"
KERNEL=="spx" NAME="%k", OWNER="root", GROUP="root", MODE="0644"
KERNEL=="fwmonitor*" NAME="%k", OWNER="root", GROUP="root", MODE="0660"
# hotplug rules - module autoloading for different buses
ACTION=="add", SUBSYSTEM=="pci", ENV{MODALIAS}=="*", RUN+="/sbin/modprobe $env{MODALIAS}"
ACTION=="add", SUBSYSTEM=="usb", ENV{MODALIAS}=="*", RUN+="/sbin/modprobe $env{MODALIAS}"
ACTION=="add", SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="*", RUN+="/sbin/modprobe $env{MODALIAS}"
ACTION=="add", SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="*", RUN+="/bin/sh -c 'echo 1 > /sys/$DEVPATH/allow_func_id_match'"
ACTION=="add", SUBSYSTEM=="ieee1394", ENV{MODALIAS}=="*", RUN+="/sbin/modprobe $env{MODALIAS}"
ACTION=="add", SUBSYSTEM=="scsi", ATTRS{type}=="[07]", RUN+="/sbin/modprobe sd_mod"
ACTION=="add", SUBSYSTEM=="scsi", ATTRS{type}=="14", RUN+="/sbin/modprobe sd_mod"
ACTION=="add", SUBSYSTEM=="scsi", ATTRS{type}=="[45]", RUN+="/sbin/modprobe sr_mod"
ACTION=="add", SUBSYSTEM=="scsi", ATTRS{type}=="1", ATTRS{vendor}=="Onstream", ATTRS{model}!="ADR*", RUN+="/sbin/modprobe osst"
ACTION=="add", SUBSYSTEM=="scsi", ATTRS{type}=="1", ATTRS{vendor}=="Onstream", ATTRS{model}=="ADR*", RUN+="/sbin/modprobe st"
ACTION=="add", SUBSYSTEM=="scsi", ATTRS{type}=="1", ATTRS{vendor}!="Onstream", RUN+="/sbin/modprobe st"
ACTION=="add", SUBSYSTEM=="scsi", ATTRS{type}=="[23689]", RUN+="/sbin/modprobe sg"
# firmware
ACTION=="add", SUBSYSTEM=="firmware", ENV{FIRMWARE}=="*", RUN+="/lib/udev/firmware.sh"
@@ -0,0 +1,15 @@
# device mapper links hook into "online" event, when the dm table
# is available, while some table types must be ignored
KERNEL=="dm-*", ACTION=="add|online", GOTO="device_mapper_do"
GOTO="device_mapper_end"
LABEL="device_mapper_do"
PROGRAM!="/sbin/dmsetup status -j %M -m %m", GOTO="device_mapper_end"
RESULT=="|*snapshot*|*error*", GOTO="device_mapper_end"
IMPORT{program}="/sbin/vol_id --export $tempnode"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}"
LABEL="device_mapper_end"
@@ -0,0 +1,9 @@
# ignore these events until someone needs them
SUBSYSTEM=="drivers", OPTIONS="ignore_device"
SUBSYSTEM=="module", OPTIONS="ignore_device"
# sysfs is populated after the event is sent
ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus"
ACTION=="add", KERNEL=="[0-9]*:[0-9]*", SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt"
ACTION=="add", SUBSYSTEM=="net", WAIT_FOR_SYSFS="address"
ACTION=="add", SUBSYSTEM=="net", ENV{PHYSDEVDRIVER}=="?*", WAIT_FOR_SYSFS="device/driver"
@@ -0,0 +1,263 @@
# /etc/udev/rules/50-udev.rules: device naming rules for udev
#
# Gentoo specific rules
#
# 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.
#
# Try not to modify this file, if you wish to change things, create a new rule
# file that can be run before this one.
#
# Net devices can have arbitrary names, even
# ones set by the user. Not try to match normal
# rules on net devices (Bug #166652)
SUBSYSTEM=="net", GOTO="gentoo_device_rules_end"
# console
KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", OPTIONS="last_rule"
KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", OPTIONS="last_rule"
KERNEL=="vcs*", NAME="%k", GROUP="tty", OPTIONS="last_rule"
KERNEL=="vcsa*", NAME="%k", GROUP="tty", OPTIONS="last_rule"
KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666", OPTIONS="last_rule"
KERNEL=="tty[0-9]", NAME="%k", GROUP="tty", OPTIONS="last_rule"
KERNEL=="tty[0-9][0-9]", NAME="%k", GROUP="tty", OPTIONS="last_rule"
KERNEL=="console", NAME="%k", GROUP="tty", MODE="0600"
KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="0666"
# tty devices
KERNEL=="ttyS[0-9]*", NAME="%k", SYMLINK="tts/%n", GROUP="uucp", MODE="0660"
KERNEL=="ttyUSB[0-9]*", NAME="%k", SYMLINK="tts/USB%n", GROUP="uucp", MODE="0660"
KERNEL=="ippp0", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="isdn*" NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="dcbri*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="ircomm*", NAME="%k", GROUP="uucp", MODE="0660"
# all block devices
SUBSYSTEM=="block", GROUP="disk"
# cdrom symlinks and other good cdrom naming
KERNEL=="sr[0-9]*|hd[a-z]|pcd[0-9]*", ACTION=="add", IMPORT{program}="cdrom_id --export $tempnode"
ENV{ID_CDROM}=="?*", GROUP="cdrom"
SUBSYSTEM=="block", KERNEL=="sr[0-9]*", SYMLINK+="scd%n"
# assign cdrom-permission also to associated generic device (for cd-burning ...)
KERNEL=="sg[0-9]*", ACTION=="add", ATTRS{type}=="4|5", GROUP="cdrom"
# disk devices
KERNEL=="sd*", NAME="%k", GROUP="disk"
KERNEL=="dasd*", NAME="%k", GROUP="disk"
KERNEL=="ataraid*", NAME="%k", GROUP="disk"
# compaq smart array
KERNEL=="cciss*", NAME="%k"
KERNEL=="ida*", NAME="%k"
# mylex
KERNEL=="rd*", NAME="%k"
# dri devices
KERNEL=="card*", NAME="dri/card%n", GROUP="video"
KERNEL=="nvidia*", NAME="%k", GROUP="video"
KERNEL=="3dfx*", NAME="%k", GROUP="video"
# alsa devices
SUBSYSTEM=="sound", GROUP="audio"
KERNEL=="controlC[0-9]*", NAME="snd/%k"
KERNEL=="hw[CD0-9]*", NAME="snd/%k"
KERNEL=="pcm[CD0-9cp]*", NAME="snd/%k"
KERNEL=="midiC[D0-9]*", NAME="snd/%k"
KERNEL=="timer", NAME="snd/%k"
KERNEL=="seq", NAME="snd/%k"
# capi devices
KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20", GROUP="uucp", MODE="0660"
KERNEL=="capi*", NAME="capi/%n", GROUP="uucp", MODE="0660"
# cpu devices
KERNEL=="cpu[0-9]*", NAME="cpu/%n/cpuid"
KERNEL=="msr[0-9]*", NAME="cpu/%n/msr"
KERNEL=="microcode", NAME="cpu/microcode"
# fb devices
KERNEL=="fb[0-9]*", NAME="fb/%n", SYMLINK+="%k", GROUP="video"
# floppy devices
KERNEL=="fd[0-9]*", NAME="floppy/%k", SYMLINK+="%k", GROUP="floppy"
KERNEL=="fd[0-9]*", ACTION=="add", ATTRS{cmos}=="*", RUN+="create_floppy_devices -c -t $attr{cmos} -m %M -M 0660 -G floppy $root/floppy/%k"
KERNEL=="fd[0-9]*", ACTION=="remove", RUN+="/bin/sh -c 'rm -f $root/floppy/%k?*'"
# i2c devices
KERNEL=="i2c-[0-9]*", NAME="i2c/%n", SYMLINK+="%k"
# input devices
KERNEL=="mice", NAME="input/%k", MODE="0644"
KERNEL=="mouse*", NAME="input/%k", MODE="0644"
KERNEL=="event*", NAME="input/%k", MODE="0600"
KERNEL=="js*", NAME="input/%k", MODE="0664"
KERNEL=="ts*", NAME="input/%k", MODE="0600"
# loop devices
KERNEL=="loop[0-9]*", NAME="loop/%n", SYMLINK+="%k", GROUP="disk"
# md block devices
KERNEL=="md[0-9]*", NAME="md/%n", SYMLINK+="%k", GROUP="disk"
# aoe char devices,
SUBSYSTEM=="aoe", KERNEL=="discover", NAME="etherd/%k", GROUP="disk", MODE="0220"
SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k", GROUP="disk", MODE="0440"
SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k", GROUP="disk", MODE="0220"
# misc devices
KERNEL=="agpgart", NAME="misc/%k", SYMLINK+="%k"
KERNEL=="psaux", NAME="misc/%k", SYMLINK+="%k"
KERNEL=="rtc", NAME="misc/%k", SYMLINK+="%k", MODE="0664"
KERNEL=="uinput", NAME="misc/%k", SYMLINK+="%k"
KERNEL=="inotify", NAME="misc/%k", SYMLINK+="%k", MODE="0666"
# netlink devices
KERNEL=="route", NAME="netlink/%k"
KERNEL=="skip", NAME="netlink/%k"
KERNEL=="usersock", NAME="netlink/%k"
KERNEL=="fwmonitor", NAME="netlink/%k"
KERNEL=="tcpdiag", NAME="netlink/%k"
KERNEL=="nflog", NAME="netlink/%k"
KERNEL=="xfrm", NAME="netlink/%k"
KERNEL=="arpd", NAME="netlink/%k"
KERNEL=="route6", NAME="netlink/%k"
KERNEL=="ip6_fw", NAME="netlink/%k"
KERNEL=="dnrtmsg", NAME="netlink/%k"
KERNEL=="tap*", NAME="netlink/%k"
# network devices
KERNEL=="tun", NAME="net/%k", MODE="0660", OPTIONS+="ignore_remove"
KERNEL=="ppp", MODE="0600", OPTIONS+="ignore_remove"
# ramdisk devices
KERNEL=="ram[0-9]*", NAME="rd/%n", SYMLINK+="%k"
# IEEE1394 (firewire) devices (must be before raw devices below)
KERNEL=="raw1394", NAME="%k", GROUP="video"
KERNEL=="dv1394*", NAME="dv1394/%n", GROUP="video"
KERNEL=="video1394*", NAME="video1394/%n", GROUP="video"
# raw devices
SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", NAME="raw/%k", GROUP="disk"
KERNEL=="ram*", NAME="%k", GROUP="disk"
# sound devices
KERNEL=="adsp", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="adsp[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="audio", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="audio[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="dsp", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="dsp[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="mixer", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="mixer[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="sequencer", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
KERNEL=="sequencer[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio"
# memory devices
KERNEL=="random", NAME="%k", MODE="0666"
KERNEL=="urandom", NAME="%k", MODE="0444"
KERNEL=="mem", NAME="%k", MODE="0640"
KERNEL=="kmem", NAME="%k", MODE="0640"
KERNEL=="port", NAME="%k", MODE="0640"
KERNEL=="full", NAME="%k", MODE="0666"
KERNEL=="null", NAME="%k", MODE="0666"
KERNEL=="zero", NAME="%k", MODE="0666"
# usb devices
KERNEL=="hiddev*", NAME="usb/%k"
KERNEL=="auer*", NAME="usb/%k"
KERNEL=="legousbtower*", NAME="usb/%k", GROUP="usb"
KERNEL=="dabusb*", NAME="usb/%k"
KERNEL=="lp[0-9]*", SUBSYSTEM=="usb", NAME="usb/%k", GROUP="lp"
# v4l devices
KERNEL=="video[0-9]*", NAME="v4l/video%n", SYMLINK+="video%n", GROUP="video"
KERNEL=="radio[0-9]*", NAME="v4l/radio%n", SYMLINK+="radio%n", GROUP="video"
KERNEL=="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK+="vbi%n", GROUP="video"
KERNEL=="vtx[0-9]*", NAME="v4l/vtx%n", GROUP="video"
# dvb devices
SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%s $${K%%%%.*} $${K#*.}'", NAME="%c", GROUP="video"
# Asterisk Zaptel devices
KERNEL=="zapctl", NAME="zap/ctl"
KERNEL=="zaptimer", NAME="zap/timer"
KERNEL=="zapchannel", NAME="zap/channel"
KERNEL=="zappseudo", NAME="zap/pseudo"
KERNEL=="zap[0-9]*", NAME="zap/%n"
# pilot/palm devices
KERNEL=="pilot", NAME="%k", GROUP="uucp"
# jaz devices
KERNEL=="jaz*", NAME="%k", GROUP="disk"
# zip devices
KERNEL=="pocketzip*", NAME="%k", GROUP="disk"
KERNEL=="zip*", NAME="%k", GROUP="disk"
# ls120 devices
KERNEL=="ls120", NAME="%k", GROUP="disk"
# lp devices
KERNEL=="lp*", NAME="%k", GROUP="lp"
KERNEL=="irlpt", NAME="%k", GROUP="lp"
KERNEL=="usblp", NAME="%k", GROUP="lp"
KERNEL=="lp*", NAME="%k", GROUP="lp"
KERNEL=="parport*", NAME="%k", GROUP="lp"
# tape devices
KERNEL=="ht*", NAME="%k", GROUP="tape"
KERNEL=="nht*", NAME="%k", GROUP="tape"
KERNEL=="pt*", NAME="%k", GROUP="tape"
KERNEL=="npt*", NAME="%k", GROUP="tape"
KERNEL=="st*", NAME="%k", GROUP="tape"
KERNEL=="nst*", NAME="%k", GROUP="tape"
KERNEL=="osst*", NAME="%k", GROUP="tape"
KERNEL=="nosst*", NAME="%k", GROUP="tape"
# diskonkey devices
KERNEL=="diskonkey*", NAME="%k", GROUP="disk"
# rem_ide devices
KERNEL=="microdrive*", NAME="%k", GROUP="disk"
# kbd devices
KERNEL=="kbd", NAME="%k", MODE="0664"
# Sony Vaio Jogdial sonypi device
KERNEL=="sonypi", NAME="%k", MODE="0666"
# packet devices
KERNEL=="pktcdvd", NAME="pktcdvd/control", GROUP="cdrw", MODE="0660"
KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/pktcdvd%n", GROUP="cdrw", MODE="0660"
# infiniband devices
KERNEL=="umad*", NAME="infiniband/%k"
KERNEL=="issm*", NAME="infiniband/%k"
# usbfs-like device nodes
# the way to go up to kernel 2.6.21 (and above if setting USB_DEVICE_CLASS=y)
SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", NAME="%c", GROUP="usb", MODE="0664"
# starting from kernel 2.6.22 use this rule
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \
NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", GROUP="usb", MODE="0664"
# Timeouts for scsi devices
# Setting timeout for tape-devices (type 1) to 900 seconds
# and 60 seconds for device types 0, 7 and 14
# if you need timeouts for other devices add a similar rule
# with correct type-value, or open a bug on bugs.gentoo.org.
SUBSYSTEM=="scsi", KERNEL=="[0-9]*:[0-9]*", ACTION=="add", ATTR{type}=="0|7|14", ATTR{timeout}="60"
SUBSYSTEM=="scsi", KERNEL=="[0-9]*:[0-9]*", ACTION=="add", ATTR{type}=="1", ATTR{timeout}="900"
# Load firmware
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware.sh"
LABEL="gentoo_device_rules_end"
@@ -0,0 +1,54 @@
# /etc/udev/rules/80-hotplug.rules: module loading rules for udev
#
# Gentoo specific rules
#
# 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.
#
# Try not to modify this file, if you wish to change things, create a new rule
# file that can be run before this one.
#
# Module autoloading
ACTION!="add", GOTO="hotplug_load_end"
# check if the device has already been claimed by a driver
ENV{DRIVER}=="?*", SUBSYSTEM!="input", GOTO="hotplug_load_end"
# this driver is broken and should not be loaded automatically
SUBSYSTEM=="platform", ENV{MODALIAS}=="i82365", GOTO="hotplug_load_end"
# Autoload modules that lack aliases but have them defined in autoload modules
ENV{MODALIAS}=="?*", RUN{ignore_error}+="modprobe.sh $env{MODALIAS}"
# /etc/modprobe.conf.
SUBSYSTEM=="pnp", ENV{MODALIAS}!="?*", RUN{ignore_error}+="/bin/sh -c 'while read id; do /lib/udev/modprobe.sh pnp:d$$id; done < /sys$devpath/id'"
# needed aliases are defined in /etc/modprobe.d/pnp-aliases
SUBSYSTEM=="i2o", RUN+="modprobe.sh i2o_block"
SUBSYSTEM=="mmc", RUN+="modprobe.sh mmc_block"
SUBSYSTEM=="tifm", RUN+="modprobe.sh tifm_sd"
SUBSYSTEM=="tifm", RUN+="modprobe.sh tifm_ms"
SUBSYSTEM=="ide", ATTR{media}=="tape", RUN+="modprobe.sh ide-scsi"
# Load driver for scsi-device
SUBSYSTEM!="scsi_device", GOTO="hotplug_scsi_end"
# Parts taken from redhat-rules
# sd: 0 TYPE_DISK, 7 TYPE_MOD, 14 TYPE_RBC
# sr: 4 TYPE_WORM, 5 TYPE_ROM
# st/osst: 1 TYPE_TAPE
ATTRS{type}=="?*", TEST!="[module/sg]", RUN+="modprobe.sh sg"
ATTRS{type}=="0|7|14", RUN+="modprobe.sh sd_mod"
ATTRS{type}=="4|5", RUN+="modprobe.sh sr_mod"
ATTRS{type}=="8", RUN+="modprobe.sh ch"
ATTRS{type}=="1", ATTRS{vendor}=="On[sS]tream", \
ATTRS{model}!="ADR*", RUN+="modprobe.sh osst", GOTO="hotplug_scsi_end"
ATTRS{type}=="1", RUN+="modprobe.sh st"
LABEL="hotplug_scsi_end"
LABEL="hotplug_load_end"
@@ -0,0 +1,18 @@
# /etc/udev/rules/95-udev-late.rules: device naming rules for udev
#
# Gentoo specific rules
#
# 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.
#
# Try not to modify this file, if you wish to change things, create a new rule
# file that can be run before this one.
#
# Activate our network if we can
SUBSYSTEM=="net", ACTION=="add", RUN+="net.sh %k start"
SUBSYSTEM=="net", ACTION=="remove", RUN+="net.sh %k stop"
# event to be catched by udevmonitor
RUN+="socket:/org/kernel/udev/monitor"
@@ -0,0 +1,8 @@
# sysfs is populated after the event is sent
ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus"
ACTION=="add", SUBSYSTEM=="net", WAIT_FOR_SYSFS="address"
ACTION=="add", SUBSYSTEM=="?*", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}"
# pnp devices
ACTION=="add", SUBSYSTEM=="pnp", ATTR{id}=="?*", RUN+="/sbin/modprobe pnp:d$attr{id}"
ACTION=="add", SUBSYSTEM=="firmware", ENV{FIRMWARE}=="*", RUN="/sbin/firmware_helper", OPTIONS="last_rule"
@@ -0,0 +1,322 @@
# 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"
#
KERNEL=="*", OWNER="root", GROUP="root", MODE="0600"
# all block devices
SUBSYSTEM=="block", GROUP="disk", MODE="0640"
KERNEL=="root", GROUP="disk", MODE="0640"
# console devices
KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666"
KERNEL=="console", NAME="%k", MODE="0600"
KERNEL=="tty[0-9]*", NAME="%k", GROUP="tty", MODE="0660"
KERNEL=="vc/[0-9]*", NAME="%k", GROUP="tty", MODE="0660"
# pty devices
# Set this to 0660 if you only want users belonging to tty group
# to be able to allocate PTYs
KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="666"
KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="660"
KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="660"
KERNEL=="pty/m*", NAME="%k", GROUP="tty", MODE="0660"
# serial+dialup devices
KERNEL=="ippp*", NAME="%k", MODE="0660"
KERNEL=="isdn*", NAME="%k", MODE="0660"
KERNEL=="isdnctrl*", NAME="%k", MODE="0660"
KERNEL=="capi", NAME="capi20", GROUP="uucp", MODE="0660"
KERNEL=="capi*", NAME="capi/%n", GROUP="uucp", MODE="0660"
KERNEL=="dcbri*", NAME="%k", MODE="0660"
KERNEL=="ircomm*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="tts/[0-9]*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="tts/USB[0-9]*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="tty[A-Z]*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="pppox*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="ircomm*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="modems/mwave*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="hvc*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="hvsi*", NAME="%k", GROUP="uucp", MODE="0660"
KERNEL=="iseries/vtty*", NAME="%k", GROUP="uucp", MODE="0660"
# vc devices
KERNEL=="vcs", NAME="%k", OWNER="vcsa", GROUP="tty"
KERNEL=="vcs[0-9]*", NAME="%k", OWNER="vcsa", GROUP="tty"
KERNEL=="vcsa", NAME="%k", OWNER="vcsa", GROUP="tty"
KERNEL=="vcsa[0-9]*", NAME="%k", OWNER="vcsa", GROUP="tty"
KERNEL=="vcc/*", NAME="%k", OWNER="vcsa", GROUP="tty"
# memory devices
KERNEL=="random", MODE="0666"
KERNEL=="urandom", MODE="0444"
KERNEL=="mem", GROUP="kmem", MODE="0640"
KERNEL=="kmem", GROUP="kmem", MODE="0640"
KERNEL=="port", GROUP="kmem", MODE="0640"
KERNEL=="full", MODE="0666"
KERNEL=="null", MODE="0666"
KERNEL=="zero", MODE="0666"
# 183 = /dev/hwrng Generic random number generator
KERNEL=="hw_random", NAME="hwrng", SYMLINK+="%k"
# misc devices
KERNEL=="nvram", MODE="0660"
KERNEL=="rtc", MODE="0644"
# floppy devices
KERNEL=="fd[01]*", GROUP="floppy", MODE="0660"
# fix floppy devices
KERNEL=="nvram", ACTION=="add", RUN+="load_floppy_module.sh"
KERNEL=="fd[0-9]*", ACTION=="add", ATTRS{cmos}=="*", \
RUN+="create_floppy_devices -c -t $attr{cmos} -m %M /dev/%k"
KERNEL=="fd[0-9]*", ACTION=="remove", RUN+="/bin/sh -c 'rm -f /dev/%k*'"
BUS=="usb", KERNEL=="sd*", ATTRS{bInterfaceClass}=="08", \
ATTRS{bInterfaceSubClass}=="04", GROUP="floppy", MODE="0660", \
SYMLINK+="floppy floppy-%k"
# audio devices
KERNEL=="dsp*", MODE="0660"
KERNEL=="audio*", MODE="0660"
KERNEL=="midi*", MODE="0660"
KERNEL=="mixer*", MODE="0660"
KERNEL=="sequencer*", MODE="0660"
KERNEL=="sound/*", MODE="0660"
KERNEL=="snd/*", MODE="0660"
KERNEL=="beep", MODE="0660"
KERNEL=="admm*", MODE="0660"
KERNEL=="adsp*", MODE="0660"
KERNEL=="aload*", MODE="0660"
KERNEL=="amidi*", MODE="0660"
KERNEL=="dmfm*", MODE="0660"
KERNEL=="dmmidi*", MODE="0660"
KERNEL=="sndstat", MODE="0660"
# lp devices
KERNEL=="lp*", GROUP="lp", MODE="0660"
KERNEL=="parport*", GROUP="lp", MODE="0660"
KERNEL=="irlpt*", GROUP="lp", MODE="0660"
KERNEL=="usblp*", GROUP="lp", MODE="0660"
KERNEL=="usb/lp*", GROUP="lp", MODE="0660"
# tape devices
SUBSYSTEM=="ide", ATTRS{media}=="tape", ACTION=="add", \
RUN+="/sbin/modprobe ide-scsi idescsi_nocd=1"
KERNEL=="ht*", GROUP="disk", MODE="0660"
KERNEL=="nht*", GROUP="disk", MODE="0660"
KERNEL=="pt[0-9]*", GROUP="disk", MODE="0660"
KERNEL=="npt*", GROUP="disk", MODE="0660"
KERNEL=="st*", GROUP="disk", MODE="0660"
KERNEL=="nst*", GROUP="disk", MODE="0660"
KERNEL=="osst*", GROUP="disk", MODE="0660"
KERNEL=="nosst*", GROUP="disk", MODE="0660"
# diskonkey devices
KERNEL=="diskonkey*", GROUP="disk", MODE="0640"
# rem_ide devices
KERNEL=="microdrive*", GROUP="disk", MODE="0640"
# kbd devices
KERNEL=="kbd", MODE="0644"
# joystick devices
KERNEL=="js[0-9]*", MODE="0644"
KERNEL=="djs[0-9]*", MODE="0644"
# v4l devices
KERNEL=="video*", MODE="0660"
KERNEL=="radio*", MODE="0660"
KERNEL=="winradio*", MODE="0660"
KERNEL=="vtx*", MODE="0660"
KERNEL=="vbi*", MODE="0660"
KERNEL=="video/*", MODE="0660"
KERNEL=="vttuner", MODE="0660"
KERNEL=="v4l/*", MODE="0660"
# input devices
KERNEL=="input/*", MODE="0660"
# gpm devices
KERNEL=="gpmctl", MODE="0700"
# dri devices
KERNEL=="nvidia*", MODE="0660"
KERNEL=="3dfx*", MODE="0660"
KERNEL=="card[0-9]*", NAME="dri/%k", MODE="0666"
# usb devices
KERNEL=="usb/dabusb*", MODE="0660"
KERNEL=="usb/mdc800*", MODE="0660"
KERNEL=="usb/rio500", MODE="0660"
# s390 devices
KERNEL=="z90crypt", MODE="0666"
KERNEL=="slram[0-9]*", SYMLINK+="xpram%n"
# DVB
KERNEL=="dvb", MODE="0660"
SUBSYSTEM=="dvb", \
PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%s $${K%%%%.*} $${K#*.}'", \
NAME="%c", MODE="0660"
KERNEL=="dm-[0-9]*", ACTION=="add", OPTIONS+="ignore_device"
# alsa devices
KERNEL=="controlC[0-9]*", NAME="snd/%k"
KERNEL=="hw[CD0-9]*", NAME="snd/%k"
KERNEL=="pcm[CD0-9cp]*", NAME="snd/%k"
KERNEL=="midi[CD0-9]*", NAME="snd/%k"
KERNEL=="timer", NAME="snd/%k"
KERNEL=="seq", NAME="snd/%k"
# input devices
KERNEL=="mice", NAME="input/%k"
KERNEL=="mouse*", NAME="input/%k"
KERNEL=="event*", NAME="input/%k"
KERNEL=="js*", NAME="input/%k", SYMLINK+="%k"
KERNEL=="ts*", NAME="input/%k"
KERNEL=="uinput", NAME="input/%k"
# IEEE1394 (firewire) devices (must be before raw devices below)
KERNEL=="raw1394", NAME="%k"
KERNEL=="dv1394*", NAME="dv1394/%n"
KERNEL=="video1394*", NAME="video1394/%n"
KERNEL=="fw*", PROGRAM="fw_unit_symlinks.sh %k %n", SYMLINK+="$result"
KERNEL=="raw[0-9]*", NAME="raw/%k"
KERNEL=="lp[0-9]*", SYMLINK+="par%n"
BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k"
KERNEL=="microcode", NAME="cpu/%k"
KERNEL=="msr[0-9]*", NAME="cpu/%n/msr"
KERNEL=="cpu[0-9]*", NAME="cpu/%n/cpuid"
KERNEL=="ram1", SYMLINK+="ram"
KERNEL=="video0", SYMLINK+="video"
KERNEL=="radio0", SYMLINK+="radio"
KERNEL=="audio0", SYMLINK+="audio"
KERNEL=="dsp0", SYMLINK+="dsp"
KERNEL=="fb0", SYMLINK+="fb"
KERNEL=="qft0", SYMLINK+="ftape"
KERNEL=="isdnctrl0", SYMLINK+="isdnctrl"
KERNEL=="mixer0", SYMLINK+="mixer"
KERNEL=="ram0", SYMLINK+="ramdisk"
KERNEL=="sbpcd0", SYMLINK+="sbpcd"
KERNEL=="radio0", SYMLINK+="radio"
KERNEL=="tty0", SYMLINK+="systty"
KERNEL=="vbi0", SYMLINK+="vbi"
KERNEL=="null", SYMLINK+="XOR"
KERNEL=="tun", NAME="net/%k", MODE="0666"
KERNEL=="device-mapper", NAME="mapper/control"
# old compat symlinks with enumeration
KERNEL=="sr[0-9]*", SYMLINK+="cdrom cdrom-%k"
KERNEL=="scd[0-9]*", SYMLINK+="cdrom cdrom-%k"
KERNEL=="pcd[0-9]*", SYMLINK+="cdrom cdrom-%k"
KERNEL=="fd[0-9]*", SYMLINK+="floppy floppy-%k"
KERNEL=="nst[0-9]", BUS=="scsi", SYMLINK+="tape tape-%k", MODE="0660"
KERNEL=="nosst[0-9]", BUS=="scsi", SYMLINK+="tape tape-%k", MODE="0660"
# Section for zaptel device
KERNEL=="zapctl", NAME="zap/ctl"
KERNEL=="zaptimer", NAME="zap/timer"
KERNEL=="zapchannel", NAME="zap/channel"
KERNEL=="zappseudo", NAME="zap/pseudo"
KERNEL=="zap[0-9]*", NAME="zap/%n"
KERNEL=="pktcdvd", NAME="%k/control"
KERNEL=="hd*[!0-9]", ATTR{removable}=="1", \
ATTR{media}=="floppy", \
SYMLINK+="floppy floppy-%k", OPTIONS+="ignore_remove, all_partitions"
KERNEL=="hd*[0-9]", ATTRS{media}=="floppy", ATTRS{removable}=="1", \
SYMLINK+="floppy-%k"
KERNEL=="hd[a-z]", BUS=="ide", ATTRS{removable}=="1", ATTRS{media}=="cdrom", \
SYMLINK+="cdrom cdrom-%k"
KERNEL=="hd[a-z]", BUS=="ide", ATTRS{removable}=="1", \
PROGRAM=="check-cdrom.sh %k DVD", SYMLINK+="dvd dvd-%k"
KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="check-cdrom.sh %k DVD", \
SYMLINK+="dvd dvd-%k"
KERNEL=="hd[a-z]", BUS=="ide", ATTRS{removable}=="1", \
PROGRAM=="check-cdrom.sh %k CD-R", \
SYMLINK+="cdwriter cdwriter-%k cdrw cdrw-%k"
KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="check-cdrom.sh %k CD-R", \
SYMLINK+="cdwriter cdwriter-%k cdrw cdrw-%k"
KERNEL=="hd[a-z]", BUS=="ide", ATTRS{removable}=="1", \
PROGRAM="check-cdrom.sh %k DVD-R", \
SYMLINK+="dvdwriter dvdwriter-%k dvdrw dvdrw-%k"
KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="check-cdrom.sh %k DVD-R", \
SYMLINK+="dvdwriter dvdwriter-%k dvdrw dvdrw-%k"
# rename sr* to scd*
KERNEL=="sr[0-9]*", BUS=="scsi", NAME="scd%n"
KERNEL=="hd*[0-9]", BUS=="ide", ATTRS{removable}=="1", \
OPTIONS+="ignore_remove"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \
NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
ACTION=="add", SUBSYSTEM=="usb_device", \
PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", \
NAME="%c", MODE="0644"
ACTION=="add", SUBSYSTEM=="usb_endpoint", \
ATTR{bEndpointAddress}=="?*", ATTRS{devnum}=="?*", ATTRS{busnum}=="?*", \
NAME="bus/usb/$attr{busnum}/$attr{devnum}_ep/$attr{bEndpointAddress}", \
MODE="0644", SYMLINK+="%k"
# sd: 0 TYPE_DISK, 7 TYPE_MOD, 14 TYPE_RBC
# sr: 4 TYPE_WORM, 5 TYPE_ROM
# st/osst: 1 TYPE_TAPE
# sg: 8 changer, [36] scanner
ACTION=="add", SUBSYSTEM=="scsi" , ATTRS{type}=="0|7|14", \
RUN+="/bin/sh -c 'echo 60 > /sys$$DEVPATH/timeout'"
ACTION=="add", SUBSYSTEM=="scsi" , ATTRS{type}=="1", \
RUN+="/bin/sh -c 'echo 900 > /sys$$DEVPATH/timeout'"
ACTION=="add", SUBSYSTEM=="scsi_device" RUN+="/sbin/modprobe sg"
ACTION=="add", SUBSYSTEM=="scsi_device", ATTRS{type}=="0|7|14", \
RUN+="/sbin/modprobe sd_mod"
ACTION=="add", SUBSYSTEM=="scsi_device", ATTRS{type}=="[45]", \
RUN+="/sbin/modprobe sr_mod"
ACTION=="add", KERNEL=="sg[0-9]*", BUS=="scsi", ATTRS{type}=="[36]", \
SYMLINK+="scanner scanner-%k", MODE="0660"
ACTION=="add", KERNEL=="sg[0-9]*", BUS=="scsi", ATTRS{type}=="8", \
SYMLINK+="changer changer-%k", MODE="0660", GROUP="disk"
ACTION=="add", SUBSYSTEM=="scsi_device", ATTRS{type}=="1", \
ATTRS{vendor}=="On[sS]tream", \
ATTRS{model}!="ADR*", RUN+="/sbin/modprobe osst"
ACTION=="add", SUBSYSTEM=="scsi_device", ATTRS{type}=="1", \
ATTRS{vendor}=="On[sS]tream", \
ATTRS{model}=="ADR*", RUN+="/sbin/modprobe st"
ACTION=="add", SUBSYSTEM=="scsi_device", ATTRS{type}=="1", \
ATTRS{vendor}!="On[sS]tream", \
RUN+="/sbin/modprobe st"
# mmc block devices
ACTION=="add", SUBSYSTEM=="mmc", RUN+="/sbin/modprobe mmc_block"
RUN+="socket:/org/kernel/udev/monitor"
@@ -0,0 +1 @@
ENV{STARTUP}!="1", ACTION=="add", SYSFS{dev}=="?*", KERNEL=="?*", RUN+="/sbin/pam_console_apply $env{DEVNAME} $env{DEVLINKS}"
@@ -0,0 +1,5 @@
# do not edit this file, it will be overwritten on update
# sysfs is populated after the event is sent
ACTION=="add", KERNEL=="[0-9]*:[0-9]*", SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt"
@@ -0,0 +1,32 @@
# do not edit this file, it will be overwritten on update
ACTION!="add", GOTO="persistent_input_end"
SUBSYSTEM!="input", GOTO="persistent_input_end"
KERNEL=="input[0-9]*", GOTO="persistent_input_end"
# usb devices
SUBSYSTEMS=="usb", IMPORT{program}="usb_id --export"
SUBSYSTEMS=="usb", ATTRS{bInterfaceClass}=="03", ATTRS{bInterfaceProtocol}=="01", ENV{ID_CLASS}="kbd"
SUBSYSTEMS=="usb", ATTRS{bInterfaceClass}=="03", ATTRS{bInterfaceProtocol}=="02", ENV{ID_CLASS}="mouse"
# other devices
DRIVERS=="pcspkr", ENV{ID_CLASS}="spkr"
DRIVERS=="atkbd", ENV{ID_CLASS}="kbd"
DRIVERS=="psmouse", ENV{ID_CLASS}="mouse"
ATTRS{name}=="*dvb*|*DVB*|* IR *", ENV{ID_CLASS}="ir"
ATTRS{modalias}=="input:*-*a[068],*|input:*-*a*,[68],*m*", ATTRS{modalias}!="input:*-*k*14A,*r*", ENV{ID_CLASS}="joystick"
# fill empty serial number
ENV{ID_CLASS}=="?*", ENV{ID_SERIAL}=="", ENV{ID_SERIAL}="noserial"
# by-id links
KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{ID_CLASS}=="?*", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_CLASS}"
KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{ID_CLASS}=="?*", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-$env{ID_CLASS}"
# by-path
IMPORT{program}="path_id %p"
ENV{ID_PATH}=="?*", KERNEL=="mouse*|js*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{ID_CLASS}"
ENV{ID_PATH}=="?*", KERNEL=="event*", SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{ID_CLASS}"
LABEL="persistent_input_end"
@@ -0,0 +1,71 @@
# do not edit this file, it will be overwritten on update
# persistent storage links: /dev/{disk,tape}/{by-id,by-uuid,by-label,by-path,by-name}
# scheme based on "Linux persistent device names", 2004, Hannes Reinecke <hare@suse.de>
ACTION!="add", GOTO="persistent_storage_end"
KERNEL=="nst[0-9]", SUBSYSTEMS=="scsi", IMPORT{program}="scsi_id --export --whitelisted --fallback-to-sysfs -s %p -d $tempnode", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}-nst"
# type 8 devices are "Medium Changers"
KERNEL=="sg*", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{program}="scsi_id --export --whitelisted --fallback-to-sysfs -s %p -d $tempnode", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
SUBSYSTEM!="block", GOTO="persistent_storage_end"
# skip rules for inappropriate block devices
KERNEL=="ram*|loop*|fd*|nbd*|gnbd*|dm-*|md*", GOTO="persistent_storage_end"
# never access non-cdrom removable ide devices, the drivers are causing event loops on open()
KERNEL=="hd*[!0-9]", ATTR{removable}=="1", DRIVERS=="ide-cs|ide-floppy", GOTO="persistent_storage_end"
KERNEL=="hd*[0-9]", ATTRS{removable}=="1", GOTO="persistent_storage_end"
# ignore partitions that span the entire disk
ATTR{whole_disk}=="*", GOTO="persistent_storage_end"
# /sys/class/block will export this
ENV{DEVTYPE}!="?*", ATTR{range}=="?*", ENV{DEVTYPE}="disk"
ENV{DEVTYPE}!="?*", ATTR{start}=="?*", ENV{DEVTYPE}="partition"
# for partitions import parent information
ENV{DEVTYPE}=="partition", IMPORT{parent}="ID_*"
# by-id (hardware serial number)
KERNEL=="hd*[!0-9]", IMPORT{program}="ata_id --export $tempnode"
KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}"
KERNEL=="hd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n"
KERNEL=="sd*[!0-9]|sr*|st*", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{ieee1394_id}", ENV{ID_BUS}="ieee1394"
KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}!="?*", IMPORT{program}="usb_id --export %p"
KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted --fallback-to-sysfs -s %p -d $tempnode"
KERNEL=="cciss?c[0-9]d[0-9]", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted --ignore-sysfs -s %p -d $tempnode", ENV{ID_BUS}="cciss"
KERNEL=="sd*[!0-9]|sr*|cciss?c[0-9]d[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="sd*[0-9]|cciss*p[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
KERNEL=="st*", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
# libata compat (links like hd*)
KERNEL=="sd*[!0-9]|sr*", ENV{ID_VENDOR}=="ATA", PROGRAM="ata_id $tempnode", RESULT=="?*", ENV{ID_ATA_COMPAT}="$result", SYMLINK+="disk/by-id/ata-$env{ID_ATA_COMPAT}"
KERNEL=="sd*[0-9]", ENV{ID_ATA_COMPAT}=="?*", SYMLINK+="disk/by-id/ata-$env{ID_ATA_COMPAT}-part%n"
KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
KERNEL=="mmcblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
# by-path (shortest physical path)
ENV{DEVTYPE}=="disk", IMPORT{program}="path_id %p"
ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
KERNEL=="st*", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}"
KERNEL=="sr*|st*", GOTO="persistent_storage_end"
KERNEL=="hd*[!0-9]", ATTR{removable}=="1", GOTO="persistent_storage_end"
# by-label/by-uuid (filesystem properties)
IMPORT{program}="vol_id --export $tempnode"
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
# BIOS Enhanced Disk Device
ENV{DEVTYPE}=="disk", IMPORT{program}="edd_id --export $tempnode"
ENV{DEVTYPE}=="disk", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}"
ENV{DEVTYPE}=="partition", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part%n"
LABEL="persistent_storage_end"
@@ -0,0 +1,5 @@
# do not edit this file, it will be overwritten on update
# event to be catched by udevmonitor
RUN+="socket:/org/kernel/udev/monitor"
@@ -0,0 +1,355 @@
# /etc/udev/udev.rules: device naming rules for udev
#
# 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.
#
# This rules file is a mix of 10.2 Slackware udev.rules file and some
# rules from the udev examples.
#
# wait for sysfs
ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus"
ACTION=="add", SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt"
ACTION=="add", SUBSYSTEM=="net", WAIT_FOR_SYSFS="address"
# all block devices
SUBSYSTEM=="block", GROUP="disk"
# permissions for IDE CD devices (without symbolic link creation)
BUS=="ide", KERNEL=="*[!0-9]", ENV{PHYSDEVDRIVER}=="ide-cdrom", NAME="%k", GROUP="cdrom", MODE="0660"
# permissions for IDE CD devices (with symbolic link creation)
# THIS RULE COMMENTED OUT BY DEFAULT: read /lib/udev/rc.optical-symlinks for more information...
#BUS=="ide", KERNEL=="*[!0-9]", ENV{PHYSDEVDRIVER}=="ide-cdrom", NAME="%k", GROUP="cdrom", MODE="0660", RUN+="/lib/udev/cdrom-symlinks.sh %k"
# permissions for IDE floppy devices
BUS=="ide", KERNEL=="*[!0-9]", ENV{PHYSDEVDRIVER}=="ide-floppy*", NAME="%k", GROUP="floppy", MODE="0660"
# permissions for SCSI cd/sg/tape devices
BUS=="scsi", KERNEL=="s[grt][0-9]*", SYSFS{type}=="5", NAME="%k", GROUP="cdrom", MODE="0660"
# load modules to scsi disks, if they aren't in kernel
SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0|7|14", RUN+="/sbin/modprobe sd_mod"
SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", SYSFS{device/vendor}=="On[sS]tream", RUN+="/sbin/modprobe osst"
SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", RUN+="/sbin/modprobe st"
SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="[45]", RUN+="/sbin/modprobe sr_mod"
SUBSYSTEM=="scsi_device", ACTION=="add", RUN+="/sbin/modprobe sg"
# disk devices
KERNEL=="sd*", NAME="%k", GROUP="disk"
KERNEL=="dasd*", NAME="%k", GROUP="disk"
KERNEL=="ataraid*", NAME="%k", GROUP="disk"
# persistent storage links: /dev/disk/{by-id,by-uuid,by-label,by-path}
ACTION!="add", GOTO="persistent_end"
SUBSYSTEM!="block", GOTO="persistent_end"
# skip rules for inappropriate block devices
KERNEL=="ram*|loop*|fd*|nbd*", GOTO="persistent_end"
# never access removable ide devices, the drivers are causing event loops on open()
BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}=="1", GOTO="persistent_end"
# by-id (hardware serial number)
KERNEL=="hd*[!0-9]", IMPORT{program}="/lib/udev/ata_id --export $tempnode"
KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}"
KERNEL=="hd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n"
KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="*", ENV{ID_SERIAL}="$sysfs{ieee1394_id}", ENV{ID_BUS}="ieee1394"
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/lib/udev/usb_id -x"
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/lib/udev/scsi_id -g -x -s %p -d $tempnode"
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/lib/udev/scsi_id -g -x -a -s %p -d $tempnode"
KERNEL=="dasd*[!0-9]", IMPORT{program}="/lib/udev/dasd_id --export $tempnode"
KERNEL=="sd*[!0-9]|sr*|dasd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
# for partitions import parent information
KERNEL=="sd*[0-9]|dasd*[0-9]", IMPORT{parent}=="ID_*"
KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
# by-path (shortest physical path)
KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", IMPORT{program}="/lib/udev/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}"
KERNEL=="st*", ENV{ID_TYPE}=="?*", IMPORT{program}="/lib/udev/path_id %p", SYMLINK+="tape/by-path/$env{ID_PATH}"
KERNEL=="sr*|st*", GOTO="persistent_end"
KERNEL=="*[0-9]", IMPORT{parent}=="ID_*"
KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
# by-label/by-uuid (filesystem properties)
KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_end"
IMPORT{program}="/lib/udev/vol_id --export $tempnode"
ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}"
ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}"
# BIOS Enhanced Disk Device
KERNEL=="*[!0-9]", IMPORT{program}="/lib/udev/edd_id --export $tempnode"
KERNEL=="*[!0-9]", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}"
KERNEL=="*[0-9]", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part%n"
# LVM2 dmsetup
KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/dmsetup info -c --noopencount --noheadings -o name -j %M -m %m", SYMLINK+="disk/by-name/%c"
LABEL="persistent_end"
# ALSA devices
SUBSYSTEM=="sound", GROUP="audio"
SUBSYSTEM=="snd", GROUP="audio"
KERNEL=="controlC[0-9]*", NAME="snd/%k", MODE="0666"
KERNEL=="hw[CD0-9]*", NAME="snd/%k", MODE="0662"
KERNEL=="pcm[CD0-9]*c", NAME="snd/%k", MODE="0662"
KERNEL=="pcm[CD0-9]*p", NAME="snd/%k", MODE="0666"
KERNEL=="midiC[D0-9]*", NAME="snd/%k", MODE="0666"
KERNEL=="timer", NAME="snd/%k", MODE="0666"
KERNEL=="seq", NAME="snd/%k", MODE="0666"
# IEEE1394 raw devices (often used for video)
KERNEL=="raw1394", NAME="%k", GROUP="video"
KERNEL=="dv1394*", NAME="dv1394/%n", GROUP="video"
KERNEL=="video1394*", NAME="video1394/%n", GROUP="video"
# capi devices
KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20"
KERNEL=="capi*", NAME="capi/%n"
# cpu devices
KERNEL=="cpu[0-9]*", NAME="cpu/%n/cpuid"
KERNEL=="msr[0-9]*", NAME="cpu/%n/msr"
KERNEL=="microcode", NAME="cpu/microcode"
# dm devices (ignore them)
KERNEL=="dm-[0-9]*", NAME=""
# create a symlink named after the device map name
# note devmap_name comes with extras/multipath
#KERNEL=="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK+="%c"
KERNEL=="device-mapper", NAME="mapper/control"
# floppy devices
KERNEL=="fd[0-9]*", NAME="floppy/%n", SYMLINK+="%k", GROUP="floppy", PROGRAM="/lib/udev/floppy-extra-devs.sh %k %b %n"
# i2c devices
KERNEL=="i2c-[0-9]*", NAME="i2c/%n", SYMLINK+="%k"
# input devices
KERNEL=="mice", NAME="input/%k", MODE="0644", SYMLINK+="mouse"
KERNEL=="mouse*", NAME="input/%k", MODE="0644"
KERNEL=="event*", NAME="input/%k", MODE="0640"
KERNEL=="js*", NAME="input/%k", MODE="664"
KERNEL=="ts*", NAME="input/%k", MODE="0600"
SUBSYSTEM=="input[0-9]*", RUN+="/lib/udev/input_device.sh"
KERNEL=="input[0-9]*", ACTION=="add", ENV{ABS}=="[1-9]*", RUN+="/sbin/modprobe joydev"
# loop devices
KERNEL=="loop[0-9]*", NAME="loop/%n", SYMLINK+="%k", GROUP="disk"
# md block devices
KERNEL=="md[0-9]*", NAME="md/%n", SYMLINK+="%k", GROUP="disk"
# aoe char devices,
SUBSYSTEM=="aoe", KERNEL=="discover", NAME="etherd/%k", GROUP="disk", MODE="0220"
SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k", GROUP="disk", MODE="0440"
SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k", GROUP="disk", MODE="0220"
# netlink devices
KERNEL=="route", NAME="netlink/%k"
KERNEL=="skip", NAME="netlink/%k"
KERNEL=="usersock", NAME="netlink/%k"
KERNEL=="fwmonitor", NAME="netlink/%k"
KERNEL=="tcpdiag", NAME="netlink/%k"
KERNEL=="nflog", NAME="netlink/%k"
KERNEL=="xfrm", NAME="netlink/%k"
KERNEL=="arpd", NAME="netlink/%k"
KERNEL=="route6", NAME="netlink/%k"
KERNEL=="ip6_fw", NAME="netlink/%k"
KERNEL=="dnrtmsg", NAME="netlink/%k"
KERNEL=="tap*", NAME="netlink/%k"
# ramdisk devices
KERNEL=="ram[0-9]*", NAME="rd/%n", SYMLINK+="%k"
# raw devices
KERNEL=="raw[0-9]*", NAME="raw/%k", GROUP="disk"
KERNEL=="ram*", NAME="%k", GROUP="disk"
# sound devices
KERNEL=="adsp", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="adsp[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="audio", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="audio[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="dsp", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="dsp[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="mixer", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="mixer[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="sequencer", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
KERNEL=="sequencer[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio", MODE="0662"
# tty devices
KERNEL=="console", NAME="%k", GROUP="tty", MODE="0600"
KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666"
KERNEL=="tty[0-9]*", NAME="vc/%n", SYMLINK+="%k", GROUP="tty"
KERNEL=="ttyS[0-9]*", NAME="tts/%n", SYMLINK+="%k", GROUP="tty"
KERNEL=="ttyUSB[0-9]*", NAME="tts/USB%n", GROUP="tty", MODE="0660"
KERNEL=="ippp0", NAME="%k", GROUP="tty"
KERNEL=="isdn*", NAME="%k", GROUP="tty"
KERNEL=="dcbri*", NAME="%k", GROUP="tty"
KERNEL=="ircomm*", NAME="%k", GROUP="tty"
# pty devices
KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="0666"
KERNEL=="pty[p-za-e][0-9a-f]*", NAME="pty/m%m", SYMLINK+="%k", GROUP="tty"
KERNEL=="tty[p-za-e][0-9a-f]*", NAME="pty/s%m", SYMLINK+="%k", GROUP="tty"
# vc devices
KERNEL=="vcs", NAME="vcc/0", SYMLINK+="%k", GROUP="tty"
KERNEL=="vcs[0-9]*", NAME="vcc/%n", SYMLINK+="%k", GROUP="tty"
KERNEL=="vcsa", NAME="vcc/a0", SYMLINK+="%k", GROUP="tty"
KERNEL=="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK+="%k", GROUP="tty"
# memory devices
KERNEL=="random", NAME="%k", MODE="0664"
KERNEL=="urandom", NAME="%k", MODE="0664"
KERNEL=="mem", NAME="%k", GROUP="kmem", MODE="0640"
KERNEL=="kmem", NAME="%k", GROUP="kmem", MODE="0640"
KERNEL=="port", NAME="%k", GROUP="kmem", MODE="0640"
KERNEL=="nvram", NAME="%k", GROUP="kmem", MODE="600"
KERNEL=="full", NAME="%k", MODE="0666"
KERNEL=="null", NAME="%k", MODE="0666"
KERNEL=="zero", NAME="%k", MODE="0666"
# misc devices
KERNEL=="agpgart", NAME="misc/%k", SYMLINK+="%k"
KERNEL=="psaux", NAME="misc/%k", SYMLINK+="%k"
KERNEL=="rtc", NAME="misc/%k", SYMLINK+="%k", MODE="0664"
KERNEL=="uinput", NAME="misc/%k", SYMLINK+="%k"
KERNEL=="inotify", NAME="misc/%k", SYMLINK+="%k", MODE="0666"
# usb devices
KERNEL=="hiddev*", NAME="usb/%k"
KERNEL=="auer*", NAME="usb/%k"
KERNEL=="legousbtower*", NAME="usb/%k"
KERNEL=="dabusb*", NAME="usb/%k"
# fb devices
KERNEL=="fb[0-9]*", NAME="fb/%n", SYMLINK+="%k", GROUP="video"
# DRI devices
KERNEL=="card*", NAME="dri/card%n", GROUP="video"
KERNEL=="nvidia*", NAME="%k", GROUP="video"
KERNEL=="3dfx*", NAME="%k", GROUP="video"
# v4l devices
KERNEL=="video[0-9]*", NAME="v4l/video%n", SYMLINK+="video%n", GROUP="video"
KERNEL=="radio[0-9]*", NAME="v4l/radio%n", SYMLINK+="radio%n", GROUP="video"
KERNEL=="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK+="vbi%n", GROUP="video"
KERNEL=="vtx[0-9]*", NAME="v4l/vtx%n", GROUP="video"
# dvb devices
SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'X=%k; X=$${X#dvb}; A=$${X%%%%.*}; D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video"
# Asterix Zaptel devices
KERNEL=="zapctl", NAME="zap/ctl"
KERNEL=="zaptimer", NAME="zap/timer"
KERNEL=="zapchannel", NAME="zap/channel"
KERNEL=="zappseudo", NAME="zap/pseudo"
KERNEL=="zap[0-9]*", NAME="zap/%n"
# pilot/palm devices
KERNEL=="pilot", NAME="%k", GROUP="uucp"
# jaz devices
KERNEL=="jaz*", NAME="%k", GROUP="disk"
# zip devices
KERNEL=="pocketzip*", NAME="%k", GROUP="disk"
KERNEL=="zip*", NAME="%k", GROUP="disk"
# ls120 devices
KERNEL=="ls120", NAME="%k", GROUP="disk"
# lp devices
KERNEL=="irlpt", NAME="%k", GROUP="lp", MODE="0664"
SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp", MODE="0664"
SUBSYSTEM=="printer", KERNEL=="lp*", NAME="%k", GROUP="lp", MODE="0664"
KERNEL=="parport*", NAME="%k", GROUP="lp", MODE="0664"
# tape devices
KERNEL=="ht*", NAME="%k"
KERNEL=="nht*", NAME="%k"
KERNEL=="pt*", NAME="%k"
KERNEL=="npt*", NAME="%k"
KERNEL=="st*", NAME="%k"
KERNEL=="nst*", NAME="%k"
KERNEL=="osst*", NAME="%k"
KERNEL=="nosst*", NAME="%k"
# diskonkey devices
KERNEL=="diskonkey*", NAME="%k", GROUP="disk"
# rem_ide devices
KERNEL=="microdrive*", NAME="%k", GROUP="disk"
# kbd devices
KERNEL=="kbd", NAME="%k", MODE="0664"
# Sony Vaio Jogdial sonypi device
KERNEL=="sonypi", NAME="%k", MODE="0666"
# packet devices
KERNEL=="pktcdvd", NAME="pktcdvd/control", GROUP="cdrom", MODE="0660"
KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/pktcdvd%n", GROUP="cdrom", MODE="0660"
# infiniband devices
KERNEL=="umad*", NAME="infiniband/%k"
KERNEL=="issm*", NAME="infiniband/%k"
# PnP
SUBSYSTEM=="pnp", ENV{MODALIAS}!="?*", \
RUN+="/bin/sh -c 'while read id; do /sbin/modprobe pnp:d$$id; done < /sys$devpath/id'"
# firewire
SUBSYSTEM=="ieee1394", ENV{MODALIAS}!="?*", IMPORT{program}="modalias_ieee1394"
# libusb device access
DEVPATH=="/module/usbcore", ACTION=="add", \
RUN+="/bin/sh -c 'sleep 1; /bin/mount none -t usbfs /proc/bus/usb -o devmode=0666,devgid=10'"
SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev}; B=$${X%%%%.*}; D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c"
# firmware loader
SUBSYSTEM=="firmware", ACTION=="add", RUN+="/lib/udev/firmware_helper"
# load module
ACTION=="add", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}"
# PCMCIA devices:
#
# Very few CIS firmware entries (which we use for matching)
# are so broken that we need to read out random bytes of it
# instead of the manufactor, card or product ID. Then the
# matching is done in userspace.
ACTION=="add", SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="?*", \
RUN+="/sbin/pcmcia-check-broken-cis"
# However, the "weak" matching by func_id is only allowed _after_ modprobe
# returns, so that "strong" matches have a higher priority.
ACTION=="add", SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="?*", \
RUN+="/bin/sh -c 'echo 1 > /sys/$DEVPATH/allow_func_id_match'"
# PCMCIA sockets:
#
# modprobe the pcmcia bus module so that 16-bit PCMCIA devices work
ACTION=="add", SUBSYSTEM=="pcmcia_socket", RUN+="/sbin/modprobe pcmcia"
# if this is a PCMCIA socket which needs a resource database,
# pcmcia-socket-startup sets it up
ACTION=="add", SUBSYSTEM=="pcmcia_socket", RUN+="/sbin/pcmcia-socket-startup"
# network devices
KERNEL=="tun", NAME="net/%k"
SUBSYSTEM=="net", ACTION=="add", RUN+="/lib/udev/nethelper.sh $env{INTERFACE} start"
SUBSYSTEM=="net", ACTION=="remove", RUN+="/lib/udev/nethelper.sh $env{INTERFACE} stop"
# if you use HAL, try this:
# send all events to HAL
#RUN+="socket:/org/freedesktop/hal/udev_event"
# catch the event in udevmonitor
RUN+="socket:/org/kernel/udev/monitor"
@@ -0,0 +1,126 @@
# do not edit this file, it will be overwritten on update
# console
KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0666", OPTIONS="last_rule"
KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0666", OPTIONS="last_rule"
KERNEL=="tty", GROUP="tty", MODE="0666", OPTIONS="last_rule"
KERNEL=="tty[0-9]*|vcs*", GROUP="tty", MODE="0620", OPTIONS="last_rule"
KERNEL=="ptmx", GROUP="tty", MODE="0666", OPTIONS="last_rule"
KERNEL=="console", MODE="0600", OPTIONS="last_rule"
# serial devices
KERNEL=="tty[A-Z]*|pppox*|ircomm*|noz*", GROUP="uucp"
KERNEL=="hvc*|hvsi*", GROUP="uucp"
KERNEL=="iseries/vtty*", GROUP="uucp"
KERNEL=="mwave", NAME="modems/%k", GROUP="uucp"
KERNEL=="ttyUSB*", ATTRS{product}=="[Pp]alm*Handheld*", SYMLINK+="pilot"
KERNEL=="ttyUSB*", ATTRS{product}=="[Hh]andspring*Treo*|[Hh]andspring*Visor*", SYMLINK+="pilot"
KERNEL=="ppp", MODE="0600", OPTIONS+="ignore_remove"
# video/graphics
SUBSYSTEM=="video4linux", GROUP="video"
SUBSYSTEM=="graphics" GROUP="video"
KERNEL=="vtx*|vbi*", GROUP="video"
KERNEL=="winradio*", GROUP="video"
KERNEL=="vttuner*", GROUP="video"
KERNEL=="nvidia*|nvidiactl*", GROUP="video"
KERNEL=="video0", SYMLINK+="video"
KERNEL=="radio0", SYMLINK+="radio"
KERNEL=="vbi0", SYMLINK+="vbi"
KERNEL=="pmu", GROUP="video"
# dvb
SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%s $${K%%%%.*} $${K#*.}'", NAME="%c", GROUP="video"
# input devices
KERNEL=="mouse*|mice|event*", NAME="input/%k", MODE="0640"
KERNEL=="js*", NAME="input/%k", MODE="0644"
KERNEL=="ts*|uinput", NAME="input/%k", MODE="0600"
KERNEL=="lirc0", SYMLINK+="lirc"
# printer
SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp"
SUBSYSTEM=="printer", KERNEL=="lp*", GROUP="lp"
KERNEL=="irlpt*", GROUP="lp"
# cpu devices
KERNEL=="cpu[0-9]*", NAME="cpu/%n/cpuid"
KERNEL=="msr[0-9]*", NAME="cpu/%n/msr"
KERNEL=="microcode", NAME="cpu/microcode", MODE="0600"
# IEEE1394 devices
KERNEL=="raw1394*", GROUP="video"
KERNEL=="dv1394*", SYMLINK+="dv1394/%n", GROUP="video"
KERNEL=="video1394*", SYMLINK+="video1394/%n", GROUP="video"
KERNEL=="hw_random", NAME="hwrng", SYMLINK+="%k"
KERNEL=="rioctl", NAME="specialix_rioctl", SYMLINK+="%k"
KERNEL=="sxctl", NAME="specialix_sxctl", SYMLINK+="%k"
# network
KERNEL=="tun", NAME="net/%k", MODE="0666", OPTIONS+="ignore_remove"
# misc devices
KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640"
KERNEL=="nvram", GROUP="kmem", MODE="0600"
KERNEL=="null|zero|random", MODE="0666"
KERNEL=="full", MODE="0622"
KERNEL=="urandom", MODE="0644"
KERNEL=="rtc", MODE="0600"
KERNEL=="fuse", MODE="0666"
KERNEL=="sonypi", MODE="0666"
KERNEL=="agpgart", MODE="0600", GROUP="video"
KERNEL=="djs*", MODE="0644"
KERNEL=="sgi_*", MODE="0666"
KERNEL=="rrom*", MODE="0400"
KERNEL=="rflash*", MODE="0400"
KERNEL=="usbscanner*", MODE="0644"
KERNEL=="3270/ttycons*", MODE="0600"
KERNEL=="3270/tub*", MODE="0666"
KERNEL=="3270/tubcons*", MODE="0600"
KERNEL=="ica", MODE="0666"
KERNEL=="z90crypt", MODE="0666"
KERNEL=="mmtimer", MODE="0644"
KERNEL=="auer[0-9]*" NAME="usb/%k"
# packet writing interface
KERNEL=="pktcdvd", NAME="pktcdvd/control"
KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%k"
# additional floppy devices (no sysfs entries)
KERNEL=="fd[0-9]*", ACTION=="add", ATTRS{cmos}=="?*", RUN+="create_floppy_devices -c -t $attr{cmos} -m %M -M 0640 -G disk $root/%k"
# block devices
SUBSYSTEM=="block", GROUP="disk", MODE="0640"
SUBSYSTEM=="block", KERNEL=="sr[0-9]*", SYMLINK+="scd%n"
# sd: 0 TYPE_DISK, 7 TYPE_MOD, 14 TYPE_RBC
# sr: 4 TYPE_WORM, 5 TYPE_ROM
# st/osst: 1 TYPE_TAPE
SUBSYSTEM=="scsi", KERNEL=="[0-9]*:[0-9]*", ACTION=="add", ATTR{type}=="0|7|14", ATTR{timeout}="60"
SUBSYSTEM=="scsi", KERNEL=="[0-9]*:[0-9]*", ACTION=="add", ATTR{type}=="1", ATTR{timeout}="900"
KERNEL=="hd*", SUBSYSTEMS=="ide", ATTRS{media}=="floppy", OPTIONS+="all_partitions"
# misc storage devices (non-block)
KERNEL=="sg*", GROUP="disk", MODE="0640"
KERNEL=="st*|nst*", GROUP="disk"
KERNEL=="qft*|nqft*|zqft*|nzqft*|rawqft*|nrawqft", GROUP="disk"
KERNEL=="ht*|nht*", GROUP="disk"
KERNEL=="pf*", GROUP="disk"
KERNEL=="sch*", GROUP="disk"
KERNEL=="pt*|npt*", GROUP="disk"
KERNEL=="pg*", GROUP="disk"
KERNEL=="evms/block_device*", GROUP="disk"
KERNEL=="rawctl*", NAME="raw/%k", GROUP="disk"
SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", NAME="raw/%k", GROUP="disk"
KERNEL=="osst*|nosst*", NAME="%k", GROUP="disk"
KERNEL=="iseries/vt*", NAME="%k", GROUP="disk"
KERNEL=="iseries/nvt*", NAME="%k", GROUP="disk"
KERNEL=="iseries/ibmsis*", NAME="%k", GROUP="disk"
# libusb device access
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
# kernel firmware loader
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware.sh"
@@ -0,0 +1,23 @@
# do not edit this file, it will be overwritten on update
KERNEL=="device-mapper", SYMLINK+="mapper/control"
KERNEL!="dm-*", GOTO="device_mapper_end"
ACTION!="add|change", GOTO="device_mapper_end"
IMPORT{program}="/sbin/dmsetup export -j%M -m%m"
ENV{DM_NAME}!="?*", GOTO="device_mapper_end"
SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}"
ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}"
ENV{DM_STATE}=="SUSPENDED", GOTO="device_mapper_end"
ENV{DM_TARGET_TYPES}=="|*error*", GOTO="device_mapper_end"
IMPORT{program}="vol_id --export $tempnode"
OPTIONS="link_priority=-100"
ENV{DM_TARGET_TYPES}=="*snapshot-origin*", OPTIONS="link_priority=-90"
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
LABEL="device_mapper_end"
@@ -0,0 +1,18 @@
# do not edit this file, it will be overwritten on update
SUBSYSTEM!="block", GOTO="md_end"
KERNEL!="md[0-9]*", GOTO="md_end"
ACTION!="add|change", GOTO="md_end"
ATTR{md/array_state}=="|clear|inactive", GOTO="md_end"
IMPORT{program}="/sbin/mdadm --detail --export $tempnode"
ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}"
ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}"
IMPORT{program}="vol_id --export $tempnode"
OPTIONS="link_priority=100"
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
LABEL="md_end"
@@ -0,0 +1,15 @@
# do not edit this file, it will be overwritten on update
ACTION!="add", GOTO="drivers_end"
DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{ignore_error}+="/sbin/modprobe $env{MODALIAS}"
SUBSYSTEM=="pnp", DRIVER!="?*", ENV{MODALIAS}!="?*", RUN{ignore_error}+="/bin/sh -c 'while read id; do /sbin/modprobe pnp:d$$id; done < /sys$devpath/id'"
SUBSYSTEM=="tifm", RUN+="/sbin/modprobe --all tifm_sd tifm_ms"
SUBSYSTEM=="mmc", RUN+="/sbin/modprobe mmc_block"
SUBSYSTEM=="ide", ATTR{media}=="tape", RUN+="/sbin/modprobe ide-scsi"
SUBSYSTEM=="scsi_device", ATTRS{type}=="1", ATTR{vendor}=="On[sS]tream", RUN+="/sbin/modprobe osst"
SUBSYSTEM=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe sg"
LABEL="drivers_end"
@@ -0,0 +1,7 @@
# udev.conf
# The initial syslog(3) priority: "err", "info", "debug" or its
# numerical equivalent. For runtime debugging, the daemons internal
# state can be changed with: "udevcontrol log_priority=<value>".
udev_log="err"
@@ -0,0 +1,70 @@
# Makefile for udev extra invoked from the udev main Makefile
#
# Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
#
# Released under the GNU General Public License, version 2.
#
PROG = ata_id
OBJ =
HEADERS =
GEN_HEADERS =
MAN_PAGES =
prefix =
etcdir = ${prefix}/etc
sbindir = ${prefix}/sbin
usrbindir = ${prefix}/usr/bin
usrsbindir = ${prefix}/usr/sbin
libudevdir = ${prefix}/lib/udev
mandir = ${prefix}/usr/share/man
configdir = ${etcdir}/udev/
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
all: $(PROG) $(MAN_PAGES)
.PHONY: all
.DEFAULT: all
%.o: %.c $(GEN_HEADERS)
$(E) " CC " $@
$(Q) $(CC) -c $(CFLAGS) $< -o $@
$(PROG): %: $(HEADERS) %.o $(OBJS)
$(E) " LD " $@
$(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
# man pages
%.8: %.xml
$(E) " XMLTO " $@
$(Q) xmlto man $?
.PRECIOUS: %.8
clean:
$(E) " CLEAN "
$(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
.PHONY: clean
install-bin: all
$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
.PHONY: install-bin
uninstall-bin:
- rm $(DESTDIR)$(libudevdir)/$(PROG)
.PHONY: uninstall-bin
install-man:
$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
.PHONY: install-man
uninstall-man:
-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
.PHONY: uninstall-man
install-config:
@echo "no config file to install"
.PHONY: install-config
@@ -0,0 +1,28 @@
.TH ATA_ID 8 "November 2005" "" "Linux Administrator's Manual"
.SH NAME
ata_id \- udev callout to read product/serial number from ATA drives
.SH SYNOPSIS
.BI ata_id
[\fI--export\fP] \fIblockdevice\fP
.SH "DESCRIPTION"
.B ata_id
is normally called from a udev rule, to provide udev with a unique string and
additional information (uuid, label) for an ATA drive. Udev can use this
information to create symlinks in /dev/disk/by-id and /dev/disk/by-label
to the real device node.
.SH USAGE
.B ata_id
opens the blockdevice node specified at the commandline and prints the
information chosen by the options.
.SH OPTIONS
The following commandline switches are supported to specify what ata_id
should print:
.TP
.BI --export
print all values (instead of only the id)
.RE
.SH SEE ALSO
.BR udev (7)
.SH AUTHORS
Developed by Kay Sievers <kay.sievers@vrfy.org>.
@@ -0,0 +1,195 @@
/*
* ata_id - reads product/serial number from ATA drives
*
* Copyright (C) 2005 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.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/hdreg.h>
#include "../../udev.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
static void set_str(char *to, const char *from, size_t count)
{
size_t i, j, len;
/* strip trailing whitespace */
len = strnlen(from, count);
while (len && isspace(from[len-1]))
len--;
/* strip leading whitespace */
i = 0;
while (isspace(from[i]) && (i < len))
i++;
j = 0;
while (i < len) {
/* substitute multiple whitespace */
if (isspace(from[i])) {
while (isspace(from[i]))
i++;
to[j++] = '_';
}
/* skip chars */
if (from[i] == '/') {
i++;
continue;
}
to[j++] = from[i++];
}
to[j] = '\0';
}
int main(int argc, char *argv[])
{
struct hd_driveid id;
char model[41];
char serial[21];
char revision[9];
const char *node = NULL;
int export = 0;
int fd;
int rc = 0;
static const struct option options[] = {
{ "export", 0, NULL, 'x' },
{ "help", 0, NULL, 'h' },
{}
};
logging_init("ata_id");
while (1) {
int option;
option = getopt_long(argc, argv, "xh", options, NULL);
if (option == -1)
break;
switch (option) {
case 'x':
export = 1;
break;
case 'h':
printf("Usage: ata_id [--export] [--help] <device>\n"
" --export print values as environemt keys\n"
" --help print this help text\n\n");
default:
rc = 1;
goto exit;
}
}
node = argv[optind];
if (node == NULL) {
err("no node specified");
rc = 1;
goto exit;
}
fd = open(node, O_RDONLY|O_NONBLOCK);
if (fd < 0) {
err("unable to open '%s'", node);
rc = 1;
goto exit;
}
if (ioctl(fd, HDIO_GET_IDENTITY, &id)) {
if (errno == ENOTTY) {
info("HDIO_GET_IDENTITY unsupported for '%s'", node);
rc = 2;
} else {
err("HDIO_GET_IDENTITY failed for '%s'", node);
rc = 3;
}
goto close;
}
set_str(model, (char *) id.model, 40);
set_str(serial, (char *) id.serial_no, 20);
set_str(revision, (char *) id.fw_rev, 8);
if (export) {
if ((id.config >> 8) & 0x80) {
/* This is an ATAPI device */
switch ((id.config >> 8) & 0x1f) {
case 0:
printf("ID_TYPE=cd\n");
break;
case 1:
printf("ID_TYPE=tape\n");
break;
case 5:
printf("ID_TYPE=cd\n");
break;
case 7:
printf("ID_TYPE=optical\n");
break;
default:
printf("ID_TYPE=generic\n");
break;
}
} else {
printf("ID_TYPE=disk\n");
}
printf("ID_MODEL=%s\n", model);
printf("ID_SERIAL=%s\n", serial);
printf("ID_REVISION=%s\n", revision);
printf("ID_BUS=ata\n");
} else {
if (serial[0] != '\0')
printf("%s_%s\n", model, serial);
else
printf("%s\n", model);
}
close:
close(fd);
exit:
logging_close();
return rc;
}
@@ -0,0 +1,3 @@
# import optical drive properties
KERNEL=="sr[0-9]*|hd[a-z]|pcd[0-9]*", IMPORT{program}="cdrom_id --export $tempnode"
@@ -0,0 +1,71 @@
# Makefile for udev extra invoked from the udev main Makefile
#
# Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
#
# Released under the GNU General Public License, version 2.
#
PROG = cdrom_id
OBJ =
HEADERS =
GEN_HEADERS =
MAN_PAGES =
prefix =
etcdir = ${prefix}/etc
sbindir = ${prefix}/sbin
usrbindir = ${prefix}/usr/bin
usrsbindir = ${prefix}/usr/sbin
libudevdir = ${prefix}/lib/udev
mandir = ${prefix}/usr/share/man
configdir = ${etcdir}/udev
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
all: $(PROG) $(MAN_PAGES)
.PHONY: all
.DEFAULT: all
%.o: %.c $(GEN_HEADERS)
$(E) " CC " $@
$(Q) $(CC) -c $(CFLAGS) $< -o $@
$(PROG): %: $(HEADERS) %.o $(OBJS)
$(E) " LD " $@
$(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
# man pages
%.8: %.xml
$(E) " XMLTO " $@
$(Q) xmlto man $?
.PRECIOUS: %.8
clean:
$(E) " CLEAN "
$(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
.PHONY: clean
install-bin: all
$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
$(INSTALL_DATA) -D 60-cdrom_id.rules $(DESTDIR)$(configdir)/rules.d/60-cdrom_id.rules
.PHONY: install-bin
uninstall-bin:
- rm $(DESTDIR)$(libudevdir)/$(PROG)
- rm $(DESTDIR)$(configdir)/rules.d/60-cdrom_id.rules
.PHONY: uninstall-bin
install-man:
$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
.PHONY: install-man
uninstall-man:
-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
.PHONY: uninstall-man
install-config:
@echo "no config file to install"
.PHONY: install-config
@@ -0,0 +1,27 @@
.TH CDROM_ID 8 "November 2005" "" "Linux Administrator's Manual"
.SH NAME
cdrom_id \- udev callout to determine the capabilities of cd/dvd drives
.SH SYNOPSIS
.BI cdrom_id
[\fI--export\fP] \fIblockdevice\fP
.SH "DESCRIPTION"
.B cdrom_id
is normally called from a udev rule, to provide udev with the capabilities
of a cdrom or dvdrom drive. Udev can use this information to create
symlinks like /dev/cdrom or /dev/dvd to the real device node.
.SH USAGE
.B cdrom_id
opens the blockdevice node specified at the commandline and prints the
discovered capabilities.
.SH OPTIONS
The following commandline switches are supported to specify what cdrom_id
should print:
.TP
.BI --export
print all values (default)
.RE
.SH SEE ALSO
.BR udev (7)
.SH AUTHORS
Developed by Greg Kroah\-Hartman <greg@kroah.com>.
@@ -0,0 +1,152 @@
/*
* cdrom_id - determines the capabilities of cdrom drives
*
* Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.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.
*
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include "../../udev.h"
/*
* Taken from the cdrom.h kernel include file.
* Included here as some distros don't have an updated version
* with all of the DVD flags. So we just include our own, aren't
* we so nice...
*/
#define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
/* capability flags used with the uniform CD-ROM driver */
#define CDC_CLOSE_TRAY 0x1 /* caddy systems _can't_ close */
#define CDC_OPEN_TRAY 0x2 /* but _can_ eject. */
#define CDC_LOCK 0x4 /* disable manual eject */
#define CDC_SELECT_SPEED 0x8 /* programmable speed */
#define CDC_SELECT_DISC 0x10 /* select disc from juke-box */
#define CDC_MULTI_SESSION 0x20 /* read sessions>1 */
#define CDC_MCN 0x40 /* Medium Catalog Number */
#define CDC_MEDIA_CHANGED 0x80 /* media changed */
#define CDC_PLAY_AUDIO 0x100 /* audio functions */
#define CDC_RESET 0x200 /* hard reset device */
#define CDC_IOCTLS 0x400 /* driver has non-standard ioctls */
#define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */
#define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */
#define CDC_CD_R 0x2000 /* drive is a CD-R */
#define CDC_CD_RW 0x4000 /* drive is a CD-RW */
#define CDC_DVD 0x8000 /* drive is a DVD */
#define CDC_DVD_R 0x10000 /* drive can write DVD-R */
#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */
#define CDC_MO_DRIVE 0x40000 /* drive is an MO device */
#define CDC_MRW 0x80000 /* drive can read MRW */
#define CDC_MRW_W 0x100000 /* drive can write MRW */
#define CDC_RAM 0x200000 /* ok to open for WRITE */
#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
int main(int argc, char *argv[])
{
const char *node = NULL;
int i;
int export = 0;
int fd;
int rc = 0;
int result;
logging_init("cdrom_id");
for (i = 1 ; i < argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "--export") == 0) {
export = 1;
} else
node = arg;
}
if (!node) {
info("no node specified");
rc = 1;
goto exit;
}
fd = open(node, O_RDONLY|O_NONBLOCK);
if (fd < 0) {
info("unable to open '%s'", node);
rc = 1;
goto exit;
}
result = ioctl(fd, CDROM_GET_CAPABILITY, NULL);
if (result < 0) {
info("CDROM_GET_CAPABILITY failed for '%s'", node);
rc = 3;
goto close;
}
printf("ID_CDROM=1\n");
if (result & CDC_CD_R)
printf("ID_CDROM_CD_R=1\n");
if (result & CDC_CD_RW)
printf("ID_CDROM_CD_RW=1\n");
if (result & CDC_DVD)
printf("ID_CDROM_DVD=1\n");
if (result & CDC_DVD_R)
printf("ID_CDROM_DVD_R=1\n");
if (result & CDC_DVD_RAM)
printf("ID_CDROM_DVD_RAM=1\n");
if (result & CDC_MRW)
printf("ID_CDROM_MRW=1\n");
if (result & CDC_MRW_W)
printf("ID_CDROM_MRW_W=1\n");
if (result & CDC_RAM)
printf("ID_CDROM_RAM=1\n");
close:
close(fd);
exit:
logging_close();
return rc;
}
@@ -0,0 +1,64 @@
# Makefile for udev extra invoked by the udev main Makefile
PROG = collect
OBJ =
HEADERS =
GEN_HEADERS =
MAN_PAGES =
prefix =
etcdir = ${prefix}/etc
sbindir = ${prefix}/sbin
usrbindir = ${prefix}/usr/bin
usrsbindir = ${prefix}/usr/sbin
libudevdir = ${prefix}/lib/udev
mandir = ${prefix}/usr/share/man
configdir = ${etcdir}/udev/
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
all: $(PROG) $(MAN_PAGES)
.PHONY: all
.DEFAULT: all
%.o: %.c $(GEN_HEADERS)
$(E) " CC " $@
$(Q) $(CC) -c $(CFLAGS) $< -o $@
$(PROG): %: $(HEADERS) %.o $(OBJS)
$(E) " LD " $@
$(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
# man pages
%.8: %.xml
$(E) " XMLTO " $@
$(Q) xmlto man $?
.PRECIOUS: %.8
clean:
$(E) " CLEAN "
$(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
.PHONY: clean
install-bin: all
$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
.PHONY: install-bin
uninstall-bin:
- rm $(DESTDIR)$(libudevdir)/$(PROG)
.PHONY: uninstall-bin
install-man:
@echo "Please create a man page for this tool."
.PHONY: install-man
uninstall-man:
@echo "Please create a man page for this tool."
.PHONY: uninstall-man
install-config:
@echo "no config file to install"
.PHONY: install-config
@@ -0,0 +1,429 @@
/*
* Collect variables across events.
*
* usage: collect [--add|--remove] <checkpoint> <id> <idlist>
*
* Adds ID <id> to the list governed by <checkpoint>.
* <id> must be part of the ID list <idlist>.
* If all IDs given by <idlist> are listed (ie collect has been
* invoked for each ID in <idlist>) collect returns 0, the
* number of missing IDs otherwise.
* A negative number is returned on error.
*
* Copyright(C) 2007, Hannes Reinecke <hare@suse.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, either version 2 of the License, or
* (at your option) any later version.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../../list.h"
#define TMPFILE "/dev/.udev/collect"
#define BUFSIZE 16
#define UDEV_ALARM_TIMEOUT 180
enum collect_state {
STATE_NONE,
STATE_OLD,
STATE_CONFIRMED,
};
struct _mate {
struct list_head node;
char *name;
enum collect_state state;
};
static LIST_HEAD(bunch);
static int debug;
/* This can increase dynamically */
static int bufsize = BUFSIZE;
static void sig_alrm(int signo)
{
exit(4);
}
static void usage(void)
{
printf("usage: collect [--add|--remove] [--debug] <checkpoint> <id> <idlist>\n"
"\n"
" Adds ID <id> to the list governed by <checkpoint>.\n"
" <id> must be part of the list <idlist>.\n"
" If all IDs given by <idlist> are listed (ie collect has been\n"
" invoked for each ID in <idlist>) collect returns 0, the\n"
" number of missing IDs otherwise.\n"
" On error a negative number is returned.\n"
"\n");
}
/*
* prepare
*
* Prepares the database file
*/
static int prepare(char *dir, char *filename)
{
struct stat statbuf;
char buf[512];
int fd;
if (stat(dir, &statbuf) < 0)
mkdir(dir, 0700);
sprintf(buf, "%s/%s", dir, filename);
fd = open(buf,O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if (fd < 0)
fprintf(stderr, "Cannot open %s: %s\n", buf, strerror(errno));
if (lockf(fd,F_TLOCK,0) < 0) {
if (debug)
fprintf(stderr, "Lock taken, wait for %d seconds\n", UDEV_ALARM_TIMEOUT);
if (errno == EAGAIN || errno == EACCES) {
alarm(UDEV_ALARM_TIMEOUT);
lockf(fd, F_LOCK, 0);
if (debug)
fprintf(stderr, "Acquired lock on %s\n", buf);
} else {
if (debug)
fprintf(stderr, "Could not get lock on %s: %s\n", buf, strerror(errno));
}
}
return fd;
}
/*
* Read checkpoint file
*
* Tricky reading this. We allocate a buffer twice as large
* as we're goint to read. Then we read into the upper half
* of that buffer and start parsing.
* Once we do _not_ find end-of-work terminator (whitespace
* character) we move the upper half to the lower half,
* adjust the read pointer and read the next bit.
* Quite clever methinks :-)
* I should become a programmer ...
*
* Yes, one could have used fgets() for this. But then we'd
* have to use freopen etc which I found quite tedious.
*/
static int checkout(int fd)
{
int len;
char *buf, *ptr, *word = NULL;
struct _mate *him;
restart:
len = bufsize >> 1;
buf = calloc(1,bufsize + 1);
if (!buf) {
fprintf(stderr, "Out of memory\n");
return -1;
}
memset(buf, ' ', bufsize);
ptr = buf + len;
while ((read(fd, buf + len, len)) > 0) {
while (ptr && *ptr) {
word = ptr;
ptr = strpbrk(word," \n\t\r");
if (!ptr && word < (buf + len)) {
bufsize = bufsize << 1;
if (debug)
fprintf(stderr, "ID overflow, restarting with size %d\n", bufsize);
free(buf);
lseek(fd, 0, SEEK_SET);
goto restart;
}
if (ptr) {
*ptr = '\0';
ptr++;
if (!strlen(word))
continue;
if (debug)
fprintf(stderr, "Found word %s\n", word);
him = malloc(sizeof (struct _mate));
him->name = malloc(strlen(word) + 1);
strcpy(him->name, word);
him->state = STATE_OLD;
list_add_tail(&him->node, &bunch);
word = NULL;
}
}
memcpy(buf, buf + len, len);
memset(buf + len, ' ', len);
if (!ptr)
ptr = word;
if (!ptr)
break;
ptr -= len;
}
free(buf);
return 0;
}
/*
* invite
*
* Adds a new ID 'us' to the internal list,
* marks it as confirmed.
*/
static void invite(char *us)
{
struct _mate *him, *who;
if (debug)
fprintf(stderr, "Adding ID '%s'\n", us);
who = NULL;
list_for_each_entry(him, &bunch, node) {
if (!strcmp(him->name, us)) {
him->state = STATE_CONFIRMED;
who = him;
}
}
if (debug && !who)
fprintf(stderr, "ID '%s' not in database\n", us);
}
/*
* reject
*
* Marks the ID 'us' as invalid,
* causing it to be removed when the
* list is written out.
*/
static void reject(char *us)
{
struct _mate *him, *who;
if (debug)
fprintf(stderr, "Removing ID '%s'\n", us);
who = NULL;
list_for_each_entry(him, &bunch, node) {
if (!strcmp(him->name, us)) {
him->state = STATE_NONE;
who = him;
}
}
if (debug && !who)
fprintf(stderr, "ID '%s' not in database\n", us);
}
/*
* kickout
*
* Remove all IDs in the internal list which are not part
* of the list passed via the commandline.
*/
static void kickout(void)
{
struct _mate *him, *them;
list_for_each_entry_safe(him, them, &bunch, node) {
if (him->state == STATE_OLD) {
list_del(&him->node);
free(him->name);
free(him);
}
}
}
/*
* missing
*
* Counts all missing IDs in the internal list.
*/
static int missing(int fd)
{
char *buf;
int ret = 0;
struct _mate *him;
buf = malloc(bufsize);
if (!buf)
return -1;
list_for_each_entry(him, &bunch, node) {
if (him->state == STATE_NONE) {
ret++;
} else {
sprintf(buf, "%s ", him->name);
write(fd, buf, strlen(buf));
}
}
free(buf);
return ret;
}
/*
* everybody
*
* Prints out the status of the internal list.
*/
static void everybody(void)
{
struct _mate *him;
const char *state = "";
list_for_each_entry(him, &bunch, node) {
switch (him->state) {
case STATE_NONE:
state = "none";
break;
case STATE_OLD:
state = "old";
break;
case STATE_CONFIRMED:
state = "confirmed";
break;
fprintf(stderr, "ID: %s=%s\n", him->name, state);
}
}
}
int main(int argc, char **argv)
{
static const struct option options[] = {
{ "add", 0, NULL, 'a' },
{ "remove", 0, NULL, 'r' },
{ "debug", 0, NULL, 'd' },
{ "help", 0, NULL, 'h' },
{}
};
int argi;
char *checkpoint, *us;
struct _mate *him, *who;
int fd;
int i;
int ret = 0;
int prune = 0;
while (1) {
int option;
option = getopt_long(argc, argv, "ardh", options, NULL);
if (option == -1)
break;
switch (option) {
case 'a':
prune = 0;
break;
case 'r':
prune = 1;
break;
case 'd':
debug = 1;
break;
case 'h':
usage();
goto exit;
default:
ret = 1;
goto exit;
}
}
argi = optind;
if (argi + 2 > argc) {
printf("Missing parameter(s)\n");
ret = 1;
goto exit;
}
checkpoint = argv[argi++];
us = argv[argi++];
if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
fprintf(stderr, "Cannot set SIGALRM: %s\n", strerror(errno));
ret = 2;
goto exit;
}
INIT_LIST_HEAD(&bunch);
if (debug)
fprintf(stderr, "Using checkpoint '%s'\n", checkpoint);
fd = prepare(TMPFILE, checkpoint);
if (fd < 0) {
ret = 3;
goto out;
}
if (checkout(fd) < 0) {
ret = 2;
goto out;
}
for (i = argi; i < argc; i++) {
who = NULL;
list_for_each_entry(him, &bunch, node) {
if (!strcmp(him->name, argv[i]))
who = him;
}
if (!who) {
if (debug)
fprintf(stderr, "ID %s: not in database\n", argv[i]);
him = malloc(sizeof (struct _mate));
him->name = malloc(strlen(argv[i]) + 1);
strcpy(him->name, argv[i]);
him->state = STATE_NONE;
list_add_tail(&him->node, &bunch);
} else {
if (debug)
fprintf(stderr, "ID %s: found in database\n", argv[i]);
who->state = STATE_CONFIRMED;
}
}
if (prune)
reject(us);
else
invite(us);
if (debug) {
everybody();
fprintf(stderr, "Prune lists\n");
}
kickout();
lseek(fd, 0, SEEK_SET);
ftruncate(fd, 0);
ret = missing(fd);
lockf(fd, F_ULOCK, 0);
close(fd);
out:
if (debug)
everybody();
if (ret >= 0)
printf("COLLECT_%s=%d\n", checkpoint, ret);
exit:
return ret;
}
@@ -0,0 +1,70 @@
# Makefile for udev extra invoked from the udev main Makefile
#
# Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
#
# Released under the GNU General Public License, version 2.
#
PROG = edd_id
OBJ =
HEADERS =
GEN_HEADERS =
MAN_PAGES =
prefix =
etcdir = ${prefix}/etc
sbindir = ${prefix}/sbin
usrbindir = ${prefix}/usr/bin
usrsbindir = ${prefix}/usr/sbin
libudevdir = ${prefix}/lib/udev
mandir = ${prefix}/usr/share/man
configdir = ${etcdir}/udev/
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
all: $(PROG) $(MAN_PAGES)
.PHONY: all
.DEFAULT: all
%.o: %.c $(GEN_HEADERS)
$(E) " CC " $@
$(Q) $(CC) -c $(CFLAGS) $< -o $@
$(PROG): %: $(HEADERS) %.o $(OBJS)
$(E) " LD " $@
$(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
# man pages
%.8: %.xml
$(E) " XMLTO " $@
$(Q) xmlto man $?
.PRECIOUS: %.8
clean:
$(E) " CLEAN "
$(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
.PHONY: clean
install-bin: all
$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
.PHONY: install-bin
uninstall-bin:
- rm $(DESTDIR)$(libudevdir)/$(PROG)
.PHONY: uninstall-bin
install-man:
$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
.PHONY: install-man
uninstall-man:
-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
.PHONY: uninstall-man
install-config:
@echo "no config file to install"
.PHONY: install-config

Some files were not shown because too many files have changed in this diff Show More