diff --git a/21cnbao/code/05/udev源代码/udev-114/.gitignore b/21cnbao/code/05/udev源代码/udev-114/.gitignore new file mode 100644 index 0000000..db03272 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/.gitignore @@ -0,0 +1,14 @@ +*.o +*.a +udevd +udevcontrol +udevtrigger +udevsettle +udevsend +udevinfo +udevmonitor +udevstart +udevtest +udev_version.h +test-udev + diff --git a/21cnbao/code/05/udev源代码/udev-114/COPYING b/21cnbao/code/05/udev源代码/udev-114/COPYING new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/COPYING @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/21cnbao/code/05/udev源代码/udev-114/ChangeLog b/21cnbao/code/05/udev源代码/udev-114/ChangeLog new file mode 100644 index 0000000..679e66f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/ChangeLog @@ -0,0 +1,3385 @@ +Summary of changes from v113 to v114 +============================================ + +Hannes Reinecke (3): + collect: extra to synchronize actions across events + add $driver subtitution + rules_generator: add S/390 persistent network support + +Kay Sievers (24): + rules_generator: remove executable flag from include file + always unlink temporary file before creating new one + rules: SUSE update + volume_id: ext4 detection + udevtrigger: allow to specify action string + add option to RUN key to ignore the return value of the program + use global udev_log variable instead of parameter in run_program + add udev_rules_run() to handle RUN list + move udev_utils_run.c into udev_rules.c + rules: SUSE update + name_list: rename loop_name -> name_loop + handle dynamic rules created in /dev/.udev/rules.d/ + allow SYMLINK== match + libvolume_id: use /usr/$libdir in pc file + Makefile: add --as-needed flag to ld + restore behavior of NAME== + rules_generator: remove "installation" function + udevtrigger: trigger "driver" events + rules: update SUSE + rules: Fedora update + rules: add "do not edit" comment + rules: Fedora update + rules_generator: skip random MAC addresses + write changed network interface names to the kernel log + +Matthias Schwarzott (3): + rules: Gentoo update + fix inotify to work not only once + rules: Gentoo update + +Richard Hughes (1): + Makefile: add "make dist" for nightly snapshots + + +Summary of changes from v112 to v113 +============================================ + +David Zeuthen (1): + vol_id: do not fail if unable to drop privileges + +Kay Sievers (12): + add missing ChangeLog + make ATTR{[$SUBSYSTEM/$KERNEL]}="" working + rules: recognize partitions and disk devices properly + rules: SUSE update + atomically replace existing nodes and symlinks + do not try to create existing file + info() for ignore_remove + rules: SUSE update + Makefile: check for missing ChangeLog or RELEASE-NOTES at release + allow to disable the replacement of unusual characters + no newline in log messages + udevd: do not use syslog if --verbose (debugging) is used + +Tobias Klauser (1): + fix typo in udev_utils_run.c + + +Summary of changes from v111 to v112 +============================================ + +Fabio Massimo Di Nitto (1): + rules: ignore partitons that span the entire disk + +Hannes Reinecke (1): + cciss device support + +Kay Sievers (34): + udevd: close /proc/meminfo after reading + create_floppy_devices: remove dead "unlink" code + volume_id: add function documentation + udev_db: escape path names with \x00 instead of %00 + udevsettle: use long options + replace_chars: replace spaces in node name + volume_id: add and export string encoding function + vol_id: export encoded strings + rules: use encoded strings instead of skipping characters + udevtest: print message before log output + volume_id: escape % character + replace_chars: replace % character + IMPORT: do not mangle whitespace + scsi_id: do not install symlink in /sbin + rules: SUSE update + volume_id: terminate overlong label strings + scsi_id: add long options + rules: use long options for scsi_id + path_id: skip subsystem directory + rules: fix cciss rule + rules: SUSE update + scsi_id: fix typo in help text + fix "do not access parent" warning for ATTR{} + sysfs: add device lookup by $SUBSYSYTEM:$KERNEL + events for "bus" and "class" registration must be matched as "subsystem" + udevtest: add --subsystem option + sysfs: change order of subsystem lookup + add $sys substitution + add TEST=="" key + add "[$SUBSYSTEM/$KERNEL]" lookup + sysfs: handle bus/class top-level directories + sysfs: skip unknown sysfs directories + rules: SUSE update + release 112 + +Miklos Vajna (2): + create_floppy_devices: add man page + path_id: remove on make uninstall + +Ryan Lortie (1): + volume_id: support for long-filename based labels + +Scott James Remnant (2): + replace_untrusted_chars: replace all whitespace with space + run_program: log "info" not "error" if program is missing + + +Summary of changes from v110 to v111 +============================================ + +Kay Sievers (19): + rules: SUSE update + rules: Fedora update + volume_id: use md native uuid format + vol_id: use long options + volume_id: add volume_id_get_* functions + vol_id: use volume_id_get_* + udevd: use fgets() to read /proc files + volume_id: add internal UUID_STRING + volume_id: add DDF support + vol_id: README update + volume_id: rename UUID_64BIT_LE/BE + vol_id: add ID_FS_UUID_SAFE + rules: use ID_FS_UUID_SAFE + rules: SUSE update + volume_id: give access to list of all available probers + vol_id: use libvolume_id prober list for --probe-all + volume_id: add remaining names for prober lookup by type + rules: SUSE update + volume_id: vol_id depends on libvolume_id + +Matthias Schwarzott (2): + volume_id: fix Makefile for parallel make + rules: Gentoo update + + +Summary of changes from v109 to v110 +============================================ + +Harald Hoyer (1): + udevcontrol: allow to set global variables in udevd + +Kay Sievers (13): + remove eventrecorder.sh + update SUSE rules + volume_id: add md metadata 1.0, 1.1, 1.2 support + unset variable with ENV{VAR}="" + delete copies of default rules in SUSE rules + volume_id: ext - fix endianess in version number + rules: Fedora update + volume_id: old md metadata has only 32 bit for the uuid + volume_id: minix version 3 support + don't create $tempnode for devices without major + usb_id: add to help text + ata_id: use getopt_long() + rules: SUSE update + +Matthias Schwarzott (3): + Makefile: respect CFLAGS/LDFLAGS + rules: Gentoo update + ata_id: don't log error for libata devices on older kernels + + +Summary of changes from v108 to v109 +============================================ + +Harald Hoyer (1): + create_floppy_devices: create nodes with correct selinux context + +Kay Sievers (11): + udevtest: export ACTION string if given as option + update SUSE rules + make ACTION!="add|change" working + udevtest: import uevent variables if possible + udevinfo: export all information stored in database + default rules: add libata compat links + create_path: don't fail if something else created the directory + udevd: fix serialization of events + path_id: remove broken example + libvolume_id: do not install static library + update SUSE rules + +Matthias Schwarzott (2): + update Gentoo rules + persistent device naming: add joystick links + +VMiklos (1): + path_id: add man page + + +Summary of changes from v107 to v108 +============================================ + +Kay Sievers (3): + udevinfo: relax check for the correct device if looked up by name + don't write to sysfs files during test run + finally remove the directory event-multiplexer crap + +Matthias Schwarzott (2): + write_cd_rules: set default link type to "by-id" for usb and ieee1394 devices + update Gentoo rules + +Pozsar Balazs (1): + udevsettle: read udev not kernel seqnum first + + +Summary of changes from v106 to v107 +============================================ + +Jean Tourrilhes (1): + udevtest: export UDEV_LOG if we changed it + +Kay Sievers (33): + man: add missing options to various man pages + man: fix typo + create_floppy_devices: apply specified mode without umask + man: spelling fixes + udevmonitor: add switch for kernel and udev events + default rules: wait for 0:0:0:0 scsi devices only + update Fedora rules + delete dasd_id, it moved to s390-tools + update Gentoo rules + encode db-file names, instead of just replacing '/' + update internal variables if we see $DEVPATH during IMPORT + increase /proc/stat buffer + maintain index over device-names to devpath relation + restore overwritten symlinks when the device goes away + store devpath with the usual leading slash + add link_priority to rule options, and store it in database + pick actual valid device in udev_db_lookup_name + cleanup already existing db-entries and db-index on device update + selinux: move selinux_exit() to the main programs + remove old error message + read list of devices from index, make index private to database + priority based symlink handling + volume_id: get rid of compiler warning + udevinfo: remove -d option + update %n on netif name change + if a node goes away, possibly restore a waiting symlink + update TODO + man: add "link_priority" option + update SUSE rules + udevtest: add --force mode + udevinfo: print link priority + usb_id: append target:lun to storage device serial + run_directory: add final warning before removal + +Marco d'Itri (1): + update Debian rules + +Matthias Schwarzott (2): + udevd: cleanup std{in,our,err} on startup + udevmonitor: fix swapped event switch descriptions + + +Summary of changes from v105 to v106 +============================================ + +A. Costa (1): + man: fix typos in scsi_id and udevd + +Andrey Borzenkov (2): + vol_id: add -L to print raw partition label + vol_id: document -L + +Jamie Wellnitz (1): + persistent device naming: tape devices and medium changers + +Kay Sievers (15): + exclude parent devices from DRIVER== match + volume_id: really fix endianess bug in linux_raid detection + release 105 + man: correct udevinfo --export-db + path_id: append LUN to iSCSI path + create_floppy_devices: add option for owner/group + update example rules + apply format chars to ATTR before writing to sysfs + add (subsystem) to udevmonitor output + update DRIVER== changes + remove --version from the udevinfo man page + add test for an attribute which contains an operator char + man: add note about parent matching behavior + scsi_id: accept tabs in /etc/scsi_id.conf + remove dead rule in persistent tape rules + +Matthias Schwarzott (4): + correct typo in extras/scsi_id/scsi_id.conf + fix retry-loop in netif-rename code + add option --version to udevd + rule_generator: fix for creating rules on read-only filesystem + +Peter Breitenlohner (1): + fix INSTALL_PROGRAM vs. INSTALL_SCRIPT + +Sergey Vlasov (3): + udevd: init signal pipe before daemonizing + unlink old database file before creating a new one + fix %c $string substitution + +Theodoros V. Kalamatianos (1): + fix udev attribute names with a colon + + +Summary of changes from v104 to v105 +============================================ + +A. Costa (1): + man: fix typos in scsi_id and udevd + +Andrey Borzenkov (2): + vol_id: add -L to print raw partition label + vol_id: document -L + +Kay Sievers (2): + exclude parent devices from DRIVER== match + volume_id: really fix endianess bug in linux_raid detection + +Matthias Schwarzott (2): + correct typo in extras/scsi_id/scsi_id.conf + fix retry-loop in netif-rename code + +Peter Breitenlohner (1): + fix INSTALL_PROGRAM vs. INSTALL_SCRIPT + +Sergey Vlasov (3): + udevd: init signal pipe before daemonizing + unlink old database file before creating a new one + fix %c $string substitution + + +Summary of changes from v103 to v104 +============================================ + +Kay Sievers (12): + update Fedora rules + update example rules + update SUSE rules + update SUSE rules + volume_id: fix endianess bug in linux_raid detection + man: fix udevmonitor text + man: recreate from xml + rename config "filename" to "dir" + remove outdated documentation + rename "udev.c" to "test-udev.c" - it is only for testing + update Fedora rules + use git-archive instead of git-tar-tree + +Kazuhiro Inaoka (1): + inotify syscall definitions for M32R + +Marco d'Itri (2): + write_cd_rules: identity-based persistence + scsi_id: remove trailing garbage from ID_SERIAL_SHORT + +Russell Coker (1): + SELinux: label created symlink instead of node + + +Summary of changes from v102 to v103 +============================================ + +Kay Sievers: + persistent storage rules: skip gnbd devices + volume_id: add checksum check to via_raid + volume_id: add comment about hfs uuid conversion + update SUSE rules + update Fedora rules + + +Summary of changes from v101 to v102 +============================================ + +Daniel Drake: + writing_udev_rules: fix typo in example rule + +Kay Sievers: + create missing ChangeLog for version 101 + update SUSE rules + update default rules + first try "subsystem" link at a parent device, before guessing + if /sys/subsystem exists, skip class, bus, block scanning + scsi_id: export ID_SERIAL_SHORT without vendor/product + update SUSE rules + +MUNEDA Takahiro: + path_id: fix SAS disk handling + + +Summary of changes from v100 to v101 +============================================ + +Arjan Opmeer: + fix udevinfo help text typo + +Bryan Kadzban: + cleanup default rules + add IMPORT operations to the udev man page + +Kay Sievers: + remove Makefile magic for leading '0' in version + udevd: use getopt_long() + udevd: add --verbose option to log also to stdout + udevd: add --debug-trace option + rule_generator: improve net rule comment generation + volume_id: correct iso9660 high sierra header + warn if a PHYSEDV* key, the "device" link, or a parent attribute is used + don't print PHYSDEV* warnings for old WAIT_FOR_SYSFS rules + udevinfo: print error in --attribute-walk + udev_sysfs: unify symlink resolving + udevtrigger: trigger devices sorted by their dependency + fix spelling in deprecation warning + release 101 + +Michał Bartoszkiewicz: + udevtrigger: fix typo that prevents partition events + +Miles Lane: + clarify "specified user/group unknown" error + +Piter PUNK: + update slackware rules + +VMiklos: + update Frugalware rules + + +Summary of changes from v099 to v100 +============================================ + +Kay Sievers: + update SUSE rules + fix messed up ChangeLog from release 099 + man: add $attr{} section about symlinks + revert persistent-storage ata-serial '_' '-' replacement + + +Summary of changes from v098 to v099 +============================================ + +Greg KH: + update Gentoo rules + +Kay Sievers: + udev_db.c: include + use fnmatch() instead of our own pattern match code + rename major/minor variable to maj/min to avoid warning + update source file headers + udevtest: print header that ENV{} can't work + update TODO + udevtrigger: options to filter by subsystem and sysfs attribute + udevtrigger: remove unused longindex + udevinfo: use long options + udevd: use files instead of symlinks for /dev/.udev/queue,failed + udevtrigger: fix pattern match + reorder options in udevinfo man page + udevinfo: fix SUBSYTEMS spelling error + fix ENV{TEST}="Test: $env{TEST}" + let $attr{symlink} return the last element of the path + cdrom_id: add rules file to call cdrom_id + udevinfo: do not show symlinks as attributes in --attribute-walk + remove broken name_cdrom.pl + +Marco d'Itri: + update Debian rules + run_program: close pipe fd's which are connected to child process + add persistent rules generator for net devices and optical drives + +MUNEDA Takahiro: + changes rules for ata disk from '_' to '-' + +Sergey Vlasov: + make struct option arrays static const + fix "subsytem" typo + + +Summary of changes from v097 to v098 +============================================ + +Alex Merry: + udevtest: allow /sys in the devpath paramter + +Harald Hoyer: + selinux: init once in the daemon, not in every event process + +Kay Sievers: + udevd: remove huge socket buffer on the control socket + man page: fix typo + rename udev_libc_wrapper -> udev_sysdeps + db: store devpath - node relationship for all devices + udevinfo: allow -a -n + udevinfo, udevtest: simplify '/sys' stripping from devpath argument + lookup_user, lookup_group: report "unknown user" and "lookup failed" + consistent key naming to match only the event device or include all parent devices + skip rule, if too may keys of the same type are used + introduce ATTR{file}="value" to set sysfs attributes + update SUSE rules + update default rules + export DRIVER for older kernels as a replacement for PHYSDEVDRIVER + fix typo in SUBSYSTEMS key parsing + udevtrigger: add --retry-failed + volume_id: add suspend partition detection + vol_id: use primary group of 'nobody' instead of 'nogroup' + remove built-in /etc/passwd /etc/group parser + always expect KEY{value} on ATTR, ATTRS, ENV keys + use new key names in test programs + cleanup commandline argument handling + db: don't create a db file for only a node name to store + man: add ATTR{file}="value" assignment + +Lennart Poettering: + volume_id: fix fat32 cluster chain traversal + +Marco d'Itri: + fix 'unknow user' error from getpwnam/getgrnam + fix rc when using udev --daemon + update Debian rules + +Michał Bartoszkiewicz: + man pages: fix typos + + +Summary of changes from v096 to v097 +============================================ + +Anssi Hannula: + add joystick support to persistent input rules + +Kay Sievers: + firmware.sh: remove needless '/' + vol_id: add --skip-raid and --probe-all option + switch uevent netlink socket to group 1 only + increase /proc/stat read buffer + use "change" instead of "online" events + remove 'static' from local variable + libvolume_id: add parameter 'size' to all probe functions + man pages: replace 'device-path' by 'devpath' + man pages: work around xmlto which tries to be smart + refresh vol_id man page + udevinfo: add DRIVER== + Makefile: fix dependency + libvolume_id: read ufs2 label + switch ifdef __KLIBC__ to ifndef __GLIBC__ + report failing getpwnam/getgrnam as error + rename udevcontrol message types and variables + initialize unused sockets to -1 + udevd: remove useless udevinitsend parameter + update README + udevd: autotune max_childs/max_childs_running + update frugalware rules + update SUSE rules + move default rules to etc/udev/rules.d/ + add 'crypto' devices to persistent storage rules + add late.rules to default rules + update Fedora rules + don't report an error on overlong comment lines + update SUSE rules + udevd: read DRIVER from the environment + +Marco d'Itri: + make rename_netif() error messages useful + path_id: fix an harmless syntax error + +Piter PUNK: + update slackware rules + +Richard Purdie: + Fix inotify syscalls on ARM + + +Summary of changes from v095 to v096 +============================================ + +Kay Sievers: + Makefiles: fix .PHONY for man page target + allow longer devpath values + path_id: prepare for new sysfs layout + + +Summary of changes from v094 to v095 +============================================ + +Kay Sievers: + update SUSE rules + don't remove symlinks if they are already there + allow "online" events to create/update symlinks + udevinfo: clarify parent device attribute use + update SUSE rules + netif rename: optimistic loop for the name to become free + remove broken %e enumeration + +Tobias Klauser: + print usage of udevcontrol when no or invalid command is given + + +Summary of changes from v093 to v094 +============================================ + +Daniel Drake: + update "writing udev rules" + +Kay Sievers: + libvolume_id: gfs + gfs2 support + remove MODALIAS key and substitution + add persistent-input.rules + +Marco d'Itri: + update Debian rules + + +Summary of changes from v092 to v093 +============================================ + +Hannes Reinecke: + path_id: add support for iSCSI devices + +Kay Sievers: + libvolume_id: fat - check for signature at end of sector + libvolume_id: add more software raid signatures + update Fedora rules + path_id: prevent endless loop for SAS devices on older kernels + remove udevsend + replace binary firmware helper with shell script + skip device mapper devices for persistent links + + +Summary of changes from v091 to v092 +============================================ + +Kay Sievers: + don't include stropts.h, some libc's don't like it + udevd: create leading directories for /dev/.udev/uevent_seqnum + vol_id: fix logging from libvolume_id's log function + update SUSE rules + update SUSE rules + add more warnings for invalid key operations + fix offsetof() build issue with recent glibc + selinux: fix typo in block device node selection + vol_id: add NetWare volume detection + edd_id: fix "(null)" output if "mbr_signature" does not exist + update Fedora rules + libvolume_id: nss - use different uuid + +Libor Klepac: + path_id: add platform and serio support + +Marco d'Itri: + update Debian rules + path_id: fix bashism + + +Summary of changes from v090 to v091 +============================================ + +Hannes Reinecke: + path_id: fix SAS device path generation + +Kay Sievers: + udevtest: don't try to delete symlinks + persistent rules: fix typo in dm rule + allow NAME=="value" to check for already assigned value + udevd: export initial sequence number on startup + + +Summary of changes from v089 to v090 +============================================ + +Kay Sievers: + udevd: export current seqnum and add udevsettle + volume_id: fix endianess conversion typo for FAT32 + merge device event handling and make database content available on "remove" + set default udevsettle timeout to 3 minutes + export INTERFACE_OLD if we renamed a netif + let udevmonitor show the possibly renamed devpath + volume_id: move some debug to info level + udevtrigger: fix event order + usb_id: remove uneeded code + remove old symlinks before creating current ones + path_id: fix loop for SAS devices + apply format char to variables exported by ENV + +Marco d'Itri: + add inotify support for hppa and MIPS and log if inotify is not available + +Matt Kraai: + fix typo in error message + + +Summary of changes from v088 to v089 +============================================ + +Hannes Reinecke: + path_id: add bus to USB path + +Kay Sievers: + change rule to skip removable IDE devices + don't create uuid/label links for raid members + volume_id: provide library + fix rule order for persistent tape links + update man page + volume_id: provide a custom debug function + volume_id: rename subdirectory + volume_id: use shared library by default + because is better than cause + volume_id: remove some global symbols + volume_id: define exported symbols + remove all stripping code + man pages: mention udev(7) not udev(8) + update Debian rules + move all *_id programs to /lib/udev/ + update Red Hat rules + update SUSE rules + pass CROSS_COMPILE to AR and RANLIB down to extras/ + volume_id: update README + volume_id: generate man page from xml source + update README + fix symlink targets in Makefiles + + +Summary of changes from v087 to v088 +============================================ + +Hannes Reinecke: + persistent links: add scsi tape links and usb path support + +Kay Sievers: + volume_id: add squashfs detection + reset signal handler in event process + correct use of fcntl() + add udevtrigger to request events for coldplug + add ',' to trusted chars + volume_id: remove partition table parsing code + volume_id: remove all partition table support + fix spelling error in debug string + rename "persistent disk" to "persistent storage" + fix output for USB path + + +Summary of changes from v086 to v087 +============================================ + +Hannes Reinecke: + path_id: support SAS devices + +Kay Sievers: + fix persistent disk rules to exclude removable IDE drives + warn about %e, MODALIAS, $modalias + remove devfs rules and scripts + +Masatake YAMATO: + typo in debug text in udev_run_hotplugd.c + + +Summary of changes from v085 to v086 +============================================ + +Kay Sievers: + volume_id: replace __packed__ by PACKED macro + volume_id: split raid and filesystem detection + volume_id: add missing return + udevd: fix queue export for multiple events for the same device + +Kyle McMartin: + workaround missing kernel headers for some architectures + +Nix: + update to udev-084/doc/writing_udev_rules + + +Summary of changes from v084 to v085 +============================================ + +Andrey Borzenkov: + Fix trivial spelling errors in RELEASE-NOTES + +Jeroen Roovers: + fix typo in parisc support to path_id + +Kay Sievers: + make WAIT_FOR_SYSFS usable in non "wait-only" rules + fix typo in man page + include sys/socket.h for klibc build + cramfs detection for bigendian + exit WAIT_FOR_SYSFS if the whole device goes away + update SUSE rules + update Red Hat rules + update Gentoo rules + include errno.h in udev_libc_wrapper.c + + +Summary of changes from v083 to v084 +============================================ + +Kay Sievers: + update SUSE rules + switch CROSS to CROSS_COMPILE + replace fancy silent build program by simple kernel build like logic + move manpages to top level + remove UDEVD_UEVENT_INITSEND + whitespace fixes + scsi_id: remove dead files + optimize sysfs device and attribute cache + let SYSFS{} look at the device, not only the parent device + add debug output to sysfs operations + + +Summary of changes from v082 to v083 +============================================ + +Andrey Borzenkov: + man page: document when substitutions are applied for RUN and other keys + check for ignore_device in loop looks redundant + +Kay Sievers: + udevstart: fix NAME="" which prevents RUN from being executed + find programs in /lib/udev for IMPORT if {program} is not given + don't add $SUBSYSTEM automatically as $1 to programs + remove redundant substitution of RUN key + + +Summary of changes from v081 to v082 +============================================ + +Andrey Borzenkov: + substitute format chars in RUN after rule matching + +Kay Sievers: + scsi_id, usb_id: request device parent by subsystem + path_id: work with "all devices in /sys/devices" + ignore all messages with missing devpath or action + Makefile: remove dynamic config file generation + path_id: handle fiber channel (Hannes Reinecke ) + usb_id: don't fail on other subsytems than "scsi" + don't do RUN if "ignore_device" is given + increase kernel uevent buffer size + move udev(8) manpage to udev(7) + recreate man pages from xml source + remove udev, udevstart, udevsend from the default installation + update SUSE rules + rename apply_format() cause it is public now + udevtest: add udev_rules_apply_format() to RUN keys + let "ignore_device" always return the event successfully + +Olivier Blin: + fixes udev build with -fpie + + +Summary of changes from v080 to v081 +============================================ + +Kay Sievers: + add DEVLINKS to "remove" event + better log text and comments + vol_id: probe volume as user nobody + fix BUS, ID, $id usage + prepare moving of /sys/class devices to /sys/devices + + +Summary of changes from v079 to v080 +============================================ + +Brent Cook: + fix dependency for make -j2 + +coly: + fix man page typos + +Kay Sievers: + update RELEASE-NOTES + TODO + fix typo in man page + update TODO + update SUSE rules + path_id: fix invalid character class + replace libsysfs + +Marco d'Itri: + udev_selinux.c: include udev.h + + +Summary of changes from v078 to v079 +============================================ + +Kay Sievers: + don't log error if database does not exist + use udev_root instead of "/dev"in selinux matchpathcon_init_prefix() + scsi_id: read page 0x80 with libata drives + update SUSE rules + remove %e from man page + + +Summary of changes from v077 to v078 +============================================ + +Greg Kroah-Hartman: + Update Gentoo udev main rule file. + add parisc support to path_id + +Hannes Reinecke: + scsi_id: -u fold multiple consecutive whitespace chars into single '_' + +Harald Hoyer: + optimize SELinux path match + +Kay Sievers: + update README + allow C99 statements + fix segfaulting create_floppy_devices + update SUSE rules + remove unused variables + remove default settings in udev.conf + clearenv() is now part of klibc + add DEVLINKS to the event environment + +Kurt Garloff: + scsi_id: support pre-SPC3 page 83 format + + +Summary of changes from v076 to v077 +============================================ + +Kay Sievers: + merge two consecutive static strlcat's + don't return an error, if "ignore_device" is used + remove outdated and misleading stuff + move SEQNUM event skipping to udevsend + update RELEASE-NOTES + update SUSE rules + allow programs in /lib/udev called without the path + update SUSE rules + add target to to generate ChangeLog section + update Red Hat rules + +Marco d'Itri: + allow to overwrite the configured udev_root by exporting UDEV_ROOT + let udevsend ignore events with SEQNUM set + update Debian rules + + +Summary of changes from v75 to v076 +============================================ + +Kay Sievers: + fix typo in eventrecorder + volume_id: include stddef.h header + remove misleading install instructions + remove all built-in wait_for_sysfs logic + add linux/types.h back, old glibc-kernel-headers want it + volume_id: use glibc's byteswap + udevd: ignore all messages without DEVPATH + udevd: track exit status of event process + udevd: export event queue and event state + remove "udev_db" option from config file + Makefile: remove exec_prefix and srcdir + update README and RELEASE-NOTES + udevd: track killed event processes as failed + update README + don't start udevd from udevsend + udevd: add a missing return + libvolume_id: fix weird fat volume recognition + move some helpers from extras to /lib/udev + +Scott James Remnant: + move delete_path() to utils + clean-up empty queue directories + Makefile: fail, if submake fails + + +Summary of changes from v74 to v075 +============================================ + +Greg Kroah-Hartman: + Make run_directory.c stat the place it is going to try to run. + +Kay Sievers: + forgot the ChangeLog for 074 + volume_id: provide libvolume_id.a file + remove our own copy of klibc + remove outdated HOWTO + update TODO + update SUSE rules + remove completely useless start script + fix tests and remove no longer useful stuff + replace udeveventrecorder by a shell script + + +Summary of changes from v73 to v074 +============================================ + +Kay Sievers: + never queue events with TIMEOUT set + let NAME="" supress node creation, but do RUN keys + remove udevinitsend + update .gitignore + +Marco d'Itri: + add strerror() to error logs + move some logging from dbg() to info() + + +Summary of changes from v72 to v073 +============================================ + +Kay Sievers: + udevd: depend on netlink and remove all sequence reorder logic + print useconds in udevmonitor + add RELEASE-NOTES, update TODO + + +Summary of changes from v71 to v072 +============================================ + +Ananth N Mavinakayanahalli: + libsysfs: translate devpath of the symlinked class devices to its real path + +Jan Luebbe: + add man pages for *_id programs + +Kay Sievers: + volume_id: add OCFS Version 1 + volume_id: add Veritas fs + volume_id: check ext fs for valid blocksize, cause magic is only 2 bytes + volume_id: move blocksize validation to fix jbd recognition + volume_id: fix typo in ocfs + volume_id: add vxfs include + volume_id: make FAT32 recognition more robust + volume_id: Version 051 + volume_id: fix typo in ext blocksize check + volume_id: Version 052 + FAQ: remove confusing statement about module loading + cleanup compiler/linker flags + use DESTDIR on uninstall, no need to pass prefix to submake + allow to pass STRIPCMD, to skip stripping of binaries + cleanup make release + fix the new warnings I asked for + move rules parsing into daemon + "make STRIPCMD=" will disable the stripping of binaries + remove no longer working udevd-test program + "STRIPCMD=" for the EXTRAS + add dummy inotify syscalls on unsupported architecture + remove no longer needed waiting for "dev" file + revert the "read symlink as device patch" + use libsysfs to translate the class linke to the device path + libsysfs: remove brute-force "bus", "driver" searching for old kernels + test: add "driver" and "bus" links to test sysfs tree + update RELEASE-NOTES + udevd: don't daemonize before initialization + log to console if syslog is not available + udevd: disable OOM + remove precompiled rules option + export DEVNAME on "remove" only if we really got a node to remove + fix typo in umask() + + +Summary of changes from v70 to v071 +============================================ + +Greg Kroah-Hartman: + Remove the udev.spec file as no one uses it anymore + +John Hull: + edd_id: check that EDD id is unique + +Kay Sievers: + ata_id: open volume O_NONBLOCK + add "Persistent Device Naming" rules file for disks + scsi_id: switch temporary node creation to /dev + volume_id: set reiser instead of reiserfs for filesystem type + update devfs rules header + update Debian rules + update Fedora rules + update Debian rules + remove no longer needed includes + switch tools and volume_id from LGPL to GPLv2 + add edd-*-part%n to the persistent.rules + update Debian persistent rules + clarify README + udevd: fix initial timeout handling + force event socket buffer size to 16MB + udevd: move logging from err to info for non-hotplug uevent + fix selinux compilation + libsysfs: accept sysmlinks to directories instead of real directories + +Marco d'Itri: + run_directory: fix typo in "make install" + + +Summary of changes from v069 to v070 +============================================ + +Amir Shalem: + udevd: fix udevd read() calls to leave room for null byte + +Edward Goggin: + scsi_id: derive a UID for a SCSI-2 not compliant with the page 83 + +Greg Kroah-Hartman: + fix nbd error messages with a gentoo rule hack + fix scsi_id rule in gentoo config file + +Jürg Billeter: + EXTRAS/Makefile: fix install targets to match main Makefile + +Kay Sievers: + volume_id: fix error handling with failing read() + EXTRAS: cleanup and sync all Makefiles + add install test to 'make buildtest' + update RELEASE-NOTES + +Olivier Blin: + fix a debug text typo in udev_rules.c + + +Summary of changes from v068 to v069 +============================================ + +Amir Shalem: + fix typo in firmware_helper + +Duncan Sands: + firmware_helper: fix write count + +Kay Sievers: + *_id: fix zero length in set_str() + add program name to logged error + fix exit code of udevinitsend and udevmonitor + udevd: keep the right order for messages without SEQNUM + volume_id: don't probe for mac_partition_maps + udevmonitor: cleanup on exit + path_id: remove SUSE specific PATH + update SUSE rules + add pci_express to bus list + update SUSE rules + store ENV{key}="value" exported keys in the database + fix lookup for name in the udevdb, it should return the devpath + prepare for new HAL udevdb dump + print persistent data with "udevinfo -q all" + change parameter order of udev_db_search_name() + add and use name_list_cleanup() for cleaning up the string lists + don't store devpath in udevdb, we don't need it + add uft8 validation for safe volume label exporting + start to enforce plain ascii or valid utf8 + use WRITE_END/READ_END for the pipe index + remove not needed sig_flag for state of signal_pipe + don't reenter get_udevd_msg() if message is ignored + rename ...trailing_char() to ...trailing_chars() + vol_id: ID_LABEL_SAFE will no longer contain fancy characters + udevd: move some logging to "info" and "err" + remove special TIMEOUT handling from incoming queue + udev_test.pl: we replace untrusted chars with '_' + check the udevdb before assigning a new %e + update RELEASE-NOTES + udevinfo: add database export + write man page masters in DocBook XML + udevinfo: rename dump() to export() + test the automatic man page rebuild and checkin + Makefile: remove all the duplicated rules + all man pages rewritten to use DocBook XML + add missing udevsend man page + also forgot udevmonitor.8 + udevinfo: restore -d option + scsi_id: rename SYSFS to LIBSYSFS + add edd_id tool to match BIOS EDD disk information + move and update libsysfs.txt + klibc: update to version 1.1.1 + delete cdromsymlinks* - obsoleted by cdrom_id and IMPORT rules + delete docs/persistent_naming - obsoleted by persistent disk names + delete old Fedora html page + add "totally outdated" header to docs/overview :) + update SUSE rules + fix useless but funny name_cdrom.pl script to work again + update TODO + Makefile: fix prerequisits for $(PROGRAMS) + Makefile: cleanup install targets + remove chassis_id program + fic gcov use and move it into the Makefile + FAQ: update things that have changed + +Thierry Vignaud: + switch to '==' in raid-devfs.sh + + +Summary of changes from v067 to v068 +============================================ + +Greg Kroah-Hartman: + add EXTRAS documentation to the README file. + Always open the cdrom drive in non-blocking mode in cdrom_id + cdrom_id: change err() to info() to help with debugging problems + +Kay Sievers: + cleanup some debug output and move to info level + unify select() loops + move udevmonitor to /usr/sbin + ENV{TEST}=="1" compares and ENV{TEST}="1" sets the environment + vol_id: fix sloppy error handling + fix typo in cdrom_id syslog + bring std(in|out|err) fd's in a sane state + fix printed udevmonitor header + + +Summary of changes from v066 to v067 +============================================ + +Greg Kroah-Hartman: + added the cdrom.h #defines directly into the cdrom_id.c file + +Kay Sievers: + update SUSE rules + fix make install, as we don't provide a default rule set anymore + fix more compiler warnings ... + fix udevstart event ordering, we want /dev/null very early + don't fail too bad, if /dev/null does not exist + + +Summary of changes from v065 to v066 +============================================ + +Greg Kroah-Hartman: + update gentoo rule file. + Created cdrom_id program to make it easier to determine cdrom types + added cdrom_id to the build check + updated gentoo rule file to handle removable ide devices. + changed cdrom_id exports to be easier to understand and consistant with other _id programs. + fix klibc build issue in cdrom_id.c + Change the gentoo rules to use cdrom_id instead of cdsymlink.sh + changed location of gentoo helper apps to be /sbin instead of in scripts dir + tweak the gentoo rules some more. + +Kay Sievers: + add NETLINK define for the lazy distros + read sysfs attribute also from parent class device + switch some strlcpy's to memcpy + allow clean shutdown of udevd + add flag for reading of precompiled rules + update distro rules files + add SUSE rules + update SUSE rules + add firmware_helper to load firmware + more distro rules updates + update README + remove example rules and put the dev.d stuff into the run_directory folder + trivial text cleanups + update SUSE rules + split udev_util in several files + update SUSE rules + allow logging of all output from executed tools + add Usage: to udevmonitor and udevcontrol + move some logging to the info level + +Thierry Vignaud: + fix udevinfo output + + +Summary of changes from v064 to v065 +============================================ + +Greg Kroah-Hartman: + Added persistent name rules for block devices to gentoo rule file. + Added horrible (but fun) path_id script to extras. + Update gentoo rules file. + +Kay Sievers: + update release notes for next version + add udevmonitor, to debug netlink+udev events at the same time + allow RUN to send the environment to a local socket + fix GGC signed pointer warnings and switch volume_id to stdint + + +Summary of changes from v063 to v064 +============================================ + +Andre Masella: + volume_id: add OCFS (Oracle Cluster File System) support + +Hannes Reinecke: + usb_id: fix typo + add ID_BUS to *_id programs + create_floppy_devices: add tool to create floppy nodes based on sysfs info + +Kay Sievers: + move code to its own files + make SYSFS{} usable for all devices + add padding to rules structure + allow rules to have labels and skip to next label + thread unknown ENV{key} match as empty value + + +Summary of changes from v062 to v063 +============================================ + +Anton Farygin: + fix typo in GROUP value application + +Greg Kroah-Hartman: + add 'make tests' as I'm always typing that one wrong... + Really commit the udev_run_devd changes... + Fixed udev_run_devd to run the /etc/dev.d/DEVNAME/ files too + fix position of raw rules in gentoo config file + +Hannes Reinecke: + dasd_id: add s390 disk-label prober + fix usb_id and let scsi_id ignore "illegal request" + +Kay Sievers: + volume_id: remove s390 dasd handling, it is dasd_id now + trivial fixes for *_id programs + IMPORT: add {parent} to import the persistent data of the parent device + allow multiple values to be matched with KEY=="value1|value2" + udevd: set incoming socket buffer SO_RCVBUF to maximum + remember mapped rules state + ata_id: check for empty serial number + compile dasd only on s390 + +Ville Skyttä: + correct default mode documentation in udev + + +Summary of changes from v061 to v062 +============================================ + +Kay Sievers: + fix symlink values separated by multiple spaces + update RELEASE-NOTES + fix typo in group assignment + fix default-name handling and NAME="" rules + add WAIT_FOR_SYSFS key to loop until a file in sysfs arrives + fix unquoted strings in udevinitsend + +Summary of changes from v060 to v061 +============================================ + +Greg Kroah-Hartman: + Sync up the Debian rules files + fix cdrom symlink problem in gentoo rules + Fix ChangeLog titles + +Kay Sievers: + update RELEASE-NOTES + we want to provide OPTFLAGS + rename ALARM_TIMEOUT to UDEV_ALARM_TIMEOUT + udevd: optimize env-key parsing + don't resolve OWNER, GROUP on precompile if string contains %, $ + set default device node to /dev + create udevdb files only if somehting interesting happened + pack parsed rules list + replace useless defines by inline text + move rule matches to function + add usb_id program to generate usb-storage device identifiers + add IEEE1394 rules to the gentoo rule file + fake also kernel-name if we renamed a netif + allow OPTIONS to be recognized for /sys/modules /sys/devices events + switch gentoo rules to new operators + + +Summary of changes from v059 to v060 +============================================ + +Greg Kroah-Hartman: + Fix the gentoo udev rules to allow the box to boot properly + +Gustavo Zacarias: + Udev doesn't properly build with $CROSS + +Kay Sievers: + Keep udevstart from skipping devices without a 'dev' file + +Marco d'Itri: + #define NETLINK_KOBJECT_UEVENT + + +Summary of changes from v058 to v059 +============================================ + +Greg Kroah-Hartman: + Update the gentoo rule file + Fix udevinfo for empty sysfs directories + Fix makefile to allow 'make release' to work with git + +Hannes Reinecke: + udev: fix netdev RUN handling + udevcontrol: fix exit code + +Kay Sievers: + prepare RELEASE-NOTES + add ID_TYPE to the id probers + add -x to scsi_id to export the queried values in env format + store the imported device information in the udevdb + rename udev_volume_id to vol_id and add --export option + add ata_id to read serial numbers from ATA drives + IMPORT allow to import program returned keys into the env + unify execute_command() and execute_program() + IMPORT= allow to import a shell-var style config-file + allow rules to be compiled to one binary file + fix the fix and change the file to wait for to the "bus" link + fix udevstart and let all events trvel trough udev + prepare for module loading rules and add MODALIAS key + remove device node, when type block/char has changed + Makefile: remove dev.d/ hotplug.d/ from install target + udevcontrol: add max_childs command + udevd: control log-priority of the running daemon with udevcontrol + udeveventrecorder: add small program that writes an event to disk + klibc: add missing files + udevinitsend: handle replay messages correctly + udev man page: add operators + udevd: allow starting of udevd with stopped exec-queue + klibc: version 1.0.14 + udev: handle all events - not only class and block devices + volume_id: use udev-provided log-level + udev: clear lists if a new value is assigned + udev: move dev.d/ handling to external helper + udev: allow final assignments := + udevd: improve timeout handling + Makefile: fix DESTDIR + udevd: add initsend + udevd: add udevcontrol + udevd: listen for netlink events + +Stefan Schweizer: + Dialout group fix for capi devices in the gentoo rules file + +Summary of changes from v057 to v058 +============================================ + +Daniel Drake: + o Writing udev rules docs update + +Darren Salt: + o update cdsymlinks to latest version + +Greg Kroah-Hartman: + o remove detach_state files from the sysfs test tree + o Update permissions on test scripts so they will run properly now + o hopefully fix up the symlinks in the test directory + o Removed klibc/klibc.spec as it is autogenerated + o Added symlinks thanks to Kay's script and git hacking + o add Red Hat/Fedora html documenation + o Update Red Hat default udev rules + +Kay Sievers: + o selinux: fix handling during creation of symlinks + o Fedora udev.rules update + o libsysfs: version 2.0 + o klibc: version 1.0.7 + +Masanao Igarashi: + o Fix libsysfs issue with relying on the detach_state file to be + +Summary of changes from v056 to v057 +============================================ + +: + o fix stupid all_partitions bug + +Kay Sievers: + o add test for make -j4 to build-check + o klibc: version 1.0.6 + o update Debian rules + o apply default permissions only for devices that will need it + o adapt RELEASE-NOTES + o udev_volume_id: fix endianess macros + o udev-test.pl: add test for DEVNAME export to RUN environment + o update the man page to reflect the recent changes + o export DEVNAME to RUN-key executed programs + o fix make -j4 and the local klibc-install + o update RELEASE-NOTES + o add RUN key to be able to run rule based notification + o fix udevtest to print the error if logging is disabled + o move execute_program to utils + add action to init_device + o correct correction for error path for PROGRAM execution + o correct error path for PROGRAM execution + o klibc: version 1.0.5 + o check for strlen()==0 before accessing strlen()-1 + o allow to match against empty key values + o read %s{}-sysfs values at any device in the chain + o udev_rules.c: don't change sysfs_device while walking up the device chain + o klibc: strlcpy/strlcat - don't alter destination if size == 0 + o fix klibc's broken strlcpy/strlcat + o udevinfo: print SYSFS attribute the same way we match it + o remove untrusted chars read from sysfs-values or returned by PROGRAM + o udevinfo: print errors to stderr instead of stdout + o klibc: version 1.0.4 + o support log-priority levels in udev.conf + o test-suite: remove UDEV_TEST, it's not needed anymore + o libsysfs: remove trailing slash on SYSFS_PATH override + + +Summary of changes from v055 to v056 +============================================ + +: + o fix header paths in udev_libc_wrapper.c + +Kay Sievers: + o udev-test.pl: use more common user/group names + o klibc: remove SCCS directories from the temporary klibc install + o udev-test.pl: add a test where the group cannot be found in /etc/passwd + o udev-test.pl: add check for textual uid/gid + o fix bad typo that prevents the GROUP to be applied + o udevd: don't delay events with TIMEOUT in the environment + o klibc: use klcc wrapper instead of our own Makefile + o change call_foreach_file to return a list + + +Summary of changes from v054 to v055 +============================================ + +: + o This patch causes the remove handler to check that each symlink actually points to the correct devnode and skip it if it does not. + +: + o udev selinux fix + +: + o The following patch fixes some warnings when compiling volume_id from udev with the -Wall compiler flag. Define _GNU_SOURCE for strnlen() and correct the path to logging.h + o The following patch fixes a warning when compiling chassis_id from udev with the -Wall compiler flag. There are too much conversions in the format string of sscanf(). One %d can be dropped. + +Greg Kroah-Hartman: + o fix raid rules + o added frugalware udev ruleset + o merge selinux and Kay's symlink fixes together + +Hannes Reinecke: + o volume_id: Fix label/uuid reading for reiserfs + +Kay Sievers: + o add udevstart to the RELEASE-NOTES + o volume_id: version 43 + o clarify the shortcomings of %e + o correct rule match for devices without a physical device + o remove unneeded code, libsysfs does this for us + o add final release note + o add ENV{} key to match agains environment variables + o simplify sysfs_pair handling + o add a test and simplify debug statement + o support =, ==, !=, += for the key match and assignment + o add OPTION="last_rule" to skip any later rule + o rename namedev_dev to udev_rule + o correct enum device_type + o remove udevstart on make clean + o volume_id: version 42 + o volume_id: version 41 + o remove unneeded include + o The path to dlist.h is not correct + o udevinfo -d: use '=' as separator, cause ':' may be a part of the devpath + o klibc: version 1.0.3 + o add RELEASE-NOTES file + o test suite: move "driver" link to physical device + o remove PLACE key match + o don't lookup "root" in the userdb + o fix ia64 compile + o fix segfaulting udev while DRIVER matching + o cleanup list.h + o klibc: version 0.214 + o rename device_list->list to device_list->node + o replace strncpy()/strncat() by strlcpy()/strlcat() + o split udev and udevstart + o udev_volume_id: version 39 + o rename LOG to USE_LOG in all places + o remove Makefile magic for klibc integration + o klibc_fixups: remove no longer needed stuff + o udev_volume_id: volume_id v38 + o use numeric owner/group as default values to avoid parsing userdb + o fix up segfaulting binaries with new klibc + o udevinfo -d: speed-up device dump + o klibc: version 0.211 + o klibc_fixups: remove unneeded stuff + o replace weird defines by real code + o udev-test.pl: remove useless tests + o allow unlimitied count of symlinks + o unmap db-file after use + o remove typedef for call_foreach_file() handler function + o correct udev_init_device + o rename attributes to options + o kill stupid gcc4 warning + o trivial clenaup of namedev code + o klibc: check for gcc4 + o klibc: update v0.205 + +Thierry Vignaud: + o gentoo rule update for raid devices + + +Summary of changes from v053 to v054 +============================================ + +: + o udev_volume_id: add Reiser4 support + +Kay Sievers: + o namedev: skip backslashes only if followed by newline + o wait_for_sysfs: add joydev + o udevinfo: print devpath -> node relationship for all devices + o trivial rename of some variables + o klibc v0.199 + o big libsysfs diet (pre 2.0 version) + o udev_volume_id: volume_id v35 + o add "serio" to bus list + o determine device type in udev_init_device() + o move kernel name/number evaluation into udev_init_device() + o detect NAME="" as ignore_device rule + o trivial namedev cleanup + o cleanup db functions + o clean up match_place() + o switch device type to enum + o switch major/minor to dev_t + o remove the device node only if the major/minor number matches + o libsysfs: work around a klibc bug + o introduce OPTIONS=ignore_device, ignore_remove, all_partitions" key + o namedev: execute PROGRAM only once and not possibly for every physical device + +Patrick Mansfield: + o update scsi_id to work with libsysfs changes + + +Summary of changes from v052 to v053 +============================================ + +Greg Kroah-Hartman: + o fix gentoo fb permission issue + o allow simple-build-check.sh to go faster if MAKEOPTS is set + o make the release tarballs have writable files in them + o remove gentoo permission file as it's not valid anymore + +Kay Sievers: + o fix special file mode mask for temporary device node + o udevstart: simplify "dev" file searching + o udev_volume_id: remove temporary node creation and parent handling + o add %P modifier to query the node name of the parent device + o udev_volume_id: remove __packed__ from dasd structure as it does not work + o create /block/*/range count of partitons for all_partitions + +Patrick Mansfield: + o scsi_id changes for use with udev %N and %p + + +Summary of changes from v051 to v052 +============================================ + +: + o debian: update rules files + o raid-devfs.sh: devfs names for hardware RAID controllers + o scsi_id: when udevstart is started, /tmp is not writeable + o cdsymlinks.sh: trivial fix, the variable is initialized to '', not 0 + +: + o gentoo/udev.rules: add default permissions for sound devices + +Greg Kroah-Hartman: + o fix example comment in ide-devfs.sh + o Add infiniband to gentoo rules + o Another gentoo fix, adding dvb support + o Fix gentoo bug #76056 (fb device group permissions.) + o Fix gentoo bug #81102, device nodes for the pktcdvd device + +Kay Sievers: + o provide temporary device node for callouts to access the device + o udev_volume_id: fix dasd disklabel reading with -l option + o udev_volume_id: volume_id version 034 + o udev_volume_id: rename probe_ibm into probe_dasd + o udev_volume_id: volume_id version 032 + o Makefile: add some more warnings and prepare for clean gcc4 compile + o Makefile: cleanup conditional config option sections + o fix -Wsign-compare warnings + o chassis_id: clean compilation and fix bad function parameter passing + o simple_build_check: make it possible to pass KERNEL_DIR + o selinux: cleanup udev integration + +Michael Buesch: + o trivial: remove _all_ trailing slashes with no_trailing_slash() + o trivial: fix signedness + o namdev: allow symlink-only rules to specify node permissions + o udevd: fix valgrind warning + + +Summary of changes from v050 to v051 +============================================ + +: + o This fixes a silly mistake in how udevinfo prints the major and minor numbers (right now it prints the minor next to "MAJOR" and the major next to "MINOR" ;) + +: + o I tried to compile udev 050plus with the GCC 4.0 snapshot 200412119 and got two errors about possibly uninitialized structs, so I fixed this. + +Christian Bornträger: + o udev_volume_id: fix -d option + +Greg Kroah-Hartman: + o gentoo fb permission fix + o fix gcc 2.96 issue in libsysfs + o remove the lfs startup script on request of the author + o clean up the aoe char device rules, and delete the block one as it's not needed + o add aoe block and char device rules to the gentoo rule file + o fix udev_volume_id build error + +Hannes Reinecke: + o rearrange link order in Makefile + +Kay Sievers: + o udev_volume_id: new version of volume_id + o klibc: update to version 0.198 + o udev_volume_id: fix FAT label reading + o klibc: update to version 0.196 + o udevd: throttle the forking of processes + o udevd: add possible initialization of expected_seqnum + o udevd: it's obviously not the brightest idea to exit a device node manager if it doesn't find /dev/null + o udevd: separate socket handling to prepare for other event sources + o udevd: support -d switch to become a daemon + o udev_volume_id: version 27 + o udevd: split up message receiving an queueing + o remove useless warning if udev.conf contains keys not read by udev itself + o improve event sequence serialization + o remove udevsend syslog noise on udevd startup + o limit the initial timeout of the udevd event handling + o correct detection of hotplug.d/ udevsend loop + o correct log statement + o remove default_* permissions from udev.conf file + o update Fedora config files and add some more tests + o allow permissions only rules + o add SUBSYSTEM rule to catch all block devices and apply the disk permissions + o update Fedora config files + o handle renamed network interfaces properly if we manage hotplug.d/ + o allow multiline rules by backslash at the end of the line + o add OnStream tape drive rules + o simplify rules file by setting default mode to 0660 + o simplify permission application + o I broke the extras/ again. Add simple build test script now + o Merge vrfy.org:/home/kay/src/udev into vrfy.org:/home/kay/src/udev.kay + o initial merge of fedora udev.permissions into udev.rules + o remove permissions file mentioning from the udev man page + o fix some typos in gentoo's udev.rules introduced by the merge + +Michael Buesch: + o The attached patch fixes the code path if namedev_name_device() fails + +Summary of changes from v049 to v050 +============================================ + +: + o selinux patch + +: + o I made some more changes to the manpage of udev including + +Kay Sievers: + o update libsysfs to CVS version and fix segfaulting attribute reading + o klibc supports LOG_PID now, so remove our own implementation + o avoid building klibc test programs and pass SUBDIRS= to klibc clean + + +Summary of changes from v048 to v049 +============================================ + +Greg Kroah-Hartman: + o fix 'make clean' error in klibc + +Kay Sievers: + o update klibc to 0.194 + o export DEVNAME regardless of the state of udev_dev_d + o add class specific files for class/spi_transport and class/spi_host + o udevd-test.pl: remove wrong date calculation + o check earlier if we should run as udevstart + o remove double initialization + o include missing header to udevtest.c + o add -V option to udev to print the version number + o prevent udev node creatinon for "class" registration + o udevd: serialization of the event sequence of a chain of devices + o add a class/fc_host file to the list of what to wait for + o udev_volume_id: links sysfs.a instead of all objects + +Martin Schlemmer: + o remove leftover from udevinfo's -d option + + +Summary of changes from v047 to v048 +============================================ + +Greg Kroah-Hartman: + o fix udev_volume_id so it will now build properly + o fix scsi_id build errors due to changes in the main udev makefile + + +Summary of changes from v046 to v047 +============================================ + +: + o Various typos and other litte errors in udev.8.in + +: + o DEVNAME on device removal + +: + o Allow GROUP to have modifiers in it + +Greg Kroah-Hartman: + o add more debian rules files + o move distro specific config files into their own directories + o update debian rules files + o added asterix rules to the gentoo file + o use udevstart for udev.init.* files + o delete a bunch of files no longer needed + o fix gentoo scsi cdrom rule + o Fix the multithreaded build again + o merge + o comment out ability to run udev-test.pl with valgrind + o fix spurious valgrind warning in udev + o fix udevinfo '-q path' option as it was not working + o merge + o fix parallel build error + +Kay Sievers: + o update Fedora dev.d/ example and remove unused conf.d/ directory + o don't install distribution specific init script on "make install" + o restore OWNER/GROUP assignment in rule coming from RESULT + o make gcov compile scripts working with recent gcc + o fix udev-test/udev-test.pl to work with again + o add net/atml and class/ppdev to the wait_for_sysfs exception list + o add net/nlv* devices to the exception list + o add "pcmcia" and "fc_transport" to the wait_for_sysfs lists + o remove unused timestamp field + o simplify permission handling + o handle /etc/hotplug.d/ only if the event comes from udevd + o trivial cleanups and change some comments + o remove unused variables + o udevsend/udevd handle events without a subsystem + o use blacklist on device "remove" and remove dev.d/ call code duplication + o update the man pages and correct Usage: hints + o don't call the hotplug scripts with a test run + o don't call dev.d/ scripts twice, if directory = subsystem + o remove archive file if we changed something + o link archive insted of objects + o rename udev_lib to udev_utils and dev_d to udev_multiplex + o handle whole hotplug event with udevd/udev + o integrate wait_for_sysfs in udev + o make the searched multiplex directories conditionally + o add MANAGED_EVENT to the forked udev environment + o export DEVNAME on remove event + o export udev_log flag to the environment + o remove my test code + o add support for /devices-devices without any file to wait for + o Patch from Alex Riesen + o add a bunch of busses to the list of what to wait for + o close connection to syslog in forked udevd child + o udevd exit path cleanup + o fix network device naming bug + + +Summary of changes from v045 to v046 +============================================ + +Greg Kroah-Hartman: + o make spotless for releases + +Kay Sievers: + o Don't try to print major/minor for devices without a dev file + o remove get_device_type and merge that into udev_set_values() + o prevent udevd crash if DEVPATH is not set + o add ippp and bcrypt to the exception lists of wait_for_sysfs + o let klibc add the trailing newline to syslog conditionally + o disable logging for udevstart + o add NAME{ignore_remove} attribute + o remove historical SYSFS_attr="value" format + o don't wait for sysfs if the kernel(2.6.10-rc2) tells us what not to expect + o change key names in udevinfo sysfs walk to match the kernel + o support DRIVER as a rule key + o support SUBSYSTEM as a rule key + o rename udevdb* to udev_db* + o Make dev.d/ handling a separate processing stage + o make the udev object available to more processing stages + o remove udev_lib dependency from udevsend, which makes it smaller + o add ACTION to udev object to expose it to the whole process + o make udevinfo's -r option also workimg for symlink queries + o let udev act as udevstart if argv[1] == "udevstart" + o improve udevinfo sysfs info walk + o add sysfs info walk to udevinfo + o pass the whole event environment to udevd + o replace tdb database by simple lockless file database + + +Summary of changes from v044 to v045 +============================================ + +Martin Schlemmer: + o Some updates for Gentoo's udev rules + + +Summary of changes from v043 to v044 +============================================ + +Greg Kroah-Hartman: + o add cdsymlinks.sh support to gentoo rules file + o fix gentoo legacy tty rule + o remove 'sudo' usage from the Makefile + o make udev-test.pl test for root permissions before running + +Kay Sievers: + o reduce syslog noise of udevsend if multiple instances try to start udevd + o add i2c-dev to the list of devices without a bus + + +Summary of changes from v042 to v043 +============================================ + +Greg Kroah-Hartman: + o add test target to makefile + o add dumb script to show all sysfs devices in the system + +Kay Sievers: + o Shut up wait_for_sysfs class/net failure messages, as it's not possible to + get that right for all net devices. Kernels later than 2.6.10-rc1 will + handle that by carrying the neccessary information in the hotplug event. + o wait() for specific pid to return from fork() + o Don't use any syslog() in signal handler, cause it may deadlock + o Add support for highpoint ataraid to volume_id to suppress label reading on raid set members. + o Add a bunch of devices without "device" symlinks + o Exit, if udevtest cannot open the device (segfault) + o Patches from Harald Hoyer + o Apply the default permissions even if we found a entry in the permissions + file. Correct one test, as the default is applied correctly now and the + mode will no longer be 0000. + o add test for format chars in multiple symlinks to replace + o Add net/vmnet and class/zaptel to the list of devices without physical device + + +Summary of changes from v040 to v042 +============================================ + +Greg Kroah-Hartman: + o add inotify to the rules for gentoo + +Kay Sievers: + o skip waiting for device if we get a bad event for class creation and not for a device underneath it + o add net/pan and net/bnep handling + o switch wait for bus_file to stat() instead of open() add net/tun device handling add ieee1394 device handling + o Remove the last klibc specific line from the main udev code Move _KLIBC_HAS_ARCH_SIG_ATOMIC_T to the fixup file which is automatically included by the Makefile is we build with klibc + o ignore *.rej files from failed patches + o update to libsysfs 1.2.0 and add some stuff klib_fixup Now we have only the sysfs.h file different from the upstream version to map our dbg() macro. + o improve klibc fixup integration + o cleanup udevd/udevstart + o expose sysfs functions for sharing it + + +Summary of changes from v039 to v040 +============================================ + +: + o wait_for_sysfs update for dm devices + +Greg Kroah-Hartman: + o sparse cleanups on the tree + o fix stupid cut-and-paste error for msr devices on gentoo boxes + o add *~ to bk ignore list + o delete udevruler.c as per Kay's request + o fix up the wait_for_sysfs_test script a bit + +Kay Sievers: + o fix debug in volume id / fix clashing global var name + o volume_id fix + o $local user + o cleanup netif handling and netif-dev.d/ events + o big cleanup of internal udev api + o don't wait for dummy devices + o close the syslog + o Fix ppp net devices in wait_for_sysfs + o Fix wait_for_sysfs messages (more debugging info) + + +Summary of changes from v038 to v039 +============================================ + +Greg Kroah-Hartman: + o Hopefully fix the vcs issue in wait_for_sysfs + o take out & from wait_for_sysfs_test that I previously missed + o add very nice cdsymlinks scripts + o add some helper scripts for dvb and input devices + o add debian config files + o let the extras/ programs build "pretty" also + o tweak the ccdv program to handle files in subdirectories being built + o crap, I messed up the 'sed' instances pretty badly, this fixes the config and man page mess + o fix broken 'make -j5' functionality + +Kay Sievers: + o swich attribute open() to simple stat() + o wait_for_sysfs update for /class/firmware and /class/net/irda devices + o fix unusual sysfs behavior for pcmcia_socket + o remove sleeps from udev as it is external now + o delete udevruler? + o Makefile fix + +Patrick Mansfield: + o update udev to scsi_id 0.7 + o pass SYSFS setting down for extras builds + o move assignments past local variables + + +Summary of changes from v037 to v038 +============================================ + +: + o Re: Problem parsing %s in udev rules + +Greg Kroah-Hartman: + o fix up error in building extras and libsysfs + +Summary of changes from v036 to v037 +============================================ + +: + o small udev patch + +Greg Kroah-Hartman: + o fix compilation warning in tdb log message + o Fix build error with klibc due to recent changes + o merge + o add wait_for_sysfs test script to the tarball to help people debug their boxes + o add ipsec to wait_for_sysfs ignore list + o added ccdv to bk ignore list + o a few more Makefile tweaks for the quiet feature + o Make the build silent, thanks to a helper program from ncftp + o rename files to have '_' instead of '-' in them + o change max time to wait in wait_for_sysfs to 10 seconds to hopefully handle some slow machines + o add support for class/raw/ to wait_for_sysfs + o fix up Makefile for wait_for_sysfs udev_version.h dependancy + o remove the debian specific file, as they don't want to share with the rest of the world :( + +Kay Sievers: + o prevent deadlocks on an corrupt udev database + o wait_for_sysfs_update + +Michael Buesch: + o fix asmlinkage + o fix incompatible pointer type warning + + +Summary of changes from v035 to v036 +============================================ + +Greg Kroah-Hartman: + o add the error number to the error message in wait_for_sysfs to help out in debugging problems + +Summary of changes from v034 to v035 +============================================ + +Greg Kroah-Hartman: + o added ieee1394 support to wait_for_sysfs + o update wait_for_sysfs with a bunch more devices thanks to user reports + +Summary of changes from v033 to v034 +============================================ + +Kay Sievers: + o wait_for_sysfs bluetooth class update + +Greg Kroah-Hartman: + o add comment in wait_for_sysfs to explain the structure better + o Revert previous dev_d.c change, it's not what is causing HAL problems + o hm, somethings odd with DEVPATH, see if this fixes it + o 33_bk mark for the makefile + o wait_for_sysfs: clean up the logic for the list of devices that we do not expect device symlinks for + o get rid of annoying extra lines in the syslog for some libsysfs debug messages + o added support for i2c devices in wait_for_sysfs.c + o add support for i2c-adapter devices to wait_for_sysfs.c + +Summary of changes from v032 to v033 +============================================ + +: + o udev close on exec + o some cleanups and security fixes + o some cleanups and security fixes + o selinux for udev + o cleanup PATCH for extras/chassis_id/Makefile + +: + o respect prefix= setting in built udev.conf (updated) + +Greg Kroah-Hartman: + o add support for usb interfaces to wait_for_sysfs to keep it quiet + o enable native tdb spinlocks on i386 platforms + o delete extras/multipath-tools as per the author's request + o be paranoid in dev_d.c + o add USE_SELINUX to README documentation so people have a chance to see what is going on + o update the selinux.h file to start to look sane + o update bk ignore list for the wait_for_sysfs binary + o kdetv wants to see device nodes in /dev + o update comments in scsi-devfs.sh + o fix up Makefiles to get the klibc build working properly + o update bk ignore list for new klibc generated files + o oops forgot to add the new klibc/include directory + o update klibc to version 0.181 + +Kay Sievers: + o fix problems with dev.d and udevstart + o wait_for_sysfs debug cleanup + o fix problems using scsi_id with udevstart + o update volume_id + o finally solve the bad sysfs-timing for all of us + o volume-id build fix and update + o switch udev's seqnum to u64 + o add enum tests + o fix udev segfaults with bad permissions file + +Patrick Mansfield: + o update udev to include scsi_id 0.6 + + +Summary of changes from v031 to v032 +============================================ + +: + o udev parse bug + +Kay Sievers: + o handle only block and class devices + o fix udevstart badly broken in udev 031 + + +Summary of changes from v030 to v031 +============================================ + +: + o udev - read long lines from config files overflow fix + +: + o Update the FAQ with info about hardlink security + +: + o compatibility symlinks for udev + +David Weinehall: + o Minor POSIX-fixes for udev + +Greg Kroah-Hartman: + o add symlink for video rule + o add a "first" list to udevstart and make it contain the class/mem/ devices + o fix compiler warning in udevtest.c + o Fix old-style pty breakage in rules file for tty device + o add rules for i386 cpu devices + o add permission for legotower usb devices + +Kay Sievers: + o Fix naming ethernet devices in udevstart + o update udev_volume_id + o let /sbin/hotplug execute udev earlier + o pass SEQNUM trough udevd + o fix manpages based on esr's spambot + +Martin Schlemmer: + o add microcode rule to permissions.gentoo file + +Michael Buesch: + o Try to provide a bit of security for hardlinks to /dev entries + +Olaf Hering: + o udevsend depends on udev_lib.o + +Tom Rini: + o fix UDEV_NO_SLEEP + o clean up start_udev a bit + o Make udev/udevstart be one binary + o Add 'asmlinkage' to udev-030 + + +Summary of changes from v029 to v030 +============================================ + +Greg Kroah-Hartman: + o fix stupid off-by-one bug that caused udevstart to die on x86-64 boxes + + +Summary of changes from v028 to v029 +============================================ + +Greg Kroah-Hartman: + o add permission rule for jogdial device + o fix dumb bug I added to udevstart + o make a "last list" of devices for udevstart to operate on last + o fix permission problem with input event and ts nodes for gentoo + o change default perms of misc/rtc to be readable by anyone + +Olaf Hering: + o allow NAME_SIZE > SYSFS_PATH_MAX + + +Summary of changes from v027 to v028 +============================================ + +: + o Patch for chassis_id exras module + +Daniel Drake: + o Writing udev rules doc update + +Greg Kroah-Hartman: + o clean up block whitelist search logic a bit + o reverse order of scanning of udevstart to look at class before block + +Kay Sievers: + o update udev_volume_id + +Leann Ogasawara: + o udevstart performance increase + +Patrick Mansfield: + o update udev scsi_id to scsi_id 0.5 + + +Summary of changes from v026 to v027 +============================================ + +: + o fix handle leak in udev_lib.c + +Greg Kroah-Hartman: + o tweak the gentoo default permission rules as they are wrong for tty and misc devices + + +Summary of changes from v025 to v026 +============================================ + +Arnd Bergmann: + o udev rpm fix + +Greg Kroah-Hartman: + o add test for ! in partition name + o 025_bk mark + o Update to version 117 of klibc (from version 108) + o add volume_id ignore rule for bk + o add volume_id support to the udev.spec file + o remove dbus and selinux stuff from the udev.spec file + o delete udev_selinux as it doesn't work properly and is the wrong way to do it + o Deleted the udev_dbus extra as it didn't really work properly and HAL has a real solution now + o add udev.permissions.slackware file + o udevstart: close open directories + +Kay Sievers: + o fix udevd zombies + o catchup with recent klibc + o Re: udevsend fallback + o udev_volume_id update + o udev callout for reading filesystem labels + o udev callout for reading filesystem labels + o udev default config layout changes + +Leann Ogasawara: + o evaluate getenv() return value for udev_config.c + +Summary of changes from v024 to v025 +============================================ + +: + o devfs.sh-ide-floppy + +: + o DEVNODE -> DEVNAME transition fixes + +Daniel Drake: + o Update writing udev rules docs + +Greg Kroah-Hartman: + o make dev.d call each directory in the directory chain of the device name, instead of just the whole name + o add devd_test script + o add more permissions based on SuSE's recommendations + o added rules for tun and raw devices + o add udev conf.d file + o Switch the default config to point to a directory for the rules and permission files + o update the Red Hat .dev files to work on other distros + o add dbus.dev, pam_console.dev and selinux.dev files for /etc/dev.d/default/ usage + o add hints for red hat users from Leann Ogasawara + o add scripts to run gcov for udev from Leann Ogasawara + o change permissions on udevd test scripts + o Fix build process for users who have LC_ALL set to a non-english language + o Added expanded tests to the test framework from Leann Ogasawara + o added execelent "writing udev rules" document from Daniel Drake + o added rule to put USB printers in their proper places + o added rules for CAPI devices + o added a dev.d alsa script to help people out + +Kay Sievers: + o fix test regressions + o udev_selinux changes + o udevd test script + o udev_dbus changes + o fix devpath for netdev + +Leann Ogasawara: + o gcov for udev + + +Summary of changes from v023 to v024 +============================================ + +: + o Add README for chassis_id + o Add chassis_id program to extras directory + +: + o udevd race conditions and performance, assorted cleanups + +: + o fix SEGV in libsysfs/dlist.c + +: + o add OSDL documentation for persistent naming + +: + o small ide-devfs.sh fix + +Greg Kroah-Hartman: + o remove compiler warning from udevd.c + o only generate udev.8 on the fly, not all other man pages + o update bk ignore list some more + o update bk ignore list + o switch to generate the man pages during the normal build, not during the install + o convert udev.8.in to use @udevdir@ macro for make install + o first step of making man pages dynamically generated + o add install and uninstall the etc/dev.d/net/hotplug.dev file to the Makefile + o tweak net_test a bit + o fix some segfaults when running udevtest for network devices + o make a net_test test script using udevtest + o handle the subsytem if provided in udevtest + o add hotplug.dev script to handle renamed network devices + o add a bunch of network class devices to the test sysfs tree + o add udevruler to the bk ignore list + o update RFC-dev.d docs due to DEVNODE to DEVNAME change + o clean up chassis_id coding style + o clean up the OSDL document formatting a bit + o add netlink rules to devfs and gentoo rules files + o added USB device rules to rules files + o clean up the gentoo rules file a bit more, adding dri rules + o fix up udev.rules to handle oss rules better + o 023_bk mark + o fix udev.spec file for where udevtest should be placed + +Kay Sievers: + o tweak node unlink handling + o switch udevd's msg_dump() to #define + o handle netdev in udevruler + o man page cleanup + o put config info in db for netdev + o increase udevd event timeout + o udevstart fix + o put netdev handling and dev.d/ in manpages + o DEVPATH for netdev + o netdev - udevdb+dev.d changes + o udevd race conditions and performance, assorted cleanups - take 2 + o udevinfo patch + o dev_d.c file sorting and cleanup + o apply all_partitions rule to main block device only + + +Summary of changes from v022 to v023 +============================================ + +Kay Sievers: + o hmm, handle net devices with udev? + o correct apply_format() for symlink only rules + o don't init namedev on remove + o first stupid try for a rule compose gui + o replace fgets() with mmap() and introduce udev_lib.[hc] + o make udevtest a real program :) + +Daniel E. F. Stekloff: + o udevinfo patch + +Greg Kroah-Hartman: + o create the /etc/dev.d/ directories in 'make install' + o actually have udev run files ending in .dev in the /etc/dev.d/ directory as documented + o added RFC-dev.d document detailing how /etc/dev.d/ works + o fixed up udev.spec to handle selinux stuff properly now + o remove USE_DBUS and USE_SELINUX flags from the README as they are no longer present + o remove selinux stuff from the main Makefile + o move udev_selinux into extras/selinux + o fix dbus build in the udev.spec file + o remove dbus stuff from main Makefile + o move udev_dbus to extras/dbus + o udev_dbus can now compile properly, but linnking is another story + o remove udev_dbus.h from Makefile + o first cut at standalone udev_selinux program + o remove selinux support from udev core as it's no longer needed + o first cut at standalone udev_dbus program + o add get_devnode() helper to udev_lib for udev_dbus program + o remove dbus code from core udev code as it's no longer needed to be there + o add /etc/dev.d/ support for udev add and remove events + o fix build error in namedev.c caused by previous patch + o 022_bk tag + o fix 'make spotless' to really do that in klibc + o add a question/answer about automounting usb devices to the FAQ + o mark scsi-devfs.sh as executable + o Increase the name size as requested by Richard Gooch + o fix udevtest to build properly after the big udev_lib change + +Olaf Hering: + o uninitialized variable for mknod and friend + +Richard Gooch: + o SCSI logical and physical names for udev + +Theodore Y. T'so: + o Trivial man page typo fixes to udev + + +Summary of changes from v021 to v022 +============================================ + +: + o more Libsysfs updates + o Libsysfs updates + +: + o fix HOWTO-udev_for_dev for udevdir + +Kay Sievers: + o udev-test.pl cleanup + o add dev node test to udev-test.pl + o add permission tests + o "symlink only" test + o callout part selector tweak + o cleanup callout fork + o allow to specify node permissions in the rule + o man page beauty + o put symlink only rules to the man page + o rename strn*() macros to strmax + o conditional remove of trailing sysfs whitespace + o clarify udevinfo text + o better fix for NAME="foo-%c{N}" gets a truncated name + o overall trivial trivial cleanup + o fix NAME="foo-%c{N}" gets a truncated name + o cleanup mult field string handling + +: + o fix a type in docs/libsysfs.txt + o Added line to udev.permissions.redhat + o Include more examples in the docs area for gentoo and redhat + +: + o udevstart fixes + +Greg Kroah-Hartman: + o add big major tests to udev-test.pl + o add a test for a minor over 255 + o udev-test.pl: print out major:minor and perm test "ok" if is ok + o make perm and major:minor test errors be reported properly + o remove extra ; in namedev_parse.c + o Added multipath-tools 0.1.1 release + o deleted current extras/multipath directory + o 021_bk mark + o fix the build for older versions of gcc + +Hanna V. Linder: + o Small fix to remove extra "will" in man page + +Olaf Hering: + o make spotless + o udev* segfaults with new klibc + +Patrick Mansfield: + o add tests for NAME="foo-%c{N}" + +Summary of changes from v020 to v021 +============================================ + +Kay Sievers: + o install udevinfo in /usr/bin + o blacklist pcmcia_socket + +Greg Kroah-Hartman: + o fix udev.spec to find udevinfo now that it has moved to /usr/bin + o Fix another problem with Makefile installing initscript + o fix the Makefile to install the init script into the proper directory + o make spec file turn off selinux support by default + + +Summary of changes from v019 to v020 +============================================ + +: + o multipath update + +Kay Sievers: + o man page udevstart + o cleanup udevstart + o bugfix for local user + o unlink bugfix + o TODO update + o clarify udevinfo device walk + o udevinfo symlink reverse query + o fix stroul endptr use + o add $local user spport for permissions + o udev - man page update + o udev - fix debug info for multiple rule file config + o udev - kill udevd on install + o udev - activate formt length attribute + o udev - safer sprintf() use + +: + o no error on enoent + o escape dashes in man pages + o remove usage of expr in ide-devfs.sh + +: + o automatically install correct initscript + o update documetation for $local + +Andrey Borzenkov: + o Add symlink only rules support + +Greg Kroah-Hartman: + o update the TODO list as we already have a devfs config file + o make start_udev use udevstart binary + o install udevstart + o Remove Debian permission files as the Debian maintainer doesn't seem to want to share :( + o update the Gentoo rules files + o Add Red Hat rules and permissions files + o add udevstart to the ignore list + o add udevstart program based on a old patch from Harald Hoyer + o unlink the file before we try to create it + o Merge greg@bucket:/home/greg/src/udev into kroah.com:/home/greg/src/udev + + +Summary of changes from v018 to v019 +============================================ + +Kay Sievers: + o TODO update + o udev - correct relative symlink + o udev - safer string handling - part four + o udev - safer string handling - part three + o udev - safer string handling - part two + o udev - man page update + o udev - safer string handling all over the place + o manpage update + o udev - allow all files in a directory as the config + o udev - simple klibc textual uid/gid handling + +Andrey Borzenkov: + o do not remove real .udev.tdb during RPM build + +Greg Kroah-Hartman: + o add new TODO item about local user permissions + o Add initial SELinux support for udev + o fix build for very old versions of make + o remove limit of the number of args passed to PROGRAM + o force udev to include the internal version of libsysfs and never the external one + o fix up libsysfs header file usage to fix bug reports from users that have sysfsutils installed already + o remove udevtest on 'make clean' + o remove udevd priority TODO item, as it's not needed at all + +Patrick Mansfield: + o update udev scsi_id to scsi_id 0.4 + + +Summary of changes from v017 to v018 +============================================ + +: + o [PATCH] symlink dm-[0-9]* rule + o update extras/multipath + +: + o init.d debian patch + +Kay Sievers: + o udev - TODO update + o udev - add %s{filename} to man page + o udev - udevd/udevsend man page + o udev - switch callout part selector to {attribute} + o udev - switch SYSFS_file to SYSFS{file} + o udev - create all partitions of blockdevice + o allow SYSFS{file} + o Adding '%s' format specifier to NAME and SYMLINK + +Greg Kroah-Hartman: + o added some scsi_id files to the bk ignore file + o added scsi_id and some more documentation to the udev.spec file + o update udev.rules.gentoo with new config file format + o Update the Gentoo udev.rules and udev.permissions files + o Create a udev.rules.examples file to hold odd udev.rules + o add udevd priority issue to the TODO list + o more HOWTO cleanups + o add HOWTO detailing how to use udev to manage /dev + o mv libsysfs/libsysfs.h to libsysfs/sysfs/libsysfs.h to make it easier to use + o add start_udev init script + o add support for UDEV_NO_SLEEP env variable so Gentoo people will be happy + o start up udevd ourselves in the init script to give it some good priorities + o update the red hat init script to handle nodes that are not present + o add a "old style" SYSFS_attribute test to udev-test.pl + o Have udevsend report more info in debug mode + o Have udevd report it's version in debug mode + o fix up bug created for udevtest in previous partition creation patch + o update the udev.spec to add udevtest and make some more Red Hat suggested changes + o add ability to install udevtest to Makefile + o 017_bk mark + o Add another test to udev-test.pl and fix a bug when only running 1 test + o Fix bug where we did not use the "converted" kernel name if we had no rule + +Patrick Mansfield: + o udev use new libsysfs header file location + o udev add some ID tests + + +Summary of changes from v016 to v017 +============================================ + +: + o make logging a config option + +: + o more udev-016/extras/multipath + o more udev-016/extras/multipath + o update extras/multipath + +Kay Sievers: + o udev - keep private data out of the database? + o better credential patch + o udevd - client access authorization + o compile udevd with klibc + o udev - fix "ignore method" + o udev - fix cdrom symlink rule + o convert udevsend/udevd to DGRAM and single-threaded + o udevd - kill the lockfile + o udevd - fix socket path length + o udevd - switch socket path to abstract namespace + o udevd - allow to bypass sequence number + o include used function + +Greg Kroah-Hartman: + o add udev_log to the documentation + o fix offsetof() define in klibc + o add some .spec file changes from Red Hat + o update the init.d udev script based on a patch from Red Hat + o remove the .udev.tdb when installing or uninstalling to be safe + o remove the database at startup + o fix bug in permission handling + o update klibc to version .107 + o update the bitkeeper ignore file list + o add udevtest program to build + o fix problem where usb devices can be either the main device or the interface + o more logging.h cleanups to be a bit more flexible + o stop using mode_t as different libcs define it in different ways :( + o remove some more KLIBC fixups that are no longer needed + o let udev-test.pl run an individual test if you ask it to + o Handle the '!' character that some block devices have + o add a block device with a ! in the name, and a test for this + o fix up 'make release' to use bk to build the export tree + o fix log option code so that it actually works for all udev programs + o finish syncing up with klibc + o sync with latest version of klibc (0.107) + o fix up Makefile dependancies for udev_version.h + +Patrick Mansfield: + o udev add wild card compare for ID + o udev kill extra bus_id compares in match_id + + +Summary of changes from v015 to v016 +============================================ + +: + o get_dev_number() in extras/ide-devfs.sh + +: + o FAQ udev.rules.devfs + +Greg Kroah-Hartman: + o add udevd and udevsend to the spec file + o make /etc/hotplug.d/default/udev.hotplug symlink point to udevsend now + o add KERNEL_DIR option so that the distros will be happy + o make udevsend binary even smaller + o udevsend now almost compiles with klibc, struct sockaddr_un is only problem now + o fix up logging code so that it can be built without it being enabled + o rework the logging code so that each program logs with the proper name in the syslog + o remove logging.c as it's no longer needed + o kill the last examples that contained the %D option + o remove a __KLIBC__ tests in libsysfs, as klibc now supports getpagesize() + o udevd - remove stupid locking error I wrote + o update to klibc version 0.101, fixing the stdin bug + o fix Makefile typo for USE_LSB install + o allow dbus code to actually build again + +Kay Sievers: + o let udevsend build with klibc + o udevd - config cleanup + o udevd - cleanup and better timeout handling + o fix possible buffer overflow + o udevd - next round of fixes + o udevinfo - missing options for man page + o udev - trivial style cleanup + + +Summary of changes from v014 to v015 +============================================ + +: + o LFS init script update + +Greg Kroah-Hartman: + o update klibc to version 0.98 + o clean up udevinfo on 'make clean' + o add udevinfo man page to spec file + o remove command line documentation from udev man page + o create initial version of udevinfo man page + o added URL to spec file + o add udevinfo to udev.spec file + o add udevinfo to install target of Makefile + o rip out command line code from udev, now that we have udevinfo + o udevinfo doesn't need to declare main_envp + o move get_pair to udev_config.c because udevinfo doesn't need all of namedev.o + o more makefile cleanups + o move udevinfo into the main build and clean up the main Makefile a bit + o clean up compiler warnings if building using klibc + o make udevd only have one instance running at a time + o new testd.block script for debugging + o udevsnd : clean up message creation logic a bit + o make bk ignore udevd and udevsend binaries + o whitespace cleanups + o remove TODO item about BUS value, as it is now done + o add support for figuring out which device on the sysfs "chain" the rule applies to + +Kay Sievers: + o udevinfo - now a real program :) + o udevd - cleanup and better timeout handling + o udev - next round of udev event order daemon + o fix udevd exec + o udev - udevinfo with device chain walk + o spilt udev into pieces + + +Summary of changes from v013 to v014 +============================================ + +: + o libsysfs update for refresh + namedev.c changes + +: + o udev-013/extras/multipath update + +: + o minor patch for devfs rules + +Kay Sievers: + o udev - program to query all device attributes to build a rule + o set default owner/group in db - update + o udev - reverse user query options + o udev - kill %D from udev-test.pl + o add udev logging to info log + o udev - mention format string escape char in man page + +Greg Kroah-Hartman: + o misc code cleanups + o fixup logging.h to handle different logging options properly + o clean up the logging patch a bit to make the option more like the other options + o remove the %D modifier as it is not longer needed + o remove unneeded keyboard rule + o add usb_host and pci_bus to the class blacklist + o added input device rules to udev.rules and udev.rules.devfs + o 013_bk mark + +Hanna V. Linder: + o set default owner/group in db + o small cut n paste error fix + +Patrick Mansfield: + o update udev scsi_id to scsi_id 0.3 + + +Summary of changes from v012 to v013 +============================================ + +: + o LSB init script and other stuff + +: + o fix udev directory for Debian init script + +: + o udev 012 old gcc fixup + +Christophe Saout: + o add IGNORE rule type + o small cleanup + +Greg Kroah-Hartman: + o update TODO with some new, small items + o Cset exclude: greg@kroah.com|ChangeSet|20040113010256|48515 + o update the README in a few places + o fix -d typo in the manpage update + o Fix stupid gcc "optimization" of 1 character printk() calls.... Ick + o oops, forgot to fix up the PROGRAM result from ID to RESULT in the config files + o Add alsa device rules and a few other devfs rules + o fix a few stale comments in namedev.c + o convert the default rules files to the new format + o convert the test shell scripts to the config file format + o add bus test for usb-serial bus + o Add some helpful messages if the user uses the older config file format + o added dri rule to the default config file + o added init.d udev script for debian + o add a script that tests the IGNORE rule + o add silly script that names cdrom drives based on the cd in them + o add cdrom rule for ide cdrom + o replace list_for_each with list_for_each_entry, saving a few lines of code + o add a blacklist of class devices we do not want to look at + +Kay Sievers: + o fix klibc with printf() and gcc + o udev - small script optimization + o udev - introduce format escape char + o udev - more CALLOUT is PROGRAM now + o udev - CALLOUT is PROGRAM now + o update documentation for new config file format + o more advanced user query options + o udev - simple debug tweak + o udev - drop all methods :) + o udev - advanced user query options + o udev - Makefile error + o udev - make exec_callout() reusable + o udev - exec status fix for klibc + o fix Silly udev script + + +Summary of changes from v011 to v012 +============================================ + +: + o make symlink work properly if there is already a file in its place + o Fix udev gcc-2.95.4 compat + +: + o extras multipath update + o extras multipath update + +Kay Sievers: + o mention user callable udev + options in man page + o make udev user callable to query the database + o depend on all .h files + o cleanup namedev_parse debug text + o extend exec_program[] + o ide-devfs.sh update + o fix for apply_format() + o check for empty symlink string + o 'ide' missing in bus_files[] + o small trivial cleanup of latest changes + +: + o introduce signal handler + +: + o udev spec file update + +Greg Kroah-Hartman: + o minor grammer fixes for the udev_vs_devfs document + o move the dbus config file to etc/dbus-1/system.d/ + o move the config files to etc/udev to clean up main directory a bit + o add Gentoo versions of the rules and permissions files + o if using glibc, link dynamically, as no one like 500Kb udev binaries + o minor change to udev_vs_devfs document + o added udev vs devfs supid document to the tree + o move the signal handling registration to after we have initialized enough stuff + o make ide-devfs.sh executable in the tree + o udev.permissions.debian - forgot the dm nodes + o update the udev.permissions.debian file with new entries + o added udev.init script for the Linux From Scratch project + + + +Summary of changes from v010 to v011 +============================================ + +: + o proper cleanup on udevdb_init() failure + +: + o patch udev 009-010 rpm spec file + +: + o fix udev sed Makefile usage + +Greg Kroah-Hartman: + o add documentation about the BUS key being optional for the LABEL rule + o add tests for LABEL rule with a device that has no bus + o Don't require the BUS value for the LABEL rule + o If a LABEL rule has a BUS id, then we must check to see if the device is on a bus + o add documentation about the BUS key being optional for the CALLOUT rule + o If a CALLOUT rule has a BUS id, then we must check to see if the device is on a bus + o Don't require the BUS value for the CALLOUT rule + o add test for callout rule with a device that has no bus + o 010_bk stamp + o added different build options to the rpm udev.spec file + o add pci to the bus_files list + o check for empty line a bit better in the parser + o more init script cleanups, the stop target now calls udev to cleanup instead of just removing the whole /udev directory + o make udev init script run udev in the background to let startup go much faster + o fix long delay for all devices in namedev + + +Summary of changes from v009 to v010 +============================================ + +: + o change pgsize + +: + o extras multipath update + o extras multipath update + o extras multipath update + o extras multipath update + +Kay Sievers: + o fix udev-test.pl + o small cleanup udev-remove.c + o experimental CALLOUT script for devfs ide node creation with cd, disc, part + o add any valid device + o introduce format char 'k' for kernel-name + o trivial make fixes + o don't overwrite old config on install + o udev-remove.c cleanups + o bug in udev-remove.c + o trivial cleanup parser changes + +: + o fix comment and whitespace handling in config files + +Adam Kropelin: + o Allow build with empty EXTRAS + +Daniel E. F. Stekloff: + o libsysfs 0.4.0 patch + o fix scsi_id segfault with udev-009 + o add libsysfs docs + +David T. Hollis: + o mark config files as such in the rpm spec file + +Greg Kroah-Hartman: + o fix complier warning in namedev.c + o add documentation for the new '%k' modifier (kernel name replacement) + o add documentation about the multiple sysfs values that are now allowed for the LABEL rule + o add tests for multi-file LABEL rules + o add ability to have up to 5 SYSFS_ file/value pairs for the LABEL rule + o Just live with a sleep(1) in namedev for now until libsysfs is fixed up + o try to wait until the proper device file shows up in sysfs + o remove unneeded TODO and FIXME entry + o clean up the stand-alone tests to work properly on other people's machines + o add tests to catch whitespace and comment config file parsing errors + + +Summary of changes from v008 to v009 +============================================ + +: + o more extras/multipath changes + o and more extras/multipath updates + o more extras/multipath updates + o yet more extras/multipath + o more extras/multipath updates + o extras/multipath update + +: + o D-BUS patch for udev-008 + +: + o add init.d/udev to "make install" + o add init.d/udev to the spec file + +Kay Sievers: + o don't rely on field order in namedev_parse + o get part of callout return string + o remove '\n' from end of callout return + o man-page mention multiple symlinks + o allow multiple symlinks + o cleanup man & remove symlink comment + o experimental (very simple) SYMLINK creation + o man page beauty + o pattern match for label method + o a bug in linefeed removal + +: + o remove udev from runlevels on uninstall + o install initscript in udev rpm + +Daniel E. F. Stekloff: + o pre-libsysfs-0.4.0 patch + +Greg Kroah-Hartman: + o signal fixes due to klibc update + o sync klibc with release 0.95 + o add mol permissions to the debian permissions file + o update the FAQ with info about bad modprobe events from the devfs scheme + o some cleanups due to the need for LABEL rules to use "SYSFS_" now + o Add restart target to the etc/init.d/udev script + o tweak the config file generation portion of the Makefile a bit + o change devfs disk name rule from 'disk' to 'disc' + o add vc support to udev.rules.devfs + o added a devfs udev config file from Marco d'Itri + o set default mode to 0600 to be safer + o Makefile tweaks for the DBUS build + o update the FAQ due to the latest devfs mess on lkml and also due to symlinks now working + o document the different Makefile config options that we have + o change USE_DBUS to DBUS in Makefile, and disable it by default as it's still to hard to build on all systems + o fix formatting of udev_dbus.c to use tabs. Also get it to build properly now + o move all of the DBUS logic into one file and remove all of the #ifdef crud from the main code + +Olaf Hering: + o dump latest klibc into the udev build tree + o use udevdir in udev.conf + +Patrick Mansfield: + o better allow builds of extras programs under udev + o update udev extras/scsi_id to version 0.2 + + +Summary of changes from v007 to v008 +============================================ + +: + o more config file parsing robustness + +: + o udev-007/extras/multipath update + +Arnd Bergmann: + o Build failure - missing linux/limits.h include? + o Add format modifier for devfs like naming + o klibc makefile fixes + +Daniel E. F. Stekloff: + o another patch for path problem + o quick fix for libsysfs bus + o libsysfs changes for sysfsutils 0.3.0 + +Greg Kroah-Hartman: + o fix up some duplicated function compiler warnings in libsysfs + o fix some compiler warnings in the tdb code + o Added Kay's name to the man page + o update the wildcard documentation in the man page to show the new styles supported + o fix permission handling logic + o enable default_mode ability to actually build + o add support for the default_mode variable, as it is documented + o show permissions and groups in the label_test + o remove some items off of the TODO list, as they are now done + o fix up the tests to work without all of the environ variables + o get rid of the majority of the debug environment variables + o Update the man page to show the new config file, it's format, and how to use it + o fix up the tests to support the rules file name change + o add support for a main udev config file, udev.conf + o turn debugging messages off by default + o split out the namedev config parsing logic to namedev_parse.c + o rename namedev's get_attr() to be main namedev_name_device() as that's what it really is + o add devfs like tty rules as an example in the default config file + o operate on the rules in the order they are in the config file (within the rule type) instead of operating on them backwards. + o Cset exclude: dsteklof@us.ibm.com|ChangeSet|20031126173159|56255 + o add test for checking the BUS value + o fix problem where we were not looking at the BUS value + o add scsi and pci bus links in the test sysfs tree + o add test and documentation for new %D devfs format modifier + o changed the default location of the database to /udev/.udev.tdb to be LSB compliant + o get rid of functions in klibc_fixups that are now in klibc + o sync up with the 0.84 version of klibc + o fix udev init.d script to handle all class devices in sysfs + o fix the test.block and test.tty scripts due to their moveing. Also add a test.all script + o 007_bk version change to Makefile + +Kay Sievers: + o pattern matching for namedev + o catch replace device by wildcard + o udev.8 tweak numeric id text + o udev-test.pl add subdir test + o namedev.c strcat tweak + o overall whitespace + debug text conditioning + o udev-test.pl - tweaks + +Martin Hicks: + o Add -nodefaultlibs while compiling against klibc + +Olaf Hering: + o ARCH detection for ppc + +Patrick Mansfield: + o fix udev parallel builds with klibc + + +Summary of changes from v006 to v007 +============================================ + +: + o fix segfault in parsing bad udev.permissions file + +Greg Kroah-Hartman: + o update default config file with a CALLOUT rule, and more documentation + o updated the man page with the latest format specifier changes + o added ability to put format specifiers in the CALLOUT program string + o tweak udev-test.pl to report '0' errors if that's what happened + o only build klibc_fixups.c if we are actually using klibc + o add support for string group and string user names in udev.permissions + o add getgrnam and getpwnam to klibc_fixups files + o remove Makefile.klibc + o add udev-test perl script from Kay Sievers which blows away my puny shell scripts + o added debian's version of udev.permissions + o change to 006_bk version + +Kay Sievers: + o format char for CALLOUT output + o more namedev whitespace cleanups + o support arguments in callout exec + o namedev.c - change order of fields in CALLOUT + o namedev.c whitespace + debug text cleanup + o man page with udev.permissions wildcard + +Olaf Hering: + o static klibc udev does not link against crt0.o + +Summary of changes from v005 to v006 +============================================ + +: + o faster test scripts + +Arnd Bergmann: + o more robust config file parsing in namedev.c + o add bus id modifier + +Daniel E. F. Stekloff: + o patch for libsysfs sysfs directory handling + +Greg Kroah-Hartman: + o add another line to udev.permissions in the proper format + o tweak replace_test + o fix permissions to work properly now + o add real udev.permissions file to test directory + o fix namedev.c to build with older version of gcc + o add dumb test for all of the different modifiers + o update the TODO list with more items that people can easily do + o move the test.block and test.tty scripts to the test/ directory + o add remove actions to the test scripts + o turn DEBUG_PARSER off by default + o add some documentation for the %b modifier to the default config file + o fix make install rule for when the udev symlink is already there + o change release target in makefile + o change debug level on printf values for now + o updated demo config file + o add some documentation of the modifiers to the default config file + o add demo config file + o updated bk ignore list for klibc generated files + o add printf option to label test to verify it works + o fix up printf-like functionality due to previous changes + o get the major/minor number before we name the device + o add scsi_id "extra" program from Patrick Mansfield + o Add multipath "extra" program from Christophe Varoqui, + o trailing whitespace cleanups + o splig LABEL and NUMBER into separate functions + o add TOPO regression test + o move TOPOLOGY rule to it's own function + o fix bug where NUMBER and TOPOLOGY would not work for partitions + o clean up the way we find the sysdevice for a block device for namedev + o updated label test script (tests for partitions now.) + o split REPLACE and CALLOUT into separate functions + o add debug line for REPLACE call + o add replace test + o add more sysfs test tree files + o change UDEV_SYSFS_PATH environment variable due to libsysfs change + o fix bug in klibc's isspace function + o fix udev-add.c to build properly with older versions of gcc + o add prototype for ftruncate to klibc + o Remove a few items from the TODO list that are already done + o version number to 005_bk + o pull some klibc stuff into the make Makefile to try to stay in sync + o klibc build fixes + +Kay Sievers: + o apply permissions.conf support for wildcard and default name + o man page with included placeholder list + o implement printf-like placeholder support for NAME + o more manpage tweaks + o add support for subdirs + o add uid/gid to nodes + +Olaf Hering: + o DESTDIR for udev + +Paul Mundt: + o Fixup path for kernel includes when building with klibc + +Robert Love: + o udev init script + + +Summary of changes from v004 to v005 +============================================ + +: + o namedev.c comments + debug patch + o man page update + +Greg Kroah-Hartman: + o ignore the klibc/linux symlink + o add klibc linux symlink info to the README + o get 'make release' to work properly again + o added README info for how to build using klibc + o turn off debugging if we are building with klibc + o turn off debugging in namedev + o added vsyslog support to klibc + o add ftruncate to klibc + o klibc specific tweaks + o libsysfs does not need mntent.h in it's header file + o udev build tweaks to tdb's spinlock code + o klibc makefile changes + o build tdb and libsysfs from the same makefile as udev + o udev-add build cleanups for other libc versions + o tweak tdb to build within udev better + o make libsysfs spit debug messages to the same place as the rest of udev + o make libsysfs build cleanly + o updated bk ignore list + o added klibc version 0.82 (cvs tree) to the udev tree + o makefile fix for now + o Merge greg@bucket:/home/greg/src/udev into kroah.com:/home/greg/src/udev + o hm, makefile bug with so many files... will fix later + o regression tests starting to be added + o fix LABEL bug for device files (not class files.) + o more warning flags to the build + o got rid of struct device_attr + o rename namedev.permissions and namedev.config to udev.permissions and udev.config + o fix dbg line in namedev.c + o more overrides of config info with env variables if in test mode + o Fix bug causing udev to sleep forever waiting for dev file to show up + o change version to 004_bk + o make config files, sysfs root, and udev root configurable from config variables + +Robert Love: + o udev: sleep_for_dev() bits + o udev: another canidate for static + + +Summary of changes from v003 to v004 +============================================ + +Daniel E. F. Stekloff: + o new version of libsysfs patch + +Greg Kroah-Hartman: + o 004 release + o major database cleanups + o Changed test.block and test.tty to take ACTION from the command line + o don't sleep if 'dev' file is already present on device add + o fix comment about how the "dev" file is made up + o more database work. Now we only store the info we really need right now + o add BUS= bug to TODO list so it will not get forgotten + o spec file changes + o test.block changes + o ok, rpm likes the "_" character instead of "-" better + o change the version to 003-bk to keep things sane with people using the bk tree + o got "remove of named devices" working + o fix segfaults when dealing with partitions + +Kay Sievers: + o man file update + o man page update + +Robert Love: + o udev: mode should be mode_t + o udev: trivial trivialities + o udev: cool test scripts again + o udev spec file symlink support + o udev: cool test scripts + o udev spec file bits + + +Summary of changes from v0.2 to v003 +============================================ + +Daniel E. F. Stekloff: + o udevdb patch + o udevdb prototype + +Greg Kroah-Hartman: + o update the spec file for the new version and install process + o fix makefile release rule to not drop tdb.h file + o Add FAQ for udev + o removed AUTHORS and INSTALL files as they were pretty pointless + o copyright updates + o Add AUTHORS and INSTALL files + o TODO updates + o Updatd the README + o updated the TODO list + o add udev man page (basically just a place holder for now.) + o added uninstall support + o added install target for makefile so people don't have to do it by hand anymore + o add version to debug log on startup + o tell the user what mknod() we are trying to do + o add dbg_parse() to cut down on parse file debugging statements + o put config files and database in /etc/udev by default + o add ols 2003 udev paper to docs/ + o clean up some debugging stuff in namedev.c + o do not build the tdb binary programs, only the objects + o merge tdb into the build process + o Added tdb code from latest cvs version in the samba tree + o added my name to the .spec file + o minor cleanups + o cleanup the mknod code a bit + o remove mknod callout + o handle new major:minor format of dev files that showed up in 2.6.0-test2-bk3 or so + o oops, everything was getting created as 000 mode, try to fix this up, but fail... + o more test stuff + +Olaf Hering: + o print udev pid + +Patrick Mansfield: + o add callout config type to udev + +Paul Mundt: + o Fix TDB cross compilation + o udev spec file + o udev/libsysfs cross compile fixes + + +Summary of changes from v0.1 to v0.2 +============================================ + +Greg Kroah-Hartman: + o more test stuff + o removed unneeded stuff from udev.h + o added 0.2 change log info + o start working on label support, and fix some segfaults for block devices + o test config file changes + o add NUMBER support (basically same logic as TOPOLOGY, perhaps we should + merge this...) + o added topology support + o got REPLACE to work properly + o make struct config_device contain a struct device_attr instead of + duplicating the mess + o block test + o split the tests up into different files + o split udev main logic into udev-add and udev-remove + o Clean up the namedev interface a bit, making the code smaller + o bk: update ignore list + o update the tests to handle block devices too + o add initial libsysfs support + o added libsysfs to the build + o added libsysfs code from sysutils-0.1.1-071803 release + o namedev config files are fully parsed + o more permission tests + o make log_message spit out warnings so I don't have to spend forever + chasing down stupid bugs that aren't there... + o added klibc makefile + o Initial namedev parsing of config files + o sleep for 2 seconds to give the kernel a chance to actually create the + files we need + o pick a better default UDEV_ROOT + o fix up the test to actually work + o added more documentation in README and TODO files + + +Summary of changes up to v0.1 +============================================ + +Greg Kroah-Hartman: + o added more documentation in README and TODO files + o updated the documentation + o cleaned up the makefile a bit + o remove now works! + o restructure code to be able to actually get remove_node() to work + o Creating nodes actually works + o added stupid test script for debugging + o added initial documentation and gpl license + o enabled debugging + o updated ignore list + o added initial files + o fixed up config + o Initial repository create + o BitKeeper file /home/greg/src/udev/udev/ChangeSet + diff --git a/21cnbao/code/05/udev源代码/udev-114/FAQ b/21cnbao/code/05/udev源代码/udev-114/FAQ new file mode 100644 index 0000000..b34c38e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/FAQ @@ -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: + + There is also a udev presentation given at OLS 2003 available at: + + +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 + diff --git a/21cnbao/code/05/udev源代码/udev-114/Makefile b/21cnbao/code/05/udev源代码/udev-114/Makefile new file mode 100644 index 0000000..1c0fda3 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/Makefile @@ -0,0 +1,379 @@ +# +# Copyright (C) 2003-2004 Greg Kroah-Hartman +# Copyright (C) 2004-2006 Kay Sievers +# +# 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/ extras/" +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" diff --git a/21cnbao/code/05/udev源代码/udev-114/README b/21cnbao/code/05/udev源代码/udev-114/README new file mode 100644 index 0000000..74aa790 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/README @@ -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 + diff --git a/21cnbao/code/05/udev源代码/udev-114/RELEASE-NOTES b/21cnbao/code/05/udev源代码/udev-114/RELEASE-NOTES new file mode 100644 index 0000000..e69db23 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/RELEASE-NOTES @@ -0,0 +1,750 @@ +udev 114 +======== +Bugfixes. + +Dynamic rules can be created in /dev/.udev/rules.d/ to trigger +actions by dynamically created rules. + +SYMLINK=="" matches agains the entries in the list of +currently defined symlinks. The links are not created in the +filesystem at that point in time, but the values can be matched. + +RUN{ignore_error}+="" will ignore any exit code from the +program and not record as a failed event. + +udev 113 +======== +Bugfixes. + +Final merge of patches/features from the Ubuntu package. + +udev 112 +======== +Bugfixes. + +Control characters in filesystem label strings are no longer silenty +removed, but hex-encoded, to be able to uniquely identify the device +by its symlink in /dev/disk/by-label/. +If libvolume_id is used by mount(8), LABEL= will work as expected, +if slashes or other characters are used in the label string. + +To test the existence of a file, TEST=="" and TEST!="" +can be specified now. The TEST key accepts an optional mode mask +TEST{0100}=="". + +Scsi_id now supports a mode without expecting scsi-specific sysfs +entries to allow the extraction of cciss-device persistent properties. + +udev 111 +======== +Bugfixes. + +In the future, we may see uuid's which are just simple character +strings (see the DDF Raid Specification). For that reason vol_id now +exports ID_FS_UUID_SAFE, just like ID_FS_LABEL_SAFE. For things like +the creation of symlinks, the *_SAFE values ensure, that no control +or whitespace characters are used in the filename. + +Possible users of libvolume_id, please use the volume_id_get_* functions. +The public struct will go away in a future release of the library. + +udev 110 +======== +Bugfixes. + +Removal of useless extras/eventrecorder.sh. + +udev 109 +======== +Bugfixes. + +udev 108 +======== +Bugfixes. + +The directory multiplexer for dev.d/ and hotplug.d are finally removed +from the udev package. + +udev 107 +======== +Bugfixes. + +Symlinks can have priorities now, the priority is assigned to the device +and specified with OPTIONS="link_priority=100". Devices with higher +priorities overwrite the symlinks of devices with lower priorities. +If the device that currently owns the link, goes away, the symlink +will be removed, and recreated, pointing to the next device with the +highest actual priority. This should make /dev/disk/by-{label,uuid,id} +more reliable, if multiple devices contain the same metadata and overwrite +these symlinks. + +The dasd_id program is removed from the udev tree, and dasdinfo, with the +needed rules, are part of the s390-tools now. + +Please add KERNEL=="[0-9]*:[0-9]*" to the scsi wait-for-sysfs rule, +we may get the scsi sysfs mess fixed some day, and this will only catch +the devices we are looking for. + +USB serial numbers for storage devices have the target:lun now appended, +to make it possibble to distinguish broken multi-lun devices with all +the same SCSI identifiers. + +Note: The extra "run_directory" which searches and executes stuff in +/etc/hotplug.d/ and /etc/dev.d/ is long deprecated, and will be removed +with the next release. Make sure, that you don't use it anymore, or +provides your own implementation of that inefficient stuff. +We are tired of reports about a "slow udev", because these directories +contain stuff, that runs with _every_ event, instead of using rules, +that run programs only for the matching events. + +udev 106 +======== +Bugfixes. + +udev 105 +======== +Bugfixes. + +DRIVER== will match only for devices that actually have a real +driver. DRIVERS== must be used, if parent devices should be +included in the match. + +Libvolume_id's "linux_raid" detection needed another fix. + +udev 104 +======== +Bugfixes. + +udev 103 +======== +Add additional check to volume_id detection of via_raid, cause +some company decided to put a matching pattern all over the empty +storage area of their music players. + +udev 102 +======== +Fix path_id for SAS devices. + +udev 101 +======== +The udev daemon can be started with --debug-trace now, which will +execute all events serialized to get a chance to catch a possible +action that crashes the box. + +A warning is logged, if PHYSDEV* keys, the "device" link, or a parent +device attribute like $attr{../file} is used, only WAIT_FOR_SYSFS rules +are excluded from the warning. Referencing parent attributes directly +may break when something in the kernel driver model changes. Udev will +just find the attribute by walking up the parent chain. + +Udevtrigger now sorts the list of devices depending on the device +dependency, so a "usb" device is triggered after the parent "pci" +device. + +udev 100 +======== +Revert persistent-storage ata-serial '_' '-' replacement. + +udev 099 +======== +Bugfixes. + +Udevtrigger can now filter the list of devices to be triggered. Matches +for subsystems or sysfs attributes can be specified. + +The entries in /dev/.udev/queue and /dev/.udev/failed have changed to +zero-sized files to avoid pointing to /sys and confuse broken tools which +scan the /dev directory. To retry failed events, udevtrigger --retry-failed +should be used now. + +The rules and scripts to create udev rules for persistent network +devices and optical drives are in the extras/rules_generator directory +now. If you use something similar, please consider replacing your own +version with this, to share the support effort. The rule_generator +installs its own rules into /etc/udev/rules.d. + +The cdrom_id tool installs its own rule now in /etc/udev/rules.d, cause +the rule_generator depends on cdrom_id to be called in an earlier rule. + +udev 098 +======== +Bugfixes. + +Renaming of some key names (the old names still work): +BUS -> SUBSYSTEMS, ID -> KERNELS, SYSFS -> ATTRS, DRIVER -> DRIVERS. +(The behavior of the key DRIVER will change soon in one of the next +releases, to match only the event device, please switch to DRIVERS +instead. If DRIVER is used, it will behave like DRIVERS, but an error +is logged. +With the new key names, we have a more consistent and simpler scheme. +We can match the properties of the event device only, with: KERNEL, +SUBSYSTEM, ATTR, DRIVER. Or include all the parent devices in the match, +with: KERNELS, SUBSYSTEMS, ATTRS, DRIVERS. ID, BUS, SYSFS, DRIVER are no +longer mentioned in the man page and should be switched in the rule +files. + +ATTR{file}="value" can be used now, to write to a sysfs file of the +event device. Instead of: + ..., SYSFS{type}=="0|7|14", RUN+="/bin/sh -c 'echo 60 > /sys$$DEVPATH/timeout'" +we now can do: + ..., ATTR{type}=="0|7|14", ATTR{timeout}="60" + +All the PHYSDEV* keys are deprecated and will be removed from a +future kernel: + PHYDEVPATH - is the path of a parent device and should not be + needed at all. + PHYSDEVBUS - is just a SUBSYSTEM value of a parent, and can be + matched with SUBSYSTEMS== + PHYSDEVDRIVER - for bus devices it is available as ENV{DRIVER}. + Newer kernels will have DRIVER in the environment, + for older kernels udev puts in. Class device will + no longer carry this property of a parent and + DRIVERS== can be used to match such a parent value. +Note that ENV{DRIVER} is only available for a few bus devices, where +the driver is already bound at device event time. On coldplug, the +events for a lot devices are already bound to a driver, and they will have +that value set. But on hotplug, at the time the kernel creates the device, +it can't know what driver may claim the device after that, therefore +in most cases it will be empty. + +Failed events should now be re-triggered with: + udevtrigger --retry-failed. +Please switch to this command, so we keep the details of the /dev/.udev/failed/ +files private to the udev tools. We may need to switch the current symlink +target, cause some obviously broken tools try to scan all files in /dev +including /dev/.udev/, find the links to /sys and end up stat()'ing sysfs files +million times. This takes ages on slow boxes. + +The udevinfo attribute walk (-a) now works with giving a device node +name (-n) instead of a devpath (-p). The query now always works, also when +no database file was created by udev. + +The built-in /etc/passwd /etc/group parser is removed, we always depend on +getpwnam() and getgrnam() now. One of the next releases will depend on +fnmatch() and may use getopt_long(). + +udev 097 +======== +Bugfixes and small improvements. + +udev 096 +======== +Fix path_id for recent kernels. + +udev 095 +======== +%e is finally gone. + +Added support for swapping network interface names, by temporarily +renaming the device and wait for the target name to become free. + +udev 094 +======== +The built-in MODALIAS key and substitution is removed. + +udev 093 +======== +The binary firmware helper is replaced by the usual simple +shell script. Udevsend is removed from the tree. + +udev 092 +======== +Bugfix release. + +udev 091 +======== +Some more keys require the correct use of '==' and '=' depending +on the kind of operation beeing an assignment or a match. Rules +with invalid operations are skipped and logged to syslog. Please +test with udevtest if the parsing of your rules throws errors and +fix possibly broken rules. + +udev 090 +======== +Provide "udevsettle" to wait for all current udev events to finish. +It also watches the current kernel netlink queue by comparing the +even sequence number to make sure that there are no current pending +events that have not already arrived in the daemon. + +udev 089 +======== +Fix rule to skip persistent rules for removable IDE devices, which +also skipped optical IDE drives. + +All *_id program are installed in /lib/udev/ by default now. + +No binary is stripped anymore as this should be done in the +packaging process and not at build time. + +libvolume_id is provided as a shared library now and vol_id is +linked against it. Also one of the next HAL versions will require +this library, and the HAL build process will also require the +header file to be installed. The copy of the same code in HAL will +be removed to have only a single copy left on the system. + +udev 088 +======== +Add persistent links for SCSI tapes. The rules file is renamed +to 60-persistent-storage.rules. + +Create persistent path for usb devices. Can be used for all sorts +of devices that can't be distinguished by other properties like +multiple identical keyboards and mice connected to the same box. + +Provide "udevtrigger" program to request events on coldplug. The +shell script is much too slow with thousends of devices. + +udev 087 +======== +Fix persistent disk rules to exclude removable IDE drives. + +Warn if %e, $modalias or MODALIAS is used. + +udev 086 +======== +Fix queue export, which wasn't correct for subsequent add/remove +events for the same device. + +udev 085 +======== +Fix cramfs detection on big endian. + +Make WAIT_FOR_SYSFS usable in "normal" rules and silent if the whole +device goes away. + +udev 084 +======== +If BUS== and SYSFS{}== have been used in the same rule, the sysfs +attributes were only checked at the parent device that matched the +by BUS requested subsystem. Fix it to also look at the device we +received the event for. + +Build variable CROSS has changed to CROSS_COMPILE to match the kernel +build name. + +udev 083 +======== +Fix a bug where NAME="" would prevent RUN from beeing executed. + +RUN="/bin/program" does not longer automatically add the subsystem +as the first parameter. This is from the days of /sbin/hotplug +which is dead now and it's just confusing to need to add a space at +the end of the program name to prevent this. +If you use rules that need the subsystem as the first parameter, +like the old "udev_run_hotlugd" and "udev_run_devd", add the subsystem +to the key like RUN+="/bin/program $env{SUBSYSTEM}". + +udev 082 +======== +The udev man page has moved to udev(7) as it does not describe a command +anymore. The programs udev, udevstart and udevsend are no longer installed +by default and must be copied manually, if they should be installed or +included in a package. + +Fix a bug where "ignore_device" could run earlier collected RUN keys before +the ignore rule was applied. + +More preparation for future sysfs changes. usb_id and scsi_id no longer +depend on a magic order of devices in the /devices chain. Specific devices +should be requested by their subsytem. + +This will always find the scsi parent device without depending on a specific +path position: + dev = sysfs_device_get(devpath); + dev_usb = sysfs_device_get_parent_with_subsystem(dev, "scsi"); + +The "device" link in the current sysfs layout will be automatically +_resolved_ as a parent and in the new sysfs layout it will just _be_ the +parent in the devpath. If a device is requested by it's symlink, like all +class devices in the new sysfs layout will look like, it gets automatically +resolved and substituted with the real devpath and not the symlink path. + +Note: +A similar logic must be applied to _all_ sysfs users, including +scripts, that search along parent devices in sysfs. The explicit use of +the "device" link must be avoided. With the future sysfs layout all +DEVPATH's will start with /devices/ and have a "subsystem" symlink poiting +back to the "class" or the "bus". The layout of the parent devices in +/devices is not necessarily expected to be stable across kernel releases and +searching for parents by their subsystem should make sysfs users tolerant +for changed parent chains. + +udev 081 +======== +Prepare udev to work with the experimental kernel patch, that moves +/sys/class devices to /sys/devices and /sys/block to /sys/class/block. + +Clarify BUS, ID, $id usage and fix $id behavior. This prepares for +moving the class devices to /sys/devices. + +Thanks again to Marco for help finding a hopefully nice compromise +to make %b simpler and working again. + +udev 080 +======== +Complete removal of libsysfs, replaced by simple helper functions +which are much simpler and a bit faster. The udev daemon operatesentirely +on event parameters and does not use sysfs for simple rules anymore. +Please report any new bugs/problems, that may be caused by this big +change. They will be fixed immediately. + +The enumeration format character '%e' is deprecated and will be +removed sometimes from a future udev version. It never worked correctly +outside of udevstart, so we can't use it with the new parallel +coldplug. A simple enumeration is as useless as the devfs naming +scheme, just get rid of both if you still use it. + +MODALIAS and $modalias is not needed and will be removed from one of +the next udev versions, replace it in all rules with ENV{MODALIAS} or +the sysfs "modalias" value. + +Thanks a lot to Marco for all his help on finding and fixing bugs. + +udev 079 +======== +Let scsi_id request libata drive serial numbers from page 0x80. + +Renamed etc/udev/persistent.rules to persistent-disk.rules and +added /dev/disk/by-name/* for device mapper device names. + +Removed %e from the man page. It never worked reliably outside +of udevstart and udevstart is no longer recommended to use. + +udev 078 +======== +Symlinks are now exported to the event environment. Hopefully it's no +longer needed to run udevinfo from an event process, like it was +mentioned on the hotplug list: + UDEV [1134776873.702967] add@/block/sdb + ... + DEVNAME=/dev/sdb + DEVLINKS=/dev/disk/by-id/usb-IBM_Memory_Key_0218B301030027E8 /dev/disk/by-path/usb-0218B301030027E8:0:0:0 + +udev 077 +======== +Fix a problem if udevsend is used as the hotplug handler and tries to use +syslog, which causes a "vc" event loop. 2.6.15 will make udevsend obsolete +and this kind of problems will hopefully go away soon. + +udev 076 +======== +All built-in logic to work around bad sysfs timing is removed with this +version. The need to wait for sysfs files is almost fixed with a kernel +version that doesn't work with this udev version anyway. Until we fix +the timing of the "bus" link creation, the former integrated logic should +be emulated by a rule placed before all other rules: + ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus" + +The option "udev_db" does no longer exist. All udev state will be in +/$udev_root/.udev/ now, there is no longer an option to set this +to anything else. +If the init script or something else used this value, just depend on +this hardcoded path. But remember _all_content_ of this directory is +still private to udev and can change at any time. + +Default location for rule sripts and helper programs is now: /lib/udev/. +Everything that is not useful on the commandline should go into this +directory. Some of the helpers in the extras folder are installed there +now. The rules need to be changed, to find the helpers there. + +Also /lib/udev/devices is recommended as a directory where packages or +the user can place real device nodes, which get copied over to /dev at +every boot. This should replace the various solutions with custom config +files. + +Udevsend does no longer start the udev daemon. This must be done with +the init script that prepares /dev on tmpfs and creates the initial nodes, +before starting the daemon. + +udev 075 +======== +Silent a too verbose error logging for the old hotplug.d/ dev.d/ +emulation. + +The copy of klibc is removed. A systemwide installed version of klibc +should be used to build a klibc udev now. + +udev 074 +======== +NAME="" will not create any nodes, but execute RUN keys. To completely +ignore an event the OPTION "ignore_device" should be used. + +After removal of the reorder queue, events with a TIMEOUT can be executed +without any queuing now. + +udev 073 +======== +Fixed bug in udevd, if inotify is not available. We depend on netlink +uevents now, kernels without that event source will not work with that +version of udev anymore. + +udev 072 +======== +The rule parsing happens now in the daemon once at startup, all udev +event processes inherit the already parsed rules from the daemon. +It is shipped with SUSE10.0 and reduces heavily the system load at +startup. The option to save precompiled rules and let the udev process +pick the them up is removed, as it's no longer needed. + +Kernel 2.6.15 will have symlinks at /class/input pointing to the real +device. Libsysfs is changed to "translate" the requested link into the +real device path, as it would happen with the hotplug event. Otherwise +device removal and the udev database will not work. + +Using 'make STRIPCMD=' will leave the binaries unstripped for debugging +and packaging. + +A few improvements for vol_id, the filesytem probing code. + +udev 071 +======== +Fix a stupid typo in extras/run_directory for "make install". + +scsi_id creates the temporary devnode now in /dev for usage with a +non-writable /tmp directory. + +The uevent kernel socket buffer can carry app. 50.000 events now, +let's see who can break this again. :) + +The upcoming kernel will have a new input driver core integration. +Some class devices are now symlinks to the real device. libsysfs +needs a fix for this to work correctly. Udevstart of older udev +versions will _not_ create these devices! + +udev 070 +======== +Fix a 'install' target in the Makefile, that prevents EXTRAS from +beeing installed. + +udev 069 +======== +A bunch of mostly trivial bugfixes. From now on no node name or +symlink name can contain any character than plain whitelisted ascii +characters or validated utf8 byte-streams. This is needed for the +/dev/disk/by-label/* links, because we import untrusted data and +export it to the filesystem. + +udev 068 +======== +More bugfixes. If udevd was started from the kernel, we don't +have stdin/stdout/stderr, which broke the forked tools in some +situations. + +udev 067 +======== +Bugfix. udevstart event ordering was broken for a long time. +The new run_program() uncovered it, because /dev/null was not +available while we try to run external programs. +Now udevstart should create it before we run anything. + +udev 066 +======== +Minor bugfixes and some distro rules updates. If you don't have the +persistent disk rules in /dev/disk/by-*/* on your distro, just +grab it from here. :) + +udev 065 +======== +We can use socket communication now to pass events from udev to +other programs: + RUN+="socket:/org/freedesktop/hal/udev_event" +will pass the whole udev event to the HAL daemon without the need +for a forked helper. (See ChangeLog for udevmonitor, as an example) + +udev 064 +======== +Mostly bugfixes and see ChangeLog. + +The test for the existence of an environment value should be +switched from: + ENV{KEY}=="*" to ENV{KEY}=="?*" +because "*" will not fail anymore, if the key does not exist or +is empty. + +udev 063 +======== +Bugfixes and a few tweaks described in the ChangeLog. + +udev 062 +======== +Mostly a Bugfix release. + +Added WAIT_FOR_SYSFS="" to be able to fight against the sysfs +timing with custom rules. + +udev 061 +======== +We changed the internal rule storage format. Our large rule files took +2 MB of RAM, with the change we are down to 99kB. + +If the device-node has been created with default name and no symlink or +options are to remenber, it is not longer stored in the udevdb. HAL will +need to be updated to work correctly with that change. + +To overrride optimization flags, OPTFLAGS may be used now. + +udev 060 +======== +Bugfix release. + +udev 059 +======== +Major changes happened with this release. The goal is to take over the +complete kernel-event handling and provide a more efficient way to dispatch +kernel events. Replacing most of the current shell script logic and the +kernel forked helper with a netlink-daemon and a rule-based event handling. + +o udevd listens to netlink events now. The first valid netlink event + will make udevd ignore any message from udevsend that contains a + SEQNUM, to avoid duplicate events. The forked events can be disabled + with: + echo "" > /proc/sys/kernel/hotplug + For full support, the broken input-subsytem needs to be fixed, not to + bypass the driver core. + +o /etc/dev.d/ + /etc/hotplug.d/ directory multiplexing is completely + removed from udev itself and must be emulated by calling small + helper binaries provided in the extras folder: + make EXTRAS=extras/run_directory/ + will build udev_run_devd and udev_run_hotplugd, which can be called + from a rule if needed: + RUN+="/sbin/udev_run_hotplugd" + The recommended way to handle this is to convert all the calls from + the directories to explicit udev rules and get completely rid of the + multiplexing. (To catch a ttyUSB event, you now no longer need to + fork and exit 300 tty script instances you are not interested in, it + is just one rule that matches exactly the device.) + +o udev handles now _all_ events not just events for class and block + devices, this way it is possible to control the complete event + behavior with udev rules. Especially useful for rules like: + ACTION="add", DEVPATH="/devices/*", MODALIAS=="?*", RUN+="/sbin/modprobe $modalias" + +o As used in the modalias rule, udev supports now textual + substitution placeholder along with the usual format chars. This + needs to be documented, for now it's only visible in udev_rules_parse.c. + +o The rule keys support now more operations. This is documented in the + man page. It is possible to add values to list-keys like the SYMLINK + and RUN list with KEY+="value" and to clear the list by assigning KEY="". + Also "final"-assignments are supported by using KEY:="value", which will + prevent changing the key by any later rule. + +o kernel 2.6.12 has the "detached_state" attribute removed from + sysfs, which was used to recognize sysfs population. We switched that + to wait for the "bus" link, which is only available in kernels after 2.6.11. + Running this udev version on older kernels may cause a short delay for + some events. + +o To provide infrastructure for persistent device naming, the id programs: + scsi_id, vol_id (former udev_volume_id), and ata_id (new) are able now + to export the probed data in environment key format: + pim:~ # /sbin/ata_id --export /dev/hda + ID_MODEL=HTS726060M9AT00 + ID_SERIAL=MRH401M4G6UM9B + ID_REVISION=MH4OA6BA + + The following rules: + KERNEL="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" + KERNEL="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_MODEL}_$env{ID_SERIAL}" + + Will create: + kay@pim:~> tree /dev/disk + /dev/disk + |-- by-id + | |-- HTS726060M9AT00_MRH401M4G6UM9B -> ../../hda + | `-- IBM-Memory_Key -> ../../sda + |-- by-label + | |-- swap -> ../../hda1 + | |-- date -> ../../sda1 + | `-- home -> ../../hda3 + `-- by-uuid + |-- 2E08712B0870F2E7 -> ../../hda3 + |-- 9352cfef-7687-47bc-a2a3-34cf136f72e1 -> ../../hda1 + |-- E845-7A89 -> ../../sda1 + `-- b2a61681-3812-4f13-a4ff-920d70604299 -> ../../hda2 + + The IMPORT= operation will import these keys in the environment and make + it available for later PROGRAM= and RUN= executed programs. The keys are + also stored in the udevdb and can be queried from there with one of the + next udev versions. + +o A few binaries are silently added to the repository, which can be used + to replay kernel events from initramfs instead of using coldplug. udevd + can be instructed now to queue-up events while the stored events from + initramfs are filled into the udevd-queue. This code is still under + development and there is no documentation now besides the code itself. + The additional binaries get compiled, but are not installed by default. + +o There is also a temporary fix for a performance problem where too many + events happen in parallel and every event needs to parse the rules. + udev can now read precompiled rules stored on disk. This is likely to be + replaced by a more elegant solution in a future udev version. + +udev 058 +======== +With kernel version 2.6.12, the sysfs file "detached_state" was removed. +Fix for libsysfs not to expect this file was added. + +udev 057 +======== +All rules are applied now, but only the first matching rule with a NAME-key +will be applied. All later rules with NAME-key are completely ignored. This +way system supplied symlinks or permissions gets applied to user-defined +naming rules. + +Note: +Please check your rules setup, if you may need to add OPTIONS="last_rule" +to some rules, to keep the old behavior. + +The rules are read on "remove"-events too. That makes is possible to match +with keys that are available on remove (KERNEL, SUBSYSTEM, ID, ENV, ...) to +instruct udev to ignore an event (OPTIONS="ignore_device"). +The new ACTION-key may be used to let a rule act only at a "remove"-event. + +The new RUN-key supports rule-based execution of programs after device-node +handling. This is meant as a general replacement for the dev.d/-directories +to give fine grained control over the execution of programs. + +The %s{}-sysfs format char replacement values are searched at any of the +devices in the device chain now, not only at the class-device. + +We support log priority levels now. The value udev_log in udev.conf is used +to determine what is printed to syslog. This makes it possible to +run a version with compiled-in debug messages in a production environment +which is sometimes needed to find a bug. +It is still possible to supress the inclusion of _any_ syslog usage with +USE_LOG=false to create the smallest possible binaries if needed. +The configured udev_log value can be overridden with the environment variable +UDEV_LOG. + +udev 056 +======== +Possible use of a system-wide klibc: + make USE_KLIBC=true KLCC=/usr/bin/klcc all +will link against an external klibc and our own version will be ignored. + +udev 055 +======== +We support an unlimited count of symlinks now. + +If USE_STATIC=true is passed to a glibc build, we link statically and use +a built-in userdb parser to resolve user and group names. + +The PLACE= key is gone. It can be replaced by an ID= for a long time, because +we walk up the chain of physical devices to find a match. + +The KEY="" format supports '=', '==', '!=,' , '+=' now. This makes it +easy to skip certain attribute matches without composing rules with weird +character class negations like: + KERNEL="[!s][!c][!d]*" +this can now be replaced with: + KERNEL!="scd*" +The current simple '=' is still supported, and should work as it does today, +but existing rules should be converted if possible, to be better readable. + +We have new ENV{}== key now, to match against a maximum of 5 environment +variables. + +udevstart is its own binary again, because we don't need co carry this araound +with every forked event. diff --git a/21cnbao/code/05/udev源代码/udev-114/TODO b/21cnbao/code/05/udev源代码/udev-114/TODO new file mode 100644 index 0000000..380de48 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/TODO @@ -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) diff --git a/21cnbao/code/05/udev源代码/udev-114/docs/README-gcov_for_udev b/21cnbao/code/05/udev源代码/udev-114/docs/README-gcov_for_udev new file mode 100644 index 0000000..c223dc3 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/docs/README-gcov_for_udev @@ -0,0 +1,90 @@ +################################################ + +Using GCC's code coverage tool, gcov, with udev + +Leann Ogasawara , 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 diff --git a/21cnbao/code/05/udev源代码/udev-114/docs/overview b/21cnbao/code/05/udev源代码/udev-114/docs/overview new file mode 100644 index 0000000..87c1d1d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/docs/overview @@ -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. + diff --git a/21cnbao/code/05/udev源代码/udev-114/docs/udev_vs_devfs b/21cnbao/code/05/udev源代码/udev-114/docs/udev_vs_devfs new file mode 100644 index 0000000..9e803ca --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/docs/udev_vs_devfs @@ -0,0 +1,192 @@ + udev and devfs - The final word + + December 30, 2003 + Greg Kroah-Hartman + + + +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: + +and the slides for the talk, available at: + +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 diff --git a/21cnbao/code/05/udev源代码/udev-114/docs/writing_udev_rules/index.html b/21cnbao/code/05/udev源代码/udev-114/docs/writing_udev_rules/index.html new file mode 100644 index 0000000..b41664b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/docs/writing_udev_rules/index.html @@ -0,0 +1,838 @@ + + + + + +Writing udev rules + + + + +

Writing udev rules

+by Daniel Drake (dsd)
+Version 0.72

+ +The most recent version of this document can always be found at:
+ +http://www.reactivated.net/writing_udev_rules.html + +

Contents

+ + +

Introduction

+ + +

About this document

+ +

+udev is targeted at Linux kernels 2.6 and beyond to provide a userspace solution for a dynamic /dev directory, with persistent device naming. The previous /dev implementation, devfs, is now deprecated, and udev is seen as the successor. udev vs devfs is a sensitive area of conversation - you should read this document before making comparisons. +

+ +

+Over the years, the things that you might use udev rules for has changed, as well as the flexibility of rules themselves. On a modern system, udev provides persistent naming for some device types out-of-the-box, eliminating the need for custom rules for those devices. However, some users will still require the extra level of customisation. +

+ +

+This document assumes that you have udev installed and running OK with default configurations. This is usually handled by your Linux distribution. +

+ +

+This document does not cover every single detail of rule writing, but does aim to introduce all of the main concepts. The finer details can be found in the udev man page. +

+ +

+This document uses various examples (many of which are entirely fictional) to illustrate ideas and concepts. Not all syntax is explicitly described in the accompanying text, be sure to look at the example rules to get a complete understanding. +

+ + +

History

+ +
    +
      October 2nd 2006 v0.72: Fixed a typo in one of the example rules. +
    • June 10th 2006 v0.71: Misc changes based on recent feedback - thanks!
    • +
    • June 3rd 2006 v0.7: Complete rework, to be more suited for the modern-day udev.
    • +
    • May 9th 2005 v0.6: Misc updates, including information about udevinfo, groups and permissions, logging, and udevtest.
    • +
    • June 20th 2004 v0.55: Added info on multiple symlinks, and some minor changes/updates.
    • +
    • April 26th 2004 v0.54: Added some Debian info. Minor corrections. Re-reverted information about what to call your rule file. Added info about naming network interfaces.
    • +
    • April 15th 2004 v0.53: Minor corrections. Added info about NAME{all_partitions}. Added info about other udevinfo tricks.
    • +
    • April 14th 2004 v0.52: Reverted to suggesting using "udev.rules" until the udev defaults allow for other files. Minor work.
    • +
    • April 6th 2004 v0.51: I now write suggest users to use their own "local.rules" file rather than prepending "udev.rules".
    • +
    • April 3rd 2004 v0.5: Minor cleanups and preparations for possible inclusion in the udev distribution.
    • +
    • March 20th 2004 v0.4: General improvements, clarifications, and cleanups. Added more information about writing rules for usb-storage.
    • +
    • February 23rd 2004 v0.3: Rewrote some parts to emphasise how sysfs naming works, and how it can be matched. Updated rule-writing parts to represent udev 018s new SYSFS{filename} naming scheme. Improved sectioning, and clarified many points. Added info about KDE.
    • +
    • February 18th 2004 v0.2: Fixed a small omission in an example. Updated section on identifying mass-storage devices. Updated section on nvidia.
    • +
    • February 15th 2004 v0.1: Initial publication.
    • +
    + +

    The concepts

    + + +

    Terminology: devfs, sysfs, nodes, etc.

    + +

    +A basic introduction only, might not be totally accurate. +

    + +

    +On typical Linux-based systems, the /dev directory is used to store file-like device nodes which refer to certain devices in the system. Each node points to a part of the system (a device), which might or might not exist. Userspace applications can use these device nodes to interface with the systems hardware, for example, the X server will "listen to" /dev/input/mice so that it can relate the user's mouse movements to moving the visual mouse pointer. +

    + +

    +The original /dev directories were just populated with every device that might possibly appear in the system. /dev directories were typically very large because of this. devfs came along to provide a more manageable approach (noticeably, it only populated /dev with hardware that is plugged into the system), as well as some other functionality, but the system proved to have problems which could not be easily fixed. +

    + +

    +udev is the "new" way of managing /dev directories, designed to clear up some issues with previous /dev implementations, and provide a robust path forward. In order to create and name /dev device nodes corresponding to devices that are present in the system, udev relies on matching information provided by sysfs with rules provided by the user. This documentation aims to detail the process of rule-writing, one of the only udev-related tasks that must (optionally) be performed by the user. +

    + +

    +sysfs is a new filesystem to the 2.6 kernels. It is managed by the kernel, and exports basic information about the devices currently plugged into your system. udev can use this information to create device nodes corresponding to your hardware. sysfs is mounted at /sys and is browseable. You may wish to investigate some of the files stored there before getting to grips with udev. Throughout this document, I will use the terms /sys and sysfs interchangeably. +

    + + +

    Why?

    + +

    +udev rules are flexible and very powerful. Here are some of the things you can use rules to achieve: +

    + +
      +
    • Rename a device node from the default name to something else
    • +
    • Provide an alternative/persistent name for a device node by creating a symbolic link to the default device node
    • +
    • Name a device node based on the output of a program
    • +
    • Change permissions and ownership of a device node
    • +
    • Launch a script when a device node is created or deleted (typically when a device is attached or unplugged)
    • +
    • Rename network interfaces
    • +
    + +

    +Writing rules is not a workaround for the problem where no device nodes for your particular device exist. Even if there are no matching rules, udev will create the device node with the default name supplied by the kernel. +

    + +

    +Having persistently named device nodes has several advantages. Assume you own two USB storage devices: a digital camera and a USB flash disk. These devices are typically assigned device nodes /dev/sda and /dev/sdb but the exact assignment depends on the order which they were originally connected. This may cause problems to some users, who would benefit greatly if each device could be named persistently every time, e.g. /dev/camera and /dev/flashdisk. +

    + + +

    Built-in persistent naming schemes

    + +

    +udev provides persistent naming for some device types out of the box. This is a very useful feature, and in many circumstances means that your journey ends here: you do not have to write any rules. +

    + +

    +udev provides out-of-the-box persistent naming for storage devices in the /dev/disk directory. To view the persistent names which have been created for your storage hardware, you can use the following command: +

    + +
    # ls -lR /dev/disk
    + +

    +This works for all storage types. As an example, udev has created /dev/disk/by-id/scsi-SATA_ST3120827AS_4MS1NDXZ-part3 which is a persistent-named symbolic link to my root partition. udev creates /dev/disk/by-id/usb-Prolific_Technology_Inc._USB_Mass_Storage_Device-part1 when I plug my USB flash disk in, which is also a persistent name. +

    + + + +

    Rule writing

    + + +

    Rule files and semantics

    + +

    +When deciding how to name a device and which additional actions to perform, udev reads a series of rules files. These files are kept in the /etc/udev/rules.d directory, and they all must have the .rules suffix. +

    + +

    +Default udev rules are stored in /etc/udev/rules.d/50-udev.rules. You may find it interesting to look over this file - it includes a few examples, and then some default rules proving a devfs-style /dev layout. However, you should not write rules into this file directly. +

    + +

    +Files in /etc/udev/rules.d/ are parsed in lexical order, and in some circumstances, the order in which rules are parsed is important. In general, you want your own rules to be parsed before the defaults, so I suggest you create a file at /etc/udev/rules.d/10-local.rules and write all your rules into this file. +

    + +

    +In a rules file, lines starting with "#" are treated as comments. Every other non-blank line is a rule. Rules cannot span multiple lines. +

    + +

    +One device can be matched by more than one rule. This has it's practical advantages, for example, we can write two rules which match the same device, where each one provides its own alternate name for the device. Both alternate names will be created, even if the rules are in separate files. It is important to understand that udev will not stop processing when it finds a matching rule, it will continue searching and attempt to apply every rule that it knows about. +

    + + +

    Rule syntax

    + +

    +Each rule is constructed from a series of key-value pairs, which are separated by commas. match keys are conditions used to identify the device which the rule is acting upon. When all match keys in a rule correspond to the device being handled, then the rule is applied and the actions of the assignment keys are invoked. Every rule should consist of at least one match key and at least one assignment key. +

    + +

    +Here is an example rule to illustrate the above: +

    + +
    KERNEL=="hdb", NAME="my_spare_disk"
    + +

    +The above rule includes one match key (KERNEL) and one assignment key (NAME). The semantics of these keys and their properties will be detailed later. It is important to note that the match key is related to its value through the equality operator (==), whereas the assignment key is related to its value through the assignment operator (=). +

    + + +

    Basic Rules

    + +

    +udev provides several different match keys which can be used to write rules which match devices very precisely. Some of the most common keys are introduced below, others will be introduced later in this document. For a complete list, see the udev man page. +

    + +
      +
    • KERNEL - match against the kernel name for the device
    • +
    • SUBSYSTEM - match against the subsystem of the device
    • +
    • DRIVER - match against the driver name for the device
    • +
    + +

    +After you have used a series of match keys to precisely match a device, udev gives you fine control over what happens next, through a range of assignment keys. For a complete list of possible assignment keys, see the udev man page. The most basic assignment keys are introduced below. Others will be introduced later in this document. +

    + +
      +
    • NAME - the name that shall be used for the device node
    • +
    • SYMLINK - a list of symbolic links which act as alternative names for the device node
    • +
    + +

    +As hinted above, udev only creates one true device node for one device. If you wish to provide alternate names for this device node, you use the symbolic link functionality. With the SYMLINK assignment, you are actually maintaining a list of symbolic links, all of which will be pointed at the real device node. To manipulate these links, we introduce a new operator for appending to lists: +=. You can append multiple symlinks to the list from any one rule by separating each one with a space. +

    + +
    KERNEL=="hdb", NAME="my_spare_disk"
    + +

    +The above rule says: match a device which was named by the kernel as hdb, and instead of calling it hdb, name the device node as my_spare_disk. The device node appears at /dev/my_spare_disk. +

    + +
    KERNEL=="hdb", DRIVER=="ide-disk", SYMLINK+="sparedisk"
    + +

    +The above rule says: match a device which was named by the kernel as hdb AND where the driver is ide-disk. Name the device node with the default name and create a symbolic link to it named sparedisk. Note that we did not specify a device node name, so udev uses the default. In order to preserve the standard /dev layout, your own rules will typically leave the NAME alone but create some SYMLINKs and/or perform other assignments. +

    + +
    KERNEL=="hdc", SYMLINK+="cdrom cdrom0"
    + +

    +The above rule is probably more typical of the types of rules you might be writing. It creates two symbolic links at /dev/cdrom and /dev/cdrom0, both of which point at /dev/hdc. Again, no NAME assignment was specified, so the default kernel name (hdc) is used. +

    + + +

    Matching sysfs attributes

    + +

    +The match keys introduced so far only provide limited matching capabilities. Realistically we require much finer control: we want to identify devices based on advanced properties such as vendor codes, exact product numbers, serial numbers, storage capacities, number of partitions, etc. +

    + +

    +Many drivers export information like this into sysfs, and udev allows us to incorporate sysfs-matching into our rules, using the SYSFS key with a slightly different syntax. +

    + +

    +Here are some examples of rules which match data from sysfs. Further detail will be provided later in this document which will aid you in writing rules based on sysfs attributes. +

    + +
    +KERNEL=="sda", SYSFS{model}=="ST3120827AS", SYMLINK+="my_hard_disk"
    +SUBSYSTEM=="block", SYSFS{size}=="234441648", SYMLINK+="my_disk"
    +BUS=="usb", SYSFS{manufacturer}=="OLYMPUS", SYSFS{product}=="X250,D560Z,C350Z", SYMLINK+="camera"
    +
    + + +

    String substitutions

    + +

    +When writing rules which will potentially handle multiple similar devices, udev's printf-like string substitution operators are very useful. You can simply include these operators in any assignments your rule makes, and udev will evaluate them when they are executed. +

    + +

    +The most common operators are %k and %n. %k evaluates to the kernel name for the device, e.g. "sda3" for a device that would (by default) appear at /dev/sda3. %n evaluates to the kernel number for the device (the partition number for storage devices), e.g. "3" for /dev/sda3. +

    + +

    +udev also provides several other substitution operators for more advanced functionality. Consult the udev man page after reading the rest of this document. There is also an alternative syntax for these operators - $kernel and $number for the examples above. For this reason, if you wish to match a literal % in a rule then you must write %%, and if you wish to match a literal $ then you must write $$. +

    + +

    +To illustrate the concept of string substitution, some example rules are shown below. +

    + +
    +KERNEL=="mice", NAME="input/%k"
    +KERNEL=="loop0", NAME="loop/%n", SYMLINK+="%k"
    +
    + +

    +The first rule ensures that the mice device node appears exclusively in the /dev/input directory (by default it would be at /dev/mice). The second rule ensures that the device node named loop0 is created at /dev/loop/0 but also creates a symbolic link at /dev/loop0 as usual. +

    + +

    +The use of the above rules is questionable, as they all could be rewritten without using any substitution operators. The true power of these substitutions will become apparent in the next section. +

    + + +

    String matching

    + +

    +As well as matching strings exactly, udev allows you to use shell-style pattern matching. There are 3 patterns supported: +

    + +
      +
    • * - match any character, zero or more times
    • +
    • ? - match any character exactly once
    • +
    • [] - match any single character specified in the brackets, ranges are also permitted
    • +
    + +

    +Here are some examples which incorporate the above patterns. Note the use of the string substitution operators. +

    + +
    +KERNEL=="fd[0-9]*", NAME="floppy/%n", SYMLINK+="%k"
    +KERNEL=="hiddev*", NAME="usb/%k"
    +
    + +

    +The first rule matches all floppy disk drives, and ensures that the device nodes are placed in the /dev/floppy directory, as well as creating a symbolic link from the default name. The second rule ensures that hiddev devices are only present in the /dev/usb directory. +

    + +

    Finding information from sysfs

    + + +

    The sysfs tree

    + +

    +The concept of using interesting information from sysfs was briefly touched upon above. In order to write rules based on this information, you first need to know the names of the attributes and their current values. +

    + +

    +sysfs is actually a very simple structure. It is logically divided into directories. Each directory contains a number of files (attributes) which typically contain just one value. Some symbolic links are present, which link various parts of the tree together. +

    + +

    +Some directories are referred to as top-level device paths. These directories act as the top-level glue which chain other parts of sysfs to the device in question. Top-level device paths can be classified as sysfs directories which contain a dev file, the following command will list these for you: +

    + +
    # find /sys -name dev
    + +

    +For example, on my system, the /sys/block/sda directory is the device path for my hard disk. It is chained to the controller through the /sys/block/sda/device/ symbolic link, which is in turn chained to the device driver through the /sys/block/sda/device/driver/ symbolic link. +

    + +

    +When you write rules based on sysfs information, you are simply matching attribute contents of some files in one part of the chain. For example, I can read the size of my hard disk as follows: +

    + +
    +# cat /sys/block/sda/size
    +234441648
    +
    + +

    +In a udev rule, I could use SYSFS{size}=="234441648" to identify this disk. As udev iterates through the entire device chain, I could alternatively opt to match attributes in another part of the chain (e.g. attributes in /sys/class/block/sda/device/), however there are some caveats when dealing with different parts of the chain which are described later. +

    + +

    +Although this serves as a useful introduction as to the structure of sysfs and exactly how udev matches values, manually trawling through sysfs is both time consuming and unnecessary. +

    + + +

    udevinfo

    + +

    +Enter udevinfo, which is probably the most straightforward tool you can use to construct rules. All you need to know is the sysfs device path of the device in question. A trimmed example is shown below: +

    + +
    +# udevinfo -a -p /sys/block/sda
    +
    +  looking at device '/block/sda':
    +    KERNEL=="sda"
    +    SUBSYSTEM=="block"
    +    SYSFS{stat}=="  128535     2246  2788977   766188    73998   317300  3132216  5735004        0   516516  6503316"
    +    SYSFS{size}=="234441648"
    +    SYSFS{removable}=="0"
    +    SYSFS{range}=="16"
    +    SYSFS{dev}=="8:0"
    +
    +  looking at device '/devices/pci0000:00/0000:00:07.0/host0/target0:0:0/0:0:0:0':
    +    ID=="0:0:0:0"
    +    BUS=="scsi"
    +    DRIVER=="sd"
    +    SYSFS{ioerr_cnt}=="0x0"
    +    SYSFS{iodone_cnt}=="0x31737"
    +    SYSFS{iorequest_cnt}=="0x31737"
    +    SYSFS{iocounterbits}=="32"
    +    SYSFS{timeout}=="30"
    +    SYSFS{state}=="running"
    +    SYSFS{rev}=="3.42"
    +    SYSFS{model}=="ST3120827AS     "
    +    SYSFS{vendor}=="ATA     "
    +    SYSFS{scsi_level}=="6"
    +    SYSFS{type}=="0"
    +    SYSFS{queue_type}=="none"
    +    SYSFS{queue_depth}=="1"
    +    SYSFS{device_blocked}=="0"
    +
    + +

    +As you can see, udevinfo simply produces a list of attributes you can use as-is as match keys in your udev rules. From the above example, I could produce (e.g.) either of the following two rules for this device: +

    + +
    +SUBSYSTEM=="block", SYSFS{size}=="234441648", NAME="my_hard_disk"
    +BUS=="scsi", SYSFS{model}=="ST3120827AS", NAME="my_hard_disk"
    + +

    +You may have noted the use of colour in the above examples. This is to demonstrate that you generally can not mix-and-match attributes from different sections of the udevinfo output - your rule will not work. For example, the following rule is invalid: +

    + +
    +SUBSYSTEM=="block", SYSFS{size}=="234441648", SYSFS{model}=="ST3120827AS", NAME="my_hard_disk"
    + +

    +You are usually provided with a large number of attributes, and you must pick a number of them (from the same section) to construct your rule. In general, you want to choose attributes which identify your device in a persistent and human-recognisable way. In the examples above, I chose the size of my disk and its model number. I did not use meaningless numbers such as SYSFS{iodone_cnt}=="0x31737". +

    + +

    +Another point to note is that it is common for text attributes to appear in the udevinfo output to be padded with spaces (e.g. see ST3120827AS above). In your rules, you can either specify the extra spaces, or you can cut them off as I have done. +

    + +

    +The only complication with using udevinfo is that you are required to know the top-level device path (/sys/block/sda in the example above). This is not always obvious. However, as you are generally writing rules for device nodes which already exist, you can use udevinfo to look up the device path for you: +

    + +
    # udevinfo -a -p $(udevinfo -q path -n /dev/sda)
    + + +

    Alternative methods

    + +

    +Although udevinfo is almost certainly the most straightforward way of listing the exact attributes you can build rules from, some users are happier with other tools. Utilities such as usbview display a similar set of information, most of which can be used in rules. +

    + +

    Advanced topics

    + + +

    Controlling permissions and ownership

    + +

    +udev allows you to use additional assignments in rules to control ownership and permission attributes on each device. +

    + +

    +The GROUP assignment allows you to define which Unix group should own the device node. Here is an example rule which defines that the video group will own the framebuffer devices: +

    + +
    KERNEL=="fb[0-9]*", NAME="fb/%n", SYMLINK+="%k", GROUP="video"
    + +

    +The OWNER key, perhaps less useful, allows you to define which Unix user should have ownership permissions on the device node. Assuming the slightly odd situation where you would want john to own your floppy devices, you could use: +

    + +
    KERNEL=="fd[0-9]*", OWNER="john"
    + +

    +udev defaults to creating nodes with Unix permissions of 0660 (read/write to owner and group). If you need to, you can override these defaults on certain devices using rules including the MODE assignment. As an example, the following rule defines that the inotify node shall be readable and writable to everyone: +

    + +
    KERNEL=="inotify", NAME="misc/%k", SYMLINK+="%k", MODE="0666"
    + + +

    Using external programs to name devices

    + +

    +Under some circumstances, you may require more flexibility than standard udev rules can provide. In this case, you can ask udev to run a program and use the standard output from that program to provide device naming. +

    + +

    +To use this functionality, you simply specify the absolute path of the program to run (and any parameters) in the PROGRAM assignment, and you then use some variant of the %c substitution in the NAME/SYMLINK assignments. +

    + +

    +The following examples refer to a fictional program found at /bin/device_namer. device_namer takes one command line argument which is the kernel name for the device. Based upon this kernel name, device_namer does its magic and produces some output to the usual stdout pipe, split into several parts. Each part is just a single word, and parts are separated by a single space. +

    + +

    +In our first example, we assume that device_namer outputs a number of parts, each one to form a symbolic link (alternative name) for the device in question. +

    + +
    KERNEL=="hda", PROGRAM="/bin/device_namer %k", SYMLINK+="%c"
    + +

    +The next example assumes that device_namer outputs two parts, the first being the device name, and the second being the name for an additional symbolic link. We now introduce the %c{N} substitution, which refers to part N of the output: +

    + +
    KERNEL=="hda", PROGRAM="/bin/device_namer %k", NAME="%c{1}", SYMLINK+="%c{2}"
    + +

    +The next example assumes that device_namer outputs one part for the device name, followed by any number of parts which will form additional symbolic links. We now introduce the %c{N+} substitution, which evaluates to part N, N+1, N+2, ... until the end of the output. +

    + +
    KERNEL=="hda", PROGRAM="/bin/device_namer %k", NAME="%c{1}", SYMLINK+="%c{2+}"
    + +

    +Output parts can be used in any assignment key, not only NAME and SYMLINK. The example below uses a fictional program to determine the Unix group which should own the device: +

    + +
    KERNEL=="hda", PROGRAM="/bin/who_owns_device %k", GROUP="%c"
    + + +

    Running external programs upon certain events

    + +

    +Yet another reason for writing udev rules is to run a particular program when a device is connected or disconnected. For example, you might want to execute a script to automatically download all of your photos from your digital camera when it is connected. +

    + +

    +Do not confuse this with the PROGRAM functionality described above. PROGRAM is used for running programs which produce device names (and they shouldn't do anything other than that). When those programs are being executed, the device node has not yet been created, so acting upon the device in any way is not possible. +

    + +

    +The functionality introduced here allows you to run a program after the device node is put in place. This program can act on the device, however it must not run for any extended period of time, because udev is effectively paused while these programs are running. One workaround for this limitation is to make sure your program immediately detaches itself. +

    + +

    +Here is an example rule which demonstrates the use of the RUN list assignment: +

    + +
    KERNEL=="sdb", RUN+="/usr/bin/my_program"
    + +

    +When /usr/bin/my_program is executed, various parts of the udev environment are available as environment variables, including key values such as SUBSYSTEM. You can also use the ACTION environment variable to detect whether the device is being connected or disconnected - ACTION will be either "add" or "remove" respectively. +

    + + +

    Environment interaction

    + +

    +udev provides an ENV key for environment variables which can be used for both matching and assignment. +

    + +

    +In the assignment case, you can set environment variables which you can then match against later. You can also set environment variables which can be used by any external programs invoked using the techniques mentioned above. A fictional example rule which sets an environment variable is shown below. +

    + +
    KERNEL=="fd0", SYMLINK+="floppy", ENV{some_var}="value"
    + +

    +In the matching case, you can ensure that rules only run depending on the value of an environment variable. Note that the environment that udev sees will not be the same user environment as you get on the console. A fictional rule involving an environment match is shown below. +

    + +
    KERNEL=="fd0", ENV{an_env_var}=="yes", SYMLINK+="floppy"
    + +

    +The above rule only creates the /dev/floppy link if $an_env_var is set to "yes" in udev's environment. +

    + + +

    Additional options

    + +

    +Another assignment which can prove useful is the OPTIONS list. A few options are available: +

    + +
      +
    • all_partitions - create all possible partitions for a block device, rather than only those that were initially detected
    • +
    • ignore_device - ignore the event completely
    • +
    • last_rule - ensure that no later rules have any effect
    • +
    + +

    +For example, the rule below sets the group ownership on my hard disk node, and ensures that no later rule can have any effect: +

    + +
    KERNEL=="sda", GROUP="disk", OPTIONS+="last_rule"
    + + +

    Examples

    + + +

    USB Printer

    + +

    +I power on my printer, and it is assigned device node /dev/lp0. Not satisfied with such a bland name, I decide to use udevinfo to aid me in writing a rule which will provide an alternative name: +

    + +
    +# udevinfo -a -p $(udevinfo -q path -n /dev/lp0)
    +looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3':
    +BUS=="usb"
    +SYSFS{manufacturer}=="EPSON"
    +SYSFS{product}=="USB Printer"
    +SYSFS{serial}=="L72010011070626380"
    +
    + +

    +My rule becomes: +

    + +
    BUS=="usb", SYSFS{serial}=="L72010011070626380", SYMLINK+="epson_680"
    + + +

    USB Camera

    + +

    +Like most, my camera identifies itself as an external hard disk connected over the USB bus, using the SCSI transport. To access my photos, I mount the drive and copy the image files onto my hard disk. +

    + +

    +Not all cameras work in this way: some of them use a non-storage protocol such as cameras supported by gphoto2. In the gphoto case, you do not want to be writing rules for your device, as is it controlled purely through userspace (rather than a specific kernel driver). +

    + +

    +A common complication with USB camera devices is that they usually identify themselves as a disk with a single partition, in this case /dev/sdb with /dev/sdb1. The sdb node is useless to me, but sdb1 is interesting - this is the one I want to mount. There is a problem here that because sysfs is chained, the useful attributes which udevinfo produces for /dev/sdb1 are identical to the ones for /dev/sdb. This results in your rule potentially matching both the raw disk and the partition, which is not what you want, your rule should be specific. +

    + +

    +To get around this, you simply need to think about what differs between sdb and sdb1. It is surprisingly simple: the name itself differs, so we can use a simple pattern match on the NAME field. +

    + +
    +# udevinfo -a -p $(udevinfo -q path -n /dev/sdb1)
    +  looking at device '/devices/pci0000:00/0000:00:02.0/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0':
    +    ID=="6:0:0:0"
    +    BUS=="scsi"
    +    DRIVER=="sd"
    +    SYSFS{rev}=="1.00"
    +    SYSFS{model}=="X250,D560Z,C350Z"
    +    SYSFS{vendor}=="OLYMPUS "
    +    SYSFS{scsi_level}=="3"
    +    SYSFS{type}=="0"
    +
    + +

    +My rule: +

    + +
    KERNEL=="sd?1", BUS=="scsi", SYSFS{model}=="X250,D560Z,C350Z", SYMLINK+="camera"
    + + +

    USB Hard Disk

    + +

    +A USB hard disk is comparable to the USB camera I described above, however typical usage patterns are different. In the camera example, I explained that I am not interested in the sdb node - it's only real use is for partitioning (e.g. with fdisk), but why would I want to partition my camera!? +

    + +

    +Of course, if you have a 100GB USB hard disk, it is perfectly understandable that you might want to partition it, in which case we can take advantage of udev's string substitutions: +

    + +
    BUS=="usb", KERNEL=="sd*", SYSFS{product}=="USB 2.0 Storage Device", NAME="%k", SYMLINK+="usbhd%n"
    + +

    +This rule creates symlinks such as: +

    + +
      +
    • /dev/usbhd - The fdiskable node
    • +
    • /dev/usbhd1 - The first partition (mountable)
    • +
    • /dev/usbhd2 - The second partition (mountable)
    • +
    + + +

    USB Card Reader

    + +

    +USB card readers (CompactFlash, SmartMedia, etc) are yet another range of USB storage devices which have different usage requirements. +

    + +

    +These devices typically do not inform the host computer upon media change. So, if you plug in the device with no media, and then insert a card, the computer does not realise, and you do not have your mountable sdb1 partition node for the media. +

    + +

    +One possible solution is to take advantage of the all_partitions option, which will create 16 partition nodes for every block device that the rule matches: +

    + +
    BUS=="usb", SYSFS{product}=="USB 2.0 CompactFlash Reader", SYMLINK+="cfrdr%n", OPTIONS+="all_partitions"
    + +You will now have nodes named: cfrdr, cfrdr1, cfrdr2, cfrdr3, ..., cfrdr15. + + +

    USB Palm Pilot

    + +

    +These devices work as USB-serial devices, so by default, you only get the ttyUSB1 device node. The palm utilities rely on /dev/pilot, so many users will want to use a rule to provide this. +

    + +

    +Carsten Clasohm's blog post appears to be the definitive source for this. Carsten's rule is shown below: +

    + +
    BUS=="usb", SYSFS{product}=="Palm Handheld", KERNEL=="ttyUSB*", SYMLINK+="pilot"
    + +

    +Note that the product string seems to vary from product to product, so make sure that you check (using udevinfo) which one applies to you. +

    + + +

    CD/DVD drives

    + +

    +I have two optical drives in this computer: a DVD reader (hdc), and a DVD rewriter (hdd). I do not expect these device nodes to change, unless I physically rewire my system. However, many users like to have device nodes such as /dev/dvd for convenience. +

    + +

    +As we know the KERNEL names for these devices, rule writing is simple. Here are some examples for my system: +

    + +
    +BUS=="ide", KERNEL=="hdc", SYMLINK+="dvd", GROUP="cdrom"
    +BUS=="ide", KERNEL=="hdd", SYMLINK+="dvdrw", GROUP="cdrom"
    +
    + + +

    Network interfaces

    + +

    +Even though they are referenced by names, network interfaces typically do not have device nodes associated with them. Despite that, the rule writing process is almost identical. +

    + +

    +It makes sense to simply match the MAC address of your interface in the rule, as this is unique. However, make sure that you use the exact MAC address as shown as udevinfo, because if you do not match the case exactly, your rule will not work. +

    + +
    +# udevinfo -a -p /sys/class/net/eth0
    +  looking at class device '/sys/class/net/eth0':
    +    SYSFS{address}=="00:52:8b:d5:04:48"
    +
    + +

    +Here is my rule: +

    + +
    KERNEL=="eth*", SYSFS{address}=="00:52:8b:d5:04:48", NAME="lan"
    + +

    +You will need to reload the net driver for this rule to take effect. You can either unload and reload the module, or simply reboot the system. You will also need to reconfigure your system to use "lan" rather than "eth0". I had some troubles getting this going (the interface wasn't being renamed) until I had completely dropped all references to eth0. +After that, you should be able to use "lan" instead of "eth0" in any calls to ifconfig or similar utilities. +

    + +

    Testing and debugging

    + + +

    Putting your rules into action

    + +

    +Assuming you are on a recent kernel with inotify support, udev will automatically monitor your rules directory and automatically pick up any modifications you make to the rule files. +

    + +

    +Despite this, udev will not automatically reprocess all devices and attempt to apply the new rule(s). For example, if you write a rule to add an extra symbolic link for your camera while your camera is plugged in, you cannot expect the extra symbolic link to show up right away. +

    + +

    +To make the symbolic link show up, you can either disconnect and reconnect your camera, or alternatively in the case of non-removable devices, you can run udevtrigger. +

    + +

    +If your kernel does not have inotify support, new rules will not be detected automatically. In this situation, you must run udevcontrol reload_rules after making any rule file modifications for those modifications to take effect. +

    + + +

    udevtest

    + +

    +If you know the top-level device path in sysfs, you can use udevtest to show the actions which udev would take. This may help you debug your rules. For example, assuming you want to debug a rule which acts on /sys/class/sound/dsp: +

    + +
    +# udevtest /class/sound/dsp
    +main: looking at device '/class/sound/dsp' from subsystem 'sound'
    +udev_rules_get_name: add symlink 'dsp'
    +udev_rules_get_name: rule applied, 'dsp' becomes 'sound/dsp'
    +udev_device_event: device '/class/sound/dsp' already known, remove possible symlinks
    +udev_node_add: creating device node '/dev/sound/dsp', major = '14', minor = '3', mode = '0660', uid = '0', gid = '18'
    +udev_node_add: creating symlink '/dev/dsp' to 'sound/dsp'
    +
    + +

    +Note the /sys prefix was removed from the udevtest command line argument, this is because udevtest operates on device paths. Also note that udevtest is purely a testing/debugging tool, it does not create any device nodes, despite what the output suggests! +

    + + +

    Author and contact

    + +

    +This document is written by Daniel Drake <dan@reactivated.net>. Feedback is appreciated. +

    + +

    +For support, you should mail the linux-hotplug mailing list: linux-hotplug-devel@lists.sourceforge.net. +

    + +

    +Copyright (C) 2003-2006 Daniel Drake.
    +This document is licensed under the GNU General Public License, Version 2. +

    + + + + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/compat.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/compat.rules new file mode 100644 index 0000000..209e3ce --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/compat.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/devfs.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/devfs.rules new file mode 100644 index 0000000..2e0caa1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/devfs.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/hotplug.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/hotplug.rules new file mode 100644 index 0000000..0b2fc57 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/hotplug.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/hotplugd.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/hotplugd.rules new file mode 100644 index 0000000..cd30fa4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/hotplugd.rules @@ -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}" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/permissions.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/permissions.rules new file mode 100644 index 0000000..ac6c0be --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/permissions.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/persistent-input.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/persistent-input.rules new file mode 100644 index 0000000..a9005e0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/persistent-input.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/persistent.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/persistent.rules new file mode 100644 index 0000000..c82a639 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/persistent.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/run.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/run.rules new file mode 100644 index 0000000..75d7137 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/run.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/udev.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/udev.rules new file mode 100644 index 0000000..3f7b704 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/debian/udev.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/frugalware/50-udev-default.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/frugalware/50-udev-default.rules new file mode 100644 index 0000000..2f47773 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/frugalware/50-udev-default.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/frugalware/64-device-mapper.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/frugalware/64-device-mapper.rules new file mode 100644 index 0000000..3837d3f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/frugalware/64-device-mapper.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/05-udev-early.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/05-udev-early.rules new file mode 100644 index 0000000..ee349dc --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/05-udev-early.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/50-udev.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/50-udev.rules new file mode 100644 index 0000000..dd32971 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/50-udev.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/80-hotplug.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/80-hotplug.rules new file mode 100644 index 0000000..0637dbc --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/80-hotplug.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/95-udev-late.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/95-udev-late.rules new file mode 100644 index 0000000..40ada28 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/gentoo/95-udev-late.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/06-udev-rh-early.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/06-udev-rh-early.rules new file mode 100644 index 0000000..7268a5f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/06-udev-rh-early.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/50-udev.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/50-udev.rules new file mode 100644 index 0000000..668785f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/50-udev.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/95-pam-console.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/95-pam-console.rules new file mode 100644 index 0000000..cbb2d4a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/redhat/95-pam-console.rules @@ -0,0 +1 @@ +ENV{STARTUP}!="1", ACTION=="add", SYSFS{dev}=="?*", KERNEL=="?*", RUN+="/sbin/pam_console_apply $env{DEVNAME} $env{DEVLINKS}" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/05-udev-early.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/05-udev-early.rules new file mode 100644 index 0000000..4c3055b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/05-udev-early.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/60-persistent-input.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/60-persistent-input.rules new file mode 100644 index 0000000..fbebe86 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/60-persistent-input.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/60-persistent-storage.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/60-persistent-storage.rules new file mode 100644 index 0000000..a49321c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/60-persistent-storage.rules @@ -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 + +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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/95-udev-late.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/95-udev-late.rules new file mode 100644 index 0000000..1755d08 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/rules.d/95-udev-late.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/slackware/udev.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/slackware/udev.rules new file mode 100644 index 0000000..12dac4d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/slackware/udev.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/50-udev-default.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/50-udev-default.rules new file mode 100644 index 0000000..4a3fe2c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/50-udev-default.rules @@ -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" + diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/64-device-mapper.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/64-device-mapper.rules new file mode 100644 index 0000000..c6142ea --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/64-device-mapper.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/64-md-raid.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/64-md-raid.rules new file mode 100644 index 0000000..02f27ee --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/64-md-raid.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/80-drivers.rules b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/80-drivers.rules new file mode 100644 index 0000000..e7ae8dc --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/suse/80-drivers.rules @@ -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" diff --git a/21cnbao/code/05/udev源代码/udev-114/etc/udev/udev.conf b/21cnbao/code/05/udev源代码/udev-114/etc/udev/udev.conf new file mode 100644 index 0000000..41902c4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/etc/udev/udev.conf @@ -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=". +udev_log="err" + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/Makefile new file mode 100644 index 0000000..c9691da --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/Makefile @@ -0,0 +1,70 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2005 Kay Sievers +# +# 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 + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/ata_id.8 b/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/ata_id.8 new file mode 100644 index 0000000..32cb371 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/ata_id.8 @@ -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 . + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/ata_id.c b/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/ata_id.c new file mode 100644 index 0000000..f94cdc0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/ata_id/ata_id.c @@ -0,0 +1,195 @@ +/* + * ata_id - reads product/serial number from ATA drives + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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] \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; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/60-cdrom_id.rules b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/60-cdrom_id.rules new file mode 100644 index 0000000..b06dafd --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/60-cdrom_id.rules @@ -0,0 +1,3 @@ +# import optical drive properties + +KERNEL=="sr[0-9]*|hd[a-z]|pcd[0-9]*", IMPORT{program}="cdrom_id --export $tempnode" diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/Makefile new file mode 100644 index 0000000..7cd7c1d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/Makefile @@ -0,0 +1,71 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2005 Kay Sievers +# +# 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 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/cdrom_id.8 b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/cdrom_id.8 new file mode 100644 index 0000000..4194ae4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/cdrom_id.8 @@ -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 . + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/cdrom_id.c b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/cdrom_id.c new file mode 100644 index 0000000..0d4a8c1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/cdrom_id/cdrom_id.c @@ -0,0 +1,152 @@ +/* + * cdrom_id - determines the capabilities of cdrom drives + * + * Copyright (C) 2005 Greg Kroah-Hartman + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/collect/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/collect/Makefile new file mode 100644 index 0000000..6168a8b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/collect/Makefile @@ -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 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/collect/collect.c b/21cnbao/code/05/udev源代码/udev-114/extras/collect/collect.c new file mode 100644 index 0000000..0a852f2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/collect/collect.c @@ -0,0 +1,429 @@ +/* + * Collect variables across events. + * + * usage: collect [--add|--remove] + * + * Adds ID to the list governed by . + * must be part of the ID list . + * If all IDs given by are listed (ie collect has been + * invoked for each ID in ) collect returns 0, the + * number of missing IDs otherwise. + * A negative number is returned on error. + * + * Copyright(C) 2007, Hannes Reinecke + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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] \n" + "\n" + " Adds ID to the list governed by .\n" + " must be part of the list .\n" + " If all IDs given by are listed (ie collect has been\n" + " invoked for each ID in ) 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; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/Makefile new file mode 100644 index 0000000..71cc3da --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/Makefile @@ -0,0 +1,70 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2005 Kay Sievers +# +# 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 + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/edd_id.8 b/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/edd_id.8 new file mode 100644 index 0000000..86576bb --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/edd_id.8 @@ -0,0 +1,27 @@ +.TH EDD_ID 8 "November 2005" "" "Linux Administrator's Manual" +.SH NAME +edd_id \- udev callout to identify BIOS disk drives via EDD +.SH SYNOPSIS +.BI edd_id +[\fI--export\fP] \fIblockdevice\fP +.SH "DESCRIPTION" +.B edd_id +is normally called from a udev rule, to provide udev with the edd id for +a BIOS disk 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 edd_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 edd_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 John Hull and Kay Sievers . + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/edd_id.c b/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/edd_id.c new file mode 100644 index 0000000..4ba89ed --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/edd_id/edd_id.c @@ -0,0 +1,197 @@ +/* + * edd_id - naming of BIOS disk devices via EDD + * + * Copyright (C) 2005 John Hull + * Copyright (C) 2005 Kay Sievers + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + +int main(int argc, char *argv[]) +{ + const char *node = NULL; + int i; + int export = 0; + uint32_t disk_id; + uint16_t mbr_valid; + struct dirent *dent; + int disk_fd; + int sysfs_fd; + DIR *dir = NULL; + int rc = 1; + char match[NAME_MAX] = ""; + + logging_init("edd_id"); + + for (i = 1 ; i < argc; i++) { + char *arg = argv[i]; + + if (strcmp(arg, "--export") == 0) { + export = 1; + } else + node = arg; + } + if (node == NULL) { + err("no node specified"); + fprintf(stderr, "no node specified\n"); + goto exit; + } + + /* check for kernel support */ + dir = opendir("/sys/firmware/edd"); + if (dir == NULL) { + info("no kernel EDD support"); + fprintf(stderr, "no kernel EDD support\n"); + rc = 2; + goto exit; + } + + disk_fd = open(node, O_RDONLY); + if (disk_fd < 0) { + info("unable to open '%s'", node); + fprintf(stderr, "unable to open '%s'\n", node); + rc = 3; + goto closedir; + } + + /* check for valid MBR signature */ + if (lseek(disk_fd, 510, SEEK_SET) < 0) { + info("seek to MBR validity failed '%s'", node); + rc = 4; + goto close; + } + if (read(disk_fd, &mbr_valid, sizeof(mbr_valid)) != sizeof(mbr_valid)) { + info("read MBR validity failed '%s'", node); + rc = 5; + goto close; + } + if (mbr_valid != 0xAA55) { + fprintf(stderr, "no valid MBR signature '%s'\n", node); + info("no valid MBR signature '%s'", node); + rc=6; + goto close; + } + + /* read EDD signature */ + if (lseek(disk_fd, 440, SEEK_SET) < 0) { + info("seek to signature failed '%s'", node); + rc = 7; + goto close; + } + if (read(disk_fd, &disk_id, sizeof(disk_id)) != sizeof(disk_id)) { + info("read signature failed '%s'", node); + rc = 8; + goto close; + } + /* all zero is invalid */ + info("read id 0x%08x from '%s'", disk_id, node); + if (disk_id == 0) { + fprintf(stderr, "no EDD signature '%s'\n", node); + info("'%s' signature is zero", node); + rc = 9; + goto close; + } + + /* lookup signature in sysfs to determine the name */ + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char file[PATH_SIZE]; + char sysfs_id_buf[256]; + uint32_t sysfs_id; + ssize_t size; + + if (dent->d_name[0] == '.') + continue; + + snprintf(file, sizeof(file), "/sys/firmware/edd/%s/mbr_signature", dent->d_name); + file[sizeof(file)-1] = '\0'; + + sysfs_fd = open(file, O_RDONLY); + if (sysfs_fd < 0) { + info("unable to open sysfs '%s'", file); + continue; + } + + size = read(sysfs_fd, sysfs_id_buf, sizeof(sysfs_id_buf)-1); + close(sysfs_fd); + if (size <= 0) { + info("read sysfs '%s' failed", file); + continue; + } + sysfs_id_buf[size] = '\0'; + info("read '%s' from '%s'", sysfs_id_buf, file); + sysfs_id = strtoul(sysfs_id_buf, NULL, 16); + + /* look for matching value, that appears only once */ + if (disk_id == sysfs_id) { + if (match[0] == '\0') { + /* store id */ + strlcpy(match, dent->d_name, sizeof(match)); + } else { + /* error, same signature for another device */ + info("'%s' does not have a unique signature", node); + fprintf(stderr, "'%s' does not have a unique signature\n", node); + rc = 10; + goto exit; + } + } + } + + if (match[0] != '\0') { + if (export) + printf("ID_EDD=%s\n", match); + else + printf("%s\n", match); + rc = 0; + } + +close: + close(disk_fd); +closedir: + closedir(dir); +exit: + logging_close(); + return rc; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/firmware/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/firmware/Makefile new file mode 100644 index 0000000..c187b47 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/firmware/Makefile @@ -0,0 +1,58 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2006 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +PROG = firmware.sh +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 + +# man pages +%.8: %.xml + $(E) " XMLTO " $@ + $(Q) xmlto man $? +.PRECIOUS: %.8 + +clean: + $(E) " CLEAN " +.PHONY: clean + +install-bin: all + $(INSTALL_SCRIPT) -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 + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/firmware/firmware.sh b/21cnbao/code/05/udev源代码/udev-114/extras/firmware/firmware.sh new file mode 100755 index 0000000..89b985e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/firmware/firmware.sh @@ -0,0 +1,27 @@ +#!/bin/sh -e + +FIRMWARE_DIRS="/lib/firmware /usr/local/lib/firmware" + +err() { + echo "$@" >&2 + if [ -x /bin/logger ]; then + /bin/logger -t "${0##*/}[$$]" "$@" + fi +} + +if [ ! -e /sys$DEVPATH/loading ]; then + err "udev firmware loader misses sysfs directory" + exit 1 +fi + +for DIR in $FIRMWARE_DIRS; do + [ -e "$DIR/$FIRMWARE" ] || continue + echo 1 > /sys$DEVPATH/loading + cat "$DIR/$FIRMWARE" > /sys$DEVPATH/data + echo 0 > /sys$DEVPATH/loading + exit 0 +done + +echo -1 > /sys$DEVPATH/loading +err "Cannot find firmware file '$FIRMWARE'" +exit 1 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/floppy/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/floppy/Makefile new file mode 100644 index 0000000..784464a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/floppy/Makefile @@ -0,0 +1,69 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2005 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +PROG = create_floppy_devices +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 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/floppy/create_floppy_devices.8 b/21cnbao/code/05/udev源代码/udev-114/extras/floppy/create_floppy_devices.8 new file mode 100644 index 0000000..8f5f048 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/floppy/create_floppy_devices.8 @@ -0,0 +1,35 @@ +.TH CREATE_FLOPPY_DEVICES 8 "May 2007" "" "Linux Administrator's Manual" +.SH NAME +create_floppy_devices \- udev callout to create all possible floppy device +based on the CMOS type. +.SH SYNOPSIS +create_floppy_devices [options] device +.SH OPTIONS +.TP +\fB\-c\fR +Create nodes. +.TP +\fB\-u\fR +Unlink nodes. +.TP +\fB\-d\fR +Print nodes. +.TP +\fB\-m\fR +Set major number. +.TP +\fB\-U\fR +Set user ownership. +.TP +\fB\-G\fR +Set group ownership. +.TP +\fB\-M\fR +Set device node mode. +.TP +\fB\-t\fR +Sed floppy type number. +.SH SEE ALSO +.BR udev (7) +.SH AUTHORS +Developed by Hannes Reinecke . diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/floppy/create_floppy_devices.c b/21cnbao/code/05/udev源代码/udev-114/extras/floppy/create_floppy_devices.c new file mode 100644 index 0000000..b9fa4ef --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/floppy/create_floppy_devices.c @@ -0,0 +1,174 @@ +/* + * create_floppy_devices + * + * Create all possible floppy device based on the CMOS type. + * Based upon code from drivers/block/floppy.c + * + * Copyright(C) 2005, SUSE Linux Products GmbH + * + * Author: + * Hannes Reinecke + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev.h" +#include "../../udev_selinux.h" + +static char *table[] = { + "", "d360", "h1200", "u360", "u720", "h360", "h720", + "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410", + "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743", + "h880", "u1040", "u1120", "h1600", "u1760", "u1920", + "u3200", "u3520", "u3840", "u1840", "u800", "u1600", + NULL +}; + +static int t360[] = { 1, 0 }; +static int t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23, 0 }; +static int t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, 17, 21, 22, 30, 0 }; +static int *table_sup[] = { NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in }; + +#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) +{ + char *dev; + char node[64]; + int type = 0, i, fdnum, c; + int major = 2, minor; + uid_t uid = 0; + gid_t gid = 0; + mode_t mode = 0660; + int create_nodes = 0; + int print_nodes = 0; + int is_err = 0; + + while ((c = getopt(argc, argv, "cudm:U:G:M:t:")) != -1) { + switch (c) { + case 'c': + create_nodes = 1; + break; + case 'd': + print_nodes = 1; + break; + case 'U': + uid = lookup_user(optarg); + break; + case 'G': + gid = lookup_group(optarg); + break; + case 'M': + mode = strtol(optarg, NULL, 0); + mode = mode & 0666; + break; + case 'm': + major = strtol(optarg, NULL, 0); + break; + case 't': + type = strtol(optarg, NULL, 0); + break; + default: + is_err++; + break; + } + } + + if (is_err || optind >= argc) { + printf("Usage: %s [OPTION] device\n" + " -c create\n" + " -d debug\n" + " -m Major number\n" + " -t floppy type number\n" + " -U device node user ownership\n" + " -G device node group owner\n" + " -M device node mode\n" + "\n", argv[0]); + return 1; + } + + dev = argv[optind]; + if (dev[strlen(dev) - 3] != 'f' || dev[strlen(dev) -2 ] != 'd') { + fprintf(stderr,"Device '%s' is not a floppy device\n", dev); + return 1; + } + + fdnum = strtol(dev + 2, NULL, 10); + if (fdnum < 0 || fdnum > 7) { + fprintf(stderr,"Floppy device number %d out of range (0-7)\n", fdnum); + return 1; + } + if (fdnum > 3) + fdnum += 128; + + if (major < 1) { + fprintf(stderr,"Invalid major number %d\n", major); + return 1; + } + + if (type < 0 || type > (int) sizeof(table)) { + fprintf(stderr,"Invalid CMOS type %d\n", type); + return 1; + } + + if (type == 0) + return 0; + + udev_config_init(); + selinux_init(); + + i = 0; + while (table_sup[type][i]) { + sprintf(node, "%s%s", dev, table[table_sup[type][i]]); + minor = (table_sup[type][i] << 2) + fdnum; + if (print_nodes) + printf("%s b %d %d %d\n", node, mode, major, minor); + if (create_nodes) { + unlink(node); + selinux_setfscreatecon(node, NULL, S_IFBLK | mode); + mknod(node, S_IFBLK | mode, makedev(major,minor)); + selinux_resetfscreatecon(); + chown(node, uid, gid); + chmod(node, S_IFBLK | mode); + } + i++; + } + + selinux_exit(); + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/path_id/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/path_id/Makefile new file mode 100644 index 0000000..d8efe64 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/path_id/Makefile @@ -0,0 +1,58 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2006 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +PROG = path_id +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 + +# man pages +%.8: %.xml + $(E) " XMLTO " $@ + $(Q) xmlto man $? +.PRECIOUS: %.8 + +clean: + $(E) " CLEAN " +.PHONY: clean + +install-bin: all + $(INSTALL_SCRIPT) -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 + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/path_id/path_id b/21cnbao/code/05/udev源代码/udev-114/extras/path_id/path_id new file mode 100755 index 0000000..57879b5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/path_id/path_id @@ -0,0 +1,574 @@ +#!/bin/sh + +# provide the shortest possible unique hardware path to a device +# for the Linux Persistent Device Naming scheme +# +# Copyright (C) 2005-2006 SUSE Linux Products GmbH +# Author: +# Hannes Reinecke +# +# 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. + +SYSFS=/sys +RESULT=1 +TYPE= +OPWD="`pwd`" +full_sysfs_path= +full_sysfs_device_path= + +if [ -z "$DEVPATH" -a -z "$1" ] ; then + exit 1 +fi + +if [ -z "$DEVPATH" ] ; then + case "$1" in + $SYSFS/*) + DEVPATH="${1#$SYSFS}" + ;; + *) + DEVPATH=$1 + ;; + esac +fi + +if [ ! -e $SYSFS$DEVPATH/dev ] ; then + exit 1 +fi + +case "$DEVPATH" in + /devices/*) + cd "$SYSFS$DEVPATH/subsystem"; + TYPE="`pwd -P`" + cd "$OPWD" + TYPE="${TYPE##*/}" + ;; + /class/*) + TYPE="${DEVPATH#/class/}" + TYPE="${TYPE%%/*}" + ;; + /block/*) + TYPE=block + ;; + *) + exit 1 + ;; +esac + +get_port_offset () { + local type offset port + type=$1 + offset=$2 + for i in $type[0-9]* ; do + : i $i + port="${i#$type}" + if [ "$port" -lt "$offset" ] ; then offset=$port ; fi + done + echo $offset +} + +handle_pci () { + local DEV=$1 + cd -P $1 + DEV=${PWD} + pci_id=${DEV##*/} + host_dev_path=$DEV + + # cciss devices don't have a separate sysfs node + for blk_link in block*; do + if [ -L "$blk_link" ]; then + case "$blk_link" in + *cciss*) + d=cciss-${blk_link#*cciss\!} + ;; + esac + fi + done + while [ ! -z "$host_dev_path" ] ; do + case "$host_dev_path" in + */pci[0-9]*) + host_dev_path=${host_dev_path%/*} + ;; + *) + break + ;; + esac + done + d="pci-$pci_id-$d" + D="$host_dev_path" + RESULT=0 +} + +handle_platform () { + local DEV=$1 + cd -P $1 + DEV=${PWD} + platform_id=${DEV##*/} + host_dev_path=$DEV + while [ ! -z "$host_dev_path" ] ; do + case "$host_dev_path" in + */platform*) + host_dev_path=${host_dev_path%/*} + ;; + *) + break + ;; + esac + done + if [ "$d" ]; then + d="platform-$platform_id-$d" + else + d="platform-$platform_id" + fi + D="$host_dev_path" + RESULT=0 +} + +handle_serio () { + local DEV=$1 + cd -P $1 + DEV=${PWD} + serio_id=${DEV##*/serio} + host_dev_path=$DEV + while [ ! -z "$host_dev_path" ] ; do + case "$host_dev_path" in + */serio*) + host_dev_path=${host_dev_path%/*} + ;; + *) + break + ;; + esac + done + if [ "$d" ]; then + d="serio-$serio_id-$d" + else + d="serio-$serio_id" + fi + D="$host_dev_path" + RESULT=0 +} + +handle_ide () { + : handle_ide $* + local DEV=$1 + local port idedev idecontroller + # IDE + : DEV $DEV + port=${DEV##*/} + idedev=${DEV%/*} + idecontroller=${idedev%/*} + # port info if the controller has more than one interface + port="${port#ide}" + : port $port d $d + : idedev $idedev kernel_port $port + case "${port#*.}" in + 0) + channel=0 + ;; + 1) + channel=1 + ;; + *) + echo "Error: $idedev is neither master or slave" >&2 + ;; + esac + cd $idecontroller + offset="`get_port_offset ide ${port%.*}`" + cd "$OPWD" + : port offset $offset + port=$((${port%.*} - $offset)) + if [ "$d" ] ; then + d="ide-${port}:$channel-$d" + else + d="ide-${port}:$channel" + fi + D=$idecontroller + RESULT=0 +} + +handle_scsi () { + : handle_scsi $* + local DEV=$1 + local cil controller_port controller_dev + # SCSI device + cil="${DEV##*/}" + cil="${cil#*:}" + target_dev=${DEV%/*} + target_id=${target_dev##*/target} + cd "$target_dev" + target_num=0 + for tid in ${target_id}* ; do + target_num=$(( $target_num + 1 )) + done + controller_port=${target_dev%/*} + controller_dev="${controller_port%/*}" + : controller_dev $controller_dev + : controller_port $controller_port + # a host controller may have more than one interface/port + controller_port="${controller_port##*/host}" + # + cd "$controller_dev" + controller_offset=$(get_port_offset host $controller_port) + cd "$OPWD" + controller_port=$(( $controller_port - $controller_offset)) + scsi_id="scsi-${controller_port}:${cil}" + if [ "$d" ] ; then + d="${scsi_id}-$d" + else + d="$scsi_id" + fi + D="$controller_dev" + RESULT=0 +} + +handle_firewire () { + : handle_firewire $* + local DEV=$1 + if [ -f "$D/ieee1394_id" ] ; then + read ieee1394_id < $D/ieee1394_id + fi + if [ -z "$ieee1394_id" ] ; then + : no IEEE1394 ID + RESULT=1 + return + fi + fw_host_dev=${DEV%/fw-host*} + # IEEE1394 devices are always endpoints + d="ieee1394-0x$ieee1394_id" + D="$fw_host_dev" + RESULT=0 +} + +handle_fc () { + : handle_fc $* + local DEV=$1 + local cil controller_port controller_dev + # SCSI-FC device + fc_tgt_hcil="${DEV##*/}" + fc_tgt_lun="${fc_tgt_hcil##*:}" + fc_tgt_path="${DEV%/*}" + fc_tgt_num="${fc_tgt_path##*/}" + fc_tgt_dev="${fc_tgt_path}/fc_transport:${fc_tgt_num}" + if [ -e "$fc_tgt_dev/port_name" ]; then + read wwpn < $fc_tgt_dev/port_name + fi + if [ -z "$wwpn" ] ; then + : no WWPN + D= + RESULT=1 + return + fi + # Linux currently knows about 32bit luns + tmp_lun3=$(printf "%04x" $(($fc_tgt_lun & 0xFFFF))) + tmp_lun2=$(printf "%04x" $(( ($fc_tgt_lun >> 16) & 0xFFFF))) + tmp_lun1="0000" + tmp_lun0="0000" + if (($fc_tgt_lun == 0)) ; then + lun="0x0000000000000000" + else + lun="0x${tmp_lun3}${tmp_lun2}${tmp_lun1}${tmp_lun0}" + fi + controller_dev="${fc_tgt_path%/host[0-9]*}" + # FC devices are always endpoints + d="fc-${wwpn}:${lun}" + D="$controller_dev" + RESULT=0 +} + +handle_sas () { + : handle_sas $* + local DEV=$1 + local cil adapter controller_dev + # SAS device + sas_host_path="${DEV%%/port*}" + sas_phy_path="${DEV#*/host*/}" + sas_phy_path="${sas_phy_path%%/target*}" + sas_phy_id="${sas_phy_path%%/*}" + sas_phy_id="${sas_phy_id##*port-}" + sas_port_id="${sas_phy_path%%/end_device*}" + sas_port_id="${sas_port_id##*port-}" + sas_end_id="${sas_phy_path##*end_device-}" + sas_phy_dev="/sys/class/sas_phy/phy-${sas_phy_id}" + if [ -e "$sas_phy_dev/sas_address" ]; then + read phy_address < $sas_phy_dev/sas_address + read phy_id < $sas_phy_dev/phy_identifier + fi + if [ -z "$phy_address" ] ; then + : no initiator address + D= + RESULT=1 + return + fi + sas_port_dev="/sys/class/sas_port/port-${sas_port_id}" + if [ -e "$sas_port_dev/num_phys" ] ; then + read phy_port < $sas_port_dev/num_phys + fi + if [ -z "$phy_port" ] ; then + : no initiator address + D= + RESULT=1 + return + fi + sas_phy_address="$phy_address:$phy_port:$phy_id" + sas_end_dev="/sys/class/sas_device/end_device-${sas_end_id}" + if [ -e "$sas_end_dev/sas_address" ]; then + read end_address < $sas_end_dev/sas_address + read end_id < $sas_end_dev/phy_identifier + fi + if [ -z "$end_address" ] ; then + : no initiator address + D= + RESULT=1 + return + fi + sas_end_address="$end_address:$end_id" + controller_dev="${sas_host_path%/host[0-9]*}" + # SAS devices are always endpoints + d="sas-${sas_phy_address}-${sas_end_address}" + D="$controller_dev" + RESULT=0 +} + +handle_iscsi() { + local DEV=$1 + local iscsi_session_dir + local iscsi_session iscsi_session_path + local iscsi_connection iscsi_connection_path + local iscsi_scsi_lun + # iSCSI device + iscsi_session_dir="${DEV%%/target*}" + iscsi_session="${iscsi_session_dir##*/}" + iscsi_session_path=/sys/class/iscsi_session/${iscsi_session} + if [ ! -d "$iscsi_session_path" ] ; then + : no iSCSI session path + RESULT=1 + return + fi + # Currently we're not doing MC/S + for conn in ${iscsi_session_dir}/connection* ; do + iscsi_conn_num=${conn##*:} + if [ "$iscsi_conn_num" = '0' ] ; then + iscsi_connection=$(basename $conn) + fi + done + if [ -z "$iscsi_connection" ] ; then + : no iSCSI connection found + RESULT=1 + return + fi + iscsi_connection_path=/sys/class/iscsi_connection/${iscsi_connection} + if [ ! -d "$iscsi_connection_path" ] ; then + : no iSCSI connection path + RESULT=1 + return + fi + if [ -e "${iscsi_session_path}/targetname" ]; then + read iscsi_tgtname < ${iscsi_session_path}/targetname + fi + if [ -z "$iscsi_tgtname" ] ; then + : No iSCSI Targetname + RESULT=1 + return + fi + if [ -e "${iscsi_connection_path}/persistent_address" ] ; then + read iscsi_address < ${iscsi_connection_path}/persistent_address + fi + if [ -z "$iscsi_address" ] ; then + : No iSCSI Target address + RESULT=1 + return + fi + if [ -e "${iscsi_connection_path}/persistent_port" ] ; then + read iscsi_port < ${iscsi_connection_path}/persistent_port + fi + iscsi_scsi_lun="${DEV##*:}" + d="ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${iscsi_scsi_lun}" + RESULT=0 +} + +handle_usb () { +: handle_usb $* + local DEV=$1 + cd -P $1 + DEV=${PWD} + port_id=${DEV##*/} + port_num=${port_id#*-} + host_dev_path=$DEV + while [ ! -z "$host_dev_path" ] ; do + case "$host_dev_path" in + */usb*) + usb_host_path=$host_dev_path + host_dev_path="${host_dev_path%/*}" + ;; + *) + break + ;; + esac + done + : host_dev_path $host_dev_path + usb_host_num=${usb_host_path##*/usb} + + cd "$host_dev_path" + usb_host_offset=$(get_port_offset usb $usb_host_num) + usb_host_port=$(($usb_host_num - $usb_host_offset)) + cd "$OPWD" + if [ "$d" ] ; then + d="usb-$usb_host_port:$port_num-${d}" + else + d="usb-$usb_host_port:$port_num" + fi + D="$host_dev_path" + RESULT=0 +} + +handle_device () { + full_sysfs_path="$SYSFS$DEVPATH" + case "$DEVPATH" in + /devices/*) + full_sysfs_path="${full_sysfs_path%/*}" + # skip parent device of the same subsystem + if [ -L $full_sysfs_path/subsystem ]; then + cd "$full_sysfs_path/subsystem"; + subsys="`pwd -P`" + cd "$OPWD" + subsys="${subsys##*/}" + if [ "$subsys" = "$TYPE" ]; then + : skip same subsystem parent + full_sysfs_path="${full_sysfs_path%/*}" + fi + fi + # skip subsystem directory + subsys="${full_sysfs_path##*/}" + if [ "$subsys" = "$TYPE" ]; then + : skip subsystem directory + full_sysfs_path="${full_sysfs_path%/*}" + fi + cd $full_sysfs_path + ;; + *) + # old sysfs layout + if [ ! -L $full_sysfs_path/device ]; then + full_sysfs_path="${full_sysfs_path%/*}" + : full_sysfs_path "$full_sysfs_path" + if [ ! -L $full_sysfs_path/device -o ! -f $full_sysfs_path/dev ]; then + return + fi + fi + cd $full_sysfs_path/device + ;; + esac + full_sysfs_device_path="`pwd -P`" + cd "$OPWD" + + D=$full_sysfs_device_path + while [ ! -z "$D" ] ; do + case "$D" in + */ide[0-9]/[0-9].[0-9]*|*/ide[0-9][0-9]/[0-9][0-9].[0-9]*) + handle_ide "$D" + ;; + */css0/*) + if [ -r $full_sysfs_device_path/wwpn ]; then + read wwpn < $full_sysfs_device_path/wwpn + fi + if [ -r $full_sysfs_device_path/fcp_lun ]; then + read lun < $full_sysfs_device_path/fcp_lun + fi + if [ -r $full_sysfs_device_path/hba_id ]; then + read bus_id < $full_sysfs_device_path/hba_id + fi + if [ "$bus_id" -a "$wwpn" -a "$lun" ]; then + # S/390 zfcp adapter + d="ccw-$bus_id-zfcp-$wwpn:$lun" + RESULT=0 + else + # DASD devices + bus="ccw" + adapter=${D##*/} + d="$bus-$adapter" + RESULT=0 + fi + D= + ;; + */rport-[0-9]*:[0-9]*-[0-9]*/*) + handle_fc "$D" + ;; + */end_device-[0-9]*:[0-9]*:[0-9]*/*) + handle_sas "$D" + ;; + */fw-host[0-9]*/*) + handle_firewire "$D" + ;; + */session[0-9]*/*) + handle_iscsi "$D" + D= + ;; + */host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*) + handle_scsi "$D" + ;; + */usb[0-9]*/[0-9]*/*) + handle_usb "$D" + ;; + */pci[0-9]*:[0-9]*) + handle_pci "$D" + ;; + */serio[0-9]*) + handle_serio "$D" + ;; + */platform/*) + handle_platform "$D" + ;; + */devices) + D= + ;; + *) + : not handled + RESULT=1 + return + ;; + esac + done + if [ "$TYPE" = "scsi_tape" ] ; then + devname=${full_sysfs_path##*/} + rewind="${devname%%st*}" + mode="${devname##*st}" + case "$mode" in + *l) + mode="l" + ;; + *m) + mode="m" + ;; + *a) + mode="a" + ;; + *) + mode="" + ;; + esac + if [ "$d" ]; then + d="$d-${rewind}st${mode}" + fi + fi +} + +case "$TYPE" in + block) + handle_device + echo "ID_PATH=$d" + ;; + scsi_tape) + handle_device + echo "ID_PATH=$d" + ;; + input) + handle_device + echo "ID_PATH=$d" + ;; + *) + RESULT=1 + ;; +esac + +exit $RESULT diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/path_id/path_id.8 b/21cnbao/code/05/udev源代码/udev-114/extras/path_id/path_id.8 new file mode 100644 index 0000000..9dc5965 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/path_id/path_id.8 @@ -0,0 +1,15 @@ +.TH PATH_ID 8 "April 2007" "" "Linux Administrator's Manual" +.SH NAME +path_id \- udev callout to create a device path based unique name +for a device to implement the Linux Persistent Device Naming scheme +.SH SYNOPSIS +path_id +.SH "DESCRIPTION" +.B path_id +is normally called from a udev rule, to create a unique name, based on +the device properties along the chain of parent devices. Udev uses this +information to create a persistent symlink to the real device node. +.SH SEE ALSO +.BR udev (7) +.SH AUTHORS +Developed by Hannes Reinecke . diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/75-cd-aliases-generator.rules b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/75-cd-aliases-generator.rules new file mode 100644 index 0000000..c3eb887 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/75-cd-aliases-generator.rules @@ -0,0 +1,3 @@ +# these rules generate rules for the /dev/{cdrom,dvd,...} symlinks + +ACTION=="add", SUBSYSTEM=="block", ENV{ID_CDROM}=="?*", ENV{GENERATED}!="?*", PROGRAM="write_cd_rules", SYMLINK+="%c" diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/75-persistent-net-generator.rules b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/75-persistent-net-generator.rules new file mode 100644 index 0000000..cfb13f1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/75-persistent-net-generator.rules @@ -0,0 +1,34 @@ +# do not edit this file, it will be overwritten on update + +# these rules generate rules for persistent network device naming + +ACTION!="add", GOTO="persistent_net_generator_end" +SUBSYSTEM!="net", GOTO="persistent_net_generator_end" + +# device name whitelist +KERNEL!="eth*|ath*|wlan*|ra*|sta*|ctc*|lcs*|hsi*", GOTO="persistent_net_generator_end" + +# ignore the interface if a name has already been set +NAME=="?*", GOTO="persistent_net_generator_end" + +# ignore Xen virtual interfaces +SUBSYSTEMS=="xen", GOTO="persistent_net_generator_end" + +# build device description string to add a comment to the generated rule +SUBSYSTEMS=="pci", ENV{COMMENT}="PCI device $attr{vendor}:$attr{device} ($driver)" +SUBSYSTEMS=="usb", ENV{COMMENT}="USB device 0x$attr{idVendor}:0x$attr{idProduct} ($driver)" +SUBSYSTEMS=="pcmcia", ENV{COMMENT}="PCMCIA device $attr{card_id}:$attr{manf_id} ($driver)" +SUBSYSTEMS=="ccwgroup", ENV{COMMENT}="S/390 $driver device at $id", ENV{NETDEV}="$id", ENV{NETDRV}="$driver" +SUBSYSTEMS=="ieee1394", ENV{COMMENT}="Firewire device $attr{host_id})" +ENV{COMMENT}=="", ENV{COMMENT}="$env{SUBSYSTEM} device ($driver)" + +DRIVERS!="?*", ENV{NETDEV}=="?*", IMPORT{program}="write_net_rules --driver $env{NETDRV} --id $env{NETDEV}" + +# skip "locally administered" MAC addresses +ATTR{address}=="?[2367abef]:*", GOTO="persistent_net_generator_end" + +DRIVERS!="?*", ENV{NETDEV}!="?*", IMPORT{program}="write_net_rules $attr{address}" +ENV{INTERFACE_NEW}=="?*", NAME="$env{INTERFACE_NEW}" + +LABEL="persistent_net_generator_end" + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/Makefile new file mode 100644 index 0000000..cc6fe05 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/Makefile @@ -0,0 +1,68 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2006 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +PROG = +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 + +# man pages +%.8: %.xml + $(E) " XMLTO " $@ + $(Q) xmlto man $? +.PRECIOUS: %.8 + +clean: + $(E) " CLEAN " +.PHONY: clean + +install-bin: all + $(INSTALL_DATA) -D rule_generator.functions $(DESTDIR)$(libudevdir)/rule_generator.functions + $(INSTALL_SCRIPT) -D write_cd_rules $(DESTDIR)$(libudevdir)/write_cd_rules + $(INSTALL_SCRIPT) -D write_net_rules $(DESTDIR)$(libudevdir)/write_net_rules + $(INSTALL_DATA) -D 75-cd-aliases-generator.rules \ + $(DESTDIR)$(configdir)/rules.d/75-cd-aliases-generator.rules + $(INSTALL_DATA) -D 75-persistent-net-generator.rules \ + $(DESTDIR)$(configdir)/rules.d/75-persistent-net-generator.rules +.PHONY: install-bin + +uninstall-bin: + - rm $(DESTDIR)$(libudevdir)/rule_generator.functions + - rm $(DESTDIR)$(libudevdir)/write_cd_rules + - rm $(DESTDIR)$(libudevdir)/write_net_rules + - rm $(DESTDIR)$(configdir)/rules.d/75-cd-aliases-generator.rules + - rm $(DESTDIR)$(configdir)/rules.d/75-persistent-net-generator.rules +.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 + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/rule_generator.functions b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/rule_generator.functions new file mode 100644 index 0000000..495bb7b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/rule_generator.functions @@ -0,0 +1,97 @@ +# functions used by the udev rule generator +# +# 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. + +PATH='/sbin:/bin' + +# Read a single line from file $1 in the $DEVPATH directory. +# The function must not return an error even if the file does not exist. +sysread() { + local file="$1" + [ -e "/sys$DEVPATH/$file" ] || return 0 + local value + read value < "/sys$DEVPATH/$file" || return 0 + echo "$value" +} + +sysreadlink() { + local file="$1" + [ -e "/sys$DEVPATH/$file" ] || return 0 + readlink -f /sys$DEVPATH/$file 2> /dev/null || true +} + +# Return true if a directory is writeable. +writeable() { + if ln -s test-link $1/.is-writeable 2> /dev/null; then + rm -f $1/.is-writeable + return 0 + else + return 1 + fi +} + +# Create a lock file for the current rules file. +lock_rules_file() { + [ -e /dev/.udev/ ] || return 0 + + RULES_LOCK="/dev/.udev/.lock-${RULES_FILE##*/}" + + retry=30 + while ! mkdir $RULES_LOCK 2> /dev/null; do + if [ $retry -eq 0 ]; then + echo "Cannot lock $RULES_FILE!" >&2 + exit 2 + fi + sleep 1 + retry=$(($retry - 1)) + done +} + +unlock_rules_file() { + [ "$RULES_LOCK" ] || return 0 + rmdir $RULES_LOCK || true +} + +# Choose the real rules file if it is writeable or a temporary file if not. +# Both files should be checked later when looking for existing rules. +choose_rules_file() { + local tmp_rules_file="/dev/.udev/tmp-rules--${RULES_FILE##*/}" + [ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1 + + if writeable ${RULES_FILE%/*}; then + RO_RULES_FILE='/dev/null' + else + RO_RULES_FILE=$RULES_FILE + RULES_FILE=$tmp_rules_file + fi +} + +# Return the name of the first free device. +raw_find_next_available() { + local links="$1" + + local basename=${links%%[ 0-9]*} + local max=-1 + for name in $links; do + local num=${name#$basename} + [ "$num" ] || num=0 + [ $num -gt $max ] && max=$num + done + + local max=$(($max + 1)) + # "name0" actually is just "name" + [ $max -eq 0 ] && return + echo "$max" +} + +# Find all rules matching a key (with action) and a pattern. +find_all_rules() { + local key="$1" + local linkre="$2" + local match="$3" + + local search='.*[[:space:],]'"$key"'"\('"$linkre"'\)"[[:space:]]*\(,.*\|\\\|\)$' + echo $(sed -n -e "${match}s/${search}/\1/p" $RO_RULES_FILE $RULES_FILE 2>/dev/null) +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/write_cd_rules b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/write_cd_rules new file mode 100644 index 0000000..bd951c5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/write_cd_rules @@ -0,0 +1,118 @@ +#!/bin/sh -e + +# This script is run if an optical drive lacks a rule for persistent naming. +# +# It adds symlinks for optical drives based on the device class determined +# by cdrom_id and used ID_PATH to identify the device. +# +# (C) 2006 Marco d'Itri +# +# 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. + +RULES_FILE="/etc/udev/rules.d/70-persistent-cd.rules" + +. /lib/udev/rule_generator.functions + +find_next_available() { + raw_find_next_available "$(find_all_rules 'SYMLINK+=' $1)" +} + +write_rule() { + local match="$1" + local link="$2" + local comment="$3" + + { + if [ "$PRINT_HEADER" ]; then + PRINT_HEADER= + echo "# This file was automatically generated by the $0" + echo "# program, probably run by the cd-aliases-generator.rules rules file." + echo "#" + echo "# You can modify it, as long as you keep each rule on a single line" + echo "# and set the \$GENERATED variable." + echo "" + fi + + [ "$comment" ] && echo "# $comment" + echo "$match, SYMLINK+=\"$link\", ENV{GENERATED}=\"1\"" + } >> $RULES_FILE + SYMLINKS="$SYMLINKS $link" +} + +if [ -z "$DEVPATH" ]; then + echo "Missing \$DEVPATH." >&2 + exit 1 +fi +if [ -z "$ID_CDROM" ]; then + echo "$DEVPATH is not a CD reader." >&2 + exit 1 +fi + +if [ "$1" ]; then + METHOD="$1" +else + case "$ID_BUS" in + usb|ieee1394) + METHOD='by-id' + ;; + + *) + METHOD='by-path' + ;; + esac +fi + +case "$METHOD" in + by-path) + if [ -z "$ID_PATH" ]; then + echo "$DEVPATH not supported by path_id. by-id may work." >&2 + exit 1 + fi + RULE="ENV{ID_PATH}==\"$ID_PATH\"" + ;; + + by-id) + if [ "$ID_SERIAL" ]; then + RULE="ENV{ID_SERIAL}==\"$ID_SERIAL\"" + elif [ "$ID_MODEL" -a "$ID_REVISION" ]; then + RULE="ENV{ID_MODEL}==\"$ID_MODEL\", ENV{ID_REVISION}==\"$ID_REVISION\"" + else + echo "$DEVPATH not supported by ata_id. by-path may work." >&2 + exit 1 + fi + ;; + + *) + echo "Invalid argument (must be either by-path or by-id)." >&2 + exit 1 + ;; +esac + +# Prevent concurrent processes from modifying the file at the same time. +lock_rules_file + +# Check if the rules file is writeable. +choose_rules_file + +link_num=$(find_next_available 'cdrom[0-9]*') + +match="ENV{ID_CDROM}==\"?*\", $RULE" + +comment="$ID_MODEL ($ID_PATH)" + + write_rule "$match" "cdrom$link_num" "$comment" +[ "$ID_CDROM_CD_R" -o "$ID_CDROM_CD_RW" ] && \ + write_rule "$match" "cdrw$link_num" +[ "$ID_CDROM_DVD" ] && \ + write_rule "$match" "dvd$link_num" +[ "$ID_CDROM_DVD_R" -o "$ID_CDROM_DVD_RW" -o "$ID_CDROM_DVD_RAM" ] && \ + write_rule "$match" "dvdrw$link_num" + +unlock_rules_file + +echo $SYMLINKS + +exit 0 + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/write_net_rules b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/write_net_rules new file mode 100644 index 0000000..62acb88 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/rule_generator/write_net_rules @@ -0,0 +1,131 @@ +#!/bin/sh -e +# +# This script is run if the interface (recognized by its MAC address) lacks +# a rule for persistent naming. +# +# If there is already a persistent rule with that interface name then the +# current interface needs to be renamed. +# +# If the interface needs to be renamed, a NAME=value pair will be printed +# on stdout to allow udev to IMPORT it. Then a rule for the MAC address and +# interface name is written. +# +# (C) 2006 Marco d'Itri +# +# 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. + +RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules' + +. /lib/udev/rule_generator.functions + +interface_name_taken() { + local value="$(find_all_rules 'NAME=' $INTERFACE)" + if [ "$value" ]; then + return 0 + else + return 1 + fi +} + +find_next_available() { + raw_find_next_available "$(find_all_rules 'NAME=' "$1")" +} + +write_rule() { + local match="$1" + local name="$2" + local comment="$3" + + { + if [ "$PRINT_HEADER" ]; then + PRINT_HEADER= + echo "# This file was automatically generated by the $0" + echo "# program run by the persistent-net-generator.rules rules file." + echo "#" + echo "# You can modify it, as long as you keep each rule on a single line." + fi + + echo "" + [ "$comment" ] && echo "# $comment" + echo "SUBSYSTEM==\"net\", $match, NAME=\"$name\"" + } >> $RULES_FILE +} + +if [ -z "$INTERFACE" ]; then + echo "Missing \$INTERFACE." >&2 + exit 1 +fi + +if [ "$1" ]; then + while [ "$*" ] ; do + case $1 in + --mac) + shift + MAC_ADDR=$1 + shift + ;; + --driver) + shift + DRIVER=$1 + shift + ;; + --id) + shift + ID=$1 + shift + ;; + *) + MAC_ADDR=$1 + shift + ;; + esac + done +else + MAC_ADDR=$(sysread address) +fi + +if [ -z "$DRIVER" ] && [ -z "$ID" ] ; then + if [ -z "$MAC_ADDR" ]; then + echo "No MAC address for $INTERFACE." >&2 + exit 1 + fi + if [ "$MAC_ADDR" = "00:00:00:00:00:00" ]; then + echo "NULL MAC address for $INTERFACE." >&2 + exit 1 + fi +fi + +# Prevent concurrent processes from modifying the file at the same time. +lock_rules_file + +# Check if the rules file is writeable. +choose_rules_file + +# If a rule using the current name already exists then find a new name and +# report it to udev which will rename the interface. +basename=${INTERFACE%%[0-9]*} +if interface_name_taken; then + INTERFACE="$basename$(find_next_available "$basename[0-9]*")" + if [ ! -t 1 ]; then + echo "INTERFACE_NEW=$INTERFACE" + fi +fi + +# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces +if [ "$MAC_ADDR" ] ; then + match="DRIVERS==\"?*\", ATTR{address}==\"$MAC_ADDR\"" +else + match="DRIVERS==\"$DRIVER\", KERNELS==\"$ID\"" +fi +if [ $basename = "ath" -o $basename = "wlan" ]; then + match="$match, ATTR{type}==\"1\"" # do not match the wifi* interfaces +fi + +write_rule "$match" "$INTERFACE" "$COMMENT" + +unlock_rules_file + +exit 0 + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/Makefile new file mode 100644 index 0000000..349eeef --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/Makefile @@ -0,0 +1,87 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2003 IBM +# Copyright (C) 2004-2005 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +SCSI_ID_VERSION = 0.9 + +PROG = scsi_id +OBJS= scsi_serial.o +HEADERS = scsi_id.h scsi.h scsi_id_version.h +GEN_HEADERS = scsi_id_version.h +MAN_PAGES = scsi_id.8 + +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) + +scsi_id_version.h: + $(E) " GENHDR " $@ + $(Q) echo "/* Generated by make. */" > $@ + $(Q) echo \#define SCSI_ID_VERSION \"$(SCSI_ID_VERSION)\" >> $@ + $(Q) echo \#define SCSI_ID_CONFIG_FILE \"$(etcdir)/scsi_id.config\" >> $@ + +# 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 scsi_id.8 $(DESTDIR)$(mandir)/man8/scsi_id.8 +.PHONY: install-man + +uninstall-man: + -rm -f $(DESTDIR)$(mandir)/man8/scsi_id.8 +.PHONY: uninstall-man + +install-config: + @ if [ ! -r $(DESTDIR)$(etcdir)/scsi_id.config ]; then \ + echo $(INSTALL_DATA) -D ./scsi_id.config $(DESTDIR)$(etcdir); \ + $(INSTALL_DATA) -D ./scsi_id.config $(DESTDIR)$(etcdir)/scsi_id.config; \ + fi +.PHONY: install-config + +install: all install-bin install-config install-man +.PHONY: install + +uninstall: uninstall-bin uninstall-man +.PHONY: uninstall diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/README b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/README new file mode 100644 index 0000000..9cfe739 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/README @@ -0,0 +1,4 @@ +scsi_id - generate a SCSI unique identifier for a given SCSI device + +Please send questions, comments or patches to or +. diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi.h b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi.h new file mode 100644 index 0000000..f5aa686 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi.h @@ -0,0 +1,92 @@ +/* + * scsi.h + * + * General scsi and linux scsi specific defines and structs. + * + * Copyright (C) IBM Corp. 2003 + * + * 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. + */ + +#include + +struct scsi_ioctl_command { + unsigned int inlen; /* excluding scsi command length */ + unsigned int outlen; + unsigned char data[1]; + /* on input, scsi command starts here then opt. data */ +}; + +/* + * Default 5 second timeout + */ +#define DEF_TIMEOUT 5000 + +#define SENSE_BUFF_LEN 32 + +/* + * The request buffer size passed to the SCSI INQUIRY commands, use 254, + * as this is a nice value for some devices, especially some of the usb + * mass storage devices. + */ +#define SCSI_INQ_BUFF_LEN 254 + +/* + * SCSI INQUIRY vendor and model (really product) lengths. + */ +#define VENDOR_LENGTH 8 +#define MODEL_LENGTH 16 + +#define INQUIRY_CMD 0x12 +#define INQUIRY_CMDLEN 6 + +/* + * INQUIRY VPD page 0x83 identifier descriptor related values. Reference the + * SCSI Primary Commands specification for details. + */ + +/* + * id type values of id descriptors. These are assumed to fit in 4 bits. + */ +#define SCSI_ID_VENDOR_SPECIFIC 0 +#define SCSI_ID_T10_VENDOR 1 +#define SCSI_ID_EUI_64 2 +#define SCSI_ID_NAA 3 + +/* + * Supported NAA values. These fit in 4 bits, so the "don't care" value + * cannot conflict with real values. + */ +#define SCSI_ID_NAA_DONT_CARE 0xff +#define SCSI_ID_NAA_IEEE_REG 5 +#define SCSI_ID_NAA_IEEE_REG_EXTENDED 6 + +/* + * Supported Code Set values. + */ +#define SCSI_ID_BINARY 1 +#define SCSI_ID_ASCII 2 + +struct scsi_id_search_values { + u_char id_type; + u_char naa_type; + u_char code_set; +}; + +/* + * Following are the "true" SCSI status codes. Linux has traditionally + * used a 1 bit right and masked version of these. So now CHECK_CONDITION + * and friends (in ) are deprecated. + */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_CONDITION_MET 0x4 +#define SCSI_BUSY 0x8 +#define SCSI_IMMEDIATE 0x10 +#define SCSI_IMMEDIATE_CONDITION_MET 0x14 +#define SCSI_RESERVATION_CONFLICT 0x18 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SCSI_TASK_SET_FULL 0x28 +#define SCSI_ACA_ACTIVE 0x30 +#define SCSI_TASK_ABORTED 0x40 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.8 b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.8 new file mode 100644 index 0000000..927549b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.8 @@ -0,0 +1,142 @@ +.TH SCSI_ID 8 "December 2003" "" "Linux Administrator's Manual" +.SH NAME +scsi_id \- retrieve and generate a unique SCSI identifier +.SH SYNOPSIS +.BI scsi_id +[\fIoptions\fP] +.SH "DESCRIPTION" +.B scsi_id +queries a SCSI device via the SCSI INQUIRY vital product data (VPD) page 0x80 or +0x83 and uses the resulting data to generate a value that is unique across +all SCSI devices that properly support page 0x80 or page 0x83. + +If a result is generated it is sent to standard output, and the program +exits with a zero value. If no identifier is output, the program exits +with a non\-zero value. + +\fBscsi_id\fP is primarily for use by other utilities such as \fBudev\fP +that require a unique SCSI identifier. + +By default all devices are assume black listed, the \fB\-\-whitelisted\fP option must +be specified on the command line or in the config file for any useful +behaviour. + +SCSI commands are sent directly to the device via the SG_IO ioctl +interface. + +In order to generate unique values for either page 0x80 or page 0x83, the +serial numbers or world wide names are prefixed as follows. + +Identifiers based on page 0x80 are prefixed by the character 'S', the SCSI +vendor, the SCSI product (model) and then the the serial number returned +by page 0x80. For example: + +.sp +.nf +# scsi_id --page=0x80 --devpath=/block/sdg +SIBM 3542 1T05078453 +.fi +.P + +Identifiers based on page 0x83 are prefixed by the identifier type +followed by the page 0x83 identifier. For example, a device with a NAA +(Name Address Authority) type of 3 (also in this case the page 0x83 +identifier starts with the NAA value of 6): + +.sp +.nf +# /sbin/scsi_id --page=0x83 --devpath=/block/sdg +3600a0b80000b174b000000d63efc5c8c +.fi +.P + +.SH OPTIONS +.TP +.BI \-\-fallback-to-sysfs +Always print information (model, vendor strings) about the device even +if it does not support VPD pages. +.TP +.BI \-\-ignore-sysfs +Ignore sysfs entries. Used for devices which are not represented as SCSI +devices, but understand SG_IO commands. +.TP +.BI \-\-blacklisted +The default behaviour \- treat the device as black listed, and do nothing +unless a white listed device is found in the scsi_id config\-file. +.TP +.BI \-\-device=\| device\^ +Instead +of determining and creating a device node based on a sysfs dev +entry as done for the \fB\-s\fP, send SG_IO commands to +\fBdevice\fP, such as \fB/dev/sdc\fP. +This argument should also be used when invoked via udev to avoid problems +with creation of temporary files on not-yet writable directories. +.TP +.BI \-\-config=\| config\-file +Read configuration and black/white list entries from +.B config\-file +rather than the default +.B /etc/scsi_id.config +file. +.TP +.BI \-\-whitelisted +Treat the device as white listed. The \fB\-\-whitelisted\fP option must be specified +on the command line or in the scsi_id configuration file for +.B scsi_id +to generate any output. +.TP +.BI \-\-prefix-bus-id +Prefix the identification string with the driver model (sysfs) bus id of +the SCSI device. +.TP +.BI \-\-page=\| 0x80 | 0x83 | pre-spc3-83 +Use SCSI INQUIRY VPD page code 0x80, 0x83, or pre-spc3-83. +.sp +The default +behaviour is to query the available VPD pages, and use page 0x83 if found, +else page 0x80 if found, else nothing. +.sp +Page pre-spc3-83 should only be utilized for those scsi devices which +are not compliant with the SPC-2 or SPC-3 format for page 83. While this +option is used for older model 4, 5, and 6 EMC Symmetrix devices, its +use with SPC-2 or SPC-3 compliant devices will fallback to the page 83 +format supported by these devices. +.TP +.BI \-\-devpath=\| sysfs\-devpath +Generate an id for the +.B sysfs\-devpath. +The sysfs mount point must not be included. +.TP +.BI \-\-replace-whitespace +Reformat the output : replace all whitespaces by underscores. +.TP +.BI \-\-export +Export all data in KEY= format used to import in other programs. +.TP +.BI \-\-verbose +Generate verbose debugging output. +.TP +.BI \-\-version +Display version number and exit. +.RE + +.SH ENVIRONMENT + +If the DEVPATH environment variable is set, scsi_id assumes it has been +invoked via udev (or some other hotplug program), and all errors or +warnings are sent using syslog. +.P + +.SH "FILES" +.nf +.ft B +.ft +/etc/scsi_id.config configuration and black/white list entries +.fi +.LP +.SH "SEE ALSO" +.BR udev (7) +.SH AUTHORS +Developed by Patrick Mansfield based on SCSI ID +source included in earlier linux 2.5 kernels, sg_utils source, and SCSI +specifications. diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.c b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.c new file mode 100644 index 0000000..d8b269a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.c @@ -0,0 +1,831 @@ +/* + * scsi_id.c + * + * Main section of the scsi_id program + * + * Copyright (C) IBM Corp. 2003 + * Copyright (C) SUSE Linux Products GmbH, 2006 + * + * Author: + * Patrick Mansfield + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev.h" +#include "scsi_id.h" +#include "scsi_id_version.h" + +/* temporary names for mknod */ +#define TMP_DIR "/dev" +#define TMP_PREFIX "tmp-scsi" + +static const struct option options[] = { + { "device", 1, NULL, 'd' }, + { "config", 1, NULL, 'f' }, + { "page", 1, NULL, 'p' }, + { "devpath", 1, NULL, 's' }, + { "fallback-to-sysfs", 0, NULL, 'a' }, + { "blacklisted", 0, NULL, 'b' }, + { "whitelisted", 0, NULL, 'g' }, + { "prefix-bus-id", 0, NULL, 'i' }, + { "replace-whitespace", 0, NULL, 'u' }, + { "ignore-sysfs", 0, NULL, 'n' }, + { "verbose", 0, NULL, 'v' }, + { "version", 0, NULL, 'V' }, + { "export", 0, NULL, 'x' }, + { "help", 0, NULL, 'h' }, + {} +}; + +static const char short_options[] = "abd:f:ghinp:s:uvVx"; +static const char dev_short_options[] = "bgp:"; + +static int all_good; +static int always_info; +static int dev_specified; +static int sys_specified; +static char config_file[MAX_PATH_LEN] = SCSI_ID_CONFIG_FILE; +static int display_bus_id; +static enum page_code default_page_code; +static int use_stderr; +static int debug; +static int hotplug_mode; +static int reformat_serial; +static int ignore_sysfs; +static int export; +static char vendor_str[64]; +static char model_str[64]; +static char revision_str[16]; +static char type_str[16]; + +#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'; +} + +static void set_type(char *to, const char *from, size_t len) +{ + int type_num; + char *eptr; + char *type = "generic"; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + type = "disk"; + break; + case 1: + type = "tape"; + break; + case 4: + type = "optical"; + break; + case 5: + type = "cd"; + break; + case 7: + type = "optical"; + break; + case 0xe: + type = "disk"; + break; + case 0xf: + type = "optical"; + break; + default: + break; + } + } + strncpy(to, type, len); + to[len-1] = '\0'; +} + +static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) +{ + unsigned int maj, min; + const char *attr; + + dbg("%s", devpath); + attr = sysfs_attr_get_value(devpath, "dev"); + if (attr == NULL) { + dbg("%s: could not get dev attribute: %s", devpath, strerror(errno)); + return -1; + } + + dbg("dev value %s", attr); + if (sscanf(attr, "%u:%u", &maj, &min) != 2) { + err("%s: invalid dev major/minor", devpath); + return -1; + } + + snprintf(tmpdev, MAX_PATH_LEN, "%s/%s-maj%d-min%d-%u", + TMP_DIR, TMP_PREFIX, maj, min, getpid()); + + dbg("tmpdev '%s'", tmpdev); + if (mknod(tmpdev, 0600 | dev_type, makedev(maj, min))) { + err("mknod failed: %s", strerror(errno)); + return -1; + } + return 0; +} + +/* + * get_value: + * + * buf points to an '=' followed by a quoted string ("foo") or a string ending + * with a space or ','. + * + * Return a pointer to the NUL terminated string, returns NULL if no + * matches. + */ +static char *get_value(char **buffer) +{ + static char *quote_string = "\"\n"; + static char *comma_string = ",\n"; + char *val; + char *end; + + if (**buffer == '"') { + /* + * skip leading quote, terminate when quote seen + */ + (*buffer)++; + end = quote_string; + } else { + end = comma_string; + } + val = strsep(buffer, end); + if (val && end == quote_string) + /* + * skip trailing quote + */ + (*buffer)++; + + while (isspace(**buffer)) + (*buffer)++; + + return val; +} + +static int argc_count(char *opts) +{ + int i = 0; + while (*opts != '\0') + if (*opts++ == ' ') + i++; + return i; +} + +/* + * get_file_options: + * + * If vendor == NULL, find a line in the config file with only "OPTIONS="; + * if vendor and model are set find the first OPTIONS line in the config + * file that matches. Set argc and argv to match the OPTIONS string. + * + * vendor and model can end in '\n'. + */ +static int get_file_options(const char *vendor, const char *model, + int *argc, char ***newargv) +{ + char *buffer; + FILE *fd; + char *buf; + char *str1; + char *vendor_in, *model_in, *options_in; /* read in from file */ + int lineno; + int c; + int retval = 0; + + dbg("vendor='%s'; model='%s'\n", vendor, model); + fd = fopen(config_file, "r"); + if (fd == NULL) { + dbg("can't open %s\n", config_file); + if (errno == ENOENT) { + return 1; + } else { + err("can't open %s: %s", config_file, strerror(errno)); + return -1; + } + } + + /* + * Allocate a buffer rather than put it on the stack so we can + * keep it around to parse any options (any allocated newargv + * points into this buffer for its strings). + */ + buffer = malloc(MAX_BUFFER_LEN); + if (!buffer) { + err("Can't allocate memory."); + return -1; + } + + *newargv = NULL; + lineno = 0; + while (1) { + vendor_in = model_in = options_in = NULL; + + buf = fgets(buffer, MAX_BUFFER_LEN, fd); + if (buf == NULL) + break; + lineno++; + if (buf[strlen(buffer) - 1] != '\n') { + info("Config file line %d too long.\n", lineno); + break; + } + + while (isspace(*buf)) + buf++; + + /* blank or all whitespace line */ + if (*buf == '\0') + continue; + + /* comment line */ + if (*buf == '#') + continue; + + dbg("lineno %d: '%s'\n", lineno, buf); + str1 = strsep(&buf, "="); + if (str1 && strcasecmp(str1, "VENDOR") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = -1; + break; + } + vendor_in = str1; + + str1 = strsep(&buf, "="); + if (str1 && strcasecmp(str1, "MODEL") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = -1; + break; + } + model_in = str1; + str1 = strsep(&buf, "="); + } + } + + if (str1 && strcasecmp(str1, "OPTIONS") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = -1; + break; + } + options_in = str1; + } + dbg("config file line %d:" + " vendor '%s'; model '%s'; options '%s'\n", + lineno, vendor_in, model_in, options_in); + /* + * Only allow: [vendor=foo[,model=bar]]options=stuff + */ + if (!options_in || (!vendor_in && model_in)) { + info("Error parsing config file line %d '%s'", lineno, buffer); + retval = -1; + break; + } + if (vendor == NULL) { + if (vendor_in == NULL) { + dbg("matched global option\n"); + break; + } + } else if ((vendor_in && strncmp(vendor, vendor_in, + strlen(vendor_in)) == 0) && + (!model_in || (strncmp(model, model_in, + strlen(model_in)) == 0))) { + /* + * Matched vendor and optionally model. + * + * Note: a short vendor_in or model_in can + * give a partial match (that is FOO + * matches FOOBAR). + */ + dbg("matched vendor/model\n"); + break; + } else { + dbg("no match\n"); + } + } + + if (retval == 0) { + if (vendor_in != NULL || model_in != NULL || + options_in != NULL) { + /* + * Something matched. Allocate newargv, and store + * values found in options_in. + */ + strcpy(buffer, options_in); + c = argc_count(buffer) + 2; + *newargv = calloc(c, sizeof(**newargv)); + if (!*newargv) { + err("Can't allocate memory."); + retval = -1; + } else { + *argc = c; + c = 0; + /* + * argv[0] at 0 is skipped by getopt, but + * store the buffer address there for + * later freeing + */ + (*newargv)[c] = buffer; + for (c = 1; c < *argc; c++) + (*newargv)[c] = strsep(&buffer, " \t"); + } + } else { + /* No matches */ + retval = 1; + } + } + if (retval != 0) + free(buffer); + fclose(fd); + return retval; +} + +static int set_options(int argc, char **argv, const char *short_opts, + char *target, char *maj_min_dev) +{ + int option; + + /* + * optind is a global extern used by getopt. Since we can call + * set_options twice (once for command line, and once for config + * file) we have to reset this back to 1. + */ + optind = 1; + while (1) { + option = getopt_long(argc, argv, short_opts, options, NULL); + if (option == -1) + break; + + if (optarg) + dbg("option '%c' arg '%s'\n", option, optarg); + else + dbg("option '%c'\n", option); + + switch (option) { + case 'a': + always_info = 1; + break; + case 'b': + all_good = 0; + break; + + case 'd': + dev_specified = 1; + strncpy(maj_min_dev, optarg, MAX_PATH_LEN); + maj_min_dev[MAX_PATH_LEN-1] = '\0'; + break; + + case 'e': + use_stderr = 1; + break; + + case 'f': + strncpy(config_file, optarg, MAX_PATH_LEN); + config_file[MAX_PATH_LEN-1] = '\0'; + break; + + case 'g': + all_good = 1; + break; + + case 'h': + printf("Usage: scsi_id OPTIONS \n" + " --device device node for SG_IO commands\n" + " --devpath sysfs devpath\n" + " --config location of config file\n" + " --page SCSI page (0x80, 0x83, pre-spc3-83)\n" + " --fallback-to-sysfs print sysfs values if inquiry fails\n" + " --ignore-sysfs ignore sysfs entries\n" + " --blacklisted threat device as blacklisted\n" + " --whitelisted threat device as whitelisted\n" + " --prefix-bus-id prefix SCSI bus id\n" + " --replace-whitespace replace all whitespaces by underscores\n" + " --verbose verbose logging\n" + " --version print version\n" + " --export print values as environment keys\n" + " --help print this help text\n\n"); + exit(0); + + case 'i': + display_bus_id = 1; + break; + + case 'p': + if (strcmp(optarg, "0x80") == 0) { + default_page_code = PAGE_80; + } else if (strcmp(optarg, "0x83") == 0) { + default_page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + default_page_code = PAGE_83_PRE_SPC3; + } else { + info("Unknown page code '%s'", optarg); + return -1; + } + break; + + case 'n': + ignore_sysfs = 1; + break; + + case 's': + sys_specified = 1; + strncpy(target, optarg, MAX_PATH_LEN); + target[MAX_PATH_LEN-1] = '\0'; + break; + + case 'u': + reformat_serial = 1; + break; + + case 'x': + export = 1; + break; + + case 'v': + debug++; + break; + + case 'V': + printf("%s\n", SCSI_ID_VERSION); + exit(0); + break; + + default: + exit(1); + } + } + return 0; +} + +static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *page_code) +{ + int retval; + int newargc; + char **newargv = NULL; + int option; + + *good_bad = all_good; + *page_code = default_page_code; + + retval = get_file_options(vendor_str, model_str, &newargc, &newargv); + + optind = 1; /* reset this global extern */ + while (retval == 0) { + option = getopt_long(newargc, newargv, dev_short_options, options, NULL); + if (option == -1) + break; + + if (optarg) + dbg("option '%c' arg '%s'\n", option, optarg); + else + dbg("option '%c'\n", option); + + switch (option) { + case 'b': + *good_bad = 0; + break; + + case 'g': + *good_bad = 1; + break; + + case 'p': + if (strcmp(optarg, "0x80") == 0) { + *page_code = PAGE_80; + } else if (strcmp(optarg, "0x83") == 0) { + *page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + *page_code = PAGE_83_PRE_SPC3; + } else { + info("Unknown page code '%s'", optarg); + retval = -1; + } + break; + + default: + info("Unknown or bad option '%c' (0x%x)", option, option); + retval = -1; + break; + } + } + + if (newargv) { + free(newargv[0]); + free(newargv); + } + return retval; +} + +static int set_sysfs_values(struct sysfs_device *dev_scsi) +{ + const char *vendor, *model, *type; + + vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); + if (!vendor) { + info("%s: cannot get vendor attribute", dev_scsi->devpath); + return -1; + } + set_str(vendor_str, vendor, sizeof(vendor_str)-1); + + model = sysfs_attr_get_value(dev_scsi->devpath, "model"); + if (!model) { + info("%s: cannot get model attribute\n", dev_scsi->devpath); + return -1; + } + set_str(model_str, model, sizeof(model_str)-1); + + type = sysfs_attr_get_value(dev_scsi->devpath, "type"); + if (!type) { + info("%s: cannot get type attribute", dev_scsi->devpath); + return -1; + } + set_type(type_str, type, sizeof(type_str)); + + type = sysfs_attr_get_value(dev_scsi->devpath, "rev"); + if (!type) { + info("%s: cannot get type attribute\n", dev_scsi->devpath); + return -1; + } + set_str(revision_str, type, sizeof(revision_str)-1); + + return 0; +} + +static int set_inq_values(struct sysfs_device *dev_scsi, const char *path) +{ + int retval; + char vendor[8], model[16], type[4], rev[4]; + + retval = scsi_std_inquiry(dev_scsi, path, vendor, model, rev, type); + if (retval) + return retval; + + set_str(vendor_str, vendor, 8); + set_str(model_str, model, 16); + set_type(type_str, type, sizeof(type_str) - 1); + set_str(revision_str, rev, sizeof(revision_str) -1); + + return 0; +} + +/* + * format_serial: replace to whitespaces by underscores for calling + * programs that use the serial for device naming (multipath, Suse + * naming, etc...) + */ +static void format_serial(char *serial) +{ + char *p = serial, *q; + + q = p; + while (*p != '\0') { + if (isspace(*p)) { + if (q > serial && q[-1] != '_') { + *q = '_'; + q++; + } + } else { + *q = *p; + q++; + } + p++; + } + *q = '\0'; +} + +/* + * scsi_id: try to get an id, if one is found, printf it to stdout. + * returns a value passed to exit() - 0 if printed an id, else 1. This + * could be expanded, for example, if we want to report a failure like no + * memory etc. return 2, and return 1 for expected cases (like broken + * device found) that do not print an id. + */ +static int scsi_id(const char *devpath, char *maj_min_dev) +{ + int retval; + int dev_type = 0; + struct sysfs_device *dev; + struct sysfs_device *dev_scsi = NULL; + int good_dev; + int page_code; + char serial[MAX_SERIAL_LEN]; + char serial_short[MAX_SERIAL_LEN]; + const char *bus_str = NULL; + + dbg("devpath %s\n", devpath); + + dev = sysfs_device_get(devpath); + if (dev == NULL) { + err("unable to access '%s'", devpath); + return 1; + } + + if (strcmp(dev->subsystem, "block") == 0) + dev_type = S_IFBLK; + else + dev_type = S_IFCHR; + + /* mknod a temp dev to communicate with the device */ + if (!dev_specified && create_tmp_dev(dev->devpath, maj_min_dev, dev_type)) { + dbg("create_tmp_dev failed\n"); + return 1; + } + + if (!ignore_sysfs) { + /* get scsi parent device */ + dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi"); + if (dev_scsi == NULL) { + err("unable to access parent device of '%s'", devpath); + return 1; + } + set_sysfs_values(dev_scsi); + bus_str = "scsi"; + } else { + dev_scsi = dev; + set_inq_values(dev_scsi, maj_min_dev); + } + + /* get per device (vendor + model) options from the config file */ + retval = per_dev_options(dev_scsi, &good_dev, &page_code); + dbg("per dev options: good %d; page code 0x%x", good_dev, page_code); + + if (!good_dev) { + retval = 1; + } else if (scsi_get_serial(dev_scsi, maj_min_dev, page_code, + serial, serial_short, MAX_SERIAL_LEN)) { + retval = always_info?0:1; + } else { + retval = 0; + } + if (!retval) { + if (export) { + char serial_str[MAX_SERIAL_LEN]; + + printf("ID_VENDOR=%s\n", vendor_str); + printf("ID_MODEL=%s\n", model_str); + printf("ID_REVISION=%s\n", revision_str); + set_str(serial_str, serial, sizeof(serial_str)); + printf("ID_SERIAL=%s\n", serial_str); + set_str(serial_str, serial_short, sizeof(serial_str)); + printf("ID_SERIAL_SHORT=%s\n", serial_str); + printf("ID_TYPE=%s\n", type_str); + if (bus_str != NULL) + printf("ID_BUS=%s\n", bus_str); + } else { + if (reformat_serial) + format_serial(serial); + if (display_bus_id) + printf("%s: ", dev_scsi->kernel); + printf("%s\n", serial); + } + dbg("%s\n", serial); + retval = 0; + } + + if (!dev_specified) + unlink(maj_min_dev); + + return retval; +} + +int main(int argc, char **argv) +{ + int retval = 0; + char devpath[MAX_PATH_LEN]; + char maj_min_dev[MAX_PATH_LEN]; + int newargc; + const char *env; + char **newargv; + + logging_init("scsi_id"); + sysfs_init(); + dbg("argc is %d\n", argc); + + /* sysfs path can be overridden for testing */ + env = getenv("SYSFS_PATH"); + if (env) { + strncpy(sysfs_path, env, sizeof(sysfs_path)); + sysfs_path[sizeof(sysfs_path)-1] = '\0'; + } else + strcpy(sysfs_path, "/sys"); + + env = getenv("DEVPATH"); + if (env) { + hotplug_mode = 1; + sys_specified = 1; + strncpy(devpath, env, MAX_PATH_LEN); + devpath[sizeof(devpath)-1] = '\0'; + } + + /* + * Get config file options. + */ + newargv = NULL; + retval = get_file_options(NULL, NULL, &newargc, &newargv); + if (retval < 0) { + retval = 1; + goto exit; + } + if (newargv && (retval == 0)) { + if (set_options(newargc, newargv, short_options, devpath, + maj_min_dev) < 0) { + retval = 2; + goto exit; + } + free(newargv); + } + + /* + * Get command line options (overriding any config file or DEVPATH + * settings). + */ + if (set_options(argc, argv, short_options, devpath, maj_min_dev) < 0) + exit(1); + + if (!sys_specified) { + info("--devpath= must be specified\n"); + retval = 1; + goto exit; + } + + retval = scsi_id(devpath, maj_min_dev); + +exit: + sysfs_cleanup(); + logging_close(); + return retval; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.config b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.config new file mode 100644 index 0000000..d2a10a5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.config @@ -0,0 +1,17 @@ +# +# scsi_id configuration +# +# lower or upper case has no effect on the left side. Quotes (") are +# required for spaces in values. Model is the same as the SCSI +# INQUIRY product identification field. Per the SCSI INQUIRY, the vendor +# is limited to 8 bytes, model to 16 bytes. +# +# The first matching line found is used. Short matches match longer ones, +# if you do not want such a match space fill the extra bytes. If no model +# is specified, only the vendor string need match. +# +# options= +# vendor=string[,model=string],options= + +# some libata drives require vpd page 0x80 +vendor="ATA",options=-p 0x80 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.h b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.h new file mode 100644 index 0000000..0e2b297 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_id.h @@ -0,0 +1,46 @@ +/* + * scsi_id.h + * + * General defines and such for scsi_id + * + * Copyright (C) IBM Corp. 2003 + * + * 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. + */ + +#define MAX_PATH_LEN 512 + +/* + * MAX_ATTR_LEN: maximum length of the result of reading a sysfs + * attribute. + */ +#define MAX_ATTR_LEN 256 + +/* + * MAX_SERIAL_LEN: the maximum length of the serial number, including + * added prefixes such as vendor and product (model) strings. + */ +#define MAX_SERIAL_LEN 256 + +/* + * MAX_BUFFER_LEN: maximum buffer size and line length used while reading + * the config file. + */ +#define MAX_BUFFER_LEN 256 + +extern int scsi_std_inquiry(struct sysfs_device *dev_scsi, const char *devname, + char *vendor, char *model, char *rev, char *type); +extern int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, + int page_code, char *serial, char *serial_short, int len); + +/* + * Page code values. + */ +enum page_code { + PAGE_83_PRE_SPC3 = -0x83, + PAGE_UNSPECIFIED = 0x00, + PAGE_80 = 0x80, + PAGE_83 = 0x83, +}; diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_serial.c b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_serial.c new file mode 100644 index 0000000..c84f41e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/scsi_id/scsi_serial.c @@ -0,0 +1,875 @@ +/* + * scsi_serial.c + * + * Code related to requesting and getting an id from a scsi device + * + * Copyright (C) IBM Corp. 2003 + * + * Author: + * Patrick Mansfield + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev.h" +#include "scsi.h" +#include "scsi_id.h" +#include "scsi_id_version.h" + +/* + * A priority based list of id, naa, and binary/ascii for the identifier + * descriptor in VPD page 0x83. + * + * Brute force search for a match starting with the first value in the + * following id_search_list. This is not a performance issue, since there + * is normally one or some small number of descriptors. + */ +static const struct scsi_id_search_values id_search_list[] = { + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_BINARY }, + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_ASCII }, + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_BINARY }, + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_ASCII }, + /* + * Devices already exist using NAA values that are now marked + * reserved. These should not conflict with other values, or it is + * a bug in the device. As long as we find the IEEE extended one + * first, we really don't care what other ones are used. Using + * don't care here means that a device that returns multiple + * non-IEEE descriptors in a random order will get different + * names. + */ + { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, + { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, + { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, + { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, +}; + +static const char hex_str[]="0123456789abcdef"; + +/* + * Values returned in the result/status, only the ones used by the code + * are used here. + */ + +#define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */ +#define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */ +#define DID_TIME_OUT 0x03 /* Timed out for some other reason */ +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ + +/* The following "category" function returns one of the following */ +#define SG_ERR_CAT_CLEAN 0 /* No errors or other information */ +#define SG_ERR_CAT_MEDIA_CHANGED 1 /* interpreted from sense buffer */ +#define SG_ERR_CAT_RESET 2 /* interpreted from sense buffer */ +#define SG_ERR_CAT_TIMEOUT 3 +#define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */ +#define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */ +#define SG_ERR_CAT_SENSE 98 /* Something else in the sense buffer */ +#define SG_ERR_CAT_OTHER 99 /* Some other error/warning */ + +static int sg_err_category_new(int scsi_status, int msg_status, int + host_status, int driver_status, const + unsigned char *sense_buffer, int sb_len) +{ + scsi_status &= 0x7e; + + /* + * XXX change to return only two values - failed or OK. + */ + + /* + * checks msg_status + */ + if (!scsi_status && !msg_status && !host_status && !driver_status) + return SG_ERR_CAT_CLEAN; + + if ((scsi_status == SCSI_CHECK_CONDITION) || + (scsi_status == SCSI_COMMAND_TERMINATED) || + ((driver_status & 0xf) == DRIVER_SENSE)) { + if (sense_buffer && (sb_len > 2)) { + int sense_key; + unsigned char asc; + + if (sense_buffer[0] & 0x2) { + sense_key = sense_buffer[1] & 0xf; + asc = sense_buffer[2]; + } else { + sense_key = sense_buffer[2] & 0xf; + asc = (sb_len > 12) ? sense_buffer[12] : 0; + } + + if (sense_key == RECOVERED_ERROR) + return SG_ERR_CAT_RECOVERED; + else if (sense_key == UNIT_ATTENTION) { + if (0x28 == asc) + return SG_ERR_CAT_MEDIA_CHANGED; + if (0x29 == asc) + return SG_ERR_CAT_RESET; + } else if (sense_key == ILLEGAL_REQUEST) { + return SG_ERR_CAT_NOTSUPPORTED; + } + } + return SG_ERR_CAT_SENSE; + } + if (!host_status) { + if ((host_status == DID_NO_CONNECT) || + (host_status == DID_BUS_BUSY) || + (host_status == DID_TIME_OUT)) + return SG_ERR_CAT_TIMEOUT; + } + if (!driver_status) { + if (driver_status == DRIVER_TIMEOUT) + return SG_ERR_CAT_TIMEOUT; + } + return SG_ERR_CAT_OTHER; +} + +static int sg_err_category3(struct sg_io_hdr *hp) +{ + return sg_err_category_new(hp->status, hp->msg_status, + hp->host_status, hp->driver_status, + hp->sbp, hp->sb_len_wr); +} + +static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io) +{ + unsigned char *sense_buffer; + int s; + int sb_len; + int code; + int sense_class; + int sense_key; + int descriptor_format; + int asc, ascq; +#ifdef DUMP_SENSE + char out_buffer[256]; + int i, j; +#endif + + /* + * Figure out and print the sense key, asc and ascq. + * + * If you want to suppress these for a particular drive model, add + * a black list entry in the scsi_id config file. + * + * XXX We probably need to: lookup the sense/asc/ascq in a retry + * table, and if found return 1 (after dumping the sense, asc, and + * ascq). So, if/when we get something like a power on/reset, + * we'll retry the command. + */ + + dbg("got check condition\n"); + + sb_len = io->sb_len_wr; + if (sb_len < 1) { + info("%s: sense buffer empty", dev_scsi->kernel); + return -1; + } + + sense_buffer = io->sbp; + sense_class = (sense_buffer[0] >> 4) & 0x07; + code = sense_buffer[0] & 0xf; + + if (sense_class == 7) { + /* + * extended sense data. + */ + s = sense_buffer[7] + 8; + if (sb_len < s) { + info("%s: sense buffer too small %d bytes, %d bytes too short", + dev_scsi->kernel, sb_len, s - sb_len); + return -1; + } + if ((code == 0x0) || (code == 0x1)) { + descriptor_format = 0; + sense_key = sense_buffer[2] & 0xf; + if (s < 14) { + /* + * Possible? + */ + info("%s: sense result too" " small %d bytes", + dev_scsi->kernel, s); + return -1; + } + asc = sense_buffer[12]; + ascq = sense_buffer[13]; + } else if ((code == 0x2) || (code == 0x3)) { + descriptor_format = 1; + sense_key = sense_buffer[1] & 0xf; + asc = sense_buffer[2]; + ascq = sense_buffer[3]; + } else { + info("%s: invalid sense code 0x%x", + dev_scsi->kernel, code); + return -1; + } + info("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x", + dev_scsi->kernel, sense_key, asc, ascq); + } else { + if (sb_len < 4) { + info("%s: sense buffer too small %d bytes, %d bytes too short", + dev_scsi->kernel, sb_len, 4 - sb_len); + return -1; + } + + if (sense_buffer[0] < 15) + info("%s: old sense key: 0x%x", dev_scsi->kernel, sense_buffer[0] & 0x0f); + else + info("%s: sense = %2x %2x", + dev_scsi->kernel, sense_buffer[0], sense_buffer[2]); + info("%s: non-extended sense class %d code 0x%0x", + dev_scsi->kernel, sense_class, code); + + } + +#ifdef DUMP_SENSE + for (i = 0, j = 0; (i < s) && (j < 254); i++) { + dbg("i %d, j %d\n", i, j); + out_buffer[j++] = hex_str[(sense_buffer[i] & 0xf0) >> 4]; + out_buffer[j++] = hex_str[sense_buffer[i] & 0x0f]; + out_buffer[j++] = ' '; + } + out_buffer[j] = '\0'; + info("%s: sense dump:", dev_scsi->kernel); + info("%s: %s", dev_scsi->kernel, out_buffer); + +#endif + return -1; +} + +static int scsi_dump(struct sysfs_device *dev_scsi, struct sg_io_hdr *io) +{ + if (!io->status && !io->host_status && !io->msg_status && + !io->driver_status) { + /* + * Impossible, should not be called. + */ + info("%s: called with no error", __FUNCTION__); + return -1; + } + + info("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x", + dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status); + if (io->status == SCSI_CHECK_CONDITION) + return scsi_dump_sense(dev_scsi, io); + else + return -1; +} + +static int scsi_inquiry(struct sysfs_device *dev_scsi, int fd, + unsigned char evpd, unsigned char page, + unsigned char *buf, unsigned int buflen) +{ + unsigned char inq_cmd[INQUIRY_CMDLEN] = + { INQUIRY_CMD, evpd, page, 0, buflen, 0 }; + unsigned char sense[SENSE_BUFF_LEN]; + struct sg_io_hdr io_hdr; + int retval; + int retry = 3; /* rather random */ + + if (buflen > SCSI_INQ_BUFF_LEN) { + info("buflen %d too long", buflen); + return -1; + } + +resend: + dbg("%s evpd %d, page 0x%x\n", dev_scsi->kernel, evpd, page); + + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof(inq_cmd); + io_hdr.mx_sb_len = sizeof(sense); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = buflen; + io_hdr.dxferp = buf; + io_hdr.cmdp = inq_cmd; + io_hdr.sbp = sense; + io_hdr.timeout = DEF_TIMEOUT; + + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + info("%s: ioctl failed: %s", dev_scsi->kernel, strerror(errno)); + retval = -1; + goto error; + } + + retval = sg_err_category3(&io_hdr); + + switch (retval) { + case SG_ERR_CAT_NOTSUPPORTED: + buf[1] = 0; + /* Fallthrough */ + case SG_ERR_CAT_CLEAN: + case SG_ERR_CAT_RECOVERED: + retval = 0; + break; + + default: + retval = scsi_dump(dev_scsi, &io_hdr); + } + + if (!retval) { + retval = buflen; + } else if (retval > 0) { + if (--retry > 0) { + dbg("%s: Retrying ...\n", dev_scsi->kernel); + goto resend; + } + retval = -1; + } + +error: + if (retval < 0) + info("%s: Unable to get INQUIRY vpd %d page 0x%x.", + dev_scsi->kernel, evpd, page); + + return retval; +} + +/* Get list of supported EVPD pages */ +static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd, + unsigned char *buffer, unsigned int len) +{ + int retval; + const char *vendor; + + memset(buffer, 0, len); + retval = scsi_inquiry(dev_scsi, fd, 1, 0x0, buffer, len); + if (retval < 0) + return 1; + + if (buffer[1] != 0) { + info("%s: page 0 not available.", dev_scsi->kernel); + return 1; + } + if (buffer[3] > len) { + info("%s: page 0 buffer too long %d", dev_scsi->kernel, buffer[3]); + return 1; + } + + /* + * Following check is based on code once included in the 2.5.x + * kernel. + * + * Some ill behaved devices return the standard inquiry here + * rather than the evpd data, snoop the data to verify. + */ + if (buffer[3] > MODEL_LENGTH) { + /* + * If the vendor id appears in the page assume the page is + * invalid. + */ + vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); + if (!vendor) { + info("%s: cannot get model attribute", dev_scsi->kernel); + return 1; + } + if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) { + info("%s: invalid page0 data", dev_scsi->kernel); + return 1; + } + } + return 0; +} + +/* + * The caller checks that serial is long enough to include the vendor + + * model. + */ +static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial) +{ + const char *attr; + int ind; + + attr = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); + if (!attr) { + info("%s: cannot get vendor attribute", dev_scsi->kernel); + return 1; + } + strncpy(serial, attr, VENDOR_LENGTH); + ind = strlen(serial) - 1; + + attr = sysfs_attr_get_value(dev_scsi->devpath, "model"); + if (!attr) { + info("%s: cannot get model attribute", dev_scsi->kernel); + return 1; + } + strncat(serial, attr, MODEL_LENGTH); + ind = strlen(serial) - 1; + ind++; + + /* + * This is not a complete check, since we are using strncat/cpy + * above, ind will never be too large. + */ + if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) { + info("%s: expected length %d, got length %d", + dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind); + return 1; + } + return ind; +} + +/** + * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill + * serial number. + **/ +static int check_fill_0x83_id(struct sysfs_device *dev_scsi, + unsigned char *page_83, + const struct scsi_id_search_values + *id_search, char *serial, char *serial_short, int max_len) +{ + int i, j, s, len; + + /* + * ASSOCIATION must be with the device (value 0) + */ + if ((page_83[1] & 0x30) != 0) + return 1; + + if ((page_83[1] & 0x0f) != id_search->id_type) + return 1; + + /* + * Possibly check NAA sub-type. + */ + if ((id_search->naa_type != SCSI_ID_NAA_DONT_CARE) && + (id_search->naa_type != (page_83[4] & 0xf0) >> 4)) + return 1; + + /* + * Check for matching code set - ASCII or BINARY. + */ + if ((page_83[0] & 0x0f) != id_search->code_set) + return 1; + + /* + * page_83[3]: identifier length + */ + len = page_83[3]; + if ((page_83[0] & 0x0f) != SCSI_ID_ASCII) + /* + * If not ASCII, use two bytes for each binary value. + */ + len *= 2; + + /* + * Add one byte for the NUL termination, and one for the id_type. + */ + len += 2; + if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC) + len += VENDOR_LENGTH + MODEL_LENGTH; + + if (max_len < len) { + info("%s: length %d too short - need %d", + dev_scsi->kernel, max_len, len); + return 1; + } + + serial[0] = hex_str[id_search->id_type]; + + /* + * For SCSI_ID_VENDOR_SPECIFIC prepend the vendor and model before + * the id since it is not unique across all vendors and models, + * this differs from SCSI_ID_T10_VENDOR, where the vendor is + * included in the identifier. + */ + if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC) + if (prepend_vendor_model(dev_scsi, &serial[1]) < 0) { + dbg("prepend failed\n"); + return 1; + } + + i = 4; /* offset to the start of the identifier */ + s = j = strlen(serial); + if ((page_83[0] & 0x0f) == SCSI_ID_ASCII) { + /* + * ASCII descriptor. + */ + while (i < (4 + page_83[3])) + serial[j++] = page_83[i++]; + } else { + /* + * Binary descriptor, convert to ASCII, using two bytes of + * ASCII for each byte in the page_83. + */ + while (i < (4 + page_83[3])) { + serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4]; + serial[j++] = hex_str[page_83[i] & 0x0f]; + i++; + } + } + + strcpy(serial_short, &serial[s]); + return 0; +} + +/* Extract the raw binary from VPD 0x83 pre-SPC devices */ +static int check_fill_0x83_prespc3(struct sysfs_device *dev_scsi, + unsigned char *page_83, + const struct scsi_id_search_values + *id_search, char *serial, char *serial_short, int max_len) +{ + int i, j; + + dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel); + serial[0] = hex_str[id_search->id_type]; + /* serial has been memset to zero before */ + j = strlen(serial); /* j = 1; */ + + for (i = 0; i < page_83[3]; ++i) { + serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4]; + serial[j++] = hex_str[ page_83[4+i] & 0x0f]; + } + strcpy(serial_short, serial); + return 0; +} + + +/* Get device identification VPD page */ +static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd, + char *serial, char *serial_short, int len) +{ + int retval; + unsigned int id_ind, j; + unsigned char page_83[SCSI_INQ_BUFF_LEN]; + + memset(page_83, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83, + SCSI_INQ_BUFF_LEN); + if (retval < 0) + return 1; + + if (page_83[1] != PAGE_83) { + info("%s: Invalid page 0x83", dev_scsi->kernel); + return 1; + } + + /* + * XXX Some devices (IBM 3542) return all spaces for an identifier if + * the LUN is not actually configured. This leads to identifers of + * the form: "1 ". + */ + + /* + * Model 4, 5, and (some) model 6 EMC Symmetrix devices return + * a page 83 reply according to SCSI-2 format instead of SPC-2/3. + * + * The SCSI-2 page 83 format returns an IEEE WWN in binary + * encoded hexi-decimal in the 16 bytes following the initial + * 4-byte page 83 reply header. + * + * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part + * of an Identification descriptor. The 3rd byte of the first + * Identification descriptor is a reserved (BSZ) byte field. + * + * Reference the 7th byte of the page 83 reply to determine + * whether the reply is compliant with SCSI-2 or SPC-2/3 + * specifications. A zero value in the 7th byte indicates + * an SPC-2/3 conformant reply, (i.e., the reserved field of the + * first Identification descriptor). This byte will be non-zero + * for a SCSI-2 conformant page 83 reply from these EMC + * Symmetrix models since the 7th byte of the reply corresponds + * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is, + * 0x006048. + */ + + if (page_83[6] != 0) + return check_fill_0x83_prespc3(dev_scsi, page_83, id_search_list, + serial, serial_short, len); + + /* + * Search for a match in the prioritized id_search_list. + */ + for (id_ind = 0; + id_ind < sizeof(id_search_list)/sizeof(id_search_list[0]); + id_ind++) { + /* + * Examine each descriptor returned. There is normally only + * one or a small number of descriptors. + */ + for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) { + retval = check_fill_0x83_id(dev_scsi, &page_83[j], + &id_search_list[id_ind], + serial, serial_short, len); + dbg("%s id desc %d/%d/%d\n", dev_scsi->kernel, + id_search_list[id_ind].id_type, + id_search_list[id_ind].naa_type, + id_search_list[id_ind].code_set); + if (!retval) { + dbg(" used\n"); + return retval; + } else if (retval < 0) { + dbg(" failed\n"); + return retval; + } else { + dbg(" not used\n"); + } + } + } + return 1; +} + +/* + * Get device identification VPD page for older SCSI-2 device which is not + * compliant with either SPC-2 or SPC-3 format. + * + * Return the hard coded error code value 2 if the page 83 reply is not + * conformant to the SCSI-2 format. + */ +static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd, + char *serial, char *serial_short, int len) +{ + int retval; + int i, j; + unsigned char page_83[SCSI_INQ_BUFF_LEN]; + + memset(page_83, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN); + if (retval < 0) + return 1; + + if (page_83[1] != PAGE_83) { + info("%s: Invalid page 0x83", dev_scsi->kernel); + return 1; + } + /* + * Model 4, 5, and (some) model 6 EMC Symmetrix devices return + * a page 83 reply according to SCSI-2 format instead of SPC-2/3. + * + * The SCSI-2 page 83 format returns an IEEE WWN in binary + * encoded hexi-decimal in the 16 bytes following the initial + * 4-byte page 83 reply header. + * + * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part + * of an Identification descriptor. The 3rd byte of the first + * Identification descriptor is a reserved (BSZ) byte field. + * + * Reference the 7th byte of the page 83 reply to determine + * whether the reply is compliant with SCSI-2 or SPC-2/3 + * specifications. A zero value in the 7th byte indicates + * an SPC-2/3 conformant reply, (i.e., the reserved field of the + * first Identification descriptor). This byte will be non-zero + * for a SCSI-2 conformant page 83 reply from these EMC + * Symmetrix models since the 7th byte of the reply corresponds + * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is, + * 0x006048. + */ + if (page_83[6] == 0) + return 2; + + serial[0] = hex_str[id_search_list[0].id_type]; + /* + * The first four bytes contain data, not a descriptor. + */ + i = 4; + j = strlen(serial); + /* + * Binary descriptor, convert to ASCII, + * using two bytes of ASCII for each byte + * in the page_83. + */ + while (i < (page_83[3]+4)) { + serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4]; + serial[j++] = hex_str[page_83[i] & 0x0f]; + i++; + } + dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel); + return 0; +} + +/* Get unit serial number VPD page */ +static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd, + char *serial, char *serial_short, int max_len) +{ + int retval; + int ser_ind; + int i; + int len; + unsigned char buf[SCSI_INQ_BUFF_LEN]; + + memset(buf, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN); + if (retval < 0) + return retval; + + if (buf[1] != PAGE_80) { + info("%s: Invalid page 0x80", dev_scsi->kernel); + return 1; + } + + len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3]; + if (max_len < len) { + info("%s: length %d too short - need %d", + dev_scsi->kernel, max_len, len); + return 1; + } + /* + * Prepend 'S' to avoid unlikely collision with page 0x83 vendor + * specific type where we prepend '0' + vendor + model. + */ + serial[0] = 'S'; + ser_ind = prepend_vendor_model(dev_scsi, &serial[1]); + if (ser_ind < 0) + return 1; + len = buf[3]; + for (i = 4; i < len + 4; i++, ser_ind++) + serial[ser_ind] = buf[i]; + memcpy(serial_short, &buf[4], len); + serial_short[len] = '\0'; + return 0; +} + +int scsi_std_inquiry(struct sysfs_device *dev_scsi, const char *devname, + char *vendor, char *model, char *rev, char *type) +{ + int retval; + int fd; + unsigned char buf[SCSI_INQ_BUFF_LEN]; + + dbg("opening %s\n", devname); + fd = open(devname, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + info("%s: cannot open %s: %s", + dev_scsi->kernel, devname, strerror(errno)); + return 1; + } + + memset(buf, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN); + if (retval < 0) + return retval; + + memcpy(vendor, buf + 8, 8); + memcpy(model, buf + 16, 16); + memcpy(rev, buf + 32, 4); + sprintf(type,"%x", buf[0] & 0x1f); + + if (close(fd) < 0) + info("%s: close failed: %s", dev_scsi->kernel, strerror(errno)); + + return 0; +} + +int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, + int page_code, char *serial, char *serial_short, int len) +{ + unsigned char page0[SCSI_INQ_BUFF_LEN]; + int fd; + int ind; + int retval; + + memset(serial, 0, len); + dbg("opening %s\n", devname); + fd = open(devname, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + info("%s: cannot open %s: %s", + dev_scsi->kernel, devname, strerror(errno)); + return 1; + } + + if (page_code == PAGE_80) { + if (do_scsi_page80_inquiry(dev_scsi, fd, serial, serial_short, len)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } else if (page_code == PAGE_83) { + if (do_scsi_page83_inquiry(dev_scsi, fd, serial, serial_short, len)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } else if (page_code == PAGE_83_PRE_SPC3) { + retval = do_scsi_page83_prespc3_inquiry(dev_scsi, fd, serial, serial_short, len); + if (retval) { + /* + * Fallback to servicing a SPC-2/3 compliant page 83 + * inquiry if the page 83 reply format does not + * conform to pre-SPC3 expectations. + */ + if (retval == 2) { + if (do_scsi_page83_inquiry(dev_scsi, fd, serial, serial_short, len)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } + else { + retval = 1; + goto completed; + } + } else { + retval = 0; + goto completed; + } + } else if (page_code != 0x00) { + info("%s: unsupported page code 0x%d", dev_scsi->kernel, page_code); + return 1; + } + + /* + * Get page 0, the page of the pages. By default, try from best to + * worst of supported pages: 0x83 then 0x80. + */ + if (do_scsi_page0_inquiry(dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) { + /* + * Don't try anything else. Black list if a specific page + * should be used for this vendor+model, or maybe have an + * optional fall-back to page 0x80 or page 0x83. + */ + retval = 1; + goto completed; + } + + dbg("%s: Checking page0\n", dev_scsi->kernel); + + for (ind = 4; ind <= page0[3] + 3; ind++) + if (page0[ind] == PAGE_83) + if (!do_scsi_page83_inquiry(dev_scsi, fd, + serial, serial_short, len)) { + /* + * Success + */ + retval = 0; + goto completed; + } + + for (ind = 4; ind <= page0[3] + 3; ind++) + if (page0[ind] == PAGE_80) + if (!do_scsi_page80_inquiry(dev_scsi, fd, + serial, serial_short, len)) { + /* + * Success + */ + retval = 0; + goto completed; + } + retval = 1; +completed: + if (close(fd) < 0) + info("%s: close failed: %s", dev_scsi->kernel, strerror(errno)); + return retval; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/usb_id/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/usb_id/Makefile new file mode 100644 index 0000000..7787161 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/usb_id/Makefile @@ -0,0 +1,69 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2005 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +PROG = usb_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: + @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 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/usb_id/usb_id.c b/21cnbao/code/05/udev源代码/udev-114/extras/usb_id/usb_id.c new file mode 100644 index 0000000..d36a27b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/usb_id/usb_id.c @@ -0,0 +1,460 @@ +/* + * usb_id.c + * + * Identify an USB (block) device + * + * Copyright (c) 2005 SUSE Linux Products GmbH, Germany + * + * Author: + * Hannes Reinecke + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev.h" + +#define MAX_PATH_LEN 512 +#define MAX_SERIAL_LEN 256 +#define BLKGETSIZE64 _IOR(0x12,114,size_t) + +#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 char vendor_str[64]; +static char model_str[64]; +static char serial_str[MAX_SERIAL_LEN]; +static char revision_str[64]; +static char type_str[64]; +static char instance_str[64]; + +static int use_usb_info; +static int use_num_info; + +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++] = '_'; + } + /* Replace '/' with '.' */ + if (from[i] == '/') { + to[j++] = '.'; + i++; + continue; + } + /* skip non-printable chars */ + if (!isalnum(from[i]) && !ispunct(from[i])) { + i++; + continue; + } + to[j++] = from[i++]; + } + to[j] = '\0'; +} + +static void set_usb_iftype(char *to, int if_class_num, size_t len) +{ + char *type = "generic"; + + switch (if_class_num) { + case 1: + type = "audio"; + break; + case 3: + type = "hid"; + break; + case 7: + type = "printer"; + break; + case 8: + type = "storage"; + break; + case 2: /* CDC-Control */ + case 5: /* Physical */ + case 6: /* Image */ + case 9: /* HUB */ + case 0x0a: /* CDC-Data */ + case 0x0b: /* Chip/Smart Card */ + case 0x0d: /* Content Security */ + case 0x0e: /* Video */ + case 0xdc: /* Diagnostic Device */ + case 0xe0: /* Wireless Controller */ + case 0xf2: /* Application-specific */ + case 0xff: /* Vendor-specific */ + break; + default: + break; + } + strncpy(to, type, len); + to[len-1] = '\0'; +} + +static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) +{ + int type_num = 0; + char *eptr; + char *type = "generic"; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 2: + type = "cd"; + break; + case 3: + type = "tape"; + break; + case 4: /* UFI */ + case 5: /* SFF-8070i */ + type = "floppy"; + break; + case 1: /* RBC devices */ + case 6: /* Transparent SPC-2 devices */ + type = "disk"; + break; + default: + break; + } + } + strlcpy(to, type, len); + + return type_num; +} + +static void set_scsi_type(char *to, const char *from, size_t len) +{ + int type_num; + char *eptr; + char *type = "generic"; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + case 0xe: + type = "disk"; + break; + case 1: + type = "tape"; + break; + case 4: + case 7: + case 0xf: + type = "optical"; + break; + case 5: + type = "cd"; + break; + default: + break; + } + } + strlcpy(to, type, len); +} + +/* + * A unique USB identification is generated like this: + * + * 1.) Get the USB device type from DeviceClass, InterfaceClass + * and InterfaceSubClass + * 2.) If the device type is 'Mass-Storage/SPC-2' or 'Mass-Storage/RBC' + * use the SCSI vendor and model as USB-Vendor and USB-model. + * 3.) Otherwise use the USB manufacturer and product as + * USB-Vendor and USB-model. Any non-printable characters + * in those strings will be skipped; a slash '/' will be converted + * into a full stop '.'. + * 4.) If that fails, too, we will use idVendor and idProduct + * as USB-Vendor and USB-model. + * 5.) The USB identification is the USB-vendor and USB-model + * string concatenated with an underscore '_'. + * 6.) If the device supplies a serial number, this number + * is concatenated with the identification with an underscore '_'. + */ +static int usb_id(const char *devpath) +{ + struct sysfs_device *dev; + struct sysfs_device *dev_interface; + struct sysfs_device *dev_usb; + const char *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; + const char *usb_model = NULL, *usb_vendor = NULL, *usb_rev, *usb_serial; + const char *if_class, *if_subclass; + int if_class_num; + int protocol = 0; + + dbg("devpath %s\n", devpath); + + /* get all usb specific information: dev_interface, if_class, dev_usb */ + dev = sysfs_device_get(devpath); + if (dev == NULL) { + err("unable to access '%s'", devpath); + return 1; + } + + /* usb interface directory */ + dev_interface = sysfs_device_get_parent_with_subsystem(dev, "usb"); + if (dev_interface == NULL) { + info("unable to access usb_interface device of '%s'", devpath); + return 1; + } + + if_class = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceClass"); + if (!if_class) { + info("%s: cannot get bInterfaceClass attribute", dev_interface->kernel); + return 1; + } + if_class_num = strtoul(if_class, NULL, 16); + if (if_class_num == 8) { + if_subclass = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceSubClass"); + if (if_subclass != NULL) + protocol = set_usb_mass_storage_ifsubtype(type_str, if_subclass, sizeof(type_str)-1); + } else + set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1); + + info("%s: if_class %d protocol %d\n", dev_interface->devpath, if_class_num, protocol); + + /* usb device directory */ + dev_usb = sysfs_device_get_parent_with_subsystem(dev_interface, "usb"); + if (!dev_usb) { + info("unable to find parent 'usb' device of '%s'", devpath); + return 1; + } + + /* mass storage */ + if (protocol == 6 && !use_usb_info) { + struct sysfs_device *dev_scsi; + int host, bus, target, lun; + + /* get scsi device */ + dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi"); + if (dev_scsi == NULL) { + info("unable to find parent 'scsi' device of '%s'", devpath); + goto fallback; + } + if (sscanf(dev_scsi->kernel, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) { + info("invalid scsi device '%s'", dev_scsi->kernel); + goto fallback; + } + + /* Generic SPC-2 device */ + scsi_vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); + if (!scsi_vendor) { + info("%s: cannot get SCSI vendor attribute", dev_scsi->kernel); + goto fallback; + } + set_str(vendor_str, scsi_vendor, sizeof(vendor_str)-1); + + scsi_model = sysfs_attr_get_value(dev_scsi->devpath, "model"); + if (!scsi_model) { + info("%s: cannot get SCSI model attribute", dev_scsi->kernel); + goto fallback; + } + set_str(model_str, scsi_model, sizeof(model_str)-1); + + scsi_type = sysfs_attr_get_value(dev_scsi->devpath, "type"); + if (!scsi_type) { + info("%s: cannot get SCSI type attribute", dev_scsi->kernel); + goto fallback; + } + set_scsi_type(type_str, scsi_type, sizeof(type_str)-1); + + scsi_rev = sysfs_attr_get_value(dev_scsi->devpath, "rev"); + if (!scsi_rev) { + info("%s: cannot get SCSI revision attribute", dev_scsi->kernel); + goto fallback; + } + set_str(revision_str, scsi_rev, sizeof(revision_str)-1); + + /* + * some broken devices have the same identifiers + * for all luns, export the target:lun number + */ + sprintf(instance_str, "%d:%d", target, lun); + } + +fallback: + /* Fallback to USB vendor & device */ + if (vendor_str[0] == '\0') { + if (!use_num_info) + if (!(usb_vendor = sysfs_attr_get_value(dev_usb->devpath, "manufacturer"))) + dbg("No USB vendor string found, using idVendor"); + + if (!usb_vendor) { + if (!(usb_vendor = sysfs_attr_get_value(dev_usb->devpath, "idVendor"))) { + dbg("No USB vendor information available\n"); + sprintf(vendor_str,"0000"); + } + } + set_str(vendor_str,usb_vendor, sizeof(vendor_str) - 1); + } + + if (model_str[0] == '\0') { + if (!use_num_info) + if (!(usb_model = sysfs_attr_get_value(dev_usb->devpath, "product"))) + dbg("No USB model string found, using idProduct"); + + if (!usb_model) { + if (!(usb_model = sysfs_attr_get_value(dev_usb->devpath, "idProduct"))) + dbg("No USB model information available\n"); sprintf(model_str,"0000"); + } + set_str(model_str, usb_model, sizeof(model_str) - 1); + } + + if (revision_str[0] == '\0') { + usb_rev = sysfs_attr_get_value(dev_usb->devpath, "bcdDevice"); + if (usb_rev) + set_str(revision_str, usb_rev, sizeof(revision_str)-1); + } + + if (serial_str[0] == '\0') { + usb_serial = sysfs_attr_get_value(dev_usb->devpath, "serial"); + if (usb_serial) + set_str(serial_str, usb_serial, sizeof(serial_str)-1); + } + return 0; +} + +int main(int argc, char **argv) +{ + int retval = 0; + const char *env; + char devpath[MAX_PATH_LEN]; + static int export; + static const struct option options[] = { + { "usb-info", 0, NULL, 'u' }, + { "num-info", 0, NULL, 'n' }, + { "export", 0, NULL, 'x' }, + { "help", 0, NULL, 'h' }, + {} + }; + + logging_init("usb_id"); + sysfs_init(); + + while (1) { + int option; + + option = getopt_long(argc, argv, "nuxh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'n': + use_num_info = 1; + use_usb_info = 1; + break; + case 'u': + use_usb_info = 1; + break; + case 'x': + export = 1; + break; + case 'h': + printf("Usage: usb_id [--usb-info] [--num-info] [--export] [--help] \n" + " --usb-info use usb strings instead\n" + " --num-info use numerical values\n" + " --export print values as environemt keys\n" + " --help print this help text\n\n"); + default: + retval = 1; + goto exit; + } + } + + env = getenv("DEVPATH"); + if (env != NULL) + strlcpy(devpath, env, sizeof(devpath)); + else { + if (argv[optind] == NULL) { + fprintf(stderr, "No device specified\n"); + retval = 1; + goto exit; + } + strlcpy(devpath, argv[optind], sizeof(devpath)); + } + + retval = usb_id(devpath); + + if (retval == 0) { + char serial[256]; + + strlcpy(serial, vendor_str, sizeof(serial)); + strlcat(serial, "_", sizeof(serial)); + strlcat(serial, model_str, sizeof(serial)); + if (serial_str[0] != '\0') { + strlcat(serial, "_", sizeof(serial)); + strlcat(serial, serial_str, sizeof(serial)); + } + if (instance_str[0] != '\0') { + strlcat(serial, "-", sizeof(serial)); + strlcat(serial, instance_str, sizeof(serial)); + } + + if (export) { + printf("ID_VENDOR=%s\n", vendor_str); + printf("ID_MODEL=%s\n", model_str); + printf("ID_REVISION=%s\n", revision_str); + printf("ID_SERIAL=%s\n", serial); + if (serial_str[0] != '\0') + printf("ID_SERIAL_SHORT=%s\n", serial_str); + printf("ID_TYPE=%s\n", type_str); + if (instance_str[0] != '\0') + printf("ID_INSTANCE=%s\n", instance_str); + printf("ID_BUS=usb\n"); + } else + printf("%s\n", serial); + } + +exit: + sysfs_cleanup(); + logging_close(); + return retval; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/Makefile new file mode 100644 index 0000000..6e50065 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/Makefile @@ -0,0 +1,82 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2004-2006 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +PROG = vol_id +GEN_HEADERS = +MAN_PAGES = vol_id.8 + +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: lib $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all + +.SUFFIXES: + +%.o: %.c $(GEN_HEADERS) + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ + +lib: + $(Q) $(MAKE) -C $@ +.PHONY: lib + +lib/libvolume_id.a: lib + +$(PROG): %: $(HEADERS) %.o lib/libvolume_id.a + $(E) " LD " $@ +ifeq ($(strip $(VOLUME_ID_STATIC)),true) + $(Q) $(LD) $(LDFLAGS) -o $@ $@.o $(LIBUDEV) lib/libvolume_id.a $(LIB_OBJS) +else + $(Q) $(LD) $(LDFLAGS) -o $@ $@.o $(LIBUDEV) -Llib -lvolume_id $(LIB_OBJS) +endif + +# man pages +%.8: %.xml + $(E) " XMLTO " $@ + $(Q) xmlto man $? +.PRECIOUS: %.8 + +clean: + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(Q) $(MAKE) -C lib clean +.PHONY: clean + +install-bin: all + $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG) + $(MAKE) -C lib install +.PHONY: install-bin + +uninstall-bin: + - rm $(DESTDIR)$(libudevdir)/$(PROG) + $(MAKE) -C lib uninstall +.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 diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/README b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/README new file mode 100644 index 0000000..217be31 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/README @@ -0,0 +1,78 @@ +vol_id - probe filesystem and read label and uuid + +This program is normally called from a udev rule, to provide udev with the +filesystem type of a volume and the label and uuid to name a device node. +vol_id opens the blockdevice node specified at the commandline. The following +commandline switches are supported to specify what vol_id should print: + --export export key/value pairs + --type filesystem type + --label filesystem label + --label-raw raw label + --uuid filesystem uuid + --skip-raid don't probe for raid + --probe-all find possibly conflicting signatures + --help + +vol_id will only return successful if the string asked for, is not +empty. All trailing whitespace will be removed, spaces replaced by underscore +and slashes ignored. + +fstype probe label uuid version +-------------------------------------------------- +linux swap * * * * +ext * * * * +reiserfs jr/3.5/3.6/4 * * * * +fat (12, 16, 32) * * * * +ntfs * * * * +jfs * * * - +xfs * * * - +hfs (plus, wrapped) * * * - +udf * * - - +iso9660 * * - - +ufs * - - - +cramfs * * - - +sysv * * - * +luks * - * - +hpfs * - - - +romfs * * - - +squashfs * - - - +minix * - - * +ocfs (1, 2) * * * * +vxfs * - - * +nss (netware) * * * +gfs, gfs2 * - - - + +Raid members are detected to prevent the probing for a filesystem +----------------------------------------------------------------- +linux raid (md) * * * * +LVM 1 * - - - +LVM 2 * - - * +ddf * - * * +highpoint * - - - +isw_raid * - - - +lsi_raid * - - - +nvidia_raid * - - - +promise_raid * - - - +silicon_raid * - - - +via_raid * - - - +jmicron * - - - +adaptec * - - - + +To give it a try, you may call it on the commandline: + $ extras/volume_id/vol_id --export /dev/sda6 + ID_FS_USAGE=filesystem + ID_FS_TYPE=ext3 + ID_FS_VERSION=1.0 + ID_FS_UUID=3e999973-00c9-4917-9442-b7633bd95b9e + ID_FS_LABEL=devel + ID_FS_LABEL_SAFE=devel + + $ extras/volume_id/vol_id --label /dev/sda6 + devel + + $ extras/volume_id/vol_id --type /dev/sda6 + ext3 + + +Any comment/questions/concerns to me: + Kay Sievers diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/Makefile b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/Makefile new file mode 100644 index 0000000..0a37c26 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/Makefile @@ -0,0 +1,127 @@ +# libvolume_id - read filesystem label/uuid +# +# Copyright (C) 2004-2006 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# +includedir = ${prefix}/usr/include +libdir = ${prefix}/lib +usrlibdir = ${prefix}/usr/lib + +INSTALL = install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_LIB = ${INSTALL} -m 755 + +SHLIB_CUR = 0 +SHLIB_REV = 79 +SHLIB_AGE = 0 +SHLIB = libvolume_id.so.$(SHLIB_CUR).$(SHLIB_REV).$(SHLIB_AGE) + +OBJS= \ + ext.o \ + fat.o \ + hfs.o \ + highpoint.o \ + isw_raid.o \ + lsi_raid.o \ + via_raid.o \ + silicon_raid.o \ + nvidia_raid.o \ + promise_raid.o \ + adaptec_raid.o \ + jmicron_raid.o \ + ddf_raid.o \ + iso9660.o \ + jfs.o \ + linux_raid.o \ + linux_swap.o \ + lvm.o \ + ntfs.o \ + reiserfs.o \ + udf.o \ + ufs.o \ + xfs.o \ + cramfs.o \ + hpfs.o \ + romfs.o \ + sysv.o \ + minix.o \ + gfs.o \ + luks.o \ + ocfs.o \ + vxfs.o \ + squashfs.o \ + netware.o \ + volume_id.o \ + util.o + +HEADERS= \ + libvolume_id.h \ + util.h + +all: libvolume_id.a $(SHLIB) libvolume_id.pc +.PHONY: all +.DEFAULT: all + +.SUFFIXES: + +%.o: %.c + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ + +.shlib/%.o: %.c + $(E) " CC " $@ + $(Q) mkdir -p $(dir $@) + $(Q) $(CC) -c $(CFLAGS) -fPIC $< -o $@ + +libvolume_id.a: $(HEADERS) $(OBJS) + $(Q) rm -f $@ + $(E) " AR " $@ + $(Q) $(AR) cq $@ $(OBJS) + $(E) " RANLIB " $@ + $(Q) $(RANLIB) $@ + +$(SHLIB): $(HEADERS) exported_symbols $(addprefix .shlib/,$(OBJS)) + $(E) " CC " $@ + $(Q) $(CC) -shared $(CFLAGS) -o $@ \ + -Wl,-soname,libvolume_id.so.$(SHLIB_CUR),--version-script,exported_symbols \ + $(addprefix .shlib/,$(OBJS)) + $(Q) ln -sf $@ libvolume_id.so.$(SHLIB_CUR) + $(Q) ln -sf $@ libvolume_id.so + +libvolume_id.pc: + $(E) " GENPC " $@ + $(Q) echo "libdir=${usrlibdir}" >> $@ + $(Q) echo "includedir=${includedir}" >> $@ + $(Q) echo "" >> $@ + $(Q) echo "Name: libvolume_id" >> $@ + $(Q) echo "Description: Filesystem label and uuid access" >> $@ + $(Q) echo "Version: $(SHLIB_CUR).$(SHLIB_REV).$(SHLIB_AGE)" >> $@ + $(Q) echo "Libs: -L\$${libdir} -lvolume_id" >> $@ + $(Q) echo "Cflags: -I\$${includedir}" >> $@ + +install: all + $(INSTALL_DATA) -D libvolume_id.h $(DESTDIR)$(includedir)/libvolume_id.h + $(INSTALL_LIB) -D $(SHLIB) $(DESTDIR)$(libdir)/$(SHLIB) + mkdir -p $(DESTDIR)$(usrlibdir)/ + ln -sf $(SHLIB) $(DESTDIR)$(libdir)/libvolume_id.so.$(SHLIB_CUR) + ln -sf $(libdir)/$(SHLIB) $(DESTDIR)$(usrlibdir)/libvolume_id.so + $(INSTALL_DATA) -D libvolume_id.pc $(DESTDIR)$(usrlibdir)/pkgconfig/libvolume_id.pc +.PHONY: install + +uninstall: + rm -f $(DESTDIR)$(includedir)/libvolume_id.h + rm -f $(DESTDIR)$(usrlibdir)/libvolume_id.a + rm -f $(DESTDIR)$(libdir)/$(SHLIB) + rm -f $(DESTDIR)$(libdir)/libvolume_id.so.$(SHLIB_CUR) + rm -f $(DESTDIR)$(libdir)/libvolume_id.so +.PHONY: uninstall + +clean: + $(E) " CLEAN " + $(Q) rm -f libvolume_id.a $(OBJS) + $(Q) rm -f $(SHLIB) libvolume_id.so.$(SHLIB_CUR) libvolume_id.so + $(Q) rm -rf .shlib + $(Q) rm -f libvolume_id.pc +.PHONY: clean + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/adaptec_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/adaptec_raid.c new file mode 100644 index 0000000..858c3ba --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/adaptec_raid.c @@ -0,0 +1,112 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2006 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct adaptec_meta { + uint32_t b0idcode; + uint8_t lunsave[8]; + uint16_t sdtype; + uint16_t ssavecyl; + uint8_t ssavehed; + uint8_t ssavesec; + uint8_t sb0flags; + uint8_t jbodEnable; + uint8_t lundsave; + uint8_t svpdirty; + uint16_t biosInfo; + uint16_t svwbskip; + uint16_t svwbcln; + uint16_t svwbmax; + uint16_t res3; + uint16_t svwbmin; + uint16_t res4; + uint16_t svrcacth; + uint16_t svwcacth; + uint16_t svwbdly; + uint8_t svsdtime; + uint8_t res5; + uint16_t firmval; + uint16_t firmbln; + uint32_t firmblk; + uint32_t fstrsvrb; + uint16_t svBlockStorageTid; + uint16_t svtid; + uint8_t svseccfl; + uint8_t res6; + uint8_t svhbanum; + uint8_t resver; + uint32_t drivemagic; + uint8_t reserved[20]; + uint8_t testnum; + uint8_t testflags; + uint16_t maxErrorCount; + uint32_t count; + uint32_t startTime; + uint32_t interval; + uint8_t tstxt0; + uint8_t tstxt1; + uint8_t serNum[32]; + uint8_t res8[102]; + uint32_t fwTestMagic; + uint32_t fwTestSeqNum; + uint8_t fwTestRes[8]; + uint8_t smagic[4]; + uint32_t raidtbl; + uint16_t raidline; + uint8_t res9[0xF6]; +} PACKED; + +int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t meta_off; + struct adaptec_meta *ad; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + ad = (struct adaptec_meta *) buf; + if (memcmp(ad->smagic, "DPTM", 4) != 0) + return -1; + + if (ad->b0idcode != be32_to_cpu(0x37FC4D1E)) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", ad->resver); + id->type = "adaptec_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/cramfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/cramfs.c new file mode 100644 index 0000000..bf32950 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/cramfs.c @@ -0,0 +1,64 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct cramfs_super { + uint8_t magic[4]; + uint32_t size; + uint32_t flags; + uint32_t future; + uint8_t signature[16]; + struct cramfs_info { + uint32_t crc; + uint32_t edition; + uint32_t blocks; + uint32_t files; + } PACKED info; + uint8_t name[16]; +} PACKED; + +int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct cramfs_super *cs; + + info("probing at offset 0x%llx", (unsigned long long) off); + + cs = (struct cramfs_super *) volume_id_get_buffer(id, off, 0x200); + if (cs == NULL) + return -1; + + if (memcmp(cs->magic, "\x45\x3d\xcd\x28", 4) == 0 || memcmp(cs->magic, "\x28\xcd\x3d\x45", 4) == 0) { + volume_id_set_label_raw(id, cs->name, 16); + volume_id_set_label_string(id, cs->name, 16); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "cramfs"; + return 0; + } + + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ddf_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ddf_raid.c new file mode 100644 index 0000000..560e6bd --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ddf_raid.c @@ -0,0 +1,66 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2007 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +/* http://www.snia.org/standards/home */ + +#define DDF_HEADER 0xDE11DE11 +#define DDF_GUID_LENGTH 24 +#define DDF_REV_LENGTH 8 + +static struct ddf_header { + uint32_t signature; + uint32_t crc; + uint8_t guid[DDF_GUID_LENGTH]; + uint8_t ddf_rev[DDF_REV_LENGTH]; +} PACKED *ddf; + +int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + uint64_t ddf_off = ((size / 0x200)-1) * 0x200; + const uint8_t *buf; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + if (size < 0x10000) + return -1; + + buf = volume_id_get_buffer(id, off + ddf_off, 0x200); + if (buf == NULL) + return -1; + ddf = (struct ddf_header *) buf; + + if (ddf->signature != cpu_to_be32(DDF_HEADER)) + return -1; + + volume_id_set_uuid(id, ddf->guid, DDF_GUID_LENGTH, UUID_STRING); + snprintf(id->type_version, DDF_REV_LENGTH, "%s", ddf->ddf_rev); + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "ddf_raid_member"; + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/exported_symbols b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/exported_symbols new file mode 100644 index 0000000..05b6e52 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/exported_symbols @@ -0,0 +1,64 @@ +{ global: + volume_id_log_fn; + + volume_id_get_label; + volume_id_get_label_raw; + volume_id_get_uuid; + volume_id_get_uuid_raw; + volume_id_get_usage; + volume_id_get_type; + volume_id_get_type_version; + + volume_id_open_fd; + volume_id_close; + volume_id_probe_all; + volume_id_probe_filesystem; + volume_id_probe_raid; + volume_id_all_probers; + volume_id_get_prober_by_type; + volume_id_encode_string; + + volume_id_open_node; + + volume_id_probe_linux_swap; + volume_id_probe_luks; + volume_id_probe_cramfs; + volume_id_probe_ext; + volume_id_probe_vfat; + volume_id_probe_hfs_hfsplus; + volume_id_probe_hpfs; + volume_id_probe_iso9660; + volume_id_probe_jfs; + volume_id_probe_minix; + volume_id_probe_ntfs; + volume_id_probe_ocfs1; + volume_id_probe_ocfs2; + volume_id_probe_reiserfs; + volume_id_probe_romfs; + volume_id_probe_sysv; + volume_id_probe_udf; + volume_id_probe_ufs; + volume_id_probe_vxfs; + volume_id_probe_xfs; + volume_id_probe_squashfs; + volume_id_probe_netware; + volume_id_probe_gfs; + volume_id_probe_gfs2; + + volume_id_probe_linux_raid; + volume_id_probe_lvm1; + volume_id_probe_lvm2; + volume_id_probe_ddf_raid; + volume_id_probe_intel_software_raid; + volume_id_probe_highpoint_37x_raid; + volume_id_probe_highpoint_45x_raid; + volume_id_probe_lsi_mega_raid; + volume_id_probe_nvidia_raid; + volume_id_probe_promise_fasttrack_raid; + volume_id_probe_silicon_medley_raid; + volume_id_probe_via_raid; + volume_id_probe_adaptec_raid; + volume_id_probe_jmicron_raid; +local: + *; +}; diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ext.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ext.c new file mode 100644 index 0000000..1997d42 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ext.c @@ -0,0 +1,134 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct ext2_super_block { + uint32_t s_inodes_count; + uint32_t s_blocks_count; + uint32_t s_r_blocks_count; + uint32_t s_free_blocks_count; + uint32_t s_free_inodes_count; + uint32_t s_first_data_block; + uint32_t s_log_block_size; + uint32_t s_log_frag_size; + uint32_t s_blocks_per_group; + uint32_t s_frags_per_group; + uint32_t s_inodes_per_group; + uint32_t s_mtime; + uint32_t s_wtime; + uint16_t s_mnt_count; + uint16_t s_max_mnt_count; + uint16_t s_magic; + uint16_t s_state; + uint16_t s_errors; + uint16_t s_minor_rev_level; + uint32_t s_lastcheck; + uint32_t s_checkinterval; + uint32_t s_creator_os; + uint32_t s_rev_level; + uint16_t s_def_resuid; + uint16_t s_def_resgid; + uint32_t s_first_ino; + uint16_t s_inode_size; + uint16_t s_block_group_nr; + uint32_t s_feature_compat; + uint32_t s_feature_incompat; + uint32_t s_feature_ro_compat; + uint8_t s_uuid[16]; + uint8_t s_volume_name[16]; +} PACKED; + +#define EXT_SUPER_MAGIC 0xEF53 +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 +#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 +#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 + +#define EXT_SUPERBLOCK_OFFSET 0x400 + +#define EXT3_MIN_BLOCK_SIZE 0x400 +#define EXT3_MAX_BLOCK_SIZE 0x1000 + +int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct ext2_super_block *es; + size_t bsize; + uint32_t feature_compat; + uint32_t feature_incompat; + + info("probing at offset 0x%llx", (unsigned long long) off); + + es = (struct ext2_super_block *) volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); + if (es == NULL) + return -1; + + if (es->s_magic != cpu_to_le16(EXT_SUPER_MAGIC)) + return -1; + + bsize = 0x400 << le32_to_cpu(es->s_log_block_size); + dbg("ext blocksize 0x%zx", bsize); + if (bsize < EXT3_MIN_BLOCK_SIZE || bsize > EXT3_MAX_BLOCK_SIZE) { + dbg("invalid ext blocksize"); + return -1; + } + + volume_id_set_label_raw(id, es->s_volume_name, 16); + volume_id_set_label_string(id, es->s_volume_name, 16); + volume_id_set_uuid(id, es->s_uuid, 0, UUID_DCE); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", + le32_to_cpu(es->s_rev_level), le16_to_cpu(es->s_minor_rev_level)); + + feature_compat = le32_to_cpu(es->s_feature_compat); + feature_incompat = le32_to_cpu(es->s_feature_incompat); + + /* check for external journal device */ + if ((feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) { + volume_id_set_usage(id, VOLUME_ID_OTHER); + id->type = "jbd"; + goto out; + } + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + + if ((feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) != 0 || + (feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) != 0 || + (feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) != 0) { + id->type = "ext4"; + goto out; + } + + if ((feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { + id->type = "ext3"; + goto out; + } + + id->type = "ext2"; + +out: + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/fat.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/fat.c new file mode 100644 index 0000000..54e6bab --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/fat.c @@ -0,0 +1,488 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004-2007 Kay Sievers + * Copyright (C) 2007 Ryan Lortie + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define FAT12_MAX 0xff5 +#define FAT16_MAX 0xfff5 +#define FAT_ATTR_VOLUME_ID 0x08 +#define FAT_ATTR_DIR 0x10 +#define FAT_ATTR_LONG_NAME 0x0f +#define FAT_ATTR_MASK 0x3f +#define FAT_ENTRY_FREE 0xe5 + +#define VFAT_LFN_SEQ_MASK 0x3f +#define VFAT_LFN_SEQ_LAST 0x40 +#define VFAT_LFN_SEQ_MAX 20 +#define VFAT_LFN_CHARS_PER_ENTRY (5 + 6 + 2) +#define VFAT_LOWERCASE_NAME 0x10 +#define VFAT_LOWERCASE_EXT 0x08 + +struct vfat_super_block { + uint8_t boot_jump[3]; + uint8_t sysid[8]; + uint16_t sector_size; + uint8_t sectors_per_cluster; + uint16_t reserved; + uint8_t fats; + uint16_t dir_entries; + uint16_t sectors; + uint8_t media; + uint16_t fat_length; + uint16_t secs_track; + uint16_t heads; + uint32_t hidden; + uint32_t total_sect; + union { + struct fat_super_block { + uint8_t unknown[3]; + uint8_t serno[4]; + uint8_t label[11]; + uint8_t magic[8]; + uint8_t dummy2[192]; + uint8_t pmagic[2]; + } PACKED fat; + struct fat32_super_block { + uint32_t fat32_length; + uint16_t flags; + uint8_t version[2]; + uint32_t root_cluster; + uint16_t fsinfo_sector; + uint16_t backup_boot; + uint16_t reserved2[6]; + uint8_t unknown[3]; + uint8_t serno[4]; + uint8_t label[11]; + uint8_t magic[8]; + uint8_t dummy2[164]; + uint8_t pmagic[2]; + } PACKED fat32; + } PACKED type; +} PACKED; + +struct fat32_fsinfo { + uint8_t signature1[4]; + uint32_t reserved1[120]; + uint8_t signature2[4]; + uint32_t free_clusters; + uint32_t next_cluster; + uint32_t reserved2[4]; +} PACKED; + +struct vfat_dir_entry { + uint8_t name[11]; + uint8_t attr; + uint8_t lowercase; + uint8_t fine_time_creat; + uint16_t time_creat; + uint16_t date_creat; + uint16_t date_acc; + uint16_t cluster_high; + uint16_t time_write; + uint16_t date_write; + uint16_t cluster_low; + uint32_t size; +} PACKED; + + +struct vfat_lfn_entry { + uint8_t seq; + uint16_t name0[5]; + uint8_t attr; + uint8_t reserved; + uint8_t cksum; + uint16_t name1[6]; + uint16_t cluster; + uint16_t name2[2]; +} PACKED; + +static uint8_t fat_lfn_checksum(const uint8_t name[11]) +{ + uint8_t cksum = 0; + int i; + + /* http://en.wikipedia.org/wiki/File_Allocation_Table */ + for (i = 0; i < 11; i++) + cksum = ((cksum & 1) ? 0x80 : 0) + (cksum >> 1) + name[i]; + + return cksum; +} + +static size_t fat_read_lfn(uint8_t *filename, size_t fnsize, + struct vfat_dir_entry *dir, + struct vfat_dir_entry *entry) +{ + uint8_t buffer[VFAT_LFN_SEQ_MAX * VFAT_LFN_CHARS_PER_ENTRY * 2]; + uint8_t expected_seq = 1; + uint8_t cksum; + size_t len = 0; + size_t fnlen = 0; + + cksum = fat_lfn_checksum(entry->name); + + while (--entry >= dir) { + struct vfat_lfn_entry *lfn = (struct vfat_lfn_entry *) entry; + + if (expected_seq > VFAT_LFN_SEQ_MAX) + break; + + if ((lfn->attr & FAT_ATTR_MASK) != FAT_ATTR_LONG_NAME) + break; + + if (lfn->cksum != cksum) + break; + + if ((lfn->seq & VFAT_LFN_SEQ_MASK) != expected_seq++) + break; + + if (lfn->cluster != 0) + break; + + /* extra paranoia -- should never happen */ + if (len + sizeof(lfn->name0) + sizeof(lfn->name1) + + sizeof(lfn->name2) > sizeof(buffer)) + break; + + memcpy (&buffer[len], lfn->name0, sizeof(lfn->name0)); + len += sizeof(lfn->name0); + memcpy (&buffer[len], lfn->name1, sizeof(lfn->name1)); + len += sizeof(lfn->name1); + memcpy (&buffer[len], lfn->name2, sizeof(lfn->name2)); + len += sizeof(lfn->name2); + + if (lfn->seq & VFAT_LFN_SEQ_LAST) { + fnlen = volume_id_set_unicode16(filename, fnsize, buffer, LE, len); + break; + } + } + + return fnlen; +} + +static size_t fat_read_filename(uint8_t *filename, size_t fnsize, + struct vfat_dir_entry *dir, struct vfat_dir_entry *entry) +{ + size_t len; + int i; + + /* check if maybe we have LFN entries */ + len = fat_read_lfn(filename, fnsize, dir, entry); + if (len > 0) + goto out; + + /* else, read the normal 8.3 name */ + for (i = 0; i < 11; i++) { + if (entry->lowercase & ((i < 8) ? VFAT_LOWERCASE_NAME : VFAT_LOWERCASE_EXT)) + filename[i] = tolower(entry->name[i]); + else + filename[i] = entry->name[i]; + } + len = 11; + +out: + filename[len] = '\0'; + return len; +} + +/* fills filename, returns string length */ +static size_t get_fat_attr_volume_id(uint8_t *filename, size_t fnsize, + struct vfat_dir_entry *dir, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) { + /* end marker */ + if (dir[i].name[0] == 0x00) { + dbg("end of dir"); + break; + } + + /* empty entry */ + if (dir[i].name[0] == FAT_ENTRY_FREE) + continue; + + /* long name */ + if ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME) + continue; + + if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { + /* labels do not have file data */ + if (dir[i].cluster_high != 0 || dir[i].cluster_low != 0) + continue; + + dbg("found ATTR_VOLUME_ID id in root dir"); + return fat_read_filename(filename, fnsize, dir, &dir[i]); + } + + dbg("skip dir entry"); + } + + return 0; +} + +int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size) +{ + uint8_t filename[255 * 3]; + struct vfat_super_block *vs; + struct vfat_dir_entry *dir; + struct fat32_fsinfo *fsinfo; + uint16_t sector_size; + uint16_t dir_entries; + uint32_t sect_count; + uint16_t reserved; + uint32_t fat_size; + uint32_t root_cluster; + uint32_t dir_size; + uint32_t cluster_count; + uint16_t fat_length; + uint32_t fat32_length; + uint64_t root_start; + uint32_t start_data_sect; + uint16_t root_dir_entries; + uint16_t fsinfo_sect; + uint8_t *buf; + uint32_t buf_size; + uint32_t next; + int maxloop; + size_t fnlen; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off, 0x400); + if (buf == NULL) + return -1; + + /* check signature */ + if (buf[510] != 0x55 || buf[511] != 0xaa) + return -1; + + vs = (struct vfat_super_block *) buf; + if (memcmp(vs->sysid, "NTFS", 4) == 0) + return -1; + + /* believe only that's fat, don't trust the version */ + if (memcmp(vs->type.fat32.magic, "MSWIN", 5) == 0) + goto magic; + + if (memcmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) + goto magic; + + if (memcmp(vs->type.fat.magic, "FAT16 ", 8) == 0) + goto magic; + + if (memcmp(vs->type.fat.magic, "MSDOS", 5) == 0) + goto magic; + + if (memcmp(vs->type.fat.magic, "FAT12 ", 8) == 0) + goto magic; + + /* some old floppies don't have a magic, expect the boot jump address to match */ + if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) && + vs->boot_jump[0] != 0xe9) + return -1; + +magic: + /* reserverd sector count */ + if (!vs->reserved) + return -1; + + /* fat count*/ + if (!vs->fats) + return -1; + + /* media check */ + if (vs->media < 0xf8 && vs->media != 0xf0) + return -1; + + /* cluster size check*/ + if (vs->sectors_per_cluster == 0 || + (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))) + return -1; + + /* sector size check */ + sector_size = le16_to_cpu(vs->sector_size); + if (sector_size != 0x200 && sector_size != 0x400 && + sector_size != 0x800 && sector_size != 0x1000) + return -1; + + dbg("sector_size 0x%x", sector_size); + dbg("sectors_per_cluster 0x%x", vs->sectors_per_cluster); + + dir_entries = le16_to_cpu(vs->dir_entries); + reserved = le16_to_cpu(vs->reserved); + dbg("reserved 0x%x", reserved); + + sect_count = le16_to_cpu(vs->sectors); + if (sect_count == 0) + sect_count = le32_to_cpu(vs->total_sect); + dbg("sect_count 0x%x", sect_count); + + fat_length = le16_to_cpu(vs->fat_length); + dbg("fat_length 0x%x", fat_length); + fat32_length = le32_to_cpu(vs->type.fat32.fat32_length); + dbg("fat32_length 0x%x", fat32_length); + + if (fat_length) + fat_size = fat_length * vs->fats; + else if (fat32_length) + fat_size = fat32_length * vs->fats; + else + return -1; + dbg("fat_size 0x%x", fat_size); + + dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) + + (sector_size-1)) / sector_size; + dbg("dir_size 0x%x", dir_size); + + cluster_count = sect_count - (reserved + fat_size + dir_size); + cluster_count /= vs->sectors_per_cluster; + dbg("cluster_count 0x%x", cluster_count); + + /* must be FAT32 */ + if (!fat_length && fat32_length) + goto fat32; + + /* cluster_count tells us the format */ + if (cluster_count < FAT12_MAX) + strcpy(id->type_version, "FAT12"); + else if (cluster_count < FAT16_MAX) + strcpy(id->type_version, "FAT16"); + else + goto fat32; + + /* the label may be an attribute in the root directory */ + root_start = (reserved + fat_size) * sector_size; + dbg("root dir start 0x%llx", (unsigned long long) root_start); + root_dir_entries = le16_to_cpu(vs->dir_entries); + dbg("expected entries 0x%x", root_dir_entries); + + buf_size = root_dir_entries * sizeof(struct vfat_dir_entry); + buf = volume_id_get_buffer(id, off + root_start, buf_size); + if (buf == NULL) + goto found; + + dir = (struct vfat_dir_entry*) buf; + + fnlen = get_fat_attr_volume_id(filename, sizeof(filename), dir, root_dir_entries); + + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + + if (fnlen > 0 && memcmp(filename, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, filename, fnlen); + volume_id_set_label_string(id, filename, fnlen); + } else if (memcmp(vs->type.fat.label, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, vs->type.fat.label, 11); + volume_id_set_label_string(id, vs->type.fat.label, 11); + } + volume_id_set_uuid(id, vs->type.fat.serno, 0, UUID_DOS); + goto found; + +fat32: + /* FAT32 should have a valid signature in the fsinfo block */ + fsinfo_sect = le16_to_cpu(vs->type.fat32.fsinfo_sector); + buf = volume_id_get_buffer(id, off + (fsinfo_sect * sector_size), 0x200); + if (buf == NULL) + return -1; + fsinfo = (struct fat32_fsinfo *) buf; + if (memcmp(fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0) + return -1; + if (memcmp(fsinfo->signature2, "\x72\x72\x41\x61", 4) != 0) + return -1 ; + + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + + strcpy(id->type_version, "FAT32"); + + /* FAT32 root dir is a cluster chain like any other directory */ + buf_size = vs->sectors_per_cluster * sector_size; + root_cluster = le32_to_cpu(vs->type.fat32.root_cluster); + dbg("root dir cluster %u", root_cluster); + start_data_sect = reserved + fat_size; + + next = root_cluster; + maxloop = 100; + while (--maxloop) { + uint32_t next_sect_off; + uint64_t next_off; + uint64_t fat_entry_off; + int count; + + dbg("next cluster %u", next); + next_sect_off = (next - 2) * vs->sectors_per_cluster; + next_off = (start_data_sect + next_sect_off) * sector_size; + dbg("cluster offset 0x%llx", (unsigned long long) next_off); + + /* get cluster */ + buf = volume_id_get_buffer(id, off + next_off, buf_size); + if (buf == NULL) + goto found; + + dir = (struct vfat_dir_entry*) buf; + count = buf_size / sizeof(struct vfat_dir_entry); + dbg("expected entries 0x%x", count); + + fnlen = get_fat_attr_volume_id(filename, sizeof(filename), dir, count); + if (fnlen > 0) + break; + + /* get FAT entry */ + fat_entry_off = (reserved * sector_size) + (next * sizeof(uint32_t)); + buf = volume_id_get_buffer(id, off + fat_entry_off, buf_size); + if (buf == NULL) + goto found; + + /* set next cluster */ + next = le32_to_cpu(*((uint32_t *) buf)) & 0x0fffffff; + if (next < 2 || next >= 0x0ffffff0) + break; + } + if (maxloop == 0) + dbg("reached maximum follow count of root cluster chain, give up"); + + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + + if (fnlen > 0 && memcmp(filename, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, filename, fnlen); + volume_id_set_label_string(id, filename, fnlen); + } else if (memcmp(vs->type.fat32.label, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, vs->type.fat32.label, 11); + volume_id_set_label_string(id, vs->type.fat32.label, 11); + } + volume_id_set_uuid(id, vs->type.fat32.serno, 0, UUID_DOS); + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "vfat"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/gfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/gfs.c new file mode 100644 index 0000000..1d3a4a0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/gfs.c @@ -0,0 +1,120 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2006 Red Hat, Inc. + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +/* Common gfs/gfs2 constants: */ +#define GFS_MAGIC 0x01161970 +#define GFS_DEFAULT_BSIZE 4096 +#define GFS_SUPERBLOCK_OFFSET (0x10 * GFS_DEFAULT_BSIZE) +#define GFS_METATYPE_SB 1 +#define GFS_FORMAT_SB 100 +#define GFS_LOCKNAME_LEN 64 + +/* gfs1 constants: */ +#define GFS_FORMAT_FS 1309 +#define GFS_FORMAT_MULTI 1401 +/* gfs2 constants: */ +#define GFS2_FORMAT_FS 1801 +#define GFS2_FORMAT_MULTI 1900 + +struct gfs2_meta_header { + uint32_t mh_magic; + uint32_t mh_type; + uint64_t __pad0; /* Was generation number in gfs1 */ + uint32_t mh_format; + uint32_t __pad1; /* Was incarnation number in gfs1 */ +}; + +struct gfs2_inum { + uint64_t no_formal_ino; + uint64_t no_addr; +}; + +struct gfs2_sb { + struct gfs2_meta_header sb_header; + + uint32_t sb_fs_format; + uint32_t sb_multihost_format; + uint32_t __pad0; /* Was superblock flags in gfs1 */ + + uint32_t sb_bsize; + uint32_t sb_bsize_shift; + uint32_t __pad1; /* Was journal segment size in gfs1 */ + + struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */ + struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */ + struct gfs2_inum sb_root_dir; + + char sb_lockproto[GFS_LOCKNAME_LEN]; + char sb_locktable[GFS_LOCKNAME_LEN]; + /* In gfs1, quota and license dinodes followed */ +} PACKED; + +static int volume_id_probe_gfs_generic(struct volume_id *id, uint64_t off, int vers) +{ + struct gfs2_sb *sbd; + + info("probing at offset 0x%llx", (unsigned long long) off); + + sbd = (struct gfs2_sb *) + volume_id_get_buffer(id, off + GFS_SUPERBLOCK_OFFSET, sizeof(struct gfs2_sb)); + if (sbd == NULL) + return -1; + + if (be32_to_cpu(sbd->sb_header.mh_magic) == GFS_MAGIC && + be32_to_cpu(sbd->sb_header.mh_type) == GFS_METATYPE_SB && + be32_to_cpu(sbd->sb_header.mh_format) == GFS_FORMAT_SB) { + if (vers == 1) { + if (be32_to_cpu(sbd->sb_fs_format) != GFS_FORMAT_FS || + be32_to_cpu(sbd->sb_multihost_format) != GFS_FORMAT_MULTI) + return -1; /* not gfs1 */ + id->type = "gfs"; + } + else if (vers == 2) { + if (be32_to_cpu(sbd->sb_fs_format) != GFS2_FORMAT_FS || + be32_to_cpu(sbd->sb_multihost_format) != GFS2_FORMAT_MULTI) + return -1; /* not gfs2 */ + id->type = "gfs2"; + } + else + return -1; + strcpy(id->type_version, "1"); + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + return 0; + } + return -1; +} + +int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + return volume_id_probe_gfs_generic(id, off, 1); +} + +int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size) +{ + return volume_id_probe_gfs_generic(id, off, 2); +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/hfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/hfs.c new file mode 100644 index 0000000..70a6b4a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/hfs.c @@ -0,0 +1,323 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct hfs_finder_info{ + uint32_t boot_folder; + uint32_t start_app; + uint32_t open_folder; + uint32_t os9_folder; + uint32_t reserved; + uint32_t osx_folder; + uint8_t id[8]; +} PACKED; + +static struct hfs_mdb { + uint8_t signature[2]; + uint32_t cr_date; + uint32_t ls_Mod; + uint16_t atrb; + uint16_t nm_fls; + uint16_t vbm_st; + uint16_t alloc_ptr; + uint16_t nm_al_blks; + uint32_t al_blk_size; + uint32_t clp_size; + uint16_t al_bl_st; + uint32_t nxt_cnid; + uint16_t free_bks; + uint8_t label_len; + uint8_t label[27]; + uint32_t vol_bkup; + uint16_t vol_seq_num; + uint32_t wr_cnt; + uint32_t xt_clump_size; + uint32_t ct_clump_size; + uint16_t num_root_dirs; + uint32_t file_count; + uint32_t dir_count; + struct hfs_finder_info finder_info; + uint8_t embed_sig[2]; + uint16_t embed_startblock; + uint16_t embed_blockcount; +} PACKED *hfs; + +struct hfsplus_bnode_descriptor { + uint32_t next; + uint32_t prev; + uint8_t type; + uint8_t height; + uint16_t num_recs; + uint16_t reserved; +} PACKED; + +struct hfsplus_bheader_record { + uint16_t depth; + uint32_t root; + uint32_t leaf_count; + uint32_t leaf_head; + uint32_t leaf_tail; + uint16_t node_size; +} PACKED; + +struct hfsplus_catalog_key { + uint16_t key_len; + uint32_t parent_id; + uint16_t unicode_len; + uint8_t unicode[255 * 2]; +} PACKED; + +struct hfsplus_extent { + uint32_t start_block; + uint32_t block_count; +} PACKED; + +#define HFSPLUS_EXTENT_COUNT 8 +struct hfsplus_fork { + uint64_t total_size; + uint32_t clump_size; + uint32_t total_blocks; + struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; +} PACKED; + +static struct hfsplus_vol_header { + uint8_t signature[2]; + uint16_t version; + uint32_t attributes; + uint32_t last_mount_vers; + uint32_t reserved; + uint32_t create_date; + uint32_t modify_date; + uint32_t backup_date; + uint32_t checked_date; + uint32_t file_count; + uint32_t folder_count; + uint32_t blocksize; + uint32_t total_blocks; + uint32_t free_blocks; + uint32_t next_alloc; + uint32_t rsrc_clump_sz; + uint32_t data_clump_sz; + uint32_t next_cnid; + uint32_t write_count; + uint64_t encodings_bmp; + struct hfs_finder_info finder_info; + struct hfsplus_fork alloc_file; + struct hfsplus_fork ext_file; + struct hfsplus_fork cat_file; + struct hfsplus_fork attr_file; + struct hfsplus_fork start_file; +} PACKED *hfsplus; + +#define HFS_SUPERBLOCK_OFFSET 0x400 +#define HFS_NODE_LEAF 0xff +#define HFSPLUS_POR_CNID 1 + +static void hfsid_set_uuid(struct volume_id *id, const uint8_t *hfs_id) +{ +#if 0 + MD5_CTX md5c; + static const uint8_t hash_init[16] = { + 0xb3, 0xe2, 0x0f, 0x39, 0xf2, 0x92, 0x11, 0xd6, + 0x97, 0xa4, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac + }; + uint8_t uuid[16]; + + if (*((uint64_t *)hfs_id) == 0) + return; + + MD5_Init(&md5c); + MD5_Update(&md5c, &hash_init, 16); + MD5_Update(&md5c, hfs_id, 8); + MD5_Final(uuid, &md5c); + + uuid[6] = 0x30 | (uuid[6] & 0x0f); + uuid[8] = 0x80 | (uuid[8] & 0x3f); + volume_id_set_uuid(id, uuid, UUID_DCE); +#endif + + volume_id_set_uuid(id, hfs_id, 0, UUID_64BIT_BE); +} + +int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size) +{ + unsigned int blocksize; + unsigned int cat_block; + unsigned int ext_block_start; + unsigned int ext_block_count; + int ext; + unsigned int leaf_node_head; + unsigned int leaf_node_count; + unsigned int leaf_node_size; + unsigned int leaf_block; + uint64_t leaf_off; + unsigned int alloc_block_size; + unsigned int alloc_first_block; + unsigned int embed_first_block; + unsigned int record_count; + struct hfsplus_bnode_descriptor *descr; + struct hfsplus_bheader_record *bnode; + struct hfsplus_catalog_key *key; + unsigned int label_len; + struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; + const uint8_t *buf; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + + hfs = (struct hfs_mdb *) buf; + if (memcmp(hfs->signature, "BD", 2) != 0) + goto checkplus; + + /* it may be just a hfs wrapper for hfs+ */ + if (memcmp(hfs->embed_sig, "H+", 2) == 0) { + alloc_block_size = be32_to_cpu(hfs->al_blk_size); + dbg("alloc_block_size 0x%x", alloc_block_size); + + alloc_first_block = be16_to_cpu(hfs->al_bl_st); + dbg("alloc_first_block 0x%x", alloc_first_block); + + embed_first_block = be16_to_cpu(hfs->embed_startblock); + dbg("embed_first_block 0x%x", embed_first_block); + + off += (alloc_first_block * 512) + + (embed_first_block * alloc_block_size); + dbg("hfs wrapped hfs+ found at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + goto checkplus; + } + + if (hfs->label_len > 0 && hfs->label_len < 28) { + volume_id_set_label_raw(id, hfs->label, hfs->label_len); + volume_id_set_label_string(id, hfs->label, hfs->label_len) ; + } + + hfsid_set_uuid(id, hfs->finder_info.id); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "hfs"; + + return 0; + +checkplus: + hfsplus = (struct hfsplus_vol_header *) buf; + if (memcmp(hfsplus->signature, "H+", 2) == 0) + goto hfsplus; + if (memcmp(hfsplus->signature, "HX", 2) == 0) + goto hfsplus; + return -1; + +hfsplus: + hfsid_set_uuid(id, hfsplus->finder_info.id); + + blocksize = be32_to_cpu(hfsplus->blocksize); + dbg("blocksize %u", blocksize); + + memcpy(extents, hfsplus->cat_file.extents, sizeof(extents)); + cat_block = be32_to_cpu(extents[0].start_block); + dbg("catalog start block 0x%x", cat_block); + + buf = volume_id_get_buffer(id, off + (cat_block * blocksize), 0x2000); + if (buf == NULL) + goto found; + + bnode = (struct hfsplus_bheader_record *) + &buf[sizeof(struct hfsplus_bnode_descriptor)]; + + leaf_node_head = be32_to_cpu(bnode->leaf_head); + dbg("catalog leaf node 0x%x", leaf_node_head); + + leaf_node_size = be16_to_cpu(bnode->node_size); + dbg("leaf node size 0x%x", leaf_node_size); + + leaf_node_count = be32_to_cpu(bnode->leaf_count); + dbg("leaf node count 0x%x", leaf_node_count); + if (leaf_node_count == 0) + goto found; + + leaf_block = (leaf_node_head * leaf_node_size) / blocksize; + + /* get physical location */ + for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) { + ext_block_start = be32_to_cpu(extents[ext].start_block); + ext_block_count = be32_to_cpu(extents[ext].block_count); + dbg("extent start block 0x%x, count 0x%x", ext_block_start, ext_block_count); + + if (ext_block_count == 0) + goto found; + + /* this is our extent */ + if (leaf_block < ext_block_count) + break; + + leaf_block -= ext_block_count; + } + if (ext == HFSPLUS_EXTENT_COUNT) + goto found; + dbg("found block in extent %i", ext); + + leaf_off = (ext_block_start + leaf_block) * blocksize; + + buf = volume_id_get_buffer(id, off + leaf_off, leaf_node_size); + if (buf == NULL) + goto found; + + descr = (struct hfsplus_bnode_descriptor *) buf; + dbg("descriptor type 0x%x", descr->type); + + record_count = be16_to_cpu(descr->num_recs); + dbg("number of records %u", record_count); + if (record_count == 0) + goto found; + + if (descr->type != HFS_NODE_LEAF) + goto found; + + key = (struct hfsplus_catalog_key *) + &buf[sizeof(struct hfsplus_bnode_descriptor)]; + + dbg("parent id 0x%x", be32_to_cpu(key->parent_id)); + if (be32_to_cpu(key->parent_id) != HFSPLUS_POR_CNID) + goto found; + + label_len = be16_to_cpu(key->unicode_len) * 2; + dbg("label unicode16 len %i", label_len); + volume_id_set_label_raw(id, key->unicode, label_len); + volume_id_set_label_unicode16(id, key->unicode, BE, label_len); + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "hfsplus"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/highpoint.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/highpoint.c new file mode 100644 index 0000000..f2c4069 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/highpoint.c @@ -0,0 +1,96 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct hpt37x_meta { + uint8_t filler1[32]; + uint32_t magic; +} PACKED; + +struct hpt45x_meta { + uint32_t magic; +} PACKED; + +#define HPT37X_CONFIG_OFF 0x1200 +#define HPT37X_MAGIC_OK 0x5a7816f0 +#define HPT37X_MAGIC_BAD 0x5a7816fd + +#define HPT45X_MAGIC_OK 0x5a7816f3 +#define HPT45X_MAGIC_BAD 0x5a7816fd + + +int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + struct hpt37x_meta *hpt; + uint32_t magic; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); + if (buf == NULL) + return -1; + + hpt = (struct hpt37x_meta *) buf; + magic = le32_to_cpu(hpt->magic); + if (magic != HPT37X_MAGIC_OK && magic != HPT37X_MAGIC_BAD) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "highpoint_raid_member"; + + return 0; +} + +int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + struct hpt45x_meta *hpt; + uint64_t meta_off; + uint32_t magic; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-11) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + hpt = (struct hpt45x_meta *) buf; + magic = le32_to_cpu(hpt->magic); + if (magic != HPT45X_MAGIC_OK && magic != HPT45X_MAGIC_BAD) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "highpoint_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/hpfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/hpfs.c new file mode 100644 index 0000000..edcf066 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/hpfs.c @@ -0,0 +1,56 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct hpfs_super +{ + uint8_t magic[4]; + uint8_t version; +} PACKED; + +#define HPFS_SUPERBLOCK_OFFSET 0x2000 + +int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct hpfs_super *hs; + + info("probing at offset 0x%llx", (unsigned long long) off); + + hs = (struct hpfs_super *) volume_id_get_buffer(id, off + HPFS_SUPERBLOCK_OFFSET, 0x200); + if (hs == NULL) + return -1; + + if (memcmp(hs->magic, "\x49\xe8\x95\xf9", 4) == 0) { + sprintf(id->type_version, "%u", hs->version); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "hpfs"; + return 0; + } + + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/iso9660.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/iso9660.c new file mode 100644 index 0000000..1d8bdff --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/iso9660.c @@ -0,0 +1,124 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define ISO_SUPERBLOCK_OFFSET 0x8000 +#define ISO_SECTOR_SIZE 0x800 +#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE) +#define ISO_VD_PRIMARY 0x1 +#define ISO_VD_SUPPLEMENTARY 0x2 +#define ISO_VD_END 0xff +#define ISO_VD_MAX 16 + +struct iso_volume_descriptor { + uint8_t type; + uint8_t id[5]; + uint8_t version; + uint8_t flags; + uint8_t system_id[32]; + uint8_t volume_id[32]; + uint8_t unused[8]; + uint8_t space_size[8]; + uint8_t escape_sequences[8]; +} PACKED; + +struct high_sierra_volume_descriptor { + uint8_t foo[8]; + uint8_t type; + uint8_t id[5]; + uint8_t version; +} PACKED; + +int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size) +{ + uint8_t *buf; + struct iso_volume_descriptor *is; + struct high_sierra_volume_descriptor *hs; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + + is = (struct iso_volume_descriptor *) buf; + + if (memcmp(is->id, "CD001", 5) == 0) { + int vd_offset; + int i; + + dbg("read label from PVD"); + volume_id_set_label_raw(id, is->volume_id, 32); + volume_id_set_label_string(id, is->volume_id, 32); + + dbg("looking for SVDs"); + vd_offset = ISO_VD_OFFSET; + for (i = 0; i < ISO_VD_MAX; i++) { + uint8_t svd_label[64]; + + is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200); + if (is == NULL || is->type == ISO_VD_END) + break; + if (is->type != ISO_VD_SUPPLEMENTARY) + continue; + + dbg("found SVD at offset 0x%llx", (unsigned long long) (off + vd_offset)); + if (memcmp(is->escape_sequences, "%/@", 3) == 0|| + memcmp(is->escape_sequences, "%/C", 3) == 0|| + memcmp(is->escape_sequences, "%/E", 3) == 0) { + dbg("Joliet extension found"); + volume_id_set_unicode16(svd_label, sizeof(svd_label), is->volume_id, BE, 32); + if (memcmp(id->label, svd_label, 16) == 0) { + dbg("SVD label is identical, use the possibly longer PVD one"); + break; + } + + volume_id_set_label_raw(id, is->volume_id, 32); + volume_id_set_label_string(id, svd_label, 32); + strcpy(id->type_version, "Joliet Extension"); + goto found; + } + vd_offset += ISO_SECTOR_SIZE; + } + goto found; + } + + hs = (struct high_sierra_volume_descriptor *) buf; + + if (memcmp(hs->id, "CDROM", 5) == 0) { + strcpy(id->type_version, "High Sierra"); + goto found; + } + + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "iso9660"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/isw_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/isw_raid.c new file mode 100644 index 0000000..f5761e8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/isw_raid.c @@ -0,0 +1,66 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct isw_meta { + uint8_t sig[32]; + uint32_t check_sum; + uint32_t mpb_size; + uint32_t family_num; + uint32_t generation_num; +} PACKED; + +#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " + + +int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t meta_off; + struct isw_meta *isw; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-2) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + isw = (struct isw_meta *) buf; + if (memcmp(isw->sig, ISW_SIGNATURE, sizeof(ISW_SIGNATURE)-1) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + memcpy(id->type_version, &isw->sig[sizeof(ISW_SIGNATURE)-1], 6); + id->type = "isw_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/jfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/jfs.c new file mode 100644 index 0000000..00b66cc --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/jfs.c @@ -0,0 +1,65 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct jfs_super_block { + uint8_t magic[4]; + uint32_t version; + uint64_t size; + uint32_t bsize; + uint32_t dummy1; + uint32_t pbsize; + uint32_t dummy2[27]; + uint8_t uuid[16]; + uint8_t label[16]; + uint8_t loguuid[16]; +} PACKED; + +#define JFS_SUPERBLOCK_OFFSET 0x8000 + +int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct jfs_super_block *js; + + info("probing at offset 0x%llx", (unsigned long long) off); + + js = (struct jfs_super_block *) volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200); + if (js == NULL) + return -1; + + if (memcmp(js->magic, "JFS1", 4) != 0) + return -1; + + volume_id_set_label_raw(id, js->label, 16); + volume_id_set_label_string(id, js->label, 16); + volume_id_set_uuid(id, js->uuid, 0, UUID_DCE); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "jfs"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/jmicron_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/jmicron_raid.c new file mode 100644 index 0000000..5182a3e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/jmicron_raid.c @@ -0,0 +1,62 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2006 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct jmicron_meta { + int8_t signature[2]; + uint8_t minor_version; + uint8_t major_version; + uint16_t checksum; +} PACKED; + +int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t meta_off; + struct jmicron_meta *jm; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + jm = (struct jmicron_meta *) buf; + if (memcmp(jm->signature, "JM", 2) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", jm->major_version, jm->minor_version); + id->type = "jmicron_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/libvolume_id.h b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/libvolume_id.h new file mode 100644 index 0000000..19aee68 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/libvolume_id.h @@ -0,0 +1,135 @@ +/* + * volume_id - reads volume label and uuid + * + * Copyright (C) 2005-2007 Kay Sievers + * + * 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 _LIBVOLUME_ID_H_ +#define _LIBVOLUME_ID_H_ + +#include +#include + +typedef void (*volume_id_log_fn_t)(int priority, const char *file, int line, const char *format, ...) + __attribute__ ((format(printf, 4, 5))); +extern volume_id_log_fn_t volume_id_log_fn; + +struct volume_id; +typedef int (*volume_id_probe_fn_t)(struct volume_id *id, uint64_t off, uint64_t size); +typedef int (*all_probers_fn_t)(volume_id_probe_fn_t probe_fn, + struct volume_id *id, uint64_t off, uint64_t size, + void *data); + +extern struct volume_id *volume_id_open_fd(int fd); +extern void volume_id_close(struct volume_id *id); +extern int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); +extern const volume_id_probe_fn_t *volume_id_get_prober_by_type(const char *type); +extern void volume_id_all_probers(all_probers_fn_t all_probers_fn, + struct volume_id *id, uint64_t off, uint64_t size, + void *data); +extern int volume_id_get_label(struct volume_id *id, const char **label); +extern int volume_id_get_label_raw(struct volume_id *id, const uint8_t **label, size_t *len); +extern int volume_id_get_uuid(struct volume_id *id, const char **uuid); +extern int volume_id_get_uuid_raw(struct volume_id *id, const uint8_t **uuid, size_t *len); +extern int volume_id_get_usage(struct volume_id *id, const char **usage); +extern int volume_id_get_type(struct volume_id *id, const char **type); +extern int volume_id_get_type_version(struct volume_id *id, const char **type_version); +extern int volume_id_encode_string(const char *str, char *str_enc, size_t len); + +/* + * Note: everything below will be made private or removed from + * a future version, and a new major release of libvolume_id + */ + +extern struct volume_id *volume_id_open_node(const char *path); + +#define VOLUME_ID_LABEL_SIZE 64 +#define VOLUME_ID_UUID_SIZE 36 +#define VOLUME_ID_FORMAT_SIZE 32 +#define VOLUME_ID_PATH_MAX 256 +#define VOLUME_ID_PARTITIONS_MAX 256 + +enum volume_id_usage { + VOLUME_ID_UNUSED, + VOLUME_ID_UNPROBED, + VOLUME_ID_OTHER, + VOLUME_ID_FILESYSTEM, + VOLUME_ID_RAID, + VOLUME_ID_DISKLABEL, + VOLUME_ID_CRYPTO, +}; + +struct volume_id { + uint8_t label_raw[VOLUME_ID_LABEL_SIZE]; + size_t label_raw_len; + char label[VOLUME_ID_LABEL_SIZE+1]; + uint8_t uuid_raw[VOLUME_ID_UUID_SIZE]; + size_t uuid_raw_len; + char uuid[VOLUME_ID_UUID_SIZE+1]; + enum volume_id_usage usage_id; + char *usage; + char *type; + char type_version[VOLUME_ID_FORMAT_SIZE]; + + int fd; + uint8_t *sbbuf; + size_t sbbuf_len; + uint8_t *seekbuf; + uint64_t seekbuf_off; + size_t seekbuf_len; + int fd_close:1; +}; + +/* filesystems */ +extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size); + +/* special formats */ +extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size); + +/* raid */ +extern int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size); + +/* bios raid */ +extern int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size); +extern int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size); + +#endif diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/linux_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/linux_raid.c new file mode 100644 index 0000000..6d1d19c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/linux_raid.c @@ -0,0 +1,164 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +static struct mdp0_super_block { + uint32_t md_magic; + uint32_t major_version; + uint32_t minor_version; + uint32_t patch_version; + uint32_t gvalid_words; + uint32_t set_uuid0; + uint32_t ctime; + uint32_t level; + uint32_t size; + uint32_t nr_disks; + uint32_t raid_disks; + uint32_t md_minor; + uint32_t not_persistent; + uint32_t set_uuid1; + uint32_t set_uuid2; + uint32_t set_uuid3; +} PACKED *mdp0; + +struct mdp1_super_block { + uint32_t magic; + uint32_t major_version; + uint32_t feature_map; + uint32_t pad0; + uint8_t set_uuid[16]; + uint8_t set_name[32]; +} PACKED *mdp1; + +#define MD_RESERVED_BYTES 0x10000 +#define MD_SB_MAGIC 0xa92b4efc + +static int volume_id_probe_linux_raid0(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + union { + uint32_t ints[4]; + uint8_t bytes[16]; + } uuid; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + if (size < 0x10000) + return -1; + + buf = volume_id_get_buffer(id, off, 0x800); + if (buf == NULL) + return -1; + mdp0 = (struct mdp0_super_block *) buf; + + if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { + uuid.ints[0] = bswap_32(mdp0->set_uuid0); + if (le32_to_cpu(mdp0->minor_version >= 90)) { + uuid.ints[1] = bswap_32(mdp0->set_uuid1); + uuid.ints[2] = bswap_32(mdp0->set_uuid2); + uuid.ints[3] = bswap_32(mdp0->set_uuid3); + } else { + uuid.ints[1] = 0; + uuid.ints[2] = 0; + uuid.ints[3] = 0; + } + volume_id_set_uuid(id, uuid.bytes, 0, UUID_FOURINT); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", + le32_to_cpu(mdp0->major_version), + le32_to_cpu(mdp0->minor_version), + le32_to_cpu(mdp0->patch_version)); + } else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { + uuid.ints[0] = mdp0->set_uuid0; + if (be32_to_cpu(mdp0->minor_version >= 90)) { + uuid.ints[1] = mdp0->set_uuid1; + uuid.ints[2] = mdp0->set_uuid2; + uuid.ints[3] = mdp0->set_uuid3; + } else { + uuid.ints[1] = 0; + uuid.ints[2] = 0; + uuid.ints[3] = 0; + } + volume_id_set_uuid(id, uuid.bytes, 0, UUID_FOURINT); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", + be32_to_cpu(mdp0->major_version), + be32_to_cpu(mdp0->minor_version), + be32_to_cpu(mdp0->patch_version)); + } else + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "linux_raid_member"; + return 0; +} + +static int volume_id_probe_linux_raid1(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + buf = volume_id_get_buffer(id, off, 0x800); + if (buf == NULL) + return -1; + mdp1 = (struct mdp1_super_block *) buf; + + if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC) + return -1; + + volume_id_set_uuid(id, mdp1->set_uuid, 0, UUID_FOURINT); + volume_id_set_label_raw(id, mdp1->set_name, 32); + volume_id_set_label_string(id, mdp1->set_name, 32); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", le32_to_cpu(mdp1->major_version)); + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "linux_raid_member"; + return 0; +} + +int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + uint64_t sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; + + /* version 0 at the end of the device */ + if (volume_id_probe_linux_raid0(id, off + sboff, size) == 0) + return 0; + + /* version 1.0 at the end of the device */ + if (volume_id_probe_linux_raid1(id, off + sboff, size) == 0) + return 0; + + /* version 1.1 at the start of the device */ + if (volume_id_probe_linux_raid1(id, off, size) == 0) + return 0; + + /* version 1.2 at 4k offset from the start */ + if (volume_id_probe_linux_raid1(id, off + 0x1000, size) == 0) + return 0; + + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/linux_swap.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/linux_swap.c new file mode 100644 index 0000000..50d43cc --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/linux_swap.c @@ -0,0 +1,90 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct swap_header_v1_2 { + uint8_t bootbits[1024]; + uint32_t version; + uint32_t last_page; + uint32_t nr_badpages; + uint8_t uuid[16]; + uint8_t volume_name[16]; +} PACKED; + +#define LARGEST_PAGESIZE 0x4000 + +int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + unsigned int page; + struct swap_header_v1_2 *sw; + + info("probing at offset 0x%llx", (unsigned long long) off); + + /* eek, the swap signature is at the end of the PAGE_SIZE */ + for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { + buf = volume_id_get_buffer(id, off + page-10, 10); + if (buf == NULL) + return -1; + + if (memcmp(buf, "SWAP-SPACE", 10) == 0) { + strcpy(id->type_version, "1"); + goto found; + } + + if (memcmp(buf, "SWAPSPACE2", 10) == 0) { + id->type = "swap"; + strcpy(id->type_version, "2"); + goto found_label; + } + + if (memcmp(buf, "S1SUSPEND", 9) == 0) { + id->type = "suspend"; + strcpy(id->type_version, "s1suspend"); + goto found_label; + } + + if (memcmp(buf, "ULSUSPEND", 9) == 0) { + id->type = "suspend"; + strcpy(id->type_version, "ulsuspend"); + goto found_label; + } + } + return -1; + +found_label: + sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); + if (sw != NULL) { + volume_id_set_label_raw(id, sw->volume_name, 16); + volume_id_set_label_string(id, sw->volume_name, 16); + volume_id_set_uuid(id, sw->uuid, 0, UUID_DCE); + } + +found: + volume_id_set_usage(id, VOLUME_ID_OTHER); + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/lsi_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/lsi_raid.c new file mode 100644 index 0000000..56fd567 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/lsi_raid.c @@ -0,0 +1,60 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct lsi_meta { + uint8_t sig[6]; +} PACKED; + +#define LSI_SIGNATURE "$XIDE$" + +int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t meta_off; + struct lsi_meta *lsi; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + lsi = (struct lsi_meta *) buf; + if (memcmp(lsi->sig, LSI_SIGNATURE, sizeof(LSI_SIGNATURE)-1) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "lsi_mega_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/luks.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/luks.c new file mode 100644 index 0000000..231374e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/luks.c @@ -0,0 +1,80 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 W. Michael Petullo + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define SECTOR_SHIFT 9 +#define SECTOR_SIZE (1 << SECTOR_SHIFT) + +#define LUKS_CIPHERNAME_L 32 +#define LUKS_CIPHERMODE_L 32 +#define LUKS_HASHSPEC_L 32 +#define LUKS_DIGESTSIZE 20 +#define LUKS_SALTSIZE 32 +#define LUKS_NUMKEYS 8 + +#define LUKS_MAGIC_L 6 +#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1) +#define UUID_STRING_L 40 +static const uint8_t LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; + +struct luks_phdr { + uint8_t magic[LUKS_MAGIC_L]; + uint16_t version; + uint8_t cipherName[LUKS_CIPHERNAME_L]; + uint8_t cipherMode[LUKS_CIPHERMODE_L]; + uint8_t hashSpec[LUKS_HASHSPEC_L]; + uint32_t payloadOffset; + uint32_t keyBytes; + uint8_t mkDigest[LUKS_DIGESTSIZE]; + uint8_t mkDigestSalt[LUKS_SALTSIZE]; + uint32_t mkDigestIterations; + uint8_t uuid[UUID_STRING_L]; + struct { + uint32_t active; + uint32_t passwordIterations; + uint8_t passwordSalt[LUKS_SALTSIZE]; + uint32_t keyMaterialOffset; + uint32_t stripes; + } keyblock[LUKS_NUMKEYS]; +}; + +int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct luks_phdr *header; + + header = (struct luks_phdr*) volume_id_get_buffer(id, off, LUKS_PHDR_SIZE); + if (header == NULL) + return -1; + + if (memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) + return -1; + + volume_id_set_usage(id, VOLUME_ID_CRYPTO); + volume_id_set_uuid(id, header->uuid, 36, UUID_HEX_STRING); + id->type = "crypto_LUKS"; + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/lvm.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/lvm.c new file mode 100644 index 0000000..9c83c55 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/lvm.c @@ -0,0 +1,97 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct lvm1_super_block { + uint8_t id[2]; +} PACKED; + +struct lvm2_super_block { + uint8_t id[8]; + uint64_t sector_xl; + uint32_t crc_xl; + uint32_t offset_xl; + uint8_t type[8]; +} PACKED; + +#define LVM1_SB_OFF 0x400 +#define LVM1_MAGIC "HM" + +int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + struct lvm1_super_block *lvm; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800); + if (buf == NULL) + return -1; + + lvm = (struct lvm1_super_block *) buf; + + if (memcmp(lvm->id, LVM1_MAGIC, 2) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "LVM1_member"; + + return 0; +} + +#define LVM2_LABEL_ID "LABELONE" +#define LVM2LABEL_SCAN_SECTORS 4 + +int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + unsigned int soff; + struct lvm2_super_block *lvm; + + dbg("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off, LVM2LABEL_SCAN_SECTORS * 0x200); + if (buf == NULL) + return -1; + + + for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) { + lvm = (struct lvm2_super_block *) &buf[soff]; + + if (memcmp(lvm->id, LVM2_LABEL_ID, 8) == 0) + goto found; + } + + return -1; + +found: + memcpy(id->type_version, lvm->type, 8); + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "LVM2_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/minix.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/minix.c new file mode 100644 index 0000000..6494506 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/minix.c @@ -0,0 +1,117 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005-2007 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define MINIX_SUPERBLOCK_OFFSET 0x400 + +#define MINIX_SUPER_MAGIC 0x137F +#define MINIX_SUPER_MAGIC2 0x138F +#define MINIX2_SUPER_MAGIC 0x2468 +#define MINIX2_SUPER_MAGIC2 0x2478 +#define MINIX3_SUPER_MAGIC 0x4d5a + +struct minix_super_block +{ + uint16_t s_ninodes; + uint16_t s_nzones; + uint16_t s_imap_blocks; + uint16_t s_zmap_blocks; + uint16_t s_firstdatazone; + uint16_t s_log_zone_size; + uint32_t s_max_size; + uint16_t s_magic; + uint16_t s_state; + uint32_t s_zones; +} PACKED; + +struct minix3_super_block { + uint32_t s_ninodes; + uint16_t s_pad0; + uint16_t s_imap_blocks; + uint16_t s_zmap_blocks; + uint16_t s_firstdatazone; + uint16_t s_log_zone_size; + uint16_t s_pad1; + uint32_t s_max_size; + uint32_t s_zones; + uint16_t s_magic; + uint16_t s_pad2; + uint16_t s_blocksize; + uint8_t s_disk_version; +} PACKED; + +int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size) +{ + uint8_t *buf; + struct minix_super_block *ms; + struct minix3_super_block *m3s; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + + ms = (struct minix_super_block *) buf; + + if (ms->s_magic == MINIX_SUPER_MAGIC || + ms->s_magic == bswap_16(MINIX_SUPER_MAGIC)) { + strcpy(id->type_version, "1"); + goto found; + } + if (ms->s_magic == MINIX_SUPER_MAGIC2 || + ms->s_magic == bswap_16(MINIX_SUPER_MAGIC2)) { + strcpy(id->type_version, "1"); + goto found; + } + if (ms->s_magic == MINIX2_SUPER_MAGIC || + ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC)) { + strcpy(id->type_version, "2"); + goto found; + } + if (ms->s_magic == MINIX2_SUPER_MAGIC2 || + ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC2)) { + strcpy(id->type_version, "2"); + goto found; + } + + m3s = (struct minix3_super_block *) buf; + if (m3s->s_magic == MINIX3_SUPER_MAGIC || + m3s->s_magic == bswap_16(MINIX3_SUPER_MAGIC)) { + strcpy(id->type_version, "3"); + goto found; + } + goto exit; + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "minix"; + return 0; + +exit: + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/netware.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/netware.c new file mode 100644 index 0000000..4d157aa --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/netware.c @@ -0,0 +1,103 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2006 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define NW_SUPERBLOCK_OFFSET 0x1000 + +struct netware_super_block { + uint8_t SBH_Signature[4]; + uint16_t SBH_VersionMajor; + uint16_t SBH_VersionMinor; + uint16_t SBH_VersionMediaMajor; + uint16_t SBH_VersionMediaMinor; + uint32_t SBH_ItemsMoved; + uint8_t SBH_InternalID[16]; + uint32_t SBH_PackedSize; + uint32_t SBH_Checksum; + uint32_t supersyncid; + int64_t superlocation[4]; + uint32_t physSizeUsed; + uint32_t sizeUsed; + uint32_t superTimeStamp; + uint32_t reserved0[1]; + int64_t SBH_LoggedPoolDataBlk; + int64_t SBH_PoolDataBlk; + uint8_t SBH_OldInternalID[16]; + uint32_t SBH_PoolToLVStartUTC; + uint32_t SBH_PoolToLVEndUTC; + uint16_t SBH_VersionMediaMajorCreate; + uint16_t SBH_VersionMediaMinorCreate; + uint32_t SBH_BlocksMoved; + uint32_t SBH_TempBTSpBlk; + uint32_t SBH_TempFTSpBlk; + uint32_t SBH_TempFTSpBlk1; + uint32_t SBH_TempFTSpBlk2; + uint32_t nssMagicNumber; + uint32_t poolClassID; + uint32_t poolID; + uint32_t createTime; + int64_t SBH_LoggedVolumeDataBlk; + int64_t SBH_VolumeDataBlk; + int64_t SBH_SystemBeastBlkNum; + uint64_t totalblocks; + uint16_t SBH_Name[64]; + uint8_t SBH_VolumeID[16]; + uint8_t SBH_PoolID[16]; + uint8_t SBH_PoolInternalID[16]; + uint64_t SBH_Lsn; + uint32_t SBH_SS_Enabled; + uint32_t SBH_SS_CreateTime; + uint8_t SBH_SS_OriginalPoolID[16]; + uint8_t SBH_SS_OriginalVolumeID[16]; + uint8_t SBH_SS_Guid[16]; + uint16_t SBH_SS_OriginalName[64]; + uint32_t reserved2[64-(2+46)]; +} PACKED; + +int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct netware_super_block *nw; + + info("probing at offset 0x%llx", (unsigned long long) off); + + nw = (struct netware_super_block *) volume_id_get_buffer(id, off + NW_SUPERBLOCK_OFFSET, 0x200); + if (nw == NULL) + return -1; + + if (memcmp(nw->SBH_Signature, "SPB5", 4) != 0) + return -1; + + volume_id_set_uuid(id, nw->SBH_PoolID, 0, UUID_DCE); + + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%02u", + le16_to_cpu(nw->SBH_VersionMediaMajor), le16_to_cpu(nw->SBH_VersionMediaMinor)); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "nss"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ntfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ntfs.c new file mode 100644 index 0000000..9262454 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ntfs.c @@ -0,0 +1,194 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +static struct ntfs_super_block { + uint8_t jump[3]; + uint8_t oem_id[8]; + uint16_t bytes_per_sector; + uint8_t sectors_per_cluster; + uint16_t reserved_sectors; + uint8_t fats; + uint16_t root_entries; + uint16_t sectors; + uint8_t media_type; + uint16_t sectors_per_fat; + uint16_t sectors_per_track; + uint16_t heads; + uint32_t hidden_sectors; + uint32_t large_sectors; + uint16_t unused[2]; + uint64_t number_of_sectors; + uint64_t mft_cluster_location; + uint64_t mft_mirror_cluster_location; + int8_t cluster_per_mft_record; + uint8_t reserved1[3]; + int8_t cluster_per_index_record; + uint8_t reserved2[3]; + uint8_t volume_serial[8]; + uint16_t checksum; +} PACKED *ns; + +static struct master_file_table_record { + uint8_t magic[4]; + uint16_t usa_ofs; + uint16_t usa_count; + uint64_t lsn; + uint16_t sequence_number; + uint16_t link_count; + uint16_t attrs_offset; + uint16_t flags; + uint32_t bytes_in_use; + uint32_t bytes_allocated; +} PACKED *mftr; + +static struct file_attribute { + uint32_t type; + uint32_t len; + uint8_t non_resident; + uint8_t name_len; + uint16_t name_offset; + uint16_t flags; + uint16_t instance; + uint32_t value_len; + uint16_t value_offset; +} PACKED *attr; + +static struct volume_info { + uint64_t reserved; + uint8_t major_ver; + uint8_t minor_ver; +} PACKED *info; + +#define MFT_RECORD_VOLUME 3 +#define MFT_RECORD_ATTR_VOLUME_NAME 0x60 +#define MFT_RECORD_ATTR_VOLUME_INFO 0x70 +#define MFT_RECORD_ATTR_OBJECT_ID 0x40 +#define MFT_RECORD_ATTR_END 0xffffffffu + +int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + unsigned int sector_size; + unsigned int cluster_size; + uint64_t mft_cluster; + uint64_t mft_off; + unsigned int mft_record_size; + unsigned int attr_type; + unsigned int attr_off; + unsigned int attr_len; + unsigned int val_off; + unsigned int val_len; + const uint8_t *buf; + const uint8_t *val; + + info("probing at offset 0x%llx", (unsigned long long) off); + + ns = (struct ntfs_super_block *) volume_id_get_buffer(id, off, 0x200); + if (ns == NULL) + return -1; + + if (memcmp(ns->oem_id, "NTFS", 4) != 0) + return -1; + + volume_id_set_uuid(id, ns->volume_serial, 0, UUID_64BIT_LE); + + sector_size = le16_to_cpu(ns->bytes_per_sector); + cluster_size = ns->sectors_per_cluster * sector_size; + mft_cluster = le64_to_cpu(ns->mft_cluster_location); + mft_off = mft_cluster * cluster_size; + + if (ns->cluster_per_mft_record < 0) + /* size = -log2(mft_record_size); normally 1024 Bytes */ + mft_record_size = 1 << -ns->cluster_per_mft_record; + else + mft_record_size = ns->cluster_per_mft_record * cluster_size; + + dbg("sectorsize 0x%x", sector_size); + dbg("clustersize 0x%x", cluster_size); + dbg("mftcluster %llu", (unsigned long long) mft_cluster); + dbg("mftoffset 0x%llx", (unsigned long long) mft_off); + dbg("cluster per mft_record %i", ns->cluster_per_mft_record); + dbg("mft record size %i", mft_record_size); + + buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size), + mft_record_size); + if (buf == NULL) + goto found; + + mftr = (struct master_file_table_record*) buf; + + dbg("mftr->magic '%c%c%c%c'", mftr->magic[0], mftr->magic[1], mftr->magic[2], mftr->magic[3]); + if (memcmp(mftr->magic, "FILE", 4) != 0) + goto found; + + attr_off = le16_to_cpu(mftr->attrs_offset); + dbg("file $Volume's attributes are at offset %i", attr_off); + + while (1) { + attr = (struct file_attribute*) &buf[attr_off]; + attr_type = le32_to_cpu(attr->type); + attr_len = le16_to_cpu(attr->len); + val_off = le16_to_cpu(attr->value_offset); + val_len = le32_to_cpu(attr->value_len); + attr_off += attr_len; + + if (attr_len == 0) + break; + + if (attr_off >= mft_record_size) + break; + + if (attr_type == MFT_RECORD_ATTR_END) + break; + + dbg("found attribute type 0x%x, len %i, at offset %i", + attr_type, attr_len, attr_off); + + if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { + dbg("found info, len %i", val_len); + info = (struct volume_info*) (((uint8_t *) attr) + val_off); + snprintf(id->type_version, sizeof(id->type_version)-1, + "%u.%u", info->major_ver, info->minor_ver); + } + + if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) { + dbg("found label, len %i", val_len); + if (val_len > VOLUME_ID_LABEL_SIZE) + val_len = VOLUME_ID_LABEL_SIZE; + + val = ((uint8_t *) attr) + val_off; + volume_id_set_label_raw(id, val, val_len); + volume_id_set_label_unicode16(id, val, LE, val_len); + } + } + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "ntfs"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/nvidia_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/nvidia_raid.c new file mode 100644 index 0000000..ca42459 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/nvidia_raid.c @@ -0,0 +1,64 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct nvidia_meta { + uint8_t vendor[8]; + uint32_t size; + uint32_t chksum; + uint16_t version; +} PACKED; + +#define NVIDIA_SIGNATURE "NVIDIA" + +int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t meta_off; + struct nvidia_meta *nv; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-2) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + nv = (struct nvidia_meta *) buf; + if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", le16_to_cpu(nv->version)); + id->type = "nvidia_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ocfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ocfs.c new file mode 100644 index 0000000..9f251f1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ocfs.c @@ -0,0 +1,194 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Andre Masella + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + + +struct ocfs1_super_block_header { + uint32_t minor_version; + uint32_t major_version; + uint8_t signature[128]; + uint8_t mount_point[128]; + uint64_t serial_num; + uint64_t device_size; + uint64_t start_off; + uint64_t bitmap_off; + uint64_t publ_off; + uint64_t vote_off; + uint64_t root_bitmap_off; + uint64_t data_start_off; + uint64_t root_bitmap_size; + uint64_t root_off; + uint64_t root_size; + uint64_t cluster_size; + uint64_t num_nodes; + uint64_t num_clusters; + uint64_t dir_node_size; + uint64_t file_node_size; + uint64_t internal_off; + uint64_t node_cfg_off; + uint64_t node_cfg_size; + uint64_t new_cfg_off; + uint32_t prot_bits; + int32_t excl_mount; +} PACKED; + +struct ocfs1_super_block_label { + struct ocfs1_disk_lock { + uint32_t curr_master; + uint8_t file_lock; + uint8_t compat_pad[3]; + uint64_t last_write_time; + uint64_t last_read_time; + uint32_t writer_node_num; + uint32_t reader_node_num; + uint64_t oin_node_map; + uint64_t dlock_seq_num; + } PACKED disk_lock; + uint8_t label[64]; + uint16_t label_len; + uint8_t vol_id[16]; + uint16_t vol_id_len; + uint8_t cluster_name[64]; + uint16_t cluster_name_len; +} PACKED; + +struct ocfs2_super_block { + uint8_t i_signature[8]; + uint32_t i_generation; + int16_t i_suballoc_slot; + uint16_t i_suballoc_bit; + uint32_t i_reserved0; + uint32_t i_clusters; + uint32_t i_uid; + uint32_t i_gid; + uint64_t i_size; + uint16_t i_mode; + uint16_t i_links_count; + uint32_t i_flags; + uint64_t i_atime; + uint64_t i_ctime; + uint64_t i_mtime; + uint64_t i_dtime; + uint64_t i_blkno; + uint64_t i_last_eb_blk; + uint32_t i_fs_generation; + uint32_t i_atime_nsec; + uint32_t i_ctime_nsec; + uint32_t i_mtime_nsec; + uint64_t i_reserved1[9]; + uint64_t i_pad1; + uint16_t s_major_rev_level; + uint16_t s_minor_rev_level; + uint16_t s_mnt_count; + int16_t s_max_mnt_count; + uint16_t s_state; + uint16_t s_errors; + uint32_t s_checkinterval; + uint64_t s_lastcheck; + uint32_t s_creator_os; + uint32_t s_feature_compat; + uint32_t s_feature_incompat; + uint32_t s_feature_ro_compat; + uint64_t s_root_blkno; + uint64_t s_system_dir_blkno; + uint32_t s_blocksize_bits; + uint32_t s_clustersize_bits; + uint16_t s_max_slots; + uint16_t s_reserved1; + uint32_t s_reserved2; + uint64_t s_first_cluster_group; + uint8_t s_label[64]; + uint8_t s_uuid[16]; +} PACKED; + +int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + struct ocfs1_super_block_header *osh; + struct ocfs1_super_block_label *osl; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off, 0x200); + if (buf == NULL) + return -1; + + osh = (struct ocfs1_super_block_header *) buf; + if (memcmp(osh->signature, "OracleCFS", 9) != 0) + return -1; + snprintf(id->type_version, sizeof(id->type_version)-1, + "%u.%u", osh->major_version, osh->minor_version); + + dbg("found OracleCFS signature, now reading label"); + buf = volume_id_get_buffer(id, off + 0x200, 0x200); + if (buf == NULL) + return -1; + + osl = (struct ocfs1_super_block_label *) buf; + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + if (osl->label_len <= 64) { + volume_id_set_label_raw(id, osl->label, 64); + volume_id_set_label_string(id, osl->label, 64); + } + if (osl->vol_id_len == 16) + volume_id_set_uuid(id, osl->vol_id, 0, UUID_DCE); + id->type = "ocfs"; + return 0; +} + +#define OCFS2_MAX_BLOCKSIZE 0x1000 +#define OCFS2_SUPER_BLOCK_BLKNO 2 + +int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + struct ocfs2_super_block *os; + size_t blksize; + + info("probing at offset 0x%llx", (unsigned long long) off); + + for (blksize = 0x200; blksize <= OCFS2_MAX_BLOCKSIZE; blksize <<= 1) { + buf = volume_id_get_buffer(id, off + OCFS2_SUPER_BLOCK_BLKNO * blksize, 0x200); + if (buf == NULL) + return -1; + + os = (struct ocfs2_super_block *) buf; + if (memcmp(os->i_signature, "OCFSV2", 6) != 0) + continue; + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + volume_id_set_label_raw(id, os->s_label, 64); + volume_id_set_label_string(id, os->s_label, 64); + volume_id_set_uuid(id, os->s_uuid, 0, UUID_DCE); + snprintf(id->type_version, sizeof(id->type_version)-1, + "%u.%u", os->s_major_rev_level, os->s_minor_rev_level); + id->type = "ocfs2"; + return 0; + } + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/promise_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/promise_raid.c new file mode 100644 index 0000000..1c4d365 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/promise_raid.c @@ -0,0 +1,70 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct promise_meta { + uint8_t sig[24]; +} PACKED; + +#define PDC_CONFIG_OFF 0x1200 +#define PDC_SIGNATURE "Promise Technology, Inc." + +int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + struct promise_meta *pdc; + unsigned int i; + static unsigned int sectors[] = { + 63, 255, 256, 16, 399, 0 + }; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x40000) + return -1; + + for (i = 0; sectors[i] != 0; i++) { + uint64_t meta_off; + + meta_off = ((size / 0x200) - sectors[i]) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + pdc = (struct promise_meta *) buf; + if (memcmp(pdc->sig, PDC_SIGNATURE, sizeof(PDC_SIGNATURE)-1) == 0) + goto found; + } + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "promise_fasttrack_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/reiserfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/reiserfs.c new file mode 100644 index 0000000..18db638 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/reiserfs.c @@ -0,0 +1,118 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2005 Tobias Klauser + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct reiserfs_super_block { + uint32_t blocks_count; + uint32_t free_blocks; + uint32_t root_block; + uint32_t journal_block; + uint32_t journal_dev; + uint32_t orig_journal_size; + uint32_t dummy2[5]; + uint16_t blocksize; + uint16_t dummy3[3]; + uint8_t magic[12]; + uint32_t dummy4[5]; + uint8_t uuid[16]; + uint8_t label[16]; +} PACKED; + +struct reiser4_super_block { + uint8_t magic[16]; + uint16_t dummy[2]; + uint8_t uuid[16]; + uint8_t label[16]; + uint64_t dummy2; +} PACKED; + +#define REISERFS1_SUPERBLOCK_OFFSET 0x2000 +#define REISERFS_SUPERBLOCK_OFFSET 0x10000 + +int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct reiserfs_super_block *rs; + struct reiser4_super_block *rs4; + uint8_t *buf; + + info("probing at offset 0x%llx", (unsigned long long) off); + + buf = volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + + rs = (struct reiserfs_super_block *) buf; + if (memcmp(rs->magic, "ReIsErFs", 8) == 0) { + strcpy(id->type_version, "3.5"); + id->type = "reiserfs"; + goto found; + } + if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) { + strcpy(id->type_version, "3.6"); + id->type = "reiserfs"; + goto found_label; + } + if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) { + strcpy(id->type_version, "JR"); + id->type = "reiserfs"; + goto found_label; + } + + rs4 = (struct reiser4_super_block *) buf; + if (memcmp(rs4->magic, "ReIsEr4", 7) == 0) { + strcpy(id->type_version, "4"); + volume_id_set_label_raw(id, rs4->label, 16); + volume_id_set_label_string(id, rs4->label, 16); + volume_id_set_uuid(id, rs4->uuid, 0, UUID_DCE); + id->type = "reiser4"; + goto found; + } + + buf = volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + + rs = (struct reiserfs_super_block *) buf; + if (memcmp(rs->magic, "ReIsErFs", 8) == 0) { + strcpy(id->type_version, "3.5"); + id->type = "reiserfs"; + goto found; + } + + return -1; + +found_label: + volume_id_set_label_raw(id, rs->label, 16); + volume_id_set_label_string(id, rs->label, 16); + volume_id_set_uuid(id, rs->uuid, 0, UUID_DCE); + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/romfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/romfs.c new file mode 100644 index 0000000..2db36d6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/romfs.c @@ -0,0 +1,60 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct romfs_super { + uint8_t magic[8]; + uint32_t size; + uint32_t checksum; + uint8_t name[0]; +} PACKED; + +int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct romfs_super *rfs; + + info("probing at offset 0x%llx", (unsigned long long) off); + + rfs = (struct romfs_super *) volume_id_get_buffer(id, off, 0x200); + if (rfs == NULL) + return -1; + + if (memcmp(rfs->magic, "-rom1fs-", 4) == 0) { + size_t len = strlen((char *)rfs->name); + + if (len) { + volume_id_set_label_raw(id, rfs->name, len); + volume_id_set_label_string(id, rfs->name, len); + } + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "romfs"; + return 0; + } + + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/silicon_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/silicon_raid.c new file mode 100644 index 0000000..634e4ab --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/silicon_raid.c @@ -0,0 +1,77 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct silicon_meta { + uint8_t unknown0[0x2E]; + uint8_t ascii_version[0x36 - 0x2E]; + uint8_t diskname[0x56 - 0x36]; + uint8_t unknown1[0x60 - 0x56]; + uint32_t magic; + uint32_t unknown1a[0x6C - 0x64]; + uint32_t array_sectors_low; + uint32_t array_sectors_high; + uint8_t unknown2[0x78 - 0x74]; + uint32_t thisdisk_sectors; + uint8_t unknown3[0x100 - 0x7C]; + uint8_t unknown4[0x104 - 0x100]; + uint16_t product_id; + uint16_t vendor_id; + uint16_t minor_ver; + uint16_t major_ver; +} PACKED; + +#define SILICON_MAGIC 0x2F000000 + +int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t meta_off; + struct silicon_meta *sil; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + sil = (struct silicon_meta *) buf; + if (le32_to_cpu(sil->magic) != SILICON_MAGIC) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", + le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); + id->type = "silicon_medley_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/squashfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/squashfs.c new file mode 100644 index 0000000..99cc78a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/squashfs.c @@ -0,0 +1,52 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2006 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define SQUASHFS_MAGIC 0x73717368 + +struct squashfs_super { + uint32_t s_magic; +} PACKED; + +int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct squashfs_super *sqs; + + info("probing at offset 0x%llx", (unsigned long long) off); + + sqs = (struct squashfs_super *) volume_id_get_buffer(id, off + 0x200, 0x200); + if (sqs == NULL) + return -1; + + if (sqs->s_magic == SQUASHFS_MAGIC || sqs->s_magic == bswap_32(SQUASHFS_MAGIC)) { + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "squashfs"; + return 0; + } + + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/sysv.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/sysv.c new file mode 100644 index 0000000..e48013c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/sysv.c @@ -0,0 +1,133 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define SYSV_NICINOD 100 +#define SYSV_NICFREE 50 + +struct sysv_super +{ + uint16_t s_isize; + uint16_t s_pad0; + uint32_t s_fsize; + uint16_t s_nfree; + uint16_t s_pad1; + uint32_t s_free[SYSV_NICFREE]; + uint16_t s_ninode; + uint16_t s_pad2; + uint16_t s_inode[SYSV_NICINOD]; + uint8_t s_flock; + uint8_t s_ilock; + uint8_t s_fmod; + uint8_t s_ronly; + uint32_t s_time; + uint16_t s_dinfo[4]; + uint32_t s_tfree; + uint16_t s_tinode; + uint16_t s_pad3; + uint8_t s_fname[6]; + uint8_t s_fpack[6]; + uint32_t s_fill[12]; + uint32_t s_state; + uint32_t s_magic; + uint32_t s_type; +} PACKED; + +#define XENIX_NICINOD 100 +#define XENIX_NICFREE 100 + +struct xenix_super { + uint16_t s_isize; + uint32_t s_fsize; + uint16_t s_nfree; + uint32_t s_free[XENIX_NICFREE]; + uint16_t s_ninode; + uint16_t s_inode[XENIX_NICINOD]; + uint8_t s_flock; + uint8_t s_ilock; + uint8_t s_fmod; + uint8_t s_ronly; + uint32_t s_time; + uint32_t s_tfree; + uint16_t s_tinode; + uint16_t s_dinfo[4]; + uint8_t s_fname[6]; + uint8_t s_fpack[6]; + uint8_t s_clean; + uint8_t s_fill[371]; + uint32_t s_magic; + uint32_t s_type; +} PACKED; + +#define SYSV_SUPERBLOCK_BLOCK 0x01 +#define SYSV_MAGIC 0xfd187e20 +#define XENIX_SUPERBLOCK_BLOCK 0x18 +#define XENIX_MAGIC 0x2b5544 +#define SYSV_MAX_BLOCKSIZE 0x800 + +int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct sysv_super *vs; + struct xenix_super *xs; + unsigned int boff; + + info("probing at offset 0x%llx", (unsigned long long) off); + + for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { + vs = (struct sysv_super *) + volume_id_get_buffer(id, off + (boff * SYSV_SUPERBLOCK_BLOCK), 0x200); + if (vs == NULL) + return -1; + + if (vs->s_magic == cpu_to_le32(SYSV_MAGIC) || vs->s_magic == cpu_to_be32(SYSV_MAGIC)) { + volume_id_set_label_raw(id, vs->s_fname, 6); + volume_id_set_label_string(id, vs->s_fname, 6); + id->type = "sysv"; + goto found; + } + } + + for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { + xs = (struct xenix_super *) + volume_id_get_buffer(id, off + (boff + XENIX_SUPERBLOCK_BLOCK), 0x200); + if (xs == NULL) + return -1; + + if (xs->s_magic == cpu_to_le32(XENIX_MAGIC) || xs->s_magic == cpu_to_be32(XENIX_MAGIC)) { + volume_id_set_label_raw(id, xs->s_fname, 6); + volume_id_set_label_string(id, xs->s_fname, 6); + id->type = "xenix"; + goto found; + } + } + + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/udf.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/udf.c new file mode 100644 index 0000000..ac2f40a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/udf.c @@ -0,0 +1,178 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct volume_descriptor { + struct descriptor_tag { + uint16_t id; + uint16_t version; + uint8_t checksum; + uint8_t reserved; + uint16_t serial; + uint16_t crc; + uint16_t crc_len; + uint32_t location; + } PACKED tag; + union { + struct anchor_descriptor { + uint32_t length; + uint32_t location; + } PACKED anchor; + struct primary_descriptor { + uint32_t seq_num; + uint32_t desc_num; + struct dstring { + uint8_t clen; + uint8_t c[31]; + } PACKED ident; + } PACKED primary; + } PACKED type; +} PACKED; + +struct volume_structure_descriptor { + uint8_t type; + uint8_t id[5]; + uint8_t version; +} PACKED; + +#define UDF_VSD_OFFSET 0x8000 + +int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct volume_descriptor *vd; + struct volume_structure_descriptor *vsd; + unsigned int bs; + unsigned int b; + unsigned int type; + unsigned int count; + unsigned int loc; + unsigned int clen; + + info("probing at offset 0x%llx", (unsigned long long) off); + + vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200); + if (vsd == NULL) + return -1; + + if (memcmp(vsd->id, "NSR02", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "NSR03", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "BEA01", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "BOOT2", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "CD001", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "CDW02", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "TEA03", 5) == 0) + goto blocksize; + return -1; + +blocksize: + /* search the next VSD to get the logical block size of the volume */ + for (bs = 0x800; bs < 0x8000; bs += 0x800) { + vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + bs, 0x800); + if (vsd == NULL) + return -1; + dbg("test for blocksize: 0x%x", bs); + if (vsd->id[0] != '\0') + goto nsr; + } + return -1; + +nsr: + /* search the list of VSDs for a NSR descriptor */ + for (b = 0; b < 64; b++) { + vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + (b * bs), 0x800); + if (vsd == NULL) + return -1; + + dbg("vsd: %c%c%c%c%c", + vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]); + + if (vsd->id[0] == '\0') + return -1; + if (memcmp(vsd->id, "NSR02", 5) == 0) + goto anchor; + if (memcmp(vsd->id, "NSR03", 5) == 0) + goto anchor; + } + return -1; + +anchor: + /* read anchor volume descriptor */ + vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + (256 * bs), 0x200); + if (vd == NULL) + return -1; + + type = le16_to_cpu(vd->tag.id); + if (type != 2) /* TAG_ID_AVDP */ + goto found; + + /* get desriptor list address and block count */ + count = le32_to_cpu(vd->type.anchor.length) / bs; + loc = le32_to_cpu(vd->type.anchor.location); + dbg("0x%x descriptors starting at logical secor 0x%x", count, loc); + + /* pick the primary descriptor from the list */ + for (b = 0; b < count; b++) { + vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + ((loc + b) * bs), 0x200); + if (vd == NULL) + return -1; + + type = le16_to_cpu(vd->tag.id); + dbg("descriptor type %i", type); + + /* check validity */ + if (type == 0) + goto found; + if (le32_to_cpu(vd->tag.location) != loc + b) + goto found; + + if (type == 1) /* TAG_ID_PVD */ + goto pvd; + } + goto found; + +pvd: + volume_id_set_label_raw(id, &(vd->type.primary.ident.clen), 32); + + clen = vd->type.primary.ident.clen; + dbg("label string charsize=%i bit", clen); + if (clen == 8) + volume_id_set_label_string(id, vd->type.primary.ident.c, 31); + else if (clen == 16) + volume_id_set_label_unicode16(id, vd->type.primary.ident.c, BE,31); + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "udf"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ufs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ufs.c new file mode 100644 index 0000000..4ace8c9 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/ufs.c @@ -0,0 +1,222 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct ufs_super_block { + uint32_t fs_link; + uint32_t fs_rlink; + uint32_t fs_sblkno; + uint32_t fs_cblkno; + uint32_t fs_iblkno; + uint32_t fs_dblkno; + uint32_t fs_cgoffset; + uint32_t fs_cgmask; + uint32_t fs_time; + uint32_t fs_size; + uint32_t fs_dsize; + uint32_t fs_ncg; + uint32_t fs_bsize; + uint32_t fs_fsize; + uint32_t fs_frag; + uint32_t fs_minfree; + uint32_t fs_rotdelay; + uint32_t fs_rps; + uint32_t fs_bmask; + uint32_t fs_fmask; + uint32_t fs_bshift; + uint32_t fs_fshift; + uint32_t fs_maxcontig; + uint32_t fs_maxbpg; + uint32_t fs_fragshift; + uint32_t fs_fsbtodb; + uint32_t fs_sbsize; + uint32_t fs_csmask; + uint32_t fs_csshift; + uint32_t fs_nindir; + uint32_t fs_inopb; + uint32_t fs_nspf; + uint32_t fs_optim; + uint32_t fs_npsect_state; + uint32_t fs_interleave; + uint32_t fs_trackskew; + uint32_t fs_id[2]; + uint32_t fs_csaddr; + uint32_t fs_cssize; + uint32_t fs_cgsize; + uint32_t fs_ntrak; + uint32_t fs_nsect; + uint32_t fs_spc; + uint32_t fs_ncyl; + uint32_t fs_cpg; + uint32_t fs_ipg; + uint32_t fs_fpg; + struct ufs_csum { + uint32_t cs_ndir; + uint32_t cs_nbfree; + uint32_t cs_nifree; + uint32_t cs_nffree; + } PACKED fs_cstotal; + int8_t fs_fmod; + int8_t fs_clean; + int8_t fs_ronly; + int8_t fs_flags; + union { + struct { + int8_t fs_fsmnt[512]; + uint32_t fs_cgrotor; + uint32_t fs_csp[31]; + uint32_t fs_maxcluster; + uint32_t fs_cpc; + uint16_t fs_opostbl[16][8]; + } PACKED fs_u1; + struct { + int8_t fs_fsmnt[468]; + uint8_t fs_volname[32]; + uint64_t fs_swuid; + int32_t fs_pad; + uint32_t fs_cgrotor; + uint32_t fs_ocsp[28]; + uint32_t fs_contigdirs; + uint32_t fs_csp; + uint32_t fs_maxcluster; + uint32_t fs_active; + int32_t fs_old_cpc; + int32_t fs_maxbsize; + int64_t fs_sparecon64[17]; + int64_t fs_sblockloc; + struct ufs2_csum_total { + uint64_t cs_ndir; + uint64_t cs_nbfree; + uint64_t cs_nifree; + uint64_t cs_nffree; + uint64_t cs_numclusters; + uint64_t cs_spare[3]; + } PACKED fs_cstotal; + struct ufs_timeval { + int32_t tv_sec; + int32_t tv_usec; + } PACKED fs_time; + int64_t fs_size; + int64_t fs_dsize; + uint64_t fs_csaddr; + int64_t fs_pendingblocks; + int32_t fs_pendinginodes; + } PACKED fs_u2; + } fs_u11; + union { + struct { + int32_t fs_sparecon[53]; + int32_t fs_reclaim; + int32_t fs_sparecon2[1]; + int32_t fs_state; + uint32_t fs_qbmask[2]; + uint32_t fs_qfmask[2]; + } PACKED fs_sun; + struct { + int32_t fs_sparecon[53]; + int32_t fs_reclaim; + int32_t fs_sparecon2[1]; + uint32_t fs_npsect; + uint32_t fs_qbmask[2]; + uint32_t fs_qfmask[2]; + } PACKED fs_sunx86; + struct { + int32_t fs_sparecon[50]; + int32_t fs_contigsumsize; + int32_t fs_maxsymlinklen; + int32_t fs_inodefmt; + uint32_t fs_maxfilesize[2]; + uint32_t fs_qbmask[2]; + uint32_t fs_qfmask[2]; + int32_t fs_state; + } PACKED fs_44; + } fs_u2; + int32_t fs_postblformat; + int32_t fs_nrpos; + int32_t fs_postbloff; + int32_t fs_rotbloff; + uint32_t fs_magic; + uint8_t fs_space[1]; +} PACKED; + +#define UFS_MAGIC 0x00011954 +#define UFS2_MAGIC 0x19540119 +#define UFS_MAGIC_FEA 0x00195612 +#define UFS_MAGIC_LFN 0x00095014 + +int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size) +{ + uint32_t magic; + int i; + struct ufs_super_block *ufs; + int offsets[] = {0, 8, 64, 256, -1}; + + info("probing at offset 0x%llx", (unsigned long long) off); + + for (i = 0; offsets[i] >= 0; i++) { + ufs = (struct ufs_super_block *) volume_id_get_buffer(id, off + (offsets[i] * 0x400), 0x800); + if (ufs == NULL) + return -1; + + dbg("offset 0x%x", offsets[i] * 0x400); + magic = be32_to_cpu(ufs->fs_magic); + if ((magic == UFS_MAGIC) || + (magic == UFS2_MAGIC) || + (magic == UFS_MAGIC_FEA) || + (magic == UFS_MAGIC_LFN)) { + dbg("magic 0x%08x(be)", magic); + goto found; + } + magic = le32_to_cpu(ufs->fs_magic); + if ((magic == UFS_MAGIC) || + (magic == UFS2_MAGIC) || + (magic == UFS_MAGIC_FEA) || + (magic == UFS_MAGIC_LFN)) { + dbg("magic 0x%08x(le)", magic); + goto found; + } + } + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "ufs"; + switch (magic) { + case UFS_MAGIC: + strcpy(id->type_version, "1"); + break; + case UFS2_MAGIC: + strcpy(id->type_version, "2"); + volume_id_set_label_raw(id, ufs->fs_u11.fs_u2.fs_volname, 32); + volume_id_set_label_string(id, ufs->fs_u11.fs_u2.fs_volname, 32); + break; + default: + break; + } + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/util.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/util.c new file mode 100644 index 0000000..395e81b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/util.c @@ -0,0 +1,426 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005-2007 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +/* count of characters used to encode one unicode char */ +static int utf8_encoded_expected_len(const char *str) +{ + unsigned char c = (unsigned char)str[0]; + + if (c < 0x80) + return 1; + if ((c & 0xe0) == 0xc0) + return 2; + if ((c & 0xf0) == 0xe0) + return 3; + if ((c & 0xf8) == 0xf0) + return 4; + if ((c & 0xfc) == 0xf8) + return 5; + if ((c & 0xfe) == 0xfc) + return 6; + return 0; +} + +/* decode one unicode char */ +static int utf8_encoded_to_unichar(const char *str) +{ + int unichar; + int len; + int i; + + len = utf8_encoded_expected_len(str); + switch (len) { + case 1: + return (int)str[0]; + case 2: + unichar = str[0] & 0x1f; + break; + case 3: + unichar = (int)str[0] & 0x0f; + break; + case 4: + unichar = (int)str[0] & 0x07; + break; + case 5: + unichar = (int)str[0] & 0x03; + break; + case 6: + unichar = (int)str[0] & 0x01; + break; + default: + return -1; + } + + for (i = 1; i < len; i++) { + if (((int)str[i] & 0xc0) != 0x80) + return -1; + unichar <<= 6; + unichar |= (int)str[i] & 0x3f; + } + + return unichar; +} + +/* expected size used to encode one unicode char */ +static int utf8_unichar_to_encoded_len(int unichar) +{ + if (unichar < 0x80) + return 1; + if (unichar < 0x800) + return 2; + if (unichar < 0x10000) + return 3; + if (unichar < 0x200000) + return 4; + if (unichar < 0x4000000) + return 5; + return 6; +} + +/* check if unicode char has a valid numeric range */ +static int utf8_unichar_valid_range(int unichar) +{ + if (unichar > 0x10ffff) + return 0; + if ((unichar & 0xfffff800) == 0xd800) + return 0; + if ((unichar > 0xfdcf) && (unichar < 0xfdf0)) + return 0; + if ((unichar & 0xffff) == 0xffff) + return 0; + return 1; +} + +/* validate one encoded unicode char and return its length */ +int volume_id_utf8_encoded_valid_unichar(const char *str) +{ + int len; + int unichar; + int i; + + len = utf8_encoded_expected_len(str); + if (len == 0) + return -1; + + /* ascii is valid */ + if (len == 1) + return 1; + + /* check if expected encoded chars are available */ + for (i = 0; i < len; i++) + if ((str[i] & 0x80) != 0x80) + return -1; + + unichar = utf8_encoded_to_unichar(str); + + /* check if encoded length matches encoded value */ + if (utf8_unichar_to_encoded_len(unichar) != len) + return -1; + + /* check if value has valid range */ + if (!utf8_unichar_valid_range(unichar)) + return -1; + + return len; +} + +size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count) +{ + size_t i, j; + uint16_t c; + + j = 0; + for (i = 0; i + 2 <= count; i += 2) { + if (endianess == LE) + c = (buf[i+1] << 8) | buf[i]; + else + c = (buf[i] << 8) | buf[i+1]; + if (c == 0) { + str[j] = '\0'; + break; + } else if (c < 0x80) { + if (j+1 >= len) + break; + str[j++] = (uint8_t) c; + } else if (c < 0x800) { + if (j+2 >= len) + break; + str[j++] = (uint8_t) (0xc0 | (c >> 6)); + str[j++] = (uint8_t) (0x80 | (c & 0x3f)); + } else { + if (j+3 >= len) + break; + str[j++] = (uint8_t) (0xe0 | (c >> 12)); + str[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); + str[j++] = (uint8_t) (0x80 | (c & 0x3f)); + } + } + str[j] = '\0'; + return j; +} + +static char *usage_to_string(enum volume_id_usage usage_id) +{ + switch (usage_id) { + case VOLUME_ID_FILESYSTEM: + return "filesystem"; + case VOLUME_ID_OTHER: + return "other"; + case VOLUME_ID_RAID: + return "raid"; + case VOLUME_ID_DISKLABEL: + return "disklabel"; + case VOLUME_ID_CRYPTO: + return "crypto"; + case VOLUME_ID_UNPROBED: + return "unprobed"; + case VOLUME_ID_UNUSED: + return "unused"; + } + return NULL; +} + +void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id) +{ + id->usage_id = usage_id; + id->usage = usage_to_string(usage_id); +} + +void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count) +{ + if (count > sizeof(id->label)) + count = sizeof(id->label); + + memcpy(id->label_raw, buf, count); + id->label_raw_len = count; +} + +void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count) +{ + size_t i; + + if (count >= sizeof(id->label)) + count = sizeof(id->label)-1; + + memcpy(id->label, buf, count); + id->label[count] = '\0'; + + /* remove trailing whitespace */ + i = strnlen(id->label, count); + while (i--) { + if (!isspace(id->label[i])) + break; + } + id->label[i+1] = '\0'; +} + +void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count) +{ + if (count >= sizeof(id->label)) + count = sizeof(id->label)-1; + + volume_id_set_unicode16((uint8_t *)id->label, sizeof(id->label), buf, endianess, count); +} + +void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format) +{ + unsigned int i; + unsigned int count = 0; + + if (len > sizeof(id->uuid_raw)) + len = sizeof(id->uuid_raw); + + switch(format) { + case UUID_STRING: + count = len; + break; + case UUID_HEX_STRING: + count = len; + break; + case UUID_DOS: + count = 4; + break; + case UUID_64BIT_LE: + case UUID_64BIT_BE: + count = 8; + break; + case UUID_DCE: + count = 16; + break; + case UUID_FOURINT: + count = 35; + break; + } + memcpy(id->uuid_raw, buf, count); + id->uuid_raw_len = count; + + /* if set, create string in the same format, the native platform uses */ + for (i = 0; i < count; i++) + if (buf[i] != 0) + goto set; + return; + +set: + switch(format) { + case UUID_DOS: + sprintf(id->uuid, "%02X%02X-%02X%02X", + buf[3], buf[2], buf[1], buf[0]); + break; + case UUID_64BIT_LE: + sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X", + buf[7], buf[6], buf[5], buf[4], + buf[3], buf[2], buf[1], buf[0]); + break; + case UUID_64BIT_BE: + sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + break; + case UUID_DCE: + sprintf(id->uuid, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], + buf[6], buf[7], + buf[8], buf[9], + buf[10], buf[11], buf[12], buf[13], buf[14],buf[15]); + break; + case UUID_HEX_STRING: + /* translate A..F to a..f */ + memcpy(id->uuid, buf, count); + for (i = 0; i < count; i++) + if (id->uuid[i] >= 'A' && id->uuid[i] <= 'F') + id->uuid[i] = (id->uuid[i] - 'A') + 'a'; + id->uuid[count] = '\0'; + break; + case UUID_STRING: + memcpy(id->uuid, buf, count); + id->uuid[count] = '\0'; + break; + case UUID_FOURINT: + sprintf(id->uuid, + "%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7], + buf[8], buf[9], buf[10], buf[11], + buf[12], buf[13], buf[14],buf[15]); + break; + } +} + +uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) +{ + ssize_t buf_len; + + info("get buffer off 0x%llx(%llu), len 0x%zx", (unsigned long long) off, (unsigned long long) off, len); + /* check if requested area fits in superblock buffer */ + if (off + len <= SB_BUFFER_SIZE) { + if (id->sbbuf == NULL) { + id->sbbuf = malloc(SB_BUFFER_SIZE); + if (id->sbbuf == NULL) { + dbg("error malloc"); + return NULL; + } + } + + /* check if we need to read */ + if ((off + len) > id->sbbuf_len) { + info("read sbbuf len:0x%llx", (unsigned long long) (off + len)); + if (lseek(id->fd, 0, SEEK_SET) < 0) { + dbg("lseek failed (%s)", strerror(errno)); + return NULL; + } + buf_len = read(id->fd, id->sbbuf, off + len); + if (buf_len < 0) { + dbg("read failed (%s)", strerror(errno)); + return NULL; + } + dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); + id->sbbuf_len = buf_len; + if ((size_t)buf_len < off + len) { + dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); + return NULL; + } + } + + return &(id->sbbuf[off]); + } else { + if (len > SEEK_BUFFER_SIZE) { + dbg("seek buffer too small %d", SEEK_BUFFER_SIZE); + return NULL; + } + + /* get seek buffer */ + if (id->seekbuf == NULL) { + id->seekbuf = malloc(SEEK_BUFFER_SIZE); + if (id->seekbuf == NULL) { + dbg("error malloc"); + return NULL; + } + } + + /* check if we need to read */ + if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { + info("read seekbuf off:0x%llx len:0x%zx", (unsigned long long) off, len); + if (lseek(id->fd, off, SEEK_SET) < 0) { + dbg("lseek failed (%s)", strerror(errno)); + return NULL; + } + buf_len = read(id->fd, id->seekbuf, len); + if (buf_len < 0) { + dbg("read failed (%s)", strerror(errno)); + return NULL; + } + dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); + id->seekbuf_off = off; + id->seekbuf_len = buf_len; + if ((size_t)buf_len < len) { + dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); + return NULL; + } + } + + return &(id->seekbuf[off - id->seekbuf_off]); + } +} + +void volume_id_free_buffer(struct volume_id *id) +{ + if (id->sbbuf != NULL) { + free(id->sbbuf); + id->sbbuf = NULL; + id->sbbuf_len = 0; + } + if (id->seekbuf != NULL) { + free(id->seekbuf); + id->seekbuf = NULL; + id->seekbuf_len = 0; + } +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/util.h b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/util.h new file mode 100644 index 0000000..14a76c8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/util.h @@ -0,0 +1,93 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005-2006 Kay Sievers + * + * 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 _VOLUME_ID_UTIL_ +#define _VOLUME_ID_UTIL_ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define ALLOWED_CHARS "#+-.:=@_" + +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif + +#define err(format, arg...) volume_id_log_fn(LOG_ERR, __FILE__, __LINE__, format, ##arg) +#define info(format, arg...) volume_id_log_fn(LOG_INFO, __FILE__, __LINE__, format, ##arg) +#ifdef DEBUG +#define dbg(format, arg...) volume_id_log_fn(LOG_DEBUG, __FILE__, __LINE__, format, ##arg) +#else +#define dbg(format, arg...) do { } while (0) +#endif + +/* size of superblock buffer, reiserfs block is at 64k */ +#define SB_BUFFER_SIZE 0x11000 +/* size of seek buffer, FAT cluster is 32k max */ +#define SEEK_BUFFER_SIZE 0x10000 + +#ifdef __BYTE_ORDER +#if (__BYTE_ORDER == __LITTLE_ENDIAN) +#define le16_to_cpu(x) (x) +#define le32_to_cpu(x) (x) +#define le64_to_cpu(x) (x) +#define be16_to_cpu(x) bswap_16(x) +#define be32_to_cpu(x) bswap_32(x) +#define cpu_to_le16(x) (x) +#define cpu_to_le32(x) (x) +#define cpu_to_be32(x) bswap_32(x) +#elif (__BYTE_ORDER == __BIG_ENDIAN) +#define le16_to_cpu(x) bswap_16(x) +#define le32_to_cpu(x) bswap_32(x) +#define le64_to_cpu(x) bswap_64(x) +#define be16_to_cpu(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_le16(x) bswap_16(x) +#define cpu_to_le32(x) bswap_32(x) +#define cpu_to_be32(x) (x) +#endif +#endif /* __BYTE_ORDER */ + +enum uuid_format { + UUID_STRING, + UUID_HEX_STRING, + UUID_DCE, + UUID_DOS, + UUID_64BIT_LE, + UUID_64BIT_BE, + UUID_FOURINT, +}; + +enum endian { + LE = 0, + BE = 1 +}; + +extern int volume_id_utf8_encoded_valid_unichar(const char *str); +extern size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count); +extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id); +extern void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count); +extern void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count); +extern void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count); +extern void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format); +extern uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len); +extern void volume_id_free_buffer(struct volume_id *id); + +#endif /* _VOLUME_ID_UTIL_ */ + diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/via_raid.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/via_raid.c new file mode 100644 index 0000000..62c165e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/via_raid.c @@ -0,0 +1,93 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * Based on information taken from dmraid: + * Copyright (C) 2004-2006 Heinz Mauelshagen, Red Hat GmbH + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct via_meta { + uint16_t signature; + uint8_t version_number; + struct via_array { + uint16_t disk_bit_mask; + uint8_t disk_array_ex; + uint32_t capacity_low; + uint32_t capacity_high; + uint32_t serial_checksum; + } PACKED array; + uint32_t serial_checksum[8]; + uint8_t checksum; +} PACKED; + +#define VIA_SIGNATURE 0xAA55 + +/* 8 bit checksum on first 50 bytes of metadata. */ +static uint8_t meta_checksum(struct via_meta *via) +{ + uint8_t i = 50, sum = 0; + + while (i--) + sum += ((uint8_t*) via)[i]; + + return sum == via->checksum; +} + + +int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t meta_off; + struct via_meta *via; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + via = (struct via_meta *) buf; + if (le16_to_cpu(via->signature) != VIA_SIGNATURE) + return -1; + + if (via->version_number > 1) + return -1; + + if (!meta_checksum(via)) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", via->version_number); + id->type = "via_raid_member"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/volume_id.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/volume_id.c new file mode 100644 index 0000000..59303d5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/volume_id.c @@ -0,0 +1,510 @@ +/* + * volume_id - reads volume label and uuid + * + * Copyright (C) 2005-2007 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +struct prober { + volume_id_probe_fn_t prober; + const char *name[4]; +}; + +static const struct prober prober_raid[] = { + { volume_id_probe_linux_raid, { "linux_raid", } }, + { volume_id_probe_ddf_raid, { "ddf_raid", } }, + { volume_id_probe_intel_software_raid, { "isw_raid", } }, + { volume_id_probe_lsi_mega_raid, { "lsi_mega_raid", } }, + { volume_id_probe_via_raid, { "via_raid", } }, + { volume_id_probe_silicon_medley_raid, { "silicon_medley_raid", } }, + { volume_id_probe_nvidia_raid, { "nvidia_raid", } }, + { volume_id_probe_promise_fasttrack_raid, { "promise_fasttrack_raid", } }, + { volume_id_probe_highpoint_45x_raid, { "highpoint_raid", } }, + { volume_id_probe_adaptec_raid, { "adaptec_raid", } }, + { volume_id_probe_jmicron_raid, { "jmicron_raid", } }, + { volume_id_probe_lvm1, { "lvm1", } }, + { volume_id_probe_lvm2, { "lvm2", } }, + { volume_id_probe_highpoint_37x_raid, { "highpoint_raid", } }, +}; + +static const struct prober prober_filesystem[] = { + { volume_id_probe_vfat, { "vfat", } }, + { volume_id_probe_linux_swap, { "swap", } }, + { volume_id_probe_luks, { "luks", } }, + { volume_id_probe_xfs, { "xfs", } }, + { volume_id_probe_ext, { "ext2", "ext3", "jbd", } }, + { volume_id_probe_reiserfs, { "reiserfs", "reiser4", } }, + { volume_id_probe_jfs, { "jfs", } }, + { volume_id_probe_udf, { "udf", } }, + { volume_id_probe_iso9660, { "iso9660", } }, + { volume_id_probe_hfs_hfsplus, { "hfs", "hfsplus", } }, + { volume_id_probe_ufs, { "ufs", } }, + { volume_id_probe_ntfs, { "ntfs", } }, + { volume_id_probe_cramfs, { "cramfs", } }, + { volume_id_probe_romfs, { "romfs", } }, + { volume_id_probe_hpfs, { "hpfs", } }, + { volume_id_probe_sysv, { "sysv", "xenix", } }, + { volume_id_probe_minix, { "minix", } }, + { volume_id_probe_ocfs1, { "ocfs1", } }, + { volume_id_probe_ocfs2, { "ocfs2", } }, + { volume_id_probe_vxfs, { "vxfs", } }, + { volume_id_probe_squashfs, { "squashfs", } }, + { volume_id_probe_netware, { "netware", } }, +}; + +/* the user can overwrite this log function */ +static void default_log(int priority, const char *file, int line, const char *format, ...) +{ + return; +} + +volume_id_log_fn_t volume_id_log_fn = default_log; + +/** + * volume_id_get_label: + * @type: Type string. + * + * Lookup the probing function for a specific type. + * + * Returns: The probing function for the given type, #NULL otherwise. + **/ +const volume_id_probe_fn_t *volume_id_get_prober_by_type(const char *type) +{ + unsigned int p, n; + + if (type == NULL) + return NULL; + + for (p = 0; p < ARRAY_SIZE(prober_raid); p++) + for (n = 0; prober_raid[p].name[n] != NULL; n++) + if (strcmp(type, prober_raid[p].name[n]) == 0) + return &prober_raid[p].prober; + for (p = 0; p < ARRAY_SIZE(prober_filesystem); p++) + for (n = 0; prober_filesystem[p].name[n] != NULL; n++) + if (strcmp(type, prober_filesystem[p].name[n]) == 0) + return &prober_filesystem[p].prober; + return NULL; +} + +/** + * volume_id_get_label: + * @id: Probing context. + * @label: Label string. Must not be freed by the caller. + * + * Get the label string after a successful probe. Unicode + * is translated to UTF-8. + * + * Returns: 1 if the value was set, 0 otherwise. + **/ +int volume_id_get_label(struct volume_id *id, const char **label) +{ + if (id == NULL) + return 0; + if (label == NULL) + return 0; + if (id->usage_id == VOLUME_ID_UNUSED) + return 0; + + *label = id->label; + return 1; +} + +/** + * volume_id_get_label_raw: + * @id: Probing context. + * @label: Label byte array. Must not be freed by the caller. + * @len: Length of raw label byte array. + * + * Get the raw label byte array after a successful probe. It may + * contain undecoded multibyte character streams. + * + * Returns: 1 if the value was set, 0 otherwise. + **/ +int volume_id_get_label_raw(struct volume_id *id, const uint8_t **label, size_t *len) +{ + if (id == NULL) + return 0; + if (label == NULL) + return 0; + if (len == NULL) + return 0; + if (id->usage_id == VOLUME_ID_UNUSED) + return 0; + + *label = id->label_raw; + *len = id->label_raw_len; + return 1; +} + +/** + * volume_id_get_uuid: + * @id: Probing context. + * @uuid: UUID string. Must not be freed by the caller. + * + * Get the raw UUID string after a successful probe. + * + * Returns: 1 if the value was set, 0 otherwise. + **/ +int volume_id_get_uuid(struct volume_id *id, const char **uuid) +{ + if (id == NULL) + return 0; + if (uuid == NULL) + return 0; + if (id->usage_id == VOLUME_ID_UNUSED) + return 0; + + *uuid = id->uuid; + return 1; +} + +/** + * volume_id_get_uuid_raw: + * @id: Probing context. + * @uuid: UUID byte array. Must not be freed by the caller. + * @len: Length of raw UUID byte array. + * + * Get the raw UUID byte array after a successful probe. It may + * contain unconverted endianes values. + * + * Returns: 1 if the value was set, 0 otherwise. + **/ +int volume_id_get_uuid_raw(struct volume_id *id, const uint8_t **uuid, size_t *len) +{ + if (id == NULL) + return 0; + if (uuid == NULL) + return 0; + if (len == NULL) + return 0; + if (id->usage_id == VOLUME_ID_UNUSED) + return 0; + + *uuid = id->uuid_raw; + *len = id->uuid_raw_len; + return 1; +} + +/** + * volume_id_get_usage: + * @id: Probing context. + * @usage: Usage string. Must not be freed by the caller. + * + * Get the usage string after a successful probe. + * + * Returns: 1 if the value was set, 0 otherwise. + **/ +int volume_id_get_usage(struct volume_id *id, const char **usage) +{ + if (id == NULL) + return 0; + if (usage == NULL) + return 0; + if (id->usage_id == VOLUME_ID_UNUSED) + return 0; + + *usage = id->usage; + return 1; +} + +/** + * volume_id_get_type: + * @id: Probing context + * @type: Type string. Must not be freed by the caller. + * + * Get the type string after a successful probe. + * + * Returns: 1 if the value was set, 0 otherwise. + **/ +int volume_id_get_type(struct volume_id *id, const char **type) +{ + if (id == NULL) + return 0; + if (type == NULL) + return 0; + if (id->usage_id == VOLUME_ID_UNUSED) + return 0; + + *type = id->type; + return 1; +} + +/** + * volume_id_get_type_version: + * @id: Probing context. + * @type_version: Type version string. Must not be freed by the caller. + * + * Get the Type version string after a successful probe. + * + * Returns: 1 if the value was set, 0 otherwise. + **/ +int volume_id_get_type_version(struct volume_id *id, const char **type_version) +{ + if (id == NULL) + return 0; + if (type_version == NULL) + return 0; + if (id->usage_id == VOLUME_ID_UNUSED) + return 0; + + *type_version = id->type_version; + return 1; +} + +static int needs_encoding(const char c) +{ + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + strchr(ALLOWED_CHARS, c)) + return 0; + return 1; +} + +/** + * volume_id_encode_string: + * @str: Input string to be encoded. + * @str_enc: Target string to store the encoded input. + * @len: Location to store the encoded string. The target string, + * which may be four times as long as the input string. + * + * Encode all potentially unsafe characters of a string to the + * corresponding hex value prefixed by '\x'. + * + * Returns: 1 if the entire string was copied, 0 otherwise. + **/ +int volume_id_encode_string(const char *str, char *str_enc, size_t len) +{ + size_t i, j; + + if (str == NULL || str_enc == NULL || len == 0) + return 0; + + str_enc[0] = '\0'; + for (i = 0, j = 0; str[i] != '\0'; i++) { + int seqlen; + + seqlen = volume_id_utf8_encoded_valid_unichar(&str[i]); + if (seqlen > 1) { + memcpy(&str_enc[j], &str[i], seqlen); + j += seqlen; + i += (seqlen-1); + } else if (str[i] == '\\' || needs_encoding(str[i])) { + sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); + j += 4; + } else { + str_enc[j] = str[i]; + j++; + } + if (j+3 >= len) + goto err; + } + str_enc[j] = '\0'; + return 1; +err: + return 0; +} + +/** + * volume_id_probe_raid: + * @id: Probing context. + * @off: Probing offset relative to the start of the device. + * @size: Total size of the device. + * + * Probe device for all known raid signatures. + * + * Returns: 0 on successful probe, otherwise negative value. + **/ +int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + unsigned int i; + + if (id == NULL) + return -EINVAL; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + for (i = 0; i < ARRAY_SIZE(prober_raid); i++) + if (prober_raid[i].prober(id, off, size) == 0) + goto found; + return -1; + +found: + /* If recognized, we free the allocated buffers */ + volume_id_free_buffer(id); + return 0; +} + +/** + * volume_id_probe_filesystem: + * @id: Probing context. + * @off: Probing offset relative to the start of the device. + * @size: Total size of the device. + * + * Probe device for all known filesystem signatures. + * + * Returns: 0 on successful probe, otherwise negative value. + **/ +int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size) +{ + unsigned int i; + + if (id == NULL) + return -EINVAL; + + info("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) + if (prober_filesystem[i].prober(id, off, size) == 0) + goto found; + return -1; + +found: + /* If recognized, we free the allocated buffers */ + volume_id_free_buffer(id); + return 0; +} + +/** + * volume_id_probe_all: + * @id: Probing context. + * @off: Probing offset relative to the start of the device. + * @size: Total size of the device. + * + * Probe device for all known raid and filesystem signatures. + * + * Returns: 0 on successful probe, otherwise negative value. + **/ +int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) +{ + if (id == NULL) + return -EINVAL; + + /* probe for raid first, because fs probes may be successful on raid members */ + if (volume_id_probe_raid(id, off, size) == 0) + return 0; + + if (volume_id_probe_filesystem(id, off, size) == 0) + return 0; + + return -1; +} + +/** + * volume_id_probe_raid: + * @all_probers_fn: prober function to called for all known probing routines. + * @id: Context passed to prober function. + * @off: Offset value passed to prober function. + * @size: Size value passed to prober function. + * @data: Arbitrary data passed to the prober function. + * + * Run a custom function for all known probing routines. + **/ +void volume_id_all_probers(all_probers_fn_t all_probers_fn, + struct volume_id *id, uint64_t off, uint64_t size, + void *data) +{ + unsigned int i; + + if (all_probers_fn == NULL) + return; + + for (i = 0; i < ARRAY_SIZE(prober_raid); i++) + if (all_probers_fn(prober_raid[i].prober, id, off, size, data) != 0) + goto out; + for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) + if (all_probers_fn(prober_filesystem[i].prober, id, off, size, data) != 0) + goto out; +out: + return; +} + +/** + * volume_id_open_fd: + * @id: Probing context. + * @fd: Open file descriptor of device to read from. + * + * Create the context for probing. + * + * Returns: Probing context, or #NULL on failure. + **/ +struct volume_id *volume_id_open_fd(int fd) +{ + struct volume_id *id; + + id = malloc(sizeof(struct volume_id)); + if (id == NULL) + return NULL; + memset(id, 0x00, sizeof(struct volume_id)); + + id->fd = fd; + + return id; +} + +struct volume_id *volume_id_open_node(const char *path) +{ + struct volume_id *id; + int fd; + + fd = open(path, O_RDONLY); + if (fd < 0) { + dbg("unable to open '%s'", path); + return NULL; + } + + id = volume_id_open_fd(fd); + if (id == NULL) + return NULL; + + /* close fd on device close */ + id->fd_close = 1; + + return id; +} + +/** + * volume_id_close: + * @id: Probing context. + * + * Release probing context and free all associated data. + */ +void volume_id_close(struct volume_id *id) +{ + if (id == NULL) + return; + + if (id->fd_close != 0) + close(id->fd); + + volume_id_free_buffer(id); + + free(id); +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/vxfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/vxfs.c new file mode 100644 index 0000000..c9b7628 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/vxfs.c @@ -0,0 +1,54 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define VXFS_SUPER_MAGIC 0xa501FCF5 + +struct vxfs_super { + uint32_t vs_magic; + int32_t vs_version; +} PACKED; + +int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct vxfs_super *vxs; + + info("probing at offset 0x%llx", (unsigned long long) off); + + vxs = (struct vxfs_super *) volume_id_get_buffer(id, off + 0x200, 0x200); + if (vxs == NULL) + return -1; + + if (vxs->vs_magic == cpu_to_le32(VXFS_SUPER_MAGIC)) { + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", (unsigned int) vxs->vs_version); + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "vxfs"; + return 0; + } + + return -1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/xfs.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/xfs.c new file mode 100644 index 0000000..9eac827 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/lib/xfs.c @@ -0,0 +1,65 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct xfs_super_block { + uint8_t magic[4]; + uint32_t blocksize; + uint64_t dblocks; + uint64_t rblocks; + uint32_t dummy1[2]; + uint8_t uuid[16]; + uint32_t dummy2[15]; + uint8_t fname[12]; + uint32_t dummy3[2]; + uint64_t icount; + uint64_t ifree; + uint64_t fdblocks; +} PACKED; + +int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size) +{ + struct xfs_super_block *xs; + + info("probing at offset 0x%llx", (unsigned long long) off); + + xs = (struct xfs_super_block *) volume_id_get_buffer(id, off, 0x200); + if (xs == NULL) + return -1; + + if (memcmp(xs->magic, "XFSB", 4) != 0) + return -1; + + volume_id_set_label_raw(id, xs->fname, 12); + volume_id_set_label_string(id, xs->fname, 12); + volume_id_set_uuid(id, xs->uuid, 0, UUID_DCE); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "xfs"; + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.8 b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.8 new file mode 100644 index 0000000..7594253 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.8 @@ -0,0 +1,79 @@ +.\" Title: vol_id +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: March 2006 +.\" Manual: vol_id +.\" Source: volume_id +.\" +.TH "VOL_ID" "8" "March 2006" "volume_id" "vol_id" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +vol_id \- probe filesystem type and read label and uuid +.SH "SYNOPSIS" +.HP 7 +\fBvol_id\fR [\fB\-\-export\fR] [\fB\-\-type\fR] [\fB\-\-label\fR] [\fB\-\-label\-raw\fR] [\fB\-\-uuid\fR] [\fB\-\-skip\-raid\fR] [\fB\-\-probe\-all\fR] [\fB\-\-help\fR] [\fIdevice\fR] +.SH "DESCRIPTION" +.PP +\fBvol_id\fR +is usually called from a udev rule, to provide udev with the filesystem type, the label and the uuid of a volume. It supports most of the common filesystem formats and detects various raid setups to prevent the recognition of raid members as a volume with a filesystem. +.SH "OPTIONS" +.PP +\fB\-\-export\fR +.RS 4 +Print all values in key/value format to import them into the environment. +.RE +.PP +\fB\-\-type\fR +.RS 4 +Print the filesystem type. +.RE +.PP +\fB\-\-label\fR +.RS 4 +Print the safe version of volume label suitable for use as filename. +.RE +.PP +\fB\-\-label\-raw\fR +.RS 4 +Print the raw volume label. +.RE +.PP +\fB\-\-uuid\fR +.RS 4 +Print the uuid of a volume. +.RE +.PP +\fB\-\-skip\-raid\fR +.RS 4 +Skip detection of raid metadata. +.RE +.PP +\fB\-\-probe\-all\fR +.RS 4 +Probe for all types and print all matches. +.RE +.PP +\fB\-\-help\fR +.RS 4 +Print usage. +.RE +.SH "ENVIRONMENT" +.PP +\fBUDEV_LOG\fR +.RS 4 +Set the syslog priority. +.RE +.SH "EXIT STATUS" +.PP +\fBvol_id\fR +will only return successful if the value asked for is not empty. All trailing whitespace will be removed, spaces replaced by underscore and slashes ignored. +.SH "AUTHOR" +.PP +Written by Kay Sievers + +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.c b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.c new file mode 100644 index 0000000..38950ee --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.c @@ -0,0 +1,324 @@ +/* + * vol_id - read filesystem label and uuid + * + * Copyright (C) 2005-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev.h" +#include "lib/libvolume_id.h" + +#define BLKGETSIZE64 _IOR(0x12,114,size_t) + +#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 vid_log(int priority, const char *file, int line, const char *format, ...) +{ +#ifdef USE_LOG + char log_str[1024]; + va_list args; + + va_start(args, format); + vsnprintf(log_str, sizeof(log_str), format, args); + log_str[sizeof(log_str)-1] = '\0'; + log_message(priority, "%s:%i %s", file, line, log_str); + va_end(args); +#endif + return; +} + +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'; +} + +static int all_probers(volume_id_probe_fn_t probe_fn, + struct volume_id *id, uint64_t off, uint64_t size, + void *data) +{ + const char *type; + + if (probe_fn(id, off, size) == 0) + if (volume_id_get_type(id, &type)) + printf("%s\n", type); + + return 0; +} + +int main(int argc, char *argv[]) +{ + static const struct option options[] = { + { "label", 0, NULL, 'l' }, + { "label-raw", 0, NULL, 'L' }, + { "uuid", 0, NULL, 'u' }, + { "type", 0, NULL, 't' }, + { "export", 0, NULL, 'x' }, + { "skip-raid", 0, NULL, 's' }, + { "probe-all", 0, NULL, 'a' }, + { "help", 0, NULL, 'h' }, + {} + }; + + enum print_type { + PRINT_EXPORT, + PRINT_TYPE, + PRINT_LABEL, + PRINT_UUID, + PRINT_LABEL_RAW, + } print = PRINT_EXPORT; + + struct volume_id *vid = NULL; + char label_safe[256]; + char label_enc[256]; + char uuid_enc[256]; + uint64_t size; + int skip_raid = 0; + int probe_all = 0; + const char *node; + int fd; + const char *label, *uuid, *type, *type_version, *usage; + int retval; + int rc = 0; + + logging_init("vol_id"); + + /* hook in our debug into libvolume_id */ + volume_id_log_fn = vid_log; + + while (1) { + int option; + + option = getopt_long(argc, argv, "lLutxsah", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'l': + print = PRINT_LABEL; + break; + case 'L': + print = PRINT_LABEL_RAW; + break; + case 'u': + print = PRINT_UUID; + break; + case 't': + print = PRINT_TYPE; + break; + case 'x': + print = PRINT_EXPORT; + break; + case 's': + skip_raid = 1; + break; + case 'a': + probe_all = 1; + break; + case 'h': + printf("Usage: vol_id [options] \n" + " --export export key/value pairs\n" + " --type filesystem type\n" + " --label filesystem label\n" + " --label-raw raw label\n" + " --uuid filesystem uuid\n" + " --skip-raid don't probe for raid\n" + " --probe-all find possibly conflicting signatures\n" + " --help\n\n"); + goto exit; + default: + retval = 1; + goto exit; + } + } + + node = argv[optind]; + if (!node) { + err("no device"); + fprintf(stderr, "no device\n"); + rc = 1; + goto exit; + } + + fd = open(node, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: error opening volume\n", node); + rc = 2; + goto exit; + } + + vid = volume_id_open_fd(fd); + if (vid == NULL) { + rc = 2; + goto exit; + } + + if (ioctl(fd, BLKGETSIZE64, &size) != 0) + size = 0; + dbg("BLKGETSIZE64=%llu", (unsigned long long)size); + + /* try to drop all privileges before reading disk content */ + if (getuid() == 0) { + struct passwd *pw; + + pw = getpwnam("nobody"); + if (pw != NULL && pw->pw_uid > 0 && pw->pw_gid > 0) { + if (setgroups(0, NULL) != 0 || + setgid(pw->pw_gid) != 0 || + setuid(pw->pw_uid) != 0) + info("unable to drop privileges: %s\n", strerror(errno)); + } + } + + if (probe_all) { + volume_id_all_probers(all_probers, vid, 0, size, NULL); + goto exit; + } + + if (skip_raid) + retval = volume_id_probe_filesystem(vid, 0, size); + else + retval = volume_id_probe_all(vid, 0, size); + if (retval != 0) { + fprintf(stderr, "%s: unknown volume type\n", node); + rc = 4; + goto exit; + } + + if (!volume_id_get_label(vid, &label) || + !volume_id_get_usage(vid, &usage) || + !volume_id_get_type(vid, &type) || + !volume_id_get_type_version(vid, &type_version) || + !volume_id_get_uuid(vid, &uuid)) { + rc = 4; + goto exit; + } + + set_str(label_safe, label, sizeof(label_safe)); + replace_chars(label_safe, ALLOWED_CHARS_INPUT); + + volume_id_encode_string(label, label_enc, sizeof(label_enc)); + volume_id_encode_string(uuid, uuid_enc, sizeof(uuid_enc)); + + switch (print) { + case PRINT_EXPORT: + printf("ID_FS_USAGE=%s\n", usage); + printf("ID_FS_TYPE=%s\n", type); + printf("ID_FS_VERSION=%s\n", type_version); + printf("ID_FS_UUID=%s\n", uuid); + printf("ID_FS_UUID_ENC=%s\n", uuid_enc); + printf("ID_FS_LABEL=%s\n", label); + printf("ID_FS_LABEL_ENC=%s\n", label_enc); + printf("ID_FS_LABEL_SAFE=%s\n", label_safe); + break; + case PRINT_TYPE: + printf("%s\n", type); + break; + case PRINT_LABEL: + if (label_safe[0] == '\0' || strcmp(usage, "raid") == 0) { + rc = 3; + goto exit; + } + printf("%s\n", label_safe); + break; + case PRINT_UUID: + if (uuid_enc[0] == '\0' || strcmp(usage, "raid") == 0) { + rc = 4; + goto exit; + } + printf("%s\n", uuid_enc); + break; + case PRINT_LABEL_RAW: + if (label[0] == '\0' || strcmp(usage, "raid") == 0) { + rc = 3; + goto exit; + } + printf("%s\n", label); + break; + } + +exit: + if (vid != NULL) + volume_id_close(vid); + + logging_close(); + return rc; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.xml b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.xml new file mode 100644 index 0000000..6d0a6c6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/extras/volume_id/vol_id.xml @@ -0,0 +1,136 @@ + + + +
    +
    + vol_id + + + vol_id + March 2006 + volume_id + + + + vol_id + 8 + + + + + vol_idprobe filesystem type and read label and uuid + + + + + vol_id + + + + + + + + + device + + + + DESCRIPTION + vol_id is usually called from a udev rule, to + provide udev with the filesystem type, the label and the uuid of a + volume. It supports most of the common filesystem formats and detects + various raid setups to prevent the recognition of raid members + as a volume with a filesystem. + + + OPTIONS + + + + + Print all values in key/value format to import them into the + environment. + + + + + + Print the filesystem type. + + + + + + + Print the safe version of volume label suitable for + use as filename. + + + + + + + + Print the raw volume label. + + + + + + + Print the uuid of a volume. + + + + + + Skip detection of raid metadata. + + + + + + Probe for all types and print all matches. + + + + + + Print usage. + + + + + + ENVIRONMENT + + + + + Set the syslog priority. + + + + + + EXIT STATUS + vol_id will only return successful if the + value asked for is not empty. All trailing whitespace will be removed, + spaces replaced by underscore and slashes ignored. + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/list.h b/21cnbao/code/05/udev源代码/udev-114/list.h new file mode 100644 index 0000000..8626630 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/list.h @@ -0,0 +1,289 @@ +/* + * Copied from the Linux kernel source tree, version 2.6.0-test1. + * + * Licensed under the GPL v2 as per the whole kernel source tree. + * + */ + +#ifndef _LIST_H +#define _LIST_H + +/** + * container_of - cast a member of a structure out to the containing structure + * + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* + * These are non-NULL pointers that will result in page faults + * under normal circumstances, used to verify that nobody uses + * non-initialized list entries. + */ +#define LIST_POISON1 ((void *) 0x00100100) +#define LIST_POISON2 ((void *) 0x00200200) + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(struct list_head *head) +{ + return head->next == head; +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(struct list_head *list, struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); \ + pos = pos->next) + +/** + * __list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + * + * This variant differs from list_for_each() in that it's the + * simplest possible list iteration code. + * Use this for code that knows the list to be very short (empty + * or 1 entry) most of the time. + */ +#define __list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +#endif /* _LIST_H */ diff --git a/21cnbao/code/05/udev源代码/udev-114/logging.h b/21cnbao/code/05/udev源代码/udev-114/logging.h new file mode 100644 index 0000000..6e1d5a2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/logging.h @@ -0,0 +1,73 @@ +/* + * simple logging functions that can be expanded into nothing + * + * Copyright (C) 2003-2004 Greg Kroah-Hartman + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef LOGGING_H +#define LOGGING_H + +#define err(format, arg...) do { } while (0) +#define info(format, arg...) do { } while (0) +#define dbg(format, arg...) do { } while (0) +#define logging_init(foo) do { } while (0) +#define logging_close(foo) do { } while (0) + +#ifdef USE_LOG +#include +#include +#include + +#undef err +#define err(format, arg...) \ + do { \ + log_message(LOG_ERR ,"%s: " format ,__FUNCTION__ ,## arg); \ + } while (0) + +#undef info +#define info(format, arg...) \ + do { \ + log_message(LOG_INFO ,"%s: " format ,__FUNCTION__ ,## arg); \ + } while (0) + +#ifdef DEBUG +#undef dbg +#define dbg(format, arg...) \ + do { \ + log_message(LOG_DEBUG ,"%s: " format ,__FUNCTION__ ,## arg); \ + } while (0) +#endif + +extern void log_message(int priority, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); + +#undef logging_init +static inline void logging_init(const char *program_name) +{ + openlog(program_name, LOG_PID | LOG_CONS, LOG_DAEMON); +} + +#undef logging_close +static inline void logging_close(void) +{ + closelog(); +} + +#endif /* USE_LOG */ + +#endif diff --git a/21cnbao/code/05/udev源代码/udev-114/test-udev.c b/21cnbao/code/05/udev源代码/udev-114/test-udev.c new file mode 100644 index 0000000..0c25778 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test-udev.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2003-2004 Greg Kroah-Hartman + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" +#include "udev_selinux.h" + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log_priority) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +static void asmlinkage sig_handler(int signum) +{ + switch (signum) { + case SIGALRM: + exit(1); + case SIGINT: + case SIGTERM: + exit(20 + signum); + } +} + +int main(int argc, char *argv[], char *envp[]) +{ + struct sysfs_device *dev; + struct udevice *udev; + const char *maj, *min; + struct udev_rules rules; + const char *action; + const char *devpath; + const char *subsystem; + struct sigaction act; + int devnull; + int retval = -EINVAL; + + if (argc == 2 && strcmp(argv[1], "-V") == 0) { + printf("%s\n", UDEV_VERSION); + exit(0); + } + + /* set std fd's to /dev/null, /sbin/hotplug forks us, we don't have them at all */ + devnull = open("/dev/null", O_RDWR); + if (devnull >= 0) { + if (devnull != STDIN_FILENO) + dup2(devnull, STDIN_FILENO); + if (devnull != STDOUT_FILENO) + dup2(devnull, STDOUT_FILENO); + if (devnull != STDERR_FILENO) + dup2(devnull, STDERR_FILENO); + if (devnull > STDERR_FILENO) + close(devnull); + } + + logging_init("udev"); + if (devnull < 0) + err("open /dev/null failed: %s", strerror(errno)); + udev_config_init(); + selinux_init(); + dbg("version %s", UDEV_VERSION); + + /* set signal handlers */ + memset(&act, 0x00, sizeof(act)); + act.sa_handler = (void (*)(int)) sig_handler; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + + /* trigger timeout to prevent hanging processes */ + alarm(UDEV_ALARM_TIMEOUT); + + action = getenv("ACTION"); + devpath = getenv("DEVPATH"); + subsystem = getenv("SUBSYSTEM"); + /* older kernels passed the SUBSYSTEM only as argument */ + if (subsystem == NULL && argc == 2) + subsystem = argv[1]; + + if (action == NULL || subsystem == NULL || devpath == NULL) { + err("action, subsystem or devpath missing"); + goto exit; + } + + /* export log_priority , as called programs may want to do the same as udev */ + if (udev_log_priority) { + char priority[32]; + + sprintf(priority, "%i", udev_log_priority); + setenv("UDEV_LOG", priority, 1); + } + + sysfs_init(); + udev_rules_init(&rules, 0); + + dev = sysfs_device_get(devpath); + if (dev == NULL) { + info("unable to open '%s'", devpath); + goto fail; + } + + udev = udev_device_init(NULL); + if (udev == NULL) + goto fail; + + /* override built-in sysfs device */ + udev->dev = dev; + strlcpy(udev->action, action, sizeof(udev->action)); + + /* get dev_t from environment, which is needed for "remove" to work, "add" works also from sysfs */ + maj = getenv("MAJOR"); + min = getenv("MINOR"); + if (maj != NULL && min != NULL) + udev->devt = makedev(atoi(maj), atoi(min)); + else + udev->devt = udev_device_get_devt(udev); + + retval = udev_device_event(&rules, udev); + + if (retval == 0 && !udev->ignore_device && udev_run) + udev_rules_run(udev); + + udev_device_cleanup(udev); +fail: + udev_rules_cleanup(&rules); + sysfs_cleanup(); + selinux_exit(); + +exit: + logging_close(); + if (retval != 0) + return 1; + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/test/simple-build-check.sh b/21cnbao/code/05/udev源代码/udev-114/test/simple-build-check.sh new file mode 100755 index 0000000..9939b88 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/simple-build-check.sh @@ -0,0 +1,38 @@ +#/bin/sh + +EXTRAS="\ + extras/path_id \ + extras/scsi_id \ + extras/ata_id \ + extras/volume_id \ + extras/usb_id \ + extras/cdrom_id \ + extras/edd_id \ + extras/floppy \ + extras/firmware \ + extras/path_id \ + extras/collect \ + extras/rule_generator" + +# with debug +make clean EXTRAS="$EXTRAS" >/dev/null +make all -j4 $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit +echo -e "\n\n" + +# without any logging +make clean EXTRAS="$EXTRAS" >/dev/null +make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit +echo -e "\n\n" + +# install in temporary dir and show it +TEMPDIR="`pwd`/.tmp" +rm -rf $TEMPDIR +mkdir $TEMPDIR +make clean EXTRAS="$EXTRAS" >/dev/null +make all $MAKEOPTS DESTDIR="$TEMPDIR" EXTRAS="$EXTRAS" || exit +make install DESTDIR="$TEMPDIR" EXTRAS="$EXTRAS" || exit +echo -e "\nInstalled tree:" +find $TEMPDIR +rm -rf $TEMPDIR + +make clean EXTRAS="$EXTRAS" >/dev/null diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p1/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p1/dev new file mode 100644 index 0000000..92c4b9b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p1/dev @@ -0,0 +1 @@ +8:1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p2/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p2/dev new file mode 100644 index 0000000..9799a26 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p2/dev @@ -0,0 +1 @@ +8:2 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p5/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p5/dev new file mode 100644 index 0000000..b3d5042 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/cciss!c0d0p5/dev @@ -0,0 +1 @@ +8:5 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/dev new file mode 100644 index 0000000..fae0a50 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/dev @@ -0,0 +1 @@ +8:0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/device b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/device new file mode 120000 index 0000000..485bf09 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/cciss!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/rd!c0d0/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/rd!c0d0/dev new file mode 100644 index 0000000..fae0a50 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/rd!c0d0/dev @@ -0,0 +1 @@ +8:0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/rd!c0d0/device b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/rd!c0d0/device new file mode 120000 index 0000000..485bf09 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/rd!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/dev new file mode 100644 index 0000000..fae0a50 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/dev @@ -0,0 +1 @@ +8:0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/device b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/device new file mode 120000 index 0000000..485bf09 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/antic_expire b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/antic_expire new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/antic_expire @@ -0,0 +1 @@ +6 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/read_batch_expire b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/read_batch_expire new file mode 100644 index 0000000..08839f6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/read_batch_expire @@ -0,0 +1 @@ +200 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/read_expire b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/read_expire new file mode 100644 index 0000000..e373ee6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/read_expire @@ -0,0 +1 @@ +50 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/write_batch_expire b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/write_batch_expire new file mode 100644 index 0000000..e373ee6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/write_batch_expire @@ -0,0 +1 @@ +50 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/write_expire b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/write_expire new file mode 100644 index 0000000..08839f6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/iosched/write_expire @@ -0,0 +1 @@ +200 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/nr_requests b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/nr_requests new file mode 100644 index 0000000..a949a93 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/queue/nr_requests @@ -0,0 +1 @@ +128 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/range b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/range new file mode 100644 index 0000000..b6a7d89 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/range @@ -0,0 +1 @@ +16 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/dev new file mode 100644 index 0000000..92c4b9b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/dev @@ -0,0 +1 @@ +8:1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/size b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/size new file mode 100644 index 0000000..f00a592 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/size @@ -0,0 +1 @@ +1060227 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/start b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/start new file mode 100644 index 0000000..4b9026d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/start @@ -0,0 +1 @@ +63 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/stat b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/stat new file mode 100644 index 0000000..199ce73 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda1/stat @@ -0,0 +1 @@ + 50 400 103 824 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/dev new file mode 100644 index 0000000..9799a26 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/dev @@ -0,0 +1 @@ +8:2 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/size b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/size new file mode 100644 index 0000000..80483ab --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/size @@ -0,0 +1 @@ +112455 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/start b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/start new file mode 100644 index 0000000..3a4bf07 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/start @@ -0,0 +1 @@ +1060290 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/stat b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/stat new file mode 100644 index 0000000..c06b749 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda2/stat @@ -0,0 +1 @@ + 342 500 15 30 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/dev new file mode 100644 index 0000000..44ccff4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/dev @@ -0,0 +1 @@ +8:3 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/size b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/size new file mode 100644 index 0000000..1373b38 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/size @@ -0,0 +1 @@ +20482875 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/start b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/start new file mode 100644 index 0000000..cab5c33 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/start @@ -0,0 +1 @@ +1172745 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/stat b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/stat new file mode 100644 index 0000000..82fb146 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda3/stat @@ -0,0 +1 @@ + 415052 6872874 669740 5357920 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/dev new file mode 100644 index 0000000..aab3fc5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/dev @@ -0,0 +1 @@ +8:4 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/size b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/size new file mode 100644 index 0000000..062619c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/size @@ -0,0 +1 @@ +49432005 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/start b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/start new file mode 100644 index 0000000..b65020c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/start @@ -0,0 +1 @@ +21655620 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/stat b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/stat new file mode 100644 index 0000000..3e7b7ad --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/sda4/stat @@ -0,0 +1 @@ + 642730 9095506 275223 2201728 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/size b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/size new file mode 100644 index 0000000..88da032 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/size @@ -0,0 +1 @@ +71096640 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/stat b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/stat new file mode 100644 index 0000000..b93c7d4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/stat @@ -0,0 +1 @@ + 1043906 19157 16008400 4313104 317001 625161 7560502 48785829 0 3846686 53153390 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/test:colon+plus b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/test:colon+plus new file mode 100644 index 0000000..0fed9a5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/block/sda/test:colon+plus @@ -0,0 +1 @@ +colon diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:00:09.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:00:09.0 new file mode 120000 index 0000000..1c77656 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:00:09.0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:09.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:00:1e.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:00:1e.0 new file mode 120000 index 0000000..e000c77 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:00:1e.0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:1e.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:02:05.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:02:05.0 new file mode 120000 index 0000000..630d35b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/devices/0000:02:05.0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 new file mode 120000 index 0000000..bd644e0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 @@ -0,0 +1 @@ +../../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/scsi/devices/0:0:0:0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/scsi/devices/0:0:0:0 new file mode 120000 index 0000000..6d8555d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/scsi/devices/0:0:0:0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/scsi/drivers/sd/0:0:0:0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/scsi/drivers/sd/0:0:0:0 new file mode 120000 index 0000000..97ae021 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/scsi/drivers/sd/0:0:0:0 @@ -0,0 +1 @@ +../../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb-serial/devices/ttyUSB0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb-serial/devices/ttyUSB0 new file mode 120000 index 0000000..b7733a6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb-serial/devices/ttyUSB0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 new file mode 120000 index 0000000..177f109 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 @@ -0,0 +1 @@ +../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-0:1.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-0:1.0 new file mode 120000 index 0000000..9137978 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-0:1.0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-1 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-1 new file mode 120000 index 0000000..e47b4d5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-1 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:09.0/usb3/3-1 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-1:1.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-1:1.0 new file mode 120000 index 0000000..f519185 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/3-1:1.0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/usb3 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/usb3 new file mode 120000 index 0000000..fb1919e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/devices/usb3 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:09.0/usb3 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/hub/3-0:1.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/hub/3-0:1.0 new file mode 120000 index 0000000..2bc160c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/hub/3-0:1.0 @@ -0,0 +1 @@ +../../../../devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/pl2303/3-1:1.0 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/pl2303/3-1:1.0 new file mode 120000 index 0000000..49d32d5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/pl2303/3-1:1.0 @@ -0,0 +1 @@ +../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/usb/3-1 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/usb/3-1 new file mode 120000 index 0000000..03c7619 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/usb/3-1 @@ -0,0 +1 @@ +../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/usb/usb3 b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/usb/usb3 new file mode 120000 index 0000000..61dc52a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/bus/usb/drivers/usb/usb3 @@ -0,0 +1 @@ +../../../../devices/pci0000:00/0000:00:09.0/usb3 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-300/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-300/dev new file mode 100644 index 0000000..e1ffb89 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-300/dev @@ -0,0 +1 @@ +89:300 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-300/name b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-300/name new file mode 100644 index 0000000..9357009 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-300/name @@ -0,0 +1 @@ +foo dev diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake1/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake1/dev new file mode 100644 index 0000000..ab45313 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake1/dev @@ -0,0 +1 @@ +4095:1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake1/name b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake1/name new file mode 100644 index 0000000..ced44c3 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake1/name @@ -0,0 +1 @@ +fake1 dev diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake2/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake2/dev new file mode 100644 index 0000000..d2425b7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake2/dev @@ -0,0 +1 @@ +4094:89999 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake2/name b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake2/name new file mode 100644 index 0000000..b69deec --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/i2c-dev/i2c-fake2/name @@ -0,0 +1 @@ +fake2 dev diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/full/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/full/dev new file mode 100644 index 0000000..4dc588f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/full/dev @@ -0,0 +1 @@ +1:7 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/kmem/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/kmem/dev new file mode 100644 index 0000000..c7bc405 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/kmem/dev @@ -0,0 +1 @@ +1:2 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/kmsg/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/kmsg/dev new file mode 100644 index 0000000..59effa1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/kmsg/dev @@ -0,0 +1 @@ +1:11 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/mem/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/mem/dev new file mode 100644 index 0000000..a72b75e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/mem/dev @@ -0,0 +1 @@ +1:1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/null/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/null/dev new file mode 100644 index 0000000..d9812ed --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/null/dev @@ -0,0 +1 @@ +1:3 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/port/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/port/dev new file mode 100644 index 0000000..ab11afd --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/port/dev @@ -0,0 +1 @@ +1:4 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/random/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/random/dev new file mode 100644 index 0000000..2b7b905 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/random/dev @@ -0,0 +1 @@ +1:8 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/urandom/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/urandom/dev new file mode 100644 index 0000000..0695af0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/urandom/dev @@ -0,0 +1 @@ +1:9 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/zero/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/zero/dev new file mode 100644 index 0000000..0acbea5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/mem/zero/dev @@ -0,0 +1 @@ +1:5 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/psaux/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/psaux/dev new file mode 100644 index 0000000..48ace1e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/psaux/dev @@ -0,0 +1 @@ +10:1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/rtc/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/rtc/dev new file mode 100644 index 0000000..64e028a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/rtc/dev @@ -0,0 +1 @@ +10:135 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/uinput/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/uinput/dev new file mode 100644 index 0000000..a47be0d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/misc/uinput/dev @@ -0,0 +1 @@ +10:223 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/addr_len b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/addr_len new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/addr_len @@ -0,0 +1 @@ +6 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/address b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/address new file mode 100644 index 0000000..4e0cdd5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/address @@ -0,0 +1 @@ +00:e0:00:fb:04:e1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/broadcast b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/broadcast new file mode 100644 index 0000000..d516b03 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/broadcast @@ -0,0 +1 @@ +ff:ff:ff:ff:ff:ff diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/features b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/features new file mode 100644 index 0000000..bf73d73 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/features @@ -0,0 +1 @@ +0x29 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/flags b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/flags new file mode 100644 index 0000000..4af9ab2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/flags @@ -0,0 +1 @@ +0x1023 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/ifindex b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/ifindex new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/ifindex @@ -0,0 +1 @@ +9 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/iflink b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/iflink new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/iflink @@ -0,0 +1 @@ +9 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/mtu b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/mtu new file mode 100644 index 0000000..3d86ec6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/mtu @@ -0,0 +1 @@ +1500 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/tx_queue_len b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/tx_queue_len new file mode 100644 index 0000000..83b33d2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/tx_queue_len @@ -0,0 +1 @@ +1000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/type b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/type new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth0/type @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/addr_len b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/addr_len new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/addr_len @@ -0,0 +1 @@ +6 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/address b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/address new file mode 100644 index 0000000..7325095 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/address @@ -0,0 +1 @@ +00:e0:00:8d:9f:25 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/broadcast b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/broadcast new file mode 100644 index 0000000..d516b03 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/broadcast @@ -0,0 +1 @@ +ff:ff:ff:ff:ff:ff diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/features b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/features new file mode 100644 index 0000000..9982566 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/features @@ -0,0 +1 @@ +0x0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/flags b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/flags new file mode 100644 index 0000000..7f97d85 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/flags @@ -0,0 +1 @@ +0x1002 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/ifindex b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/ifindex new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/ifindex @@ -0,0 +1 @@ +10 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/iflink b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/iflink new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/iflink @@ -0,0 +1 @@ +10 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/mtu b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/mtu new file mode 100644 index 0000000..3d86ec6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/mtu @@ -0,0 +1 @@ +1500 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/tx_queue_len b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/tx_queue_len new file mode 100644 index 0000000..83b33d2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/tx_queue_len @@ -0,0 +1 @@ +1000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/type b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/type new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/type @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/beacon b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/beacon new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/beacon @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/crypt b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/crypt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/crypt @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/fragment b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/fragment new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/fragment @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/level b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/level new file mode 100644 index 0000000..e702a30 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/level @@ -0,0 +1 @@ +188 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/link b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/link new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/link @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/misc b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/misc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/misc @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/noise b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/noise new file mode 100644 index 0000000..405e2af --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/noise @@ -0,0 +1 @@ +134 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/nwid b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/nwid new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/nwid @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/retries b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/retries new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/retries @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/status b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/status new file mode 100644 index 0000000..9982566 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/eth1/wireless/status @@ -0,0 +1 @@ +0x0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/addr_len b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/addr_len new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/addr_len @@ -0,0 +1 @@ +6 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/address b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/address new file mode 100644 index 0000000..34e09d0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/address @@ -0,0 +1 @@ +00:00:00:00:00:00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/broadcast b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/broadcast new file mode 100644 index 0000000..34e09d0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/broadcast @@ -0,0 +1 @@ +00:00:00:00:00:00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/features b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/features new file mode 100644 index 0000000..e8768d2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/features @@ -0,0 +1 @@ +0x65 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/flags b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/flags new file mode 100644 index 0000000..4bc4da1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/flags @@ -0,0 +1 @@ +0x9 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/ifindex b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/ifindex new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/ifindex @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/iflink b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/iflink new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/iflink @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/mtu b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/mtu new file mode 100644 index 0000000..e20e16c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/mtu @@ -0,0 +1 @@ +16436 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/tx_queue_len b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/tx_queue_len new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/tx_queue_len @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/type b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/type new file mode 100644 index 0000000..6d629c4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/net/lo/type @@ -0,0 +1 @@ +772 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/console/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/console/dev new file mode 100644 index 0000000..99eb99c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/console/dev @@ -0,0 +1 @@ +5:1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ptmx/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ptmx/dev new file mode 100644 index 0000000..b1df63e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ptmx/dev @@ -0,0 +1 @@ +5:2 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty/dev new file mode 100644 index 0000000..97f5a22 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty/dev @@ -0,0 +1 @@ +5:0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty0/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty0/dev new file mode 100644 index 0000000..192d8b7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty0/dev @@ -0,0 +1 @@ +4:0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty1/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty1/dev new file mode 100644 index 0000000..71275a2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty1/dev @@ -0,0 +1 @@ +4:1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty10/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty10/dev new file mode 100644 index 0000000..eb477d0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty10/dev @@ -0,0 +1 @@ +4:10 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty11/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty11/dev new file mode 100644 index 0000000..685b194 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty11/dev @@ -0,0 +1 @@ +4:11 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty12/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty12/dev new file mode 100644 index 0000000..47b68a9 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty12/dev @@ -0,0 +1 @@ +4:12 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty13/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty13/dev new file mode 100644 index 0000000..86e3145 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty13/dev @@ -0,0 +1 @@ +4:13 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty14/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty14/dev new file mode 100644 index 0000000..9fa8103 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty14/dev @@ -0,0 +1 @@ +4:14 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty15/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty15/dev new file mode 100644 index 0000000..3f601b8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty15/dev @@ -0,0 +1 @@ +4:15 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty16/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty16/dev new file mode 100644 index 0000000..0310e80 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty16/dev @@ -0,0 +1 @@ +4:16 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty17/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty17/dev new file mode 100644 index 0000000..1936046 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty17/dev @@ -0,0 +1 @@ +4:17 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty18/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty18/dev new file mode 100644 index 0000000..8710c48 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty18/dev @@ -0,0 +1 @@ +4:18 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty19/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty19/dev new file mode 100644 index 0000000..5fac93e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty19/dev @@ -0,0 +1 @@ +4:19 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty2/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty2/dev new file mode 100644 index 0000000..ac0836d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty2/dev @@ -0,0 +1 @@ +4:2 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty20/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty20/dev new file mode 100644 index 0000000..3db4a84 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty20/dev @@ -0,0 +1 @@ +4:20 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty21/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty21/dev new file mode 100644 index 0000000..f86a025 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty21/dev @@ -0,0 +1 @@ +4:21 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty22/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty22/dev new file mode 100644 index 0000000..b27a240 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty22/dev @@ -0,0 +1 @@ +4:22 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty23/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty23/dev new file mode 100644 index 0000000..9359bfa --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty23/dev @@ -0,0 +1 @@ +4:23 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty24/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty24/dev new file mode 100644 index 0000000..9cd85c8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty24/dev @@ -0,0 +1 @@ +4:24 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty25/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty25/dev new file mode 100644 index 0000000..f9d8c9c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty25/dev @@ -0,0 +1 @@ +4:25 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty26/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty26/dev new file mode 100644 index 0000000..210b637 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty26/dev @@ -0,0 +1 @@ +4:26 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty27/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty27/dev new file mode 100644 index 0000000..de59b62 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty27/dev @@ -0,0 +1 @@ +4:27 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty28/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty28/dev new file mode 100644 index 0000000..023871c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty28/dev @@ -0,0 +1 @@ +4:28 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty29/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty29/dev new file mode 100644 index 0000000..2edd7c5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty29/dev @@ -0,0 +1 @@ +4:29 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty3/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty3/dev new file mode 100644 index 0000000..c814288 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty3/dev @@ -0,0 +1 @@ +4:3 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty30/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty30/dev new file mode 100644 index 0000000..63f0e66 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty30/dev @@ -0,0 +1 @@ +4:30 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty31/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty31/dev new file mode 100644 index 0000000..77a50ee --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty31/dev @@ -0,0 +1 @@ +4:31 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty32/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty32/dev new file mode 100644 index 0000000..ae38a8d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty32/dev @@ -0,0 +1 @@ +4:32 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty33/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty33/dev new file mode 100644 index 0000000..9307b44 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty33/dev @@ -0,0 +1 @@ +4:33 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty34/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty34/dev new file mode 100644 index 0000000..be00cbe --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty34/dev @@ -0,0 +1 @@ +4:34 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty35/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty35/dev new file mode 100644 index 0000000..4e5e85c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty35/dev @@ -0,0 +1 @@ +4:35 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty36/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty36/dev new file mode 100644 index 0000000..4e5407e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty36/dev @@ -0,0 +1 @@ +4:36 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty37/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty37/dev new file mode 100644 index 0000000..765acf2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty37/dev @@ -0,0 +1 @@ +4:37 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty38/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty38/dev new file mode 100644 index 0000000..1532b15 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty38/dev @@ -0,0 +1 @@ +4:38 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty39/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty39/dev new file mode 100644 index 0000000..fac383d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty39/dev @@ -0,0 +1 @@ +4:39 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty4/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty4/dev new file mode 100644 index 0000000..7f407b5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty4/dev @@ -0,0 +1 @@ +4:4 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty40/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty40/dev new file mode 100644 index 0000000..d724613 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty40/dev @@ -0,0 +1 @@ +4:40 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty41/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty41/dev new file mode 100644 index 0000000..0d97430 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty41/dev @@ -0,0 +1 @@ +4:41 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty42/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty42/dev new file mode 100644 index 0000000..4019d23 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty42/dev @@ -0,0 +1 @@ +4:42 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty43/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty43/dev new file mode 100644 index 0000000..4b6c086 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty43/dev @@ -0,0 +1 @@ +4:43 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty44/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty44/dev new file mode 100644 index 0000000..9c23574 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty44/dev @@ -0,0 +1 @@ +4:44 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty45/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty45/dev new file mode 100644 index 0000000..23437be --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty45/dev @@ -0,0 +1 @@ +4:45 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty46/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty46/dev new file mode 100644 index 0000000..816feaf --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty46/dev @@ -0,0 +1 @@ +4:46 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty47/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty47/dev new file mode 100644 index 0000000..d2534e7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty47/dev @@ -0,0 +1 @@ +4:47 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty48/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty48/dev new file mode 100644 index 0000000..4003c70 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty48/dev @@ -0,0 +1 @@ +4:48 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty49/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty49/dev new file mode 100644 index 0000000..64dc806 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty49/dev @@ -0,0 +1 @@ +4:49 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty5/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty5/dev new file mode 100644 index 0000000..1553222 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty5/dev @@ -0,0 +1 @@ +4:5 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty50/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty50/dev new file mode 100644 index 0000000..71e681b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty50/dev @@ -0,0 +1 @@ +4:50 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty51/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty51/dev new file mode 100644 index 0000000..1f8c4b6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty51/dev @@ -0,0 +1 @@ +4:51 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty52/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty52/dev new file mode 100644 index 0000000..344e8c9 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty52/dev @@ -0,0 +1 @@ +4:52 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty53/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty53/dev new file mode 100644 index 0000000..c4b80fb --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty53/dev @@ -0,0 +1 @@ +4:53 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty54/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty54/dev new file mode 100644 index 0000000..ba56c5e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty54/dev @@ -0,0 +1 @@ +4:54 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty55/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty55/dev new file mode 100644 index 0000000..540bf11 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty55/dev @@ -0,0 +1 @@ +4:55 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty56/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty56/dev new file mode 100644 index 0000000..ee03fba --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty56/dev @@ -0,0 +1 @@ +4:56 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty57/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty57/dev new file mode 100644 index 0000000..664d8ec --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty57/dev @@ -0,0 +1 @@ +4:57 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty58/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty58/dev new file mode 100644 index 0000000..ffc6c0b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty58/dev @@ -0,0 +1 @@ +4:58 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty59/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty59/dev new file mode 100644 index 0000000..c48309e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty59/dev @@ -0,0 +1 @@ +4:59 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty6/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty6/dev new file mode 100644 index 0000000..cd94e0d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty6/dev @@ -0,0 +1 @@ +4:6 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty60/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty60/dev new file mode 100644 index 0000000..37d25ea --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty60/dev @@ -0,0 +1 @@ +4:60 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty61/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty61/dev new file mode 100644 index 0000000..599df60 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty61/dev @@ -0,0 +1 @@ +4:61 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty62/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty62/dev new file mode 100644 index 0000000..49fc9a0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty62/dev @@ -0,0 +1 @@ +4:62 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty63/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty63/dev new file mode 100644 index 0000000..d11e9d2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty63/dev @@ -0,0 +1 @@ +4:63 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty7/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty7/dev new file mode 100644 index 0000000..9410476 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty7/dev @@ -0,0 +1 @@ +4:7 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty8/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty8/dev new file mode 100644 index 0000000..a79f74b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty8/dev @@ -0,0 +1 @@ +4:8 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty9/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty9/dev new file mode 100644 index 0000000..62ada4b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/tty9/dev @@ -0,0 +1 @@ +4:9 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS0/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS0/dev new file mode 100644 index 0000000..9f6b667 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS0/dev @@ -0,0 +1 @@ +4:64 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS1/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS1/dev new file mode 100644 index 0000000..db3f8ec --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS1/dev @@ -0,0 +1 @@ +4:65 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS2/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS2/dev new file mode 100644 index 0000000..cef5d02 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS2/dev @@ -0,0 +1 @@ +4:66 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS3/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS3/dev new file mode 100644 index 0000000..3077006 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS3/dev @@ -0,0 +1 @@ +4:67 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS4/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS4/dev new file mode 100644 index 0000000..26cd2d8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS4/dev @@ -0,0 +1 @@ +4:68 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS5/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS5/dev new file mode 100644 index 0000000..189b73b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS5/dev @@ -0,0 +1 @@ +4:69 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS6/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS6/dev new file mode 100644 index 0000000..f40a113 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS6/dev @@ -0,0 +1 @@ +4:70 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS7/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS7/dev new file mode 100644 index 0000000..ec1b8ff --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyS7/dev @@ -0,0 +1 @@ +4:71 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyUSB0/dev b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyUSB0/dev new file mode 100644 index 0000000..5c0bba8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyUSB0/dev @@ -0,0 +1 @@ +188:0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyUSB0/device b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyUSB0/device new file mode 120000 index 0000000..b7733a6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/class/tty/ttyUSB0/device @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/bus new file mode 120000 index 0000000..4b20ef9 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/bus @@ -0,0 +1 @@ +../../../bus/pci \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/class b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/class new file mode 100644 index 0000000..a9a8817 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/class @@ -0,0 +1 @@ +0x0c0310 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/device b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/device new file mode 100644 index 0000000..90e151e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/device @@ -0,0 +1 @@ +0x0035 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/irq b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/irq new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/irq @@ -0,0 +1 @@ +9 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/pools b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/pools new file mode 100644 index 0000000..7da8ce8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/pools @@ -0,0 +1,7 @@ +poolinfo - 0.1 +ohci_ed 1 64 64 1 +ohci_td 1 64 64 1 +buffer-2048 0 0 2048 0 +buffer-512 0 0 512 0 +buffer-128 0 0 128 0 +buffer-32 1 128 32 1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/power/state b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/power/state new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/power/state @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/resource b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/resource new file mode 100644 index 0000000..e7c459f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/resource @@ -0,0 +1,7 @@ +0x0000000017100000 0x0000000017100fff 0x0000000000000200 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device new file mode 100644 index 0000000..db5e9bc --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device @@ -0,0 +1 @@ +0x11a3 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor new file mode 100644 index 0000000..3dc3dee --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor @@ -0,0 +1 @@ +0x10cf diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting new file mode 100644 index 0000000..2142470 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting @@ -0,0 +1 @@ + 0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass new file mode 100644 index 0000000..86397e5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass @@ -0,0 +1 @@ +09 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints new file mode 100644 index 0000000..8a0f05e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints @@ -0,0 +1 @@ +01 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bus new file mode 120000 index 0000000..af968de --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bus @@ -0,0 +1 @@ +../../../../../bus/usb \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/driver b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/driver new file mode 120000 index 0000000..5cf4934 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/driver @@ -0,0 +1 @@ +../../../../../bus/usb/drivers/hub \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting new file mode 100644 index 0000000..2142470 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting @@ -0,0 +1 @@ + 0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass new file mode 100644 index 0000000..fcd15ac --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass @@ -0,0 +1 @@ +ff diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints new file mode 100644 index 0000000..75016ea --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints @@ -0,0 +1 @@ +03 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bus new file mode 120000 index 0000000..29689de --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bus @@ -0,0 +1 @@ +../../../../../../bus/usb \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/driver b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/driver new file mode 120000 index 0000000..27eb850 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/driver @@ -0,0 +1 @@ +../../../../../../bus/usb/drivers/pl2303 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/power/state b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/power/state new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/power/state @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower new file mode 100644 index 0000000..d579c4b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower @@ -0,0 +1 @@ + 50mA diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces new file mode 100644 index 0000000..c6cf386 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces @@ -0,0 +1 @@ + 1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice new file mode 100644 index 0000000..6350475 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice @@ -0,0 +1 @@ +0001 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes new file mode 100644 index 0000000..0042f6c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes @@ -0,0 +1 @@ +a0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bus new file mode 120000 index 0000000..af968de --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bus @@ -0,0 +1 @@ +../../../../../bus/usb \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/driver b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/driver new file mode 120000 index 0000000..092d228 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/driver @@ -0,0 +1 @@ +../../../../../bus/usb/drivers/usb \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct new file mode 100644 index 0000000..9142bb4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct @@ -0,0 +1 @@ +2008 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor new file mode 100644 index 0000000..6ffae17 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor @@ -0,0 +1 @@ +0557 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed @@ -0,0 +1 @@ +12 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/bus new file mode 120000 index 0000000..dd0c04b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/bus @@ -0,0 +1 @@ +../../../../../../bus/usb-serial \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver new file mode 120000 index 0000000..9ff2c81 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver @@ -0,0 +1 @@ +../../../../../../bus/usb-serial/drivers/PL-2303 \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bConfigurationValue b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bConfigurationValue new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bConfigurationValue @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass new file mode 100644 index 0000000..86397e5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass @@ -0,0 +1 @@ +09 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass @@ -0,0 +1 @@ +00 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower new file mode 100644 index 0000000..ca2ea0d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower @@ -0,0 +1 @@ + 0mA diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumConfigurations b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumConfigurations new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumConfigurations @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces new file mode 100644 index 0000000..c6cf386 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces @@ -0,0 +1 @@ + 1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice new file mode 100644 index 0000000..ff5c161 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice @@ -0,0 +1 @@ +0206 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes new file mode 100644 index 0000000..425151f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes @@ -0,0 +1 @@ +40 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bus new file mode 120000 index 0000000..77682fa --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bus @@ -0,0 +1 @@ +../../../../bus/usb \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/driver b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/driver new file mode 120000 index 0000000..0b3eba3 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/driver @@ -0,0 +1 @@ +../../../../bus/usb/drivers/usb \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct new file mode 100644 index 0000000..739d797 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct @@ -0,0 +1 @@ +0000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor new file mode 100644 index 0000000..739d797 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor @@ -0,0 +1 @@ +0000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/manufacturer b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/manufacturer new file mode 100644 index 0000000..7ea94ce --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/manufacturer @@ -0,0 +1 @@ +Linux 2.6.0-test9-bk16 ohci_hcd diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/product b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/product new file mode 100644 index 0000000..a1c773a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/product @@ -0,0 +1 @@ +OHCI Host Controller diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial new file mode 100644 index 0000000..1b7fda3 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial @@ -0,0 +1 @@ +0000:00:09.0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed @@ -0,0 +1 @@ +12 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/vendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/vendor new file mode 100644 index 0000000..fcfa779 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:09.0/vendor @@ -0,0 +1 @@ +0x1033 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/bus new file mode 120000 index 0000000..d621099 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/bus @@ -0,0 +1 @@ +../../../../bus/pci \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/class b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/class new file mode 100644 index 0000000..145a550 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/class @@ -0,0 +1 @@ +0x010000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/device b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/device new file mode 100644 index 0000000..c271a13 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/device @@ -0,0 +1 @@ +0x008f diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/driver b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/driver new file mode 120000 index 0000000..f6536ff --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/driver @@ -0,0 +1 @@ +../../../../bus/pci/drivers/aic7xxx \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/bus new file mode 120000 index 0000000..2edcea4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/bus @@ -0,0 +1 @@ +../../../../../../../bus/scsi \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/device_blocked b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/device_blocked new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/device_blocked @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/driver b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/driver new file mode 120000 index 0000000..5fbbc0f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/driver @@ -0,0 +1 @@ +../../../../../../../bus/scsi/drivers/sd \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/model b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/model new file mode 100644 index 0000000..392039b --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/model @@ -0,0 +1 @@ +ST336605LW !# diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/online b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/online new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/online @@ -0,0 +1 @@ +1 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/queue_depth b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/queue_depth new file mode 100644 index 0000000..f5c8955 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/queue_depth @@ -0,0 +1 @@ +32 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/rev b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/rev new file mode 100644 index 0000000..65dd514 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/rev @@ -0,0 +1 @@ +B245 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/scsi_level b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/scsi_level new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/scsi_level @@ -0,0 +1 @@ +4 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/type b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/type new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/type @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/vendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/vendor new file mode 100644 index 0000000..d87b2a5 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/vendor @@ -0,0 +1 @@ +IBM-ESXS diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/whitespace_test b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/whitespace_test new file mode 100644 index 0000000..e3d48f0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/whitespace_test @@ -0,0 +1 @@ +WHITE SPACE diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/irq b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/irq new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/irq @@ -0,0 +1 @@ +22 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/resource b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/resource new file mode 100644 index 0000000..2a3d654 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/resource @@ -0,0 +1,7 @@ +0x0000000000007400 0x00000000000074ff 0x0000000000000101 +0x0000000080a11000 0x0000000080a11fff 0x0000000000000204 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000080a40000 0x0000000080a5ffff 0x0000000000007200 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_device b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_device new file mode 100644 index 0000000..8419b39 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_device @@ -0,0 +1 @@ +0x0205 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_vendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_vendor new file mode 100644 index 0000000..7369ccd --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_vendor @@ -0,0 +1 @@ +0x1014 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/vendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/vendor new file mode 100644 index 0000000..a5d5704 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/vendor @@ -0,0 +1 @@ +0x9005 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/bus b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/bus new file mode 120000 index 0000000..4b20ef9 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/bus @@ -0,0 +1 @@ +../../../bus/pci \ No newline at end of file diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/class b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/class new file mode 100644 index 0000000..8b40e6a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/class @@ -0,0 +1 @@ +0x060400 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/device b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/device new file mode 100644 index 0000000..9fe3927 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/device @@ -0,0 +1 @@ +0x244e diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/irq b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/irq new file mode 100644 index 0000000..573541a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/irq @@ -0,0 +1 @@ +0 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/resource b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/resource new file mode 100644 index 0000000..f8f56ab --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/resource @@ -0,0 +1,12 @@ +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_device b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_device new file mode 100644 index 0000000..aa01954 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_device @@ -0,0 +1 @@ +0x0000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor new file mode 100644 index 0000000..aa01954 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor @@ -0,0 +1 @@ +0x0000 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/vendor b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/vendor new file mode 100644 index 0000000..ce6dc4d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/sys/devices/pci0000:00/0000:00:1e.0/vendor @@ -0,0 +1 @@ +0x8086 diff --git a/21cnbao/code/05/udev源代码/udev-114/test/udev-test.pl b/21cnbao/code/05/udev源代码/udev-114/test/udev-test.pl new file mode 100755 index 0000000..53499d8 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/udev-test.pl @@ -0,0 +1,1812 @@ +#!/usr/bin/perl + +# udev-test +# +# Provides automated testing of the udev binary. +# The whole test is self contained in this file, except the matching sysfs tree. +# Simply extend the @tests array, to add a new test variant. +# +# Every test is driven by its own temporary config file. +# This program prepares the environment, creates the config and calls udev. +# +# udev parses the rules, looks at the provided sysfs and +# first creates and then removes the device node. +# After creation and removal the result is checked against the +# expected value and the result is printed. +# +# Copyright (C) 2004-2006 Kay Sievers +# Copyright (C) 2004 Leann Ogasawara + +use warnings; +use strict; + +my $PWD = $ENV{PWD}; +my $sysfs = "sys/"; +my $udev_bin = "../test-udev"; +my $udev_root = "udev-root/"; # !!! directory will be removed !!! +my $udev_conf = "udev-test.conf"; +my $udev_rules = "udev-test.rules"; + +# uncomment following line to run udev with valgrind. +# Should make this a runtime option to the script someday... +#my $udev_bin = "valgrind --tool=memcheck --leak-check=yes ../udev"; + +my @tests = ( + { + desc => "label test of scsi disc (old key names)", + subsys => "block", + devpath => "/block/sda", + exp_name => "boot_disk" , + rules => < "label test of scsi disc (old key names)", + subsys => "block", + devpath => "/block/sda", + exp_name => "boot_disk" , + rules => < "label test of scsi disc", + subsys => "block", + devpath => "/block/sda", + exp_name => "boot_disk" , + rules => < "label test of scsi partition", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "label test of pattern match", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "label test of multiple sysfs files", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "label test of max sysfs files", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "catch device by *", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor/0" , + rules => < "catch device by * - take 2", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor/0" , + rules => < "catch device by ?", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor/0" , + rules => < "catch device by character class", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor/0" , + rules => < "replace kernel name", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + rules => < "Handle comment lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + rules => < "Handle comment lines in config file with whitespace (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + rules => < "Handle whitespace only lines (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "whitespace" , + rules => < "Handle empty lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + rules => < "Handle backslashed multi lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + rules => < "preserve backslashes, if they are not for a newline", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "aaa", + rules => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + rules => < "subdirectory handling", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "sub/direct/ory/visor" , + rules => < "parent device name match of scsi partition", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "first_disk3" , + rules => < "test substitution chars (old key names)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "Major:8:minor:3:kernelnumber:3:id:0:0:0:0" , + rules => < "test substitution chars", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "Major:8:minor:3:kernelnumber:3:id:0:0:0:0" , + rules => < "test substitution chars (with length limit)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "M8-m3-n3-b0:0-sIBM" , + rules => < "import of shell-value file", + subsys => "block", + devpath => "/block/sda", + exp_name => "subdir/info/node" , + rules => < "import of shell-value returned from program", + subsys => "block", + devpath => "/block/sda", + exp_name => "node12345678", + rules => < "sustitution of sysfs value (%s{file})", + subsys => "block", + devpath => "/block/sda", + exp_name => "disk-IBM-ESXS-sda" , + rules => < "program result substitution", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "special-device-3" , + rules => < "program result substitution (newline removal)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "newline_removed" , + rules => < "program result substitution", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "test-0:0:0:0" , + rules => < "program with escaped format char (tricky: callout returns format char!)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "escape-3" , + rules => < "program with lots of arguments", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "foo9" , + rules => < "program with subshell", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "bar9" , + rules => < "program arguments combined with apostrophes", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "foo7" , + rules => < "characters before the %c{N} substitution", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "my-foo9" , + rules => < "substitute the second to last argument", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "my-foo8" , + rules => < "test substitution by variable name", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "Major:8-minor:3-kernelnumber:3-id:0:0:0:0", + rules => < "test substitution by variable name 2", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "Major:8-minor:3-kernelnumber:3-id:0:0:0:0", + rules => < "test substitution by variable name 3", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "830:0:0:03" , + rules => < "test substitution by variable name 4", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "833" , + rules => < "test substitution by variable name 5", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "8330:0:0:0" , + rules => < "non matching SUBSYSTEMS for device with no parent", + subsys => "tty", + devpath => "/class/tty/console", + exp_name => "TTY", + rules => < "non matching SUBSYSTEMS", + subsys => "tty", + devpath => "/class/tty/console", + exp_name => "TTY" , + rules => < "ATTRS match", + subsys => "tty", + devpath => "/class/tty/console", + exp_name => "foo" , + rules => < "program and bus type match", + subsys => "block", + devpath => "/block/sda", + exp_name => "scsi-0:0:0:0" , + rules => < "create all possible partitions", + subsys => "block", + devpath => "/block/sda", + exp_name => "boot_disk15" , + exp_majorminor => "8:15", + rules => < "sysfs parent hierarchy", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + rules => < "name test with ! in the name", + subsys => "block", + devpath => "/block/rd!c0d0", + exp_name => "rd/c0d0" , + rules => < "name test with ! in the name, but no matching rule", + subsys => "block", + devpath => "/block/rd!c0d0", + exp_name => "rd/c0d0" , + rules => < "name test with ! in the name for a partition", + subsys => "block", + devpath => "/block/cciss!c0d0/cciss!c0d0p1", + exp_name => "cciss/c0d0p1" , + rules => < "KERNELS rule", + subsys => "block", + devpath => "/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "KERNELS wildcard all", + subsys => "block", + devpath => "/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "KERNELS wildcard partial", + subsys => "block", + devpath => "/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "KERNELS wildcard partial 2", + subsys => "block", + devpath => "/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "substitute attr with link target value (first match)", + subsys => "block", + devpath => "/block/sda", + exp_name => "driver-is-sd", + rules => < "substitute attr with link target value (currently selected device)", + subsys => "block", + devpath => "/block/sda", + exp_name => "driver-is-aic7xxx", + rules => < "ignore ATTRS attribute whitespace", + subsys => "block", + devpath => "/block/sda", + exp_name => "ignored", + rules => < "do not ignore ATTRS attribute whitespace", + subsys => "block", + devpath => "/block/sda", + exp_name => "matched-with-space", + rules => < "permissions USER=bad GROUP=name", + subsys => "tty", + devpath => "/class/tty/tty33", + exp_name => "tty33", + exp_perms => "0:0:0660", + rules => < "permissions OWNER=5000", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "5000::0660", + rules => < "permissions GROUP=100", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => ":100:0660", + rules => < "textual user id", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "nobody::0660", + rules => < "textual group id", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => ":daemon:0660", + rules => < "textual user/group id", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "root:mail:0660", + rules => < "permissions MODE=0777", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "::0777", + rules => < "permissions OWNER=5000 GROUP=100 MODE=0777", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "5000:100:0777", + rules => < "permissions OWNER to 5000", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "5000::", + rules => < "permissions GROUP to 100", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => ":100:0660", + rules => < "permissions MODE to 0060", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "::0060", + rules => < "permissions OWNER, GROUP, MODE", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "5000:100:0777", + rules => < "permissions only rule", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "5000:100:0777", + rules => < "multiple permissions only rule", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "3000:4000:0777", + rules => < "permissions only rule with override at NAME rule", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "3000:8000:0777", + rules => < "major/minor number test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_majorminor => "8:0", + rules => < "big minor number test", + subsys => "i2c-dev", + devpath => "/class/i2c-dev/i2c-300", + exp_name => "node", + exp_majorminor => "89:300", + rules => < "big major number test", + subsys => "i2c-dev", + devpath => "/class/i2c-dev/i2c-fake1", + exp_name => "node", + exp_majorminor => "4095:1", + rules => < "big major and big minor number test", + subsys => "i2c-dev", + devpath => "/class/i2c-dev/i2c-fake2", + exp_name => "node", + exp_majorminor => "4094:89999", + rules => < "multiple symlinks with format char", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "symlink2-ttyUSB0", + exp_target => "ttyUSB0", + rules => < "multiple symlinks with a lot of s p a c e s", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "one", + not_exp_name => " ", + exp_target => "ttyUSB0", + rules => < "symlink creation (same directory)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor0", + exp_target => "ttyUSB0", + rules => < "symlink creation (relative link forward)", + subsys => "block", + devpath => "/block/sda/sda2", + exp_name => "1/2/symlink" , + exp_target => "a/b/node", + rules => < "symlink creation (relative link back and forward)", + subsys => "block", + devpath => "/block/sda/sda2", + exp_name => "1/2/c/d/symlink" , + exp_target => "../../a/b/node", + rules => < "multiple symlinks", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "second-0" , + exp_target => "visor" , + rules => < "symlink only rule", + subsys => "block", + devpath => "/block/sda", + exp_name => "symlink-only2", + exp_target => "link", + rules => < "symlink name '.'", + subsys => "block", + devpath => "/block/sda", + exp_name => ".", + exp_target => "link", + exp_add_error => "yes", + exp_rem_error => "yes", + rules => < "symlink node to itself", + subsys => "tty", + devpath => "/class/tty/tty0", + exp_name => "link", + exp_target => "link", + exp_add_error => "yes", + exp_rem_error => "yes", + option => "clean", + rules => < "symlink %n substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "symlink0", + exp_target => "ttyUSB0", + rules => < "symlink %k substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "symlink-ttyUSB0", + exp_target => "ttyUSB0", + rules => < "symlink %M:%m substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "major-188:0", + exp_target => "ttyUSB0", + rules => < "symlink %b substitution", + subsys => "block", + devpath => "/block/sda", + exp_name => "symlink-0:0:0:0", + exp_target => "node", + rules => < "symlink %c substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "test", + exp_target => "ttyUSB0", + rules => < "symlink %c{N} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "test", + exp_target => "ttyUSB0", + rules => < "symlink %c{N+} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "this", + exp_target => "ttyUSB0", + rules => < "symlink only rule with %c{N+}", + subsys => "block", + devpath => "/block/sda", + exp_name => "test", + exp_target => "link", + rules => < "symlink %s{filename} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "188:0", + exp_target => "ttyUSB0", + rules => < "symlink %Ns{filename} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "188", + exp_target => "ttyUSB0", + rules => < "program result substitution (numbered part of)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "link1", + exp_target => "node", + rules => < "program result substitution (numbered part of+)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "link4", + exp_target => "node", + rules => < "ignore rule test", + subsys => "block", + devpath => "/block/sda", + exp_name => "nothing", + not_exp_name => "node", + exp_add_error => "yes", + rules => < "all_partitions, option-only rule", + subsys => "block", + devpath => "/block/sda", + exp_name => "node6", + rules => < "all_partitions, option-only rule (fail on partition)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "node6", + exp_add_error => "yes", + rules => < "ignore remove event test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_rem_error => "yes", + rules => < "ignore remove event test (with all partitions)", + subsys => "block", + devpath => "/block/sda", + exp_name => "node14", + exp_rem_error => "yes", + option => "clean", + rules => < "SUBSYSTEM match test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + rules => < "DRIVERS match test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + rules => < "temporary node creation test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + rules => < "devpath substitution test", + subsys => "block", + devpath => "/block/sda", + exp_name => "sda", + rules => < "parent node name substitution test sequence 1/2 (keep)", + subsys => "block", + devpath => "/block/sda", + exp_name => "main_device", + option => "keep", + rules => < "parent node name substitution test sequence 2/2 (clean)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "main_device-part-1", + option => "clean", + rules => < "udev_root substitution", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "start-udev-root-end", + rules => < "last_rule option", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "last", + rules => < "negation KERNEL!=", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "match", + rules => < "negation SUBSYSTEM!=", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "not-anything", + rules => < "negation PROGRAM!= exit code", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "nonzero-program", + rules => < "test for whitespace between the operator", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test (assign)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test (assign 2 times)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test (assign2)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "part", + rules => < "untrusted string sanitize", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "sane", + rules => < "untrusted string sanitize (don't replace utf8)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "uber", + rules => < "untrusted string sanitize (replace invalid utf8)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "replaced", + rules => < "read sysfs value from device down in the chain", + subsys => "block", + devpath => "/class/tty/ttyUSB0", + exp_name => "serial-0000:00:09.0", + rules => < "match against empty key string", + subsys => "block", + devpath => "/block/sda", + exp_name => "ok", + rules => < "check ACTION value", + subsys => "block", + devpath => "/block/sda", + exp_name => "ok", + rules => < "apply NAME only once", + subsys => "block", + devpath => "/block/sda", + exp_name => "link", + exp_target => "ok", + rules => < "test RUN key", + subsys => "block", + devpath => "/block/sda", + exp_name => "testsymlink", + exp_target => "ok", + exp_rem_error => "yes", + option => "clean", + rules => < "test RUN key and DEVNAME", + subsys => "block", + devpath => "/block/sda", + exp_name => "testsymlink", + exp_target => "ok", + exp_rem_error => "yes", + option => "clean", + rules => < "test RUN key remove", + subsys => "block", + devpath => "/block/sda", + exp_name => "testsymlink2", + exp_target => "ok2", + rules => < "final assignment", + subsys => "block", + devpath => "/block/sda", + exp_name => "ok", + exp_perms => "root:nobody:0640", + rules => < "final assignment", + subsys => "block", + devpath => "/block/sda", + exp_name => "ok", + exp_perms => "root:nobody:0640", + rules => < "env substitution", + subsys => "block", + devpath => "/block/sda", + exp_name => "node-add-me", + rules => < "reset list to current value", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "three", + not_exp_name => "two", + exp_target => "node", + rules => < "test empty NAME", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "node", + not_exp_name => "wrong", + exp_add_error => "yes", + rules => < "test empty NAME 2", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "right", + rules => < "test multi matches", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "right", + rules => < "test multi matches 2", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "right", + rules => < "IMPORT parent test sequence 1/2 (keep)", + subsys => "block", + devpath => "/block/sda", + exp_name => "parent", + option => "keep", + rules => < "IMPORT parent test sequence 2/2 (keep)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "parentenv-parent_right", + option => "clean", + rules => < "GOTO test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "right", + rules => < "NAME compare test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "link", + exp_target => "node", + not_exp_name => "wronglink", + rules => < "NAME compare test 2", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "link2", + exp_target => "sda1", + not_exp_name => "link", + rules => < "invalid key operation", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "yes", + rules => < "operator chars in attribute", + subsys => "block", + devpath => "/block/sda", + exp_name => "yes", + rules => < "overlong comment line", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "yes", + rules => < "magic subsys/kernel lookup", + subsys => "block", + devpath => "/block/sda", + exp_name => "00:e0:00:fb:04:e1", + rules => <$udev_rules" || die "unable to create rules file: $udev_rules"; + print CONF $$rules; + close CONF; + + $ENV{ACTION} = $action; + system("$udev_bin $subsys"); +} + +my $error = 0; + +sub permissions_test { + my($rules, $uid, $gid, $mode) = @_; + + my $wrong = 0; + my $userid; + my $groupid; + + $rules->{exp_perms} =~ m/^(.*):(.*):(.*)$/; + if ($1 ne "") { + if (defined(getpwnam($1))) { + $userid = int(getpwnam($1)); + } else { + $userid = $1; + } + if ($uid != $userid) { $wrong = 1; } + } + if ($2 ne "") { + if (defined(getgrnam($2))) { + $groupid = int(getgrnam($2)); + } else { + $groupid = $2; + } + if ($gid != $groupid) { $wrong = 1; } + } + if ($3 ne "") { + if (($mode & 07777) != oct($3)) { $wrong = 1; }; + } + if ($wrong == 0) { + print "permissions: ok\n"; + } else { + printf " expected permissions are: %s:%s:%#o\n", $1, $2, oct($3); + printf " created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; + print "permissions: error\n"; + $error++; + } +} + +sub major_minor_test { + my($rules, $rdev) = @_; + + my $major = ($rdev >> 8) & 0xfff; + my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00); + my $wrong = 0; + + $rules->{exp_majorminor} =~ m/^(.*):(.*)$/; + if ($1 ne "") { + if ($major != $1) { $wrong = 1; }; + } + if ($2 ne "") { + if ($minor != $2) { $wrong = 1; }; + } + if ($wrong == 0) { + print "major:minor: ok\n"; + } else { + printf " expected major:minor is: %i:%i\n", $1, $2; + printf " created major:minor is : %i:%i\n", $major, $minor; + print "major:minor: error\n"; + $error++; + } +} + +sub symlink_test { + my ($rules) = @_; + + my $output = `ls -l $PWD/$udev_root$rules->{exp_name}`; + + if ($output =~ m/(.*)-> (.*)/) { + if ($2 eq $rules->{exp_target}) { + print "symlink: ok\n"; + } else { + print " expected symlink from: \'$rules->{exp_name}\' to \'$rules->{exp_target}\'\n"; + print " created symlink from: \'$rules->{exp_name}\' to \'$2\'\n"; + print "symlink: error"; + if ($rules->{exp_add_error}) { + print " as expected\n"; + } else { + print "\n"; + $error++; + } + } + } else { + print " expected symlink from: \'$rules->{exp_name}\' to \'$rules->{exp_target}\'\n"; + print "symlink: not created"; + if ($rules->{exp_add_error}) { + print " as expected\n"; + } else { + print "\n"; + $error++; + } + } +} + +sub run_test { + my ($rules, $number) = @_; + + print "TEST $number: $rules->{desc}\n"; + + if ($rules->{exp_target}) { + print "device \'$rules->{devpath}\' expecting symlink '$rules->{exp_name}' to node \'$rules->{exp_target}\'\n"; + } else { + print "device \'$rules->{devpath}\' expecting node \'$rules->{exp_name}\'\n"; + } + + + udev("add", $rules->{subsys}, $rules->{devpath}, \$rules->{rules}); + if ((-e "$PWD/$udev_root$rules->{exp_name}") || + (-l "$PWD/$udev_root$rules->{exp_name}")) { + + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, + $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$rules->{exp_name}"); + + if (defined($rules->{not_exp_name})) { + if ((-e "$PWD/$udev_root$rules->{not_exp_name}") || + (-l "$PWD/$udev_root$rules->{not_exp_name}")) { + print "nonexistent: error \'$rules->{not_exp_name}\' not expected to be there\n"; + $error++ + } + } + if (defined($rules->{exp_perms})) { + permissions_test($rules, $uid, $gid, $mode); + } + if (defined($rules->{exp_majorminor})) { + major_minor_test($rules, $rdev); + } + if (defined($rules->{exp_target})) { + symlink_test($rules); + } + print "add: ok\n"; + } else { + print "add: error"; + if ($rules->{exp_add_error}) { + print " as expected\n"; + } else { + print "\n"; + system("tree $udev_root"); + print "\n"; + $error++; + } + } + + if (defined($rules->{option}) && $rules->{option} eq "keep") { + print "\n\n"; + return; + } + + udev("remove", $rules->{subsys}, $rules->{devpath}, \$rules->{rules}); + if ((-e "$PWD/$udev_root$rules->{exp_name}") || + (-l "$PWD/$udev_root$rules->{exp_name}")) { + print "remove: error"; + if ($rules->{exp_rem_error}) { + print " as expected\n"; + } else { + print "\n"; + system("tree $udev_root"); + print "\n"; + $error++; + } + } else { + print "remove: ok\n"; + } + + print "\n"; + + if (defined($rules->{option}) && $rules->{option} eq "clean") { + system("rm -rf $udev_root"); + mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; + } + +} + +# only run if we have root permissions +# due to mknod restrictions +if (!($<==0)) { + print "Must have root permissions to run properly.\n"; + exit; +} + +# prepare +system("rm -rf $udev_root"); +mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; + +# create config file +open CONF, ">$udev_conf" || die "unable to create config file: $udev_conf"; +print CONF "udev_root=\"$udev_root\"\n"; +print CONF "udev_rules=\"$udev_rules\"\n"; +print CONF "udev_log=\"info\"\n"; +close CONF; + +my $test_num = 1; + +if ($ARGV[0]) { + # only run one test + $test_num = $ARGV[0]; + + if (defined($tests[$test_num-1]->{desc})) { + print "udev-test will run test number $test_num only:\n\n"; + run_test($tests[$test_num-1], $test_num); + } else { + print "test does not exist.\n"; + } +} else { + # test all + print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; + + foreach my $rules (@tests) { + run_test($rules, $test_num); + $test_num++; + } +} + +print "$error errors occured\n\n"; + +# cleanup +system("rm -rf $udev_root"); +unlink($udev_rules); +unlink($udev_conf); + diff --git a/21cnbao/code/05/udev源代码/udev-114/test/udevstart-test.pl b/21cnbao/code/05/udev源代码/udev-114/test/udevstart-test.pl new file mode 100755 index 0000000..6829bc0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/test/udevstart-test.pl @@ -0,0 +1,61 @@ +#!/usr/bin/perl + +# udevstart-test +# +# runs udevstart in a temporary directory with our test sysfs-tree +# and counts the created nodes to compare it with the expected numbers. +# +# Kay Sievers , 2005 +# + +use warnings; +use strict; + +my $PWD = $ENV{PWD}; +my $sysfs = "sys/"; +my $udevstart_bin = "../udevstart"; +my $udev_root = "udev-root/"; # !!! directory will be removed !!! +my $udev_db = ".udevdb"; +my $udev_conf = "udev-test.conf"; +my $udev_rules = "udev-test.rules"; + +# set env +$ENV{SYSFS_PATH} = $sysfs; +$ENV{UDEV_CONFIG_FILE} = $udev_conf; + +# due to mknod restrictions +if (!($<==0)) { + print "Must have root permissions to run properly.\n"; + exit; +} + +# prepare +system("rm -rf $udev_root"); +mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; + +# create config file +open CONF, ">$udev_conf" || die "unable to create config file: $udev_conf"; +print CONF "udev_root=\"$udev_root\"\n"; +print CONF "udev_db=\"$udev_db\"\n"; +print CONF "udev_rules=\"$udev_rules\"\n"; +close CONF; + +# create rules file +open RULES, ">$udev_rules" || die "unable to create rules file: $udev_rules"; +print RULES "\n"; +close RULES; + +system("$udevstart_bin"); +my $block = int(`find $udev_root -type b -print | wc -l`); +my $char = int(`find $udev_root -type c -print | wc -l`); + +print "block devices: $block/10\n"; +print "char devices: $char/91\n"; +print "\n"; + +# cleanup +system("rm -rf $udev_db"); +system("rm -rf $udev_root"); +unlink($udev_rules); +unlink($udev_conf); + diff --git a/21cnbao/code/05/udev源代码/udev-114/udev.7 b/21cnbao/code/05/udev源代码/udev-114/udev.7 new file mode 100644 index 0000000..821a476 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev.7 @@ -0,0 +1,418 @@ +.\" Title: udev +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: August 2005 +.\" Manual: udev +.\" Source: udev +.\" +.TH "UDEV" "7" "August 2005" "udev" "udev" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udev \- dynamic device management +.SH "DESCRIPTION" +.PP +udev provides a dynamic device directory containing only the files for actually present devices. It creates or removes device node files in the +\fI/dev\fR +directory, or it renames network interfaces. +.PP +Usually udev runs as +\fBudevd\fR(8) +and receives uevents directly from the kernel if a device is added or removed from the system. +.PP +If udev receives a device event, it matches its configured rules against the available device attributes provided in sysfs to identify the device. Rules that match may provide additional device information or specify a device node name and multiple symlink names and instruct udev to run additional programs as part of the device event handling. +.SH "CONFIGURATION" +.PP +All udev configuration files are placed in +\fI/etc/udev/*\fR. Every file consists of a set of lines of text. All empty lines or lines beginning with '#' will be ignored. +.SS "Configuration file" +.PP +udev expects its main configuration file at +\fI/etc/udev/udev.conf\fR. It consists of a set of variables allowing the user to override default udev values. The following variables can be set: +.PP +\fBudev_root\fR +.RS 4 +Specifies where to place the device nodes in the filesystem. The default value is +\fI/dev\fR. +.RE +.PP +\fBudev_rules\fR +.RS 4 +The name of the udev rules file or directory to look for files with the suffix +\fI.rules\fR. Multiple rule files are read in lexical order. The default value is +\fI/etc/udev/rules.d\fR. +.RE +.PP +\fBudev_log\fR +.RS 4 +The logging priority. Valid values are the numerical syslog priorities or their textual representations: +\fBerr\fR, +\fBinfo\fR +and +\fBdebug\fR. +.RE +.SS "Rules files" +.PP +The udev rules are read from the files located in the +\fI/etc/udev/rules.d\fR +directory or at the location specified value in the configuration file. Every line in the rules file contains at least one key value pair. There are two kind of keys, match and assignment keys. If all match keys are matching against its value, the rule gets applied and the assign keys get the specified value assigned. +.PP +A matching rule may specify the name of the device node, add a symlink pointing to the node, or run a specified program as part of the event handling. If no matching rule is found, the default device node name is used. +.PP +A rule may consist of a list of one or more key value pairs separated by a comma. Each key has a distinct operation, depending on the used operator. Valid operators are: +.PP +\fB==\fR +.RS 4 +Compare for equality. +.RE +.PP +\fB!=\fR +.RS 4 +Compare for non\-equality. +.RE +.PP +\fB=\fR +.RS 4 +Assign a value to a key. Keys that represent a list, are reset and only this single value is assigned. +.RE +.PP +\fB+=\fR +.RS 4 +Add the value to a key that holds a list of entries. +.RE +.PP +\fB:=\fR +.RS 4 +Assign a value to a key finally; disallow any later changes, which may be used to prevent changes by any later rules. +.RE +.PP +The following key names can be used to match against device properties. Some of the keys also match against properties of the parent devices in sysfs, not only the device that has generated the event. If multiple keys that match a parent device are specified in a single rule, all these keys must match at one and the same parent device. +.PP +\fBACTION\fR +.RS 4 +Match the name of the event action. +.RE +.PP +\fBDEVPATH\fR +.RS 4 +Match the devpath of the event device. +.RE +.PP +\fBKERNEL\fR +.RS 4 +Match the name of the event device. +.RE +.PP +\fBSUBSYSTEM\fR +.RS 4 +Match the subsystem of the event device. +.RE +.PP +\fBDRIVER\fR +.RS 4 +Match the driver name of the event device. Only set for devices which are bound to a driver at the time the event is generated. +.RE +.PP +\fBATTR{\fR\fB\fIfilename\fR\fR\fB}\fR +.RS 4 +Match sysfs attribute values of the event device. Up to five +\fBATTR\fR +keys can be specified per rule. Trailing whitespace in the attribute values is ignored, if the specified match value does not contain trailing whitespace itself. Depending on the type of operator, this key is also used to set the value of a sysfs attribute. +.RE +.PP +\fBKERNELS\fR +.RS 4 +Search the devpath upwards for a matching device name. +.RE +.PP +\fBSUBSYSTEMS\fR +.RS 4 +Search the devpath upwards for a matching device subsystem name. +.RE +.PP +\fBDRIVERS\fR +.RS 4 +Search the devpath upwards for a matching device driver name. +.RE +.PP +\fBATTRS{\fR\fB\fIfilename\fR\fR\fB}\fR +.RS 4 +Search the devpath upwards for a device with matching sysfs attribute values. Up to five +\fBATTRS\fR +keys can be specified per rule, but all of them must match on the same device. Trailing whitespace in the attribute values is ignored, if the specified match value does not contain trailing whitespace itself. +.RE +.PP +\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR +.RS 4 +Match against the value of an environment variable. Up to five +\fBENV\fR +keys can be specified per rule. Depending on the type of operator, this key is also used to export a variable to the environment. +.RE +.PP +\fBTEST{\fR\fB\fIoctal mode mask\fR\fR\fB}\fR +.RS 4 +Test the existence of a file. An octal mode mask can be specified if needed. +.RE +.PP +\fBPROGRAM\fR +.RS 4 +Execute external program. The key is true, if the program returns with exit code zero. The whole event environment is available to the executed program. The program's output printed to stdout, is available in the RESULT key. +.RE +.PP +\fBRESULT\fR +.RS 4 +Match the returned string of the last PROGRAM call. This key can be used in the same or in any later rule after a PROGRAM call. +.RE +.PP +Most of the fields support a shell style pattern matching. The following pattern characters are supported: +.PP +\fB*\fR +.RS 4 +Matches zero, or any number of characters. +.RE +.PP +\fB?\fR +.RS 4 +Matches any single character. +.RE +.PP +\fB[]\fR +.RS 4 +Matches any single character specified within the brackets. For example, the pattern string 'tty[SR]' would match either 'ttyS' or 'ttyR'. Ranges are also supported within this match with the '\-' character. For example, to match on the range of all digits, the pattern [0\-9] would be used. If the first character following the '[' is a '!', any characters not enclosed are matched. +.RE +.PP +The following keys can get values assigned: +.PP +\fBNAME\fR +.RS 4 +The name of the node to be created, or the name the network interface should be renamed to. Only one rule can set the node name, all later rules with a NAME key will be ignored. +.RE +.PP +\fBSYMLINK\fR +.RS 4 +The name of a symlink targeting the node. Every matching rule can add this value to the list of symlinks to be created along with the device node. Multiple symlinks may be specified by separating the names by the space character. +.RE +.PP +\fBOWNER, GROUP, MODE\fR +.RS 4 +The permissions for the device node. Every specified value overwrites the compiled\-in default value. +.RE +.PP +\fBATTR{\fR\fB\fIkey\fR\fR\fB}\fR +.RS 4 +The value that should be written to a sysfs attribute of the event device. Depending on the type of operator, this key is also used to match against the value of a sysfs attribute. +.RE +.PP +\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR +.RS 4 +Export a variable to the environment. Depending on the type of operator, this key is also to match against an environment variable. +.RE +.PP +\fBRUN\fR +.RS 4 +Add a program to the list of programs to be executed for a specific device. This can only be used for very short running tasks. Running an event process for a long period of time may block all further events for this or a dependent device. Long running tasks need to be immediately detached from the event process itself. +.RE +.PP +\fBLABEL\fR +.RS 4 +Named label where a GOTO can jump to. +.RE +.PP +\fBGOTO\fR +.RS 4 +Jumps to the next LABEL with a matching name +.RE +.PP +\fBIMPORT{\fR\fB\fItype\fR\fR\fB}\fR +.RS 4 +Import a set of variables into the event environment, depending on +\fItype\fR: +.RS 4 +.PP +\fBprogram\fR +.RS 4 +Execute an external program specified as the assigned value and import its output, which must be in environment key format. +.RE +.PP +\fBfile\fR +.RS 4 +Import a text file specified as the assigned value, which must be in environment key format. +.RE +.PP +\fBparent\fR +.RS 4 +Import the stored keys from the parent device by reading the database entry of the parent device. The value assigned to +\fBIMPORT{parent}\fR +is used as a filter of key names to import (with the same shell\-style pattern matching used for comparisons). +.RE +.RE +.IP "" 4 +If no option is given, udev will choose between +\fBprogram\fR +and +\fBfile\fR +based on the executable bit of the file permissions. +.RE +.PP +\fBWAIT_FOR_SYSFS\fR +.RS 4 +Wait for the specified sysfs file of the device to be created. Can be used to fight against kernel sysfs timing issues. +.RE +.PP +\fBOPTIONS\fR +.RS 4 +Rule and device options: +.RS 4 +.PP +\fBlast_rule\fR +.RS 4 +Stops further rules application. No later rules will have any effect. +.RE +.PP +\fBignore_device\fR +.RS 4 +Ignore this event completely. +.RE +.PP +\fBignore_remove\fR +.RS 4 +Ignore any later remove event for this device. This may be useful as a workaround for broken device drivers. +.RE +.PP +\fBlink_priority=\fR\fB\fIvalue\fR\fR +.RS 4 +Specify the priority of the created symlinks. Devices with higher priorities overwrite existing symlinks of other devices. +.RE +.PP +\fBall_partitions\fR +.RS 4 +Create the device nodes for all available partitions of a block device. This may be useful for removable media devices where media changes are not detected. +.RE +.PP +\fBstring_escape=\fR\fB\fInone|replace\fR\fR +.RS 4 +Usually control and other possibly unsafe characters are replaced in strings used for device naming. The mode of replacement can be specified with this option. +.RE +.RE +.RE +.PP +The +\fBNAME\fR, +\fBSYMLINK\fR, +\fBPROGRAM\fR, +\fBOWNER\fR, +\fBGROUP\fR +and +\fBRUN\fR +fields support simple printf\-like string substitutions. The +\fBRUN\fR +format chars gets applied after all rules have been processed, right before the program is executed. It allows the use of the complete environment set by earlier matching rules. For all other fields, substitutions are applied while the individual rule is being processed. The available substitutions are: +.PP +\fB$kernel\fR, \fB%k\fR +.RS 4 +The kernel name for this device. +.RE +.PP +\fB$number\fR, \fB%n\fR +.RS 4 +The kernel number for this device. For example, 'sda3' has kernel number of '3' +.RE +.PP +\fB$devpath\fR, \fB%p\fR +.RS 4 +The devpath of the device. +.RE +.PP +\fB$id\fR, \fB%b\fR +.RS 4 +The name of the device matched while searching the devpath upwards for +\fBSUBSYSTEMS\fR, +\fBKERNELS\fR, +\fBDRIVERS\fR +and +\fBATTRS\fR. +.RE +.PP +\fB$driver\fR, \fB%d\fR +.RS 4 +The driver name of the device matched while searching the devpath upwards for +\fBSUBSYSTEMS\fR, +\fBKERNELS\fR, +\fBDRIVERS\fR +and +\fBATTRS\fR. +.RE +.PP +\fB$attr{\fR\fB\fIfile\fR\fR\fB}\fR, \fB%s{\fR\fB\fIfile\fR\fR\fB}\fR +.RS 4 +The value of a sysfs attribute found at the device, where all keys of the rule have matched. If the matching device does not have such an attribute, all devices along the chain of parents are searched for a matching attribute. If the attribute is a symlink, the last element of the symlink target is returned as the value. +.RE +.PP +\fB$env{\fR\fB\fIkey\fR\fR\fB}\fR, \fB%E{\fR\fB\fIkey\fR\fR\fB}\fR +.RS 4 +The value of an environment variable. +.RE +.PP +\fB$major\fR, \fB%M\fR +.RS 4 +The kernel major number for the device. +.RE +.PP +\fB$minor\fR, \fB%m\fR +.RS 4 +The kernel minor number for the device. +.RE +.PP +\fB$result\fR, \fB%c\fR +.RS 4 +The string returned by the external program requested with PROGRAM. A single part of the string, separated by a space character may be selected by specifying the part number as an attribute: +\fB%c{N}\fR. If the number is followed by the '+' char this part plus all remaining parts of the result string are substituted: +\fB%c{N+}\fR +.RE +.PP +\fB$parent\fR, \fB%P\fR +.RS 4 +The node name of the parent device. +.RE +.PP +\fB$root\fR, \fB%r\fR +.RS 4 +The udev_root value. +.RE +.PP +\fB$sys\fR, \fB%S\fR +.RS 4 +The sysfs mount point. +.RE +.PP +\fB$tempnode\fR, \fB%N\fR +.RS 4 +The name of a created temporary device node to provide access to the device from a external program before the real node is created. +.RE +.PP +\fB%%\fR +.RS 4 +The '%' character itself. +.RE +.PP +\fB$$\fR +.RS 4 +The '$' character itself. +.RE +.PP +The count of characters to be substituted may be limited by specifying the format length value. For example, '%3s{file}' will only insert the first three characters of the sysfs attribute +.SH "AUTHOR" +.PP +Written by Greg Kroah\-Hartman + +and Kay Sievers +. With much help from Dan Stekloff + +and many others. +.SH "SEE ALSO" +.PP +\fBudevd\fR(8), +\fBudevinfo\fR(8), +\fBudevmonitor\fR(8) diff --git a/21cnbao/code/05/udev源代码/udev-114/udev.h b/21cnbao/code/05/udev源代码/udev-114/udev.h new file mode 100644 index 0000000..f13eb83 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef _UDEV_H_ +#define _UDEV_H_ + +#include +#include + +#include "list.h" +#include "logging.h" +#include "udev_sysdeps.h" +#include "udev_version.h" + +#define COMMENT_CHARACTER '#' +#define LINE_SIZE 512 +#define PATH_SIZE 512 +#define NAME_SIZE 256 +#define VALUE_SIZE 128 + +#define ALLOWED_CHARS "#+-.:=@_" +#define ALLOWED_CHARS_FILE ALLOWED_CHARS "/" +#define ALLOWED_CHARS_INPUT ALLOWED_CHARS_FILE " $%?," + +#define DEFAULT_PARTITIONS_COUNT 15 +#define UDEV_ALARM_TIMEOUT 180 + +#define UDEV_MAX(a,b) ((a) > (b) ? (a) : (b)) + +/* pipes */ +#define READ_END 0 +#define WRITE_END 1 + +#define DB_DIR ".udev/db" +#define DB_NAME_INDEX_DIR ".udev/names" +#define RULES_DYN_DIR ".udev/rules.d" + +struct udev_rules; + +struct sysfs_device { + struct list_head node; /* for device cache */ + struct sysfs_device *parent; /* already cached parent*/ + char devpath[PATH_SIZE]; + char subsystem[NAME_SIZE]; /* $class, $bus, drivers, module */ + char kernel[NAME_SIZE]; /* device instance name */ + char kernel_number[NAME_SIZE]; + char driver[NAME_SIZE]; /* device driver name */ +}; + +struct udevice { + /* device event */ + struct sysfs_device *dev; /* points to dev_local by default */ + struct sysfs_device dev_local; + struct sysfs_device *dev_parent; /* current parent device used for matching */ + char action[NAME_SIZE]; + + /* node */ + char name[PATH_SIZE]; + struct list_head symlink_list; + int symlink_final; + char owner[NAME_SIZE]; + int owner_final; + char group[NAME_SIZE]; + int group_final; + mode_t mode; + int mode_final; + dev_t devt; + + /* event processing */ + struct list_head run_list; + int run_final; + struct list_head env_list; + char tmp_node[PATH_SIZE]; + int partitions; + int ignore_device; + int ignore_remove; + char program_result[PATH_SIZE]; + int link_priority; + int test_run; +}; + +/* udev_config.c */ +extern char udev_root[PATH_SIZE]; +extern char udev_config_filename[PATH_SIZE]; +extern char udev_rules_dir[PATH_SIZE]; +extern int udev_log_priority; +extern int udev_run; +extern void udev_config_init(void); + +/* udev_device.c */ +extern struct udevice *udev_device_init(struct udevice *udev); +extern void udev_device_cleanup(struct udevice *udev); +extern int udev_device_event(struct udev_rules *rules, struct udevice *udev); +extern dev_t udev_device_get_devt(struct udevice *udev); + +/* udev_sysfs.c */ +extern char sysfs_path[PATH_SIZE]; +extern int sysfs_init(void); +extern void sysfs_cleanup(void); +extern void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath, + const char *subsystem, const char *driver); +extern struct sysfs_device *sysfs_device_get(const char *devpath); +extern struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev); +extern struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device *dev, const char *subsystem); +extern char *sysfs_attr_get_value(const char *devpath, const char *attr_name); +extern int sysfs_resolve_link(char *path, size_t size); +extern int sysfs_lookup_devpath_by_subsys_id(char *devpath, size_t len, const char *subsystem, const char *id); + +/* udev_node.c */ +extern int udev_node_mknod(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); +extern void udev_node_update_symlinks(struct udevice *udev, struct udevice *udev_old); +extern int udev_node_add(struct udevice *udev); +extern int udev_node_remove(struct udevice *udev); + +/* udev_db.c */ +extern int udev_db_add_device(struct udevice *dev); +extern int udev_db_delete_device(struct udevice *dev); +extern int udev_db_get_device(struct udevice *udev, const char *devpath); +extern int udev_db_get_devices_by_name(const char *name, struct list_head *name_list); +extern int udev_db_get_all_entries(struct list_head *name_list); + +/* udev_utils.c */ +struct name_entry { + struct list_head node; + char name[PATH_SIZE]; + unsigned int ignore_error:1; +}; + +extern int log_priority(const char *priority); +extern struct name_entry *name_list_add(struct list_head *name_list, const char *name, int sort); +extern struct name_entry *name_list_key_add(struct list_head *name_list, const char *key, const char *value); +extern int name_list_key_remove(struct list_head *name_list, const char *key); +extern void name_list_cleanup(struct list_head *name_list); +extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); +extern uid_t lookup_user(const char *user); +extern gid_t lookup_group(const char *group); + +/* udev_utils_string.c */ +extern int string_is_true(const char *str); +extern void remove_trailing_chars(char *path, char c); +extern size_t path_encode(char *s, size_t len); +extern size_t path_decode(char *s); +extern int utf8_encoded_valid_unichar(const char *str); +extern int replace_chars(char *str, const char *white); + +/* udev_utils_file.c */ +extern int create_path(const char *path); +extern int delete_path(const char *path); +extern int file_map(const char *filename, char **buf, size_t *bufsize); +extern void file_unmap(void *buf, size_t bufsize); +extern int unlink_secure(const char *filename); +extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); + +#endif diff --git a/21cnbao/code/05/udev源代码/udev-114/udev.xml b/21cnbao/code/05/udev源代码/udev-114/udev.xml new file mode 100644 index 0000000..b43abb7 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev.xml @@ -0,0 +1,612 @@ + + + +
    +
    + udev + + + udev + August 2005 + udev + + + + udev + 7 + + + + + udev + dynamic device management + + + DESCRIPTION + udev provides a dynamic device directory containing only the files for + actually present devices. It creates or removes device node files in the + /dev directory, or it renames network interfaces. + + Usually udev runs as udevd + 8 and receives uevents directly from the + kernel if a device is added or removed from the system. + + If udev receives a device event, it matches its configured rules + against the available device attributes provided in sysfs to identify the device. + Rules that match may provide additional device information or specify a device + node name and multiple symlink names and instruct udev to run additional programs + as part of the device event handling. + + + CONFIGURATION + All udev configuration files are placed in /etc/udev/*. + Every file consists of a set of lines of text. All empty lines or lines beginning + with '#' will be ignored. + + Configuration file + udev expects its main configuration file at /etc/udev/udev.conf. + It consists of a set of variables allowing the user to override default udev values. + The following variables can be set: + + + + + Specifies where to place the device nodes in the filesystem. + The default value is /dev. + + + + + + + The name of the udev rules file or directory to look for files + with the suffix .rules. Multiple rule files are + read in lexical order. The default value is + /etc/udev/rules.d. + + + + + + + The logging priority. Valid values are the numerical syslog priorities + or their textual representations: , + and . + + + + + + Rules files + The udev rules are read from the files located in the + /etc/udev/rules.d directory or at the location specified + value in the configuration file. Every line in the rules file contains at least + one key value pair. There are two kind of keys, match and assignment keys. + If all match keys are matching against its value, the rule gets applied and the + assign keys get the specified value assigned. + + A matching rule may specify the name of the device node, add a symlink + pointing to the node, or run a specified program as part of the event handling. + If no matching rule is found, the default device node name is used. + + A rule may consist of a list of one or more key value pairs separated by + a comma. Each key has a distinct operation, depending on the used operator. Valid + operators are: + + + + + Compare for equality. + + + + + + + Compare for non-equality. + + + + + + + Assign a value to a key. Keys that represent a list, are reset + and only this single value is assigned. + + + + + + + Add the value to a key that holds a list of entries. + + + + + + + Assign a value to a key finally; disallow any later changes, + which may be used to prevent changes by any later rules. + + + + + The following key names can be used to match against device properties. + Some of the keys also match against properties of the parent devices in sysfs, + not only the device that has generated the event. If multiple keys that match + a parent device are specified in a single rule, all these keys must match at + one and the same parent device. + + + + + Match the name of the event action. + + + + + + + Match the devpath of the event device. + + + + + + + Match the name of the event device. + + + + + + + Match the subsystem of the event device. + + + + + + Match the driver name of the event device. Only set for devices + which are bound to a driver at the time the event is generated. + + + + + + Match sysfs attribute values of the event device. Up to five + keys can be specified per rule. Trailing + whitespace in the attribute values is ignored, if the specified match + value does not contain trailing whitespace itself. Depending on the type + of operator, this key is also used to set the value of a sysfs attribute. + + + + + + + + Search the devpath upwards for a matching device name. + + + + + + + Search the devpath upwards for a matching device subsystem name. + + + + + + + Search the devpath upwards for a matching device driver name. + + + + + + + Search the devpath upwards for a device with matching sysfs attribute values. + Up to five keys can be specified per rule, but all of them + must match on the same device. Trailing whitespace in the attribute values is ignored, + if the specified match value does not contain trailing whitespace itself. + + + + + + + Match against the value of an environment variable. Up to five + keys can be specified per rule. Depending on the type of operator, this key is also used + to export a variable to the environment. + + + + + + + Test the existence of a file. An octal mode mask can be specified + if needed. + + + + + + + Execute external program. The key is true, if the program returns + with exit code zero. The whole event environment is available to the + executed program. The program's output printed to stdout, is available in + the RESULT key. + + + + + + + Match the returned string of the last PROGRAM call. This key can + be used in the same or in any later rule after a PROGRAM call. + + + + + Most of the fields support a shell style pattern matching. The following + pattern characters are supported: + + + + + Matches zero, or any number of characters. + + + + + + Matches any single character. + + + + + + Matches any single character specified within the brackets. For + example, the pattern string 'tty[SR]' would match either 'ttyS' or 'ttyR'. + Ranges are also supported within this match with the '-' character. + For example, to match on the range of all digits, the pattern [0-9] would + be used. If the first character following the '[' is a '!', any characters + not enclosed are matched. + + + + + The following keys can get values assigned: + + + + + The name of the node to be created, or the name the network interface + should be renamed to. Only one rule can set the node name, all later rules with + a NAME key will be ignored. + + + + + + + The name of a symlink targeting the node. Every matching rule can add + this value to the list of symlinks to be created along with the device node. + Multiple symlinks may be specified by separating the names by the space + character. + + + + + + + The permissions for the device node. Every specified value overwrites + the compiled-in default value. + + + + + + + The value that should be written to a sysfs attribute of the + event device. Depending on the type of operator, this key is also + used to match against the value of a sysfs attribute. + + + + + + + Export a variable to the environment. Depending on the type of operator, + this key is also to match against an environment variable. + + + + + + + Add a program to the list of programs to be executed for a specific + device. This can only be used for very short running tasks. Running an + event process for a long period of time may block all further events for + this or a dependent device. Long running tasks need to be immediately + detached from the event process itself. + + + + + + + Named label where a GOTO can jump to. + + + + + + + Jumps to the next LABEL with a matching name + + + + + + + Import a set of variables into the event environment, + depending on type: + + + + + Execute an external program specified as the assigned value and + import its output, which must be in environment key format. + + + + + + Import a text file specified as the assigned value, which must be in + environment key format. + + + + + + Import the stored keys from the parent device by reading + the database entry of the parent device. The value assigned to + is used as a filter of key names + to import (with the same shell-style pattern matching used for + comparisons). + + + + If no option is given, udev will choose between + and based on the executable bit of the file + permissions. + + + + + + + Wait for the specified sysfs file of the device to be created. Can be used + to fight against kernel sysfs timing issues. + + + + + + + Rule and device options: + + + + + Stops further rules application. No later rules will have + any effect. + + + + + + Ignore this event completely. + + + + + + Ignore any later remove event for this device. This may be useful + as a workaround for broken device drivers. + + + + + + Specify the priority of the created symlinks. Devices with higher + priorities overwrite existing symlinks of other devices. + + + + + + Create the device nodes for all available partitions of a block device. + This may be useful for removable media devices where media changes are not + detected. + + + + + + Usually control and other possibly unsafe characters are replaced + in strings used for device naming. The mode of replacement can be specified + with this option. + + + + + + + + The , , , + , and + fields support simple printf-like string substitutions. The + format chars gets applied after all rules have been processed, right before the program + is executed. It allows the use of the complete environment set by earlier matching + rules. For all other fields, substitutions are applied while the individual rule is + being processed. The available substitutions are: + + + , + + The kernel name for this device. + + + + + , + + The kernel number for this device. For example, 'sda3' has + kernel number of '3' + + + + + , + + The devpath of the device. + + + + + , + + The name of the device matched while searching the devpath upwards for + , , and . + + + + + + , + + The driver name of the device matched while searching the devpath upwards for + , , and . + + + + + + , + + The value of a sysfs attribute found at the device, where + all keys of the rule have matched. If the matching device does not have + such an attribute, all devices along the chain of parents are searched + for a matching attribute. + If the attribute is a symlink, the last element of the symlink target is + returned as the value. + + + + + , + + The value of an environment variable. + + + + + , + + The kernel major number for the device. + + + + + , + + The kernel minor number for the device. + + + + + , + + The string returned by the external program requested with PROGRAM. + A single part of the string, separated by a space character may be selected + by specifying the part number as an attribute: . + If the number is followed by the '+' char this part plus all remaining parts + of the result string are substituted: + + + + + , + + The node name of the parent device. + + + + + , + + The udev_root value. + + + + + , + + The sysfs mount point. + + + + + , + + The name of a created temporary device node to provide access to + the device from a external program before the real node is created. + + + + + + + The '%' character itself. + + + + + + + The '$' character itself. + + + + The count of characters to be substituted may be limited by specifying + the format length value. For example, '%3s{file}' will only + insert the first three characters of the sysfs attribute + + + + AUTHOR + Written by Greg Kroah-Hartman greg@kroah.com and + Kay Sievers kay.sievers@vrfy.org. With much help from + Dan Stekloff dsteklof@us.ibm.com and many others. + + + + SEE ALSO + + udevd8 + , + + udevinfo8 + , + + udevmonitor8 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_config.c b/21cnbao/code/05/udev源代码/udev-114/udev_config.c new file mode 100644 index 0000000..3f226b9 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_config.c @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2003-2004 Greg Kroah-Hartman + * Copyright (C) 2004-2005 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +/* global variables */ +char udev_root[PATH_SIZE]; +char udev_config_filename[PATH_SIZE]; +char udev_rules_dir[PATH_SIZE]; +int udev_log_priority; +int udev_run; + +static int get_key(char **line, char **key, char **value) +{ + char *linepos; + char *temp; + + linepos = *line; + if (!linepos) + return -1; + + /* skip whitespace */ + while (isspace(linepos[0])) + linepos++; + + /* get the key */ + *key = linepos; + while (1) { + linepos++; + if (linepos[0] == '\0') + return -1; + if (isspace(linepos[0])) + break; + if (linepos[0] == '=') + break; + } + + /* terminate key */ + linepos[0] = '\0'; + linepos++; + + /* skip whitespace */ + while (isspace(linepos[0])) + linepos++; + + /* get the value*/ + if (linepos[0] == '"') + linepos++; + else + return -1; + *value = linepos; + + temp = strchr(linepos, '"'); + if (!temp) + return -1; + temp[0] = '\0'; + + return 0; +} + +static int parse_config_file(void) +{ + char line[LINE_SIZE]; + char *bufline; + char *linepos; + char *variable; + char *value; + char *buf; + size_t bufsize; + size_t cur; + size_t count; + int lineno; + int retval = 0; + + if (file_map(udev_config_filename, &buf, &bufsize) != 0) { + err("can't open '%s' as config file: %s", udev_config_filename, strerror(errno)); + return -ENODEV; + } + + /* loop through the whole file */ + lineno = 0; + cur = 0; + while (cur < bufsize) { + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + lineno++; + + if (count >= sizeof(line)) { + err("line too long, conf line skipped %s, line %d", udev_config_filename, lineno); + continue; + } + + /* eat the whitespace */ + while ((count > 0) && isspace(bufline[0])) { + bufline++; + count--; + } + if (count == 0) + continue; + + /* see if this is a comment */ + if (bufline[0] == COMMENT_CHARACTER) + continue; + + memcpy(line, bufline, count); + line[count] = '\0'; + + linepos = line; + retval = get_key(&linepos, &variable, &value); + if (retval != 0) { + err("error parsing %s, line %d:%d", udev_config_filename, lineno, (int)(linepos-line)); + continue; + } + + if (strcasecmp(variable, "udev_root") == 0) { + strlcpy(udev_root, value, sizeof(udev_root)); + remove_trailing_chars(udev_root, '/'); + continue; + } + + if (strcasecmp(variable, "udev_rules") == 0) { + strlcpy(udev_rules_dir, value, sizeof(udev_rules_dir)); + remove_trailing_chars(udev_rules_dir, '/'); + continue; + } + + if (strcasecmp(variable, "udev_log") == 0) { + udev_log_priority = log_priority(value); + continue; + } + } + + file_unmap(buf, bufsize); + return retval; +} + +void udev_config_init(void) +{ + const char *env; + + strcpy(udev_root, UDEV_ROOT); + strcpy(udev_config_filename, UDEV_CONFIG_FILE); + strcpy(udev_rules_dir, UDEV_RULES_DIR); + udev_log_priority = LOG_ERR; + udev_run = 1; + + /* disable RUN key execution */ + env = getenv("UDEV_RUN"); + if (env && !string_is_true(env)) + udev_run = 0; + + env = getenv("UDEV_CONFIG_FILE"); + if (env) { + strlcpy(udev_config_filename, env, sizeof(udev_config_filename)); + remove_trailing_chars(udev_config_filename, '/'); + } + + parse_config_file(); + + env = getenv("UDEV_ROOT"); + if (env) { + strlcpy(udev_root, env, sizeof(udev_root)); + remove_trailing_chars(udev_root, '/'); + } + + env = getenv("UDEV_LOG"); + if (env) + udev_log_priority = log_priority(env); + + dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename); + dbg("udev_root='%s'", udev_root); + dbg("udev_rules='%s'", udev_rules_dir); + dbg("udev_log=%d", udev_log_priority); +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_db.c b/21cnbao/code/05/udev源代码/udev-114/udev_db.c new file mode 100644 index 0000000..abc1e5a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_db.c @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2004-2005 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + + +static size_t devpath_to_db_path(const char *devpath, char *filename, size_t len) +{ + size_t start; + + /* add location of db files */ + strlcpy(filename, udev_root, len); + start = strlcat(filename, "/"DB_DIR"/", len); + strlcat(filename, devpath, len); + return path_encode(&filename[start], len - start); +} + +/* reverse mapping from the device file name to the devpath */ +static int name_index(const char *devpath, const char *name, int add) +{ + char device[PATH_SIZE]; + char filename[PATH_SIZE * 2]; + size_t start; + int fd; + + /* directory with device name */ + strlcpy(filename, udev_root, sizeof(filename)); + start = strlcat(filename, "/"DB_NAME_INDEX_DIR"/", sizeof(filename)); + strlcat(filename, name, sizeof(filename)); + path_encode(&filename[start], sizeof(filename) - start); + /* entry with the devpath */ + strlcpy(device, devpath, sizeof(device)); + path_encode(device, sizeof(device)); + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, device, sizeof(filename)); + + if (add) { + info("creating index: '%s'", filename); + create_path(filename); + fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644); + if (fd > 0) + close(fd); + } else { + info("removing index: '%s'", filename); + unlink(filename); + delete_path(filename); + } + return 0; +} + +int udev_db_get_devices_by_name(const char *name, struct list_head *name_list) +{ + char dirname[PATH_MAX]; + size_t start; + DIR *dir; + int rc = 0; + + strlcpy(dirname, udev_root, sizeof(dirname)); + start = strlcat(dirname, "/"DB_NAME_INDEX_DIR"/", sizeof(dirname)); + strlcat(dirname, name, sizeof(dirname)); + path_encode(&dirname[start], sizeof(dirname) - start); + + dir = opendir(dirname); + if (dir == NULL) { + info("no index directory '%s': %s", dirname, strerror(errno)); + rc = -1; + goto out; + } + + info("found index directory '%s'", dirname); + while (1) { + struct dirent *ent; + char device[PATH_SIZE]; + + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + if (ent->d_name[0] == '.') + continue; + + strlcpy(device, ent->d_name, sizeof(device)); + path_decode(device); + name_list_add(name_list, device, 0); + rc++; + } + closedir(dir); +out: + return rc; +} + +int udev_db_add_device(struct udevice *udev) +{ + char filename[PATH_SIZE]; + + if (udev->test_run) + return 0; + + devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename)); + create_path(filename); + unlink(filename); + + /* + * don't waste tmpfs memory pages, if we don't have any data to store + * create fake db-file; store the node-name in a symlink target + */ + if (list_empty(&udev->symlink_list) && list_empty(&udev->env_list) && + !udev->partitions && !udev->ignore_remove) { + dbg("nothing interesting to store, create symlink"); + if (symlink(udev->name, filename) != 0) { + err("unable to create db link '%s': %s", filename, strerror(errno)); + return -1; + } + } else { + FILE *f; + struct name_entry *name_loop; + + f = fopen(filename, "w"); + if (f == NULL) { + err("unable to create db file '%s': %s", filename, strerror(errno)); + return -1; + } + dbg("storing data for device '%s' in '%s'", udev->dev->devpath, filename); + + fprintf(f, "N:%s\n", udev->name); + list_for_each_entry(name_loop, &udev->symlink_list, node) { + fprintf(f, "S:%s\n", name_loop->name); + /* add symlink-name to index */ + name_index(udev->dev->devpath, name_loop->name, 1); + } + fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt)); + if (udev->link_priority != 0) + fprintf(f, "L:%u\n", udev->link_priority); + if (udev->partitions != 0) + fprintf(f, "A:%u\n", udev->partitions); + if (udev->ignore_remove) + fprintf(f, "R:%u\n", udev->ignore_remove); + list_for_each_entry(name_loop, &udev->env_list, node) + fprintf(f, "E:%s\n", name_loop->name); + fclose(f); + } + + /* add name to index */ + name_index(udev->dev->devpath, udev->name, 1); + + return 0; +} + +int udev_db_get_device(struct udevice *udev, const char *devpath) +{ + struct stat stats; + char filename[PATH_SIZE]; + char line[PATH_SIZE]; + unsigned int maj, min; + char *bufline; + char *buf; + size_t bufsize; + size_t cur; + size_t count; + + sysfs_device_set_values(udev->dev, devpath, NULL, NULL); + devpath_to_db_path(devpath, filename, sizeof(filename)); + + if (lstat(filename, &stats) != 0) { + info("no db file to read %s: %s", filename, strerror(errno)); + return -1; + } + if ((stats.st_mode & S_IFMT) == S_IFLNK) { + char target[NAME_SIZE]; + int target_len; + + info("found a symlink as db file"); + target_len = readlink(filename, target, sizeof(target)); + if (target_len > 0) + target[target_len] = '\0'; + else { + info("error reading db link %s: %s", filename, strerror(errno)); + return -1; + } + dbg("db link points to '%s'", target); + strlcpy(udev->name, target, sizeof(udev->name)); + return 0; + } + + if (file_map(filename, &buf, &bufsize) != 0) { + info("error reading db file %s: %s", filename, strerror(errno)); + return -1; + } + + cur = 0; + while (cur < bufsize) { + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + + switch(bufline[0]) { + case 'N': + if (count > sizeof(udev->name)) + count = sizeof(udev->name); + memcpy(udev->name, &bufline[2], count-2); + udev->name[count-2] = '\0'; + break; + case 'M': + if (count > sizeof(line)) + count = sizeof(line); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; + sscanf(line, "%u:%u", &maj, &min); + udev->devt = makedev(maj, min); + break; + case 'S': + if (count > sizeof(line)) + count = sizeof(line); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; + name_list_add(&udev->symlink_list, line, 0); + break; + case 'L': + if (count > sizeof(line)) + count = sizeof(line); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; + udev->link_priority = atoi(line); + break; + case 'A': + if (count > sizeof(line)) + count = sizeof(line); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; + udev->partitions = atoi(line); + break; + case 'R': + if (count > sizeof(line)) + count = sizeof(line); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; + udev->ignore_remove = atoi(line); + break; + case 'E': + if (count > sizeof(line)) + count = sizeof(line); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; + name_list_add(&udev->env_list, line, 0); + break; + } + } + file_unmap(buf, bufsize); + + if (udev->name[0] == '\0') + return -1; + + return 0; +} + +int udev_db_delete_device(struct udevice *udev) +{ + char filename[PATH_SIZE]; + struct name_entry *name_loop; + + if (udev->test_run) + return 0; + + devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename)); + unlink(filename); + + name_index(udev->dev->devpath, udev->name, 0); + list_for_each_entry(name_loop, &udev->symlink_list, node) + name_index(udev->dev->devpath, name_loop->name, 0); + + return 0; +} + +int udev_db_get_all_entries(struct list_head *name_list) +{ + char dbpath[PATH_MAX]; + DIR *dir; + + strlcpy(dbpath, udev_root, sizeof(dbpath)); + strlcat(dbpath, "/"DB_DIR, sizeof(dbpath)); + dir = opendir(dbpath); + if (dir == NULL) { + info("no udev_db available '%s': %s", dbpath, strerror(errno)); + return -1; + } + + while (1) { + struct dirent *ent; + char device[PATH_SIZE]; + + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + if (ent->d_name[0] == '.') + continue; + + strlcpy(device, ent->d_name, sizeof(device)); + path_decode(device); + name_list_add(name_list, device, 1); + dbg("added '%s'", device); + } + + closedir(dir); + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_device.c b/21cnbao/code/05/udev源代码/udev-114/udev_device.c new file mode 100644 index 0000000..23ba313 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_device.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" + + +struct udevice *udev_device_init(struct udevice *udev) +{ + if (udev == NULL) + udev = malloc(sizeof(struct udevice)); + if (udev == NULL) + return NULL; + memset(udev, 0x00, sizeof(struct udevice)); + + INIT_LIST_HEAD(&udev->symlink_list); + INIT_LIST_HEAD(&udev->run_list); + INIT_LIST_HEAD(&udev->env_list); + + /* set sysfs device to local storage, can be overridden if needed */ + udev->dev = &udev->dev_local; + + /* default node permissions */ + udev->mode = 0660; + strcpy(udev->owner, "root"); + strcpy(udev->group, "root"); + + return udev; +} + +void udev_device_cleanup(struct udevice *udev) +{ + name_list_cleanup(&udev->symlink_list); + name_list_cleanup(&udev->run_list); + name_list_cleanup(&udev->env_list); + free(udev); +} + +dev_t udev_device_get_devt(struct udevice *udev) +{ + const char *attr; + unsigned int maj, min; + + /* read it from sysfs */ + attr = sysfs_attr_get_value(udev->dev->devpath, "dev"); + if (attr != NULL) { + if (sscanf(attr, "%u:%u", &maj, &min) == 2) + return makedev(maj, min); + } + return makedev(0, 0); +} + +static void kernel_log(struct ifreq ifr) +{ + int klog; + FILE *f; + + klog = open("/dev/kmsg", O_WRONLY); + if (klog < 0) + return; + + f = fdopen(klog, "w"); + if (f == NULL) { + close(klog); + return; + } + + fprintf(f, "<6>udev: renamed network interface %s to %s\n", + ifr.ifr_name, ifr.ifr_newname); + fclose(f); +} + +static int rename_netif(struct udevice *udev) +{ + int sk; + struct ifreq ifr; + int retval; + + info("changing net interface name from '%s' to '%s'", udev->dev->kernel, udev->name); + if (udev->test_run) + return 0; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) { + err("error opening socket: %s", strerror(errno)); + return -1; + } + + memset(&ifr, 0x00, sizeof(struct ifreq)); + strlcpy(ifr.ifr_name, udev->dev->kernel, IFNAMSIZ); + strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ); + retval = ioctl(sk, SIOCSIFNAME, &ifr); + if (retval == 0) + kernel_log(ifr); + else { + int loop; + + /* see if the destination interface name already exists */ + if (errno != EEXIST) { + err("error changing netif name %s to %s: %s", ifr.ifr_name, ifr.ifr_newname, strerror(errno)); + goto exit; + } + + /* free our own name, another process may wait for us */ + strlcpy(ifr.ifr_newname, udev->dev->kernel, IFNAMSIZ); + strlcat(ifr.ifr_newname, "_rename", IFNAMSIZ); + retval = ioctl(sk, SIOCSIFNAME, &ifr); + if (retval != 0) { + err("error changing netif name %s to %s: %s", ifr.ifr_name, ifr.ifr_newname, strerror(errno)); + goto exit; + } + + /* wait 30 seconds for our target to become available */ + strlcpy(ifr.ifr_name, ifr.ifr_newname, IFNAMSIZ); + strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ); + loop = 30 * 20; + while (loop--) { + retval = ioctl(sk, SIOCSIFNAME, &ifr); + if (retval == 0) { + kernel_log(ifr); + break; + } + + if (errno != EEXIST) { + err("error changing net interface name %s to %s: %s", + ifr.ifr_name, ifr.ifr_newname, strerror(errno)); + break; + } + dbg("wait for netif '%s' to become free, loop=%i", udev->name, (30 * 20) - loop); + usleep(1000 * 1000 / 20); + } + } + +exit: + close(sk); + return retval; +} + +int udev_device_event(struct udev_rules *rules, struct udevice *udev) +{ + int retval = 0; + + /* add device node */ + if (major(udev->devt) != 0 && + (strcmp(udev->action, "add") == 0 || strcmp(udev->action, "change") == 0)) { + struct udevice *udev_old; + + dbg("device node add '%s'", udev->dev->devpath); + + udev_rules_get_name(rules, udev); + if (udev->ignore_device) { + info("device event will be ignored"); + goto exit; + } + if (udev->name[0] == '\0') { + info("device node creation supressed"); + goto exit; + } + + /* read current database entry; cleanup, if it is known device */ + udev_old = udev_device_init(NULL); + if (udev_old != NULL) { + udev_old->test_run = udev->test_run; + if (udev_db_get_device(udev_old, udev->dev->devpath) == 0) { + info("device '%s' already in database, cleanup", udev->dev->devpath); + udev_db_delete_device(udev_old); + } else { + udev_device_cleanup(udev_old); + udev_old = NULL; + } + } + + /* create node */ + retval = udev_node_add(udev); + if (retval != 0) + goto exit; + + /* store in database */ + udev_db_add_device(udev); + + /* create, replace, delete symlinks according to priority */ + udev_node_update_symlinks(udev, udev_old); + + if (udev_old != NULL) + udev_device_cleanup(udev_old); + goto exit; + } + + /* add netif */ + if (strcmp(udev->dev->subsystem, "net") == 0 && strcmp(udev->action, "add") == 0) { + dbg("netif add '%s'", udev->dev->devpath); + udev_rules_get_name(rules, udev); + if (udev->ignore_device) { + info("device event will be ignored"); + goto exit; + } + if (udev->name[0] == '\0') { + info("device renaming supressed"); + goto exit; + } + + /* look if we want to change the name of the netif */ + if (strcmp(udev->name, udev->dev->kernel) != 0) { + char devpath[PATH_MAX]; + char *pos; + + retval = rename_netif(udev); + if (retval != 0) + goto exit; + info("renamed netif to '%s'", udev->name); + + /* export old name */ + setenv("INTERFACE_OLD", udev->dev->kernel, 1); + + /* now change the devpath, because the kernel device name has changed */ + strlcpy(devpath, udev->dev->devpath, sizeof(devpath)); + pos = strrchr(devpath, '/'); + if (pos != NULL) { + pos[1] = '\0'; + strlcat(devpath, udev->name, sizeof(devpath)); + sysfs_device_set_values(udev->dev, devpath, NULL, NULL); + setenv("DEVPATH", udev->dev->devpath, 1); + setenv("INTERFACE", udev->name, 1); + info("changed devpath to '%s'", udev->dev->devpath); + } + } + goto exit; + } + + /* remove device node */ + if (major(udev->devt) != 0 && strcmp(udev->action, "remove") == 0) { + struct name_entry *name_loop; + + /* import database entry, and delete it */ + if (udev_db_get_device(udev, udev->dev->devpath) == 0) { + udev_db_delete_device(udev); + if (udev->ignore_remove) { + info("ignore_remove for '%s'", udev->name); + goto exit; + } + /* restore stored persistent data */ + list_for_each_entry(name_loop, &udev->env_list, node) + putenv(name_loop->name); + } else { + dbg("'%s' not found in database, using kernel name '%s'", + udev->dev->devpath, udev->dev->kernel); + strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name)); + } + + udev_rules_get_run(rules, udev); + if (udev->ignore_device) { + info("device event will be ignored"); + goto exit; + } + + /* remove the node */ + retval = udev_node_remove(udev); + + /* delete or restore symlinks according to priority */ + udev_node_update_symlinks(udev, NULL); + goto exit; + } + + /* default devices */ + udev_rules_get_run(rules, udev); + if (udev->ignore_device) + info("device event will be ignored"); + +exit: + return retval; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_node.c b/21cnbao/code/05/udev源代码/udev-114/udev_node.c new file mode 100644 index 0000000..fcd52d0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_node.c @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" +#include "udev_selinux.h" + +#define TMP_FILE_EXT ".udev-tmp" + +int udev_node_mknod(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid) +{ + char file_tmp[PATH_SIZE + sizeof(TMP_FILE_EXT)]; + struct stat stats; + int retval = 0; + + if (major(devt) != 0 && strcmp(udev->dev->subsystem, "block") == 0) + mode |= S_IFBLK; + else + mode |= S_IFCHR; + + if (lstat(file, &stats) == 0) { + if ((stats.st_mode & S_IFMT) == (mode & S_IFMT) && (stats.st_rdev == devt)) { + info("preserve file '%s', because it has correct dev_t", file); + selinux_setfilecon(file, udev->dev->kernel, stats.st_mode); + goto perms; + } + } else { + selinux_setfscreatecon(file, udev->dev->kernel, mode); + retval = mknod(file, mode, devt); + selinux_resetfscreatecon(); + if (retval == 0) + goto perms; + } + + info("atomically replace '%s'", file); + strlcpy(file_tmp, file, sizeof(file_tmp)); + strlcat(file_tmp, TMP_FILE_EXT, sizeof(file_tmp)); + unlink(file_tmp); + selinux_setfscreatecon(file_tmp, udev->dev->kernel, mode); + retval = mknod(file_tmp, mode, devt); + selinux_resetfscreatecon(); + if (retval != 0) { + err("mknod(%s, %#o, %u, %u) failed: %s", + file_tmp, mode, major(devt), minor(devt), strerror(errno)); + goto exit; + } + retval = rename(file_tmp, file); + if (retval != 0) { + err("rename(%s, %s) failed: %s", + file_tmp, file, strerror(errno)); + unlink(file_tmp); + goto exit; + } + +perms: + dbg("chmod(%s, %#o)", file, mode); + if (chmod(file, mode) != 0) { + err("chmod(%s, %#o) failed: %s", file, mode, strerror(errno)); + goto exit; + } + + if (uid != 0 || gid != 0) { + dbg("chown(%s, %u, %u)", file, uid, gid); + if (chown(file, uid, gid) != 0) { + err("chown(%s, %u, %u) failed: %s", + file, uid, gid, strerror(errno)); + goto exit; + } + } +exit: + return retval; +} + +static int node_symlink(const char *node, const char *slink) +{ + struct stat stats; + char target[PATH_SIZE] = ""; + char slink_tmp[PATH_SIZE + sizeof(TMP_FILE_EXT)]; + int i = 0; + int tail = 0; + int len; + int retval = 0; + + /* use relative link */ + while (node[i] && (node[i] == slink[i])) { + if (node[i] == '/') + tail = i+1; + i++; + } + while (slink[i] != '\0') { + if (slink[i] == '/') + strlcat(target, "../", sizeof(target)); + i++; + } + strlcat(target, &node[tail], sizeof(target)); + + /* preserve link with correct target, do not replace node of other device */ + if (lstat(slink, &stats) == 0) { + if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) { + struct stat stats2; + + info("found existing node instead of symlink '%s'", slink); + if (lstat(node, &stats2) == 0) { + if ((stats.st_mode & S_IFMT) == (stats2.st_mode & S_IFMT) && + stats.st_rdev == stats2.st_rdev) { + info("replace device node '%s' with symlink to our node '%s'", slink, node); + } else { + err("device node '%s' already exists, link '%s' will not overwrite it", node, slink); + goto exit; + } + } + } else if (S_ISLNK(stats.st_mode)) { + char buf[PATH_SIZE]; + + info("found existing symlink '%s'", slink); + len = readlink(slink, buf, sizeof(buf)); + if (len > 0) { + buf[len] = '\0'; + if (strcmp(target, buf) == 0) { + info("preserve already existing symlink '%s' to '%s'", slink, target); + selinux_setfilecon(slink, NULL, S_IFLNK); + goto exit; + } + } + } + } else { + info("creating symlink '%s' to '%s'", slink, target); + selinux_setfscreatecon(slink, NULL, S_IFLNK); + retval = symlink(target, slink); + selinux_resetfscreatecon(); + if (retval == 0) + goto exit; + } + + info("atomically replace '%s'", slink); + strlcpy(slink_tmp, slink, sizeof(slink_tmp)); + strlcat(slink_tmp, TMP_FILE_EXT, sizeof(slink_tmp)); + unlink(slink_tmp); + selinux_setfscreatecon(slink_tmp, NULL, S_IFLNK); + retval = symlink(target, slink_tmp); + selinux_resetfscreatecon(); + if (retval != 0) { + err("symlink(%s, %s) failed: %s", target, slink_tmp, strerror(errno)); + goto exit; + } + retval = rename(slink_tmp, slink); + if (retval != 0) { + err("rename(%s, %s) failed: %s", slink_tmp, slink, strerror(errno)); + unlink(slink_tmp); + goto exit; + } +exit: + return retval; +} + +static int update_link(struct udevice *udev, const char *name) +{ + LIST_HEAD(name_list); + char slink[PATH_SIZE]; + char node[PATH_SIZE]; + struct udevice *udev_db; + struct name_entry *device; + char target[PATH_MAX] = ""; + int count; + int priority = 0; + int rc = 0; + + strlcpy(slink, udev_root, sizeof(slink)); + strlcat(slink, "/", sizeof(slink)); + strlcat(slink, name, sizeof(slink)); + + count = udev_db_get_devices_by_name(name, &name_list); + info("found %i devices with name '%s'", count, name); + + /* if we don't have a reference, delete it */ + if (count <= 0) { + info("no reference left, remove '%s'", name); + if (!udev->test_run) { + unlink(slink); + delete_path(slink); + } + goto out; + } + + /* find the device with the highest priority */ + list_for_each_entry(device, &name_list, node) { + info("found '%s' for '%s'", device->name, name); + + /* did we find ourself? we win, if we have the same priority */ + if (strcmp(udev->dev->devpath, device->name) == 0) { + info("compare (our own) priority of '%s' %i >= %i", + udev->dev->devpath, udev->link_priority, priority); + if (target[0] == '\0' || udev->link_priority >= priority) { + priority = udev->link_priority; + strlcpy(target, udev->name, sizeof(target)); + } + continue; + } + + /* or something else, then read priority from database */ + udev_db = udev_device_init(NULL); + if (udev_db == NULL) + continue; + if (udev_db_get_device(udev_db, device->name) == 0) { + info("compare priority of '%s' %i > %i", + udev_db->dev->devpath, udev_db->link_priority, priority); + if (target[0] == '\0' || udev_db->link_priority > priority) { + priority = udev_db->link_priority; + strlcpy(target, udev_db->name, sizeof(target)); + } + } + udev_device_cleanup(udev_db); + } + name_list_cleanup(&name_list); + + if (target[0] == '\0') { + err("missing target for '%s'", name); + rc = -1; + goto out; + } + + /* create symlink to the target with the highest priority */ + strlcpy(node, udev_root, sizeof(node)); + strlcat(node, "/", sizeof(node)); + strlcat(node, target, sizeof(node)); + info("'%s' with target '%s' has the highest priority %i, create it", name, target, priority); + if (!udev->test_run) { + create_path(slink); + node_symlink(node, slink); + } +out: + return rc; +} + +void udev_node_update_symlinks(struct udevice *udev, struct udevice *udev_old) +{ + struct name_entry *name_loop; + char symlinks[PATH_SIZE] = ""; + + list_for_each_entry(name_loop, &udev->symlink_list, node) { + info("update symlink '%s' of '%s'", name_loop->name, udev->dev->devpath); + update_link(udev, name_loop->name); + strlcat(symlinks, udev_root, sizeof(symlinks)); + strlcat(symlinks, "/", sizeof(symlinks)); + strlcat(symlinks, name_loop->name, sizeof(symlinks)); + strlcat(symlinks, " ", sizeof(symlinks)); + } + + /* export symlinks to environment */ + remove_trailing_chars(symlinks, ' '); + if (symlinks[0] != '\0') + setenv("DEVLINKS", symlinks, 1); + + /* update possible left-over symlinks (device metadata changed) */ + if (udev_old != NULL) { + struct name_entry *link_loop; + struct name_entry *link_old_loop; + int found; + + /* remove current symlinks from old list */ + list_for_each_entry(link_old_loop, &udev_old->symlink_list, node) { + found = 0; + list_for_each_entry(link_loop, &udev->symlink_list, node) { + if (strcmp(link_old_loop->name, link_loop->name) == 0) { + found = 1; + break; + } + } + if (!found) { + /* link does no longer belong to this device */ + info("update old symlink '%s' no longer belonging to '%s'", + link_old_loop->name, udev->dev->devpath); + update_link(udev, link_old_loop->name); + } + } + + /* + * if the node name has changed, delete the node, + * or possibly restore a symlink of another device + */ + if (strcmp(udev->name, udev_old->name) != 0) + update_link(udev, udev_old->name); + } +} + +int udev_node_add(struct udevice *udev) +{ + char filename[PATH_SIZE]; + uid_t uid; + gid_t gid; + int i; + int retval = 0; + + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, udev->name, sizeof(filename)); + create_path(filename); + + if (strcmp(udev->owner, "root") == 0) + uid = 0; + else { + char *endptr; + unsigned long id; + + id = strtoul(udev->owner, &endptr, 10); + if (endptr[0] == '\0') + uid = (uid_t) id; + else + uid = lookup_user(udev->owner); + } + + if (strcmp(udev->group, "root") == 0) + gid = 0; + else { + char *endptr; + unsigned long id; + + id = strtoul(udev->group, &endptr, 10); + if (endptr[0] == '\0') + gid = (gid_t) id; + else + gid = lookup_group(udev->group); + } + + info("creating device node '%s', major=%d, minor=%d, mode=%#o, uid=%d, gid=%d", + filename, major(udev->devt), minor(udev->devt), udev->mode, uid, gid); + + if (!udev->test_run) + if (udev_node_mknod(udev, filename, udev->devt, udev->mode, uid, gid) != 0) { + retval = -1; + goto exit; + } + + setenv("DEVNAME", filename, 1); + + /* create all_partitions if requested */ + if (udev->partitions) { + char partitionname[PATH_SIZE]; + char *attr; + int range; + + /* take the maximum registered minor range */ + attr = sysfs_attr_get_value(udev->dev->devpath, "range"); + if (attr != NULL) { + range = atoi(attr); + if (range > 1) + udev->partitions = range-1; + } + info("creating device partition nodes '%s[1-%i]'", filename, udev->partitions); + if (!udev->test_run) { + for (i = 1; i <= udev->partitions; i++) { + dev_t part_devt; + + snprintf(partitionname, sizeof(partitionname), "%s%d", filename, i); + partitionname[sizeof(partitionname)-1] = '\0'; + part_devt = makedev(major(udev->devt), minor(udev->devt) + i); + udev_node_mknod(udev, partitionname, part_devt, udev->mode, uid, gid); + } + } + } +exit: + return retval; +} + +int udev_node_remove(struct udevice *udev) +{ + char filename[PATH_SIZE]; + char partitionname[PATH_SIZE]; + struct stat stats; + int retval = 0; + int num; + + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, udev->name, sizeof(filename)); + if (stat(filename, &stats) != 0) { + dbg("device node '%s' not found", filename); + return -1; + } + if (udev->devt && stats.st_rdev != udev->devt) { + info("device node '%s' points to a different device, skip removal", filename); + return -1; + } + + info("removing device node '%s'", filename); + if (!udev->test_run) + retval = unlink_secure(filename); + if (retval) + return retval; + + setenv("DEVNAME", filename, 1); + num = udev->partitions; + if (num > 0) { + int i; + + info("removing all_partitions '%s[1-%i]'", filename, num); + if (num > 255) + return -1; + for (i = 1; i <= num; i++) { + snprintf(partitionname, sizeof(partitionname), "%s%d", filename, i); + partitionname[sizeof(partitionname)-1] = '\0'; + if (!udev->test_run) + unlink_secure(partitionname); + } + } + delete_path(filename); + return retval; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_rules.c b/21cnbao/code/05/udev源代码/udev-114/udev_rules.c new file mode 100644 index 0000000..e2877ab --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_rules.c @@ -0,0 +1,1502 @@ +/* + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" + +extern char **environ; + +/* extract possible {attr} and move str behind it */ +static char *get_format_attribute(char **str) +{ + char *pos; + char *attr = NULL; + + if (*str[0] == '{') { + pos = strchr(*str, '}'); + if (pos == NULL) { + err("missing closing brace for format"); + return NULL; + } + pos[0] = '\0'; + attr = *str+1; + *str = pos+1; + dbg("attribute='%s', str='%s'", attr, *str); + } + return attr; +} + +/* extract possible format length and move str behind it*/ +static int get_format_len(char **str) +{ + int num; + char *tail; + + if (isdigit(*str[0])) { + num = (int) strtoul(*str, &tail, 10); + if (num > 0) { + *str = tail; + dbg("format length=%i", num); + return num; + } else { + err("format parsing error '%s'", *str); + } + } + return -1; +} + +static int get_key(char **line, char **key, char **value) +{ + char *linepos; + char *temp; + + linepos = *line; + if (linepos == NULL) + return -1; + + /* skip whitespace */ + while (isspace(linepos[0])) + linepos++; + + /* get the key */ + temp = strchr(linepos, '='); + if (temp == NULL || temp == linepos) + return -1; + temp[0] = '\0'; + *key = linepos; + linepos = &temp[1]; + + /* get a quoted value */ + if (linepos[0] == '"' || linepos[0] == '\'') { + temp = strchr(&linepos[1], linepos[0]); + if (temp != NULL) { + temp[0] = '\0'; + *value = &linepos[1]; + goto out; + } + } + + /* get the value*/ + temp = strchr(linepos, '\n'); + if (temp != NULL) + temp[0] = '\0'; + *value = linepos; +out: + return 0; +} + +static int run_program(const char *command, const char *subsystem, + char *result, size_t ressize, size_t *reslen) +{ + int status; + int outpipe[2] = {-1, -1}; + int errpipe[2] = {-1, -1}; + pid_t pid; + char arg[PATH_SIZE]; + char program[PATH_SIZE]; + char *argv[(sizeof(arg) / 2) + 1]; + int devnull; + int i; + int retval = 0; + + /* build argv from comand */ + strlcpy(arg, command, sizeof(arg)); + i = 0; + if (strchr(arg, ' ') != NULL) { + char *pos = arg; + + while (pos != NULL) { + if (pos[0] == '\'') { + /* don't separate if in apostrophes */ + pos++; + argv[i] = strsep(&pos, "\'"); + while (pos != NULL && pos[0] == ' ') + pos++; + } else { + argv[i] = strsep(&pos, " "); + } + dbg("arg[%i] '%s'", i, argv[i]); + i++; + } + argv[i] = NULL; + } else { + argv[0] = arg; + argv[1] = NULL; + } + info("'%s'", command); + + /* prepare pipes from child to parent */ + if (result != NULL || udev_log_priority >= LOG_INFO) { + if (pipe(outpipe) != 0) { + err("pipe failed: %s", strerror(errno)); + return -1; + } + } + if (udev_log_priority >= LOG_INFO) { + if (pipe(errpipe) != 0) { + err("pipe failed: %s", strerror(errno)); + return -1; + } + } + + /* allow programs in /lib/udev called without the path */ + if (strchr(argv[0], '/') == NULL) { + strlcpy(program, "/lib/udev/", sizeof(program)); + strlcat(program, argv[0], sizeof(program)); + argv[0] = program; + } + + pid = fork(); + switch(pid) { + case 0: + /* child closes parent ends of pipes */ + if (outpipe[READ_END] > 0) + close(outpipe[READ_END]); + if (errpipe[READ_END] > 0) + close(errpipe[READ_END]); + + /* discard child output or connect to pipe */ + devnull = open("/dev/null", O_RDWR); + if (devnull > 0) { + dup2(devnull, STDIN_FILENO); + if (outpipe[WRITE_END] < 0) + dup2(devnull, STDOUT_FILENO); + if (errpipe[WRITE_END] < 0) + dup2(devnull, STDERR_FILENO); + close(devnull); + } else + err("open /dev/null failed: %s", strerror(errno)); + if (outpipe[WRITE_END] > 0) { + dup2(outpipe[WRITE_END], STDOUT_FILENO); + close(outpipe[WRITE_END]); + } + if (errpipe[WRITE_END] > 0) { + dup2(errpipe[WRITE_END], STDERR_FILENO); + close(errpipe[WRITE_END]); + } + execv(argv[0], argv); + if (errno == ENOENT || errno == ENOTDIR) { + /* may be on a filesytem which is not mounted right now */ + info("program '%s' not found", argv[0]); + } else { + /* other problems */ + err("exec of program '%s' failed", argv[0]); + } + _exit(1); + case -1: + err("fork of '%s' failed: %s", argv[0], strerror(errno)); + return -1; + default: + /* read from child if requested */ + if (outpipe[READ_END] > 0 || errpipe[READ_END] > 0) { + ssize_t count; + size_t respos = 0; + + /* parent closes child ends of pipes */ + if (outpipe[WRITE_END] > 0) + close(outpipe[WRITE_END]); + if (errpipe[WRITE_END] > 0) + close(errpipe[WRITE_END]); + + /* read child output */ + while (outpipe[READ_END] > 0 || errpipe[READ_END] > 0) { + int fdcount; + fd_set readfds; + + FD_ZERO(&readfds); + if (outpipe[READ_END] > 0) + FD_SET(outpipe[READ_END], &readfds); + if (errpipe[READ_END] > 0) + FD_SET(errpipe[READ_END], &readfds); + fdcount = select(UDEV_MAX(outpipe[READ_END], errpipe[READ_END])+1, &readfds, NULL, NULL, NULL); + if (fdcount < 0) { + if (errno == EINTR) + continue; + retval = -1; + break; + } + + /* get stdout */ + if (outpipe[READ_END] > 0 && FD_ISSET(outpipe[READ_END], &readfds)) { + char inbuf[1024]; + char *pos; + char *line; + + count = read(outpipe[READ_END], inbuf, sizeof(inbuf)-1); + if (count <= 0) { + close(outpipe[READ_END]); + outpipe[READ_END] = -1; + if (count < 0) { + err("stdin read failed: %s", strerror(errno)); + retval = -1; + } + continue; + } + inbuf[count] = '\0'; + + /* store result for rule processing */ + if (result) { + if (respos + count < ressize) { + memcpy(&result[respos], inbuf, count); + respos += count; + } else { + err("ressize %ld too short", (long)ressize); + retval = -1; + } + } + pos = inbuf; + while ((line = strsep(&pos, "\n"))) + if (pos || line[0] != '\0') + info("'%s' (stdout) '%s'", argv[0], line); + } + + /* get stderr */ + if (errpipe[READ_END] > 0 && FD_ISSET(errpipe[READ_END], &readfds)) { + char errbuf[1024]; + char *pos; + char *line; + + count = read(errpipe[READ_END], errbuf, sizeof(errbuf)-1); + if (count <= 0) { + close(errpipe[READ_END]); + errpipe[READ_END] = -1; + if (count < 0) + err("stderr read failed: %s", strerror(errno)); + continue; + } + errbuf[count] = '\0'; + pos = errbuf; + while ((line = strsep(&pos, "\n"))) + if (pos || line[0] != '\0') + info("'%s' (stderr) '%s'", argv[0], line); + } + } + if (outpipe[READ_END] > 0) + close(outpipe[READ_END]); + if (errpipe[READ_END] > 0) + close(errpipe[READ_END]); + + /* return the childs stdout string */ + if (result) { + result[respos] = '\0'; + dbg("result='%s'", result); + if (reslen) + *reslen = respos; + } + } + waitpid(pid, &status, 0); + if (WIFEXITED(status)) { + info("'%s' returned with status %i", argv[0], WEXITSTATUS(status)); + if (WEXITSTATUS(status) != 0) + retval = -1; + } else { + err("'%s' abnormal exit", argv[0]); + retval = -1; + } + } + + return retval; +} + +static int import_keys_into_env(struct udevice *udev, const char *buf, size_t bufsize) +{ + char line[LINE_SIZE]; + const char *bufline; + char *linepos; + char *variable; + char *value; + size_t cur; + size_t count; + int lineno; + + /* loop through the whole buffer */ + lineno = 0; + cur = 0; + while (cur < bufsize) { + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + lineno++; + + if (count >= sizeof(line)) { + err("line too long, conf line skipped %s, line %d", udev_config_filename, lineno); + continue; + } + + /* eat the whitespace */ + while ((count > 0) && isspace(bufline[0])) { + bufline++; + count--; + } + if (count == 0) + continue; + + /* see if this is a comment */ + if (bufline[0] == COMMENT_CHARACTER) + continue; + + memcpy(line, bufline, count); + line[count] = '\0'; + + linepos = line; + if (get_key(&linepos, &variable, &value) == 0) { + dbg("import '%s=%s'", variable, value); + + /* handle device, renamed by external tool, returning new path */ + if (strcmp(variable, "DEVPATH") == 0) { + info("updating devpath from '%s' to '%s'", udev->dev->devpath, value); + sysfs_device_set_values(udev->dev, value, NULL, NULL); + } else + name_list_key_add(&udev->env_list, variable, value); + setenv(variable, value, 1); + } + } + + return 0; +} + +static int import_file_into_env(struct udevice *udev, const char *filename) +{ + char *buf; + size_t bufsize; + + if (file_map(filename, &buf, &bufsize) != 0) { + err("can't open '%s': %s", filename, strerror(errno)); + return -1; + } + import_keys_into_env(udev, buf, bufsize); + file_unmap(buf, bufsize); + + return 0; +} + +static int import_program_into_env(struct udevice *udev, const char *program) +{ + char result[2048]; + size_t reslen; + + if (run_program(program, udev->dev->subsystem, result, sizeof(result), &reslen) != 0) + return -1; + return import_keys_into_env(udev, result, reslen); +} + +static int import_parent_into_env(struct udevice *udev, const char *filter) +{ + struct sysfs_device *dev_parent; + int rc = -1; + + dev_parent = sysfs_device_get_parent(udev->dev); + if (dev_parent != NULL) { + struct udevice *udev_parent; + struct name_entry *name_loop; + + dbg("found parent '%s', get the node name", dev_parent->devpath); + udev_parent = udev_device_init(NULL); + if (udev_parent == NULL) + return -1; + /* import the udev_db of the parent */ + if (udev_db_get_device(udev_parent, dev_parent->devpath) == 0) { + dbg("import stored parent env '%s'", udev_parent->name); + list_for_each_entry(name_loop, &udev_parent->env_list, node) { + char name[NAME_SIZE]; + char *pos; + + strlcpy(name, name_loop->name, sizeof(name)); + pos = strchr(name, '='); + if (pos) { + pos[0] = '\0'; + pos++; + if (fnmatch(filter, name, 0) == 0) { + dbg("import key '%s'", name_loop->name); + name_list_add(&udev->env_list, name_loop->name, 0); + setenv(name, pos, 1); + } else + dbg("skip key '%s'", name_loop->name); + } + } + rc = 0; + } else + dbg("parent not found in database"); + udev_device_cleanup(udev_parent); + } + + return rc; +} + +static int pass_env_to_socket(const char *sockname, const char *devpath, const char *action) +{ + int sock; + struct sockaddr_un saddr; + socklen_t addrlen; + char buf[2048]; + size_t bufpos = 0; + int i; + ssize_t count; + int retval = 0; + + dbg("pass environment to socket '%s'", sockname); + sock = socket(AF_LOCAL, SOCK_DGRAM, 0); + memset(&saddr, 0x00, sizeof(struct sockaddr_un)); + saddr.sun_family = AF_LOCAL; + /* abstract namespace only */ + strcpy(&saddr.sun_path[1], sockname); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + bufpos = snprintf(buf, sizeof(buf)-1, "%s@%s", action, devpath); + bufpos++; + for (i = 0; environ[i] != NULL && bufpos < sizeof(buf); i++) { + bufpos += strlcpy(&buf[bufpos], environ[i], sizeof(buf) - bufpos-1); + bufpos++; + } + + count = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, addrlen); + if (count < 0) + retval = -1; + info("passed %zi bytes to socket '%s', ", count, sockname); + + close(sock); + return retval; +} + +int udev_rules_run(struct udevice *udev) +{ + struct name_entry *name_loop; + int retval = 0; + + dbg("executing run list"); + list_for_each_entry(name_loop, &udev->run_list, node) { + if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) { + pass_env_to_socket(&name_loop->name[strlen("socket:")], udev->dev->devpath, udev->action); + } else { + char program[PATH_SIZE]; + + strlcpy(program, name_loop->name, sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); + if (run_program(program, udev->dev->subsystem, NULL, 0, NULL) != 0) + if (!name_loop->ignore_error) + retval = -1; + } + } + + return retval; +} + +#define WAIT_LOOP_PER_SECOND 50 +static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) +{ + char devicepath[PATH_SIZE]; + char filepath[PATH_SIZE]; + struct stat stats; + int loop = timeout * WAIT_LOOP_PER_SECOND; + + strlcpy(devicepath, sysfs_path, sizeof(devicepath)); + strlcat(devicepath, udev->dev->devpath, sizeof(devicepath)); + strlcpy(filepath, devicepath, sizeof(filepath)); + strlcat(filepath, "/", sizeof(filepath)); + strlcat(filepath, file, sizeof(filepath)); + + dbg("will wait %i sec for '%s'", timeout, filepath); + while (--loop) { + /* lookup file */ + if (stat(filepath, &stats) == 0) { + info("file '%s' appeared after %i loops", filepath, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); + return 0; + } + /* make sure, the device did not disappear in the meantime */ + if (stat(devicepath, &stats) != 0) { + info("device disappeared while waiting for '%s'", filepath); + return -2; + } + info("wait for '%s' for %i mseconds", filepath, 1000 / WAIT_LOOP_PER_SECOND); + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + info("waiting for '%s' failed", filepath); + return -1; +} + +/* handle "[$SUBSYSTEM/$KERNEL]" lookup */ +static int attr_get_by_subsys_id(const char *attrstr, char *devpath, size_t len, char **attr) +{ + char subsys[NAME_SIZE]; + char *attrib; + char *id; + int found = 0; + + if (attrstr[0] != '[') + goto out; + + strlcpy(subsys, &attrstr[1], sizeof(subsys)); + + attrib = strchr(subsys, ']'); + if (attrib == NULL) + goto out; + attrib[0] = '\0'; + attrib = &attrib[1]; + + id = strchr(subsys, '/'); + if (id == NULL) + goto out; + id[0] = '\0'; + id = &id[1]; + + if (sysfs_lookup_devpath_by_subsys_id(devpath, len, subsys, id)) { + if (attr != NULL) { + if (attrib[0] != '\0') + *attr = attrib; + else + *attr = NULL; + } + found = 1; + } +out: + return found; +} + +void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize) +{ + char temp[PATH_SIZE]; + char temp2[PATH_SIZE]; + char *head, *tail, *pos, *cpos, *attr, *rest; + int len; + int i; + int count; + enum subst_type { + SUBST_UNKNOWN, + SUBST_DEVPATH, + SUBST_KERNEL, + SUBST_KERNEL_NUMBER, + SUBST_ID, + SUBST_DRIVER, + SUBST_MAJOR, + SUBST_MINOR, + SUBST_RESULT, + SUBST_ATTR, + SUBST_PARENT, + SUBST_TEMP_NODE, + SUBST_ROOT, + SUBST_SYS, + SUBST_ENV, + }; + static const struct subst_map { + char *name; + char fmt; + enum subst_type type; + } map[] = { + { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH }, + { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER }, + { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL }, + { .name = "id", .fmt = 'b', .type = SUBST_ID }, + { .name = "driver", .fmt = 'd', .type = SUBST_DRIVER }, + { .name = "major", .fmt = 'M', .type = SUBST_MAJOR }, + { .name = "minor", .fmt = 'm', .type = SUBST_MINOR }, + { .name = "result", .fmt = 'c', .type = SUBST_RESULT }, + { .name = "attr", .fmt = 's', .type = SUBST_ATTR }, + { .name = "sysfs", .fmt = 's', .type = SUBST_ATTR }, + { .name = "parent", .fmt = 'P', .type = SUBST_PARENT }, + { .name = "tempnode", .fmt = 'N', .type = SUBST_TEMP_NODE }, + { .name = "root", .fmt = 'r', .type = SUBST_ROOT }, + { .name = "sys", .fmt = 'S', .type = SUBST_SYS }, + { .name = "env", .fmt = 'E', .type = SUBST_ENV }, + { NULL, '\0', 0 } + }; + enum subst_type type; + const struct subst_map *subst; + + head = string; + while (1) { + len = -1; + while (head[0] != '\0') { + if (head[0] == '$') { + /* substitute named variable */ + if (head[1] == '\0') + break; + if (head[1] == '$') { + strlcpy(temp, head+2, sizeof(temp)); + strlcpy(head+1, temp, maxsize); + head++; + continue; + } + head[0] = '\0'; + for (subst = map; subst->name; subst++) { + if (strncasecmp(&head[1], subst->name, strlen(subst->name)) == 0) { + type = subst->type; + tail = head + strlen(subst->name)+1; + dbg("will substitute format name '%s'", subst->name); + goto found; + } + } + head[0] = '$'; + err("unknown format variable '%s'", head); + } else if (head[0] == '%') { + /* substitute format char */ + if (head[1] == '\0') + break; + if (head[1] == '%') { + strlcpy(temp, head+2, sizeof(temp)); + strlcpy(head+1, temp, maxsize); + head++; + continue; + } + head[0] = '\0'; + tail = head+1; + len = get_format_len(&tail); + for (subst = map; subst->name; subst++) { + if (tail[0] == subst->fmt) { + type = subst->type; + tail++; + dbg("will substitute format char '%c'", subst->fmt); + goto found; + } + } + head[0] = '%'; + err("unknown format char '%c'", tail[0]); + } + head++; + } + break; +found: + attr = get_format_attribute(&tail); + strlcpy(temp, tail, sizeof(temp)); + dbg("format=%i, string='%s', tail='%s'", type ,string, tail); + + switch (type) { + case SUBST_DEVPATH: + strlcat(string, udev->dev->devpath, maxsize); + dbg("substitute devpath '%s'", udev->dev->devpath); + break; + case SUBST_KERNEL: + strlcat(string, udev->dev->kernel, maxsize); + dbg("substitute kernel name '%s'", udev->dev->kernel); + break; + case SUBST_KERNEL_NUMBER: + strlcat(string, udev->dev->kernel_number, maxsize); + dbg("substitute kernel number '%s'", udev->dev->kernel_number); + break; + case SUBST_ID: + if (udev->dev_parent != NULL) { + strlcat(string, udev->dev_parent->kernel, maxsize); + dbg("substitute id '%s'", udev->dev_parent->kernel); + } + break; + case SUBST_DRIVER: + if (udev->dev_parent != NULL) { + strlcat(string, udev->dev_parent->driver, maxsize); + dbg("substitute driver '%s'", udev->dev_parent->driver); + } + break; + case SUBST_MAJOR: + sprintf(temp2, "%d", major(udev->devt)); + strlcat(string, temp2, maxsize); + dbg("substitute major number '%s'", temp2); + break; + case SUBST_MINOR: + sprintf(temp2, "%d", minor(udev->devt)); + strlcat(string, temp2, maxsize); + dbg("substitute minor number '%s'", temp2); + break; + case SUBST_RESULT: + if (udev->program_result[0] == '\0') + break; + /* get part part of the result string */ + i = 0; + if (attr != NULL) + i = strtoul(attr, &rest, 10); + if (i > 0) { + dbg("request part #%d of result string", i); + cpos = udev->program_result; + while (--i) { + while (cpos[0] != '\0' && !isspace(cpos[0])) + cpos++; + while (isspace(cpos[0])) + cpos++; + } + if (i > 0) { + err("requested part of result string not found"); + break; + } + strlcpy(temp2, cpos, sizeof(temp2)); + /* %{2+}c copies the whole string from the second part on */ + if (rest[0] != '+') { + cpos = strchr(temp2, ' '); + if (cpos) + cpos[0] = '\0'; + } + strlcat(string, temp2, maxsize); + dbg("substitute part of result string '%s'", temp2); + } else { + strlcat(string, udev->program_result, maxsize); + dbg("substitute result string '%s'", udev->program_result); + } + break; + case SUBST_ATTR: + if (attr == NULL) + err("missing file parameter for attr"); + else { + char devpath[PATH_SIZE]; + char *attrib; + const char *value = NULL; + size_t size; + + if (attr_get_by_subsys_id(attr, devpath, sizeof(devpath), &attrib)) { + if (attrib != NULL) + value = sysfs_attr_get_value(devpath, attrib); + else + break; + } + + /* try the current device, other matches may have selected */ + if (value == NULL && udev->dev_parent != NULL && udev->dev_parent != udev->dev) + value = sysfs_attr_get_value(udev->dev_parent->devpath, attr); + + /* look at all devices along the chain of parents */ + if (value == NULL) { + struct sysfs_device *dev_parent = udev->dev; + + do { + dbg("looking at '%s'", dev_parent->devpath); + value = sysfs_attr_get_value(dev_parent->devpath, attr); + if (value != NULL) { + strlcpy(temp2, value, sizeof(temp2)); + break; + } + dev_parent = sysfs_device_get_parent(dev_parent); + } while (dev_parent != NULL); + } + + if (value == NULL) + break; + + /* strip trailing whitespace, and replace unwanted characters */ + size = strlcpy(temp2, value, sizeof(temp2)); + if (size >= sizeof(temp2)) + size = sizeof(temp2)-1; + while (size > 0 && isspace(temp2[size-1])) + temp2[--size] = '\0'; + count = replace_chars(temp2, ALLOWED_CHARS_INPUT); + if (count > 0) + info("%i character(s) replaced" , count); + strlcat(string, temp2, maxsize); + dbg("substitute sysfs value '%s'", temp2); + } + break; + case SUBST_PARENT: + { + struct sysfs_device *dev_parent; + + dev_parent = sysfs_device_get_parent(udev->dev); + if (dev_parent != NULL) { + struct udevice *udev_parent; + + dbg("found parent '%s', get the node name", dev_parent->devpath); + udev_parent = udev_device_init(NULL); + if (udev_parent != NULL) { + /* lookup the name in the udev_db with the DEVPATH of the parent */ + if (udev_db_get_device(udev_parent, dev_parent->devpath) == 0) { + strlcat(string, udev_parent->name, maxsize); + dbg("substitute parent node name'%s'", udev_parent->name); + } else + dbg("parent not found in database"); + udev_device_cleanup(udev_parent); + } + } + } + break; + case SUBST_TEMP_NODE: + if (udev->tmp_node[0] == '\0' && major(udev->devt) > 0) { + dbg("create temporary device node for callout"); + snprintf(udev->tmp_node, sizeof(udev->tmp_node), "%s/.tmp-%u-%u", + udev_root, major(udev->devt), minor(udev->devt)); + udev->tmp_node[sizeof(udev->tmp_node)-1] = '\0'; + udev_node_mknod(udev, udev->tmp_node, udev->devt, 0600, 0, 0); + } + strlcat(string, udev->tmp_node, maxsize); + dbg("substitute temporary device node name '%s'", udev->tmp_node); + break; + case SUBST_ROOT: + strlcat(string, udev_root, maxsize); + dbg("substitute udev_root '%s'", udev_root); + break; + case SUBST_SYS: + strlcat(string, sysfs_path, maxsize); + dbg("substitute sysfs_path '%s'", sysfs_path); + break; + case SUBST_ENV: + if (attr == NULL) { + dbg("missing attribute"); + break; + } + pos = getenv(attr); + if (pos == NULL) { + dbg("env '%s' not available", attr); + break; + } + dbg("substitute env '%s=%s'", attr, pos); + strlcat(string, pos, maxsize); + break; + default: + err("unknown substitution type=%i", type); + break; + } + /* possibly truncate to format-char specified length */ + if (len >= 0 && len < (int)strlen(head)) { + head[len] = '\0'; + dbg("truncate to %i chars, subtitution string becomes '%s'", len, head); + } + strlcat(string, temp, maxsize); + } +} + +static char *key_val(struct udev_rule *rule, struct key *key) +{ + return rule->buf + key->val_off; +} + +static char *key_pair_name(struct udev_rule *rule, struct key_pair *pair) +{ + return rule->buf + pair->key_name_off; +} + +static int match_key(const char *key_name, struct udev_rule *rule, struct key *key, const char *val) +{ + char value[PATH_SIZE]; + char *key_value; + char *pos; + int match = 0; + + if (key->operation != KEY_OP_MATCH && + key->operation != KEY_OP_NOMATCH) + return 0; + + /* look for a matching string, parts are separated by '|' */ + strlcpy(value, rule->buf + key->val_off, sizeof(value)); + key_value = value; + dbg("key %s value='%s'", key_name, key_value); + while (key_value) { + pos = strchr(key_value, '|'); + if (pos) { + pos[0] = '\0'; + pos++; + } + + dbg("match %s '%s' <-> '%s'", key_name, key_value, val); + match = (fnmatch(key_value, val, 0) == 0); + if (match) + break; + + key_value = pos; + } + + if (match && (key->operation == KEY_OP_MATCH)) { + dbg("%s is true (matching value)", key_name); + return 0; + } + if (!match && (key->operation == KEY_OP_NOMATCH)) { + dbg("%s is true (non-matching value)", key_name); + return 0; + } + return -1; +} + +/* match a single rule against a given device and possibly its parent devices */ +static int match_rule(struct udevice *udev, struct udev_rule *rule) +{ + int i; + + if (match_key("ACTION", rule, &rule->action, udev->action)) + goto nomatch; + + if (match_key("KERNEL", rule, &rule->kernel, udev->dev->kernel)) + goto nomatch; + + if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->dev->subsystem)) + goto nomatch; + + if (match_key("DEVPATH", rule, &rule->devpath, udev->dev->devpath)) + goto nomatch; + + if (match_key("DRIVER", rule, &rule->driver, udev->dev->driver)) + goto nomatch; + + /* match NAME against a value assigned by an earlier rule */ + if (match_key("NAME", rule, &rule->name, udev->name)) + goto nomatch; + + /* match against current list of symlinks */ + if (rule->symlink_match.operation == KEY_OP_MATCH || + rule->symlink_match.operation == KEY_OP_NOMATCH) { + struct name_entry *name_loop; + int match = 0; + + list_for_each_entry(name_loop, &udev->symlink_list, node) { + if (match_key("SYMLINK", rule, &rule->symlink_match, name_loop->name) == 0) { + match = 1; + break; + } + } + if (!match) + goto nomatch; + } + + for (i = 0; i < rule->env.count; i++) { + struct key_pair *pair = &rule->env.keys[i]; + + /* we only check for matches, assignments will be handled later */ + if (pair->key.operation == KEY_OP_MATCH || + pair->key.operation == KEY_OP_NOMATCH) { + const char *key_name = key_pair_name(rule, pair); + const char *value = getenv(key_name); + + if (!value) { + dbg("ENV{'%s'} is not set, treat as empty", key_name); + value = ""; + } + if (match_key("ENV", rule, &pair->key, value)) + goto nomatch; + } + } + + if (rule->test.operation != KEY_OP_UNSET) { + char filename[PATH_SIZE]; + char devpath[PATH_SIZE]; + char *attr; + struct stat statbuf; + int match; + + strlcpy(filename, key_val(rule, &rule->test), sizeof(filename)); + udev_rules_apply_format(udev, filename, sizeof(filename)); + + if (attr_get_by_subsys_id(filename, devpath, sizeof(devpath), &attr)) { + strlcpy(filename, sysfs_path, sizeof(filename)); + strlcat(filename, devpath, sizeof(filename)); + if (attr != NULL) { + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, attr, sizeof(filename)); + } + } + + match = (stat(filename, &statbuf) == 0); + info("'%s' %s", filename, match ? "exists" : "does not exist"); + if (match && rule->test_mode_mask > 0) { + match = ((statbuf.st_mode & rule->test_mode_mask) > 0); + info("'%s' has mode=%#o and %s %#o", filename, statbuf.st_mode, + match ? "matches" : "does not match", + rule->test_mode_mask); + } + if (match && rule->test.operation == KEY_OP_NOMATCH) + goto nomatch; + if (!match && rule->test.operation == KEY_OP_MATCH) + goto nomatch; + dbg("TEST key is true"); + } + + if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) { + int found; + + found = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0); + if (!found && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) + goto nomatch; + } + + /* check for matching sysfs attribute pairs */ + for (i = 0; i < rule->attr.count; i++) { + struct key_pair *pair = &rule->attr.keys[i]; + + if (pair->key.operation == KEY_OP_MATCH || + pair->key.operation == KEY_OP_NOMATCH) { + const char *key_name = key_pair_name(rule, pair); + const char *key_value = key_val(rule, &pair->key); + char devpath[PATH_SIZE]; + char *attrib; + const char *value = NULL; + char val[VALUE_SIZE]; + size_t len; + + if (attr_get_by_subsys_id(key_name, devpath, sizeof(devpath), &attrib)) { + if (attrib != NULL) + value = sysfs_attr_get_value(devpath, attrib); + else + goto nomatch; + } + if (value == NULL) + value = sysfs_attr_get_value(udev->dev->devpath, key_name); + if (value == NULL) + goto nomatch; + strlcpy(val, value, sizeof(val)); + + /* strip trailing whitespace of value, if not asked to match for it */ + len = strlen(key_value); + if (len > 0 && !isspace(key_value[len-1])) { + len = strlen(val); + while (len > 0 && isspace(val[len-1])) + val[--len] = '\0'; + dbg("removed %zi trailing whitespace chars from '%s'", strlen(val)-len, val); + } + + if (match_key("ATTR", rule, &pair->key, val)) + goto nomatch; + } + } + + /* walk up the chain of parent devices and find a match */ + udev->dev_parent = udev->dev; + while (1) { + /* check for matching kernel device name */ + if (match_key("KERNELS", rule, &rule->kernels, udev->dev_parent->kernel)) + goto try_parent; + + /* check for matching subsystem value */ + if (match_key("SUBSYSTEMS", rule, &rule->subsystems, udev->dev_parent->subsystem)) + goto try_parent; + + /* check for matching driver */ + if (match_key("DRIVERS", rule, &rule->drivers, udev->dev_parent->driver)) + goto try_parent; + + /* check for matching sysfs attribute pairs */ + for (i = 0; i < rule->attrs.count; i++) { + struct key_pair *pair = &rule->attrs.keys[i]; + + if (pair->key.operation == KEY_OP_MATCH || + pair->key.operation == KEY_OP_NOMATCH) { + const char *key_name = key_pair_name(rule, pair); + const char *key_value = key_val(rule, &pair->key); + const char *value; + char val[VALUE_SIZE]; + size_t len; + + value = sysfs_attr_get_value(udev->dev_parent->devpath, key_name); + if (value == NULL) + value = sysfs_attr_get_value(udev->dev->devpath, key_name); + if (value == NULL) + goto try_parent; + strlcpy(val, value, sizeof(val)); + + /* strip trailing whitespace of value, if not asked to match for it */ + len = strlen(key_value); + if (len > 0 && !isspace(key_value[len-1])) { + len = strlen(val); + while (len > 0 && isspace(val[len-1])) + val[--len] = '\0'; + dbg("removed %zi trailing whitespace chars from '%s'", strlen(val)-len, val); + } + + if (match_key("ATTRS", rule, &pair->key, val)) + goto try_parent; + } + } + + /* found matching device */ + break; +try_parent: + /* move to parent device */ + dbg("try parent sysfs device"); + udev->dev_parent = sysfs_device_get_parent(udev->dev_parent); + if (udev->dev_parent == NULL) + goto nomatch; + dbg("looking at dev_parent->devpath='%s'", udev->dev_parent->devpath); + dbg("looking at dev_parent->kernel='%s'", udev->dev_parent->kernel); + } + + /* execute external program */ + if (rule->program.operation != KEY_OP_UNSET) { + char program[PATH_SIZE]; + char result[PATH_SIZE]; + + strlcpy(program, key_val(rule, &rule->program), sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); + if (run_program(program, udev->dev->subsystem, result, sizeof(result), NULL) != 0) { + dbg("PROGRAM is false"); + udev->program_result[0] = '\0'; + if (rule->program.operation != KEY_OP_NOMATCH) + goto nomatch; + } else { + int count; + + dbg("PROGRAM matches"); + remove_trailing_chars(result, '\n'); + if (rule->string_escape == ESCAPE_UNSET || + rule->string_escape == ESCAPE_REPLACE) { + count = replace_chars(result, ALLOWED_CHARS_INPUT); + if (count > 0) + info("%i character(s) replaced" , count); + } + dbg("result is '%s'", result); + strlcpy(udev->program_result, result, sizeof(udev->program_result)); + dbg("PROGRAM returned successful"); + if (rule->program.operation == KEY_OP_NOMATCH) + goto nomatch; + } + dbg("PROGRAM key is true"); + } + + /* check for matching result of external program */ + if (match_key("RESULT", rule, &rule->result, udev->program_result)) + goto nomatch; + + /* import variables returned from program or or file into environment */ + if (rule->import.operation != KEY_OP_UNSET) { + char import[PATH_SIZE]; + int rc = -1; + + strlcpy(import, key_val(rule, &rule->import), sizeof(import)); + udev_rules_apply_format(udev, import, sizeof(import)); + dbg("check for IMPORT import='%s'", import); + if (rule->import_type == IMPORT_PROGRAM) { + rc = import_program_into_env(udev, import); + } else if (rule->import_type == IMPORT_FILE) { + dbg("import file import='%s'", import); + rc = import_file_into_env(udev, import); + } else if (rule->import_type == IMPORT_PARENT) { + dbg("import parent import='%s'", import); + rc = import_parent_into_env(udev, import); + } + if (rc != 0) { + dbg("IMPORT failed"); + if (rule->import.operation != KEY_OP_NOMATCH) + goto nomatch; + } else + dbg("IMPORT '%s' imported", key_val(rule, &rule->import)); + dbg("IMPORT key is true"); + } + + /* rule matches, if we have ENV assignments export it */ + for (i = 0; i < rule->env.count; i++) { + struct key_pair *pair = &rule->env.keys[i]; + + if (pair->key.operation == KEY_OP_ASSIGN) { + char temp_value[NAME_SIZE]; + const char *key_name = key_pair_name(rule, pair); + const char *value = key_val(rule, &pair->key); + + /* make sure we don't write to the same string we possibly read from */ + strlcpy(temp_value, value, sizeof(temp_value)); + udev_rules_apply_format(udev, temp_value, NAME_SIZE); + + if (temp_value[0] == '\0') { + name_list_key_remove(&udev->env_list, key_name); + unsetenv(key_name); + info("unset ENV '%s'", key_name); + } else { + struct name_entry *entry; + + entry = name_list_key_add(&udev->env_list, key_name, temp_value); + if (entry == NULL) + break; + putenv(entry->name); + info("set ENV '%s'", entry->name); + } + } + } + + /* if we have ATTR assignments, write value to sysfs file */ + for (i = 0; i < rule->attr.count; i++) { + struct key_pair *pair = &rule->attr.keys[i]; + + if (pair->key.operation == KEY_OP_ASSIGN) { + const char *key_name = key_pair_name(rule, pair); + char devpath[PATH_SIZE]; + char *attrib; + char attr[PATH_SIZE] = ""; + char value[NAME_SIZE]; + FILE *f; + + if (attr_get_by_subsys_id(key_name, devpath, sizeof(devpath), &attrib)) { + if (attrib != NULL) { + strlcpy(attr, sysfs_path, sizeof(attr)); + strlcat(attr, devpath, sizeof(attr)); + strlcat(attr, "/", sizeof(attr)); + strlcat(attr, attrib, sizeof(attr)); + } + } + + if (attr[0] == '\0') { + strlcpy(attr, sysfs_path, sizeof(attr)); + strlcat(attr, udev->dev->devpath, sizeof(attr)); + strlcat(attr, "/", sizeof(attr)); + strlcat(attr, key_name, sizeof(attr)); + } + + strlcpy(value, key_val(rule, &pair->key), sizeof(value)); + udev_rules_apply_format(udev, value, sizeof(value)); + info("writing '%s' to sysfs file '%s'", value, attr); + f = fopen(attr, "w"); + if (f != NULL) { + if (!udev->test_run) + if (fprintf(f, "%s", value) <= 0) + err("error writing ATTR{%s}: %s", attr, strerror(errno)); + fclose(f); + } else + err("error opening ATTR{%s} for writing: %s", attr, strerror(errno)); + } + } + return 0; + +nomatch: + return -1; +} + +int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) +{ + struct udev_rule *rule; + int name_set = 0; + + dbg("udev->dev->devpath='%s'", udev->dev->devpath); + dbg("udev->dev->kernel='%s'", udev->dev->kernel); + + /* look for a matching rule to apply */ + udev_rules_iter_init(rules); + while (1) { + rule = udev_rules_iter_next(rules); + if (rule == NULL) + break; + + if (name_set && + (rule->name.operation == KEY_OP_ASSIGN || + rule->name.operation == KEY_OP_ASSIGN_FINAL || + rule->name.operation == KEY_OP_ADD)) { + dbg("node name already set, rule ignored"); + continue; + } + + dbg("process rule"); + if (match_rule(udev, rule) == 0) { + /* apply options */ + if (rule->ignore_device) { + info("rule applied, '%s' is ignored", udev->dev->kernel); + udev->ignore_device = 1; + return 0; + } + if (rule->ignore_remove) { + udev->ignore_remove = 1; + dbg("remove event should be ignored"); + } + if (rule->link_priority != 0) { + udev->link_priority = rule->link_priority; + info("link_priority=%i", udev->link_priority); + } + /* apply all_partitions option only at a main block device */ + if (rule->partitions && + strcmp(udev->dev->subsystem, "block") == 0 && udev->dev->kernel_number[0] == '\0') { + udev->partitions = rule->partitions; + dbg("creation of partition nodes requested"); + } + + /* apply permissions */ + if (!udev->mode_final && rule->mode != 0000) { + if (rule->mode_operation == KEY_OP_ASSIGN_FINAL) + udev->mode_final = 1; + udev->mode = rule->mode; + dbg("applied mode=%#o to '%s'", rule->mode, udev->dev->kernel); + } + if (!udev->owner_final && rule->owner.operation != KEY_OP_UNSET) { + if (rule->owner.operation == KEY_OP_ASSIGN_FINAL) + udev->owner_final = 1; + strlcpy(udev->owner, key_val(rule, &rule->owner), sizeof(udev->owner)); + udev_rules_apply_format(udev, udev->owner, sizeof(udev->owner)); + dbg("applied owner='%s' to '%s'", udev->owner, udev->dev->kernel); + } + if (!udev->group_final && rule->group.operation != KEY_OP_UNSET) { + if (rule->group.operation == KEY_OP_ASSIGN_FINAL) + udev->group_final = 1; + strlcpy(udev->group, key_val(rule, &rule->group), sizeof(udev->group)); + udev_rules_apply_format(udev, udev->group, sizeof(udev->group)); + dbg("applied group='%s' to '%s'", udev->group, udev->dev->kernel); + } + + /* collect symlinks */ + if (!udev->symlink_final && + (rule->symlink.operation == KEY_OP_ASSIGN || + rule->symlink.operation == KEY_OP_ASSIGN_FINAL || + rule->symlink.operation == KEY_OP_ADD)) { + char temp[PATH_SIZE]; + char *pos, *next; + int count; + + if (rule->symlink.operation == KEY_OP_ASSIGN_FINAL) + udev->symlink_final = 1; + if (rule->symlink.operation == KEY_OP_ASSIGN || + rule->symlink.operation == KEY_OP_ASSIGN_FINAL) { + info("reset symlink list"); + name_list_cleanup(&udev->symlink_list); + } + /* allow multiple symlinks separated by spaces */ + strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); + udev_rules_apply_format(udev, temp, sizeof(temp)); + if (rule->string_escape == ESCAPE_UNSET || + rule->string_escape == ESCAPE_REPLACE) { + count = replace_chars(temp, ALLOWED_CHARS_FILE " "); + if (count > 0) + info("%i character(s) replaced" , count); + } + dbg("rule applied, added symlink(s) '%s'", temp); + pos = temp; + while (isspace(pos[0])) + pos++; + next = strchr(pos, ' '); + while (next) { + next[0] = '\0'; + info("add symlink '%s'", pos); + name_list_add(&udev->symlink_list, pos, 0); + while (isspace(next[1])) + next++; + pos = &next[1]; + next = strchr(pos, ' '); + } + if (pos[0] != '\0') { + info("add symlink '%s'", pos); + name_list_add(&udev->symlink_list, pos, 0); + } + } + + /* set name, later rules with name set will be ignored */ + if (rule->name.operation == KEY_OP_ASSIGN || + rule->name.operation == KEY_OP_ASSIGN_FINAL || + rule->name.operation == KEY_OP_ADD) { + int count; + + name_set = 1; + strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name)); + udev_rules_apply_format(udev, udev->name, sizeof(udev->name)); + if (rule->string_escape == ESCAPE_UNSET || + rule->string_escape == ESCAPE_REPLACE) { + count = replace_chars(udev->name, ALLOWED_CHARS_FILE); + if (count > 0) + info("%i character(s) replaced", count); + } + + info("rule applied, '%s' becomes '%s'", udev->dev->kernel, udev->name); + if (strcmp(udev->dev->subsystem, "net") != 0) + dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i", + udev->name, udev->owner, udev->group, udev->mode, udev->partitions); + } + + if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { + struct name_entry *entry; + + if (rule->run.operation == KEY_OP_ASSIGN_FINAL) + udev->run_final = 1; + if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) { + info("reset run list"); + name_list_cleanup(&udev->run_list); + } + dbg("add run '%s'", key_val(rule, &rule->run)); + entry = name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); + if (rule->run_ignore_error) + entry->ignore_error = 1; + } + + if (rule->last_rule) { + dbg("last rule to be applied"); + break; + } + + if (rule->goto_label.operation != KEY_OP_UNSET) { + dbg("moving forward to label '%s'", key_val(rule, &rule->goto_label)); + udev_rules_iter_label(rules, key_val(rule, &rule->goto_label)); + } + } + } + + if (!name_set) { + info("no node name set, will use kernel name '%s'", udev->name); + strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name)); + } + + if (udev->tmp_node[0] != '\0') { + dbg("removing temporary device node"); + unlink_secure(udev->tmp_node); + udev->tmp_node[0] = '\0'; + } + + return 0; +} + +int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev) +{ + struct udev_rule *rule; + + dbg("udev->kernel='%s'", udev->dev->kernel); + + /* look for a matching rule to apply */ + udev_rules_iter_init(rules); + while (1) { + rule = udev_rules_iter_next(rules); + if (rule == NULL) + break; + + dbg("process rule"); + if (rule->name.operation != KEY_OP_UNSET || rule->symlink.operation != KEY_OP_UNSET || + rule->mode_operation != KEY_OP_UNSET || rule->owner.operation != KEY_OP_UNSET || + rule->group.operation != KEY_OP_UNSET) { + dbg("skip rule that names a device"); + continue; + } + + if (match_rule(udev, rule) == 0) { + if (rule->ignore_device) { + info("rule applied, '%s' is ignored", udev->dev->kernel); + udev->ignore_device = 1; + return 0; + } + + if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { + struct name_entry *entry; + + if (rule->run.operation == KEY_OP_ASSIGN || + rule->run.operation == KEY_OP_ASSIGN_FINAL) { + info("reset run list"); + name_list_cleanup(&udev->run_list); + } + dbg("add run '%s'", key_val(rule, &rule->run)); + entry = name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); + if (rule->run_ignore_error) + entry->ignore_error = 1; + if (rule->run.operation == KEY_OP_ASSIGN_FINAL) + break; + } + + if (rule->last_rule) { + dbg("last rule to be applied"); + break; + } + + if (rule->goto_label.operation != KEY_OP_UNSET) { + dbg("moving forward to label '%s'", key_val(rule, &rule->goto_label)); + udev_rules_iter_label(rules, key_val(rule, &rule->goto_label)); + } + } + } + + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_rules.h b/21cnbao/code/05/udev源代码/udev-114/udev_rules.h new file mode 100644 index 0000000..0ad4ec3 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_rules.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2003-2004 Greg Kroah-Hartman + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef UDEV_RULES_H +#define UDEV_RULES_H + +#include "udev.h" +#include "list.h" + +#define PAIRS_MAX 5 +#define RULESFILE_SUFFIX ".rules" + +enum key_operation { + KEY_OP_UNSET, + KEY_OP_MATCH, + KEY_OP_NOMATCH, + KEY_OP_ADD, + KEY_OP_ASSIGN, + KEY_OP_ASSIGN_FINAL, +}; + +struct key { + enum key_operation operation; + size_t val_off; +}; + +struct key_pair { + struct key key; + size_t key_name_off; +}; + +struct key_pairs { + int count; + struct key_pair keys[PAIRS_MAX]; +}; + +enum import_type { + IMPORT_UNSET, + IMPORT_PROGRAM, + IMPORT_FILE, + IMPORT_PARENT, +}; + +enum escape_type { + ESCAPE_UNSET, + ESCAPE_NONE, + ESCAPE_REPLACE, +}; + +struct udev_rule { + struct key action; + struct key devpath; + struct key kernel; + struct key subsystem; + struct key driver; + struct key_pairs attr; + + struct key kernels; + struct key subsystems; + struct key drivers; + struct key_pairs attrs; + + struct key_pairs env; + struct key program; + struct key result; + struct key import; + enum import_type import_type; + struct key test; + mode_t test_mode_mask; + struct key run; + struct key wait_for_sysfs; + struct key label; + struct key goto_label; + + struct key name; + struct key symlink; + struct key symlink_match; + struct key owner; + struct key group; + mode_t mode; + enum key_operation mode_operation; + enum escape_type string_escape; + + unsigned int link_priority; + unsigned int partitions; + unsigned int last_rule:1, + run_ignore_error:1, + ignore_device:1, + ignore_remove:1; + + size_t bufsize; + char buf[]; +}; + +struct udev_rules { + char *buf; + size_t bufsize; + size_t current; + int resolve_names; +}; + +extern int udev_rules_init(struct udev_rules *rules, int resolve_names); +extern void udev_rules_cleanup(struct udev_rules *rules); + +extern void udev_rules_iter_init(struct udev_rules *rules); +extern struct udev_rule *udev_rules_iter_next(struct udev_rules *rules); +extern struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const char *label); + +extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev); +extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev); +extern int udev_rules_run(struct udevice *udev); + +extern void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize); + +#endif diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_rules_parse.c b/21cnbao/code/05/udev源代码/udev-114/udev_rules_parse.c new file mode 100644 index 0000000..81c24b9 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_rules_parse.c @@ -0,0 +1,789 @@ +/* + * Copyright (C) 2003,2004 Greg Kroah-Hartman + * Copyright (C) 2003-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" + + +void udev_rules_iter_init(struct udev_rules *rules) +{ + dbg("bufsize=%zi", rules->bufsize); + rules->current = 0; +} + +struct udev_rule *udev_rules_iter_next(struct udev_rules *rules) +{ + static struct udev_rule *rule; + + if (!rules) + return NULL; + + dbg("current=%zi", rules->current); + if (rules->current >= rules->bufsize) { + dbg("no more rules"); + return NULL; + } + + /* get next rule */ + rule = (struct udev_rule *) (rules->buf + rules->current); + rules->current += sizeof(struct udev_rule) + rule->bufsize; + + return rule; +} + +struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const char *label) +{ + static struct udev_rule *rule; + +next: + dbg("current=%zi", rules->current); + if (rules->current >= rules->bufsize) { + dbg("no more rules"); + return NULL; + } + rule = (struct udev_rule *) (rules->buf + rules->current); + + if (strcmp(&rule->buf[rule->label.val_off], label) != 0) { + dbg("moving forward, looking for label '%s'", label); + rules->current += sizeof(struct udev_rule) + rule->bufsize; + goto next; + } + + dbg("found label '%s'", label); + return rule; +} + +static int get_key(char **line, char **key, enum key_operation *operation, char **value) +{ + char *linepos; + char *temp; + + linepos = *line; + if (linepos == NULL && linepos[0] == '\0') + return -1; + + /* skip whitespace */ + while (isspace(linepos[0]) || linepos[0] == ',') + linepos++; + + /* get the key */ + if (linepos[0] == '\0') + return -1; + *key = linepos; + + while (1) { + linepos++; + if (linepos[0] == '\0') + return -1; + if (isspace(linepos[0])) + break; + if (linepos[0] == '=') + break; + if ((linepos[0] == '+') || (linepos[0] == '!') || (linepos[0] == ':')) + if (linepos[1] == '=') + break; + } + + /* remember end of key */ + temp = linepos; + + /* skip whitespace after key */ + while (isspace(linepos[0])) + linepos++; + if (linepos[0] == '\0') + return -1; + + /* get operation type */ + if (linepos[0] == '=' && linepos[1] == '=') { + *operation = KEY_OP_MATCH; + linepos += 2; + dbg("operator=match"); + } else if (linepos[0] == '!' && linepos[1] == '=') { + *operation = KEY_OP_NOMATCH; + linepos += 2; + dbg("operator=nomatch"); + } else if (linepos[0] == '+' && linepos[1] == '=') { + *operation = KEY_OP_ADD; + linepos += 2; + dbg("operator=add"); + } else if (linepos[0] == '=') { + *operation = KEY_OP_ASSIGN; + linepos++; + dbg("operator=assign"); + } else if (linepos[0] == ':' && linepos[1] == '=') { + *operation = KEY_OP_ASSIGN_FINAL; + linepos += 2; + dbg("operator=assign_final"); + } else + return -1; + + /* terminate key */ + temp[0] = '\0'; + dbg("key='%s'", *key); + + /* skip whitespace after operator */ + while (isspace(linepos[0])) + linepos++; + if (linepos[0] == '\0') + return -1; + + /* get the value*/ + if (linepos[0] == '"') + linepos++; + else + return -1; + *value = linepos; + + temp = strchr(linepos, '"'); + if (!temp) + return -1; + temp[0] = '\0'; + temp++; + dbg("value='%s'", *value); + + /* move line to next key */ + *line = temp; + + return 0; +} + +/* extract possible KEY{attr} */ +static char *get_key_attribute(char *str) +{ + char *pos; + char *attr; + + attr = strchr(str, '{'); + if (attr != NULL) { + attr++; + pos = strchr(attr, '}'); + if (pos == NULL) { + err("missing closing brace for format"); + return NULL; + } + pos[0] = '\0'; + dbg("attribute='%s'", attr); + return attr; + } + + return NULL; +} + +static int add_rule_key(struct udev_rule *rule, struct key *key, + enum key_operation operation, const char *value) +{ + size_t val_len = strnlen(value, PATH_SIZE); + + key->operation = operation; + + key->val_off = rule->bufsize; + strlcpy(rule->buf + rule->bufsize, value, val_len+1); + rule->bufsize += val_len+1; + + return 0; +} + +static int add_rule_key_pair(struct udev_rule *rule, struct key_pairs *pairs, + enum key_operation operation, const char *key, const char *value) +{ + size_t key_len = strnlen(key, PATH_SIZE); + + if (pairs->count >= PAIRS_MAX) { + err("skip, too many keys of the same type in a single rule"); + return -1; + } + + add_rule_key(rule, &pairs->keys[pairs->count].key, operation, value); + + /* add the key-name of the pair */ + pairs->keys[pairs->count].key_name_off = rule->bufsize; + strlcpy(rule->buf + rule->bufsize, key, key_len+1); + rule->bufsize += key_len+1; + + pairs->count++; + + return 0; +} + +static int add_to_rules(struct udev_rules *rules, char *line, const char *filename, unsigned int lineno) +{ + char buf[sizeof(struct udev_rule) + LINE_SIZE]; + struct udev_rule *rule; + size_t rule_size; + int valid; + char *linepos; + char *attr; + size_t padding; + int physdev = 0; + int retval; + + memset(buf, 0x00, sizeof(buf)); + rule = (struct udev_rule *) buf; + linepos = line; + valid = 0; + + /* get all the keys */ + while (1) { + char *key; + char *value; + enum key_operation operation = KEY_OP_UNSET; + + retval = get_key(&linepos, &key, &operation, &value); + if (retval) + break; + + if (strcasecmp(key, "ACTION") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid ACTION operation"); + goto invalid; + } + add_rule_key(rule, &rule->action, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "DEVPATH") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid DEVPATH operation"); + goto invalid; + } + add_rule_key(rule, &rule->devpath, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "KERNEL") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid KERNEL operation"); + goto invalid; + } + add_rule_key(rule, &rule->kernel, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "SUBSYSTEM") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid SUBSYSTEM operation"); + goto invalid; + } + /* bus, class, subsystem events should all be the same */ + if (strcmp(value, "subsystem") == 0 || + strcmp(value, "bus") == 0 || + strcmp(value, "class") == 0) { + if (strcmp(value, "bus") == 0 || strcmp(value, "class") == 0) + err("'%s' must be specified as 'subsystem' " + "please fix it in %s:%u", value, filename, lineno); + add_rule_key(rule, &rule->subsystem, operation, "subsystem|class|bus"); + } else + add_rule_key(rule, &rule->subsystem, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "DRIVER") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid DRIVER operation"); + goto invalid; + } + add_rule_key(rule, &rule->driver, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "ATTR{", sizeof("ATTR{")-1) == 0) { + attr = get_key_attribute(key + sizeof("ATTR")-1); + if (attr == NULL) { + err("error parsing ATTR attribute"); + goto invalid; + } + if (add_rule_key_pair(rule, &rule->attr, operation, attr, value) != 0) + goto invalid; + valid = 1; + continue; + } + + if (strcasecmp(key, "KERNELS") == 0 || + strcasecmp(key, "ID") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid KERNELS operation"); + goto invalid; + } + add_rule_key(rule, &rule->kernels, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "SUBSYSTEMS") == 0 || + strcasecmp(key, "BUS") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid SUBSYSTEMS operation"); + goto invalid; + } + add_rule_key(rule, &rule->subsystems, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "DRIVERS") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid DRIVERS operation"); + goto invalid; + } + add_rule_key(rule, &rule->drivers, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "ATTRS{", sizeof("ATTRS{")-1) == 0 || + strncasecmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid ATTRS operation"); + goto invalid; + } + attr = get_key_attribute(key + sizeof("ATTRS")-1); + if (attr == NULL) { + err("error parsing ATTRS attribute"); + goto invalid; + } + if (strncmp(attr, "device/", 7) == 0) + err("the 'device' link is deprecated and will be removed from a future kernel, " + "please fix it in %s:%u", filename, lineno); + else if (strstr(attr, "../") != NULL) + err("do not reference parent sysfs directories directly, that may break with a future kernel, " + "please fix it in %s:%u", filename, lineno); + if (add_rule_key_pair(rule, &rule->attrs, operation, attr, value) != 0) + goto invalid; + valid = 1; + continue; + } + + if (strncasecmp(key, "ENV{", sizeof("ENV{")-1) == 0) { + attr = get_key_attribute(key + sizeof("ENV")-1); + if (attr == NULL) { + err("error parsing ENV attribute"); + goto invalid; + } + if (strncmp(attr, "PHYSDEV", 7) == 0) + physdev = 1; + if (add_rule_key_pair(rule, &rule->env, operation, attr, value) != 0) + goto invalid; + valid = 1; + continue; + } + + if (strcasecmp(key, "PROGRAM") == 0) { + add_rule_key(rule, &rule->program, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "RESULT") == 0) { + if (operation != KEY_OP_MATCH && + operation != KEY_OP_NOMATCH) { + err("invalid RESULT operation"); + goto invalid; + } + add_rule_key(rule, &rule->result, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) { + attr = get_key_attribute(key + sizeof("IMPORT")-1); + if (attr != NULL && strstr(attr, "program")) { + dbg("IMPORT will be executed"); + rule->import_type = IMPORT_PROGRAM; + } else if (attr != NULL && strstr(attr, "file")) { + dbg("IMPORT will be included as file"); + rule->import_type = IMPORT_FILE; + } else if (attr != NULL && strstr(attr, "parent")) { + dbg("IMPORT will include the parent values"); + rule->import_type = IMPORT_PARENT; + } else { + /* figure it out if it is executable */ + char file[PATH_SIZE]; + char *pos; + struct stat statbuf; + + strlcpy(file, value, sizeof(file)); + pos = strchr(file, ' '); + if (pos) + pos[0] = '\0'; + + /* allow programs in /lib/udev called without the path */ + if (strchr(file, '/') == NULL) { + strlcpy(file, "/lib/udev/", sizeof(file)); + strlcat(file, value, sizeof(file)); + pos = strchr(file, ' '); + if (pos) + pos[0] = '\0'; + } + + dbg("IMPORT auto mode for '%s'", file); + if (!lstat(file, &statbuf) && (statbuf.st_mode & S_IXUSR)) { + dbg("IMPORT is executable, will be executed (autotype)"); + rule->import_type = IMPORT_PROGRAM; + } else { + dbg("IMPORT is not executable, will be included as file (autotype)"); + rule->import_type = IMPORT_FILE; + } + } + add_rule_key(rule, &rule->import, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "TEST", sizeof("TEST")-1) == 0) { + attr = get_key_attribute(key + sizeof("TEST")-1); + if (attr != NULL) + rule->test_mode_mask = strtol(attr, NULL, 8); + add_rule_key(rule, &rule->test, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "RUN", sizeof("RUN")-1) == 0) { + attr = get_key_attribute(key + sizeof("RUN")-1); + if (attr != NULL) { + if (strstr(attr, "ignore_error")) + rule->run_ignore_error = 1; + } + add_rule_key(rule, &rule->run, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) { + add_rule_key(rule, &rule->wait_for_sysfs, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "LABEL") == 0) { + add_rule_key(rule, &rule->label, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "GOTO") == 0) { + add_rule_key(rule, &rule->goto_label, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "NAME", sizeof("NAME")-1) == 0) { + attr = get_key_attribute(key + sizeof("NAME")-1); + if (attr != NULL) { + if (strstr(attr, "all_partitions") != NULL) { + dbg("creation of partition nodes requested"); + rule->partitions = DEFAULT_PARTITIONS_COUNT; + } + if (strstr(attr, "ignore_remove") != NULL) { + dbg("remove event should be ignored"); + rule->ignore_remove = 1; + } + } + if (value[0] == '\0') + dbg("name empty, node creation supressed"); + add_rule_key(rule, &rule->name, operation, value); + continue; + } + + if (strcasecmp(key, "SYMLINK") == 0) { + if (operation == KEY_OP_MATCH || + operation == KEY_OP_NOMATCH) + add_rule_key(rule, &rule->symlink_match, operation, value); + else + add_rule_key(rule, &rule->symlink, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "OWNER") == 0) { + valid = 1; + if (rules->resolve_names && (!strchr(value, '$') && !strchr(value, '%'))) { + char *endptr; + strtoul(value, &endptr, 10); + if (endptr[0] != '\0') { + char owner[32]; + uid_t uid = lookup_user(value); + dbg("replacing username='%s' by id=%i", value, uid); + sprintf(owner, "%u", (unsigned int) uid); + add_rule_key(rule, &rule->owner, operation, owner); + continue; + } + } + + add_rule_key(rule, &rule->owner, operation, value); + continue; + } + + if (strcasecmp(key, "GROUP") == 0) { + valid = 1; + if (rules->resolve_names && (!strchr(value, '$') && !strchr(value, '%'))) { + char *endptr; + strtoul(value, &endptr, 10); + if (endptr[0] != '\0') { + char group[32]; + gid_t gid = lookup_group(value); + dbg("replacing groupname='%s' by id=%i", value, gid); + sprintf(group, "%u", (unsigned int) gid); + add_rule_key(rule, &rule->group, operation, group); + continue; + } + } + + add_rule_key(rule, &rule->group, operation, value); + continue; + } + + if (strcasecmp(key, "MODE") == 0) { + rule->mode = strtol(value, NULL, 8); + rule->mode_operation = operation; + valid = 1; + continue; + } + + if (strcasecmp(key, "OPTIONS") == 0) { + const char *pos; + + if (strstr(value, "last_rule") != NULL) { + dbg("last rule to be applied"); + rule->last_rule = 1; + } + if (strstr(value, "ignore_device") != NULL) { + dbg("device should be ignored"); + rule->ignore_device = 1; + } + if (strstr(value, "ignore_remove") != NULL) { + dbg("remove event should be ignored"); + rule->ignore_remove = 1; + } + pos = strstr(value, "link_priority="); + if (pos != NULL) { + rule->link_priority = atoi(&pos[strlen("link_priority=")]); + dbg("link priority=%i", rule->link_priority); + } + pos = strstr(value, "string_escape="); + if (pos != NULL) { + pos = &pos[strlen("string_escape=")]; + if (strncmp(pos, "none", strlen("none")) == 0) + rule->string_escape = ESCAPE_NONE; + else if (strncmp(pos, "replace", strlen("replace")) == 0) + rule->string_escape = ESCAPE_REPLACE; + } + if (strstr(value, "all_partitions") != NULL) { + dbg("creation of partition nodes requested"); + rule->partitions = DEFAULT_PARTITIONS_COUNT; + } + valid = 1; + continue; + } + + err("unknown key '%s' in %s:%u", key, filename, lineno); + } + + if (physdev && rule->wait_for_sysfs.operation == KEY_OP_UNSET) + err("PHYSDEV* values are deprecated and will be removed from a future kernel, " + "please fix it in %s:%u", filename, lineno); + + /* skip line if not any valid key was found */ + if (!valid) + goto invalid; + + /* grow buffer and add rule */ + rule_size = sizeof(struct udev_rule) + rule->bufsize; + padding = (sizeof(size_t) - rule_size % sizeof(size_t)) % sizeof(size_t); + dbg("add %zi padding bytes", padding); + rule_size += padding; + rule->bufsize += padding; + + rules->buf = realloc(rules->buf, rules->bufsize + rule_size); + if (!rules->buf) { + err("realloc failed"); + goto exit; + } + dbg("adding rule to offset %zi", rules->bufsize); + memcpy(rules->buf + rules->bufsize, rule, rule_size); + rules->bufsize += rule_size; +exit: + return 0; + +invalid: + err("invalid rule '%s:%u'", filename, lineno); + return -1; +} + +static int parse_file(struct udev_rules *rules, const char *filename) +{ + char line[LINE_SIZE]; + char *bufline; + unsigned int lineno; + char *buf; + size_t bufsize; + size_t cur; + size_t count; + int retval = 0; + + if (file_map(filename, &buf, &bufsize) != 0) { + err("can't open '%s' as rules file: %s", filename, strerror(errno)); + return -1; + } + info("reading '%s' as rules file", filename); + + /* loop through the whole file */ + cur = 0; + lineno = 0; + while (cur < bufsize) { + unsigned int i, j; + + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + lineno++; + + /* eat the whitespace */ + while ((count > 0) && isspace(bufline[0])) { + bufline++; + count--; + } + if (count == 0) + continue; + + /* see if this is a comment */ + if (bufline[0] == COMMENT_CHARACTER) + continue; + + if (count >= sizeof(line)) { + err("line too long, rule skipped '%s:%u'", filename, lineno); + continue; + } + + /* skip backslash and newline from multiline rules */ + for (i = j = 0; i < count; i++) { + if (bufline[i] == '\\' && bufline[i+1] == '\n') + continue; + + line[j++] = bufline[i]; + } + line[j] = '\0'; + + dbg("read '%s'", line); + add_to_rules(rules, line, filename, lineno); + } + + file_unmap(buf, bufsize); + return retval; +} + +int udev_rules_init(struct udev_rules *rules, int resolve_names) +{ + struct stat statbuf; + char filename[PATH_MAX]; + LIST_HEAD(name_list); + LIST_HEAD(dyn_list); + struct name_entry *name_loop, *name_tmp; + struct name_entry *dyn_loop, *dyn_tmp; + int retval = 0; + + memset(rules, 0x00, sizeof(struct udev_rules)); + rules->resolve_names = resolve_names; + + /* read main config from single file or all files in a directory */ + if (stat(udev_rules_dir, &statbuf) != 0) + return -1; + if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { + dbg("parse single rules file '%s'", udev_rules_dir); + name_list_add(&name_list, udev_rules_dir, 1); + } else { + dbg("parse rules directory '%s'", udev_rules_dir); + retval = add_matching_files(&name_list, udev_rules_dir, RULESFILE_SUFFIX); + } + + /* read dynamic rules directory */ + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/"RULES_DYN_DIR, sizeof(filename)); + if (stat(filename, &statbuf) != 0) { + create_path(filename); + mkdir(filename, 0755); + } + add_matching_files(&dyn_list, filename, RULESFILE_SUFFIX); + + /* sort dynamic rules files by basename into list of files */ + list_for_each_entry_safe(dyn_loop, dyn_tmp, &dyn_list, node) { + const char *dyn_base = strrchr(dyn_loop->name, '/'); + + if (dyn_base == NULL) + continue; + + list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { + const char *name_base = strrchr(name_loop->name, '/'); + + if (name_base == NULL) + continue; + + if (strcmp(name_base, dyn_base) > 0) { + list_move_tail(&dyn_loop->node, &name_loop->node); + break; + } + } + } + + /* parse list of files */ + list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { + if (stat(name_loop->name, &statbuf) == 0) { + if (statbuf.st_size) + parse_file(rules, name_loop->name); + else + dbg("empty rules file '%s'", name_loop->name); + } else + err("could not read '%s': %s", name_loop->name, strerror(errno)); + list_del(&name_loop->node); + free(name_loop); + } + + return retval; +} + +void udev_rules_cleanup(struct udev_rules *rules) +{ + if (rules->buf) { + free(rules->buf); + rules->buf = NULL; + } +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_selinux.c b/21cnbao/code/05/udev源代码/udev-114/udev_selinux.c new file mode 100644 index 0000000..1ad6e8a --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_selinux.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2004 Daniel Walsh + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_selinux.h" + +static security_context_t prev_scontext = NULL; + +static int is_selinux_running(void) +{ + static int selinux_enabled = -1; + + if (selinux_enabled == -1) + selinux_enabled = (is_selinux_enabled() > 0); + + dbg("selinux=%i", selinux_enabled); + return selinux_enabled; +} + +static char *get_media(const char *devname, int mode) +{ + FILE *fp; + char procfile[PATH_MAX]; + char mediabuf[256]; + int size; + char *media = NULL; + + if (!(mode & S_IFBLK)) + return NULL; + + snprintf(procfile, PATH_MAX, "/proc/ide/%s/media", devname); + procfile[PATH_MAX-1] = '\0'; + + fp = fopen(procfile, "r"); + if (!fp) + goto out; + + if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL) + goto close_out; + + size = strlen(mediabuf); + while (size-- > 0) { + if (isspace(mediabuf[size])) { + mediabuf[size] = '\0'; + } else { + break; + } + } + + media = strdup(mediabuf); + info("selinux_get_media(%s)='%s'", devname, media); + +close_out: + fclose(fp); +out: + return media; +} + +void selinux_setfilecon(const char *file, const char *devname, unsigned int mode) +{ + if (is_selinux_running()) { + security_context_t scontext = NULL; + char *media; + int ret = -1; + + if (devname) { + media = get_media(devname, mode); + if (media) { + ret = matchmediacon(media, &scontext); + free(media); + } + } + + if (ret < 0) + if (matchpathcon(file, mode, &scontext) < 0) { + err("matchpathcon(%s) failed", file); + return; + } + + if (lsetfilecon(file, scontext) < 0) + err("setfilecon %s failed: %s", file, strerror(errno)); + + freecon(scontext); + } +} + +void selinux_setfscreatecon(const char *file, const char *devname, unsigned int mode) +{ + if (is_selinux_running()) { + security_context_t scontext = NULL; + char *media; + int ret = -1; + + if (devname) { + media = get_media(devname, mode); + if (media) { + ret = matchmediacon(media, &scontext); + free(media); + } + } + + if (ret < 0) + if (matchpathcon(file, mode, &scontext) < 0) { + err("matchpathcon(%s) failed", file); + return; + } + + if (setfscreatecon(scontext) < 0) + err("setfscreatecon %s failed: %s", file, strerror(errno)); + + freecon(scontext); + } +} + +void selinux_resetfscreatecon(void) +{ + if (is_selinux_running()) { + if (setfscreatecon(prev_scontext) < 0) + err("setfscreatecon failed: %s", strerror(errno)); + } +} + +void selinux_init(void) +{ + /* + * record the present security context, for file-creation + * restoration creation purposes. + */ + if (is_selinux_running()) { + if (!udev_root[0]) + err("selinux_init: udev_root not set"); + matchpathcon_init_prefix(NULL, udev_root); + if (getfscreatecon(&prev_scontext) < 0) { + err("getfscreatecon failed"); + prev_scontext = NULL; + } + } +} + +void selinux_exit(void) +{ + if (is_selinux_running() && prev_scontext) { + freecon(prev_scontext); + prev_scontext = NULL; + } +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_selinux.h b/21cnbao/code/05/udev源代码/udev-114/udev_selinux.h new file mode 100644 index 0000000..73567d6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_selinux.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2004 Daniel Walsh + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef _UDEV_SELINUX_H +#define _UDEV_SELINUX_H + +#ifdef USE_SELINUX + +extern void selinux_setfilecon(const char *file, const char *devname, unsigned int mode); +extern void selinux_setfscreatecon(const char *file, const char *devname, unsigned int mode); +extern void selinux_resetfscreatecon(void); +extern void selinux_init(void); +extern void selinux_exit(void); + +#else + +static inline void selinux_setfilecon(const char *file, const char *devname, unsigned int mode) {} +static inline void selinux_setfscreatecon(const char *file, const char *devname, unsigned int mode) {} +static inline void selinux_resetfscreatecon(void) {} +static inline void selinux_init(void) {} +static inline void selinux_exit(void) {} + +#endif /* USE_SELINUX */ +#endif /* _UDEV_USE_SELINUX */ diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_sysdeps.c b/21cnbao/code/05/udev源代码/udev-114/udev_sysdeps.c new file mode 100644 index 0000000..9447cca --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_sysdeps.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2005-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +#ifdef __GLIBC__ +size_t strlcpy(char *dst, const char *src, size_t size) +{ + size_t bytes = 0; + char *q = dst; + const char *p = src; + char ch; + + while ((ch = *p++)) { + if (bytes+1 < size) + *q++ = ch; + bytes++; + } + + /* If size == 0 there is no space for a final null... */ + if (size) + *q = '\0'; + return bytes; +} + +size_t strlcat(char *dst, const char *src, size_t size) +{ + size_t bytes = 0; + char *q = dst; + const char *p = src; + char ch; + + while (bytes < size && *q) { + q++; + bytes++; + } + if (bytes == size) + return (bytes + strlen(src)); + + while ((ch = *p++)) { + if (bytes+1 < size) + *q++ = ch; + bytes++; + } + + *q = '\0'; + return bytes; +} +#endif /* __GLIBC__ */ diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_sysdeps.h b/21cnbao/code/05/udev源代码/udev-114/udev_sysdeps.h new file mode 100644 index 0000000..d4f0368 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_sysdeps.h @@ -0,0 +1,172 @@ +/* + * wrapping of libc features and kernel interfaces + * + * Copyright (C) 2005-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef _UDEV_SYSDEPS_H_ +#define _UDEV_SYSDEPS_H_ + +#include +#include +#include + +/* needed until Inotify! syscalls reach glibc */ +#include +#ifndef __NR_inotify_init +#if defined(__i386__) +# define __NR_inotify_init 291 +# define __NR_inotify_add_watch 292 +# define __NR_inotify_rm_watch 293 +#elif defined(__x86_64__) +# define __NR_inotify_init 253 +# define __NR_inotify_add_watch 254 +# define __NR_inotify_rm_watch 255 +#elif defined(__powerpc__) || defined(__powerpc64__) +# define __NR_inotify_init 275 +# define __NR_inotify_add_watch 276 +# define __NR_inotify_rm_watch 277 +#elif defined (__ia64__) +# define __NR_inotify_init 1277 +# define __NR_inotify_add_watch 1278 +# define __NR_inotify_rm_watch 1279 +#elif defined (__s390__) +# define __NR_inotify_init 284 +# define __NR_inotify_add_watch 285 +# define __NR_inotify_rm_watch 286 +#elif defined (__alpha__) +# define __NR_inotify_init 444 +# define __NR_inotify_add_watch 445 +# define __NR_inotify_rm_watch 446 +#elif defined (__sparc__) || defined (__sparc64__) +# define __NR_inotify_init 151 +# define __NR_inotify_add_watch 152 +# define __NR_inotify_rm_watch 156 +#elif defined (__arm__) +# define __NR_inotify_init __NR_SYSCALL_BASE+316 +# define __NR_inotify_add_watch __NR_SYSCALL_BASE+317 +# define __NR_inotify_rm_watch __NR_SYSCALL_BASE+318 +#elif defined (__sh__) +# define __NR_inotify_init 290 +# define __NR_inotify_add_watch 291 +# define __NR_inotify_rm_watch 292 +#elif defined (__m32r__) +# define __NR_inotify_init 290 +# define __NR_inotify_add_watch 291 +# define __NR_inotify_rm_watch 292 +#elif defined (__hppa__) +# define __NR_inotify_init 269 +# define __NR_inotify_add_watch 270 +# define __NR_inotify_rm_watch 271 +#elif defined (__mips__) +# include +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define __NR_Linux 4000 +# define __NR_inotify_init (__NR_Linux + 284) +# define __NR_inotify_add_watch (__NR_Linux + 285) +# define __NR_inotify_rm_watch (__NR_Linux + 286) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define __NR_Linux 5000 +# define __NR_inotify_init (__NR_Linux + 243) +# define __NR_inotify_add_watch (__NR_Linux + 244) +# define __NR_inotify_rm_watch (__NR_Linux + 245) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define __NR_Linux 6000 +# define __NR_inotify_init (__NR_Linux + 247) +# define __NR_inotify_add_watch (__NR_Linux + 248) +# define __NR_inotify_rm_watch (__NR_Linux + 249) +# endif +#else +#warning "inotify unsupported on this architecture!" +#endif +#endif /* __NR_inotify_init */ + +/* dummy if we don't have the syscalls defined */ +#ifndef __NR_inotify_init +static inline int inotify_init(void) +{ + return -1; +} + +static inline int inotify_add_watch(int fd, const char *name, uint32_t mask) +{ + return -1; +} +#else +/* needed until /usr/include/sys/inotify.h is working */ +#ifndef __GLIBC__ +#include +#else +static inline int inotify_init(void) +{ + return syscall(__NR_inotify_init); +} + +static inline int inotify_add_watch(int fd, const char *name, uint32_t mask) +{ + return syscall(__NR_inotify_add_watch, fd, name, mask); +} +#endif /* __GLIBC__ */ +#endif /* __NR_inotify_init */ + +#ifndef IN_CREATE +#define IN_CREATE 0x00000100 /* Subfile was created */ +#define IN_MOVED_FROM 0x00000040 /* File was moved from X */ +#define IN_MOVED_TO 0x00000080 /* File was moved to Y */ +#define IN_DELETE 0x00000200 /* Subfile was deleted */ +#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ +#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */ +#endif /* IN_CREATE */ + +/* needed for our signal handlers to work */ +#undef asmlinkage +#ifdef __i386__ +#define asmlinkage __attribute__((regparm(0))) +#else +#define asmlinkage +#endif /* __i386__ */ + +/* headers are broken on some architectures */ +#ifndef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#endif +#ifndef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#endif +#ifndef __FD_ISSET +#define __FD_ISSET(d, set) (((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0) +#endif +#ifndef __FD_ZERO +#define __FD_ZERO(set) ((void) memset ((void*) (set), 0, sizeof (fd_set))) +#endif + +#ifndef NETLINK_KOBJECT_UEVENT +#define NETLINK_KOBJECT_UEVENT 15 +#endif + +#ifndef SO_RCVBUFFORCE +#if defined(__alpha__) || defined(__hppa__) || defined(__sparc__) || defined(__sparc_v9__) +#define SO_RCVBUFFORCE 0x100b +#else +#define SO_RCVBUFFORCE 33 +#endif +#endif + +extern size_t strlcpy(char *dst, const char *src, size_t size); +extern size_t strlcat(char *dst, const char *src, size_t size); + +#endif diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_sysfs.c b/21cnbao/code/05/udev源代码/udev-114/udev_sysfs.c new file mode 100644 index 0000000..34ae9ac --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_sysfs.c @@ -0,0 +1,526 @@ +/* + * Copyright (C) 2005-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +char sysfs_path[PATH_SIZE]; + +/* device cache */ +static LIST_HEAD(dev_list); + +/* attribute value cache */ +static LIST_HEAD(attr_list); +struct sysfs_attr { + struct list_head node; + char path[PATH_SIZE]; + char *value; /* points to value_local if value is cached */ + char value_local[NAME_SIZE]; +}; + +int sysfs_init(void) +{ + const char *env; + + env = getenv("SYSFS_PATH"); + if (env) { + strlcpy(sysfs_path, env, sizeof(sysfs_path)); + remove_trailing_chars(sysfs_path, '/'); + } else + strlcpy(sysfs_path, "/sys", sizeof(sysfs_path)); + dbg("sysfs_path='%s'", sysfs_path); + + INIT_LIST_HEAD(&dev_list); + INIT_LIST_HEAD(&attr_list); + return 0; +} + +void sysfs_cleanup(void) +{ + struct sysfs_attr *attr_loop; + struct sysfs_attr *attr_temp; + struct sysfs_device *dev_loop; + struct sysfs_device *dev_temp; + + list_for_each_entry_safe(attr_loop, attr_temp, &attr_list, node) { + list_del(&attr_loop->node); + free(attr_loop); + } + + list_for_each_entry_safe(dev_loop, dev_temp, &dev_list, node) { + list_del(&dev_loop->node); + free(dev_loop); + } +} + +void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath, + const char *subsystem, const char *driver) +{ + char *pos; + + strlcpy(dev->devpath, devpath, sizeof(dev->devpath)); + if (subsystem != NULL) + strlcpy(dev->subsystem, subsystem, sizeof(dev->subsystem)); + if (driver != NULL) + strlcpy(dev->driver, driver, sizeof(dev->driver)); + + /* set kernel name */ + pos = strrchr(dev->devpath, '/'); + if (pos == NULL) + return; + strlcpy(dev->kernel, &pos[1], sizeof(dev->kernel)); + dbg("kernel='%s'", dev->kernel); + + /* some devices have '!' in their name, change that to '/' */ + pos = dev->kernel; + while (pos[0] != '\0') { + if (pos[0] == '!') + pos[0] = '/'; + pos++; + } + + /* get kernel number */ + pos = &dev->kernel[strlen(dev->kernel)]; + while (isdigit(pos[-1])) + pos--; + strlcpy(dev->kernel_number, pos, sizeof(dev->kernel_number)); + dbg("kernel_number='%s'", dev->kernel_number); +} + +int sysfs_resolve_link(char *devpath, size_t size) +{ + char link_path[PATH_SIZE]; + char link_target[PATH_SIZE]; + int len; + int i; + int back; + + strlcpy(link_path, sysfs_path, sizeof(link_path)); + strlcat(link_path, devpath, sizeof(link_path)); + len = readlink(link_path, link_target, sizeof(link_target)); + if (len <= 0) + return -1; + link_target[len] = '\0'; + dbg("path link '%s' points to '%s'", devpath, link_target); + + for (back = 0; strncmp(&link_target[back * 3], "../", 3) == 0; back++) + ; + dbg("base '%s', tail '%s', back %i", devpath, &link_target[back * 3], back); + for (i = 0; i <= back; i++) { + char *pos = strrchr(devpath, '/'); + + if (pos == NULL) + return -1; + pos[0] = '\0'; + } + dbg("after moving back '%s'", devpath); + strlcat(devpath, "/", size); + strlcat(devpath, &link_target[back * 3], size); + return 0; +} + +struct sysfs_device *sysfs_device_get(const char *devpath) +{ + char path[PATH_SIZE]; + char devpath_real[PATH_SIZE]; + struct sysfs_device *dev; + struct sysfs_device *dev_loop; + struct stat statbuf; + char link_path[PATH_SIZE]; + char link_target[PATH_SIZE]; + int len; + char *pos; + + /* we handle only these devpathes */ + if (devpath != NULL && + strncmp(devpath, "/devices/", 9) != 0 && + strncmp(devpath, "/subsystem/", 11) != 0 && + strncmp(devpath, "/module/", 8) != 0 && + strncmp(devpath, "/bus/", 5) != 0 && + strncmp(devpath, "/class/", 7) != 0 && + strncmp(devpath, "/block/", 7) != 0) + return NULL; + + dbg("open '%s'", devpath); + strlcpy(devpath_real, devpath, sizeof(devpath_real)); + remove_trailing_chars(devpath_real, '/'); + if (devpath[0] == '\0' ) + return NULL; + + /* look for device already in cache (we never put an untranslated path in the cache) */ + list_for_each_entry(dev_loop, &dev_list, node) { + if (strcmp(dev_loop->devpath, devpath_real) == 0) { + dbg("found in cache '%s'", dev_loop->devpath); + return dev_loop; + } + } + + /* if we got a link, resolve it to the real device */ + strlcpy(path, sysfs_path, sizeof(path)); + strlcat(path, devpath_real, sizeof(path)); + if (lstat(path, &statbuf) != 0) { + dbg("stat '%s' failed: %s", path, strerror(errno)); + return NULL; + } + if (S_ISLNK(statbuf.st_mode)) { + if (sysfs_resolve_link(devpath_real, sizeof(devpath_real)) != 0) + return NULL; + + /* now look for device in cache after path translation */ + list_for_each_entry(dev_loop, &dev_list, node) { + if (strcmp(dev_loop->devpath, devpath_real) == 0) { + dbg("found in cache '%s'", dev_loop->devpath); + return dev_loop; + } + } + } + + /* it is a new device */ + dbg("new uncached device '%s'", devpath_real); + dev = malloc(sizeof(struct sysfs_device)); + if (dev == NULL) + return NULL; + memset(dev, 0x00, sizeof(struct sysfs_device)); + + sysfs_device_set_values(dev, devpath_real, NULL, NULL); + + /* get subsystem name */ + strlcpy(link_path, sysfs_path, sizeof(link_path)); + strlcat(link_path, dev->devpath, sizeof(link_path)); + strlcat(link_path, "/subsystem", sizeof(link_path)); + len = readlink(link_path, link_target, sizeof(link_target)); + if (len > 0) { + /* get subsystem from "subsystem" link */ + link_target[len] = '\0'; + dbg("subsystem link '%s' points to '%s'", link_path, link_target); + pos = strrchr(link_target, '/'); + if (pos != NULL) + strlcpy(dev->subsystem, &pos[1], sizeof(dev->subsystem)); + } else if (strncmp(dev->devpath, "/class/", 7) == 0) { + /* get subsystem from class dir */ + strlcpy(dev->subsystem, &dev->devpath[7], sizeof(dev->subsystem)); + pos = strchr(dev->subsystem, '/'); + if (pos != NULL) + pos[0] = '\0'; + else + strlcpy(dev->subsystem, "subsystem", sizeof(dev->subsystem)); + } else if (strncmp(dev->devpath, "/block/", 7) == 0) { + strlcpy(dev->subsystem, "block", sizeof(dev->subsystem)); + } else if (strncmp(dev->devpath, "/devices/", 9) == 0) { + /* get subsystem from "bus" link */ + strlcpy(link_path, sysfs_path, sizeof(link_path)); + strlcat(link_path, dev->devpath, sizeof(link_path)); + strlcat(link_path, "/bus", sizeof(link_path)); + len = readlink(link_path, link_target, sizeof(link_target)); + if (len > 0) { + link_target[len] = '\0'; + dbg("bus link '%s' points to '%s'", link_path, link_target); + pos = strrchr(link_target, '/'); + if (pos != NULL) + strlcpy(dev->subsystem, &pos[1], sizeof(dev->subsystem)); + } + } else if (strstr(dev->devpath, "/drivers/") != NULL) { + strlcpy(dev->subsystem, "drivers", sizeof(dev->subsystem)); + } else if (strncmp(dev->devpath, "/module/", 8) == 0) { + strlcpy(dev->subsystem, "module", sizeof(dev->subsystem)); + } else if (strncmp(dev->devpath, "/subsystem/", 11) == 0) { + pos = strrchr(dev->devpath, '/'); + if (pos == &dev->devpath[10]) + strlcpy(dev->subsystem, "subsystem", sizeof(dev->subsystem)); + } else if (strncmp(dev->devpath, "/bus/", 5) == 0) { + pos = strrchr(dev->devpath, '/'); + if (pos == &dev->devpath[4]) + strlcpy(dev->subsystem, "subsystem", sizeof(dev->subsystem)); + } + + /* get driver name */ + strlcpy(link_path, sysfs_path, sizeof(link_path)); + strlcat(link_path, dev->devpath, sizeof(link_path)); + strlcat(link_path, "/driver", sizeof(link_path)); + len = readlink(link_path, link_target, sizeof(link_target)); + if (len > 0) { + link_target[len] = '\0'; + dbg("driver link '%s' points to '%s'", link_path, link_target); + pos = strrchr(link_target, '/'); + if (pos != NULL) + strlcpy(dev->driver, &pos[1], sizeof(dev->driver)); + } + + dbg("add to cache 'devpath=%s', subsystem='%s', driver='%s'", dev->devpath, dev->subsystem, dev->driver); + list_add(&dev->node, &dev_list); + + return dev; +} + +struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) +{ + char parent_devpath[PATH_SIZE]; + char *pos; + + dbg("open '%s'", dev->devpath); + + /* look if we already know the parent */ + if (dev->parent != NULL) + return dev->parent; + + strlcpy(parent_devpath, dev->devpath, sizeof(parent_devpath)); + dbg("'%s'", parent_devpath); + + /* strip last element */ + pos = strrchr(parent_devpath, '/'); + if (pos == NULL || pos == parent_devpath) + return NULL; + pos[0] = '\0'; + + if (strncmp(parent_devpath, "/class", 6) == 0) { + pos = strrchr(parent_devpath, '/'); + if (pos == &parent_devpath[6] || pos == parent_devpath) { + dbg("/class top level, look for device link"); + goto device_link; + } + } + if (strcmp(parent_devpath, "/block") == 0) { + dbg("/block top level, look for device link"); + goto device_link; + } + + /* are we at the top level? */ + pos = strrchr(parent_devpath, '/'); + if (pos == NULL || pos == parent_devpath) + return NULL; + + /* get parent and remember it */ + dev->parent = sysfs_device_get(parent_devpath); + return dev->parent; + +device_link: + strlcpy(parent_devpath, dev->devpath, sizeof(parent_devpath)); + strlcat(parent_devpath, "/device", sizeof(parent_devpath)); + if (sysfs_resolve_link(parent_devpath, sizeof(parent_devpath)) != 0) + return NULL; + + /* get parent and remember it */ + dev->parent = sysfs_device_get(parent_devpath); + return dev->parent; +} + +struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device *dev, const char *subsystem) +{ + struct sysfs_device *dev_parent; + + dev_parent = sysfs_device_get_parent(dev); + while (dev_parent != NULL) { + if (strcmp(dev_parent->subsystem, subsystem) == 0) + return dev_parent; + dev_parent = sysfs_device_get_parent(dev_parent); + } + return NULL; +} + +char *sysfs_attr_get_value(const char *devpath, const char *attr_name) +{ + char path_full[PATH_SIZE]; + const char *path; + char value[NAME_SIZE]; + struct sysfs_attr *attr_loop; + struct sysfs_attr *attr; + struct stat statbuf; + int fd; + ssize_t size; + size_t sysfs_len; + + dbg("open '%s'/'%s'", devpath, attr_name); + sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full)); + path = &path_full[sysfs_len]; + strlcat(path_full, devpath, sizeof(path_full)); + strlcat(path_full, "/", sizeof(path_full)); + strlcat(path_full, attr_name, sizeof(path_full)); + + /* look for attribute in cache */ + list_for_each_entry(attr_loop, &attr_list, node) { + if (strcmp(attr_loop->path, path) == 0) { + dbg("found in cache '%s'", attr_loop->path); + return attr_loop->value; + } + } + + /* store attribute in cache (also negatives are kept in cache) */ + dbg("new uncached attribute '%s'", path_full); + attr = malloc(sizeof(struct sysfs_attr)); + if (attr == NULL) + return NULL; + memset(attr, 0x00, sizeof(struct sysfs_attr)); + strlcpy(attr->path, path, sizeof(attr->path)); + dbg("add to cache '%s'", path_full); + list_add(&attr->node, &attr_list); + + if (lstat(path_full, &statbuf) != 0) { + dbg("stat '%s' failed: %s", path_full, strerror(errno)); + goto out; + } + + if (S_ISLNK(statbuf.st_mode)) { + /* links return the last element of the target path */ + char link_target[PATH_SIZE]; + int len; + const char *pos; + + len = readlink(path_full, link_target, sizeof(link_target)); + if (len > 0) { + link_target[len] = '\0'; + pos = strrchr(link_target, '/'); + if (pos != NULL) { + dbg("cache '%s' with link value '%s'", path_full, value); + strlcpy(attr->value_local, &pos[1], sizeof(attr->value_local)); + attr->value = attr->value_local; + } + } + goto out; + } + + /* skip directories */ + if (S_ISDIR(statbuf.st_mode)) + goto out; + + /* skip non-readable files */ + if ((statbuf.st_mode & S_IRUSR) == 0) + goto out; + + /* read attribute value */ + fd = open(path_full, O_RDONLY); + if (fd < 0) { + dbg("attribute '%s' does not exist", path_full); + goto out; + } + size = read(fd, value, sizeof(value)); + close(fd); + if (size < 0) + goto out; + if (size == sizeof(value)) + goto out; + + /* got a valid value, store and return it */ + value[size] = '\0'; + remove_trailing_chars(value, '\n'); + dbg("cache '%s' with attribute value '%s'", path_full, value); + strlcpy(attr->value_local, value, sizeof(attr->value_local)); + attr->value = attr->value_local; + +out: + return attr->value; +} + +int sysfs_lookup_devpath_by_subsys_id(char *devpath_full, size_t len, const char *subsystem, const char *id) +{ + size_t sysfs_len; + char path_full[PATH_SIZE]; + char *path; + struct stat statbuf; + + sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full)); + path = &path_full[sysfs_len]; + + if (strcmp(subsystem, "subsystem") == 0) { + strlcpy(path, "/subsystem/", sizeof(path_full) - sysfs_len); + strlcat(path, id, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len); + strlcat(path, id, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + goto out; + + strlcpy(path, "/class/", sizeof(path_full) - sysfs_len); + strlcat(path, id, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + } + + if (strcmp(subsystem, "module") == 0) { + strlcpy(path, "/module/", sizeof(path_full) - sysfs_len); + strlcat(path, id, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + goto out; + } + + if (strcmp(subsystem, "drivers") == 0) { + char subsys[NAME_SIZE]; + char *driver; + + strlcpy(subsys, id, sizeof(subsys)); + driver = strchr(subsys, ':'); + if (driver != NULL) { + driver[0] = '\0'; + driver = &driver[1]; + strlcpy(path, "/subsystem/", sizeof(path_full) - sysfs_len); + strlcat(path, subsys, sizeof(path_full) - sysfs_len); + strlcat(path, "/drivers/", sizeof(path_full) - sysfs_len); + strlcat(path, driver, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len); + strlcat(path, subsys, sizeof(path_full) - sysfs_len); + strlcat(path, "/drivers/", sizeof(path_full) - sysfs_len); + strlcat(path, driver, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + } + goto out; + } + + strlcpy(path, "/subsystem/", sizeof(path_full) - sysfs_len); + strlcat(path, subsystem, sizeof(path_full) - sysfs_len); + strlcat(path, "/devices/", sizeof(path_full) - sysfs_len); + strlcat(path, id, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len); + strlcat(path, subsystem, sizeof(path_full) - sysfs_len); + strlcat(path, "/devices/", sizeof(path_full) - sysfs_len); + strlcat(path, id, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + strlcpy(path, "/class/", sizeof(path_full) - sysfs_len); + strlcat(path, subsystem, sizeof(path_full) - sysfs_len); + strlcat(path, "/", sizeof(path_full) - sysfs_len); + strlcat(path, id, sizeof(path_full) - sysfs_len); + if (stat(path_full, &statbuf) == 0) + goto found; +out: + return 0; +found: + if (S_ISLNK(statbuf.st_mode)) + sysfs_resolve_link(path, sizeof(path_full) - sysfs_len); + strlcpy(devpath_full, path, len); + return 1; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_utils.c b/21cnbao/code/05/udev源代码/udev-114/udev_utils.c new file mode 100644 index 0000000..e1630b6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_utils.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2004-2005 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + + +int log_priority(const char *priority) +{ + char *endptr; + int prio; + + prio = strtol(priority, &endptr, 10); + if (endptr[0] == '\0') + return prio; + if (strncasecmp(priority, "err", 3) == 0) + return LOG_ERR; + if (strcasecmp(priority, "info") == 0) + return LOG_INFO; + if (strcasecmp(priority, "debug") == 0) + return LOG_DEBUG; + if (string_is_true(priority)) + return LOG_ERR; + + return 0; +} + +struct name_entry *name_list_add(struct list_head *name_list, const char *name, int sort) +{ + struct name_entry *name_loop; + struct name_entry *name_new; + + /* avoid duplicate entries */ + list_for_each_entry(name_loop, name_list, node) { + if (strcmp(name_loop->name, name) == 0) { + dbg("'%s' is already in the list", name); + return name_loop; + } + } + + if (sort) + list_for_each_entry(name_loop, name_list, node) { + if (strcmp(name_loop->name, name) > 0) + break; + } + + name_new = malloc(sizeof(struct name_entry)); + if (name_new == NULL) + return NULL; + + strlcpy(name_new->name, name, sizeof(name_new->name)); + dbg("adding '%s'", name_new->name); + list_add_tail(&name_new->node, &name_loop->node); + + return name_new; +} + +struct name_entry *name_list_key_add(struct list_head *name_list, const char *key, const char *value) +{ + struct name_entry *name_loop; + struct name_entry *name_new; + + list_for_each_entry(name_loop, name_list, node) { + if (strncmp(name_loop->name, key, strlen(key)) == 0) { + dbg("key already present '%s', replace it", name_loop->name); + snprintf(name_loop->name, sizeof(name_loop->name), "%s=%s", key, value); + name_loop->name[sizeof(name_loop->name)-1] = '\0'; + return name_loop; + } + } + + name_new = malloc(sizeof(struct name_entry)); + if (name_new == NULL) + return NULL; + + snprintf(name_new->name, sizeof(name_new->name), "%s=%s", key, value); + name_new->name[sizeof(name_new->name)-1] = '\0'; + dbg("adding '%s'", name_new->name); + list_add_tail(&name_new->node, &name_loop->node); + + return name_new; +} + +int name_list_key_remove(struct list_head *name_list, const char *key) +{ + struct name_entry *name_loop; + struct name_entry *name_tmp; + size_t keylen = strlen(key); + int retval = 0; + + list_for_each_entry_safe(name_loop, name_tmp, name_list, node) { + if (strncmp(name_loop->name, key, keylen) != 0) + continue; + if (name_loop->name[keylen] != '=') + continue; + list_del(&name_loop->node); + free(name_loop); + retval = 1; + break; + } + return retval; +} + +void name_list_cleanup(struct list_head *name_list) +{ + struct name_entry *name_loop; + struct name_entry *name_tmp; + + list_for_each_entry_safe(name_loop, name_tmp, name_list, node) { + list_del(&name_loop->node); + free(name_loop); + } +} + +/* calls function for every file found in specified directory */ +int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix) +{ + struct dirent *ent; + DIR *dir; + char filename[PATH_SIZE]; + + dbg("open directory '%s'", dirname); + dir = opendir(dirname); + if (dir == NULL) { + err("unable to open '%s': %s", dirname, strerror(errno)); + return -1; + } + + while (1) { + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + + if ((ent->d_name[0] == '.') || (ent->d_name[0] == COMMENT_CHARACTER)) + continue; + + /* look for file matching with specified suffix */ + if (suffix != NULL) { + const char *ext; + + ext = strrchr(ent->d_name, '.'); + if (ext == NULL) + continue; + if (strcmp(ext, suffix) != 0) + continue; + } + dbg("put file '%s/%s' into list", dirname, ent->d_name); + + snprintf(filename, sizeof(filename), "%s/%s", dirname, ent->d_name); + filename[sizeof(filename)-1] = '\0'; + name_list_add(name_list, filename, 1); + } + + closedir(dir); + return 0; +} + +uid_t lookup_user(const char *user) +{ + struct passwd *pw; + uid_t uid = 0; + + errno = 0; + pw = getpwnam(user); + if (pw == NULL) { + if (errno == 0 || errno == ENOENT || errno == ESRCH) + err("specified user '%s' unknown", user); + else + err("error resolving user '%s': %s", user, strerror(errno)); + } else + uid = pw->pw_uid; + + return uid; +} + +extern gid_t lookup_group(const char *group) +{ + struct group *gr; + gid_t gid = 0; + + errno = 0; + gr = getgrnam(group); + if (gr == NULL) { + if (errno == 0 || errno == ENOENT || errno == ESRCH) + err("specified group '%s' unknown", group); + else + err("error resolving group '%s': %s", group, strerror(errno)); + } else + gid = gr->gr_gid; + + return gid; +} + diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_utils_file.c b/21cnbao/code/05/udev源代码/udev-114/udev_utils_file.c new file mode 100644 index 0000000..0ceefe1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_utils_file.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2004-2005 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +int create_path(const char *path) +{ + char p[PATH_SIZE]; + char *pos; + struct stat stats; + + strlcpy(p, path, sizeof(p)); + pos = strrchr(p, '/'); + if (pos == p || pos == NULL) + return 0; + + while (pos[-1] == '/') + pos--; + pos[0] = '\0'; + + dbg("stat '%s'", p); + if (stat(p, &stats) == 0 && (stats.st_mode & S_IFMT) == S_IFDIR) + return 0; + + if (create_path(p) != 0) + return -1; + + dbg("mkdir '%s'", p); + if (mkdir(p, 0755) == 0) + return 0; + if (errno == EEXIST) + if (stat(p, &stats) == 0 && (stats.st_mode & S_IFMT) == S_IFDIR) + return 0; + return -1; +} + +int delete_path(const char *path) +{ + char p[PATH_SIZE]; + char *pos; + int retval; + + strcpy (p, path); + pos = strrchr(p, '/'); + if (pos == p || pos == NULL) + return 0; + + while (1) { + *pos = '\0'; + pos = strrchr(p, '/'); + + /* don't remove the last one */ + if ((pos == p) || (pos == NULL)) + break; + + /* remove if empty */ + retval = rmdir(p); + if (errno == ENOENT) + retval = 0; + if (retval) { + if (errno == ENOTEMPTY) + return 0; + err("rmdir(%s) failed: %s", p, strerror(errno)); + break; + } + dbg("removed '%s'", p); + } + return 0; +} + +/* Reset permissions on the device node, before unlinking it to make sure, + * that permisions of possible hard links will be removed too. + */ +int unlink_secure(const char *filename) +{ + int retval; + + retval = chown(filename, 0, 0); + if (retval) + err("chown(%s, 0, 0) failed: %s", filename, strerror(errno)); + + retval = chmod(filename, 0000); + if (retval) + err("chmod(%s, 0000) failed: %s", filename, strerror(errno)); + + retval = unlink(filename); + if (errno == ENOENT) + retval = 0; + + if (retval) + err("unlink(%s) failed: %s", filename, strerror(errno)); + + return retval; +} + +int file_map(const char *filename, char **buf, size_t *bufsize) +{ + struct stat stats; + int fd; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + return -1; + } + + if (fstat(fd, &stats) < 0) { + close(fd); + return -1; + } + + *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (*buf == MAP_FAILED) { + close(fd); + return -1; + } + *bufsize = stats.st_size; + + close(fd); + + return 0; +} + +void file_unmap(void *buf, size_t bufsize) +{ + munmap(buf, bufsize); +} + +/* return number of chars until the next newline, skip escaped newline */ +size_t buf_get_line(const char *buf, size_t buflen, size_t cur) +{ + int escape = 0; + size_t count; + + for (count = cur; count < buflen; count++) { + if (!escape && buf[count] == '\n') + break; + + if (buf[count] == '\\') + escape = 1; + else + escape = 0; + } + + return count - cur; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udev_utils_string.c b/21cnbao/code/05/udev源代码/udev-114/udev_utils_string.c new file mode 100644 index 0000000..e3dc137 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udev_utils_string.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2004-2005 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +int string_is_true(const char *str) +{ + if (strcasecmp(str, "true") == 0) + return 1; + if (strcasecmp(str, "yes") == 0) + return 1; + if (strcasecmp(str, "1") == 0) + return 1; + return 0; +} + +void remove_trailing_chars(char *path, char c) +{ + size_t len; + + len = strlen(path); + while (len > 0 && path[len-1] == c) + path[--len] = '\0'; +} + +size_t path_encode(char *s, size_t len) +{ + char t[(len * 3)+1]; + size_t i, j; + + t[0] = '\0'; + for (i = 0, j = 0; s[i] != '\0'; i++) { + if (s[i] == '/') { + memcpy(&t[j], "\\x2f", 4); + j += 4; + } else if (s[i] == '\\') { + memcpy(&t[j], "\\x5c", 4); + j += 4; + } else { + t[j] = s[i]; + j++; + } + } + t[j] = '\0'; + strncpy(s, t, len); + return j; +} + +size_t path_decode(char *s) +{ + size_t i, j; + + for (i = 0, j = 0; s[i] != '\0'; j++) { + if (memcmp(&s[i], "\\x2f", 4) == 0) { + s[j] = '/'; + i += 4; + }else if (memcmp(&s[i], "\\x5c", 4) == 0) { + s[j] = '\\'; + i += 4; + } else { + s[j] = s[i]; + i++; + } + } + s[j] = '\0'; + return j; +} + +/* count of characters used to encode one unicode char */ +static int utf8_encoded_expected_len(const char *str) +{ + unsigned char c = (unsigned char)str[0]; + + if (c < 0x80) + return 1; + if ((c & 0xe0) == 0xc0) + return 2; + if ((c & 0xf0) == 0xe0) + return 3; + if ((c & 0xf8) == 0xf0) + return 4; + if ((c & 0xfc) == 0xf8) + return 5; + if ((c & 0xfe) == 0xfc) + return 6; + return 0; +} + +/* decode one unicode char */ +static int utf8_encoded_to_unichar(const char *str) +{ + int unichar; + int len; + int i; + + len = utf8_encoded_expected_len(str); + switch (len) { + case 1: + return (int)str[0]; + case 2: + unichar = str[0] & 0x1f; + break; + case 3: + unichar = (int)str[0] & 0x0f; + break; + case 4: + unichar = (int)str[0] & 0x07; + break; + case 5: + unichar = (int)str[0] & 0x03; + break; + case 6: + unichar = (int)str[0] & 0x01; + break; + default: + return -1; + } + + for (i = 1; i < len; i++) { + if (((int)str[i] & 0xc0) != 0x80) + return -1; + unichar <<= 6; + unichar |= (int)str[i] & 0x3f; + } + + return unichar; +} + +/* expected size used to encode one unicode char */ +static int utf8_unichar_to_encoded_len(int unichar) +{ + if (unichar < 0x80) + return 1; + if (unichar < 0x800) + return 2; + if (unichar < 0x10000) + return 3; + if (unichar < 0x200000) + return 4; + if (unichar < 0x4000000) + return 5; + return 6; +} + +/* check if unicode char has a valid numeric range */ +static int utf8_unichar_valid_range(int unichar) +{ + if (unichar > 0x10ffff) + return 0; + if ((unichar & 0xfffff800) == 0xd800) + return 0; + if ((unichar > 0xfdcf) && (unichar < 0xfdf0)) + return 0; + if ((unichar & 0xffff) == 0xffff) + return 0; + return 1; +} + +/* validate one encoded unicode char and return its length */ +int utf8_encoded_valid_unichar(const char *str) +{ + int len; + int unichar; + int i; + + len = utf8_encoded_expected_len(str); + if (len == 0) + return -1; + + /* ascii is valid */ + if (len == 1) + return 1; + + /* check if expected encoded chars are available */ + for (i = 0; i < len; i++) + if ((str[i] & 0x80) != 0x80) + return -1; + + unichar = utf8_encoded_to_unichar(str); + + /* check if encoded length matches encoded value */ + if (utf8_unichar_to_encoded_len(unichar) != len) + return -1; + + /* check if value has valid range */ + if (!utf8_unichar_valid_range(unichar)) + return -1; + + return len; +} + +/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ +int replace_chars(char *str, const char *white) +{ + size_t i = 0; + int replaced = 0; + + while (str[i] != '\0') { + int len; + + /* accept whitelist */ + if (white != NULL && strchr(white, str[i]) != NULL) { + i++; + continue; + } + + /* accept plain ascii char */ + if ((str[i] >= '0' && str[i] <= '9') || + (str[i] >= 'A' && str[i] <= 'Z') || + (str[i] >= 'a' && str[i] <= 'z')) { + i++; + continue; + } + + /* accept hex encoding */ + if (str[i] == '\\' && str[i+1] == 'x') { + i += 2; + continue; + } + + /* accept valid utf8 */ + len = utf8_encoded_valid_unichar(&str[i]); + if (len > 1) { + i += len; + continue; + } + + /* if space is allowed, replace whitespace with ordinary space */ + if (isspace(str[i]) && strchr(white, ' ') != NULL) { + str[i] = ' '; + i++; + replaced++; + continue; + } + + /* everything else is replaced with '_' */ + str[i] = '_'; + i++; + replaced++; + } + + return replaced; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevcontrol.c b/21cnbao/code/05/udev源代码/udev-114/udevcontrol.c new file mode 100644 index 0000000..b20ce2e --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevcontrol.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2005-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" + +static int sock = -1; +static int udev_log = 0; + +#ifdef USE_LOG +void log_message (int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +int main(int argc, char *argv[], char *envp[]) +{ + static struct udevd_ctrl_msg ctrl_msg; + struct sockaddr_un saddr; + socklen_t addrlen; + const char *env; + const char *arg; + const char *val; + int *intval; + int retval = 1; + + env = getenv("UDEV_LOG"); + if (env) + udev_log = log_priority(env); + + logging_init("udevcontrol"); + dbg("version %s", UDEV_VERSION); + + if (argc < 2) { + fprintf(stderr, "missing command\n\n"); + goto exit; + } + memset(&ctrl_msg, 0x00, sizeof(struct udevd_ctrl_msg)); + strcpy(ctrl_msg.magic, UDEVD_CTRL_MAGIC); + arg = argv[1]; + + if (!strcmp(arg, "stop_exec_queue")) + ctrl_msg.type = UDEVD_CTRL_STOP_EXEC_QUEUE; + else if (!strcmp(arg, "start_exec_queue")) + ctrl_msg.type = UDEVD_CTRL_START_EXEC_QUEUE; + else if (!strcmp(arg, "reload_rules")) + ctrl_msg.type = UDEVD_CTRL_RELOAD_RULES; + else if (!strncmp(arg, "log_priority=", strlen("log_priority="))) { + intval = (int *) ctrl_msg.buf; + val = &arg[strlen("log_priority=")]; + ctrl_msg.type = UDEVD_CTRL_SET_LOG_LEVEL; + *intval = log_priority(val); + info("send log_priority=%i", *intval); + } else if (!strncmp(arg, "max_childs=", strlen("max_childs="))) { + char *endp; + int count; + + intval = (int *) ctrl_msg.buf; + val = &arg[strlen("max_childs=")]; + ctrl_msg.type = UDEVD_CTRL_SET_MAX_CHILDS; + count = strtoul(val, &endp, 0); + if (endp[0] != '\0' || count < 1) { + fprintf(stderr, "invalid number\n"); + goto exit; + } + *intval = count; + info("send max_childs=%i", *intval); + } else if (!strncmp(arg, "max_childs_running=", strlen("max_childs_running="))) { + char *endp; + int count; + + intval = (int *) ctrl_msg.buf; + val = &arg[strlen("max_childs_running=")]; + ctrl_msg.type = UDEVD_CTRL_SET_MAX_CHILDS_RUNNING; + count = strtoul(val, &endp, 0); + if (endp[0] != '\0' || count < 1) { + fprintf(stderr, "invalid number\n"); + goto exit; + } + *intval = count; + info("send max_childs_running=%i", *intval); + } else if (!strncmp(arg, "env", strlen("env"))) { + val = argv[2]; + if (val == NULL) { + fprintf(stderr, "missing key\n"); + goto exit; + } + ctrl_msg.type = UDEVD_CTRL_ENV; + strlcpy(ctrl_msg.buf, val, sizeof(ctrl_msg.buf)); + info("send env '%s'", val); + } else if (strcmp(arg, "help") == 0 || strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) { + printf("Usage: udevcontrol COMMAND\n" + " log_priority= set the udev log level for the daemon\n" + " stop_exec_queue keep udevd from executing events, queue only\n" + " start_exec_queue execute events, flush queue\n" + " reload_rules reloads the rules files\n" + " env = set a global environment variable\n" + " max_childs= maximum number of childs\n" + " max_childs_running= maximum number of childs running at the same time\n" + " help print this help text\n\n"); + goto exit; + } else { + fprintf(stderr, "unrecognized command '%s'\n", arg); + goto exit; + } + + if (getuid() != 0) { + fprintf(stderr, "root privileges required\n"); + goto exit; + } + + sock = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (sock == -1) { + err("error getting socket: %s", strerror(errno)); + goto exit; + } + + memset(&saddr, 0x00, sizeof(struct sockaddr_un)); + saddr.sun_family = AF_LOCAL; + /* use abstract namespace for socket path */ + strcpy(&saddr.sun_path[1], UDEVD_CTRL_SOCK_PATH); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + retval = sendto(sock, &ctrl_msg, sizeof(ctrl_msg), 0, (struct sockaddr *)&saddr, addrlen); + if (retval == -1) { + err("error sending message: %s", strerror(errno)); + retval = 1; + } else { + dbg("sent message type=0x%02x, %u bytes sent", ctrl_msg.type, retval); + retval = 0; + } + + close(sock); +exit: + logging_close(); + return retval; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevd.8 b/21cnbao/code/05/udev源代码/udev-114/udevd.8 new file mode 100644 index 0000000..25996d1 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevd.8 @@ -0,0 +1,105 @@ +.\" Title: udevd +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: August 2005 +.\" Manual: udevd, udevcontrol +.\" Source: udev +.\" +.TH "UDEVD" "8" "August 2005" "udev" "udevd, udevcontrol" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevd \- event managing daemon +.SH "SYNOPSIS" +.HP 6 +\fBudevd\fR [\fB\-\-daemon\fR] [\fB\-\-debug\-trace\fR] [\fB\-\-verbose\fR] [\fB\-\-version\fR] [\fB\-\-help\fR] +.HP 20 +\fBudevcontrol \fR\fB\fIcommand\fR\fR +.SH "DESCRIPTION" +.PP +udevd listens to kernel uevents and passes the incoming events to udev. It ensures the right event order and takes care, that events for child devices are delayed until the parent has finished the device handling. +.SH "OPTIONS" +.PP +\fB\-\-daemon\fR +.RS 4 +Detach and run in the background. +.RE +.PP +\fB\-\-debug\-trace\fR +.RS 4 +Run all events completely serialized. This may be useful if udev triggers actions or loads kernel modules which cause problems and a slow but continuous operation is needed, where no events are processed in parallel. +.RE +.PP +\fB\-\-verbose\fR +.RS 4 +Print log messages to stdout. +.RE +.PP +\fB\-\-version\fR +.RS 4 +Print version number. +.RE +.PP +\fB\-\-help\fR +.RS 4 +Print usage. +.RE +.PP +\fBlog_priority=\fR\fB\fIvalue\fR\fR +.RS 4 +Set the internal log level of udevd. Valid values are the numerical syslog priorities or their textual representations: +\fBerr\fR, +\fBinfo\fR +and +\fBdebug\fR. +.RE +.PP +\fBstop_exec_queue\fR +.RS 4 +Signal udevd to stop executing new events. Incoming events will be queued. +.RE +.PP +\fBstart_exec_queue\fR +.RS 4 +Signal udevd to enable the execution of events. +.RE +.PP +\fBreload_rules\fR +.RS 4 +Signal udevd to reload the rules from the config. +.RE +.PP +\fBenv \fR\fB\fIvar\fR\fR\fB=\fR\fB\fIvalue\fR\fR +.RS 4 +Set global variable. +.RE +.PP +\fBmax_childs\fR +.RS 4 +Set the maximum number of events, udevd will handle at the same time. +.RE +.PP +\fBmax_childs_running\fR +.RS 4 +Set the maximum number of events, which are allowed to run at the same time. +.RE +.PP +\fBhelp\fR +.RS 4 +Print help text. +.RE +.SH "ENVIRONMENT" +.PP +\fBUDEV_LOG\fR +.RS 4 +Overrides the syslog priority specified in the config file. +.RE +.SH "AUTHOR" +.PP +Written by Kay Sievers +. +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/udevd.c b/21cnbao/code/05/udev源代码/udev-114/udevd.c new file mode 100644 index 0000000..8f56de6 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevd.c @@ -0,0 +1,1256 @@ +/* + * Copyright (C) 2004-2006 Kay Sievers + * Copyright (C) 2004 Chris Friesen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" +#include "udevd.h" +#include "udev_selinux.h" + +static int debug_trace; +static int verbose; + +static struct udev_rules rules; +static int udevd_sock = -1; +static int uevent_netlink_sock = -1; +static int inotify_fd = -1; +static pid_t sid; + +static int signal_pipe[2] = {-1, -1}; +static volatile int sigchilds_waiting; +static volatile int udev_exit; +static volatile int reload_config; +static int run_exec_q; +static int stop_exec_q; +static int max_childs; +static int max_childs_running; +static char udev_log[32]; + +static LIST_HEAD(exec_list); +static LIST_HEAD(running_list); + + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log_priority) + return; + + if (verbose) { + printf("[%d] ", (int) getpid()); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + } else { + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); + } +} + +#endif + +static void asmlinkage udev_event_sig_handler(int signum) +{ + if (signum == SIGALRM) + exit(1); +} + +static int udev_event_process(struct udevd_uevent_msg *msg) +{ + struct sigaction act; + struct udevice *udev; + int i; + int retval; + + /* set signal handlers */ + memset(&act, 0x00, sizeof(act)); + act.sa_handler = (void (*)(int)) udev_event_sig_handler; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + + /* reset to default */ + act.sa_handler = SIG_DFL; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + sigaction(SIGCHLD, &act, NULL); + sigaction(SIGHUP, &act, NULL); + + /* trigger timeout to prevent hanging processes */ + alarm(UDEV_ALARM_TIMEOUT); + + /* reconstruct event environment from message */ + for (i = 0; msg->envp[i]; i++) + putenv(msg->envp[i]); + + udev = udev_device_init(NULL); + if (udev == NULL) + return -1; + strlcpy(udev->action, msg->action, sizeof(udev->action)); + sysfs_device_set_values(udev->dev, msg->devpath, msg->subsystem, msg->driver); + udev->devt = msg->devt; + + retval = udev_device_event(&rules, udev); + + /* run programs collected by RUN-key*/ + if (retval == 0 && !udev->ignore_device && udev_run) + retval = udev_rules_run(udev); + + udev_device_cleanup(udev); + return retval; +} + +enum event_state { + EVENT_QUEUED, + EVENT_FINISHED, + EVENT_FAILED, +}; + +static void export_event_state(struct udevd_uevent_msg *msg, enum event_state state) +{ + char filename[PATH_SIZE]; + char filename_failed[PATH_SIZE]; + size_t start; + struct udevd_uevent_msg *loop_msg; + int fd; + + /* add location of queue files */ + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + start = strlcat(filename, EVENT_QUEUE_DIR"/", sizeof(filename)); + strlcat(filename, msg->devpath, sizeof(filename)); + path_encode(&filename[start], sizeof(filename) - start); + + /* add location of failed files */ + strlcpy(filename_failed, udev_root, sizeof(filename_failed)); + strlcat(filename_failed, "/", sizeof(filename_failed)); + start = strlcat(filename_failed, EVENT_FAILED_DIR"/", sizeof(filename_failed)); + strlcat(filename_failed, msg->devpath, sizeof(filename_failed)); + path_encode(&filename_failed[start], sizeof(filename) - start); + + switch (state) { + case EVENT_QUEUED: + unlink(filename_failed); + delete_path(filename_failed); + create_path(filename); + fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644); + if (fd > 0) + close(fd); + return; + case EVENT_FINISHED: + case EVENT_FAILED: + unlink(filename_failed); + delete_path(filename_failed); + + /* don't remove, if events for the same path are still pending */ + list_for_each_entry(loop_msg, &running_list, node) + if (loop_msg->devpath && strcmp(loop_msg->devpath, msg->devpath) == 0) + return; + + list_for_each_entry(loop_msg, &exec_list, node) + if (loop_msg->devpath && strcmp(loop_msg->devpath, msg->devpath) == 0) + return; + + /* move failed events to the failed directory */ + if (state == EVENT_FAILED) { + create_path(filename_failed); + rename(filename, filename_failed); + } else { + unlink(filename); + } + + /* clean up the queue directory */ + delete_path(filename); + + return; + } +} + +static void msg_queue_delete(struct udevd_uevent_msg *msg) +{ + list_del(&msg->node); + + /* mark as failed, if add event returns non-zero */ + if (msg->exitstatus && strcmp(msg->action, "add") == 0) + export_event_state(msg, EVENT_FAILED); + else + export_event_state(msg, EVENT_FINISHED); + + free(msg); +} + +static void udev_event_run(struct udevd_uevent_msg *msg) +{ + pid_t pid; + int retval; + + pid = fork(); + switch (pid) { + case 0: + /* child */ + close(uevent_netlink_sock); + close(udevd_sock); + if (inotify_fd >= 0) + close(inotify_fd); + close(signal_pipe[READ_END]); + close(signal_pipe[WRITE_END]); + logging_close(); + + logging_init("udevd-event"); + setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); + + retval = udev_event_process(msg); + info("seq %llu finished with %i", msg->seqnum, retval); + + logging_close(); + if (retval) + exit(1); + exit(0); + case -1: + err("fork of child failed: %s", strerror(errno)); + msg_queue_delete(msg); + break; + default: + /* get SIGCHLD in main loop */ + info("seq %llu forked, pid [%d], '%s' '%s', %ld seconds old", + msg->seqnum, pid, msg->action, msg->subsystem, time(NULL) - msg->queue_time); + msg->pid = pid; + } +} + +static void msg_queue_insert(struct udevd_uevent_msg *msg) +{ + char filename[PATH_SIZE]; + int fd; + + msg->queue_time = time(NULL); + + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/" EVENT_SEQNUM, sizeof(filename)); + fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644); + if (fd >= 0) { + char str[32]; + int len; + + len = sprintf(str, "%llu\n", msg->seqnum); + write(fd, str, len); + close(fd); + } + + export_event_state(msg, EVENT_QUEUED); + + /* run one event after the other in debug mode */ + if (debug_trace) { + list_add_tail(&msg->node, &running_list); + udev_event_run(msg); + waitpid(msg->pid, NULL, 0); + msg_queue_delete(msg); + return; + } + + /* run all events with a timeout set immediately */ + if (msg->timeout != 0) { + list_add_tail(&msg->node, &running_list); + udev_event_run(msg); + return; + } + + list_add_tail(&msg->node, &exec_list); + run_exec_q = 1; +} + +static int mem_size_mb(void) +{ + FILE* f; + char buf[4096]; + long int memsize = -1; + + f = fopen("/proc/meminfo", "r"); + if (f == NULL) + return -1; + + while (fgets(buf, sizeof(buf), f) != NULL) { + long int value; + + if (sscanf(buf, "MemTotal: %ld kB", &value) == 1) { + memsize = value / 1024; + break; + } + } + + fclose(f); + return memsize; +} + +static int cpu_count(void) +{ + FILE* f; + char buf[4096]; + int count = 0; + + f = fopen("/proc/stat", "r"); + if (f == NULL) + return -1; + + while (fgets(buf, sizeof(buf), f) != NULL) { + if (strncmp(buf, "cpu", 3) == 0 && isdigit(buf[3])) + count++; + } + + fclose(f); + if (count == 0) + return -1; + return count; +} + +static int running_processes(void) +{ + FILE* f; + char buf[4096]; + int running = -1; + + f = fopen("/proc/stat", "r"); + if (f == NULL) + return -1; + + while (fgets(buf, sizeof(buf), f) != NULL) { + int value; + + if (sscanf(buf, "procs_running %u", &value) == 1) { + running = value; + break; + } + } + + fclose(f); + return running; +} + +/* return the number of process es in our session, count only until limit */ +static int running_processes_in_session(pid_t session, int limit) +{ + DIR *dir; + struct dirent *dent; + int running = 0; + + dir = opendir("/proc"); + if (!dir) + return -1; + + /* read process info from /proc */ + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + int f; + char procdir[64]; + char line[256]; + const char *pos; + char state; + pid_t ppid, pgrp, sess; + int len; + + if (!isdigit(dent->d_name[0])) + continue; + + snprintf(procdir, sizeof(procdir), "/proc/%s/stat", dent->d_name); + procdir[sizeof(procdir)-1] = '\0'; + + f = open(procdir, O_RDONLY); + if (f == -1) + continue; + + len = read(f, line, sizeof(line)-1); + close(f); + + if (len <= 0) + continue; + else + line[len] = '\0'; + + /* skip ugly program name */ + pos = strrchr(line, ')') + 2; + if (pos == NULL) + continue; + + if (sscanf(pos, "%c %d %d %d ", &state, &ppid, &pgrp, &sess) != 4) + continue; + + /* count only processes in our session */ + if (sess != session) + continue; + + /* count only running, no sleeping processes */ + if (state != 'R') + continue; + + running++; + if (limit > 0 && running >= limit) + break; + } + closedir(dir); + + return running; +} + +static int compare_devpath(const char *running, const char *waiting) +{ + int i; + + for (i = 0; i < PATH_SIZE; i++) { + /* identical device event found */ + if (running[i] == '\0' && waiting[i] == '\0') + return 1; + + /* parent device event found */ + if (running[i] == '\0' && waiting[i] == '/') + return 2; + + /* child device event found */ + if (running[i] == '/' && waiting[i] == '\0') + return 3; + + /* no matching event */ + if (running[i] != waiting[i]) + break; + } + + return 0; +} + +/* lookup event for identical, parent, child, or physical device */ +static int devpath_busy(struct udevd_uevent_msg *msg, int limit) +{ + struct udevd_uevent_msg *loop_msg; + int childs_count = 0; + + /* check exec-queue which may still contain delayed events we depend on */ + list_for_each_entry(loop_msg, &exec_list, node) { + /* skip ourself and all later events */ + if (loop_msg->seqnum >= msg->seqnum) + break; + + /* check identical, parent, or child device event */ + if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) { + dbg("%llu, device event still pending %llu (%s)", + msg->seqnum, loop_msg->seqnum, loop_msg->devpath); + return 2; + } + + /* check physical device event (special case of parent) */ + if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0) + if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0) { + dbg("%llu, physical device event still pending %llu (%s)", + msg->seqnum, loop_msg->seqnum, loop_msg->devpath); + return 3; + } + } + + /* check runing-queue for still running events */ + list_for_each_entry(loop_msg, &running_list, node) { + if (limit && childs_count++ > limit) { + dbg("%llu, maximum number (%i) of childs reached", msg->seqnum, childs_count); + return 1; + } + + /* check identical, parent, or child device event */ + if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) { + dbg("%llu, device event still running %llu (%s)", + msg->seqnum, loop_msg->seqnum, loop_msg->devpath); + return 2; + } + + /* check physical device event (special case of parent) */ + if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0) + if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0) { + dbg("%llu, physical device event still running %llu (%s)", + msg->seqnum, loop_msg->seqnum, loop_msg->devpath); + return 3; + } + } + return 0; +} + +/* serializes events for the identical and parent and child devices */ +static void msg_queue_manager(void) +{ + struct udevd_uevent_msg *loop_msg; + struct udevd_uevent_msg *tmp_msg; + int running; + + if (list_empty(&exec_list)) + return; + + running = running_processes(); + dbg("%d processes runnning on system", running); + if (running < 0) + running = max_childs_running; + + list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, node) { + /* check running processes in our session and possibly throttle */ + if (running >= max_childs_running) { + running = running_processes_in_session(sid, max_childs_running+10); + dbg("at least %d processes running in session", running); + if (running >= max_childs_running) { + dbg("delay seq %llu, too many processes already running", loop_msg->seqnum); + return; + } + } + + /* serialize and wait for parent or child events */ + if (devpath_busy(loop_msg, max_childs) != 0) { + dbg("delay seq %llu (%s)", loop_msg->seqnum, loop_msg->devpath); + continue; + } + + /* move event to run list */ + list_move_tail(&loop_msg->node, &running_list); + udev_event_run(loop_msg); + running++; + dbg("moved seq %llu to running list", loop_msg->seqnum); + } +} + +static struct udevd_uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) +{ + int bufpos; + int i; + struct udevd_uevent_msg *msg; + char *physdevdriver_key = NULL; + int maj = 0; + int min = 0; + + msg = malloc(sizeof(struct udevd_uevent_msg) + buf_size); + if (msg == NULL) + return NULL; + memset(msg, 0x00, sizeof(struct udevd_uevent_msg) + buf_size); + + /* copy environment buffer and reconstruct envp */ + memcpy(msg->envbuf, buf, buf_size); + bufpos = 0; + for (i = 0; (bufpos < buf_size) && (i < UEVENT_NUM_ENVP-2); i++) { + int keylen; + char *key; + + key = &msg->envbuf[bufpos]; + keylen = strlen(key); + msg->envp[i] = key; + bufpos += keylen + 1; + dbg("add '%s' to msg.envp[%i]", msg->envp[i], i); + + /* remember some keys for further processing */ + if (strncmp(key, "ACTION=", 7) == 0) + msg->action = &key[7]; + else if (strncmp(key, "DEVPATH=", 8) == 0) + msg->devpath = &key[8]; + else if (strncmp(key, "SUBSYSTEM=", 10) == 0) + msg->subsystem = &key[10]; + else if (strncmp(key, "DRIVER=", 7) == 0) + msg->driver = &key[7]; + else if (strncmp(key, "SEQNUM=", 7) == 0) + msg->seqnum = strtoull(&key[7], NULL, 10); + else if (strncmp(key, "PHYSDEVPATH=", 12) == 0) + msg->physdevpath = &key[12]; + else if (strncmp(key, "PHYSDEVDRIVER=", 14) == 0) + physdevdriver_key = key; + else if (strncmp(key, "MAJOR=", 6) == 0) + maj = strtoull(&key[6], NULL, 10); + else if (strncmp(key, "MINOR=", 6) == 0) + min = strtoull(&key[6], NULL, 10); + else if (strncmp(key, "TIMEOUT=", 8) == 0) + msg->timeout = strtoull(&key[8], NULL, 10); + } + msg->devt = makedev(maj, min); + msg->envp[i++] = "UDEVD_EVENT=1"; + + if (msg->driver == NULL && msg->physdevpath == NULL && physdevdriver_key != NULL) { + /* for older kernels DRIVER is empty for a bus device, export PHYSDEVDRIVER as DRIVER */ + msg->envp[i++] = &physdevdriver_key[7]; + msg->driver = &physdevdriver_key[14]; + } + + msg->envp[i] = NULL; + + if (msg->devpath == NULL || msg->action == NULL) { + info("DEVPATH or ACTION missing, ignore message"); + free(msg); + return NULL; + } + return msg; +} + +/* receive the udevd message from userspace */ +static void get_ctrl_msg(void) +{ + struct udevd_ctrl_msg ctrl_msg; + ssize_t size; + struct msghdr smsg; + struct cmsghdr *cmsg; + struct iovec iov; + struct ucred *cred; + char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; + int *intval; + char *pos; + + memset(&ctrl_msg, 0x00, sizeof(struct udevd_ctrl_msg)); + iov.iov_base = &ctrl_msg; + iov.iov_len = sizeof(struct udevd_ctrl_msg); + + memset(&smsg, 0x00, sizeof(struct msghdr)); + smsg.msg_iov = &iov; + smsg.msg_iovlen = 1; + smsg.msg_control = cred_msg; + smsg.msg_controllen = sizeof(cred_msg); + + size = recvmsg(udevd_sock, &smsg, 0); + if (size < 0) { + if (errno != EINTR) + err("unable to receive user udevd message: %s", strerror(errno)); + return; + } + cmsg = CMSG_FIRSTHDR(&smsg); + cred = (struct ucred *) CMSG_DATA(cmsg); + + if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { + err("no sender credentials received, message ignored"); + return; + } + + if (cred->uid != 0) { + err("sender uid=%i, message ignored", cred->uid); + return; + } + + if (strncmp(ctrl_msg.magic, UDEVD_CTRL_MAGIC, sizeof(UDEVD_CTRL_MAGIC)) != 0 ) { + err("message magic '%s' doesn't match, ignore it", ctrl_msg.magic); + return; + } + + switch (ctrl_msg.type) { + case UDEVD_CTRL_ENV: + pos = strchr(ctrl_msg.buf, '='); + if (pos == NULL) { + err("wrong key format '%s'", ctrl_msg.buf); + break; + } + pos[0] = '\0'; + if (pos[1] == '\0') { + info("udevd message (ENV) received, unset '%s'", ctrl_msg.buf); + unsetenv(ctrl_msg.buf); + } else { + info("udevd message (ENV) received, set '%s=%s'", ctrl_msg.buf, &pos[1]); + setenv(ctrl_msg.buf, &pos[1], 1); + } + break; + case UDEVD_CTRL_STOP_EXEC_QUEUE: + info("udevd message (STOP_EXEC_QUEUE) received"); + stop_exec_q = 1; + break; + case UDEVD_CTRL_START_EXEC_QUEUE: + info("udevd message (START_EXEC_QUEUE) received"); + stop_exec_q = 0; + msg_queue_manager(); + break; + case UDEVD_CTRL_SET_LOG_LEVEL: + intval = (int *) ctrl_msg.buf; + info("udevd message (SET_LOG_PRIORITY) received, udev_log_priority=%i", *intval); + udev_log_priority = *intval; + sprintf(udev_log, "UDEV_LOG=%i", udev_log_priority); + putenv(udev_log); + break; + case UDEVD_CTRL_SET_MAX_CHILDS: + intval = (int *) ctrl_msg.buf; + info("udevd message (UDEVD_SET_MAX_CHILDS) received, max_childs=%i", *intval); + max_childs = *intval; + break; + case UDEVD_CTRL_SET_MAX_CHILDS_RUNNING: + intval = (int *) ctrl_msg.buf; + info("udevd message (UDEVD_SET_MAX_CHILDS_RUNNING) received, max_childs=%i", *intval); + max_childs_running = *intval; + break; + case UDEVD_CTRL_RELOAD_RULES: + info("udevd message (RELOAD_RULES) received"); + reload_config = 1; + break; + default: + err("unknown control message type"); + } +} + +/* receive the kernel user event message and do some sanity checks */ +static struct udevd_uevent_msg *get_netlink_msg(void) +{ + struct udevd_uevent_msg *msg; + int bufpos; + ssize_t size; + static char buffer[UEVENT_BUFFER_SIZE+512]; + char *pos; + + size = recv(uevent_netlink_sock, &buffer, sizeof(buffer), 0); + if (size < 0) { + if (errno != EINTR) + err("unable to receive kernel netlink message: %s", strerror(errno)); + return NULL; + } + + if ((size_t)size > sizeof(buffer)-1) + size = sizeof(buffer)-1; + buffer[size] = '\0'; + dbg("uevent_size=%zi", size); + + /* start of event payload */ + bufpos = strlen(buffer)+1; + msg = get_msg_from_envbuf(&buffer[bufpos], size-bufpos); + if (msg == NULL) + return NULL; + + /* validate message */ + pos = strchr(buffer, '@'); + if (pos == NULL) { + err("invalid uevent '%s'", buffer); + free(msg); + return NULL; + } + pos[0] = '\0'; + + if (msg->action == NULL) { + info("no ACTION in payload found, skip event '%s'", buffer); + free(msg); + return NULL; + } + + if (strcmp(msg->action, buffer) != 0) { + err("ACTION in payload does not match uevent, skip event '%s'", buffer); + free(msg); + return NULL; + } + + return msg; +} + +static void asmlinkage sig_handler(int signum) +{ + switch (signum) { + case SIGINT: + case SIGTERM: + udev_exit = 1; + break; + case SIGCHLD: + /* set flag, then write to pipe if needed */ + sigchilds_waiting = 1; + break; + case SIGHUP: + reload_config = 1; + break; + } + + /* write to pipe, which will wakeup select() in our mainloop */ + write(signal_pipe[WRITE_END], "", 1); +} + +static void udev_done(int pid, int exitstatus) +{ + /* find msg associated with pid and delete it */ + struct udevd_uevent_msg *msg; + + list_for_each_entry(msg, &running_list, node) { + if (msg->pid == pid) { + info("seq %llu, pid [%d] exit with %i, %ld seconds old", msg->seqnum, msg->pid, + exitstatus, time(NULL) - msg->queue_time); + msg->exitstatus = exitstatus; + msg_queue_delete(msg); + + /* there may be events waiting with the same devpath */ + run_exec_q = 1; + return; + } + } +} + +static void reap_sigchilds(void) +{ + pid_t pid; + int status; + + while (1) { + pid = waitpid(-1, &status, WNOHANG); + if (pid <= 0) + break; + if (WIFEXITED(status)) + status = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + status = WTERMSIG(status) + 128; + else + status = 0; + udev_done(pid, status); + } +} + +static int init_udevd_socket(void) +{ + struct sockaddr_un saddr; + socklen_t addrlen; + const int feature_on = 1; + int retval; + + memset(&saddr, 0x00, sizeof(saddr)); + saddr.sun_family = AF_LOCAL; + /* use abstract namespace for socket path */ + strcpy(&saddr.sun_path[1], UDEVD_CTRL_SOCK_PATH); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + udevd_sock = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (udevd_sock == -1) { + err("error getting socket: %s", strerror(errno)); + return -1; + } + + /* the bind takes care of ensuring only one copy running */ + retval = bind(udevd_sock, (struct sockaddr *) &saddr, addrlen); + if (retval < 0) { + err("bind failed: %s", strerror(errno)); + close(udevd_sock); + udevd_sock = -1; + return -1; + } + + /* enable receiving of the sender credentials */ + setsockopt(udevd_sock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); + + return 0; +} + +static int init_uevent_netlink_sock(void) +{ + struct sockaddr_nl snl; + const int buffersize = 16 * 1024 * 1024; + int retval; + + memset(&snl, 0x00, sizeof(struct sockaddr_nl)); + snl.nl_family = AF_NETLINK; + snl.nl_pid = getpid(); + snl.nl_groups = 1; + + uevent_netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); + if (uevent_netlink_sock == -1) { + err("error getting socket: %s", strerror(errno)); + return -1; + } + + /* set receive buffersize */ + setsockopt(uevent_netlink_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize)); + + retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl)); + if (retval < 0) { + err("bind failed: %s", strerror(errno)); + close(uevent_netlink_sock); + uevent_netlink_sock = -1; + return -1; + } + return 0; +} + +static void export_initial_seqnum(void) +{ + char filename[PATH_SIZE]; + int fd; + char seqnum[32]; + ssize_t len = 0; + + strlcpy(filename, sysfs_path, sizeof(filename)); + strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename)); + fd = open(filename, O_RDONLY); + if (fd >= 0) { + len = read(fd, seqnum, sizeof(seqnum)-1); + close(fd); + } + if (len <= 0) { + strcpy(seqnum, "0\n"); + len = 3; + } + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/" EVENT_SEQNUM, sizeof(filename)); + create_path(filename); + fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644); + if (fd >= 0) { + write(fd, seqnum, len); + close(fd); + } +} + +int main(int argc, char *argv[], char *envp[]) +{ + int retval; + int fd; + struct sigaction act; + fd_set readfds; + const char *value; + int daemonize = 0; + int option; + static const struct option options[] = { + { "daemon", 0, NULL, 'd' }, + { "debug-trace", 0, NULL, 't' }, + { "verbose", 0, NULL, 'v' }, + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + {} + }; + int rc = 1; + int maxfd; + + logging_init("udevd"); + udev_config_init(); + selinux_init(); + dbg("version %s", UDEV_VERSION); + + while (1) { + option = getopt_long(argc, argv, "dtvhV", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'd': + daemonize = 1; + break; + case 't': + debug_trace = 1; + break; + case 'v': + verbose = 1; + if (udev_log_priority < LOG_INFO) + udev_log_priority = LOG_INFO; + break; + case 'h': + printf("Usage: udevd [--help] [--daemon] [--debug-trace] [--verbose] [--version]\n"); + goto exit; + case 'V': + printf("%s\n", UDEV_VERSION); + goto exit; + default: + goto exit; + } + } + + if (getuid() != 0) { + fprintf(stderr, "root privileges required\n"); + err("root privileges required"); + goto exit; + } + + /* make sure std{in,out,err} fd's are in a sane state */ + fd = open("/dev/null", O_RDWR); + if (fd < 0) { + fprintf(stderr, "cannot open /dev/null\n"); + err("cannot open /dev/null"); + } + if (fd > STDIN_FILENO) + dup2(fd, STDIN_FILENO); + if (write(STDOUT_FILENO, 0, 0) < 0) + dup2(fd, STDOUT_FILENO); + if (write(STDERR_FILENO, 0, 0) < 0) + dup2(fd, STDERR_FILENO); + + /* init sockets to receive events */ + if (init_udevd_socket() < 0) { + if (errno == EADDRINUSE) { + fprintf(stderr, "another udev daemon already running\n"); + err("another udev daemon already running"); + rc = 1; + } else { + fprintf(stderr, "error initializing udevd socket\n"); + err("error initializing udevd socket"); + rc = 2; + } + goto exit; + } + + if (init_uevent_netlink_sock() < 0) { + fprintf(stderr, "error initializing netlink socket\n"); + err("error initializing netlink socket"); + rc = 3; + goto exit; + } + + /* setup signal handler pipe */ + retval = pipe(signal_pipe); + if (retval < 0) { + err("error getting pipes: %s", strerror(errno)); + goto exit; + } + + retval = fcntl(signal_pipe[READ_END], F_GETFL, 0); + if (retval < 0) { + err("error fcntl on read pipe: %s", strerror(errno)); + goto exit; + } + retval = fcntl(signal_pipe[READ_END], F_SETFL, retval | O_NONBLOCK); + if (retval < 0) { + err("error fcntl on read pipe: %s", strerror(errno)); + goto exit; + } + + retval = fcntl(signal_pipe[WRITE_END], F_GETFL, 0); + if (retval < 0) { + err("error fcntl on write pipe: %s", strerror(errno)); + goto exit; + } + retval = fcntl(signal_pipe[WRITE_END], F_SETFL, retval | O_NONBLOCK); + if (retval < 0) { + err("error fcntl on write pipe: %s", strerror(errno)); + goto exit; + } + + /* parse the rules and keep them in memory */ + sysfs_init(); + udev_rules_init(&rules, 1); + + export_initial_seqnum(); + + if (daemonize) { + pid_t pid; + + pid = fork(); + switch (pid) { + case 0: + dbg("daemonized fork running"); + break; + case -1: + err("fork of daemon failed: %s", strerror(errno)); + rc = 4; + goto exit; + default: + dbg("child [%u] running, parent exits", pid); + rc = 0; + goto exit; + } + } + + /* redirect std{out,err} fd's */ + if (!verbose) + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + close(fd); + + /* set scheduling priority for the daemon */ + setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); + + chdir("/"); + umask(022); + + /* become session leader */ + sid = setsid(); + dbg("our session is %d", sid); + + /* OOM_DISABLE == -17 */ + fd = open("/proc/self/oom_adj", O_RDWR); + if (fd < 0) + err("error disabling OOM: %s", strerror(errno)); + else { + write(fd, "-17", 3); + close(fd); + } + + /* set signal handlers */ + memset(&act, 0x00, sizeof(struct sigaction)); + act.sa_handler = (void (*)(int)) sig_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + sigaction(SIGCHLD, &act, NULL); + sigaction(SIGHUP, &act, NULL); + + /* watch rules directory */ + inotify_fd = inotify_init(); + if (inotify_fd >= 0) { + char filename[PATH_MAX]; + + inotify_add_watch(inotify_fd, udev_rules_dir, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); + + /* watch dynamic rules directory */ + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/"RULES_DYN_DIR, sizeof(filename)); + inotify_add_watch(inotify_fd, filename, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); + } else if (errno == ENOSYS) + err("the kernel does not support inotify, udevd can't monitor rules file changes"); + else + err("inotify_init failed: %s", strerror(errno)); + + /* maximum limit of forked childs */ + value = getenv("UDEVD_MAX_CHILDS"); + if (value) + max_childs = strtoul(value, NULL, 10); + else { + int memsize = mem_size_mb(); + if (memsize > 0) + max_childs = 128 + (memsize / 4); + else + max_childs = UDEVD_MAX_CHILDS; + } + info("initialize max_childs to %u", max_childs); + + /* start to throttle forking if maximum number of _running_ childs is reached */ + value = getenv("UDEVD_MAX_CHILDS_RUNNING"); + if (value) + max_childs_running = strtoull(value, NULL, 10); + else { + int cpus = cpu_count(); + if (cpus > 0) + max_childs_running = 8 + (8 * cpus); + else + max_childs_running = UDEVD_MAX_CHILDS_RUNNING; + } + info("initialize max_childs_running to %u", max_childs_running); + + /* clear environment for forked event processes */ + clearenv(); + + /* export log_priority , as called programs may want to follow that setting */ + sprintf(udev_log, "UDEV_LOG=%i", udev_log_priority); + putenv(udev_log); + if (debug_trace) + putenv("DEBUG=1"); + + maxfd = udevd_sock; + maxfd = UDEV_MAX(maxfd, uevent_netlink_sock); + maxfd = UDEV_MAX(maxfd, signal_pipe[READ_END]); + maxfd = UDEV_MAX(maxfd, inotify_fd); + + while (!udev_exit) { + struct udevd_uevent_msg *msg; + int fdcount; + + FD_ZERO(&readfds); + FD_SET(signal_pipe[READ_END], &readfds); + FD_SET(udevd_sock, &readfds); + FD_SET(uevent_netlink_sock, &readfds); + if (inotify_fd >= 0) + FD_SET(inotify_fd, &readfds); + + fdcount = select(maxfd+1, &readfds, NULL, NULL, NULL); + if (fdcount < 0) { + if (errno != EINTR) + err("error in select: %s", strerror(errno)); + continue; + } + + /* get control message */ + if (FD_ISSET(udevd_sock, &readfds)) + get_ctrl_msg(); + + /* get netlink message */ + if (FD_ISSET(uevent_netlink_sock, &readfds)) { + msg = get_netlink_msg(); + if (msg) + msg_queue_insert(msg); + } + + /* received a signal, clear our notification pipe */ + if (FD_ISSET(signal_pipe[READ_END], &readfds)) { + char buf[256]; + + read(signal_pipe[READ_END], &buf, sizeof(buf)); + } + + /* rules directory inotify watch */ + if ((inotify_fd >= 0) && FD_ISSET(inotify_fd, &readfds)) { + int nbytes; + + /* discard all possible events, we can just reload the config */ + if ((ioctl(inotify_fd, FIONREAD, &nbytes) == 0) && nbytes > 0) { + char *buf; + + reload_config = 1; + buf = malloc(nbytes); + if (buf == NULL) { + err("error getting buffer for inotify, disable watching"); + close(inotify_fd); + inotify_fd = -1; + } + read(inotify_fd, buf, nbytes); + free(buf); + } + } + + /* rules changed, set by inotify or a HUP signal */ + if (reload_config) { + reload_config = 0; + udev_rules_cleanup(&rules); + udev_rules_init(&rules, 1); + } + + /* forked child has returned */ + if (sigchilds_waiting) { + sigchilds_waiting = 0; + reap_sigchilds(); + } + + if (run_exec_q) { + run_exec_q = 0; + if (!stop_exec_q) + msg_queue_manager(); + } + } + rc = 0; + +exit: + udev_rules_cleanup(&rules); + sysfs_cleanup(); + selinux_exit(); + + if (signal_pipe[READ_END] >= 0) + close(signal_pipe[READ_END]); + if (signal_pipe[WRITE_END] >= 0) + close(signal_pipe[WRITE_END]); + + if (udevd_sock >= 0) + close(udevd_sock); + if (inotify_fd >= 0) + close(inotify_fd); + if (uevent_netlink_sock >= 0) + close(uevent_netlink_sock); + + logging_close(); + + return rc; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevd.h b/21cnbao/code/05/udev源代码/udev-114/udevd.h new file mode 100644 index 0000000..4ca6d1d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevd.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2004 Ling, Xiaofeng + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "list.h" + +#define UDEVD_PRIORITY -4 +#define UDEV_PRIORITY -2 + +#define EVENT_QUEUE_DIR ".udev/queue" +#define EVENT_FAILED_DIR ".udev/failed" +#define EVENT_SEQNUM ".udev/uevent_seqnum" + +/* maximum limit of forked childs */ +#define UDEVD_MAX_CHILDS 256 +/* start to throttle forking if maximum number of running childs in our session is reached */ +#define UDEVD_MAX_CHILDS_RUNNING 16 + +/* linux/include/linux/kobject.h */ +#define UEVENT_BUFFER_SIZE 2048 +#define UEVENT_NUM_ENVP 32 + +#define UDEVD_CTRL_SOCK_PATH "/org/kernel/udev/udevd" +#define UDEVD_CTRL_MAGIC "udevd_" UDEV_VERSION + +enum udevd_ctrl_msg_type { + UDEVD_CTRL_UNKNOWN, + UDEVD_CTRL_STOP_EXEC_QUEUE, + UDEVD_CTRL_START_EXEC_QUEUE, + UDEVD_CTRL_SET_LOG_LEVEL, + UDEVD_CTRL_SET_MAX_CHILDS, + UDEVD_CTRL_SET_MAX_CHILDS_RUNNING, + UDEVD_CTRL_RELOAD_RULES, + UDEVD_CTRL_ENV, +}; + +struct udevd_ctrl_msg { + char magic[32]; + enum udevd_ctrl_msg_type type; + char buf[256]; +}; + +struct udevd_uevent_msg { + struct list_head node; + pid_t pid; + int exitstatus; + time_t queue_time; + char *action; + char *devpath; + char *subsystem; + char *driver; + dev_t devt; + unsigned long long seqnum; + char *physdevpath; + unsigned int timeout; + char *envp[UEVENT_NUM_ENVP+1]; + char envbuf[]; +}; diff --git a/21cnbao/code/05/udev源代码/udev-114/udevd.xml b/21cnbao/code/05/udev源代码/udev-114/udevd.xml new file mode 100644 index 0000000..cf033a0 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevd.xml @@ -0,0 +1,159 @@ + + + +
    +
    + udevd, udevcontrol + + + udevd + August 2005 + udev + + + + udevd + 8 + + + + + udevdevent managing daemon + + + + + udevd + + + + + + + + udevcontrol command + + + + DESCRIPTION + udevd listens to kernel uevents and passes the incoming events to + udev. It ensures the right event order and takes care, that events for child + devices are delayed until the parent has finished the device handling. + + + OPTIONS + + + + + Detach and run in the background. + + + + + + Run all events completely serialized. This may be useful if udev triggers + actions or loads kernel modules which cause problems and a slow but continuous + operation is needed, where no events are processed in parallel. + + + + + + + Print log messages to stdout. + + + + + + Print version number. + + + + + + Print usage. + + + + + + Set the internal log level of udevd. Valid values are the numerical + syslog priorities or their textual representations: , + and . + + + + + + Signal udevd to stop executing new events. Incoming events + will be queued. + + + + + + Signal udevd to enable the execution of events. + + + + + + Signal udevd to reload the rules from the config. + + + + + + Set global variable. + + + + + + Set the maximum number of events, udevd will handle at the + same time. + + + + + + Set the maximum number of events, which are allowed to run at the + same time. + + + + + + Print help text. + + + + + + ENVIRONMENT + + + + + Overrides the syslog priority specified in the config file. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/udevinfo.8 b/21cnbao/code/05/udev源代码/udev-114/udevinfo.8 new file mode 100644 index 0000000..337f206 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevinfo.8 @@ -0,0 +1,82 @@ +.\" Title: udevinfo +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: August 2005 +.\" Manual: udevinfo +.\" Source: udev +.\" +.TH "UDEVINFO" "8" "August 2005" "udev" "udevinfo" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevinfo \- query udev device information +.SH "SYNOPSIS" +.HP 9 +\fBudevinfo\fR [\fB\-\-query=\fR\fB\fIquery\-type\fR\fR] [\fB\-\-path=\fR\fB\fIdevpath\fR\fR] [\fB\-\-name=\fR\fB\fInode\fR\fR] [\fB\-\-root\fR] [\fB\-\-attribute\-walk\fR] [\fB\-\-export\-db\fR] [\fB\-\-version\fR] [\fB\-\-help\fR] +.SH "DESCRIPTION" +.PP +udevinfo queries the udev database for device information stored in the udev database. It can also query the properties of a device from its sysfs representation to help creating udev rules that match this device. +.SH "OPTIONS" +.PP +\fB\-\-query=\fR\fB\fItype\fR\fR +.RS 4 +Query the database for specified type of device data. It needs the +\fB\-\-path\fR +or +\fB\-\-name\fR +to identify the specified device. Valid queries are: +\fBname\fR, +\fBsymlink\fR, +\fBpath\fR, +\fBenv\fR, +\fBall\fR. +.RE +.PP +\fB\-\-path=\fR\fB\fIdevpath\fR\fR +.RS 4 +The devpath of the device to query. +.RE +.PP +\fB\-\-name=\fR\fB\fInode\fR\fR +.RS 4 +The name of the device node or a symlink to query +.RE +.PP +\fB\-\-root\fR +.RS 4 +The udev root directory: +\fI/dev\fR. If used in conjunction with a +\fBname\fR +or +\fBsymlink\fR +query, the query returns the absolute path including the root directory. +.RE +.PP +\fB\-\-attribute\-walk\fR +.RS 4 +Print all sysfs properties of the specified device that can be used in udev rules to match the specified device. It prints all devices along the chain, up to the root of sysfs that can be used in udev rules. +.RE +.PP +\fB\-\-export\-db\fR +.RS 4 +Export the content of the udev database. +.RE +.PP +\fB\-\-version\fR +.RS 4 +Print version. +.RE +.PP +\fB\-\-help\fR +.RS 4 +Print help text. +.RE +.SH "AUTHOR" +.PP +Written by Kay Sievers +. +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/udevinfo.c b/21cnbao/code/05/udev源代码/udev-114/udevinfo.c new file mode 100644 index 0000000..d0b1c44 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevinfo.c @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + + +#ifdef USE_LOG +void log_message (int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log_priority) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +static void print_all_attributes(const char *devpath, const char *key) +{ + char path[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + strlcpy(path, sysfs_path, sizeof(path)); + strlcat(path, devpath, sizeof(path)); + + dir = opendir(path); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + struct stat statbuf; + char filename[PATH_SIZE]; + char *attr_value; + char value[NAME_SIZE]; + size_t len; + + if (dent->d_name[0] == '.') + continue; + + strlcpy(filename, path, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, dent->d_name, sizeof(filename)); + if (lstat(filename, &statbuf) != 0) + continue; + if (S_ISLNK(statbuf.st_mode)) + continue; + + attr_value = sysfs_attr_get_value(devpath, dent->d_name); + if (attr_value == NULL) + continue; + len = strlcpy(value, attr_value, sizeof(value)); + dbg("attr '%s'='%s'(%zi)", dent->d_name, value, len); + + /* remove trailing newlines */ + while (len && value[len-1] == '\n') + value[--len] = '\0'; + + /* skip nonprintable attributes */ + while (len && isprint(value[len-1])) + len--; + if (len) { + dbg("attribute value of '%s' non-printable, skip", dent->d_name); + continue; + } + + replace_chars(value, ALLOWED_CHARS_INPUT); + printf(" %s{%s}==\"%s\"\n", key, dent->d_name, value); + } + } + printf("\n"); +} + +static int print_device_chain(const char *devpath) +{ + struct sysfs_device *dev; + + dev = sysfs_device_get(devpath); + if (dev == NULL) + return -1; + + printf("\n" + "Udevinfo starts with the device specified by the devpath and then\n" + "walks up the chain of parent devices. It prints for every device\n" + "found, all possible attributes in the udev rules key format.\n" + "A rule to match, can be composed by the attributes of the device\n" + "and the attributes from one single parent device.\n" + "\n"); + + printf(" looking at device '%s':\n", dev->devpath); + printf(" KERNEL==\"%s\"\n", dev->kernel); + printf(" SUBSYSTEM==\"%s\"\n", dev->subsystem); + printf(" DRIVER==\"%s\"\n", dev->driver); + print_all_attributes(dev->devpath, "ATTR"); + + /* walk up the chain of devices */ + while (1) { + dev = sysfs_device_get_parent(dev); + if (dev == NULL) + break; + printf(" looking at parent device '%s':\n", dev->devpath); + printf(" KERNELS==\"%s\"\n", dev->kernel); + printf(" SUBSYSTEMS==\"%s\"\n", dev->subsystem); + printf(" DRIVERS==\"%s\"\n", dev->driver); + + print_all_attributes(dev->devpath, "ATTRS"); + } + + return 0; +} + +static void print_record(struct udevice *udev) +{ + struct name_entry *name_loop; + + printf("P: %s\n", udev->dev->devpath); + printf("N: %s\n", udev->name); + list_for_each_entry(name_loop, &udev->symlink_list, node) + printf("S: %s\n", name_loop->name); + if (udev->link_priority != 0) + printf("L: %i\n", udev->link_priority); + if (udev->partitions != 0) + printf("A:%u\n", udev->partitions); + if (udev->ignore_remove) + printf("R:%u\n", udev->ignore_remove); + list_for_each_entry(name_loop, &udev->env_list, node) + printf("E: %s\n", name_loop->name); +} + +static void export_db(void) { + LIST_HEAD(name_list); + struct name_entry *name_loop; + + udev_db_get_all_entries(&name_list); + list_for_each_entry(name_loop, &name_list, node) { + struct udevice *udev_db; + + udev_db = udev_device_init(NULL); + if (udev_db == NULL) + continue; + if (udev_db_get_device(udev_db, name_loop->name) == 0) + print_record(udev_db); + printf("\n"); + udev_device_cleanup(udev_db); + } + name_list_cleanup(&name_list); +} + +static int lookup_device_by_name(struct udevice *udev, const char *name) +{ + LIST_HEAD(name_list); + int count; + struct name_entry *device; + int rc = -1; + + count = udev_db_get_devices_by_name(name, &name_list); + if (count <= 0) + goto out; + + info("found %i devices for '%s'", count, name); + + /* select the device that seems to match */ + list_for_each_entry(device, &name_list, node) { + char filename[PATH_SIZE]; + struct stat statbuf; + + udev_device_init(udev); + if (udev_db_get_device(udev, device->name) != 0) + continue; + info("found db entry '%s'", device->name); + + /* make sure, we don't get a link of a differnt device */ + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, name, sizeof(filename)); + if (stat(filename, &statbuf) != 0) + continue; + if (major(udev->devt) > 0 && udev->devt != statbuf.st_rdev) { + info("skip '%s', dev_t doesn't match", udev->name); + continue; + } + rc = 0; + break; + } +out: + name_list_cleanup(&name_list); + return rc; +} + +int main(int argc, char *argv[], char *envp[]) +{ + int option; + struct udevice *udev; + int root = 0; + + static const struct option options[] = { + { "name", 1, NULL, 'n' }, + { "path", 1, NULL, 'p' }, + { "query", 1, NULL, 'q' }, + { "attribute-walk", 0, NULL, 'a' }, + { "export-db", 0, NULL, 'e' }, + { "root", 0, NULL, 'r' }, + { "version", 0, NULL, 1 }, /* -V outputs braindead format */ + { "help", 0, NULL, 'h' }, + {} + }; + + enum action_type { + ACTION_NONE, + ACTION_QUERY, + ACTION_ATTRIBUTE_WALK, + ACTION_ROOT, + } action = ACTION_NONE; + + enum query_type { + QUERY_NONE, + QUERY_NAME, + QUERY_PATH, + QUERY_SYMLINK, + QUERY_ENV, + QUERY_ALL, + } query = QUERY_NONE; + + char path[PATH_SIZE] = ""; + char name[PATH_SIZE] = ""; + struct name_entry *name_loop; + int rc = 0; + + logging_init("udevinfo"); + udev_config_init(); + sysfs_init(); + + udev = udev_device_init(NULL); + if (udev == NULL) { + rc = 1; + goto exit; + } + + while (1) { + option = getopt_long(argc, argv, "aen:p:q:rVh", options, NULL); + if (option == -1) + break; + + dbg("option '%c'", option); + switch (option) { + case 'n': + /* remove /dev if given */ + if (strncmp(optarg, udev_root, strlen(udev_root)) == 0) + strlcpy(name, &optarg[strlen(udev_root)+1], sizeof(name)); + else + strlcpy(name, optarg, sizeof(name)); + dbg("name: %s", name); + break; + case 'p': + /* remove /sys if given */ + if (strncmp(optarg, sysfs_path, strlen(sysfs_path)) == 0) + strlcpy(path, &optarg[strlen(sysfs_path)], sizeof(path)); + else + strlcpy(path, optarg, sizeof(path)); + dbg("path: %s", path); + break; + case 'q': + action = ACTION_QUERY; + if (strcmp(optarg, "name") == 0) { + query = QUERY_NAME; + break; + } + if (strcmp(optarg, "symlink") == 0) { + query = QUERY_SYMLINK; + break; + } + if (strcmp(optarg, "path") == 0) { + query = QUERY_PATH; + break; + } + if (strcmp(optarg, "env") == 0) { + query = QUERY_ENV; + break; + } + if (strcmp(optarg, "all") == 0) { + query = QUERY_ALL; + break; + } + fprintf(stderr, "unknown query type\n"); + rc = 2; + goto exit; + case 'r': + if (action == ACTION_NONE) + action = ACTION_ROOT; + root = 1; + break; + case 'a': + action = ACTION_ATTRIBUTE_WALK; + break; + case 'e': + export_db(); + goto exit; + case 1: + printf("%s\n", UDEV_VERSION); + goto exit; + case 'V': + printf("udevinfo, version %s\n", UDEV_VERSION); + goto exit; + case 'h': + printf("Usage: udevinfo OPTIONS\n" + " --query= query database for the specified value:\n" + " name name of device node\n" + " symlink pointing to node\n" + " path sysfs device path\n" + " env the device related imported environment\n" + " all all values\n" + "\n" + " --path= sysfs device path used for query or chain\n" + " --name= node or symlink name used for query\n" + "\n" + " --root prepend to query result or print udev_root\n" + " --attribute-walk print all SYSFS_attributes along the device chain\n" + " --export-db export the content of the udev database\n" + " --help print this text\n" + "\n"); + goto exit; + default: + goto exit; + } + } + + /* run action */ + switch (action) { + case ACTION_QUERY: + /* needs devpath or node/symlink name for query */ + if (path[0] != '\0') { + if (udev_db_get_device(udev, path) != 0) { + fprintf(stderr, "no record for '%s' in database\n", path); + rc = 3; + goto exit; + } + } else if (name[0] != '\0') { + if (lookup_device_by_name(udev, name) != 0) { + fprintf(stderr, "node name not found\n"); + rc = 4; + goto exit; + } + } else { + fprintf(stderr, "query needs --path or node --name specified\n"); + rc = 4; + goto exit; + } + + switch(query) { + case QUERY_NAME: + if (root) + printf("%s/%s\n", udev_root, udev->name); + else + printf("%s\n", udev->name); + break; + case QUERY_SYMLINK: + if (list_empty(&udev->symlink_list)) + goto exit; + if (root) + list_for_each_entry(name_loop, &udev->symlink_list, node) + printf("%s/%s ", udev_root, name_loop->name); + else + list_for_each_entry(name_loop, &udev->symlink_list, node) + printf("%s ", name_loop->name); + printf("\n"); + break; + case QUERY_PATH: + printf("%s\n", udev->dev->devpath); + goto exit; + case QUERY_ENV: + list_for_each_entry(name_loop, &udev->env_list, node) + printf("%s\n", name_loop->name); + break; + case QUERY_ALL: + print_record(udev); + break; + default: + fprintf(stderr, "unknown query type\n"); + break; + } + break; + case ACTION_ATTRIBUTE_WALK: + if (path[0] != '\0') { + if (print_device_chain(path) != 0) { + fprintf(stderr, "no valid sysfs device found\n"); + rc = 4; + goto exit; + } + } else if (name[0] != '\0') { + if (lookup_device_by_name(udev, name) != 0) { + fprintf(stderr, "node name not found\n"); + rc = 4; + goto exit; + } + if (print_device_chain(udev->dev->devpath) != 0) { + fprintf(stderr, "no valid sysfs device found\n"); + rc = 4; + goto exit; + } + } else { + fprintf(stderr, "attribute walk needs --path or node --name specified\n"); + rc = 5; + goto exit; + } + break; + case ACTION_ROOT: + printf("%s\n", udev_root); + break; + default: + fprintf(stderr, "missing option\n"); + rc = 1; + break; + } + +exit: + udev_device_cleanup(udev); + sysfs_cleanup(); + logging_close(); + return rc; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevinfo.xml b/21cnbao/code/05/udev源代码/udev-114/udevinfo.xml new file mode 100644 index 0000000..bb3571c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevinfo.xml @@ -0,0 +1,122 @@ + + + +
    +
    + udevinfo + + + udevinfo + August 2005 + udev + + + + udevinfo + 8 + + + + + udevinfo + query udev device information + + + + + udevinfo + + + + + + + + + + + + DESCRIPTION + udevinfo queries the udev database for device information + stored in the udev database. It can also query the properties + of a device from its sysfs representation to help creating udev + rules that match this device. + + + OPTIONS + + + + + Query the database for specified type of device data. It needs the + or to identify the specified + device. Valid queries are: + name, symlink, path, + env, all. + + + + + + The devpath of the device to query. + + + + + + The name of the device node or a symlink to query + + + + + + The udev root directory: /dev. If used in conjunction + with a name or symlink query, the + query returns the absolute path including the root directory. + + + + + + Print all sysfs properties of the specified device that can be used + in udev rules to match the specified device. It prints all devices + along the chain, up to the root of sysfs that can be used in udev rules. + + + + + + Export the content of the udev database. + + + + + + + Print version. + + + + + + + Print help text. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/udevmonitor.8 b/21cnbao/code/05/udev源代码/udev-114/udevmonitor.8 new file mode 100644 index 0000000..0adb998 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevmonitor.8 @@ -0,0 +1,48 @@ +.\" Title: udevmonitor +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: August 2005 +.\" Manual: udevmonitor +.\" Source: udev +.\" +.TH "UDEVMONITOR" "8" "August 2005" "udev" "udevmonitor" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevmonitor \- print the kernel and udev event sequence to the console +.SH "SYNOPSIS" +.HP 12 +\fBudevmonitor\fR [\fB\-\-environment\fR] [\fB\-\-kernel\fR] [\fB\-\-udev\fR] [\fB\-\-help\fR] +.SH "DESCRIPTION" +.PP +udevmonitor listens to the kernel uevents and events sent out by a udev rule and prints the devpath of the event to the console. It can be used to analyze the event timing, by comparing the timestamps of the kernel uevent and the udev event. +.SH "OPTIONS" +.PP +\fB\-\-environment\fR +.RS 4 +Print the complete environment for all events. Can be used to compare the kernel supplied and the udev added environment values. +.RE +.PP +\fB\-\-kernel\fR +.RS 4 +Print the kernel uevents. +.RE +.PP +\fB\-\-udev\fR +.RS 4 +Print the udev event after the rule processing. +.RE +.PP +\fB\-\-help\fR +.RS 4 +Print usage. +.RE +.SH "AUTHOR" +.PP +Written by Kay Sievers +. +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/udevmonitor.c b/21cnbao/code/05/udev源代码/udev-114/udevmonitor.c new file mode 100644 index 0000000..a9cc061 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevmonitor.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" + +static int uevent_netlink_sock = -1; +static int udev_monitor_sock = -1; +static volatile int udev_exit; + +static int init_udev_monitor_socket(void) +{ + struct sockaddr_un saddr; + socklen_t addrlen; + const int feature_on = 1; + int retval; + + memset(&saddr, 0x00, sizeof(saddr)); + saddr.sun_family = AF_LOCAL; + /* use abstract namespace for socket path */ + strcpy(&saddr.sun_path[1], "/org/kernel/udev/monitor"); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + udev_monitor_sock = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (udev_monitor_sock == -1) { + fprintf(stderr, "error getting socket: %s\n", strerror(errno)); + return -1; + } + + /* the bind takes care of ensuring only one copy running */ + retval = bind(udev_monitor_sock, (struct sockaddr *) &saddr, addrlen); + if (retval < 0) { + fprintf(stderr, "bind failed: %s\n", strerror(errno)); + close(udev_monitor_sock); + udev_monitor_sock = -1; + return -1; + } + + /* enable receiving of the sender credentials */ + setsockopt(udev_monitor_sock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); + + return 0; +} + +static int init_uevent_netlink_sock(void) +{ + struct sockaddr_nl snl; + int retval; + + memset(&snl, 0x00, sizeof(struct sockaddr_nl)); + snl.nl_family = AF_NETLINK; + snl.nl_pid = getpid(); + snl.nl_groups = 1; + + uevent_netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); + if (uevent_netlink_sock == -1) { + fprintf(stderr, "error getting socket: %s\n", strerror(errno)); + return -1; + } + + retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, + sizeof(struct sockaddr_nl)); + if (retval < 0) { + fprintf(stderr, "bind failed: %s\n", strerror(errno)); + close(uevent_netlink_sock); + uevent_netlink_sock = -1; + return -1; + } + + return 0; +} + +static void asmlinkage sig_handler(int signum) +{ + if (signum == SIGINT || signum == SIGTERM) + udev_exit = 1; +} + +static const char *search_key(const char *searchkey, const char *buf, size_t buflen) +{ + size_t bufpos = 0; + size_t searchkeylen = strlen(searchkey); + + while (bufpos < buflen) { + const char *key; + int keylen; + + key = &buf[bufpos]; + keylen = strlen(key); + if (keylen == 0) + break; + if ((strncmp(searchkey, key, searchkeylen) == 0) && key[searchkeylen] == '=') + return &key[searchkeylen + 1]; + bufpos += keylen + 1; + } + return NULL; +} + +int main(int argc, char *argv[]) +{ + struct sigaction act; + int option; + int env = 0; + int kernel = 0; + int udev = 0; + fd_set readfds; + int retval = 0; + + static const struct option options[] = { + { "environment", 0, NULL, 'e' }, + { "kernel", 0, NULL, 'k' }, + { "udev", 0, NULL, 'u' }, + { "help", 0, NULL, 'h' }, + {} + }; + + while (1) { + option = getopt_long(argc, argv, "ekuh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'e': + env = 1; + break; + case 'k': + kernel = 1; + break; + case 'u': + udev = 1; + break; + case 'h': + printf("Usage: udevmonitor [--environment] [--kernel] [--udev] [--help]\n" + " --env print the whole event environment\n" + " --kernel print kernel uevents\n" + " --udev print udev events\n" + " --help print this help text\n\n"); + default: + goto out; + } + } + + if (!kernel && !udev) { + kernel = 1; + udev =1; + } + + if (getuid() != 0 && kernel) { + fprintf(stderr, "root privileges needed to subscribe to kernel events\n"); + goto out; + } + + /* set signal handlers */ + memset(&act, 0x00, sizeof(struct sigaction)); + act.sa_handler = (void (*)(int)) sig_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + + printf("udevmonitor will print the received events for:\n"); + if (udev) { + retval = init_udev_monitor_socket(); + if (retval) + goto out; + printf("UDEV the event which udev sends out after rule processing\n"); + } + if (kernel) { + retval = init_uevent_netlink_sock(); + if (retval) + goto out; + printf("UEVENT the kernel uevent\n"); + } + printf("\n"); + + while (!udev_exit) { + char buf[UEVENT_BUFFER_SIZE*2]; + ssize_t buflen; + ssize_t bufpos; + ssize_t keys; + int fdcount; + struct timeval tv; + struct timezone tz; + char timestr[64]; + const char *source = NULL; + const char *devpath, *action, *subsys; + + buflen = 0; + FD_ZERO(&readfds); + if (uevent_netlink_sock >= 0) + FD_SET(uevent_netlink_sock, &readfds); + if (udev_monitor_sock >= 0) + FD_SET(udev_monitor_sock, &readfds); + + fdcount = select(UDEV_MAX(uevent_netlink_sock, udev_monitor_sock)+1, &readfds, NULL, NULL, NULL); + if (fdcount < 0) { + if (errno != EINTR) + fprintf(stderr, "error receiving uevent message: %s\n", strerror(errno)); + continue; + } + + if (gettimeofday(&tv, &tz) == 0) { + snprintf(timestr, sizeof(timestr), "%llu.%06u", + (unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec); + } else + timestr[0] = '\0'; + + if ((uevent_netlink_sock >= 0) && FD_ISSET(uevent_netlink_sock, &readfds)) { + buflen = recv(uevent_netlink_sock, &buf, sizeof(buf), 0); + if (buflen <= 0) { + fprintf(stderr, "error receiving uevent message: %s\n", strerror(errno)); + continue; + } + source = "UEVENT"; + } + + if ((udev_monitor_sock >= 0) && FD_ISSET(udev_monitor_sock, &readfds)) { + buflen = recv(udev_monitor_sock, &buf, sizeof(buf), 0); + if (buflen <= 0) { + fprintf(stderr, "error receiving udev message: %s\n", strerror(errno)); + continue; + } + source = "UDEV "; + } + + if (buflen == 0) + continue; + + keys = strlen(buf) + 1; /* start of payload */ + devpath = search_key("DEVPATH", &buf[keys], buflen); + action = search_key("ACTION", &buf[keys], buflen); + subsys = search_key("SUBSYSTEM", &buf[keys], buflen); + printf("%s[%s] %-8s %s (%s)\n", source, timestr, action, devpath, subsys); + + /* print environment */ + bufpos = keys; + if (env) { + while (bufpos < buflen) { + int keylen; + char *key; + + key = &buf[bufpos]; + keylen = strlen(key); + if (keylen == 0) + break; + printf("%s\n", key); + bufpos += keylen + 1; + } + printf("\n"); + } + } + +out: + if (uevent_netlink_sock >= 0) + close(uevent_netlink_sock); + if (udev_monitor_sock >= 0) + close(udev_monitor_sock); + + if (retval) + return 1; + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevmonitor.xml b/21cnbao/code/05/udev源代码/udev-114/udevmonitor.xml new file mode 100644 index 0000000..1ab87ab --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevmonitor.xml @@ -0,0 +1,85 @@ + + + +
    +
    + udevmonitor + + + udevmonitor + August 2005 + udev + + + + udevmonitor + 8 + + + + + udevmonitor + print the kernel and udev event sequence to the console + + + + + udevmonitor + + + + + + + + DESCRIPTION + udevmonitor listens to the kernel uevents and events sent out by a udev rule + and prints the devpath of the event to the console. It can be used to analyze the + event timing, by comparing the timestamps of the kernel uevent and the udev event. + + + + OPTIONS + + + + + Print the complete environment for all events. Can be used to compare the + kernel supplied and the udev added environment values. + + + + + + Print the kernel uevents. + + + + + + Print the udev event after the rule processing. + + + + + + Print usage. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/udevsettle.8 b/21cnbao/code/05/udev源代码/udev-114/udevsettle.8 new file mode 100644 index 0000000..818a7ff --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevsettle.8 @@ -0,0 +1,39 @@ +.\" Title: udevsettle +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: March 2006 +.\" Manual: udevsettle +.\" Source: udev +.\" +.TH "UDEVSETTLE" "8" "March 2006" "udev" "udevsettle" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevsettle \- wait until queued kernel/udev events are handled +.SH "SYNOPSIS" +.HP 11 +\fBudevsettle\fR [\fB\-\-timeout=\fR\fB\fIseconds\fR\fR] +.SH "DESCRIPTION" +.PP +Waits watching the udev event queue and exits if all current events are handled. +.SH "OPTIONS" +.PP +\fB\-\-timeout=\fR\fB\fIseconds\fR\fR +.RS 4 +maximum seconds to wait for the queue to become empty. +.RE +.SH "ENVIRONMENT" +.PP +\fBUDEV_LOG\fR +.RS 4 +Overrides the syslog priority specified in the config file. +.RE +.SH "AUTHOR" +.PP +Written by Kay Sievers +. +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/udevsettle.c b/21cnbao/code/05/udev源代码/udev-114/udevsettle.c new file mode 100644 index 0000000..42a03ba --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevsettle.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" + +#define DEFAULT_TIMEOUT 180 +#define LOOP_PER_SECOND 20 + + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log_priority) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +int main(int argc, char *argv[], char *envp[]) +{ + char queuename[PATH_SIZE]; + char filename[PATH_SIZE]; + unsigned long long seq_kernel; + unsigned long long seq_udev; + char seqnum[32]; + int fd; + ssize_t len; + int timeout = DEFAULT_TIMEOUT; + int loop; + static const struct option options[] = { + { "timeout", 1, NULL, 't' }, + { "help", 0, NULL, 'h' }, + {} + }; + int option; + int rc = 1; + int seconds; + + logging_init("udevsettle"); + udev_config_init(); + dbg("version %s", UDEV_VERSION); + sysfs_init(); + + while (1) { + option = getopt_long(argc, argv, "t:h", options, NULL); + if (option == -1) + break; + + switch (option) { + case 't': + seconds = atoi(optarg); + if (seconds > 0) + timeout = seconds; + else + fprintf(stderr, "invalid timeout value\n"); + dbg("timeout=%i", timeout); + break; + case 'h': + printf("Usage: udevsettle [--help] [--timeout=]\n\n"); + goto exit; + } + } + + strlcpy(queuename, udev_root, sizeof(queuename)); + strlcat(queuename, "/" EVENT_QUEUE_DIR, sizeof(queuename)); + + loop = timeout * LOOP_PER_SECOND; + while (loop--) { + /* wait for events in queue to finish */ + while (loop--) { + struct stat statbuf; + + if (stat(queuename, &statbuf) < 0) { + info("queue is empty"); + break; + } + usleep(1000 * 1000 / LOOP_PER_SECOND); + } + if (loop <= 0) { + info("timeout waiting for queue"); + goto exit; + } + + /* read current udev seqnum */ + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/" EVENT_SEQNUM, sizeof(filename)); + fd = open(filename, O_RDONLY); + if (fd < 0) + goto exit; + len = read(fd, seqnum, sizeof(seqnum)-1); + close(fd); + if (len <= 0) + goto exit; + seqnum[len] = '\0'; + seq_udev = strtoull(seqnum, NULL, 10); + info("udev seqnum = %llu", seq_udev); + + /* read current kernel seqnum */ + strlcpy(filename, sysfs_path, sizeof(filename)); + strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename)); + fd = open(filename, O_RDONLY); + if (fd < 0) + goto exit; + len = read(fd, seqnum, sizeof(seqnum)-1); + close(fd); + if (len <= 0) + goto exit; + seqnum[len] = '\0'; + seq_kernel = strtoull(seqnum, NULL, 10); + info("kernel seqnum = %llu", seq_kernel); + + /* make sure all kernel events have arrived in the queue */ + if (seq_udev >= seq_kernel) { + info("queue is empty and no pending events left"); + rc = 0; + goto exit; + } + usleep(1000 * 1000 / LOOP_PER_SECOND); + info("queue is empty, but events still pending"); + } + +exit: + sysfs_cleanup(); + logging_close(); + return rc; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevsettle.xml b/21cnbao/code/05/udev源代码/udev-114/udevsettle.xml new file mode 100644 index 0000000..8eb8cbd --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevsettle.xml @@ -0,0 +1,70 @@ + + + +
    +
    + udevsettle + + + udevsettle + March 2006 + udev + + + + udevsettle + 8 + + + + + udevsettlewait until queued kernel/udev events are handled + + + + + udevsettle + + + + + DESCRIPTION + Waits watching the udev event queue and exits if all current events are handled. + + + OPTIONS + + + + + maximum seconds to wait for the queue to become empty. + + + + + + ENVIRONMENT + + + + + Overrides the syslog priority specified in the config file. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/udevstart.8 b/21cnbao/code/05/udev源代码/udev-114/udevstart.8 new file mode 100644 index 0000000..ac7d070 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevstart.8 @@ -0,0 +1,27 @@ +.\" Title: udevstart +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: August 2005 +.\" Manual: udevstart +.\" Source: udev +.\" +.TH "UDEVSTART" "8" "August 2005" "udev" "udevstart" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevstart \- populate initial device directory +.SH "SYNOPSIS" +.HP 10 +\fBudevstart\fR +.SH "DESCRIPTION" +.PP +udevstart scans the kernel exported device information available in sysfs for devices which require a device node to operate and creates the node using the specified udev rules. udevstart is used to create the initial device directory after system bootup. +.SH "AUTHOR" +.PP +Written by Harald Hoyer +. +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/udevstart.c b/21cnbao/code/05/udev源代码/udev-114/udevstart.c new file mode 100644 index 0000000..66b96a2 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevstart.c @@ -0,0 +1,359 @@ +/* + * quick and dirty way to populate a /dev directory + * + * Copyright (C) 2004 Harald Hoyer + * Copyright (C) 2004 Greg Kroah-Hartman + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" +#include "udev_selinux.h" + +static const char *udev_run_str; +static const char *udev_log_str; +static struct udev_rules rules; + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log_priority) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +struct device { + struct list_head node; + char path[PATH_SIZE]; +}; + +/* sort files in lexical order */ +static int device_list_insert(const char *path, struct list_head *device_list) +{ + struct device *loop_device; + struct device *new_device; + const char *devpath = &path[strlen(sysfs_path)]; + + dbg("insert: '%s'", devpath); + + list_for_each_entry(loop_device, device_list, node) { + if (strcmp(loop_device->path, devpath) > 0) { + break; + } + } + + new_device = malloc(sizeof(struct device)); + if (new_device == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + strlcpy(new_device->path, devpath, sizeof(new_device->path)); + list_add_tail(&new_device->node, &loop_device->node); + dbg("add '%s'" , new_device->path); + return 0; +} + +/* list of devices that we should run last due to any one of a number of reasons */ +static char *last_list[] = { + "/block/dm", /* on here because dm wants to have the block devices around before it */ + NULL, +}; + +/* list of devices that we should run first due to any one of a number of reasons */ +static char *first_list[] = { + "/class/mem", + "/class/tty", + NULL, +}; + +static int add_device(const char *devpath) +{ + struct sysfs_device *dev; + struct udevice *udev; + int retval = 0; + + /* clear and set environment for next event */ + clearenv(); + setenv("ACTION", "add", 1); + setenv("UDEV_START", "1", 1); + if (udev_log_str) + setenv("UDEV_LOG", udev_log_str, 1); + if (udev_run_str) + setenv("UDEV_RUN", udev_run_str, 1); + + dev = sysfs_device_get(devpath); + if (dev == NULL) + return -1; + + udev = udev_device_init(NULL); + if (udev == NULL) + return -1; + + /* override built-in sysfs device */ + udev->dev = dev; + strcpy(udev->action, "add"); + + if (strcmp(udev->dev->subsystem, "net") != 0) { + udev->devt = udev_device_get_devt(udev); + if (major(udev->devt) == 0) + return -1; + } + + dbg("add '%s'", udev->dev->devpath); + setenv("DEVPATH", udev->dev->devpath, 1); + setenv("SUBSYSTEM", udev->dev->subsystem, 1); + + udev_rules_get_name(&rules, udev); + if (udev->ignore_device) { + dbg("device event will be ignored"); + goto exit; + } + if (udev->name[0] != '\0') + retval = udev_device_event(&rules, udev); + else + info("device node creation supressed"); + + if (retval == 0 && udev_run) + udev_rules_run(udev); + +exit: + udev_device_cleanup(udev); + return 0; +} + +static void exec_list(struct list_head *device_list) +{ + struct device *loop_device; + struct device *tmp_device; + int i; + + /* handle the "first" type devices first */ + list_for_each_entry_safe(loop_device, tmp_device, device_list, node) { + for (i = 0; first_list[i] != NULL; i++) { + if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) { + add_device(loop_device->path); + list_del(&loop_device->node); + free(loop_device); + break; + } + } + } + + /* handle the devices we are allowed to, excluding the "last" type devices */ + list_for_each_entry_safe(loop_device, tmp_device, device_list, node) { + int found = 0; + for (i = 0; last_list[i] != NULL; i++) { + if (strncmp(loop_device->path, last_list[i], strlen(last_list[i])) == 0) { + found = 1; + break; + } + } + if (found) + continue; + + add_device(loop_device->path); + list_del(&loop_device->node); + free(loop_device); + } + + /* handle the rest of the devices left over, if any */ + list_for_each_entry_safe(loop_device, tmp_device, device_list, node) { + add_device(loop_device->path); + list_del(&loop_device->node); + free(loop_device); + } +} + +static int has_devt(const char *path) +{ + char filename[PATH_SIZE]; + struct stat statbuf; + + snprintf(filename, sizeof(filename), "%s/dev", path); + filename[sizeof(filename)-1] = '\0'; + + if (stat(filename, &statbuf) == 0) + return 1; + + return 0; +} + +static void udev_scan_block(struct list_head *device_list) +{ + char base[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + snprintf(base, sizeof(base), "%s/block", sysfs_path); + base[sizeof(base)-1] = '\0'; + + dir = opendir(base); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; + DIR *dir2; + struct dirent *dent2; + + if (dent->d_name[0] == '.') + continue; + + snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name); + dirname[sizeof(dirname)-1] = '\0'; + if (has_devt(dirname)) + device_list_insert(dirname, device_list); + else + continue; + + /* look for partitions */ + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[PATH_SIZE]; + + if (dent2->d_name[0] == '.') + continue; + + snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name); + dirname2[sizeof(dirname2)-1] = '\0'; + + if (has_devt(dirname2)) + device_list_insert(dirname2, device_list); + } + closedir(dir2); + } + } + closedir(dir); + } +} + +static void udev_scan_class(struct list_head *device_list) +{ + char base[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + snprintf(base, sizeof(base), "%s/class", sysfs_path); + base[sizeof(base)-1] = '\0'; + + dir = opendir(base); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; + DIR *dir2; + struct dirent *dent2; + + if (dent->d_name[0] == '.') + continue; + + snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name); + dirname[sizeof(dirname)-1] = '\0'; + + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[PATH_SIZE]; + + if (dent2->d_name[0] == '.') + continue; + + snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name); + dirname2[sizeof(dirname2)-1] = '\0'; + + if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0) + device_list_insert(dirname2, device_list); + } + closedir(dir2); + } + } + closedir(dir); + } +} + +static void asmlinkage sig_handler(int signum) +{ + switch (signum) { + case SIGALRM: + exit(1); + case SIGINT: + case SIGTERM: + exit(20 + signum); + } +} + +int main(int argc, char *argv[], char *envp[]) +{ + LIST_HEAD(device_list); + struct sigaction act; + + logging_init("udevstart"); + udev_config_init(); + selinux_init(); + dbg("version %s", UDEV_VERSION); + + udev_run_str = getenv("UDEV_RUN"); + udev_log_str = getenv("UDEV_LOG"); + + /* disable all logging if not explicitely requested */ + if (udev_log_str == NULL) + udev_log_priority = 0; + + /* set signal handlers */ + memset(&act, 0x00, sizeof(act)); + act.sa_handler = (void (*) (int))sig_handler; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + + /* trigger timeout to prevent hanging processes */ + alarm(UDEV_ALARM_TIMEOUT); + + sysfs_init(); + udev_rules_init(&rules, 1); + + udev_scan_class(&device_list); + udev_scan_block(&device_list); + exec_list(&device_list); + + udev_rules_cleanup(&rules); + sysfs_cleanup(); + selinux_exit(); + logging_close(); + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevstart.xml b/21cnbao/code/05/udev源代码/udev-114/udevstart.xml new file mode 100644 index 0000000..c48de7c --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevstart.xml @@ -0,0 +1,50 @@ + + + +
    +
    + udevstart + + + udevstart + August 2005 + udev + + + + udevstart + 8 + + + + + udevstartpopulate initial device directory + + + + + udevstart + + + + DESCRIPTION + udevstart scans the kernel exported device information available in + sysfs for devices which require a device node to operate and creates the node + using the specified udev rules. udevstart is used to create the initial + device directory after system bootup. + + + AUTHOR + Written by Harald Hoyer harald@redhat.com. + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/udevtest.8 b/21cnbao/code/05/udev源代码/udev-114/udevtest.8 new file mode 100644 index 0000000..9ab9249 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevtest.8 @@ -0,0 +1,27 @@ +.\" Title: udevtest +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: August 2005 +.\" Manual: udevtest +.\" Source: udev +.\" +.TH "UDEVTEST" "8" "August 2005" "udev" "udevtest" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevtest \- simulate a udev run and print the action to the console +.SH "SYNOPSIS" +.HP 21 +\fBudevtest \fR\fB\fIdevice\-path\fR\fR +.SH "DESCRIPTION" +.PP +udevtest simulates a udev run for the given device and prints out the name of the node udev would have created, or the name of the network interface, that would have been renamed. +.SH "AUTHOR" +.PP +Written by Greg Kroah\-Hartman +. +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/udevtest.c b/21cnbao/code/05/udev源代码/udev-114/udevtest.c new file mode 100644 index 0000000..7b3ea63 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevtest.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2003-2004 Greg Kroah-Hartman + * Copyright (C) 2004-2006 Kay Sievers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_rules.h" + + +#ifdef USE_LOG +void log_message (int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log_priority) + return; + + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); +} +#endif + +static int import_uevent_var(const char *devpath) +{ + char path[PATH_SIZE]; + static char value[4096]; /* must stay, used with putenv */ + ssize_t size; + int fd; + char *key; + char *next; + int rc = -1; + + /* read uevent file */ + strlcpy(path, sysfs_path, sizeof(path)); + strlcat(path, devpath, sizeof(path)); + strlcat(path, "/uevent", sizeof(path)); + fd = open(path, O_RDONLY); + if (fd < 0) + goto out; + size = read(fd, value, sizeof(value)); + close(fd); + if (size < 0) + goto out; + value[size] = '\0'; + + /* import keys into environment */ + key = value; + while (key[0] != '\0') { + next = strchr(key, '\n'); + if (next == NULL) + goto out; + next[0] = '\0'; + info("import into environment: '%s'", key); + putenv(key); + key = &next[1]; + } + rc = 0; +out: + return rc; +} + +int main(int argc, char *argv[], char *envp[]) +{ + int force = 0; + const char *action = "add"; + const char *subsystem = NULL; + const char *devpath = NULL; + struct udevice *udev; + struct sysfs_device *dev; + struct udev_rules rules = {}; + int retval; + int rc = 0; + + static const struct option options[] = { + { "action", 1, NULL, 'a' }, + { "subsystem", 1, NULL, 's' }, + { "force", 0, NULL, 'f' }, + { "help", 0, NULL, 'h' }, + {} + }; + + info("version %s", UDEV_VERSION); + udev_config_init(); + if (udev_log_priority < LOG_INFO) { + char priority[32]; + + udev_log_priority = LOG_INFO; + sprintf(priority, "%i", udev_log_priority); + setenv("UDEV_LOG", priority, 1); + } + + while (1) { + int option; + + option = getopt_long(argc, argv, "a:s:fh", options, NULL); + if (option == -1) + break; + + dbg("option '%c'", option); + switch (option) { + case 'a': + action = optarg; + break; + case 's': + subsystem = optarg; + break; + case 'f': + force = 1; + break; + case 'h': + printf("Usage: udevtest OPTIONS \n" + " --action= set action string\n" + " --subsystem= set subsystem string\n" + " --force don't skip node/link creation\n" + " --help print this help text\n\n"); + exit(0); + default: + exit(1); + } + } + devpath = argv[optind]; + + if (devpath == NULL) { + fprintf(stderr, "devpath parameter missing\n"); + rc = 1; + goto exit; + } + + printf("This program is for debugging only, it does not run any program,\n" + "specified by a RUN key. It may show incorrect results, because\n" + "some values may be different, or not available at a simulation run.\n" + "\n"); + + sysfs_init(); + udev_rules_init(&rules, 0); + + /* remove /sys if given */ + if (strncmp(devpath, sysfs_path, strlen(sysfs_path)) == 0) + devpath = &devpath[strlen(sysfs_path)]; + + dev = sysfs_device_get(devpath); + if (dev == NULL) { + fprintf(stderr, "unable to open device '%s'\n", devpath); + rc = 2; + goto exit; + } + + udev = udev_device_init(NULL); + if (udev == NULL) { + fprintf(stderr, "error initializing device\n"); + rc = 3; + goto exit; + } + + if (subsystem != NULL) + strlcpy(dev->subsystem, subsystem, sizeof(dev->subsystem)); + + /* override built-in sysfs device */ + udev->dev = dev; + strlcpy(udev->action, action, sizeof(udev->action)); + udev->devt = udev_device_get_devt(udev); + + /* simulate node creation with test flag */ + if (!force) + udev->test_run = 1; + + setenv("DEVPATH", udev->dev->devpath, 1); + setenv("SUBSYSTEM", udev->dev->subsystem, 1); + setenv("ACTION", udev->action, 1); + import_uevent_var(udev->dev->devpath); + + info("looking at device '%s' from subsystem '%s'", udev->dev->devpath, udev->dev->subsystem); + retval = udev_device_event(&rules, udev); + if (retval == 0 && !udev->ignore_device && udev_run) { + struct name_entry *name_loop; + + list_for_each_entry(name_loop, &udev->run_list, node) { + char program[PATH_SIZE]; + + strlcpy(program, name_loop->name, sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); + info("run: '%s'", program); + } + } + udev_device_cleanup(udev); + +exit: + udev_rules_cleanup(&rules); + sysfs_cleanup(); + return rc; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevtest.xml b/21cnbao/code/05/udev源代码/udev-114/udevtest.xml new file mode 100644 index 0000000..259558d --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevtest.xml @@ -0,0 +1,50 @@ + + + +
    +
    + udevtest + + + udevtest + August 2005 + udev + + + + udevtest + 8 + + + + + udevtest + simulate a udev run and print the action to the console + + + + + udevtest device-path + + + + DESCRIPTION + udevtest simulates a udev run for the given device and prints out the + name of the node udev would have created, or the name of the network interface, + that would have been renamed. + + + AUTHOR + Written by Greg Kroah-Hartman greg@kroah.com. + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/05/udev源代码/udev-114/udevtrigger.8 b/21cnbao/code/05/udev源代码/udev-114/udevtrigger.8 new file mode 100644 index 0000000..5ef9e8f --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevtrigger.8 @@ -0,0 +1,76 @@ +.\" Title: udevtrigger +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: March 2006 +.\" Manual: udevtrigger +.\" Source: udev +.\" +.TH "UDEVTRIGGER" "8" "March 2006" "udev" "udevtrigger" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevtrigger \- request kernel devices events for coldplug +.SH "SYNOPSIS" +.HP 12 +\fBudevtrigger\fR [\fB\-\-verbose\fR] [\fB\-\-dry\-run\fR] [\fB\-\-retry\-failed\fR] [\fB\-\-help\fR] [\fB\-\-action=\fR\fB\fIaction\fR\fR] [\fB\-\-subsystem\-match=\fR\fB\fIsubsystem\fR\fR] [\fB\-\-subsystem\-nomatch=\fR\fB\fIsubsystem\fR\fR] [\fB\-\-attr\-match=\fR\fB\fIattribute=value\fR\fR] [\fB\-\-attr\-nomatch=\fR\fB\fIattribute=value\fR\fR] +.SH "DESCRIPTION" +.PP +Trigger kernel device uevents to replay missing events at system coldplug. +.SH "OPTIONS" +.PP +\fB\-\-verbose\fR +.RS 4 +Print the list of devices which will be triggered. +.RE +.PP +\fB\-\-dry\-run\fR +.RS 4 +Do not actually trigger the event. +.RE +.PP +\fB\-\-retry\-failed\fR +.RS 4 +Trigger only the events which are failed during a previous run. +.RE +.PP +\fB\-\-action=\fR\fB\fIaction\fR\fR +.RS 4 +Type of event to be triggered. The default value is "add". +.RE +.PP +\fB\-\-subsystem\-match=\fR\fB\fIsubsystem\fR\fR +.RS 4 +Trigger events for devices which belong to a matching subsystem. This option can be specified multiple times and supports shell style pattern matching. +.RE +.PP +\fB\-\-subsystem\-nomatch=\fR\fB\fIsubsystem\fR\fR +.RS 4 +Do not trigger events for devices which belong to a matching subsystem. This option can be specified multiple times and supports shell style pattern matching. +.RE +.PP +\fB\-\-attr\-match=\fR\fB\fIattribute=value\fR\fR +.RS 4 +Trigger events for devices with a matching sysfs attribute. If a value is specified along with the attribute name, the content of the attribute is matched against the given value using shell style pattern matching. If no value is specified, the existence of the sysfs attribute is checked. This option can be specified multiple times. +.RE +.PP +\fB\-\-attr\-nomatch\fR\fB\fIattribute=value\fR\fR +.RS 4 +Do not trigger events for devices with a matching sysfs attribute. If a value is specified along with the attribute name, the content of the attribute is matched against the given value using shell style pattern matching. If no value is specified, the existence of the sysfs attribute is checked. This option can be specified multiple times. +.RE +.SH "ENVIRONMENT" +.PP +\fBUDEV_LOG\fR +.RS 4 +Overrides the syslog priority specified in the config file. +.RE +.SH "AUTHOR" +.PP +Written by Kay Sievers + +and Hannes Reinecke +. +.SH "SEE ALSO" +.PP +\fBudev\fR(7) diff --git a/21cnbao/code/05/udev源代码/udev-114/udevtrigger.c b/21cnbao/code/05/udev源代码/udev-114/udevtrigger.c new file mode 100644 index 0000000..cf8f209 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevtrigger.c @@ -0,0 +1,558 @@ +/* + * Copyright (C) 2004-2006 Kay Sievers + * Copyright (C) 2006 Hannes Reinecke + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" + +static int verbose; +static int dry_run; +LIST_HEAD(device_list); +LIST_HEAD(filter_subsystem_match_list); +LIST_HEAD(filter_subsystem_nomatch_list); +LIST_HEAD(filter_attr_match_list); +LIST_HEAD(filter_attr_nomatch_list); + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + + if (priority > udev_log_priority) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +/* devices that should run last cause of their dependencies */ +static int delay_device(const char *devpath) +{ + static const char *delay_device_list[] = { + "*/md*", + "*/dm-*", + NULL + }; + int i; + + for (i = 0; delay_device_list[i] != NULL; i++) + if (fnmatch(delay_device_list[i], devpath, 0) == 0) + return 1; + return 0; +} + +static int device_list_insert(const char *path) +{ + char filename[PATH_SIZE]; + char devpath[PATH_SIZE]; + struct stat statbuf; + + dbg("add '%s'" , path); + + /* we only have a device, if we have an uevent file */ + strlcpy(filename, path, sizeof(filename)); + strlcat(filename, "/uevent", sizeof(filename)); + if (stat(filename, &statbuf) < 0) + return -1; + if (!(statbuf.st_mode & S_IWUSR)) + return -1; + + strlcpy(devpath, &path[strlen(sysfs_path)], sizeof(devpath)); + + /* resolve possible link to real target */ + if (lstat(path, &statbuf) < 0) + return -1; + if (S_ISLNK(statbuf.st_mode)) + if (sysfs_resolve_link(devpath, sizeof(devpath)) != 0) + return -1; + + name_list_add(&device_list, devpath, 1); + return 0; +} + +static void trigger_uevent(const char *devpath, const char *action) +{ + char filename[PATH_SIZE]; + int fd; + + strlcpy(filename, sysfs_path, sizeof(filename)); + strlcat(filename, devpath, sizeof(filename)); + strlcat(filename, "/uevent", sizeof(filename)); + + if (verbose) + printf("%s\n", devpath); + + if (dry_run) + return; + + fd = open(filename, O_WRONLY); + if (fd < 0) { + dbg("error on opening %s: %s", filename, strerror(errno)); + return; + } + + if (write(fd, action, strlen(action)) < 0) + info("error writing '%s' to '%s': %s", action, filename, strerror(errno)); + + close(fd); +} + +static void exec_list(const char *action) +{ + struct name_entry *loop_device; + struct name_entry *tmp_device; + + list_for_each_entry_safe(loop_device, tmp_device, &device_list, node) { + if (delay_device(loop_device->name)) + continue; + + trigger_uevent(loop_device->name, action); + list_del(&loop_device->node); + free(loop_device); + } + + /* trigger remaining delayed devices */ + list_for_each_entry_safe(loop_device, tmp_device, &device_list, node) { + trigger_uevent(loop_device->name, action); + list_del(&loop_device->node); + free(loop_device); + } +} + +static int subsystem_filtered(const char *subsystem) +{ + struct name_entry *loop_name; + + /* skip devices matching the listed subsystems */ + list_for_each_entry(loop_name, &filter_subsystem_nomatch_list, node) + if (fnmatch(loop_name->name, subsystem, 0) == 0) + return 1; + + /* skip devices not matching the listed subsystems */ + if (!list_empty(&filter_subsystem_match_list)) { + list_for_each_entry(loop_name, &filter_subsystem_match_list, node) + if (fnmatch(loop_name->name, subsystem, 0) == 0) + return 0; + return 1; + } + + return 0; +} + +static int attr_match(const char *path, const char *attr_value) +{ + char attr[NAME_SIZE]; + char file[PATH_SIZE]; + char *match_value; + + strlcpy(attr, attr_value, sizeof(attr)); + + /* separate attr and match value */ + match_value = strchr(attr, '='); + if (match_value != NULL) { + match_value[0] = '\0'; + match_value = &match_value[1]; + } + + strlcpy(file, path, sizeof(file)); + strlcat(file, "/", sizeof(file)); + strlcat(file, attr, sizeof(file)); + + if (match_value != NULL) { + /* match file content */ + char value[NAME_SIZE]; + int fd; + ssize_t size; + + fd = open(file, O_RDONLY); + if (fd < 0) + return 0; + size = read(fd, value, sizeof(value)); + close(fd); + if (size < 0) + return 0; + value[size] = '\0'; + remove_trailing_chars(value, '\n'); + + /* match if attribute value matches */ + if (fnmatch(match_value, value, 0) == 0) + return 1; + } else { + /* match if attribute exists */ + struct stat statbuf; + + if (stat(file, &statbuf) == 0) + return 1; + } + return 0; +} + +static int attr_filtered(const char *path) +{ + struct name_entry *loop_name; + + /* skip devices matching the listed sysfs attributes */ + list_for_each_entry(loop_name, &filter_attr_nomatch_list, node) + if (attr_match(path, loop_name->name)) + return 1; + + /* skip devices not matching the listed sysfs attributes */ + if (!list_empty(&filter_attr_match_list)) { + list_for_each_entry(loop_name, &filter_attr_match_list, node) + if (attr_match(path, loop_name->name)) + return 0; + return 1; + } + return 0; +} + +enum scan_type { + SCAN_DEVICES, + SCAN_SUBSYSTEM, +}; + +static void scan_subsystem(const char *subsys, enum scan_type scan) +{ + char base[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + const char *subdir; + + if (scan == SCAN_DEVICES) + subdir = "/devices"; + else if (scan == SCAN_SUBSYSTEM) + subdir = "/drivers"; + else + return; + + strlcpy(base, sysfs_path, sizeof(base)); + strlcat(base, "/", sizeof(base)); + strlcat(base, subsys, sizeof(base)); + + dir = opendir(base); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; + DIR *dir2; + struct dirent *dent2; + + if (dent->d_name[0] == '.') + continue; + + if (scan == SCAN_DEVICES) + if (subsystem_filtered(dent->d_name)) + continue; + + strlcpy(dirname, base, sizeof(dirname)); + strlcat(dirname, "/", sizeof(dirname)); + strlcat(dirname, dent->d_name, sizeof(dirname)); + + if (scan == SCAN_SUBSYSTEM) { + if (!subsystem_filtered("subsystem")) + device_list_insert(dirname); + if (subsystem_filtered("drivers")) + continue; + } + + strlcat(dirname, subdir, sizeof(dirname)); + + /* look for devices/drivers */ + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[PATH_SIZE]; + + if (dent2->d_name[0] == '.') + continue; + + strlcpy(dirname2, dirname, sizeof(dirname2)); + strlcat(dirname2, "/", sizeof(dirname2)); + strlcat(dirname2, dent2->d_name, sizeof(dirname2)); + if (attr_filtered(dirname2)) + continue; + device_list_insert(dirname2); + } + closedir(dir2); + } + } + closedir(dir); + } +} + +static void scan_block(void) +{ + char base[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + if (subsystem_filtered("block")) + return; + + strlcpy(base, sysfs_path, sizeof(base)); + strlcat(base, "/block", sizeof(base)); + + dir = opendir(base); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; + DIR *dir2; + struct dirent *dent2; + + if (dent->d_name[0] == '.') + continue; + + strlcpy(dirname, base, sizeof(dirname)); + strlcat(dirname, "/", sizeof(dirname)); + strlcat(dirname, dent->d_name, sizeof(dirname)); + if (attr_filtered(dirname)) + continue; + if (device_list_insert(dirname) != 0) + continue; + + /* look for partitions */ + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[PATH_SIZE]; + + if (dent2->d_name[0] == '.') + continue; + + if (!strcmp(dent2->d_name,"device")) + continue; + + strlcpy(dirname2, dirname, sizeof(dirname2)); + strlcat(dirname2, "/", sizeof(dirname2)); + strlcat(dirname2, dent2->d_name, sizeof(dirname2)); + if (attr_filtered(dirname2)) + continue; + device_list_insert(dirname2); + } + closedir(dir2); + } + } + closedir(dir); + } +} + +static void scan_class(void) +{ + char base[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + strlcpy(base, sysfs_path, sizeof(base)); + strlcat(base, "/class", sizeof(base)); + + dir = opendir(base); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; + DIR *dir2; + struct dirent *dent2; + + if (dent->d_name[0] == '.') + continue; + + if (subsystem_filtered(dent->d_name)) + continue; + + strlcpy(dirname, base, sizeof(dirname)); + strlcat(dirname, "/", sizeof(dirname)); + strlcat(dirname, dent->d_name, sizeof(dirname)); + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[PATH_SIZE]; + + if (dent2->d_name[0] == '.') + continue; + + if (!strcmp(dent2->d_name, "device")) + continue; + + strlcpy(dirname2, dirname, sizeof(dirname2)); + strlcat(dirname2, "/", sizeof(dirname2)); + strlcat(dirname2, dent2->d_name, sizeof(dirname2)); + if (attr_filtered(dirname2)) + continue; + device_list_insert(dirname2); + } + closedir(dir2); + } + } + closedir(dir); + } +} + +static void scan_failed(void) +{ + char base[PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + strlcpy(base, udev_root, sizeof(base)); + strlcat(base, "/" EVENT_FAILED_DIR, sizeof(base)); + + dir = opendir(base); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char device[PATH_SIZE]; + size_t start; + + if (dent->d_name[0] == '.') + continue; + + start = strlcpy(device, sysfs_path, sizeof(device)); + strlcat(device, dent->d_name, sizeof(device)); + path_decode(&device[start]); + device_list_insert(device); + } + closedir(dir); + } +} + +int main(int argc, char *argv[], char *envp[]) +{ + int failed = 0; + int option; + const char *action = "add"; + static const struct option options[] = { + { "verbose", 0, NULL, 'v' }, + { "dry-run", 0, NULL, 'n' }, + { "retry-failed", 0, NULL, 'F' }, + { "help", 0, NULL, 'h' }, + { "action", 1, NULL, 'c' }, + { "subsystem-match", 1, NULL, 's' }, + { "subsystem-nomatch", 1, NULL, 'S' }, + { "attr-match", 1, NULL, 'a' }, + { "attr-nomatch", 1, NULL, 'A' }, + {} + }; + + logging_init("udevtrigger"); + udev_config_init(); + dbg("version %s", UDEV_VERSION); + sysfs_init(); + + while (1) { + option = getopt_long(argc, argv, "vnFhc:s:S:a:A:", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'v': + verbose = 1; + break; + case 'n': + dry_run = 1; + break; + case 'F': + failed = 1; + break; + case 'c': + action = optarg; + break; + case 's': + name_list_add(&filter_subsystem_match_list, optarg, 0); + break; + case 'S': + name_list_add(&filter_subsystem_nomatch_list, optarg, 0); + break; + case 'a': + name_list_add(&filter_attr_match_list, optarg, 0); + break; + case 'A': + name_list_add(&filter_attr_nomatch_list, optarg, 0); + break; + case 'h': + printf("Usage: udevtrigger OPTIONS\n" + " --verbose print the list of devices while running\n" + " --dry-run do not actually trigger the events\n" + " --retry-failed trigger only the events which have been\n" + " marked as failed during a previous run\n" + " --subsystem-match= trigger devices from a matching subystem\n" + " --subsystem-nomatch= exclude devices from a matching subystem\n" + " --attr-match=]> trigger devices with a matching sysfs\n" + " attribute\n" + " --attr-nomatch=]> exclude devices with a matching sysfs\n" + " attribute\n" + " --help print this text\n" + "\n"); + goto exit; + default: + goto exit; + } + } + + if (failed) { + scan_failed(); + exec_list(action); + } else { + char base[PATH_SIZE]; + struct stat statbuf; + + /* if we have /sys/subsystem, forget all the old stuff */ + strlcpy(base, sysfs_path, sizeof(base)); + strlcat(base, "/subsystem", sizeof(base)); + if (stat(base, &statbuf) == 0) { + scan_subsystem("subsystem", SCAN_SUBSYSTEM); + exec_list(action); + scan_subsystem("subsystem", SCAN_DEVICES); + exec_list(action); + } else { + scan_subsystem("bus", SCAN_SUBSYSTEM); + exec_list(action); + scan_subsystem("bus", SCAN_DEVICES); + scan_class(); + + /* scan "block" if it isn't a "class" */ + strlcpy(base, sysfs_path, sizeof(base)); + strlcat(base, "/class/block", sizeof(base)); + if (stat(base, &statbuf) != 0) + scan_block(); + exec_list(action); + } + } + +exit: + name_list_cleanup(&filter_subsystem_match_list); + name_list_cleanup(&filter_subsystem_nomatch_list); + name_list_cleanup(&filter_attr_match_list); + name_list_cleanup(&filter_attr_nomatch_list); + + sysfs_cleanup(); + logging_close(); + return 0; +} diff --git a/21cnbao/code/05/udev源代码/udev-114/udevtrigger.xml b/21cnbao/code/05/udev源代码/udev-114/udevtrigger.xml new file mode 100644 index 0000000..eb2b985 --- /dev/null +++ b/21cnbao/code/05/udev源代码/udev-114/udevtrigger.xml @@ -0,0 +1,129 @@ + + + +
    +
    + udevtrigger + + + udevtrigger + March 2006 + udev + + + + udevtrigger + 8 + + + + + udevtriggerrequest kernel devices events for coldplug + + + + + udevtrigger + + + + + + + + + + + + + DESCRIPTION + Trigger kernel device uevents to replay missing events at system coldplug. + + + OPTIONS + + + + + Print the list of devices which will be triggered. + + + + + + Do not actually trigger the event. + + + + + + Trigger only the events which are failed during a previous run. + + + + + + Type of event to be triggered. The default value is "add". + + + + + + Trigger events for devices which belong to a matching subsystem. This option + can be specified multiple times and supports shell style pattern matching. + + + + + + Do not trigger events for devices which belong to a matching subsystem. This option + can be specified multiple times and supports shell style pattern matching. + + + + + + Trigger events for devices with a matching sysfs attribute. If a value is specified + along with the attribute name, the content of the attribute is matched against the given + value using shell style pattern matching. If no value is specified, the existence of the + sysfs attribute is checked. This option can be specified multiple times. + + + + + + Do not trigger events for devices with a matching sysfs attribute. If a value is + specified along with the attribute name, the content of the attribute is matched against + the given value using shell style pattern matching. If no value is specified, the existence + of the sysfs attribute is checked. This option can be specified multiple times. + + + + + + ENVIRONMENT + + + + + Overrides the syslog priority specified in the config file. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org and + Hannes Reinecke hare@suse.de. + + + + SEE ALSO + + udev7 + + + +
    +
    diff --git a/21cnbao/code/06/globalmem驱动/globalmem.c b/21cnbao/code/06/globalmem驱动/globalmem.c index 643bf6f..22cf393 100644 --- a/21cnbao/code/06/globalmem驱动/globalmem.c +++ b/21cnbao/code/06/globalmem驱动/globalmem.c @@ -1,9 +1,10 @@ /*====================================================================== - A globalmem driver as an example of char device drivers - + A globalmem driver as an example of char device drivers + The initial developer of the original code is Baohua Song . All Rights Reserved. ======================================================================*/ + #include #include #include @@ -16,216 +17,275 @@ #include #include -#define GLOBALMEM_SIZE 0x1000 /*ȫڴ4Kֽ*/ -#define MEM_CLEAR 0x1 /*0ȫڴ*/ -#define GLOBALMEM_MAJOR 254 /*Ԥglobalmem豸*/ +#define GLOBALMEM_SIZE 0x1000 /* ȫڴ4Kֽ */ +#define MEM_CLEAR 0x1 /* 0ȫڴ */ +#define GLOBALMEM_MAJOR 254 /* Ԥglobalmem豸 */ static globalmem_major = GLOBALMEM_MAJOR; -/*globalmem豸ṹ*/ -struct globalmem_dev -{ - struct cdev cdev; /*cdevṹ*/ - unsigned char mem[GLOBALMEM_SIZE]; /*ȫڴ*/ + +/* globalmem豸ṹ */ +struct globalmem_dev +{ + + struct cdev cdev; /* cdevṹ */ + unsigned char mem[GLOBALMEM_SIZE]; /* ȫڴ */ + }; -struct globalmem_dev *globalmem_devp; /*豸ṹָ*/ -/*ļ򿪺*/ +struct globalmem_dev *globalmem_devp; /* 豸ṹָ */ + +/* ļ򿪺 */ int globalmem_open(struct inode *inode, struct file *filp) { - /*豸ṹָ븳ֵļ˽ָ*/ - filp->private_data = globalmem_devp; - return 0; + /* 豸ṹָ븳ֵļ˽ָ */ + filp->private_data = globalmem_devp; + + return 0; } -/*ļͷź*/ + +/* ļͷź */ int globalmem_release(struct inode *inode, struct file *filp) { - return 0; + return 0; } /* ioctl豸ƺ */ -static int globalmem_ioctl(struct inode *inodep, struct file *filp, unsigned - int cmd, unsigned long arg) +static int globalmem_ioctl( + struct inode *inodep, + struct file *filp, + unsigned int cmd, + unsigned long arg) { - struct globalmem_dev *dev = filp->private_data;/*豸ṹָ*/ + struct globalmem_dev *dev = filp->private_data;/*豸ṹָ*/ - switch (cmd) - { - case MEM_CLEAR: - memset(dev->mem, 0, GLOBALMEM_SIZE); - printk(KERN_INFO "globalmem is set to zero\n"); - break; + switch (cmd) + { + case MEM_CLEAR: + { + memset(dev->mem, 0, GLOBALMEM_SIZE); + printk(KERN_INFO "globalmem is set to zero\n"); + } + break; - default: - return - EINVAL; - } - return 0; + default: + { + return - EINVAL; + } + } + + return 0; } /**/ -static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size, - loff_t *ppos) +static ssize_t globalmem_read( + struct file *filp, + char __user *buf, + size_t size, + loff_t *ppos) { - unsigned long p = *ppos; - unsigned int count = size; - int ret = 0; - struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ + unsigned long p = *ppos; /* ļָƫ*/ + unsigned int count = size; + int ret = 0; + struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ - /*ͻȡЧд*/ - if (p >= GLOBALMEM_SIZE) - return count ? - ENXIO: 0; - if (count > GLOBALMEM_SIZE - p) - count = GLOBALMEM_SIZE - p; + /* ͻȡЧд */ + if (p >= GLOBALMEM_SIZE) + { + return count ? - ENXIO: 0; + } - /*ں˿ռ->ûռ*/ - if (copy_to_user(buf, (void*)(dev->mem + p), count)) - { - ret = - EFAULT; - } - else - { - *ppos += count; - ret = count; - - printk(KERN_INFO "read %d bytes(s) from %d\n", count, p); - } + if (count > GLOBALMEM_SIZE - p) + { + count = GLOBALMEM_SIZE - p; + } - return ret; + /* ں˿ռ->ûռ + * + * dev->memƫpΪʼڴ, countֽڵûbuf + * */ + if (copy_to_user(buf, (void*)(dev->mem + p), count)) + { + ret = - EFAULT; + } + else + { + *ppos += count; + ret = count; + + printk(KERN_INFO "read %d bytes(s) from %d\n", count, p); + } + + return ret; } /*д*/ -static ssize_t globalmem_write(struct file *filp, const char __user *buf, - size_t size, loff_t *ppos) +static ssize_t globalmem_write( + struct file *filp, + const char __user *buf, + size_t size, + loff_t *ppos) { - unsigned long p = *ppos; - unsigned int count = size; - int ret = 0; - struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ - - /*ͻȡЧд*/ - if (p >= GLOBALMEM_SIZE) - return count ? - ENXIO: 0; - if (count > GLOBALMEM_SIZE - p) - count = GLOBALMEM_SIZE - p; - - /*ûռ->ں˿ռ*/ - if (copy_from_user(dev->mem + p, buf, count)) - ret = - EFAULT; - else - { - *ppos += count; - ret = count; - - printk(KERN_INFO "written %d bytes(s) from %d\n", count, p); - } + unsigned long p = *ppos; + unsigned int count = size; + int ret = 0; + struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ - return ret; + /* ͻȡЧд */ + if (p >= GLOBALMEM_SIZE) + { + return count ? - ENXIO: 0; + } + + if (count > GLOBALMEM_SIZE - p) + { + count = GLOBALMEM_SIZE - p; + } + + /* ûռ->ں˿ռ*/ + if (copy_from_user(dev->mem + p, buf, count) != 0) + { + ret = - EFAULT; + } + else + { + *ppos += count; + ret = count; + + printk(KERN_INFO "written %d bytes(s) from %d\n", count, p); + } + + return ret; } /* seekļλ */ -static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig) +static loff_t globalmem_llseek( + struct file *filp, + loff_t offset, + int orig) { - loff_t ret = 0; - switch (orig) - { - case 0: /*ļʼλƫ*/ - if (offset < 0) - { - ret = - EINVAL; - break; - } - if ((unsigned int)offset > GLOBALMEM_SIZE) - { - ret = - EINVAL; - break; - } - filp->f_pos = (unsigned int)offset; - ret = filp->f_pos; - break; - case 1: /*ļǰλƫ*/ - if ((filp->f_pos + offset) > GLOBALMEM_SIZE) - { - ret = - EINVAL; - break; - } - if ((filp->f_pos + offset) < 0) - { - ret = - EINVAL; - break; - } - filp->f_pos += offset; - ret = filp->f_pos; - break; - default: - ret = - EINVAL; - break; - } - return ret; + loff_t ret = 0; + switch (orig) + { + case 0: /*ļʼλƫ*/ + if (offset < 0) + { + ret = - EINVAL; + break; + } + + if ((unsigned int)offset > GLOBALMEM_SIZE) + { + ret = - EINVAL; + break; + } + + filp->f_pos = (unsigned int)offset; + + ret = filp->f_pos; + + break; + + case 1: /*ļǰλƫ*/ + if ((filp->f_pos + offset) > GLOBALMEM_SIZE) + { + ret = - EINVAL; + break; + } + if ((filp->f_pos + offset) < 0) + { + ret = - EINVAL; + break; + } + + filp->f_pos += offset; + ret = filp->f_pos; + + break; + + default: + + ret = - EINVAL; + break; + } + + return ret; } /*ļṹ*/ static const struct file_operations globalmem_fops = { - .owner = THIS_MODULE, - .llseek = globalmem_llseek, - .read = globalmem_read, - .write = globalmem_write, - .ioctl = globalmem_ioctl, - .open = globalmem_open, - .release = globalmem_release, + .owner = THIS_MODULE, + .llseek = globalmem_llseek, + .read = globalmem_read, + .write = globalmem_write, + .ioctl = globalmem_ioctl, + .open = globalmem_open, + .release = globalmem_release, }; /*ʼעcdev*/ static void globalmem_setup_cdev(struct globalmem_dev *dev, int index) { - int err, devno = MKDEV(globalmem_major, index); + int err, devno = MKDEV(globalmem_major, index); - cdev_init(&dev->cdev, &globalmem_fops); - dev->cdev.owner = THIS_MODULE; - dev->cdev.ops = &globalmem_fops; - err = cdev_add(&dev->cdev, devno, 1); - if (err) - printk(KERN_NOTICE "Error %d adding LED%d", err, index); + cdev_init(&dev->cdev, &globalmem_fops); + + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &globalmem_fops; + + err = cdev_add(&dev->cdev, devno, 1); + if (err) + { + printk(KERN_NOTICE "Error %d adding LED%d", err, index); + } } -/*豸ģغ*/ +/* 豸ģغ */ int globalmem_init(void) { - int result; - dev_t devno = MKDEV(globalmem_major, 0); + int result; + dev_t devno = MKDEV(globalmem_major, 0); - /* 豸*/ - if (globalmem_major) - result = register_chrdev_region(devno, 1, "globalmem"); - else /* ̬豸 */ - { - result = alloc_chrdev_region(&devno, 0, 1, "globalmem"); - globalmem_major = MAJOR(devno); - } - if (result < 0) - return result; - - /* ̬豸ṹڴ*/ - globalmem_devp = kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL); - if (!globalmem_devp) /*ʧ*/ - { - result = - ENOMEM; - goto fail_malloc; - } - memset(globalmem_devp, 0, sizeof(struct globalmem_dev)); - - globalmem_setup_cdev(globalmem_devp, 0); - return 0; + /* 豸*/ + if (globalmem_major) + { + result = register_chrdev_region(devno, 1, "globalmem"); + } + else /* ̬豸 */ + { + result = alloc_chrdev_region(&devno, 0, 1, "globalmem"); + globalmem_major = MAJOR(devno); + } - fail_malloc: unregister_chrdev_region(devno, 1); - return result; + if (result < 0) + { + return result; + } + + /* ̬豸ṹڴ*/ + globalmem_devp = kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL); + if (!globalmem_devp) /* ʧ */ + { + result = - ENOMEM; + unregister_chrdev_region(devno, 1); + + return result; + } + memset(globalmem_devp, 0, sizeof(struct globalmem_dev)); + + globalmem_setup_cdev(globalmem_devp, 0); + + return 0; } /*ģжغ*/ void globalmem_exit(void) { - cdev_del(&globalmem_devp->cdev); /*עcdev*/ - kfree(globalmem_devp); /*ͷ豸ṹڴ*/ - unregister_chrdev_region(MKDEV(globalmem_major, 0), 1); /*ͷ豸*/ + cdev_del(&globalmem_devp->cdev); /*עcdev*/ + + kfree(globalmem_devp); /*ͷ豸ṹڴ*/ + + unregister_chrdev_region(MKDEV(globalmem_major, 0), 1); /*ͷ豸*/ } MODULE_AUTHOR("Song Baohua"); diff --git a/21cnbao/code/07/含并发控制的globalmem驱动/globalmem_lock.c b/21cnbao/code/07/含并发控制的globalmem驱动/globalmem_lock.c index a99d060..713dfb4 100644 --- a/21cnbao/code/07/含并发控制的globalmem驱动/globalmem_lock.c +++ b/21cnbao/code/07/含并发控制的globalmem驱动/globalmem_lock.c @@ -1,9 +1,9 @@ /*====================================================================== - A globalmem driver as an example of char device drivers - This example is to introduce how to use locks to avoid race conditions - - The initial developer of the original code is Baohua Song - . All Rights Reserved. + A globalmem driver as an example of char device drivers + This example is to introduce how to use locks to avoid race conditions + + The initial developer of the original code is Baohua Song + . All Rights Reserved. ======================================================================*/ #include #include @@ -18,235 +18,252 @@ #include #define GLOBALMEM_SIZE 0x1000 /*ȫڴ4Kֽ*/ -#define MEM_CLEAR 0x1 /*0ȫڴ*/ -#define GLOBALMEM_MAJOR 254 /*Ԥglobalmem豸*/ +#define MEM_CLEAR 0x1 /*0ȫڴ*/ +#define GLOBALMEM_MAJOR 254 /*Ԥglobalmem豸*/ static globalmem_major = GLOBALMEM_MAJOR; -/*globalmem豸ṹ*/ -struct globalmem_dev -{ - struct cdev cdev; /*cdevṹ*/ - unsigned char mem[GLOBALMEM_SIZE]; /*ȫڴ*/ - struct semaphore sem; /*õź*/ + +/* globalmem豸ṹ */ +struct globalmem_dev +{ + struct cdev cdev; /* cdevṹ */ + unsigned char mem[GLOBALMEM_SIZE]; /* ȫڴ */ + struct semaphore sem; /* õź */ }; -struct globalmem_dev *globalmem_devp; /*豸ṹָ*/ +struct globalmem_dev *globalmem_devp; /* 豸ṹָ */ -/*ļ򿪺*/ +/* ļ򿪺 */ int globalmem_open(struct inode *inode, struct file *filp) { - /*豸ṹָ븳ֵļ˽ָ*/ - filp->private_data = globalmem_devp; - return 0; + /* 豸ṹָ븳ֵļ˽ָ */ + filp->private_data = globalmem_devp; + + return 0; } -/*ļͷź*/ +/* ļͷź */ int globalmem_release(struct inode *inode, struct file *filp) { - return 0; + return 0; } -/* ioctl豸ƺ */ -static int globalmem_ioctl(struct inode *inodep, struct file *filp, unsigned - int cmd, unsigned long arg) +/* ioctl豸ƺ */ +static int globalmem_ioctl( + struct inode *inodep, + struct file *filp, + unsigned int cmd, + unsigned long arg) { - struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ + struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ - switch (cmd) - { - case MEM_CLEAR: - if (down_interruptible(&dev->sem)) - { + switch (cmd) + { + case MEM_CLEAR: + if (down_interruptible(&dev->sem)) + { + return - ERESTARTSYS; + } + + memset(dev->mem, 0, GLOBALMEM_SIZE); + + up(&dev->sem); //ͷź + + printk(KERN_INFO "globalmem is set to zero\n"); + break; + + default: + + return - EINVAL; + } + return 0; +} + +/* */ +static ssize_t globalmem_read( + struct file *filp, + char __user *buf, + size_t size, + loff_t *ppos) +{ + unsigned long p = *ppos; + unsigned int count = size; + int ret = 0; + struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ + + /*ͻȡЧд*/ + if (p >= GLOBALMEM_SIZE) + { + return count ? - ENXIO: 0; + } + + if (count > GLOBALMEM_SIZE - p) + { + count = GLOBALMEM_SIZE - p; + } + + if (down_interruptible(&dev->sem)) + { return - ERESTARTSYS; - } - memset(dev->mem, 0, GLOBALMEM_SIZE); - up(&dev->sem); //ͷź + } - printk(KERN_INFO "globalmem is set to zero\n"); - break; + /*ں˿ռ->ûռ*/ + if (copy_to_user(buf, (void*)(dev->mem + p), count)) + { + ret = - EFAULT; + } + else + { + *ppos += count; + ret = count; - default: - return - EINVAL; - } - return 0; -} + printk(KERN_INFO "read %d bytes(s) from %d\n", count, p); + } -/**/ -static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size, - loff_t *ppos) -{ - unsigned long p = *ppos; - unsigned int count = size; - int ret = 0; - struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ + up(&dev->sem); //ͷź - /*ͻȡЧд*/ - if (p >= GLOBALMEM_SIZE) - return count ? - ENXIO: 0; - if (count > GLOBALMEM_SIZE - p) - count = GLOBALMEM_SIZE - p; - - if (down_interruptible(&dev->sem)) - { - return - ERESTARTSYS; - } - - /*ں˿ռ->ûռ*/ - if (copy_to_user(buf, (void*)(dev->mem + p), count)) - { - ret = - EFAULT; - } - else - { - *ppos += count; - ret = count; - - printk(KERN_INFO "read %d bytes(s) from %d\n", count, p); - } - up(&dev->sem); //ͷź - - return ret; + return ret; } /*д*/ static ssize_t globalmem_write(struct file *filp, const char __user *buf, - size_t size, loff_t *ppos) + size_t size, loff_t *ppos) { - unsigned long p = *ppos; - unsigned int count = size; - int ret = 0; - struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ + unsigned long p = *ppos; + unsigned int count = size; + int ret = 0; + struct globalmem_dev *dev = filp->private_data; /*豸ṹָ*/ - /*ͻȡЧд*/ - if (p >= GLOBALMEM_SIZE) - return count ? - ENXIO: 0; - if (count > GLOBALMEM_SIZE - p) - count = GLOBALMEM_SIZE - p; + /*ͻȡЧд*/ + if (p >= GLOBALMEM_SIZE) + return count ? - ENXIO: 0; + if (count > GLOBALMEM_SIZE - p) + count = GLOBALMEM_SIZE - p; - if (down_interruptible(&dev->sem))//ź - { - return - ERESTARTSYS; - } - /*ûռ->ں˿ռ*/ - if (copy_from_user(dev->mem + p, buf, count)) - ret = - EFAULT; - else - { - *ppos += count; - ret = count; + if (down_interruptible(&dev->sem))//ź + { + return - ERESTARTSYS; + } + /*ûռ->ں˿ռ*/ + if (copy_from_user(dev->mem + p, buf, count)) + ret = - EFAULT; + else + { + *ppos += count; + ret = count; - printk(KERN_INFO "written %d bytes(s) from %d\n", count, p); - } - up(&dev->sem); //ͷź - return ret; + printk(KERN_INFO "written %d bytes(s) from %d\n", count, p); + } + up(&dev->sem); //ͷź + return ret; } /* seekļλ */ static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig) { - loff_t ret = 0; - switch (orig) - { - case 0: /*ļʼλƫ*/ - if (offset < 0) - { + loff_t ret = 0; + switch (orig) + { + case 0: /*ļʼλƫ*/ + if (offset < 0) + { + ret = - EINVAL; + break; + } + if ((unsigned int)offset > GLOBALMEM_SIZE) + { + ret = - EINVAL; + break; + } + filp->f_pos = (unsigned int)offset; + ret = filp->f_pos; + break; + case 1: /*ļǰλƫ*/ + if ((filp->f_pos + offset) > GLOBALMEM_SIZE) + { + ret = - EINVAL; + break; + } + if ((filp->f_pos + offset) < 0) + { + ret = - EINVAL; + break; + } + filp->f_pos += offset; + ret = filp->f_pos; + break; + default: ret = - EINVAL; break; - } - if ((unsigned int)offset > GLOBALMEM_SIZE) - { - ret = - EINVAL; - break; - } - filp->f_pos = (unsigned int)offset; - ret = filp->f_pos; - break; - case 1: /*ļǰλƫ*/ - if ((filp->f_pos + offset) > GLOBALMEM_SIZE) - { - ret = - EINVAL; - break; - } - if ((filp->f_pos + offset) < 0) - { - ret = - EINVAL; - break; - } - filp->f_pos += offset; - ret = filp->f_pos; - break; - default: - ret = - EINVAL; - break; - } - return ret; + } + return ret; } /*ļṹ*/ static const struct file_operations globalmem_fops = { - .owner = THIS_MODULE, - .llseek = globalmem_llseek, - .read = globalmem_read, - .write = globalmem_write, - .ioctl = globalmem_ioctl, - .open = globalmem_open, - .release = globalmem_release, + .owner = THIS_MODULE, + .llseek = globalmem_llseek, + .read = globalmem_read, + .write = globalmem_write, + .ioctl = globalmem_ioctl, + .open = globalmem_open, + .release = globalmem_release, }; /*ʼעcdev*/ static void globalmem_setup_cdev(struct globalmem_dev *dev, int index) { - int err, devno = MKDEV(globalmem_major, index); + int err, devno = MKDEV(globalmem_major, index); - cdev_init(&dev->cdev, &globalmem_fops); - dev->cdev.owner = THIS_MODULE; - dev->cdev.ops = &globalmem_fops; - err = cdev_add(&dev->cdev, devno, 1); - if (err) - printk(KERN_NOTICE "Error %d adding LED%d", err, index); + cdev_init(&dev->cdev, &globalmem_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &globalmem_fops; + err = cdev_add(&dev->cdev, devno, 1); + if (err) + printk(KERN_NOTICE "Error %d adding LED%d", err, index); } /*豸ģغ*/ int globalmem_init(void) { - int result; - dev_t devno = MKDEV(globalmem_major, 0); + int result; + dev_t devno = MKDEV(globalmem_major, 0); - /* 豸*/ - if (globalmem_major) - result = register_chrdev_region(devno, 1, "globalmem"); - else /* ̬豸 */ - { - result = alloc_chrdev_region(&devno, 0, 1, "globalmem"); - globalmem_major = MAJOR(devno); - } - if (result < 0) + /* 豸*/ + if (globalmem_major) + result = register_chrdev_region(devno, 1, "globalmem"); + else /* ̬豸 */ + { + result = alloc_chrdev_region(&devno, 0, 1, "globalmem"); + globalmem_major = MAJOR(devno); + } + if (result < 0) + return result; + + /* ̬豸ṹڴ*/ + globalmem_devp = kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL); + if (!globalmem_devp) /*ʧ*/ + { + result = - ENOMEM; + goto fail_malloc; + } + memset(globalmem_devp, 0, sizeof(struct globalmem_dev)); + + globalmem_setup_cdev(globalmem_devp, 0); + init_MUTEX(&globalfifo_devp->sem); /*ʼź*/ + return 0; + + fail_malloc: unregister_chrdev_region(devno, 1); return result; - - /* ̬豸ṹڴ*/ - globalmem_devp = kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL); - if (!globalmem_devp) /*ʧ*/ - { - result = - ENOMEM; - goto fail_malloc; - } - memset(globalmem_devp, 0, sizeof(struct globalmem_dev)); - - globalmem_setup_cdev(globalmem_devp, 0); - init_MUTEX(&globalfifo_devp->sem); /*ʼź*/ - return 0; - - fail_malloc: unregister_chrdev_region(devno, 1); - return result; } /*ģжغ*/ void globalmem_exit(void) { - cdev_del(&globalmem_devp->cdev); /*עcdev*/ - kfree(globalmem_devp); /*ͷ豸ṹڴ*/ - unregister_chrdev_region(MKDEV(globalmem_major, 0), 1); /*ͷ豸*/ + cdev_del(&globalmem_devp->cdev); /*עcdev*/ + kfree(globalmem_devp); /*ͷ豸ṹڴ*/ + unregister_chrdev_region(MKDEV(globalmem_major, 0), 1); /*ͷ豸*/ } MODULE_AUTHOR("Song Baohua"); diff --git a/21cnbao/code/08/globalfifo驱动/globalfifo.c b/21cnbao/code/08/globalfifo驱动/globalfifo.c index 0a4b4fc..ea84f22 100644 --- a/21cnbao/code/08/globalfifo驱动/globalfifo.c +++ b/21cnbao/code/08/globalfifo驱动/globalfifo.c @@ -1,7 +1,7 @@ /*====================================================================== - A globalfifo driver as an example of char device drivers + A globalfifo driver as an example of char device drivers This example is to introduce poll,blocking and non-blocking access - + The initial developer of the original code is Baohua Song . All Rights Reserved. ======================================================================*/ @@ -18,51 +18,58 @@ #include #include -#define GLOBALFIFO_SIZE 0x1000 /*ȫfifo4Kֽ*/ -#define FIFO_CLEAR 0x1 /*0ȫڴij*/ -#define GLOBALFIFO_MAJOR 253 /*Ԥglobalfifo豸*/ +#define GLOBALFIFO_SIZE 0x1000 /* ȫfifo4Kֽ */ +#define FIFO_CLEAR 0x1 /* 0ȫڴij */ +#define GLOBALFIFO_MAJOR 253 /* Ԥglobalfifo豸 */ static int globalfifo_major = GLOBALFIFO_MAJOR; -/*globalfifo豸ṹ*/ -struct globalfifo_dev -{ - struct cdev cdev; /*cdevṹ*/ - unsigned int current_len; /*fifoЧݳ*/ - unsigned char mem[GLOBALFIFO_SIZE]; /*ȫڴ*/ - struct semaphore sem; /*õź*/ - wait_queue_head_t r_wait; /*õĵȴͷ*/ - wait_queue_head_t w_wait; /*дõĵȴͷ*/ + +/* globalfifo豸ṹ */ +struct globalfifo_dev +{ + struct cdev cdev; /* cdevṹ */ + unsigned int current_len; /* fifoЧݳ */ + unsigned char mem[GLOBALFIFO_SIZE]; /* ȫڴ */ + struct semaphore sem; /* õź */ + wait_queue_head_t r_wait; /* õĵȴͷ */ + wait_queue_head_t w_wait; /* дõĵȴͷ */ }; -struct globalfifo_dev *globalfifo_devp; /*豸ṹָ*/ -/*ļ򿪺*/ +struct globalfifo_dev *globalfifo_devp; /* 豸ṹָ */ + +/* ļ򿪺 */ int globalfifo_open(struct inode *inode, struct file *filp) { - /*豸ṹָ븳ֵļ˽ָ*/ - filp->private_data = globalfifo_devp; - return 0; + /*豸ṹָ븳ֵļ˽ָ*/ + filp->private_data = globalfifo_devp; + + return 0; } + /*ļͷź*/ int globalfifo_release(struct inode *inode, struct file *filp) { - return 0; + return 0; } /* ioctl豸ƺ */ -static int globalfifo_ioctl(struct inode *inodep, struct file *filp, unsigned - int cmd, unsigned long arg) +static int globalfifo_ioctl( + struct inode *inodep, + struct file *filp, + unsigned int cmd, + unsigned long arg) { - struct globalfifo_dev *dev = filp->private_data;/*豸ṹָ*/ + struct globalfifo_dev *dev = filp->private_data; /*豸ṹָ*/ switch (cmd) { case FIFO_CLEAR: - down(&dev->sem); //ź + down(&dev->sem); //ź dev->current_len = 0; memset(dev->mem,0,GLOBALFIFO_SIZE); up(&dev->sem); //ͷź - - printk(KERN_INFO "globalfifo is set to zero\n"); + + printk(KERN_INFO "globalfifo is set to zero\n"); break; default: @@ -75,11 +82,11 @@ static unsigned int globalfifo_poll(struct file *filp, poll_table *wait) { unsigned int mask = 0; struct globalfifo_dev *dev = filp->private_data; /*豸ṹָ*/ - + down(&dev->sem); - + poll_wait(filp, &dev->r_wait, wait); - poll_wait(filp, &dev->w_wait, wait); + poll_wait(filp, &dev->w_wait, wait); /*fifoǿ*/ if (dev->current_len != 0) { @@ -90,68 +97,84 @@ static unsigned int globalfifo_poll(struct file *filp, poll_table *wait) { mask |= POLLOUT | POLLWRNORM; /*ʾݿд*/ } - + up(&dev->sem); return mask; } /*globalfifo*/ -static ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t count, - loff_t *ppos) +static ssize_t globalfifo_read( + struct file *filp, + char __user *buf, + size_t count, + loff_t *ppos) { - int ret; - struct globalfifo_dev *dev = filp->private_data; //豸ṹָ - DECLARE_WAITQUEUE(wait, current); //ȴ + int ret; + struct globalfifo_dev *dev = filp->private_data; //豸ṹָ - down(&dev->sem); //ź - add_wait_queue(&dev->r_wait, &wait); //ȴͷ + DECLARE_WAITQUEUE(wait, current); // ȴ - /* ȴFIFOǿ */ - if (dev->current_len == 0) - { - if (filp->f_flags &O_NONBLOCK) + + down(&dev->sem); // ź + add_wait_queue(&dev->r_wait, &wait); // ȴͷ + + /* ȴFIFOǿ */ + if (dev->current_len == 0) { - ret = - EAGAIN; - goto out; - } - __set_current_state(TASK_INTERRUPTIBLE); //ı״̬Ϊ˯ - up(&dev->sem); + if (filp->f_flags &O_NONBLOCK) + { + ret = - EAGAIN; + goto out; + } - schedule(); //ִ - if (signal_pending(current)) - //ΪźŻ - { - ret = - ERESTARTSYS; - goto out2; + __set_current_state(TASK_INTERRUPTIBLE); //ı״̬Ϊ˯ + + up(&dev->sem); + + + schedule(); //ִ + + if (signal_pending(current)) + //ΪźŻ + { + ret = - ERESTARTSYS; + goto out2; + } + + down(&dev->sem); } - down(&dev->sem); + /* ûռ */ + if (count > dev->current_len) + { + count = dev->current_len; + } + + if (copy_to_user(buf, dev->mem, count)) + { + ret = - EFAULT; + goto out; + } + else + { + memcpy(dev->mem, dev->mem + count, dev->current_len - count); //fifoǰ + dev->current_len -= count; //Чݳȼ + printk(KERN_INFO "read %d bytes(s),current_len:%d\n", count, dev->current_len); + + wake_up_interruptible(&dev->w_wait); //дȴ + + ret = count; } - /* ûռ */ - if (count > dev->current_len) - count = dev->current_len; - if (copy_to_user(buf, dev->mem, count)) - { - ret = - EFAULT; - goto out; - } - else - { - memcpy(dev->mem, dev->mem + count, dev->current_len - count); //fifoǰ - dev->current_len -= count; //Чݳȼ - printk(KERN_INFO "read %d bytes(s),current_len:%d\n", count, dev->current_len); - - wake_up_interruptible(&dev->w_wait); //дȴ - - ret = count; - } - out: up(&dev->sem); //ͷź - out2:remove_wait_queue(&dev->w_wait, &wait); //ӸĵȴͷƳ - set_current_state(TASK_RUNNING); - return ret; +out : + up(&dev->sem); //ͷź +out2 : + remove_wait_queue(&dev->w_wait, &wait); //ӸĵȴͷƳ + set_current_state(TASK_RUNNING); + + return ret; } @@ -174,7 +197,7 @@ static ssize_t globalfifo_write(struct file *filp, const char __user *buf, { ret = - EAGAIN; goto out; - } + } __set_current_state(TASK_INTERRUPTIBLE); //ı״̬Ϊ˯ up(&dev->sem); @@ -205,7 +228,7 @@ static ssize_t globalfifo_write(struct file *filp, const char __user *buf, ->current_len); wake_up_interruptible(&dev->r_wait); //Ѷȴ - + ret = count; }